lxgui
Loading...
Searching...
No Matches
gui_region_parser.cpp
1#include "lxgui/gui_anchor.hpp"
2#include "lxgui/gui_color.hpp"
3#include "lxgui/gui_layout_node.hpp"
4#include "lxgui/gui_out.hpp"
5#include "lxgui/gui_region.hpp"
6#include "lxgui/utils_std.hpp"
7
8namespace lxgui::gui {
9
11 if (const auto attr = node.try_get_attribute_value<std::string>("c")) {
12 const std::string& s = attr.value();
13 if (!s.empty() && s[0] == '#')
14 return color(s);
15 }
16
17 return color(
18 node.get_attribute_value_or<float>("r", 0.0f),
19 node.get_attribute_value_or<float>("g", 0.0f),
20 node.get_attribute_value_or<float>("b", 0.0f),
21 node.get_attribute_value_or<float>("a", 1.0f));
22}
23
27
29 return {
30 node.get_attribute_value_or<float>("x", fallback),
31 node.get_attribute_value_or<float>("y", fallback)};
32}
33
34std::pair<anchor_type, vector2<std::optional<float>>>
36 const layout_node* abs_dim_node = node.try_get_child("AbsDimension");
37 const layout_node* rel_dim_node = node.try_get_child("RelDimension");
38
39 if (abs_dim_node && rel_dim_node) {
40 gui::out << gui::warning << node.get_location() << ": " << node.get_name()
41 << " node can only contain one of AbsDimension or RelDimension, but not both. "
42 "RelDimension ignored."
43 << std::endl;
44 }
45
46 if (!abs_dim_node && !rel_dim_node) {
47 gui::out << gui::warning << node.get_location() << ": " << node.get_name()
48 << " node must contain one of AbsDimension or RelDimension." << std::endl;
49 return {};
50 }
51
53 const layout_node* chosen_node = nullptr;
54 if (abs_dim_node) {
55 type = anchor_type::abs;
56 chosen_node = abs_dim_node;
57 } else {
58 type = anchor_type::rel;
59 chosen_node = rel_dim_node;
60 }
61
62 return std::make_pair(type, parse_offset_node_(*chosen_node));
63}
64
66 if (const layout_node* size_block = node.try_get_child("Size")) {
67 auto dimensions = parse_dimension_node_(*size_block);
68 bool has_x = dimensions.second.x.has_value();
69 bool has_y = dimensions.second.y.has_value();
70 if (dimensions.first == anchor_type::abs) {
71 if (has_x && has_y) {
72 set_dimensions(vector2f(dimensions.second.x.value(), dimensions.second.y.value()));
73 } else if (has_x)
74 set_width(dimensions.second.x.value());
75 else if (has_y)
76 set_height(dimensions.second.y.value());
77 } else {
78 if (has_x && has_y) {
80 vector2f(dimensions.second.x.value(), dimensions.second.y.value()));
81 } else if (has_x)
82 set_relative_width(dimensions.second.x.value());
83 else if (has_y)
84 set_relative_height(dimensions.second.y.value());
85 }
86 }
87}
88
90 if (const layout_node* anchors_node = node.try_get_child("Anchors")) {
91 std::vector<point> found_points;
92 for (const auto& anchor_node : anchors_node->get_children()) {
93 if (anchor_node.get_name() != "Anchor" && anchor_node.get_name() != "") {
94 gui::out << gui::warning << anchor_node.get_location() << ": "
95 << "unexpected node '" << anchor_node.get_name() << "'; ignored."
96 << std::endl;
97 continue;
98 }
99
100 point pt = anchor_node.get_attribute_value_or<point>("point", point::top_left);
101 std::string parent = anchor_node.get_attribute_value_or<std::string>(
102 "relativeTo", parent_ || is_virtual() ? "$parent" : "");
103 point relative_point = anchor_node.get_attribute_value_or<point>("relativePoint", pt);
104
105 if (utils::find(found_points, pt) != found_points.end()) {
106 gui::out << gui::warning << anchor_node.get_location() << ": "
107 << "anchor point \"" << utils::to_string(pt)
108 << "\" has already been defined for \"" << name_ << "\". anchor skipped."
109 << std::endl;
110 continue;
111 }
112
113 anchor_data a(pt, parent, relative_point);
114
115 if (const layout_node* offset_node = anchor_node.try_get_child("Offset")) {
116 auto dimensions = parse_dimension_node_(*offset_node);
117 a.type = dimensions.first;
118 a.offset = vector2f(
119 dimensions.second.x.value_or(0.0f), dimensions.second.y.value_or(0.0f));
120 }
121
122 set_anchor(a);
123 }
124 }
125}
126
128 parse_attributes_(node);
129 parse_size_node_(node);
130 parse_anchor_node_(node);
131}
132
134 if (node.get_attribute_value_or<bool>("setAllAnchors", false))
135 set_all_anchors("$parent");
136}
137
138} // namespace lxgui::gui
Holds a single color (float RGBA, 128 bits)
Definition gui_color.hpp:13
std::string_view get_name() const noexcept
Returns this node's name.
std::string_view get_location() const noexcept
Returns this node's location in the file as {file}:{line}.
An node in a layout file.
const layout_node * try_get_child(std::string_view name) const noexcept
Returns the first child with a given name, or null if none.
std::optional< std::string_view > try_get_attribute_value(std::string_view name) const noexcept
Returns the value of the attribute with the provided name, nullopt if not found.
T get_attribute_value_or(std::string_view name, T fallback) const noexcept
Returns the value of the attribute with the provided name, or a default if not found or parsing faile...
virtual void set_width(float abs_width)
Changes this region's absolute width (in pixels).
void set_all_anchors(const utils::observer_ptr< region > &obj)
Adjusts this regions anchors to fit the provided region.
void set_anchor(const anchor_data &a)
Adds/replaces an anchor.
color parse_color_node_(const layout_node &node)
virtual void parse_layout(const layout_node &node)
Parses data from a layout_node.
bool is_virtual() const
Checks if this region is virtual.
virtual void parse_size_node_(const layout_node &node)
std::pair< anchor_type, vector2< std::optional< float > > > parse_dimension_node_(const layout_node &node)
utils::observer_ptr< frame > parent_
virtual void set_height(float abs_height)
Changes this region's absolute height (in pixels).
void set_relative_height(float rel_height)
Changes this region's height (relative to its parent).
virtual void parse_attributes_(const layout_node &node)
vector2< std::optional< float > > parse_offset_node_(const layout_node &node)
virtual void set_dimensions(const vector2f &dimensions)
Changes this region's absolute dimensions (in pixels).
void set_relative_width(float rel_width)
Changes this region's width (relative to its parent).
void set_relative_dimensions(const vector2f &dimensions)
Changes this region's dimensions (relative to its parent).
vector2< float > parse_offset_node_or_(const layout_node &node, float fallback)
virtual void parse_anchor_node_(const layout_node &node)
vector2< float > vector2f
Holds 2D coordinates (as floats)
std::ostream out
const std::string warning
Definition gui_out.cpp:6
auto find(C &v, const T &s)
Definition utils_std.hpp:14
Raw data of an anchor (value type)
Holds 2D coordinates.