lxgui
Loading...
Searching...
No Matches
gui_region.cpp
1#include "lxgui/gui_region.hpp"
2
3#include "lxgui/gui_addon.hpp"
4#include "lxgui/gui_frame.hpp"
5#include "lxgui/gui_layered_region.hpp"
6#include "lxgui/gui_manager.hpp"
7#include "lxgui/gui_out.hpp"
8#include "lxgui/gui_region_tpl.hpp"
9#include "lxgui/gui_registry.hpp"
10#include "lxgui/gui_root.hpp"
11#include "lxgui/gui_virtual_registry.hpp"
12#include "lxgui/gui_virtual_root.hpp"
13#include "lxgui/utils_std.hpp"
14#include "lxgui/utils_string.hpp"
15
16#include <lxgui/extern_sol2_state.hpp>
17#include <sstream>
18
19namespace lxgui::gui {
20
21region::region(utils::control_block& block, manager& mgr, const region_core_attributes& attr) :
22 utils::enable_observer_from_this<region>(block), manager_(mgr) {
23
24 if (attr.is_virtual)
26
27 if (attr.parent)
28 set_parent_(attr.parent);
29
30 set_name_(attr.name);
31
32 initialize_(*this, attr);
33}
34
36 if (!is_virtual_) {
37 // Tell this region's anchor parents that it is no longer anchored to them
38 for (auto& a : anchor_list_) {
39 if (a) {
40 if (auto* anchor_parent = a->get_parent().get())
41 anchor_parent->remove_anchored_object(*this);
42 }
43
44 a.reset();
45 }
46
47 // Replace anchors pointing to this region by absolute anchors
48 // (need to copy the anchored object list, because the objects will attempt to
49 // modify it when un-anchored, which would invalidate our iteration)
50 std::vector<utils::observer_ptr<region>> temp_anchored_object_list =
51 std::move(anchored_object_list_);
52 for (const auto& obj : temp_anchored_object_list) {
53 if (!obj)
54 continue;
55
56 std::vector<point> anchored_point_list;
57 for (const auto& a : obj->get_anchors()) {
58 if (a && a->get_parent().get() == this)
59 anchored_point_list.push_back(a->object_point);
60 }
61
62 for (const auto& p : anchored_point_list) {
63 const anchor& a = obj->get_anchor(p);
64 anchor_data new_anchor = anchor_data(p, "", point::top_left);
65 new_anchor.offset = a.offset;
66
67 switch (a.parent_point) {
68 case point::top_left: new_anchor.offset += borders_.top_left(); break;
69 case point::top: new_anchor.offset.y += borders_.top; break;
70 case point::top_right: new_anchor.offset += borders_.top_right(); break;
71 case point::right: new_anchor.offset.x += borders_.right; break;
72 case point::bottom_right: new_anchor.offset += borders_.bottom_right(); break;
73 case point::bottom: new_anchor.offset.y += borders_.bottom; break;
74 case point::bottom_left: new_anchor.offset += borders_.bottom_left(); break;
75 case point::left: new_anchor.offset.x += borders_.left; break;
76 case point::center: new_anchor.offset += borders_.center(); break;
77 }
78
79 obj->set_anchor(new_anchor);
80 }
81 }
82
84 }
85
86 // Unregister this object from the GUI manager
87 if (!is_virtual() || parent_ == nullptr)
89}
90
91std::string region::serialize(const std::string& tab) const {
92 std::ostringstream str;
93
94 str << tab << " # Name : " << name_ << " ("
95 << std::string(is_valid_ ? "valid" : "not valid")
96 << std::string(is_manually_inherited_ ? ", manually inherited" : "") << ")\n";
97 str << tab << " # Raw name : " << raw_name_ << "\n";
98 str << tab << " # Type : " << get_region_type() << "\n";
99 if (parent_)
100 str << tab << " # Parent : " << parent_->get_name() << "\n";
101 else
102 str << tab << " # Parent : none\n";
103 str << tab << " # Num anchors: " << get_anchor_count() << "\n";
104 if (!anchor_list_.empty()) {
105 str << tab << " |-###\n";
106 for (const auto& a : anchor_list_) {
107 if (a) {
108 str << a->serialize(tab);
109 str << tab << " |-###\n";
110 }
111 }
112 }
113 str << tab << " # Borders :\n";
114 str << tab << " |-###\n";
115 str << tab << " | # left : " << borders_.left << "\n";
116 str << tab << " | # top : " << borders_.top << "\n";
117 str << tab << " | # right : " << borders_.right << "\n";
118 str << tab << " | # bottom: " << borders_.bottom << "\n";
119 str << tab << " |-###\n";
120 str << tab << " # Alpha : " << alpha_ << "\n";
121 str << tab << " # Shown : " << is_shown_ << "\n";
122 str << tab << " # Abs width : " << dimensions_.x << "\n";
123 str << tab << " # Abs height : " << dimensions_.y << "\n";
124
125 return str.str();
126}
127
128void region::copy_from(const region& obj) {
129 this->set_alpha(obj.get_alpha());
130 this->set_shown(obj.is_shown());
131 this->set_dimensions(obj.get_dimensions());
132
133 for (const std::optional<anchor>& a : obj.get_anchors()) {
134 if (a) {
135 this->set_anchor(a->get_data());
136 }
137 }
138}
139
140const std::string& region::get_name() const {
141 return name_;
142}
143
144const std::string& region::get_raw_name() const {
145 return raw_name_;
146}
147
148const std::string& region::get_region_type() const {
149 return get_type_list_().back();
150}
151
152bool region::is_region_type(const std::string& type_name) const {
153 const auto& type_list = get_type_list_();
154 return utils::find(type_list, type_name) != type_list.end();
155}
156
157float region::get_alpha() const {
158 return alpha_;
159}
160
162 if (parent_) {
163 return parent_->get_effective_alpha() * get_alpha();
164 } else {
165 return get_alpha();
166 }
167}
168
169void region::set_alpha(float alpha) {
170 if (alpha_ != alpha) {
171 alpha_ = alpha;
173 }
174}
175
177 if (is_shown_)
178 return;
179
180 is_shown_ = true;
181
182 if (!is_visible_ && (!parent_ || parent_->is_visible()))
184}
185
187 if (!is_shown_)
188 return;
189
190 is_shown_ = false;
191
192 if (is_visible_)
194}
195
196void region::set_shown(bool is_shown) {
197 if (is_shown)
198 show();
199 else
200 hide();
201}
202
203bool region::is_shown() const {
204 return is_shown_;
205}
206
207bool region::is_visible() const {
208 return is_visible_;
209}
210
211bool region::is_valid() const {
212 return is_valid_;
213}
214
215void region::set_dimensions(const vector2f& dimensions) {
216 if (dimensions_ == dimensions)
217 return;
218
219 dimensions_ = dimensions;
220
221 if (!is_virtual_) {
224 }
225}
226
227void region::set_width(float abs_width) {
228 if (dimensions_.x == abs_width)
229 return;
230
231 dimensions_.x = abs_width;
232
233 if (!is_virtual_) {
236 }
237}
238
239void region::set_height(float abs_height) {
240 if (dimensions_.y == abs_height)
241 return;
242
243 dimensions_.y = abs_height;
244
245 if (!is_virtual_) {
248 }
249}
250
252 if (parent_)
253 set_dimensions(dimensions * parent_->get_apparent_dimensions());
254 else
255 set_dimensions(dimensions * get_effective_frame_renderer()->get_target_dimensions());
256}
257
258void region::set_relative_width(float rel_width) {
259 if (parent_)
260 set_width(rel_width * parent_->get_apparent_dimensions().x);
261 else
262 set_width(rel_width * get_effective_frame_renderer()->get_target_dimensions().x);
263}
264
265void region::set_relative_height(float rel_height) {
266 if (parent_)
267 set_height(rel_height * parent_->get_apparent_dimensions().y);
268 else
269 set_height(rel_height * get_effective_frame_renderer()->get_target_dimensions().y);
270}
271
273 return dimensions_;
274}
275
279
283
287
288bool region::is_in_region(const vector2f& position) const {
289 return (
290 (borders_.left <= position.x && position.x <= borders_.right - 1) &&
291 (borders_.top <= position.y && position.y <= borders_.bottom - 1));
292}
293
294void region::set_name_(const std::string& name) {
295 if (name_.empty()) {
296 name_ = raw_name_ = name;
297 if (utils::starts_with(name_, "$parent")) {
298 if (parent_)
299 utils::replace(name_, "$parent", parent_->get_name());
300 else {
301 gui::out << gui::warning << "gui::" << get_region_type() << ": \"" << name_
302 << "\" has no parent" << std::endl;
303 utils::replace(name_, "$parent", "");
304 }
305 }
306 } else {
307 gui::out << gui::warning << "gui::" << get_region_type() << ": "
308 << "set_name() can only be called once." << std::endl;
309 }
310}
311
312void region::set_parent_(utils::observer_ptr<frame> parent) {
313 if (parent == observer_from_this()) {
314 gui::out << gui::error << "gui::" << get_region_type() << ": Cannot call set_parent(this)."
315 << std::endl;
316 return;
317 }
318
319 if (parent_ == parent)
320 return;
321
322 parent_ = std::move(parent);
323
324 if (!is_virtual()) {
326 }
327}
328
332
334 // Gracefully disappear (triggers events, etc).
335 hide();
336
337 // Ignoring the return value destroys the object.
339}
340
342 return borders_.center();
343}
344
345float region::get_left() const {
346 return borders_.left;
347}
348
349float region::get_right() const {
350 return borders_.right;
351}
352
353float region::get_top() const {
354 return borders_.top;
355}
356
357float region::get_bottom() const {
358 return borders_.bottom;
359}
360
362 return borders_;
363}
364
366 bool had_anchors = false;
367 for (auto& a : anchor_list_) {
368 if (a) {
369 if (!is_virtual_) {
370 if (auto parent = a->get_parent()) {
371 parent->remove_anchored_object(*this);
372 }
373 }
374
375 a.reset();
376 had_anchors = true;
377 }
378 }
379
380 defined_borders_ = bounds2<bool>(false, false, false, false);
381
382 if (had_anchors || !is_virtual_) {
385 }
386}
387
388bool check_cyclic_anchors(const region& self, anchor& a) {
389 if (utils::observer_ptr<region> other = a.get_parent()) {
390 if (other->depends_on(self)) {
391 gui::out << gui::error << "gui::" << self.get_region_type()
392 << ": Cyclic anchor dependency ! "
393 << "\"" << self.get_name() << "\" and \"" << other->get_name()
394 << "\" depend on eachothers (directly or indirectly). \""
395 << utils::to_string(a.object_point) << "\" anchor removed." << std::endl;
396
397 return false;
398 }
399 }
400
401 return true;
402}
403
404void region::set_all_anchors(const std::string& obj_name) {
405 if (obj_name == name_) {
406 gui::out << gui::error << "gui::" << get_region_type()
407 << ": Cannot call set_all_anchors(this)." << std::endl;
408 return;
409 }
410
412
413 auto& top_left = anchor_list_[static_cast<int>(point::top_left)];
414 auto& bottom_right = anchor_list_[static_cast<int>(point::bottom_right)];
415
416 top_left.emplace(*this, anchor_data(point::top_left, obj_name));
417
418 if (!check_cyclic_anchors(*this, top_left.value())) {
419 top_left = std::nullopt;
420 return;
421 }
422
423 bottom_right.emplace(*this, anchor_data(point::bottom_right, obj_name));
424
425 defined_borders_ = bounds2<bool>(true, true, true, true);
426
427 if (!is_virtual_) {
428 if (auto* parent = top_left->get_parent().get()) {
429 parent->add_anchored_object(*this);
430 }
431
434 }
435}
436
437void region::set_all_anchors(const utils::observer_ptr<region>& obj) {
438 if (obj == observer_from_this()) {
439 gui::out << gui::error << "gui::" << get_region_type()
440 << ": Cannot call set_all_anchors(this)." << std::endl;
441 return;
442 }
443
444 set_all_anchors(obj ? obj->get_name() : "");
445}
446
447void set_defined_borders(bounds2<bool>& defined_borders, point p, bool defined) {
448 switch (p) {
449 case point::top_left:
450 defined_borders.top = defined;
451 defined_borders.left = defined;
452 break;
453 case point::top: defined_borders.top = defined; break;
454 case point::top_right:
455 defined_borders.top = defined;
456 defined_borders.right = defined;
457 break;
458 case point::right: defined_borders.right = defined; break;
460 defined_borders.bottom = defined;
461 defined_borders.right = defined;
462 break;
463 case point::bottom: defined_borders.bottom = defined; break;
465 defined_borders.bottom = defined;
466 defined_borders.left = defined;
467 break;
468 case point::left: defined_borders.left = defined; break;
469 default: break;
470 }
471}
472
474 auto& modified_anchor = anchor_list_[static_cast<int>(a.object_point)];
475 auto previous_parent = modified_anchor.has_value() ? modified_anchor->get_parent() : nullptr;
476
477 modified_anchor.emplace(*this, a);
478
480
481 auto new_parent = modified_anchor->get_parent();
482 if (new_parent != previous_parent) {
483 if (previous_parent) {
484 previous_parent->remove_anchored_object(*this);
485 }
486
487 if (new_parent) {
488 if (!check_cyclic_anchors(*this, modified_anchor.value())) {
489 modified_anchor.reset();
491 } else {
492 new_parent->add_anchored_object(*this);
493 }
494 }
495 }
496
497 if (!is_virtual_) {
500 }
501}
502
503bool region::depends_on(const region& obj) const {
504 for (const auto& a : anchor_list_) {
505 if (!a)
506 continue;
507
508 const region* parent = a->get_parent().get();
509 if (parent == &obj)
510 return true;
511
512 if (parent)
513 return parent->depends_on(obj);
514 }
515
516 return false;
517}
518
519std::size_t region::get_anchor_count() const {
520 std::size_t num_anchors = 0u;
521 for (const auto& a : anchor_list_) {
522 if (a)
523 ++num_anchors;
524 }
525
526 return num_anchors;
527}
528
530 auto& a = anchor_list_[static_cast<int>(p)];
531 if (!a) {
532 throw gui::exception(
533 "region", "Cannot modify a point that does not exist. Use set_anchor() first.");
534 }
535
536 return *a;
537}
538
540 const auto& a = anchor_list_[static_cast<int>(p)];
541 if (!a) {
542 throw gui::exception(
543 "region", "Cannot get an anchor that does not exist. Use set_anchor() first.");
544 }
545
546 return *a;
547}
548
549const std::array<std::optional<anchor>, 9>& region::get_anchors() const {
550 return anchor_list_;
551}
552
553bool region::is_virtual() const {
554 return is_virtual_;
555}
556
558 is_virtual_ = true;
559}
560
564
566 auto iter =
567 utils::find_if(anchored_object_list_, [&](const auto& ptr) { return ptr.get() == &obj; });
568
569 if (iter != anchored_object_list_.end())
570 anchored_object_list_.erase(iter);
571}
572
573float region::round_to_pixel(float value, utils::rounding_method method) const {
574 float scaling_factor = get_manager().get_interface_scaling_factor();
575 return utils::round(value, 1.0f / scaling_factor, method);
576}
577
579 float scaling_factor = get_manager().get_interface_scaling_factor();
580 return vector2f(
581 utils::round(position.x, 1.0f / scaling_factor, method),
582 utils::round(position.y, 1.0f / scaling_factor, method));
583}
584
585bool region::make_borders_(float& min, float& max, float center, float size) const {
586 if (std::isinf(min) && std::isinf(max)) {
587 if (!std::isinf(size) && size > 0.0f && !std::isinf(center)) {
588 min = center - size / 2.0f;
589 max = center + size / 2.0f;
590 } else {
591 return false;
592 }
593 } else if (std::isinf(max)) {
594 if (!std::isinf(size) && size > 0.0f) {
595 max = min + size;
596 } else if (!std::isinf(center)) {
597 max = min + 2.0f * (center - min);
598 } else {
599 return false;
600 }
601 } else if (std::isinf(min)) {
602 if (!std::isinf(size) && size > 0.0f) {
603 min = max - size;
604 } else if (!std::isinf(center)) {
605 min = max - 2.0f * (max - center);
606 } else {
607 return false;
608 }
609 }
610
611 return true;
612}
613
615 float& left, float& right, float& top, float& bottom, float& x_center, float& y_center) const {
616 left = +std::numeric_limits<float>::infinity();
617 right = -std::numeric_limits<float>::infinity();
618 top = +std::numeric_limits<float>::infinity();
619 bottom = -std::numeric_limits<float>::infinity();
620
621 for (const auto& opt_anchor : anchor_list_) {
622 if (!opt_anchor)
623 continue;
624
625 const anchor& a = opt_anchor.value();
626 const vector2f p = a.get_point(*this);
627
628 switch (a.object_point) {
629 case point::top_left:
630 top = std::min<float>(top, p.y);
631 left = std::min<float>(left, p.x);
632 break;
633 case point::top:
634 top = std::min<float>(top, p.y);
635 x_center = p.x;
636 break;
637 case point::top_right:
638 top = std::min<float>(top, p.y);
639 right = std::max<float>(right, p.x);
640 break;
641 case point::right:
642 right = std::max<float>(right, p.x);
643 y_center = p.y;
644 break;
646 bottom = std::max<float>(bottom, p.y);
647 right = std::max<float>(right, p.x);
648 break;
649 case point::bottom:
650 bottom = std::max<float>(bottom, p.y);
651 x_center = p.x;
652 break;
654 bottom = std::max<float>(bottom, p.y);
655 left = std::min<float>(left, p.x);
656 break;
657 case point::left:
658 left = std::min<float>(left, p.x);
659 y_center = p.y;
660 break;
661 case point::center:
662 x_center = p.x;
663 y_center = p.y;
664 break;
665 }
666 }
667}
668
670// #define DEBUG_LOG(msg) gui::out << (msg) << std::endl
671#define DEBUG_LOG(msg)
672
673 DEBUG_LOG(" Update anchors for " + lua_name_);
674
675 const bool old_is_ready = is_valid_;
676 const auto old_border_list = borders_;
677
678 is_valid_ = true;
679
680 if (!anchor_list_.empty()) {
681 float left = 0.0f, right = 0.0f, top = 0.0f, bottom = 0.0f;
682 float x_center = 0.0f, y_center = 0.0f;
683
684 float rounded_width =
686 float rounded_height =
688
689 DEBUG_LOG(" Read anchors");
690 read_anchors_(left, right, top, bottom, x_center, y_center);
691 DEBUG_LOG(" left=" + utils::to_string(left));
692 DEBUG_LOG(" right=" + utils::to_string(right));
693 DEBUG_LOG(" top=" + utils::to_string(top));
694 DEBUG_LOG(" bottom=" + utils::to_string(bottom));
695 DEBUG_LOG(" x_center=" + utils::to_string(x_center));
696 DEBUG_LOG(" y_center=" + utils::to_string(y_center));
697
698 DEBUG_LOG(" Make borders");
699 if (!make_borders_(top, bottom, y_center, rounded_height)) {
700 is_valid_ = false;
701 }
702
703 if (!make_borders_(left, right, x_center, rounded_width)) {
704 is_valid_ = false;
705 }
706
707 if (is_valid_) {
708 if (right < left) {
709 right = left + 1;
710 }
711 if (bottom < top) {
712 bottom = top + 1;
713 }
714
716 } else {
718 }
719 } else {
721 is_valid_ = false;
722 }
723
724 DEBUG_LOG(" Final borders");
729
730 DEBUG_LOG(" left=" + utils::to_string(borders_.left));
731 DEBUG_LOG(" right=" + utils::to_string(borders_.right));
732 DEBUG_LOG(" top=" + utils::to_string(borders_.top));
733 DEBUG_LOG(" bottom=" + utils::to_string(borders_.bottom));
734
735 if (borders_ != old_border_list || is_valid_ != old_is_ready) {
736 DEBUG_LOG(" Fire redraw");
738 }
739
740 DEBUG_LOG(" @");
741#undef DEBUG_LOG
742}
743
745 if (is_virtual())
746 return;
747
748 const bool old_valid = is_valid_;
749 const auto old_border_list = borders_;
750
752
753 if (borders_ != old_border_list || is_valid_ != old_valid) {
754 for (const auto& object : anchored_object_list_)
755 object->notify_borders_need_update();
756 }
757}
758
762
763void region::update(float) {}
764
765void region::render() const {}
766
767sol::state& region::get_lua_() {
768 return get_manager().get_lua();
769}
770
771const sol::state& region::get_lua_() const {
772 return get_manager().get_lua();
773}
774
776 get_lua_().globals()[get_name()] = sol::lua_nil;
777 get_lua_().globals()["_METADATA"][get_name()] = sol::lua_nil;
778}
779
780void region::set_manually_inherited(bool manually_inherited) {
781 is_manually_inherited_ = manually_inherited;
782}
783
787
789
790const std::vector<utils::observer_ptr<region>>& region::get_anchored_objects() const {
792}
793
795 is_loaded_ = true;
796}
797
798bool region::is_loaded() const {
799 return is_loaded_;
800}
801
802utils::observer_ptr<const frame_renderer> region::get_effective_frame_renderer() const {
803 if (!parent_)
804 return get_manager().get_root().observer_from_this();
805 return parent_->get_effective_frame_renderer();
806}
807
812
817
818std::string region::parse_file_name(const std::string& file_name) const {
819 if (file_name.empty())
820 return file_name;
821
822 std::string new_file = file_name;
823
824 const addon* addon = get_addon();
825 if (new_file[0] == '|' && addon) {
826 new_file[0] = '/';
827 new_file = addon->directory + new_file;
828 }
829
830 return new_file;
831}
832
833void region::set_addon(const addon* a) {
834 if (addon_) {
835 gui::out << gui::warning << "gui::" << get_region_type()
836 << ": set_addon() can only be called once." << std::endl;
837 return;
838 }
839
840 addon_ = a;
841}
842
843const addon* region::get_addon() const {
844 if (!addon_ && parent_)
845 return parent_->get_addon();
846 else
847 return addon_;
848}
849
854
859
860const std::vector<std::string>& region::get_type_list_() const {
861 return get_type_list_impl_<region>();
862}
863
864} // namespace lxgui::gui
Stores a position for a UI region.
vector2f get_point(const region &object) const
Returns this anchor's absolute coordinates (in pixels).
const utils::observer_ptr< region > & get_parent()
Returns this anchor's parent region.
Exception to be thrown by GUI code.
Manages the user interface.
virtual_root & get_virtual_root()
Returns the UI root object, which contains root frames.
root & get_root()
Returns the UI root object, which contains root frames.
float get_interface_scaling_factor() const
Returns the current UI scaling factor.
sol::state & get_lua()
Returns the GUI Lua state (sol wrapper).
The base class of all elements in the GUI.
void set_shown(bool is_shown)
shows/hides this region.
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.
bool is_region_type() const
Checks if this region is of the provided type.
bool is_valid() const
Checks if this region has all its borders correctly defined.
const std::vector< utils::observer_ptr< region > > & get_anchored_objects() const
Returns the list of all objects that are anchored to this one.
const anchor & get_anchor(point p) const
Returns one of this region's anchor.
virtual void set_parent_(utils::observer_ptr< frame > parent)
Changes this region's parent.
const std::string & get_region_type() const
Returns the type of this region.
manager & get_manager()
Returns this region's manager.
void set_anchor(const anchor_data &a)
Adds/replaces an anchor.
virtual utils::observer_ptr< const frame_renderer > get_effective_frame_renderer() const
Returns the renderer of this object or its parents.
const bounds2f & get_borders() const
Returns this region's borders.
~region() override
Destructor.
void initialize_(T &self, const region_core_attributes &attr)
Set up function to call in all derived class constructors.
bool is_virtual() const
Checks if this region is virtual.
float get_effective_alpha() const
Returns this region's effective alpha (opacity).
utils::observer_ptr< const frame > get_parent() const
Returns this region's parent.
bool is_apparent_width_defined() const
Checks if this region's apparent width is defined.
registry & get_registry()
Returns the UI object registry, which keeps track of all objects in the UI.
bool is_visible() const
Checks if this region can be seen on the screen.
utils::observer_ptr< frame > parent_
virtual utils::owner_ptr< region > release_from_parent()
Removes this region from its parent and return an owning pointer.
virtual void notify_loaded()
Notifies this region that it has been fully loaded.
void hide()
hides this region.
virtual void notify_renderer_need_redraw()
Notifies the renderer of this region that it needs to be redrawn.
float round_to_pixel(float value, utils::rounding_method method=utils::rounding_method::nearest) const
Round an absolute position on screen to the nearest physical pixel.
vector2f get_apparent_dimensions() const
Returns this region's apparent width and height (in pixels).
void read_anchors_(float &left, float &right, float &top, float &bottom, float &x_center, float &y_center) const
virtual void notify_visible()
Notifies this region that it is now visible on screen.
void set_manually_inherited(bool manually_inherited)
Flags this region as manually inherited or not.
const addon * addon_
virtual void render() const
Renders this region on the current render target.
virtual void set_height(float abs_height)
Changes this region's absolute height (in pixels).
void show()
shows this region.
void set_relative_height(float rel_height)
Changes this region's height (relative to its parent).
const vector2f & get_dimensions() const
Returns this region's explicitly-defined width and height (in pixels).
bool depends_on(const region &obj) const
Checks if this region depends on another.
void set_alpha(float alpha)
Changes this region's alpha (opacity).
vector2f get_center() const
Returns the position of this region's center.
const std::string & get_name() const
Returns this region's name.
bool is_shown() const
Checks if this region is shown.
void destroy()
Forcefully removes this region from the GUI.
float get_right() const
Returns the horizontal position of this region's right border.
float get_left() const
Returns the horizontal position of this region's left border.
virtual void notify_invisible()
Notifies this region that it is no longer visible on screen.
void add_anchored_object(region &obj)
Notifies this region that another one is anchored to it.
const std::string & get_raw_name() const
Returns this region's raw name.
void set_addon(const addon *a)
Sets the addon this frame belongs to.
std::array< std::optional< anchor >, 9 > anchor_list_
void set_virtual_()
Makes this region virtual.
anchor & modify_anchor(point p)
Returns one of this region's anchor to modify it.
bool is_manually_inherited() const
Checks if this object is manually inherited.
virtual bool is_in_region(const vector2f &position) const
Checks if the provided coordinates are inside this region.
virtual void set_dimensions(const vector2f &dimensions)
Changes this region's absolute dimensions (in pixels).
float get_bottom() const
Returns the vertical position of this region's bottom border.
virtual void update(float delta)
Updates this region's logic.
void set_relative_width(float rel_width)
Changes this region's width (relative to its parent).
void clear_all_anchors()
Removes all anchors.
virtual const std::vector< std::string > & get_type_list_() const
bool is_loaded() const
Checks if this region has been fully loaded.
region(utils::control_block &block, manager &mgr, const region_core_attributes &attr)
Contructor.
virtual void notify_borders_need_update()
Tells this region that its borders need updating.
bounds2< bool > defined_borders_
bool make_borders_(float &min, float &max, float center, float size) const
void set_relative_dimensions(const vector2f &dimensions)
Changes this region's dimensions (relative to its parent).
float get_top() const
Returns the vertical position of this region's top border.
std::string raw_name_
bool is_apparent_height_defined() const
Checks if this region's apparent height is defined.
const std::array< std::optional< anchor >, 9 > & get_anchors() const
Returns all of this region's anchors.
virtual void copy_from(const region &obj)
Copies a region's parameters into this region (inheritance).
const addon * get_addon() const
Returns this frame's addon.
std::string parse_file_name(const std::string &file_name) const
Convert an addon-relative file path to a application-relative path.
float get_alpha() const
Returns this region's alpha (opacity).
sol::state & get_lua_()
std::vector< utils::observer_ptr< region > > anchored_object_list_
virtual std::string serialize(const std::string &tab) const
Prints all relevant information about this region in a string.
void remove_anchored_object(region &obj)
Notifies this region that another one is no longer anchored to it.
virtual void notify_scaling_factor_updated()
Tells this region that the global interface scaling factor has changed.
std::size_t get_anchor_count() const
Returns the number of defined anchors.
virtual void update_borders_()
void set_name_(const std::string &name)
Sets this region's name.
void remove_glue()
Removes the Lua glue.
Keeps track of created UI objects and records their names for lookup.
void remove_region(const region &obj)
Removes a region from this registry.
registry & get_registry()
Returns the UI object registry, which keeps track of all objects in the UI.
Definition gui_root.hpp:261
virtual_registry & get_registry()
Returns the UI object registry, which keeps track of all objects in the UI.
vector2< float > vector2f
Holds 2D coordinates (as floats)
bounds2< float > bounds2f
Holds 2D bounds of a region (as floats).
void set_defined_borders(bounds2< bool > &defined_borders, point p, bool defined)
std::ostream out
utils::observer_ptr< ObjectType > observer_from(ObjectType *self)
Obtain an observer pointer from a raw pointer (typically 'this')
const std::string warning
Definition gui_out.cpp:6
const std::string error
Definition gui_out.cpp:7
bool check_cyclic_anchors(const region &self, anchor &a)
auto find(C &v, const T &s)
Definition utils_std.hpp:14
float round(float value, float unit, rounding_method method)
Round a floating point value to a specific unit and using a specific rounding method.
auto find_if(C &v, T &&f)
Definition utils_std.hpp:19
rounding_method
Rounding method for points to pixels conversions.
@ nearest_not_zero
Equivalent to round() but only returns 0 if input is exactly 0.
oup::observable_sealed_ptr< T > owner_ptr
A piece of the user interface.
Definition gui_addon.hpp:12
std::string directory
Definition gui_addon.hpp:21
Raw data of an anchor (value type)
vector2< T > bottom_left() const noexcept
static const bounds2 zero
vector2< T > bottom_right() const noexcept
T height() const noexcept
T width() const noexcept
vector2< T > center() const noexcept
vector2< T > top_right() const noexcept
vector2< T > top_left() const noexcept
Struct holding all the core information about a region necessary for its creation.