lxgui
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 
19 namespace lxgui::gui {
20 
21 region::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)
25  set_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 
83  remove_glue();
84  }
85 
86  // Unregister this object from the GUI manager
87  if (!is_virtual() || parent_ == nullptr)
88  get_registry().remove_region(*this);
89 }
90 
91 std::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 
128 void 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 
140 const std::string& region::get_name() const {
141  return name_;
142 }
143 
144 const std::string& region::get_raw_name() const {
145  return raw_name_;
146 }
147 
148 const std::string& region::get_region_type() const {
149  return get_type_list_().back();
150 }
151 
152 bool 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 
157 float 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 
169 void region::set_alpha(float alpha) {
170  if (alpha_ != alpha) {
171  alpha_ = alpha;
173  }
174 }
175 
176 void region::show() {
177  if (is_shown_)
178  return;
179 
180  is_shown_ = true;
181 
182  if (!is_visible_ && (!parent_ || parent_->is_visible()))
183  notify_visible();
184 }
185 
186 void region::hide() {
187  if (!is_shown_)
188  return;
189 
190  is_shown_ = false;
191 
192  if (is_visible_)
194 }
195 
196 void region::set_shown(bool is_shown) {
197  if (is_shown)
198  show();
199  else
200  hide();
201 }
202 
203 bool region::is_shown() const {
204  return is_shown_;
205 }
206 
207 bool region::is_visible() const {
208  return is_visible_;
209 }
210 
211 bool region::is_valid() const {
212  return is_valid_;
213 }
214 
215 void region::set_dimensions(const vector2f& dimensions) {
216  if (dimensions_ == dimensions)
217  return;
218 
219  dimensions_ = dimensions;
220 
221  if (!is_virtual_) {
224  }
225 }
226 
227 void 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 
239 void 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 
251 void region::set_relative_dimensions(const vector2f& dimensions) {
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 
258 void 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 
265 void 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 
277  return vector2f(borders_.width(), borders_.height());
278 }
279 
282 }
283 
286 }
287 
288 bool 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 
294 void 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 
312 void 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 
330  return nullptr;
331 }
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 
345 float region::get_left() const {
346  return borders_.left;
347 }
348 
349 float region::get_right() const {
350  return borders_.right;
351 }
352 
353 float region::get_top() const {
354  return borders_.top;
355 }
356 
357 float 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 
388 bool 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 
404 void 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 
437 void 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 
447 void 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;
459  case point::bottom_right:
460  defined_borders.bottom = defined;
461  defined_borders.right = defined;
462  break;
463  case point::bottom: defined_borders.bottom = defined; break;
464  case point::bottom_left:
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 
503 bool 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 
519 std::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 
539 const anchor& region::get_anchor(point p) const {
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 
549 const std::array<std::optional<anchor>, 9>& region::get_anchors() const {
550  return anchor_list_;
551 }
552 
553 bool region::is_virtual() const {
554  return is_virtual_;
555 }
556 
558  is_virtual_ = true;
559 }
560 
562  anchored_object_list_.push_back(observer_from(&obj));
563 }
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 
573 float 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 
585 bool 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;
645  case point::bottom_right:
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;
653  case point::bottom_left:
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 {
720  borders_ = bounds2f(0.0, 0.0, dimensions_.x, dimensions_.y);
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 
751  update_borders_();
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 
761 }
762 
763 void region::update(float) {}
764 
765 void region::render() const {}
766 
767 sol::state& region::get_lua_() {
768  return get_manager().get_lua();
769 }
770 
771 const 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 
780 void region::set_manually_inherited(bool manually_inherited) {
781  is_manually_inherited_ = manually_inherited;
782 }
783 
785  return is_manually_inherited_;
786 }
787 
789 
790 const std::vector<utils::observer_ptr<region>>& region::get_anchored_objects() const {
791  return anchored_object_list_;
792 }
793 
795  is_loaded_ = true;
796 }
797 
798 bool region::is_loaded() const {
799  return is_loaded_;
800 }
801 
802 utils::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 
809  is_visible_ = true;
811 }
812 
814  is_visible_ = false;
816 }
817 
818 std::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 
833 void 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 
843 const addon* region::get_addon() const {
844  if (!addon_ && parent_)
845  return parent_->get_addon();
846  else
847  return addon_;
848 }
849 
853 }
854 
858 }
859 
860 const 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.
Definition: gui_anchor.hpp:97
vector2f get_point(const region &object) const
Returns this anchor's absolute coordinates (in pixels).
Definition: gui_anchor.cpp:55
const utils::observer_ptr< region > & get_parent()
Returns this anchor's parent region.
Definition: gui_anchor.hpp:128
Exception to be thrown by GUI code.
Manages the user interface.
Definition: gui_manager.hpp:44
float get_interface_scaling_factor() const
Returns the current UI scaling factor.
Definition: gui_manager.cpp:87
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.
sol::state & get_lua()
Returns the GUI Lua state (sol wrapper).
The base class of all elements in the GUI.
Definition: gui_region.hpp:161
void set_shown(bool is_shown)
shows/hides this region.
Definition: gui_region.cpp:196
virtual void set_width(float abs_width)
Changes this region's absolute width (in pixels).
Definition: gui_region.cpp:227
void set_all_anchors(const utils::observer_ptr< region > &obj)
Adjusts this regions anchors to fit the provided region.
Definition: gui_region.cpp:437
bool is_region_type() const
Checks if this region is of the provided type.
Definition: gui_region.hpp:423
bool is_valid() const
Checks if this region has all its borders correctly defined.
Definition: gui_region.cpp:211
const std::vector< utils::observer_ptr< region > > & get_anchored_objects() const
Returns the list of all objects that are anchored to this one.
Definition: gui_region.cpp:790
const anchor & get_anchor(point p) const
Returns one of this region's anchor.
Definition: gui_region.cpp:539
virtual void set_parent_(utils::observer_ptr< frame > parent)
Changes this region's parent.
Definition: gui_region.cpp:312
const std::string & get_region_type() const
Returns the type of this region.
Definition: gui_region.cpp:148
void set_anchor(const anchor_data &a)
Adds/replaces an anchor.
Definition: gui_region.cpp:473
virtual utils::observer_ptr< const frame_renderer > get_effective_frame_renderer() const
Returns the renderer of this object or its parents.
Definition: gui_region.cpp:802
const bounds2f & get_borders() const
Returns this region's borders.
Definition: gui_region.cpp:361
~region() override
Destructor.
Definition: gui_region.cpp:35
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.
Definition: gui_region.cpp:553
float get_effective_alpha() const
Returns this region's effective alpha (opacity).
Definition: gui_region.cpp:161
bool is_apparent_width_defined() const
Checks if this region's apparent width is defined.
Definition: gui_region.cpp:280
registry & get_registry()
Returns the UI object registry, which keeps track of all objects in the UI.
Definition: gui_region.cpp:850
bool is_visible() const
Checks if this region can be seen on the screen.
Definition: gui_region.cpp:207
utils::observer_ptr< frame > parent_
Definition: gui_region.hpp:807
virtual utils::owner_ptr< region > release_from_parent()
Removes this region from its parent and return an owning pointer.
Definition: gui_region.cpp:329
manager & get_manager()
Returns this region's manager.
Definition: gui_region.hpp:693
virtual void notify_loaded()
Notifies this region that it has been fully loaded.
Definition: gui_region.cpp:794
void hide()
hides this region.
Definition: gui_region.cpp:186
virtual void notify_renderer_need_redraw()
Notifies the renderer of this region that it needs to be redrawn.
Definition: gui_region.cpp:788
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.
Definition: gui_region.cpp:573
vector2f get_apparent_dimensions() const
Returns this region's apparent width and height (in pixels).
Definition: gui_region.cpp:276
void read_anchors_(float &left, float &right, float &top, float &bottom, float &x_center, float &y_center) const
Definition: gui_region.cpp:614
virtual void notify_visible()
Notifies this region that it is now visible on screen.
Definition: gui_region.cpp:808
void set_manually_inherited(bool manually_inherited)
Flags this region as manually inherited or not.
Definition: gui_region.cpp:780
const addon * addon_
Definition: gui_region.hpp:802
virtual void render() const
Renders this region on the current render target.
Definition: gui_region.cpp:765
virtual void set_height(float abs_height)
Changes this region's absolute height (in pixels).
Definition: gui_region.cpp:239
void show()
shows this region.
Definition: gui_region.cpp:176
void set_relative_height(float rel_height)
Changes this region's height (relative to its parent).
Definition: gui_region.cpp:265
const vector2f & get_dimensions() const
Returns this region's explicitly-defined width and height (in pixels).
Definition: gui_region.cpp:272
bool depends_on(const region &obj) const
Checks if this region depends on another.
Definition: gui_region.cpp:503
void set_alpha(float alpha)
Changes this region's alpha (opacity).
Definition: gui_region.cpp:169
vector2f get_center() const
Returns the position of this region's center.
Definition: gui_region.cpp:341
const std::string & get_name() const
Returns this region's name.
Definition: gui_region.cpp:140
bool is_shown() const
Checks if this region is shown.
Definition: gui_region.cpp:203
void destroy()
Forcefully removes this region from the GUI.
Definition: gui_region.cpp:333
float get_right() const
Returns the horizontal position of this region's right border.
Definition: gui_region.cpp:349
float get_left() const
Returns the horizontal position of this region's left border.
Definition: gui_region.cpp:345
virtual void notify_invisible()
Notifies this region that it is no longer visible on screen.
Definition: gui_region.cpp:813
void add_anchored_object(region &obj)
Notifies this region that another one is anchored to it.
Definition: gui_region.cpp:561
std::string name_
Definition: gui_region.hpp:804
const std::string & get_raw_name() const
Returns this region's raw name.
Definition: gui_region.cpp:144
void set_addon(const addon *a)
Sets the addon this frame belongs to.
Definition: gui_region.cpp:833
std::array< std::optional< anchor >, 9 > anchor_list_
Definition: gui_region.hpp:814
void set_virtual_()
Makes this region virtual.
Definition: gui_region.cpp:557
anchor & modify_anchor(point p)
Returns one of this region's anchor to modify it.
Definition: gui_region.cpp:529
bool is_manually_inherited() const
Checks if this object is manually inherited.
Definition: gui_region.cpp:784
virtual bool is_in_region(const vector2f &position) const
Checks if the provided coordinates are inside this region.
Definition: gui_region.cpp:288
virtual void set_dimensions(const vector2f &dimensions)
Changes this region's absolute dimensions (in pixels).
Definition: gui_region.cpp:215
float get_bottom() const
Returns the vertical position of this region's bottom border.
Definition: gui_region.cpp:357
virtual void update(float delta)
Updates this region's logic.
Definition: gui_region.cpp:763
void set_relative_width(float rel_width)
Changes this region's width (relative to its parent).
Definition: gui_region.cpp:258
void clear_all_anchors()
Removes all anchors.
Definition: gui_region.cpp:365
virtual const std::vector< std::string > & get_type_list_() const
Definition: gui_region.cpp:860
utils::observer_ptr< const frame > get_parent() const
Returns this region's parent.
Definition: gui_region.hpp:229
bool is_loaded() const
Checks if this region has been fully loaded.
Definition: gui_region.cpp:798
region(utils::control_block &block, manager &mgr, const region_core_attributes &attr)
Contructor.
Definition: gui_region.cpp:21
virtual void notify_borders_need_update()
Tells this region that its borders need updating.
Definition: gui_region.cpp:744
bounds2< bool > defined_borders_
Definition: gui_region.hpp:815
bool make_borders_(float &min, float &max, float center, float size) const
Definition: gui_region.cpp:585
void set_relative_dimensions(const vector2f &dimensions)
Changes this region's dimensions (relative to its parent).
Definition: gui_region.cpp:251
float get_top() const
Returns the vertical position of this region's top border.
Definition: gui_region.cpp:353
std::string raw_name_
Definition: gui_region.hpp:805
bool is_apparent_height_defined() const
Checks if this region's apparent height is defined.
Definition: gui_region.cpp:284
const std::array< std::optional< anchor >, 9 > & get_anchors() const
Returns all of this region's anchors.
Definition: gui_region.cpp:549
virtual void copy_from(const region &obj)
Copies a region's parameters into this region (inheritance).
Definition: gui_region.cpp:128
const addon * get_addon() const
Returns this frame's addon.
Definition: gui_region.cpp:843
std::string parse_file_name(const std::string &file_name) const
Convert an addon-relative file path to a application-relative path.
Definition: gui_region.cpp:818
float get_alpha() const
Returns this region's alpha (opacity).
Definition: gui_region.cpp:157
sol::state & get_lua_()
Definition: gui_region.cpp:767
std::vector< utils::observer_ptr< region > > anchored_object_list_
Definition: gui_region.hpp:824
virtual std::string serialize(const std::string &tab) const
Prints all relevant information about this region in a string.
Definition: gui_region.cpp:91
void remove_anchored_object(region &obj)
Notifies this region that another one is no longer anchored to it.
Definition: gui_region.cpp:565
virtual void notify_scaling_factor_updated()
Tells this region that the global interface scaling factor has changed.
Definition: gui_region.cpp:759
std::size_t get_anchor_count() const
Returns the number of defined anchors.
Definition: gui_region.cpp:519
virtual void update_borders_()
Definition: gui_region.cpp:669
void set_name_(const std::string &name)
Sets this region's name.
Definition: gui_region.cpp:294
void remove_glue()
Removes the Lua glue.
Definition: gui_region.cpp:775
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)
Definition: gui_region.cpp:447
utils::observer_ptr< ObjectType > observer_from(ObjectType *self)
Obtain an observer pointer from a raw pointer (typically 'this')
Definition: gui_region.hpp:946
std::ostream out
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)
Definition: gui_region.cpp:388
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.
Definition: utils_maths.cpp:8
auto find_if(C &v, T &&f)
Definition: utils_std.hpp:19
rounding_method
Rounding method for points to pixels conversions.
Definition: utils_maths.hpp:10
@ 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)
Definition: gui_anchor.hpp:32
vector2< T > bottom_left() const noexcept
Definition: gui_bounds2.hpp:44
static const bounds2 zero
Definition: gui_bounds2.hpp:85
vector2< T > bottom_right() const noexcept
Definition: gui_bounds2.hpp:40
T height() const noexcept
Definition: gui_bounds2.hpp:56
T width() const noexcept
Definition: gui_bounds2.hpp:52
vector2< T > top_right() const noexcept
Definition: gui_bounds2.hpp:36
vector2< T > center() const noexcept
Definition: gui_bounds2.hpp:48
vector2< T > top_left() const noexcept
Definition: gui_bounds2.hpp:32
Struct holding all the core information about a region necessary for its creation.