Skip to content

Commit 6de83a2

Browse files
adelcoding1nerzhul
authored andcommittedMar 4, 2017
FormSpec: Add position and anchor elements (#5284)
1 parent 22df959 commit 6de83a2

File tree

3 files changed

+109
-8
lines changed

3 files changed

+109
-8
lines changed
 

Diff for: ‎doc/lua_api.txt

+10
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,16 @@ examples.
15221522
* `fixed_size`: `true`/`false` (optional)
15231523
* deprecated: `invsize[<W>,<H>;]`
15241524

1525+
#### `position[<X>,<Y>]`
1526+
* Define the position of the formspec
1527+
* A value between 0.0 and 1.0 represents a position inside the screen
1528+
* The default value is the center of the screen (0.5, 0.5)
1529+
1530+
#### `anchor[<X>,<Y>]`
1531+
* Define the anchor of the formspec
1532+
* A value between 0.0 and 1.0 represents an anchor inside the formspec
1533+
* The default value is the center of the formspec (0.5, 0.5)
1534+
15251535
#### `container[<X>,<Y>]`
15261536
* Start of a container block, moves all physical elements in the container by (X, Y)
15271537
* Must have matching container_end

Diff for: ‎src/guiFormSpecMenu.cpp

+93-8
Original file line numberDiff line numberDiff line change
@@ -1706,6 +1706,74 @@ bool GUIFormSpecMenu::parseSizeDirect(parserData* data, std::string element)
17061706
return true;
17071707
}
17081708

1709+
bool GUIFormSpecMenu::parsePositionDirect(parserData *data, const std::string &element)
1710+
{
1711+
if (element.empty())
1712+
return false;
1713+
1714+
std::vector<std::string> parts = split(element, '[');
1715+
1716+
if (parts.size() != 2)
1717+
return false;
1718+
1719+
std::string type = trim(parts[0]);
1720+
std::string description = trim(parts[1]);
1721+
1722+
if (type != "position")
1723+
return false;
1724+
1725+
parsePosition(data, description);
1726+
1727+
return true;
1728+
}
1729+
1730+
void GUIFormSpecMenu::parsePosition(parserData *data, const std::string &element)
1731+
{
1732+
std::vector<std::string> parts = split(element, ',');
1733+
1734+
if (parts.size() == 2) {
1735+
data->offset.X = stof(parts[0]);
1736+
data->offset.Y = stof(parts[1]);
1737+
return;
1738+
}
1739+
1740+
errorstream << "Invalid position element (" << parts.size() << "): '" << element << "'" << std::endl;
1741+
}
1742+
1743+
bool GUIFormSpecMenu::parseAnchorDirect(parserData *data, const std::string &element)
1744+
{
1745+
if (element.empty())
1746+
return false;
1747+
1748+
std::vector<std::string> parts = split(element, '[');
1749+
1750+
if (parts.size() != 2)
1751+
return false;
1752+
1753+
std::string type = trim(parts[0]);
1754+
std::string description = trim(parts[1]);
1755+
1756+
if (type != "anchor")
1757+
return false;
1758+
1759+
parseAnchor(data, description);
1760+
1761+
return true;
1762+
}
1763+
1764+
void GUIFormSpecMenu::parseAnchor(parserData *data, const std::string &element)
1765+
{
1766+
std::vector<std::string> parts = split(element, ',');
1767+
1768+
if (parts.size() == 2) {
1769+
data->anchor.X = stof(parts[0]);
1770+
data->anchor.Y = stof(parts[1]);
1771+
return;
1772+
}
1773+
1774+
errorstream << "Invalid anchor element (" << parts.size() << "): '" << element << "'" << std::endl;
1775+
}
1776+
17091777
void GUIFormSpecMenu::parseElement(parserData* data, std::string element)
17101778
{
17111779
//some prechecks
@@ -1917,6 +1985,8 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
19171985

19181986
mydata.size= v2s32(100,100);
19191987
mydata.screensize = screensize;
1988+
mydata.offset = v2f32(0.5f, 0.5f);
1989+
mydata.anchor = v2f32(0.5f, 0.5f);
19201990

19211991
// Base position of contents of form
19221992
mydata.basepos = getBasePos();
@@ -1983,6 +2053,21 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
19832053
}
19842054
}
19852055

