lxgui
gui_manager.cpp
1 #include "lxgui/gui_manager.hpp"
2 
3 #include "lxgui/gui_addon_registry.hpp"
4 #include "lxgui/gui_anchor.hpp"
5 #include "lxgui/gui_event_emitter.hpp"
6 #include "lxgui/gui_factory.hpp"
7 #include "lxgui/gui_frame.hpp"
8 #include "lxgui/gui_key_binder.hpp"
9 #include "lxgui/gui_localizer.hpp"
10 #include "lxgui/gui_out.hpp"
11 #include "lxgui/gui_region.hpp"
12 #include "lxgui/gui_renderer.hpp"
13 #include "lxgui/gui_root.hpp"
14 #include "lxgui/gui_virtual_root.hpp"
15 #include "lxgui/input_dispatcher.hpp"
16 #include "lxgui/input_source.hpp"
17 #include "lxgui/input_window.hpp"
18 #include "lxgui/input_world_dispatcher.hpp"
19 #include "lxgui/utils_std.hpp"
20 
21 #include <sstream>
22 
31 // #define DEBUG_LOG(msg) gui::out << (msg) << std::endl
32 #define DEBUG_LOG(msg)
33 
34 namespace lxgui::gui {
35 
37  utils::control_block& block,
38  std::unique_ptr<input::source> src,
39  std::unique_ptr<renderer> rdr) :
40  utils::enable_observer_from_this<manager>(block),
41  input_source_(std::move(src)),
42  renderer_(std::move(rdr)),
43  window_(std::make_unique<input::window>(*input_source_)),
44  input_dispatcher_(std::make_unique<input::dispatcher>(*input_source_)),
45  world_input_dispatcher_(std::make_unique<input::world_dispatcher>()),
46  event_emitter_(std::make_unique<gui::event_emitter>()),
47  factory_(std::make_unique<factory>(*this)),
48  localizer_(std::make_unique<localizer>()) {
50 
51  // Register base types
52  factory_->register_region_type<region>();
53  factory_->register_region_type<frame>();
54  factory_->register_region_type<layered_region>();
55 
56  window_->on_window_resized.connect([&](const vector2ui& dimensions) {
57  // Update the scaling factor; on mobile platforms, rotating the screen will
58  // trigger a change of window size and resolution, which the scaling factor "hint"
59  // will pick up.
60  set_interface_scaling_factor(base_scaling_factor_);
61 
62  renderer_->notify_window_resized(dimensions);
63  });
64 }
65 
67  close_ui_now();
68 }
69 
70 void manager::set_interface_scaling_factor(float scaling_factor) {
71  float full_scaling_factor = scaling_factor * window_->get_interface_scaling_factor_hint();
72 
73  if (full_scaling_factor == scaling_factor_)
74  return;
75 
76  base_scaling_factor_ = scaling_factor;
77  scaling_factor_ = full_scaling_factor;
78 
79  input_dispatcher_->set_interface_scaling_factor(scaling_factor_);
80 
81  if (root_) {
82  root_->notify_scaling_factor_updated();
83  root_->notify_hovered_frame_dirty();
84  }
85 }
86 
88  return scaling_factor_;
89 }
90 
91 void manager::enable_caching(bool enable_caching) {
92  enable_caching_ = enable_caching;
93  if (root_)
94  root_->enable_caching(enable_caching_);
95 }
96 
98  enable_caching_ = !enable_caching_;
99  if (root_)
100  root_->enable_caching(enable_caching_);
101 }
102 
104  if (root_)
105  return root_->is_caching_enabled();
106  else
107  return enable_caching_;
108 }
109 
110 void manager::add_addon_directory(const std::string& directory) {
111  if (utils::find(gui_directory_list_, directory) == gui_directory_list_.end())
112  gui_directory_list_.push_back(directory);
113 }
114 
116  gui_directory_list_.clear();
117 }
118 
119 void manager::add_localization_directory(const std::string& directory) {
120  if (utils::find(localization_directory_list_, directory) == localization_directory_list_.end())
121  localization_directory_list_.push_back(directory);
122 }
123 
125  localization_directory_list_.clear();
126 }
127 
128 sol::state& manager::get_lua() {
129  return *lua_;
130 }
131 
132 const sol::state& manager::get_lua() const {
133  return *lua_;
134 }
135 
136 void manager::read_files_() {
137  if (is_loaded_ || addon_registry_)
138  return;
139 
140  for (const auto& directory : localization_directory_list_)
141  localizer_->load_translations(directory);
142 
143  addon_registry_ = std::make_unique<addon_registry>(
145 
146  for (const auto& directory : gui_directory_list_)
147  addon_registry_->load_addon_directory(directory);
148 }
149 
151  if (is_loaded_)
152  return;
153 
154  root_ = utils::make_owned<root>(*this);
155  virtual_root_ = utils::make_owned<virtual_root>(*this, get_root().get_registry());
156 
157  create_lua_();
158  read_files_();
159 
160  is_loaded_ = true;
161  close_ui_flag_ = false;
162  reload_ui_flag_ = false;
163 }
164 
166  close_ui_flag_ = true;
167 }
168 
170  if (!is_loaded_)
171  return;
172 
173  if (addon_registry_)
174  addon_registry_->save_variables();
175 
176  virtual_root_ = nullptr;
177  root_ = nullptr;
178  addon_registry_ = nullptr;
179  lua_ = nullptr;
180 
181  localizer_->clear_translations();
182 
183  is_loaded_ = false;
184  is_first_iteration_ = true;
185  close_ui_flag_ = false;
186  reload_ui_flag_ = false;
187 }
188 
190  reload_ui_flag_ = true;
191 }
192 
194  gui::out << "Closing UI..." << std::endl;
195  close_ui_now();
196  gui::out << "Done. Loading UI..." << std::endl;
197  load_ui();
198  // Call update again, otherwise we may call render() with no prior update() call.
199  update_ui(0.0);
200  gui::out << "Done." << std::endl;
201 }
202 
203 void manager::render_ui() const {
204  renderer_->begin();
205 
206  root_->render();
207 
208  renderer_->end();
209 }
210 
211 bool manager::is_loaded() const {
212  return is_loaded_;
213 }
214 
215 void manager::update_ui(float delta) {
216  DEBUG_LOG(" Update regions...");
217  root_->update(delta);
218 
219  if (is_first_iteration_) {
220  DEBUG_LOG(" Entering world...");
221  get_event_emitter().fire_event("ENTERING_WORLD");
222  is_first_iteration_ = false;
223 
224  root_->notify_hovered_frame_dirty();
225  }
226 
227  if (close_ui_flag_) {
228  close_ui_now();
229  } else if (reload_ui_flag_) {
230  reload_ui_now();
231  }
232 }
233 
234 std::string manager::print_ui() const {
235  std::stringstream s;
236 
237  s << "\n\n######################## Regions "
238  "########################\n\n########################\n"
239  << std::endl;
240  for (const auto& frame : root_->get_root_frames()) {
241  s << frame.serialize("") << "\n########################\n" << std::endl;
242  }
243 
244  s << "\n\n#################### Virtual Regions "
245  "####################\n\n########################\n"
246  << std::endl;
247  for (const auto& frame : virtual_root_->get_root_frames()) {
248  s << frame.serialize("") << "\n########################\n" << std::endl;
249  }
250 
251  return s.str();
252 }
253 
254 } // namespace lxgui::gui
Generates events and keep tracks of registered callbacks.
void fire_event(const std::string &event_name, event_data data=event_data{})
Emmit a new event.
Handles the creation of new UI objects.
Definition: gui_factory.hpp:39
A region that can contain other regions and react to events.
Definition: gui_frame.hpp:255
std::string serialize(const std::string &tab) const override
Prints all relevant information about this region in a string.
Definition: gui_frame.cpp:84
A region that can be rendered in a layer.
Utility class to translate strings for display in GUI.
Manages the user interface.
Definition: gui_manager.hpp:44
manager(utils::control_block &block, std::unique_ptr< input::source > src, std::unique_ptr< renderer > rdr)
Constructor.
Definition: gui_manager.cpp:36
void add_localization_directory(const std::string &directory)
Adds a new directory to be parsed for localization.
const event_emitter & get_event_emitter() const
Returns the gui event emitter.
void toggle_caching()
Toggles interface caching.
Definition: gui_manager.cpp:97
localizer & get_localizer()
Returns the object used for localizing strings.
void set_interface_scaling_factor(float scaling_factor)
Sets the global UI scaling factor.
Definition: gui_manager.cpp:70
float get_interface_scaling_factor() const
Returns the current UI scaling factor.
Definition: gui_manager.cpp:87
bool is_loaded() const
Checks if the UI has been loaded.
void load_ui()
Loads the UI.
void render_ui() const
Renders the UI into the current render target.
virtual_root & get_virtual_root()
Returns the UI root object, which contains root frames.
void reload_ui_now()
Closes the UI and load it again (immediately).
std::string print_ui() const
Prints debug information in the log file.
void close_ui()
Closes the UI safely (at the end of update_ui()).
void clear_localization_directory_list()
Clears the localization directory list.
void clear_addon_directory_list()
Clears the addon directory list.
void enable_caching(bool enable_caching)
Enables or disables interface caching.
Definition: gui_manager.cpp:91
void close_ui_now()
Closes the UI (immediately).
root & get_root()
Returns the UI root object, which contains root frames.
sol::state & get_lua()
Returns the GUI Lua state (sol wrapper).
void reload_ui()
Closes the UI and load it again safely (at the end of update_ui()).
~manager() override
Destructor.
Definition: gui_manager.cpp:66
bool is_caching_enabled() const
Checks if interface caching is enabled.
void add_addon_directory(const std::string &directory)
Adds a new directory to be parsed for UI addons.
void update_ui(float delta)
Updates this manager and its regions.
The base class of all elements in the GUI.
Definition: gui_region.hpp:161
std::ostream out
auto find(C &v, const T &s)
Definition: utils_std.hpp:14