enhance ui

This commit is contained in:
BuckarooBanzay 2021-01-16 21:03:43 +01:00
parent cef7983f4b
commit 4691175a30
16 changed files with 242 additions and 138 deletions

View File

@ -8,9 +8,9 @@ local abm_mapped_keys = {
"catch_up" "catch_up"
} }
minetest.register_on_mods_loaded(function() mtinfo.export_abms = function()
local data = {} local data = {}
mtinfo.map_list(data, minetest.registered_abms, abm_mapped_keys) mtinfo.map_list(data, minetest.registered_abms, abm_mapped_keys)
mtinfo.export_json(mtinfo.basepath.."/data/abm.js", data, "mtinfo.abm") mtinfo.export_json(mtinfo.basepath.."/data/abm.js", data, "mtinfo.abm")
end) end

View File

@ -21,16 +21,24 @@
<script src="js/components/app.js"></script> <script src="js/components/app.js"></script>
<script src="js/components/start-page.js"></script> <script src="js/components/start-page.js"></script>
<script src="js/components/nav-bar.js"></script> <script src="js/components/nav-bar.js"></script>
<script src="js/components/node-info.js"></script> <script src="js/components/node-list.js"></script>
<script src="js/components/node-detail.js"></script>
<script src="js/components/node-preview-normal.js"></script>
<script src="js/components/node-preview-inventoryimage.js"></script>
<script src="js/components/node-info.js"></script>
<!-- Utilities --> <!-- Utilities -->
<script src="js/util/imageresolver.js"></script> <script src="js/util/imageresolver.js"></script>
<!-- exported data --> <!-- exported data -->
<script src="data/nodes.js"></script> <script src="data/nodes.js"></script>
<script src="data/recipes.js"></script> <script src="data/recipes.js"></script>
<script src="data/abm.js"></script>
<!-- init --> <!-- precomputations -->
<script src="js/util/compute_abm_nodes.js"></script>
<!-- init -->
<script src="js/main.js"></script> <script src="js/main.js"></script>
</body> </body>
</html> </html>

View File

@ -0,0 +1,21 @@
Vue.component("node-detail", {
props: ["node"],
template: /*html*/`
<div>
<h3>{{ node.description }} <small class="text-muted">{{ node.name }}</small></h3>
<span v-if="node.diggable" class="badge badge-success">Diggable</span>
<span v-if="node.pointable" class="badge badge-success">Pointable</span>
<span v-if="node.airlike" class="badge badge-success">Airlike</span>
<span v-if="node.walkable" class="badge badge-success">Walkable</span>
<p>Stack-max: <span class="badge badge-primary">{{ node.stack_max }}</span></p>
<p v-if="node.light_source">Light-source: <span class="badge badge-primary">{{ node.light_source }}</span></p>
<p>Groups</p>
<ul v-if="node.groups">
<li v-for="group in Object.keys(node.groups)">
{{ group }} {{ node.groups[group] }}
</li>
</ul>
</div>
`
});

View File

