mtimer/system/formspec_helpers.lua

196 lines
7.8 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- # vim: nowrap
--
-- Set Vim to no-wrapping mode because of some lines not fitting within the 80
-- characters width limit due to overall readability of the code.
-- Localise needed functions
local m = mtimer
local S = m.translator
local esc = minetest.formspec_escape
-- Get a button with icon
--
-- This function returns a fully formatted button with icon.
--
-- The provided ID is set as the buttons ID as well as the buttons image.
-- When set as image all colons are replaced with underscores and the id then
-- is formatted: `mtimer_ID.png` where `ID` is the given ID.
--
-- The definition table sets up the buttons parameters and is fully optional
-- even if it makes no sense.
--
-- definition = {
-- label = 'My Cool Button label' or '',
-- width = 5, or 3,
-- image_size = 1, or 0,5,
-- container = { left = 1, top = 1} or pos_container
-- exit_button = true or false
-- }
--
-- The container table is used to position the button. If the `container` sub
-- table is unset, the following table is used, causing the button to be in the
-- top left corner of the formspec if not contained in another container.
--
-- pos_container = {
-- left = 0
-- top = 0
-- }
--
-- @param id The ID for the button
-- @param definition The definition table as described
-- @return string The created button as formspec code
mtimer.get_icon_button = function (id, definition)
local def = definition or {}
-- Set button defaults
local b_width = def.width or 3
local i_size = def.image_size or 0.5
local c_left = (def.container or {}).left or 0
local c_top = (def.container or {}).top or 0
-- Calculate button parameters
local b_padding = i_size / 4
local b_height = (b_padding * 2) + i_size
local l_top_pos = i_size / 2
local l_left_pos = i_size + (i_size / 4)
-- Create/Return the button
return (table.concat({
'container[+containerLeft,+containerTop]',
' container[+buttonPadding,+buttonPadding]',
' image[0,0;+imageSize,+imageSize;+icon]',
' label[+labelLeftPos,+labelTopPos;+label]',
' container_end[]',
' +buttonType[0,0;+buttonWidth,+buttonHeight;+id;]',
'container_end[]'
}, ' '):gsub('%+%w+', {
['+containerLeft'] = c_left,
['+containerTop'] = c_top,
['+buttonType'] = def.exit_button == true and 'button_exit' or 'button',
['+buttonWidth'] = b_width,
['+buttonHeight'] = b_height,
['+buttonPadding'] = b_padding,
['+imageSize'] = i_size,
['+icon'] = 'mtimer_'..id:gsub(':', '_')..'.png',
['+labelLeftPos'] = l_left_pos,
['+labelTopPos'] = l_top_pos,
['+id'] = id,
['+label'] = esc(def.label or '')
}))
end
-- Build the formspec frame
--
-- This function builds and displays a formspec based on the input.
--
-- The `id` is the usual formspec ID (for example `mymod:my_formspec`) and
-- has to be provided as a simple string all other parameters are provided via
-- the `def` table. The following table is an example.
--
-- {
-- title = 'Nice Title' -- Automatically prefixed for orientation
-- prefix = '[Blarb] ' -- Optional title prefix
-- width = 8, -- Optional width of the content container
-- height = 3, -- Optional height of the content container
-- show_to = 'Playername' -- Name of the player to show the formspec to
-- add_buttons = false -- Optionally hide buttons
-- content_offset = 0 -- Optionally Offset content height position
-- formspec = {} -- Table with formspec definition
-- }
--
-- When set the title is prefixed with the prefix value. If omitted “[mTimer] ”
-- is used. The example creates “[Blarb] Nice Title” as title. Translated
-- strings can be used here. The Title and prefix are “formspec-safe” so
-- strings that are formspec elements can be used to show them literal.
--
-- The default buttons can be hidden by adding `add_buttons = false` to the
-- definition table. If omitted the buttons are shown. When not shown the
-- formspec size will be reduced by the amout of units the buttons would
-- have taken place.
--
-- Some formspec elements do not properly start at 0,0 even if set so. The
-- `content_offset` attribute offsets the content vertically by the given
-- amount of units. Formspec height and button positions are fixed according
-- to the given value.
--
-- The table entries for `formspec` are the usual formspec elements that
-- define what a formspec looks like. You can write all definition in one entry
-- or split the definition into multiple entries.
--
-- The definition defines the CONTENT of the formspec not the whole formspec so
-- you can easily start at 0,0 for your definition. The function automatically
-- places everything in relation to the formspec frame and default buttons.
--
-- The minimum formspec width and height are 9 units in width and 4 units in
-- height. So `width` and `height` can be omitted when all of your content fits
-- into the default size. The resulting formspec is a minimum of 9 units wide
-- and 5.85 units high (1.85 units are added for the title and the buttons).
--
-- All formspec table entries can contain the following variables. Variables
-- start with a plus sign (+) and are read until any character that is not
-- a letter. Some variables are useless, some can be used quite well.
--
-- Variable Name Value Type
-- --------------------------------------------------------------------------
-- +title formspecs title
-- +width width of the formspec
-- +height height of the formspec
-- +contentWidth optimal width for the content
-- +contentPosition content container vertical position (+offset)
-- +buttons default buttons vertical position
--
-- @param id The ID of the formspec
-- @param def The definition table as described
-- @return string the constructed “frame”
mtimer.show_formspec = function (id, def)
local add_buttons = def.add_buttons == true or def.add_buttons == nil
local content_offset = def.content_offset or 0
local width = (def.width or 0) <= 10 and 10 or def.width
local height = (def.height or 0) <= 4 and 5.85 or def.height + 1.85
local prefix = def.prefix or '[mTimer] '
-- Calculate height
if not add_buttons then height = height - 1.85 end
height = height + content_offset
-- Set up buttons
local buttons = not add_buttons and '' or table.concat({
'container[0.25,+buttons]',
' box[0,0;+contentWidth,0.04;#ffffff]',
mtimer.get_icon_button('main_menu', { label = S('Main Menu'), width = 2.5, container = { top = 0.25 } }),
' container[+contentWidth,0.25]',
mtimer.get_icon_button('exit', { label = S('Exit'), exit_button = true, width = 2.5, container = { left = -2.5 } }),
mtimer.get_icon_button('default', { label = S('Default'), width = 2.5, container = { left = -5.25 } }),
' container_end[]',
'container_end[]'
}, ' ')
-- Build formspec
local formspec = table.concat({
'formspec_version[2]',
'size[+width,+height]',
'image[0.25,0.2;0.3,0.3;+icon]',
'label[0.65,0.35;+title]',
'box[0.25,0.6;+contentWidth,0.04;#ffffff]',
'container[0.25,+contentPosition]',
table.concat(def.formspec, ' '),
'container_end[]',
buttons
}, ' '):gsub('%+%a+', {
['+width'] = width+0.25,
['+height'] = height,
['+contentWidth'] = width-0.25,
['+title'] = minetest.formspec_escape(prefix..def.title),
['+icon'] = 'mtimer_'..id:gsub('mtimer:', '')..'.png',
['+contentPosition'] = 0.9 + content_offset,
['+buttons'] = height-1.25,
})
-- Show formspec to the plauyer
minetest.show_formspec(def.show_to, id, formspec)
end