1 #include "lxgui/gui_region.hpp"
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"
16 #include <lxgui/extern_sol2_state.hpp>
22 utils::enable_observer_from_this<
region>(block), manager_(mgr) {
40 if (
auto* anchor_parent = a->get_parent().get())
41 anchor_parent->remove_anchored_object(*
this);
50 std::vector<utils::observer_ptr<region>> temp_anchored_object_list =
52 for (
const auto& obj : temp_anchored_object_list) {
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);
62 for (
const auto& p : anchored_point_list) {
63 const anchor& a = obj->get_anchor(p);
79 obj->set_anchor(new_anchor);
92 std::ostringstream str;
94 str << tab <<
" # Name : " <<
name_ <<
" ("
95 << std::string(
is_valid_ ?
"valid" :
"not valid")
97 str << tab <<
" # Raw name : " <<
raw_name_ <<
"\n";
100 str << tab <<
" # Parent : " <<
parent_->get_name() <<
"\n";
102 str << tab <<
" # Parent : none\n";
105 str << tab <<
" |-###\n";
108 str << a->serialize(tab);
109 str << tab <<
" |-###\n";
113 str << tab <<
" # Borders :\n";
114 str << tab <<
" |-###\n";
116 str << tab <<
" | # top : " <<
borders_.
top <<
"\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";
133 for (
const std::optional<anchor>& a : obj.
get_anchors()) {
154 return utils::find(type_list, type_name) != type_list.end();
297 if (utils::starts_with(
name_,
"$parent")) {
302 <<
"\" has no parent" << std::endl;
303 utils::replace(
name_,
"$parent",
"");
308 <<
"set_name() can only be called once." << std::endl;
313 if (parent == observer_from_this()) {
366 bool had_anchors =
false;
370 if (
auto parent = a->get_parent()) {
371 parent->remove_anchored_object(*
this);
389 if (utils::observer_ptr<region> other = a.
get_parent()) {
390 if (other->depends_on(
self)) {
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;
405 if (obj_name ==
name_) {
407 <<
": Cannot call set_all_anchors(this)." << std::endl;
428 if (
auto* parent =
top_left->get_parent().get()) {
429 parent->add_anchored_object(*
this);
438 if (obj == observer_from_this()) {
440 <<
": Cannot call set_all_anchors(this)." << std::endl;
450 defined_borders.
top = defined;
451 defined_borders.
left = defined;
455 defined_borders.
top = defined;
456 defined_borders.
right = defined;
460 defined_borders.
bottom = defined;
461 defined_borders.
right = defined;
465 defined_borders.
bottom = defined;
466 defined_borders.
left = defined;
475 auto previous_parent = modified_anchor.has_value() ? modified_anchor->get_parent() :
nullptr;
477 modified_anchor.emplace(*
this, a);
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);
489 modified_anchor.reset();
492 new_parent->add_anchored_object(*
this);
520 std::size_t num_anchors = 0u;
533 "region",
"Cannot modify a point that does not exist. Use set_anchor() first.");
543 "region",
"Cannot get an anchor that does not exist. Use set_anchor() first.");
575 return utils::round(value, 1.0f / scaling_factor, method);
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;
593 }
else if (std::isinf(max)) {
594 if (!std::isinf(size) && size > 0.0f) {
596 }
else if (!std::isinf(
center)) {
597 max = min + 2.0f * (
center - min);
601 }
else if (std::isinf(min)) {
602 if (!std::isinf(size) && size > 0.0f) {
604 }
else if (!std::isinf(
center)) {
605 min = max - 2.0f * (max -
center);
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();
625 const anchor& a = opt_anchor.value();
630 top = std::min<float>(
top, p.
y);
634 top = std::min<float>(
top, p.
y);
638 top = std::min<float>(
top, p.
y);
671 #define DEBUG_LOG(msg)
673 DEBUG_LOG(
" Update anchors for " + lua_name_);
676 const auto old_border_list =
borders_;
682 float x_center = 0.0f, y_center = 0.0f;
684 float rounded_width =
686 float rounded_height =
689 DEBUG_LOG(
" Read anchors");
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));
698 DEBUG_LOG(
" Make borders");
724 DEBUG_LOG(
" Final borders");
732 DEBUG_LOG(
" top=" + utils::to_string(
borders_.
top));
736 DEBUG_LOG(
" Fire redraw");
749 const auto old_border_list =
borders_;
755 object->notify_borders_need_update();
805 return parent_->get_effective_frame_renderer();
819 if (file_name.empty())
822 std::string new_file = file_name;
825 if (new_file[0] ==
'|' &&
addon) {
836 <<
": set_addon() can only be called once." << std::endl;
861 return get_type_list_impl_<region>();
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.
float get_interface_scaling_factor() const
Returns the current UI scaling factor.
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.
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.
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).
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.
manager & get_manager()
Returns this region's manager.
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.
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
utils::observer_ptr< const frame > get_parent() const
Returns this region's parent.
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.
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.
bool is_manually_inherited_
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).
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.
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)
utils::observer_ptr< ObjectType > observer_from(ObjectType *self)
Obtain an observer pointer from a raw pointer (typically 'this')
const std::string warning
bool check_cyclic_anchors(const region &self, anchor &a)
auto find(C &v, const T &s)
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)
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.
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
vector2< T > top_right() const noexcept
vector2< T > center() const noexcept
vector2< T > top_left() const noexcept
Struct holding all the core information about a region necessary for its creation.
utils::observer_ptr< frame > parent