@ -1,35 +1,30 @@
Vue.component("node-list", {
template: /*html*/`
<div>
<h4>Node list</h4>
<table class="table">
<thead>
<tr>
<th>Mod</th>
<th>Image</th>
<th>Nodename</th>
</tr>
</thead>
<tbody>
<tr v-for="nodename in Object.keys(mtinfo.nodes)">
<td>{{ nodename.substring(0, nodename.indexOf(":")) }}</td>
<td>
<img :src="mtinfo.imageresolver(mtinfo.nodes[nodename])"/>
</td>
<td>
<router-link :to="'/nodes/' + nodename">
{{ nodename }}
</router-link>
</td>
</tr>
</tbody>
</table>
</div>
`
});
Vue.component("node-info", { Vue.component("node-info", {
props: ["name"], props: ["name"],
created: function(){
//TODO: debug
const nodename = this.name;
const nodedef = mtinfo.nodes[this.name];
console.log(nodedef);
if (mtinfo.abm_nodenames[this.name]){
console.log("abm nodename", mtinfo.abm_nodenames[this.name]);
}
if (mtinfo.abm_neighbors[this.name]){
console.log("abm neighbor", mtinfo.abm_neighbors[this.name]);
}
if (nodedef.groups){
Object.keys(nodedef.groups).forEach(function(group){
const name = "group:" + group;
if (mtinfo.abm_nodenames[name]){
console.log("abm group nodename", mtinfo.abm_nodenames[name]);
}
if (mtinfo.abm_neighbors[name]){
console.log("abm group neighbor", mtinfo.abm_neighbors[name]);
}
});
}
},
computed: { computed: {
previewImage: function(){ previewImage: function(){
return mtinfo.imageresolver(mtinfo.nodes[this.name]); return mtinfo.imageresolver(mtinfo.nodes[this.name]);
@ -37,98 +32,23 @@ Vue.component("node-info", {
}, },
template: /*html*/` template: /*html*/`
<div> <div>
<h4>Node info: {{ name }}</h4>
<pre>
{{ JSON.stringify(mtinfo.nodes[name]) }}
</pre>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-3">
<!-- <img :src="previewImage" style="height: 64px; width: 64px;"/> --> <!-- <img :src="previewImage" style="height: 64px; width: 64px;"/> -->
<node-preview-normal v-if="mtinfo.nodes[name].drawtype == 'normal'" :node="mtinfo.nodes[name]"></node-preview-normal> <node-preview-inventoryimage v-if="mtinfo.nodes[name].inventory_image" :node="mtinfo.nodes[name]"></node-preview-inventoryimage>
<node-preview-normal v-if="mtinfo.nodes[name].drawtype == 'glasslike'" :node="mtinfo.nodes[name]"></node-preview-normal> <node-preview-normal v-else-if="mtinfo.nodes[name].drawtype == 'normal'" :node="mtinfo.nodes[name]"></node-preview-normal>
<node-preview-normal v-if="mtinfo.nodes[name].drawtype == 'allfaces_optional'" :node="mtinfo.nodes[name]"></node-preview-normal> <node-preview-normal v-else-if="mtinfo.nodes[name].drawtype == 'glasslike'" :node="mtinfo.nodes[name]"></node-preview-normal>
<node-preview-normal v-else-if="mtinfo.nodes[name].drawtype == 'allfaces_optional'" :node="mtinfo.nodes[name]"></node-preview-normal>
<node-preview-normal v-else-if="mtinfo.nodes[name].drawtype == 'glasslike_framed_optional'" :node="mtinfo.nodes[name]"></node-preview-normal>
<node-preview-inventoryimage v-else-if="mtinfo.nodes[name].drawtype == 'plantlike'" :node="mtinfo.nodes[name]"></node-preview-inventoryimage>
<div v-else> <div v-else>
No preview available No preview available
</div> </div>
</div> </div>
<div class="col-md-6"> <div class="col-md-9">
<node-detail :node="mtinfo.nodes[name]"/>
</div> </div>
</div> </div>
</div> </div>
` `
}); });
Vue.component("node-preview-normal", {
props: ["node"],
computed: {
frontStyle: function(){
let texture = "pics/unknown_node.png";
if (this.node.tiles){
if (this.node.tiles.length >= 3) {
// x+
texture = "textures/" + mtinfo.stripimagetransforms(this.node.tiles[2]);
} else {
// last tile
texture = "textures/" + mtinfo.stripimagetransforms(this.node.tiles[this.node.tiles.length-1]);
}
}
return {
"transform-origin": "0 0",
"position": "absolute",
"width": "100px",
"height": "100px",
"background-image": "url('" + texture + "')",
"background-size": "cover",
"transform": "rotate(0deg) skewY(30deg) scaleX(0.864) translate(31px, 69px)"
};
},
sideStyle: function(){
let texture = "pics/unknown_node.png";
if (this.node.tiles){
if (this.node.tiles.length >= 5) {
// z+
texture = "textures/" + mtinfo.stripimagetransforms(this.node.tiles[4]);
} else {
// last tile
texture = "textures/" + mtinfo.stripimagetransforms(this.node.tiles[this.node.tiles.length-1]);
}
}
return {
"transform-origin": "0 0",
"position": "absolute",
"width": "100px",
"height": "100px",
"background-image": "url('" + texture + "')",
"background-size": "cover",
"transform": "rotate(-30deg) skewX(-30deg) translate(130px, 173px) scaleY(0.864)"
};
},
topStyle: function(){
let texture = "pics/unknown_node.png";
if (this.node.tiles && this.node.tiles.length >= 1){
texture = "textures/" + mtinfo.stripimagetransforms(this.node.tiles[0]);
}
return {
"transform-origin": "0 0",
"position": "absolute",
"width": "100px",
"height": "100px",
"background-image": "url('" + texture + "')",
"background-size": "cover",
"transform": "rotate(210deg) skew(-30deg) translate(-200px, -60px) scaleY(0.864)"
};
}
},
template: /*html*/`
<div style="width: 300px; height: 300px; overflow: hidden;">
<h4>Preview: {{ node.name }}</h4>
<div v-bind:style="frontStyle"></div>
<div v-bind:style="sideStyle"></div>
<div v-bind:style="topStyle"></div>
</div>
`
});

View File

@ -0,0 +1,29 @@
Vue.component("node-list", {
template: /*html*/`
<div>
<h4>Node list</h4>
<table class="table">
<thead>
<tr>
<th>Mod</th>
<th>Image</th>
<th>Nodename</th>
</tr>
</thead>
<tbody>
<tr v-for="nodename in Object.keys(mtinfo.nodes)">
<td>{{ nodename.substring(0, nodename.indexOf(":")) }}</td>
<td>
<img :src="mtinfo.imageresolver(mtinfo.nodes[nodename])"/>
</td>
<td>
<router-link :to="'/nodes/' + nodename">
{{ nodename }}
</router-link>
</td>
</tr>
</tbody>
</table>
</div>
`
});

View File

@ -0,0 +1,12 @@
Vue.component("node-preview-inventoryimage", {
props: ["node"],
computed: {
imgsrc: function(){
return `textures/${this.node.inventory_image}`;
}
},
template: /*html*/`
<img :src="imgsrc" width="300" height="300" style="image-rendering: crisp-edges;"/>
`
});

View File

@ -0,0 +1,67 @@
const common_attributes = {
"transform-origin": "0 0",
"position": "absolute",
"width": "100px",
"height": "100px",
"background-size": "cover",
"image-rendering": "crisp-edges"
};
Vue.component("node-preview-normal", {
props: ["node"],
computed: {
frontStyle: function(){
let texture = "pics/unknown_node.png";
if (this.node.tiles){
if (this.node.tiles.length >= 3) {
// x+
texture = "textures/" + mtinfo.stripimagetransforms(this.node.tiles[2]);
} else {
// last tile
texture = "textures/" + mtinfo.stripimagetransforms(this.node.tiles[this.node.tiles.length-1]);
}
}
return Object.assign({}, common_attributes, {
"background-image": "url('" + texture + "')",
"transform": "rotate(0deg) skewY(30deg) scaleX(0.864) translate(31px, 69px)"
});
},
sideStyle: function(){
let texture = "pics/unknown_node.png";
if (this.node.tiles){
if (this.node.tiles.length >= 5) {
// z+
texture = "textures/" + mtinfo.stripimagetransforms(this.node.tiles[4]);
} else {
// last tile
texture = "textures/" + mtinfo.stripimagetransforms(this.node.tiles[this.node.tiles.length-1]);
}
}
return Object.assign({}, common_attributes, {
"background-image": "url('" + texture + "')",
"transform": "rotate(-30deg) skewX(-30deg) translate(130px, 173px) scaleY(0.864)"
});
},
topStyle: function(){
let texture = "pics/unknown_node.png";
if (this.node.tiles && this.node.tiles.length >= 1){
texture = "textures/" + mtinfo.stripimagetransforms(this.node.tiles[0]);
}
return Object.assign({}, common_attributes, {
"background-image": "url('" + texture + "')",
"transform": "rotate(210deg) skew(-30deg) translate(-200px, -60px) scaleY(0.864)"
});
}
},
template: /*html*/`
<div style="width: 300px; height: 300px; overflow: hidden;">
<div v-bind:style="frontStyle"></div>
<div v-bind:style="sideStyle"></div>
<div v-bind:style="topStyle"></div>
</div>
`
});

View File

@ -16,5 +16,3 @@ new Vue({
el: "#app", el: "#app",
router: router router: router
}); });
console.log("OK");

View File

@ -0,0 +1,25 @@
/*
pre-compute abm name/group maps
mtinfo.abm = [];
mtinfo.abm_nodenames[nodename_or_group] = abm
mtinfo.abm_neighbors[nodename_or_group] = abm
*/
mtinfo.abm_nodenames = {};
mtinfo.abm_neighbors = {};
mtinfo.abm.forEach(function(abm){
abm.nodenames.forEach(function(nodename){
mtinfo.abm_nodenames[nodename] = abm;
});
if (abm.neighbors){
if (typeof(abm.neighbors) == "string"){
mtinfo.abm_neighbors[abm.neighbors] = abm;
} else {
abm.neighbors.forEach(function(nodename){
mtinfo.abm_neighbors[nodename] = abm;
});
}
}
});

View File

@ -12,6 +12,10 @@ function mtinfo.map_list(target, list, keys, filter)
if def[key] and def[key] ~= 0 then if def[key] and def[key] ~= 0 then
-- only export fields that are populated -- only export fields that are populated
item[key] = def[key] item[key] = def[key]
if key == "description" then
-- translate content
item[key] = minetest.get_translated_string("", def[key])
end
end end
end end
target[name] = item target[name] = item
@ -56,8 +60,8 @@ end
function mtinfo.export_json(fname, data, varname) function mtinfo.export_json(fname, data, varname)
local f = io.open(fname, "w") local f = io.open(fname, "w")
local data_string, err = minetest.write_json(data) local data_string, err = minetest.write_json(data)
if err then if err or not f then
error(err) error("error while opening " .. fname .. " " .. (err or ""))
end end
f:write(varname .. "=") f:write(varname .. "=")
f:write(data_string) f:write(data_string)

View File

@ -14,9 +14,29 @@ dofile(MP .. "/lbm.lua")
dofile(MP .. "/recipes.lua") dofile(MP .. "/recipes.lua")
dofile(MP .. "/textures.lua") dofile(MP .. "/textures.lua")
-- copy static assets minetest.register_on_mods_loaded(function()
minetest.mkdir(mtinfo.basepath .. "/data")
mtinfo.copyrecursive(MP .. "/app/pics", mtinfo.basepath .. "/pics") -- workaround for empty translations, defer a globalstep until everything is initialized
mtinfo.copyrecursive(MP .. "/app/js", mtinfo.basepath .. "/js") minetest.after(0, function()
mtinfo.copyrecursive(MP .. "/app/css", mtinfo.basepath .. "/css") local start = minetest.get_us_time()
mtinfo.copyfile(MP .. "/app/index.html", mtinfo.basepath .. "/index.html")
-- export data
mtinfo.export_nodes()
mtinfo.export_lbms()
mtinfo.export_abms()
mtinfo.export_items()
mtinfo.export_recipes()
mtinfo.export_tools()
-- copy static assets
minetest.mkdir(mtinfo.basepath)
minetest.mkdir(mtinfo.basepath .. "/data")
mtinfo.copyrecursive(MP .. "/app/pics", mtinfo.basepath .. "/pics")
mtinfo.copyrecursive(MP .. "/app/js", mtinfo.basepath .. "/js")
mtinfo.copyrecursive(MP .. "/app/css", mtinfo.basepath .. "/css")
mtinfo.copyfile(MP .. "/app/index.html", mtinfo.basepath .. "/index.html")
local diff = minetest.get_us_time() - start
print("[mtinfo] export took " .. diff .. " us")
end)
end)

View File

@ -8,9 +8,9 @@ local item_mapped_keys = {
"range" "range"
} }
minetest.register_on_mods_loaded(function() mtinfo.export_items = function()
local data = {} local data = {}
mtinfo.map_list(data, minetest.registered_items, item_mapped_keys) mtinfo.map_list(data, minetest.registered_items, item_mapped_keys)
mtinfo.export_json(mtinfo.basepath.."/data/items.js", data, "mtinfo.items") mtinfo.export_json(mtinfo.basepath.."/data/items.js", data, "mtinfo.items")
end) end

View File

@ -6,9 +6,9 @@ local lbm_mapped_keys = {
"run_at_every_load" "run_at_every_load"
} }
minetest.register_on_mods_loaded(function() mtinfo.export_lbms = function()
local data = {} local data = {}
mtinfo.map_list(data, minetest.registered_lbms, lbm_mapped_keys) mtinfo.map_list(data, minetest.registered_lbms, lbm_mapped_keys)
mtinfo.export_json(mtinfo.basepath.."/data/lbm.js", data, "mtinfo.lbm") mtinfo.export_json(mtinfo.basepath.."/data/lbm.js", data, "mtinfo.lbm")
end) end

