forked from Mirrorlandia_minetest/minetest
Add padding[] element to formspecs (#11821)
This commit is contained in:
parent
4a16ab3585
commit
544b9d5c72
@ -2326,9 +2326,20 @@ Elements
|
|||||||
* `position` and `anchor` elements need suitable values to avoid a formspec
|
* `position` and `anchor` elements need suitable values to avoid a formspec
|
||||||
extending off the game window due to particular game window sizes.
|
extending off the game window due to particular game window sizes.
|
||||||
|
|
||||||
### `no_prepend[]`
|
### `padding[<X>,<Y>]`
|
||||||
|
|
||||||
* Must be used after the `size`, `position`, and `anchor` elements (if present).
|
* Must be used after the `size`, `position`, and `anchor` elements (if present).
|
||||||
|
* Defines how much space is padded around the formspec if the formspec tries to
|
||||||
|
increase past the size of the screen and coordinates have to be shrunk.
|
||||||
|
* For X and Y, 0.0 represents no padding (the formspec can touch the edge of the
|
||||||
|
screen), and 0.5 represents half the screen (which forces the coordinate size
|
||||||
|
to 0). If negative, the formspec can extend off the edge of the screen.
|
||||||
|
* Defaults to [0.05, 0.05].
|
||||||
|
|
||||||
|
### `no_prepend[]`
|
||||||
|
|
||||||
|
* Must be used after the `size`, `position`, `anchor`, and `padding` elements
|
||||||
|
(if present).
|
||||||
* Disables player:set_formspec_prepend() from applying to this formspec.
|
* Disables player:set_formspec_prepend() from applying to this formspec.
|
||||||
|
|
||||||
### `real_coordinates[<bool>]`
|
### `real_coordinates[<bool>]`
|
||||||
|
@ -270,6 +270,16 @@ local scroll_fs =
|
|||||||
--style_type[label;border=;bgcolor=]
|
--style_type[label;border=;bgcolor=]
|
||||||
--label[0.75,2;Reset]
|
--label[0.75,2;Reset]
|
||||||
|
|
||||||
|
local window = {
|
||||||
|
sizex = 12,
|
||||||
|
sizey = 13,
|
||||||
|
positionx = 0.5,
|
||||||
|
positiony = 0.5,
|
||||||
|
anchorx = 0.5,
|
||||||
|
anchory = 0.5,
|
||||||
|
paddingx = 0.05,
|
||||||
|
paddingy = 0.05
|
||||||
|
}
|
||||||
|
|
||||||
local pages = {
|
local pages = {
|
||||||
-- Real Coordinates
|
-- Real Coordinates
|
||||||
@ -341,9 +351,28 @@ local pages = {
|
|||||||
"size[12,13]real_coordinates[true]" ..
|
"size[12,13]real_coordinates[true]" ..
|
||||||
"container[0.5,1.5]" .. tabheaders_fs .. "container_end[]",
|
"container[0.5,1.5]" .. tabheaders_fs .. "container_end[]",
|
||||||
|
|
||||||
-- Inv
|
-- Inv
|
||||||
"size[12,13]real_coordinates[true]" .. inv_style_fs,
|
"size[12,13]real_coordinates[true]" .. inv_style_fs,
|
||||||
|
|
||||||
|
-- Window
|
||||||
|
function()
|
||||||
|
return "formspec_version[3]" ..
|
||||||
|
string.format("size[%s,%s]position[%s,%s]anchor[%s,%s]padding[%s,%s]",
|
||||||
|
window.sizex, window.sizey, window.positionx, window.positiony,
|
||||||
|
window.anchorx, window.anchory, window.paddingx, window.paddingy) ..
|
||||||
|
string.format("field[0.5,0.5;2.5,0.5;sizex;X Size;%s]field[3.5,0.5;2.5,0.5;sizey;Y Size;%s]" ..
|
||||||
|
"field[0.5,1.5;2.5,0.5;positionx;X Position;%s]field[3.5,1.5;2.5,0.5;positiony;Y Position;%s]" ..
|
||||||
|
"field[0.5,2.5;2.5,0.5;anchorx;X Anchor;%s]field[3.5,2.5;2.5,0.5;anchory;Y Anchor;%s]" ..
|
||||||
|
"field[0.5,3.5;2.5,0.5;paddingx;X Padding;%s]field[3.5,3.5;2.5,0.5;paddingy;Y Padding;%s]" ..
|
||||||
|
"button[2,4.5;2.5,0.5;submit_window;Submit]",
|
||||||
|
window.sizex, window.sizey, window.positionx, window.positiony,
|
||||||
|
window.anchorx, window.anchory, window.paddingx, window.paddingy) ..
|
||||||
|
"field_close_on_enter[sizex;false]field_close_on_enter[sizey;false]" ..
|
||||||
|
"field_close_on_enter[positionx;false]field_close_on_enter[positiony;false]" ..
|
||||||
|
"field_close_on_enter[anchorx;false]field_close_on_enter[anchory;false]" ..
|
||||||
|
"field_close_on_enter[paddingx;false]field_close_on_enter[paddingy;false]"
|
||||||
|
end,
|
||||||
|
|
||||||
-- Animation
|
-- Animation
|
||||||
[[
|
[[
|
||||||
formspec_version[3]
|
formspec_version[3]
|
||||||
@ -403,10 +432,14 @@ mouse control = true]
|
|||||||
]],
|
]],
|
||||||
}
|
}
|
||||||
|
|
||||||
local function show_test_formspec(pname, page_id)
|
local page_id = 2
|
||||||
page_id = page_id or 2
|
local function show_test_formspec(pname)
|
||||||
|
local page = pages[page_id]
|
||||||
|
if type(page) == "function" then
|
||||||
|
page = page()
|
||||||
|
end
|
||||||
|
|
||||||
local fs = pages[page_id] .. "tabheader[0,0;8,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Anim,Model,ScrollC,Sound;" .. page_id .. ";false;false]"
|
local fs = page .. "tabheader[0,0;8,0.65;maintabs;Real Coord,Styles,Noclip,Hypertext,Tabs,Invs,Window,Anim,Model,ScrollC,Sound;" .. page_id .. ";false;false]"
|
||||||
|
|
||||||
minetest.show_formspec(pname, "testformspec:formspec", fs)
|
minetest.show_formspec(pname, "testformspec:formspec", fs)
|
||||||
end
|
end
|
||||||
@ -416,9 +449,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if fields.maintabs then
|
if fields.maintabs then
|
||||||
show_test_formspec(player:get_player_name(), tonumber(fields.maintabs))
|
page_id = tonumber(fields.maintabs)
|
||||||
|
show_test_formspec(player:get_player_name())
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -434,6 +467,26 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
minetest.chat_send_player(player:get_player_name(), "Hypertext action received: " .. tostring(fields.hypertext))
|
minetest.chat_send_player(player:get_player_name(), "Hypertext action received: " .. tostring(fields.hypertext))
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for name, value in pairs(fields) do
|
||||||
|
if window[name] then
|
||||||
|
print(name, window[name])
|
||||||
|
local num_val = tonumber(value) or 0
|
||||||
|
|
||||||
|
if name == "sizex" and num_val < 4 then
|
||||||
|
num_val = 6.5
|
||||||
|
elseif name == "sizey" and num_val < 5 then
|
||||||
|
num_val = 5.5
|
||||||
|
end
|
||||||
|
|
||||||
|
window[name] = num_val
|
||||||
|
print(name, window[name])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.submit_window then
|
||||||
|
show_test_formspec(player:get_player_name())
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_chatcommand("test_formspec", {
|
minetest.register_chatcommand("test_formspec", {
|
||||||
|
@ -2470,11 +2470,16 @@ bool GUIFormSpecMenu::parsePositionDirect(parserData *data, const std::string &e
|
|||||||
|
|
||||||
void GUIFormSpecMenu::parsePosition(parserData *data, const std::string &element)
|
void GUIFormSpecMenu::parsePosition(parserData *data, const std::string &element)
|
||||||
{
|
{
|
||||||
std::vector<std::string> parts = split(element, ',');
|
std::vector<std::string> parts = split(element, ';');
|
||||||
|
|
||||||
if (parts.size() == 2) {
|
if (parts.size() == 1 ||
|
||||||
data->offset.X = stof(parts[0]);
|
(parts.size() > 1 && m_formspec_version > FORMSPEC_API_VERSION)) {
|
||||||
data->offset.Y = stof(parts[1]);
|
std::vector<std::string> v_geom = split(parts[0], ',');
|
||||||
|
|
||||||
|
MY_CHECKGEOM("position", 0);
|
||||||
|
|
||||||
|
data->offset.X = stof(v_geom[0]);
|
||||||
|
data->offset.Y = stof(v_geom[1]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2504,11 +2509,16 @@ bool GUIFormSpecMenu::parseAnchorDirect(parserData *data, const std::string &ele
|
|||||||
|
|
||||||
void GUIFormSpecMenu::parseAnchor(parserData *data, const std::string &element)
|
void GUIFormSpecMenu::parseAnchor(parserData *data, const std::string &element)
|
||||||
{
|
{
|
||||||
std::vector<std::string> parts = split(element, ',');
|
std::vector<std::string> parts = split(element, ';');
|
||||||
|
|
||||||
if (parts.size() == 2) {
|
if (parts.size() == 1 ||
|
||||||
data->anchor.X = stof(parts[0]);
|
(parts.size() > 1 && m_formspec_version > FORMSPEC_API_VERSION)) {
|
||||||
data->anchor.Y = stof(parts[1]);
|
std::vector<std::string> v_geom = split(parts[0], ',');
|
||||||
|
|
||||||
|
MY_CHECKGEOM("anchor", 0);
|
||||||
|
|
||||||
|
data->anchor.X = stof(v_geom[0]);
|
||||||
|
data->anchor.Y = stof(v_geom[1]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2516,6 +2526,46 @@ void GUIFormSpecMenu::parseAnchor(parserData *data, const std::string &element)
|
|||||||
<< "'" << std::endl;
|
<< "'" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GUIFormSpecMenu::parsePaddingDirect(parserData *data, const std::string &element)
|
||||||
|
{
|
||||||
|
if (element.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::vector<std::string> parts = split(element, '[');
|
||||||
|
|
||||||
|
if (parts.size() != 2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::string type = trim(parts[0]);
|
||||||
|
std::string description = trim(parts[1]);
|
||||||
|
|
||||||
|
if (type != "padding")
|
||||||
|
return false;
|
||||||
|
|
||||||
|
parsePadding(data, description);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GUIFormSpecMenu::parsePadding(parserData *data, const std::string &element)
|
||||||
|
{
|
||||||
|
std::vector<std::string> parts = split(element, ';');
|
||||||
|
|
||||||
|
if (parts.size() == 1 ||
|
||||||
|
(parts.size() > 1 && m_formspec_version > FORMSPEC_API_VERSION)) {
|
||||||
|
std::vector<std::string> v_geom = split(parts[0], ',');
|
||||||
|
|
||||||
|
MY_CHECKGEOM("padding", 0);
|
||||||
|
|
||||||
|
data->padding.X = stof(v_geom[0]);
|
||||||
|
data->padding.Y = stof(v_geom[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
errorstream << "Invalid padding element (" << parts.size() << "): '" << element
|
||||||
|
<< "'" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
bool GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element, bool style_type)
|
bool GUIFormSpecMenu::parseStyle(parserData *data, const std::string &element, bool style_type)
|
||||||
{
|
{
|
||||||
std::vector<std::string> parts = split(element, ';');
|
std::vector<std::string> parts = split(element, ';');
|
||||||
@ -3022,6 +3072,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
|||||||
mydata.screensize = screensize;
|
mydata.screensize = screensize;
|
||||||
mydata.offset = v2f32(0.5f, 0.5f);
|
mydata.offset = v2f32(0.5f, 0.5f);
|
||||||
mydata.anchor = v2f32(0.5f, 0.5f);
|
mydata.anchor = v2f32(0.5f, 0.5f);
|
||||||
|
mydata.padding = v2f32(0.05f, 0.05f);
|
||||||
mydata.simple_field_count = 0;
|
mydata.simple_field_count = 0;
|
||||||
|
|
||||||
// Base position of contents of form
|
// Base position of contents of form
|
||||||
@ -3124,7 +3175,14 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "no_prepend" element is always after "position" (or "size" element) if it used */
|
/* "padding" element is always after "anchor" and previous if it is used */
|
||||||
|
for (; i < elements.size(); i++) {
|
||||||
|
if (!parsePaddingDirect(&mydata, elements[i])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "no_prepend" element is always after "padding" and previous if it used */
|
||||||
bool enable_prepends = true;
|
bool enable_prepends = true;
|
||||||
for (; i < elements.size(); i++) {
|
for (; i < elements.size(); i++) {
|
||||||
if (elements[i].empty())
|
if (elements[i].empty())
|
||||||
@ -3189,11 +3247,9 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
|||||||
double fitx_imgsize;
|
double fitx_imgsize;
|
||||||
double fity_imgsize;
|
double fity_imgsize;
|
||||||
|
|
||||||
// Pad the screensize with 5% of the screensize on all sides to ensure
|
|
||||||
// that even the largest formspecs don't touch the screen borders.
|
|
||||||
v2f padded_screensize(
|
v2f padded_screensize(
|
||||||
mydata.screensize.X * 0.9f,
|
mydata.screensize.X * (1.0f - mydata.padding.X * 2.0f),
|
||||||
mydata.screensize.Y * 0.9f
|
mydata.screensize.Y * (1.0f - mydata.padding.Y * 2.0f)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (mydata.real_coordinates) {
|
if (mydata.real_coordinates) {
|
||||||
@ -3209,13 +3265,15 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
|||||||
((15.0 / 13.0) * (0.85 + mydata.invsize.Y));
|
((15.0 / 13.0) * (0.85 + mydata.invsize.Y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 min_screen_dim = std::min(mydata.screensize.X, mydata.screensize.Y);
|
||||||
|
|
||||||
#ifdef HAVE_TOUCHSCREENGUI
|
#ifdef HAVE_TOUCHSCREENGUI
|
||||||
// In Android, the preferred imgsize should be larger to accommodate the
|
// In Android, the preferred imgsize should be larger to accommodate the
|
||||||
// smaller screensize.
|
// smaller screensize.
|
||||||
double prefer_imgsize = padded_screensize.Y / 10 * gui_scaling;
|
double prefer_imgsize = min_screen_dim / 10 * gui_scaling;
|
||||||
#else
|
#else
|
||||||
// Desktop computers have more space, so try to fit 15 coordinates.
|
// Desktop computers have more space, so try to fit 15 coordinates.
|
||||||
double prefer_imgsize = padded_screensize.Y / 15 * gui_scaling;
|
double prefer_imgsize = min_screen_dim / 15 * gui_scaling;
|
||||||
#endif
|
#endif
|
||||||
// Try to use the preferred imgsize, but if that's bigger than the maximum
|
// Try to use the preferred imgsize, but if that's bigger than the maximum
|
||||||
// size, use the maximum size.
|
// size, use the maximum size.
|
||||||
|
@ -368,6 +368,7 @@ private:
|
|||||||
v2s32 size;
|
v2s32 size;
|
||||||
v2f32 offset;
|
v2f32 offset;
|
||||||
v2f32 anchor;
|
v2f32 anchor;
|
||||||
|
v2f32 padding;
|
||||||
core::rect<s32> rect;
|
core::rect<s32> rect;
|
||||||
v2s32 basepos;
|
v2s32 basepos;
|
||||||
v2u32 screensize;
|
v2u32 screensize;
|
||||||
@ -449,6 +450,8 @@ private:
|
|||||||
void parsePosition(parserData *data, const std::string &element);
|
void parsePosition(parserData *data, const std::string &element);
|
||||||
bool parseAnchorDirect(parserData *data, const std::string &element);
|
bool parseAnchorDirect(parserData *data, const std::string &element);
|
||||||
void parseAnchor(parserData *data, const std::string &element);
|
void parseAnchor(parserData *data, const std::string &element);
|
||||||
|
bool parsePaddingDirect(parserData *data, const std::string &element);
|
||||||
|
void parsePadding(parserData *data, const std::string &element);
|
||||||
bool parseStyle(parserData *data, const std::string &element, bool style_type);
|
bool parseStyle(parserData *data, const std::string &element, bool style_type);
|
||||||
void parseSetFocus(const std::string &element);
|
void parseSetFocus(const std::string &element);
|
||||||
void parseModel(parserData *data, const std::string &element);
|
void parseModel(parserData *data, const std::string &element);
|
||||||
|
Loading…
Reference in New Issue
Block a user