ui nodes 'gravity' write-only property

This commit is contained in:
MihailRis
2024-03-06 13:36:31 +03:00
parent 7601bfad3a
commit eba8332b75
5 changed files with 142 additions and 51 deletions
+47
View File
@@ -190,3 +190,50 @@ void UINode::reposition() {
setPos(positionfunc());
}
}
void UINode::setGravity(Gravity gravity) {
if (gravity == Gravity::none) {
setPositionFunc(nullptr);
return;
}
setPositionFunc([this, gravity](){
auto parent = getParent();
if (parent == nullptr) {
return getPos();
}
glm::vec4 margin = getMargin();
glm::vec2 size = getSize();
glm::vec2 parentSize = parent->getSize();
float x = 0.0f, y = 0.0f;
switch (gravity) {
case Gravity::top_left:
case Gravity::center_left:
case Gravity::bottom_left: x = parentSize.x+margin.x; break;
case Gravity::top_center:
case Gravity::center_center:
case Gravity::bottom_center: x = (parentSize.x-size.x)/2.0f; break;
case Gravity::top_right:
case Gravity::center_right:
case Gravity::bottom_right: x = parentSize.x-size.x-margin.z; break;
default: break;
}
switch (gravity) {
case Gravity::top_left:
case Gravity::top_center:
case Gravity::top_right: y = parentSize.y+margin.y; break;
case Gravity::center_left:
case Gravity::center_center:
case Gravity::center_right: y = (parentSize.y-size.y)/2.0f; break;
case Gravity::bottom_left:
case Gravity::bottom_center:
case Gravity::bottom_right: y = parentSize.y-size.y-margin.w; break;
default: break;
}
return glm::vec2(x, y);
});
if (parent) {
reposition();
}
}
+18
View File
@@ -24,6 +24,22 @@ namespace gui {
top=left, bottom=right,
};
enum class Gravity {
none,
top_left,
top_center,
top_right,
center_left,
center_center,
center_right,
bottom_left,
bottom_center,
bottom_right
};
/// @brief Base abstract class for all UI elements
class UINode {
/// @brief element identifier used for direct access in UiDocument
@@ -161,6 +177,8 @@ namespace gui {
/* Fetch pos from positionfunc if assigned */
void reposition();
virtual void setGravity(Gravity gravity);
};
}
+25
View File
@@ -22,6 +22,25 @@ static Align align_from_string(const std::string& str, Align def) {
return def;
}
static Gravity gravity_from_string(const std::string& str) {
static const std::unordered_map<std::string, Gravity> gravity_names {
{"top-left", Gravity::top_left},
{"top-center", Gravity::top_center},
{"top-right", Gravity::top_right},
{"center-left", Gravity::center_left},
{"center-center", Gravity::center_center},
{"center-right", Gravity::center_right},
{"bottom-left", Gravity::bottom_left},
{"bottom-center", Gravity::bottom_center},
{"bottom-right", Gravity::bottom_right},
};
auto found = gravity_names.find(str);
if (found == gravity_names.end()) {
return found->second;
}
return Gravity::none;
}
/* Read basic UINode properties */
static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& node) {
if (element->has("id")) {
@@ -67,6 +86,12 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no
}
std::string alignName = element->attr("align", "").getText();
node.setAlign(align_from_string(alignName, node.getAlign()));
if (element->has("gravity")) {
node.setGravity(gravity_from_string(
element->attr("gravity").getText()
));
}
}