summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Robinson <robinsonvincent89@gmail.com>2021-12-30 12:54:47 -0800
committerGitHub <noreply@github.com>2021-12-30 12:54:47 -0800
commit544b9d5c72f690d6a729053616d26e023f7e0e28 (patch)
treee549d0a2eda19c5cfd76aee5bc077b95980a80e4 /src
parent4a16ab3585dafdf4d36b2807a1ee9507be64b363 (diff)
downloadminetest-544b9d5c72f690d6a729053616d26e023f7e0e28.tar.gz
minetest-544b9d5c72f690d6a729053616d26e023f7e0e28.tar.bz2
minetest-544b9d5c72f690d6a729053616d26e023f7e0e28.zip
Add padding[] element to formspecs (#11821)
Diffstat (limited to 'src')
-rw-r--r--src/gui/guiFormSpecMenu.cpp88
-rw-r--r--src/gui/guiFormSpecMenu.h3
2 files changed, 76 insertions, 15 deletions
diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp
index dfeea12db..2cf9d9942 100644
--- a/src/gui/guiFormSpecMenu.cpp
+++ b/src/gui/guiFormSpecMenu.cpp
@@ -2470,11 +2470,16 @@ bool GUIFormSpecMenu::parsePositionDirect(parserData *data, const std::string &e
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) {
- data->offset.X = stof(parts[0]);
- data->offset.Y = stof(parts[1]);
+ if (parts.size() == 1 ||
+ (parts.size() > 1 && m_formspec_version > FORMSPEC_API_VERSION)) {
+ 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;
}
@@ -2504,11 +2509,16 @@ bool GUIFormSpecMenu::parseAnchorDirect(parserData *data, const std::string &ele
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) {
- data->anchor.X = stof(parts[0]);
- data->anchor.Y = stof(parts[1]);
+ if (parts.size() == 1 ||
+ (parts.size() > 1 && m_formspec_version > FORMSPEC_API_VERSION)) {
+ 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;
}
@@ -2516,6 +2526,46 @@ void GUIFormSpecMenu::parseAnchor(parserData *data, const std::string &element)
<< "'" << 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)
{
std::vector<std::string> parts = split(element, ';');
@@ -3022,6 +3072,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
mydata.screensize = screensize;
mydata.offset = v2f32(0.5f, 0.5f);
mydata.anchor = v2f32(0.5f, 0.5f);
+ mydata.padding = v2f32(0.05f, 0.05f);
mydata.simple_field_count = 0;
// 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;
for (; i < elements.size(); i++) {
if (elements[i].empty())
@@ -3189,11 +3247,9 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
double fitx_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(
- mydata.screensize.X * 0.9f,
- mydata.screensize.Y * 0.9f
+ mydata.screensize.X * (1.0f - mydata.padding.X * 2.0f),
+ mydata.screensize.Y * (1.0f - mydata.padding.Y * 2.0f)
);
if (mydata.real_coordinates) {
@@ -3209,13 +3265,15 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
((15.0 / 13.0) * (0.85 + mydata.invsize.Y));
}
+ s32 min_screen_dim = std::min(mydata.screensize.X, mydata.screensize.Y);
+
#ifdef HAVE_TOUCHSCREENGUI
// In Android, the preferred imgsize should be larger to accommodate the
// smaller screensize.
- double prefer_imgsize = padded_screensize.Y / 10 * gui_scaling;
+ double prefer_imgsize = min_screen_dim / 10 * gui_scaling;
#else
// 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
// Try to use the preferred imgsize, but if that's bigger than the maximum
// size, use the maximum size.
diff --git a/src/gui/guiFormSpecMenu.h b/src/gui/guiFormSpecMenu.h
index 4ba9f3959..0b4d3879d 100644
--- a/src/gui/guiFormSpecMenu.h
+++ b/src/gui/guiFormSpecMenu.h
@@ -368,6 +368,7 @@ private:
v2s32 size;
v2f32 offset;
v2f32 anchor;
+ v2f32 padding;
core::rect<s32> rect;
v2s32 basepos;
v2u32 screensize;
@@ -449,6 +450,8 @@ private:
void parsePosition(parserData *data, const std::string &element);
bool parseAnchorDirect(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);
void parseSetFocus(const std::string &element);
void parseModel(parserData *data, const std::string &element);