This repository has been archived on 2020-06-22. You can view files and clone it, but cannot push or open issues or pull requests.
formspeclib/objects.lua

319 lines
9.2 KiB
Lua

--
-- formspeclib default objects
--
-- These are unprefixed, however if you create a mod that registers objects,
-- it is recommended to prefix them with your mod name to prevent conflicts.
--
--
-- Raw formspec data
--
-- Parameters: data
--
-- Example 'bgcolor[#fff;true;]':
-- {
-- type = 'formspeclib:raw_formspec',
-- data = 'bgcolor[#fff;true;]',
-- }
--
-- Using this is not recommended, and it is disabled in safe mode as it can be
-- used to crash MT clients, effectively kicking an unsuspecting victim.
--
formspeclib.register_object('formspeclib:raw_formspec', function(obj, safe_mode)
if safe_mode or type(obj.data) ~= 'string' then
return false
else
return obj.data
end
end)
--
-- A label
--
-- Parameters: x, y, align(?), text
--
-- Example 'label[1,1;Hello world!]':
-- {
-- type = 'text',
-- x = 1,
-- y = 1,
-- align = 'left',
-- text = 'Hello world!'
-- }
--
-- align can be one of 'left', 'centre'/'center', or 'vertical'. If align is
-- set to 'centre'/'center', you can also set width and height.
--
formspeclib.register_object('text', function(obj, safe_mode)
if not obj.text or not obj.x or not obj.y then return false end
if not obj.align then obj.align = 'left' end
local x = formspeclib.escape(obj.x)
local y = formspeclib.escape(obj.y)
local text = formspeclib.escape(obj.text)
if obj.align == 'left' then
return 'label[' .. x .. ',' .. y .. ';' .. text .. ']'
elseif obj.align == 'centre' or obj.align == 'center' then
-- This magical hack lets you centre/center text in formspecs.
-- Make sure your formspec ignores 'formspeclib:ignore'.
local width = formspeclib.escape(obj.width or 8)
local height = formspeclib.escape(obj.height or 0.5)
return 'image_button[' .. x .. ',' .. y .. ';' .. width .. ',' ..
height .. ';' ..
formspeclib.escape('default_dirt.png^[colorize:#343434') ..
';formspeclib:ignore;' .. text .. ']'
elseif obj.align == 'vertical' then
return 'vertlabel[' .. x .. ',' .. y .. ';' .. text .. ']'
else
return false
end
end)
--
-- An image
--
-- Parameters: x, y, width(?), height(?), image
--
-- Example 'image[1,1;1,1;default_dirt.png]':
-- {
-- type = 'image',
-- x = 1,
-- y = 1,
-- width = 1,
-- height = 1,
-- image = 'default_dirt.png'
-- }
formspeclib.register_object('image', function(obj, safe_mode)
if not obj.image or not obj.x or not obj.y then return false end
local x = formspeclib.escape(obj.x)
local y = formspeclib.escape(obj.y)
local width = formspeclib.escape(obj.width or obj.height or 1)
local height = formspeclib.escape(obj.height or obj.width or 1)
local image = formspeclib.escape(obj.image)
return 'image[' .. x .. ',' .. y .. ';' .. width .. ',' .. height .. ';' ..
image .. ']'
end)
--
-- A button
--
-- Parameters: x, y, width, height(?), name, text, quit(?), image(?)
--
-- Example 'image_button_exit[1,1;3,1;button_cancel.png;cancel;Cancel]':
-- {
-- type = 'button',
-- x = 1,
-- y = 1,
-- width = 3,
-- height = 1,
-- name = 'cancel',
-- text = 'Cancel',
-- quit = true,
-- image = 'button_cancel.png',
-- }
--
formspeclib.register_object('button', function(obj, safe_mode)
if not obj.text or not obj.x or not obj.y or not obj.width or not obj.name then
return false
end
local x = formspeclib.escape(obj.x)
local y = formspeclib.escape(obj.y)
local w = formspeclib.escape(obj.width)
local h = formspeclib.escape(obj.height or 2)
local name = formspeclib.escape(obj.name)
local text = formspeclib.escape(obj.text)
local t = 'button'
local img = ''
if obj.quit then
t = t .. '_exit'
end
if obj.image then
t = 'image_' .. t
img = ';' .. formspeclib.escape(obj.image)
if not obj.quit and not string.find(img, '.') then
t = 'item_' .. t
end
end
return t .. '[' .. x .. ',' .. y .. ';' .. w .. ',' .. h .. img .. ';' ..
name .. ';' .. text .. ']'
end)
--
-- A text box
--
-- Parameters: x, y, width, height(?), name, label(?), default(?), password(?)
--
-- Example 'textarea[1,1;2,3;message;Yay]':
-- {
-- type = 'textbox',
-- x = 1,
-- y = 1,
-- width = 2,
-- height = 3,
-- default = 'Yay',
-- name = 'message',
-- }
formspeclib.register_object('textbox', function(obj, safe_mode)
if not obj.x or not obj.y or not obj.width or not obj.name then
return false
end
local x = formspeclib.escape(obj.x)
local y = formspeclib.escape(obj.y)
local w = formspeclib.escape(obj.width)
local name = formspeclib.escape(obj.name)
local l = formspeclib.escape(obj.label or '')
local def = formspeclib.escape(obj.default or '')
local t = 'field'
local img = ''
def = ';' .. def
local h
if obj.height then
h = formspeclib.escape(obj.height)
t = 'textarea'
else
h = 2
end
if obj.password then
if obj.default or obj.height then
return false
else
t = 'pwd' .. t
def = ''
end
end
if not obj.close_on_enter and obj.close_on_enter ~= nil then
if t == 'field' then
def = def .. ']field_close_on_enter[' .. name .. ';false'
end
end
return t .. '[' .. x .. ',' .. y .. ';' .. w .. ',' .. h .. ';' .. name ..
';' .. l .. def .. ']'
end)
--
-- A combo box
--
-- Parameters: x, y, width, height(?), name, items, label(?), default(?)
--
formspeclib.register_object('combobox', function(obj, safe_mode)
if not obj.x or not obj.y or not obj.width or not obj.name or not obj.items then
return false
end
local x = formspeclib.escape(obj.x)
local y = formspeclib.escape(obj.y)
local w = formspeclib.escape(obj.width)
local name = formspeclib.escape(obj.name)
local l = formspeclib.escape(obj.label or '')
local def = formspeclib.escape(obj.default or '')
local img = ''
def = ';' .. def
local h
local t
local i
local items
for i = 1, #obj.items do
if i ~= 1 then i = i .. ';' end
items = items .. obj.items[i]
end
if obj.height then
h = formspeclib.escape(obj.height)
t = 'textlist'
else
h = 2
t = 'dropdown'
end
return t .. '[' .. x .. ',' .. y .. ';' .. w .. ',' .. h .. ';' .. name ..
';' .. l .. def .. ']'
end)
--
-- An inventory list
--
-- Parameters: location(?), name(?), x, y, width, height, start_at(?), shift_click(?)
--
formspeclib.register_object('inventory', function(obj, safe_mode)
if not obj.x or not obj.y or not obj.width or not obj.height then
return false
end
local x = formspeclib.escape(obj.x)
local y = formspeclib.escape(obj.y)
local w = formspeclib.escape(obj.width)
local h = formspeclib.escape(obj.height)
local location = formspeclib.escape(obj.location or 'current_player')
local name = formspeclib.escape(obj.name or 'main')
local start = formspeclib.escape(obj.start_at or '')
if safe_mode and location ~= 'current_player' and location ~= 'context' then
-- You are not allowed to use other locations in safe mode.
return false
end
local extra = ''
if obj.shift_click then
extra = 'listring[' .. location .. ';' .. name .. ']'
end
return 'list[' .. location .. ';' .. name .. ';' .. x .. ',' .. y .. ';' ..
w .. ',' .. h .. ';' .. start .. ']' .. extra
end)
--
-- A semitransparent box
--
-- Parameters: x, y, width, height, colour/color
--
-- Example 'box[1,1;1,1;black]':
-- {
-- type = 'image',
-- x = 1,
-- y = 1,
-- width = 1,
-- height = 1,
-- colour = 'black'
-- }
formspeclib.register_object('box', function(obj, safe_mode)
if (not obj.colour and not obj.color) or not obj.x or not obj.y then
return false
end
local x = formspeclib.escape(obj.x)
local y = formspeclib.escape(obj.y)
local width = formspeclib.escape(obj.width or obj.height or 4)
local height = formspeclib.escape(obj.height or obj.width or 4)
local colour = formspeclib.escape(obj.colour or obj.color)
return 'box[' .. x .. ',' .. y .. ';' .. width .. ',' .. height .. ';' ..
colour .. ']'
end)
--
-- A container
--
-- Parameters: x, y, children
--
-- Each element inside the container is offset by the x and y
--
formspeclib.register_object('container', function(obj, safe_mode)
local t = {
{
type = 'formspeclib:container_start',
x = formspeclib.escape(obj.x or 0),
y = formspeclib.escape(obj.y or 0),
},
(table.unpack or unpack)(obj)
}
table.insert(t, {type = 'formspeclib:container_end'})
return t
end)
formspeclib.register_object('formspeclib:container_start', function(obj, safe_mode)
if not obj.x or not obj.y then
return false
end
local x = formspeclib.escape(obj.x)
local y = formspeclib.escape(obj.y)
obj.x = nil
obj.y = nil
return 'container[' .. x .. ',' .. y .. ']'
end)
formspeclib.register_object('formspeclib:container_end', function(obj, safe_mode)
return 'container_end[]'
end)