aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Yves Rollo <dev@pyrollo.com>2018-11-23 11:35:42 +0100
committerPierre-Yves Rollo <dev@pyrollo.com>2018-11-23 11:35:42 +0100
commit0f8db34368378efeedc5689446fbea9017d096df (patch)
treee7363f128eec9283f88712867bcdca66918bd385
parentdb66553fbfd5f251b4a26e8b4867cebd021a5647 (diff)
parent367e5026ddef3e6a0220f37a2f4aba64ec88f16b (diff)
downloaddisplay_modpack-0f8db34368378efeedc5689446fbea9017d096df.tar.gz
display_modpack-0f8db34368378efeedc5689446fbea9017d096df.tar.bz2
display_modpack-0f8db34368378efeedc5689446fbea9017d096df.zip
Font chooser form added
-rw-r--r--font_api/fontform.lua167
-rw-r--r--font_api/init.lua8
-rw-r--r--font_api/textures/font_api_center.pngbin0 -> 224 bytes
-rw-r--r--font_api/textures/font_api_font.pngbin0 -> 238 bytes
-rw-r--r--font_api/textures/font_api_left.pngbin0 -> 220 bytes
-rw-r--r--font_api/textures/font_api_right.pngbin0 -> 222 bytes
-rw-r--r--signs/nodes.lua93
-rw-r--r--signs_api/init.lua45
-rw-r--r--steles/nodes.lua22
9 files changed, 264 insertions, 71 deletions
diff --git a/font_api/fontform.lua b/font_api/fontform.lua
new file mode 100644
index 0000000..e4952ed
--- /dev/null
+++ b/font_api/fontform.lua
@@ -0,0 +1,167 @@
+--[[
+ font_api mod for Minetest - Library to add font display capability
+ to display_api mod.
+ (c) Pierre-Yves Rollo
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+--]]
+
+local modname = minetest.get_current_modname()
+
+local contexts = {}
+
+minetest.register_on_leaveplayer(function(player)
+ if minetest.is_player(player) then
+ contexts[player:get_player_name()] = nil
+ end
+end)
+
+local function get_context(playername)
+ if not contexts[playername] then
+ contexts[playername] = { playername = playername }
+ end
+ return contexts[playername]
+end
+
+-- Show node formspec functions
+local function show_node_formspec(playername, pos)
+ local meta = minetest.get_meta(pos)
+
+ -- Decontextualize formspec
+ local fs = meta:get_string('formspec')
+
+ if not fs then
+ return
+ end
+
+ -- Change context and currrent_name references to nodemeta references
+ -- Change context and currrent_name references to nodemeta references
+ local nodemeta = string.format("nodemeta:%i,%i,%i", pos.x, pos.y ,pos.z)
+ fs = fs:gsub("current_name", nodemeta)
+ fs = fs:gsub("context", nodemeta)
+
+ -- Change all ${} to their corresponding metadata values
+ local s, e
+ repeat
+ s, e = fs:find('%${.*}')
+ if s and e then
+ fs = fs:sub(1, s-1)..
+ minetest.formspec_escape(meta:get_string(fs:sub(s+2,e-1)))..
+ fs:sub(e+1)
+ end
+ until s == nil
+
+ local context = get_context(playername)
+ context.node_pos = pos
+
+ -- Find node on_receive_fields
+ local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
+ if ndef and ndef.on_receive_fields then
+ context.on_receive_fields = ndef.on_receive_fields
+ end
+
+ -- Show formspec
+ minetest.show_formspec(playername, modname..':context_formspec', fs)
+end
+
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ if formname ~= modname..':context_formspec' then
+ return
+ end
+
+ if not minetest.is_player(player) then
+ return true
+ end
+
+ local context = get_context(player:get_player_name())
+ if context.on_receive_fields then
+ context.on_receive_fields(context.pos, '', fields, player)
+ end
+ return true
+end)
+
+-- Specific functions
+
+local function show_font_formspec(playername)
+ local context = get_context(playername)
+ local fonts = {}
+ for name, _ in pairs(font_api.registered_fonts) do
+ fonts[#fonts+1] = name
+ end
+ table.sort(fonts)
+
+ local fs = string.format(
+ "size[4,%s]%s%s%sbutton_exit[0,%s;4,1;cancel;Cancel]",
+ #fonts + 0.8, default.gui_bg, default.gui_bg_img, default.gui_slots,
+ #fonts)
+
+ for line = 1, #fonts do
+ local font = font_api.get_font(fonts[line])
+ local texture = font:make_text_texture(font.name, font:get_height()*5,
+ font:get_height()*1.2, 1, "center", "top", "#fff")
+ fs = string.format(
+ "%simage[0.1,%s;4.5,0.8;%s]button_exit[0,%s;4,1;font_%s;]",
+ fs, line-0.9, texture, line-1, font.name)
+ end
+ minetest.show_formspec(context.playername, modname..':font_list', fs)
+end
+
+minetest.register_on_player_receive_fields(function(player, formname, fields)
+ if formname ~= modname..':font_list' then
+ return
+ end
+
+ if not minetest.is_player(player) then
+ return true
+ end
+
+ local playername = player:get_player_name()
+ local context = get_context(playername)
+
+ if not context.pos
+ or minetest.is_protected(context.pos, playername) then
+ return true
+ end
+
+ if fields.quit == 'true' then
+ for name, _ in pairs(font_api.registered_fonts) do
+ if fields['font_'..name] then
+ local meta = minetest.get_meta(context.pos)
+ meta:set_string("font", name)
+ display_api.update_entities(context.pos)
+ end
+ end
+
+ if context.callback and type(context.callback) == "function" then
+ -- Using after to avoid the "double close" bug
+ minetest.after(0, context.callback, playername, context.pos)
+ else
+ -- Using after to avoid the "double close" bug
+ minetest.after(0, show_node_formspec, playername, context.pos)
+ end
+ end
+ return true
+end)
+
+-- @param player Player viewing the form
+-- @param pos Node pos
+-- @param callback function(playername, pos) to be called on form close
+function font_api.show_font_list(player, pos, callback)
+ if minetest.is_player(player) then
+ local context = get_context(player:get_player_name())
+ context.pos = pos
+ context.callback = callback
+ show_font_formspec(player:get_player_name())
+ end
+end
diff --git a/font_api/init.lua b/font_api/init.lua
index dc3a3e0..27cba99 100644
--- a/font_api/init.lua
+++ b/font_api/init.lua
@@ -29,9 +29,10 @@ font_api.path = minetest.get_modpath(font_api.name)
dofile(font_api.path.."/font.lua")
dofile(font_api.path.."/registry.lua")
+dofile(font_api.path.."/fontform.lua")
--- Standard on_display_update entity callback.
--- Node should have a corresponding display_entity with size, resolution and
+-- Node should have a corresponding display_entity with size, resolution and
-- maxlines fields and optionally halign, valign and color fields
-- @param pos Node position
-- @param objref Object reference of entity
@@ -49,8 +50,8 @@ function font_api.on_display_update(pos, objref)
local maxlines = def.maxlines or 1 -- TODO:How to do w/o maxlines ?
- objref:set_properties({
- textures={font:make_text_texture(text,
+ objref:set_properties({
+ textures={font:make_text_texture(text,
font:get_height(maxlines) * def.size.x / def.size.y
/ (def.aspect_ratio or 1),
font:get_height(maxlines),
@@ -62,4 +63,3 @@ end
-- Compatibility
font_lib = font_api
-
diff --git a/font_api/textures/font_api_center.png b/font_api/textures/font_api_center.png
new file mode 100644
index 0000000..967db6a
--- /dev/null
+++ b/font_api/textures/font_api_center.png
Binary files differ
diff --git a/font_api/textures/font_api_font.png b/font_api/textures/font_api_font.png
new file mode 100644
index 0000000..e450338
--- /dev/null
+++ b/font_api/textures/font_api_font.png
Binary files differ
diff --git a/font_api/textures/font_api_left.png b/font_api/textures/font_api_left.png
new file mode 100644
index 0000000..727410b
--- /dev/null
+++ b/font_api/textures/font_api_left.png
Binary files differ
diff --git a/font_api/textures/font_api_right.png b/font_api/textures/font_api_right.png
new file mode 100644
index 0000000..16401d3
--- /dev/null
+++ b/font_api/textures/font_api_right.png
Binary files differ
diff --git a/signs/nodes.lua b/signs/nodes.lua
index c74ab6f..8e65e27 100644
--- a/signs/nodes.lua
+++ b/signs/nodes.lua
@@ -23,51 +23,58 @@ local F = function(...) return minetest.formspec_escape(S(...)) end
-- Poster specific formspec
local function display_poster(pos, node, player)
- local formspec
local meta = minetest.get_meta(pos)
+
local def = minetest.registered_nodes[node.name].display_entities["signs:display_text"]
local font = font_api.get_font(meta:get_string("font") or def.font_name)
+ local fs
+ local fname = string.format("%s@%s:display",
+ node.name, minetest.pos_to_string(pos))
+
-- Title texture
local titletexture = font:make_text_texture(
- meta:get_string("display_text"), font:get_height()*8.4, font:get_height(), 1, "center")
-
- formspec =
- "size[7,9]"..
- "background[0,0;7,9;signs_poster_formspec.png]"..
- "image[0,-0.2;8.4,2;"..titletexture.."]"..
- "textarea[0.3,1.5;7,8;;"..minetest.colorize("#111", minetest.formspec_escape(meta:get_string("text")))..";]"..
- "bgcolor[#0000]"
+ meta:get_string("display_text"), font:get_height()*8.4,
+ font:get_height(), 1, "center")
+
+ fs = string.format([=[
+ size[7,9]bgcolor[#0000]
+ background[0,0;7,9;signs_poster_formspec.png]
+ image[0,-0.2;8.4,2;%s]
+ textarea[0.3,1.5;7,8;;%s;]]=],
+ titletexture,
+ minetest.colorize("#111",
+ minetest.formspec_escape(meta:get_string("text"))))
if minetest.is_protected(pos, player:get_player_name()) then
- formspec = formspec..
- "button_exit[2.5,8;2,1;ok;"..F("Close").."]"
+ fs = string.format("%sbutton_exit[2.5,8;2,1;ok;%s]", fs, F("Close"))
else
- formspec = formspec..
- "button[1,8;2,1;edit;"..F("Edit").."]"..
- "button_exit[4,8;2,1;ok;"..F("Close").."]"
+ fs = string.format(
+ "%sbutton[1,8;2,1;edit;%s]button_exit[4,8;2,1;ok;%s]",
+ fs, F("Edit"), F("Close"))
end
- minetest.show_formspec(player:get_player_name(),
- node.name.."@"..minetest.pos_to_string(pos)..":display",
- formspec)
+ minetest.show_formspec(player:get_player_name(), fname, fs)
end
local function edit_poster(pos, node, player)
- local formspec
local meta = minetest.get_meta(pos)
+ local fs
+ local fname = string.format("%s@%s:edit",
+ node.name, minetest.pos_to_string(pos))
+
if not minetest.is_protected(pos, player:get_player_name()) then
- formspec =
- "size[6.5,7.5]"..
- default.gui_bg .. default.gui_bg_img .. default.gui_slots ..
- "field[0.5,0.7;6,1;display_text;"..F("Title")..";"..
- minetest.formspec_escape(meta:get_string("display_text")).."]"..
- "textarea[0.5,1.7;6,6;text;"..F("Text")..";"..
- minetest.formspec_escape(meta:get_string("text")).."]"..
- "button_exit[2.25,7;2,1;write;"..F("Write").."]"
- minetest.show_formspec(player:get_player_name(),
- node.name.."@"..minetest.pos_to_string(pos)..":edit",
- formspec)
+ fs = string.format([=[
+ size[6.5,7.5]%s%s%s
+ field[0.5,0.7;6,1;display_text;%s;%s]
+ textarea[0.5,1.7;6,6;text;%s;%s]
+ button[1.25,7;2,1;font;%s]
+ button_exit[3.25,7;2,1;write;%s]]=],
+ default.gui_bg, default.gui_bg_img, default.gui_slots, F("Title"),
+ minetest.formspec_escape(meta:get_string("display_text")),
+ F("Text"), minetest.formspec_escape(meta:get_string("text")),
+ F("Title font"), F("Write"))
+ minetest.show_formspec(player:get_player_name(), fname, fs)
end
end
@@ -80,15 +87,29 @@ local function on_receive_fields_poster(pos, formname, fields, player)
if formname == node.name.."@"..minetest.pos_to_string(pos)..":display"
and fields.edit then
edit_poster(pos, node, player)
+ return true
end
if formname == node.name.."@"..minetest.pos_to_string(pos)..":edit"
- and (fields.write or fields.key_enter) then
- meta:set_string("display_text", fields.display_text)
- meta:set_string("text", fields.text)
- meta:set_string("infotext", "\""..fields.display_text
- .."\"\n"..S("(right-click to read more text)"))
- display_api.update_entities(pos)
- display_poster(pos, node, player)
+ then
+ if (fields.write or fields.font or fields.key_enter) then
+ meta:set_string("display_text", fields.display_text)
+ meta:set_string("text", fields.text)
+ meta:set_string("infotext", "\""..fields.display_text
+ .."\"\n"..S("(right-click to read more text)"))
+ display_api.update_entities(pos)
+ end
+ if (fields.write or fields.key_enter) then
+ display_poster(pos, node, player)
+ elseif (fields.font) then
+ font_api.show_font_list(player, pos, function (playername, pos)
+ local player = minetest.get_player_by_name(playername)
+ local node = minetest.get_node(pos)
+ if player and node then
+ edit_poster(pos, node, player)
+ end
+ end)
+ end
+ return true
end
end
end
diff --git a/signs_api/init.lua b/signs_api/init.lua
index ec3b0e9..9fcaa10 100644
--- a/signs_api/init.lua
+++ b/signs_api/init.lua
@@ -35,49 +35,53 @@ function signs_api.set_display_text(pos, text, font)
else
meta:set_string("infotext", "")
end
- meta:set_string("font", font)
+ if font then
+ meta:set_string("font", font)
+ end
display_api.update_entities(pos)
end
function signs_api.set_formspec(pos)
local meta = minetest.get_meta(pos)
local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
- if ndef and ndef.display_entities
+ if ndef and ndef.display_entities
and ndef.display_entities["signs:display_text"] then
local maxlines = ndef.display_entities["signs:display_text"].maxlines
- local formspec, formheight
+ local fs, y
if maxlines == 1 then
- formspec =
- "field[0.5,0.7;5.5,1;display_text;"..F("Text")..
- ";${display_text}]"
- formheight = 2
+ fs = "field[0.5,0.7;5.5,1;display_text;"..F("Text")..
+ ";${display_text}]"
+ y = 1.2
else
local extralabel = ""
if maxlines then
extralabel = F(" (first %s lines only)"):format(maxlines)
end
- formspec =
- "textarea[0.5,0.7;5.5,2;display_text;"..F("Text")..""..
+ fs = "textarea[0.5,0.7;5.5,2;display_text;"..F("Text")..""..
extralabel..";${display_text}]"
- formheight = 3
+ y = 2.4
end
- formspec = formspec.."button_exit[2,"..formheight..";2,1;ok;"..
- F("Write").."]"
- formheight = formheight + 1
- formspec = "size[6,"..formheight.."]"..default.gui_bg..
- default.gui_bg_img..default.gui_slots..formspec
+ fs = fs.."button[1,"..y..";2,1;font;"..F("Font").."]"
+ fs = fs.."button_exit[3,"..y..";2,1;ok;"..F("Write").."]"
+ y = y + 0.8
+ fs = "size[6,"..y.."]"..default.gui_bg..
+ default.gui_bg_img..default.gui_slots..fs
- meta:set_string("formspec", formspec)
+ meta:set_string("formspec", fs)
end
end
function signs_api.on_receive_fields(pos, formname, fields, player)
if not minetest.is_protected(pos, player:get_player_name()) then
if fields and (fields.ok or fields.key_enter) then
- signs_api.set_display_text(pos, fields.display_text, fields.font)
+ signs_api.set_display_text(pos, fields.display_text)
+ end
+ if fields and (fields.font) then
+ signs_api.set_display_text(pos, fields.display_text)
+ font_api.show_font_list(player, pos)
end
end
end
@@ -183,7 +187,8 @@ function signs_api.register_sign(mod, name, model)
on_destruct = display_api.on_destruct,
on_rotate = signs_api.on_rotate,
on_receive_fields = signs_api.on_receive_fields,
- on_punch = function(pos, node, player, pointed_thing)
+ on_punch = function(pos, node, player, pointed_thing)
+ signs_api.set_formspec(pos)
display_api.update_entities(pos)
end,
}
@@ -211,7 +216,3 @@ end
-- Text entity for all signs
display_api.register_display_entity("signs:display_text")
-
-
-
-
diff --git a/steles/nodes.lua b/steles/nodes.lua
index 9b23b8d..79a9ed3 100644
--- a/steles/nodes.lua
+++ b/steles/nodes.lua
@@ -50,7 +50,7 @@ for i, material in ipairs(steles.materials) do
display_entities = {
["steles:text"] = {
on_display_update = font_api.on_display_update,
- depth = -2/16 - display_api.entity_spacing,
+ depth = -2/16 - display_api.entity_spacing,
top = -2/16,
aspect_ratio = 0.4,
size = { x = 10/16, y = 12/16 },
@@ -63,12 +63,14 @@ for i, material in ipairs(steles.materials) do
end,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
- meta:set_string("formspec", "size[6,4]"
- ..default.gui_bg .. default.gui_bg_img .. default.gui_slots
- .."textarea[0.5,0.7;5.5,2;display_text;"
- ..F("Displayed text (3 lines max)")
- ..";${display_text}]"
- .."button_exit[2,3;2,1;ok;"..F("Write").."]")
+ meta:set_string("formspec", string.format([=[
+ size[6,4]%s%s%s
+ textarea[0.5,0.7;5.5,2;display_text;%s;${display_text}]
+ button[1,3;2,1;font;%s]
+ button_exit[3,3;2,1;ok;%s]]=],
+ default.gui_bg, default.gui_bg_img, default.gui_slots,
+ F("Displayed text (3 lines max)"),
+ F("Font"), F("Write")))
display_api.on_construct(pos)
end,
on_destruct = display_api.on_destruct,
@@ -76,15 +78,17 @@ for i, material in ipairs(steles.materials) do
on_receive_fields = function(pos, formname, fields, player)
if not minetest.is_protected(pos, player:get_player_name()) then
local meta = minetest.get_meta(pos)
- if fields and fields.ok then
+ if fields.ok or fields.font then
meta:set_string("display_text", fields.display_text)
meta:set_string("infotext", "\""..fields.display_text.."\"")
display_api.update_entities(pos)
end
+ if fields.font then
+ font_api.show_font_list(player, pos)
+ end
end
end,
on_punch = display_api.update_entities,
})
end
end
-