@@ -1706,6 +1706,74 @@ bool GUIFormSpecMenu::parseSizeDirect(parserData* data, std::string element)
1706
1706
return true ;
1707
1707
}
1708
1708
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
+
1709
1777
void GUIFormSpecMenu::parseElement (parserData* data, std::string element)
1710
1778
{
1711
1779
// some prechecks
@@ -1917,6 +1985,8 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
1917
1985
1918
1986
mydata.size = v2s32 (100 ,100 );
1919
1987
mydata.screensize = screensize;
1988
+ mydata.offset = v2f32 (0 .5f , 0 .5f );
1989
+ mydata.anchor = v2f32 (0 .5f , 0 .5f );
1920
1990
1921
1991
// Base position of contents of form
1922
1992
mydata.basepos = getBasePos ();
@@ -1983,6 +2053,21 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
1983
2053
}
1984
2054
}
1985
2055
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
+
1986
2071
if (mydata.explicit_size ) {
1987
2072
// compute scaling for specified form size
1988
2073
if (m_lock) {
@@ -2066,10 +2151,10 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
2066
2151
padding.Y *2 +spacing.Y *(mydata.invsize .Y -1.0 )+imgsize.Y + m_btn_height*2.0 /3.0
2067
2152
);
2068
2153
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
2073
2158
);
2074
2159
} else {
2075
2160
// Non-size[] form must consist only of text fields and
@@ -2078,10 +2163,10 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
2078
2163
m_font = g_fontengine->getFont ();
2079
2164
m_btn_height = font_line_height (m_font) * 0.875 ;
2080
2165
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 )
2085
2170
);
2086
2171
}
2087
2172
recalculateAbsolutePosition (false );
0 commit comments