View File

@ -26,7 +26,7 @@ local node_mapped_keys = {
"drop" "drop"
} }
minetest.register_on_mods_loaded(function() mtinfo.export_nodes = function()
local data = {} local data = {}
mtinfo.map_list(data, minetest.registered_nodes, node_mapped_keys, function(def) mtinfo.map_list(data, minetest.registered_nodes, node_mapped_keys, function(def)
@ -37,4 +37,4 @@ minetest.register_on_mods_loaded(function()
end end
end) end)
mtinfo.export_json(mtinfo.basepath.."/data/nodes.js", data, "mtinfo.nodes") mtinfo.export_json(mtinfo.basepath.."/data/nodes.js", data, "mtinfo.nodes")
end) end

View File

@ -1,5 +1,5 @@
minetest.register_on_mods_loaded(function() mtinfo.export_recipes = function()
local data = {} local data = {}
for name in pairs(minetest.registered_nodes) do for name in pairs(minetest.registered_nodes) do
@ -7,4 +7,4 @@ minetest.register_on_mods_loaded(function()
end end
mtinfo.export_json(mtinfo.basepath.."/data/recipes.js", data, "mtinfo.recipes") mtinfo.export_json(mtinfo.basepath.."/data/recipes.js", data, "mtinfo.recipes")
end) end

View File

@ -8,9 +8,9 @@ local tool_mapped_keys = {
"range" "range"
} }
minetest.register_on_mods_loaded(function() mtinfo.export_tools = function()
local data = {} local data = {}
mtinfo.map_list(data, minetest.registered_tools, tool_mapped_keys) mtinfo.map_list(data, minetest.registered_tools, tool_mapped_keys)
mtinfo.export_json(mtinfo.basepath.."/data/tools.js", data, "mtinfo.tools") mtinfo.export_json(mtinfo.basepath.."/data/tools.js", data, "mtinfo.tools")
end) end