2056+
/* "position" element is always after "size" element if it used */
2057+
for (; i< elements.size(); i++) {
2058+
if (!parsePositionDirect(&mydata, elements[i])) {
2059+
break;
2060+
}
2061+
}
2062+
2063+
/* "anchor" element is always after "position" (or "size" element) if it used */
2064+
for (; i< elements.size(); i++) {
2065+
if (!parseAnchorDirect(&mydata, elements[i])) {
2066+
break;
2067+
}
2068+
}
2069+
2070+
19862071
if (mydata.explicit_size) {
19872072
// compute scaling for specified form size
19882073
if (m_lock) {
@@ -2066,10 +2151,10 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
20662151
padding.Y*2+spacing.Y*(mydata.invsize.Y-1.0)+imgsize.Y + m_btn_height*2.0/3.0
20672152
);
20682153
DesiredRect = mydata.rect = core::rect<s32>(
2069-
mydata.screensize.X/2 - mydata.size.X/2 + offset.X,
2070-
mydata.screensize.Y/2 - mydata.size.Y/2 + offset.Y,
2071-
mydata.screensize.X/2 + mydata.size.X/2 + offset.X,
2072-
mydata.screensize.Y/2 + mydata.size.Y/2 + offset.Y
2154+
(s32)((f32)mydata.screensize.X * mydata.offset.X) - (s32)(mydata.anchor.X * (f32)mydata.size.X) + offset.X,
2155+
(s32)((f32)mydata.screensize.Y * mydata.offset.Y) - (s32)(mydata.anchor.Y * (f32)mydata.size.Y) + offset.Y,
2156+
(s32)((f32)mydata.screensize.X * mydata.offset.X) + (s32)((1.0 - mydata.anchor.X) * (f32)mydata.size.X) + offset.X,
2157+
(s32)((f32)mydata.screensize.Y * mydata.offset.Y) + (s32)((1.0 - mydata.anchor.Y) * (f32)mydata.size.Y) + offset.Y
20732158
);
20742159
} else {
20752160
// Non-size[] form must consist only of text fields and
@@ -2078,10 +2163,10 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
20782163
m_font = g_fontengine->getFont();
20792164
m_btn_height = font_line_height(m_font) * 0.875;
20802165
DesiredRect = core::rect<s32>(
2081-
mydata.screensize.X/2 - 580/2,
2082-
mydata.screensize.Y/2 - 300/2,
2083-
mydata.screensize.X/2 + 580/2,
2084-
mydata.screensize.Y/2 + 300/2
2166+
(s32)((f32)mydata.screensize.X * mydata.offset.X) - (s32)(mydata.anchor.X * 580.0),
2167+
(s32)((f32)mydata.screensize.Y * mydata.offset.Y) - (s32)(mydata.anchor.Y * 300.0),
2168+
(s32)((f32)mydata.screensize.X * mydata.offset.X) + (s32)((1.0 - mydata.anchor.X) * 580.0),
2169+
(s32)((f32)mydata.screensize.Y * mydata.offset.Y) + (s32)((1.0 - mydata.anchor.Y) * 300.0)
20852170
);
20862171
}
20872172
recalculateAbsolutePosition(false);

Diff for: ‎src/guiFormSpecMenu.h

+6
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ class GUIFormSpecMenu : public GUIModalMenu
447447
bool explicit_size;
448448
v2f invsize;
449449
v2s32 size;
450+
v2f32 offset;
451+
v2f32 anchor;
450452
core::rect<s32> rect;
451453
v2s32 basepos;
452454
v2u32 screensize;
@@ -502,6 +504,10 @@ class GUIFormSpecMenu : public GUIModalMenu
502504
bool parseVersionDirect(std::string data);
503505
bool parseSizeDirect(parserData* data, std::string element);
504506
void parseScrollBar(parserData* data, std::string element);
507+
bool parsePositionDirect(parserData *data, const std::string &element);
508+
void parsePosition(parserData *data, const std::string &element);
509+
bool parseAnchorDirect(parserData *data, const std::string &element);
510+
void parseAnchor(parserData *data, const std::string &element);
505511

506512
void tryClose();
507513

0 commit comments

Comments
 (0)
Please sign in to comment.