21 #define GETTEXT_DOMAIN "wesnoth-lib" 53 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS 72 namespace wfl {
class function_symbol_table; }
73 namespace gui2 {
class button; }
76 #define ERR_GUI LOG_STREAM(err, log_gui) 78 #define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__ 79 #define LOG_HEADER LOG_SCOPE_HEADER + ':' 81 #define LOG_IMPL_SCOPE_HEADER \ 82 window.get_control_type() + " [" + window.id() + "] " + __func__ 83 #define LOG_IMPL_HEADER LOG_IMPL_SCOPE_HEADER + ':' 103 virtual std::unique_ptr<widget>
build()
const override 114 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS 115 const unsigned SHOW = debug_layout_graph::SHOW;
116 const unsigned LAYOUT = debug_layout_graph::LAYOUT;
119 const unsigned SHOW = 0;
120 const unsigned LAYOUT = 0;
131 static void push_draw_event()
141 SDL_PushEvent(&event);
151 static uint32_t delay_event_callback(
const uint32_t,
void* event)
153 SDL_PushEvent(static_cast<SDL_Event*>(event));
154 delete static_cast<SDL_Event*
>(event);
167 static void delay_event(
const SDL_Event& event,
const uint32_t delay)
169 SDL_AddTimer(delay, delay_event_callback,
new SDL_Event(event));
177 static void helptip()
179 DBG_GUI_E <<
"Pushing SHOW_HELPTIP_EVENT event in queue.\n";
187 SDL_PushEvent(&event);
201 static manager& instance();
205 void remove(window& window);
207 unsigned get_id(window& window);
209 window* get_window(
const unsigned id);
221 manager& manager::instance()
223 static manager window_manager;
224 return window_manager;
227 void manager::add(window& win)
240 if(itor->second == &win) {
254 if(itor->second == &win) {
263 window* manager::get_window(
const unsigned id)
297 ,
w_(definition.width)
298 ,
h_(definition.height)
309 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS 316 manager::instance().add(*
this);
322 connect_signal<event::DRAW>(std::bind(&
window::draw,
this));
325 connect_signal<event::SDL_VIDEO_RESIZE>(std::bind(
328 connect_signal<event::SDL_ACTIVATE>(std::bind(
331 connect_signal<event::SDL_LEFT_BUTTON_UP>(
334 std::placeholders::_2,
335 std::placeholders::_3,
336 std::placeholders::_4,
339 connect_signal<event::SDL_MIDDLE_BUTTON_UP>(
342 std::placeholders::_2,
343 std::placeholders::_3,
344 std::placeholders::_4,
347 connect_signal<event::SDL_RIGHT_BUTTON_UP>(
350 std::placeholders::_2,
351 std::placeholders::_3,
352 std::placeholders::_4,
356 connect_signal<event::SDL_KEY_DOWN>(
360 connect_signal<event::SDL_KEY_DOWN>(std::bind(
363 connect_signal<event::MESSAGE_SHOW_TOOLTIP>(
366 std::placeholders::_2,
367 std::placeholders::_3,
368 std::placeholders::_5),
371 connect_signal<event::MESSAGE_SHOW_HELPTIP>(
374 std::placeholders::_2,
375 std::placeholders::_3,
376 std::placeholders::_5),
379 connect_signal<event::REQUEST_PLACEMENT>(
419 manager::instance().remove(*
this);
421 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS 423 delete debug_layout_;
430 return manager::instance().
get_window(handle);
439 }
else if(
id ==
"cancel" ||
id ==
"quit") {
493 int window::show(
const bool restore,
const unsigned auto_close_timeout)
518 if(auto_close_timeout) {
529 delay_event(event, auto_close_timeout);
536 bool mouse_button_state_initialized =
false;
544 if(!mouse_button_state_initialized) {
556 mouse_button_state_initialized =
true;
598 tb->interrupt_composition();
671 throw std::logic_error(
"The title screen is constantly changing, " 672 "which has a huge CPU usage cost. See the code comment.");
678 assert(!
item.empty());
680 const SDL_Rect dirty_rect
682 :
item.back()->get_dirty_rectangle();
688 dirty_list_.emplace_back(1,
this);
719 || (**itor).get_drawing_action()
726 (**citor).set_is_dirty(
false);
745 (**itor).draw_background(0, 0);
750 item.back()->draw_children(0, 0);
754 for(std::vector<widget*>::reverse_iterator ritor =
item.rbegin();
755 ritor !=
item.rend();
758 (**ritor).draw_foreground(0, 0);
759 (**ritor).set_is_dirty(
false);
769 assert(dirty_list_.empty());
811 const bool must_be_active)
const 828 const bool fixed_width,
829 const bool fixed_height)
831 assert(fixed_width || fixed_height);
846 ERR_GUI <<
"Unknown linked group '" <<
id <<
"'; skipping\n";
851 if(std::find(widgets.begin(), widgets.end(), wgt) == widgets.end()) {
852 widgets.push_back(wgt);
866 = std::find(widgets.begin(), widgets.end(), wgt);
868 if(itor != widgets.end()) {
871 assert(std::find(widgets.begin(), widgets.end(), wgt)
880 const auto conf = cast_config_to<window_definition>();
915 button* click_dismiss_button =
nullptr;
916 if((click_dismiss_button
917 = find_widget<button>(
this,
"click_dismiss",
false,
false))) {
922 button* btn = find_widget<button>(
this,
"ok",
false,
false);
925 click_dismiss_button = btn;
928 _(
"Click dismiss needs a 'click_dismiss' or 'ok' button."));
946 std::stringstream sstr;
947 sstr << __FILE__ <<
":" << __LINE__ <<
" in function '" << __func__
948 <<
"' found the following problem: Failed to size window;" 950 << maximum_width <<
',' << maximum_height <<
" screen size " 954 "which doesn't fit on the screen."),
960 assert(click_dismiss_button);
964 *click_dismiss_button,
975 *
this, maximum_width, maximum_height);
982 std::stringstream sstr;
983 sstr << __FILE__ <<
":" << __LINE__ <<
" in function '" << __func__
984 <<
"' found the following problem: Failed to size window;" 986 << maximum_width <<
',' << maximum_height <<
" screen size " 991 "which doesn't fit on the screen."),
1002 assert(size.x >= 0 && static_cast<unsigned>(size.x) <= maximum_width
1003 && size.y >= 0 && static_cast<unsigned>(size.y) <= maximum_height);
1065 place(origin, size);
1079 point max_size(0, 0);
1087 if(size.
x > max_size.
x) {
1088 max_size.
x = size.
x;
1090 if(size.
y > max_size.
y) {
1091 max_size.
y = size.
y;
1108 size.
x = max_size.
x;
1111 size.
y = max_size.
y;
1135 auto me = std::find(dispatchers.begin(), dispatchers.end(),
this);
1137 for(
auto it = std::next(me); it != dispatchers.end(); ++it) {
1148 static const std::string
id =
"_window_content_grid";
1153 auto* parent_grid = find_widget<grid>(&
get_grid(),
id,
true,
false);
1154 assert(parent_grid);
1156 if(
grid* grandparent_grid = dynamic_cast<grid*>(parent_grid->parent())) {
1157 grandparent_grid->swap_child(
id, std::move(
widget),
false);
1158 }
else if(
container_base*
c = dynamic_cast<container_base*>(parent_grid->parent())) {
1159 c->get_grid().swap_child(
id, std::move(
widget),
true);
1165 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS 1168 const unsigned domain)
1170 debug_layout_->generate_dot_file(generator, domain);
1175 const unsigned maximum_width,
1176 const unsigned maximum_height)
1191 <<
" maximum size : " << maximum_width <<
',' 1192 << maximum_height <<
".\n";
1193 if(size.
x <= static_cast<int>(maximum_width)
1194 && size.
y <= static_cast<int>(maximum_height)) {
1200 if(size.
x > static_cast<int>(maximum_width)) {
1204 if(size.
x > static_cast<int>(maximum_width)) {
1206 <<
" Wanted width " << maximum_width
1207 <<
" resulting width " << size.
x <<
".\n";
1211 <<
" Status: Resize width succeeded.\n";
1214 if(size.
y > static_cast<int>(maximum_height)) {
1218 if(size.
y > static_cast<int>(maximum_height)) {
1220 <<
" Wanted height " << maximum_height
1221 <<
" resulting height " << size.
y <<
".\n";
1225 <<
" Status: Resize height succeeded.\n";
1228 assert(size.
x <= static_cast<int>(maximum_width)
1229 && size.
y <= static_cast<int>(maximum_height));
1238 <<
" Status: Width has been modified, rerun.\n";
1242 layout(window, maximum_width, maximum_height);
1280 if(at < 0 || at >= static_cast<int>(
tab_order.size())) {
1289 const point& new_size)
1305 const int mouse_button_mask)
1308 <<
static_cast<unsigned>(mouse_button_mask) <<
".\n";
1315 if(
const styled_widget* control = dynamic_cast<const styled_widget*>(wgt)) {
1323 const SDL_Keycode key,
1324 const SDL_Keymod mod,
1330 if(tb->is_composing()) {
1331 if(handle_tab && !
tab_order.empty() && key == SDLK_TAB) {
1332 tb->interrupt_composition();
1338 if(!
enter_disabled_ && (key == SDLK_KP_ENTER || key == SDLK_RETURN)) {
1344 }
else if(key == SDLK_SPACE) {
1346 }
else if(handle_tab && !
tab_order.empty() && key == SDLK_TAB) {
1351 if(mod & KMOD_SHIFT) {
1370 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS 1371 if(key == SDLK_F12) {
1372 debug_layout_->generate_dot_file(
"manual", debug_layout_graph::MANUAL);
1426 DBG_GUI_P <<
"Parsing window " <<
id <<
'\n';
1428 load_resolutions<resolution>(cfg);
1439 grid = std::make_shared<builder_grid>(child);
Define the common log macros for the gui toolkit.
bool click_dismiss_
Do we want to have easy close behavior?
void keyboard_capture(widget *widget)
Dialog was closed with the CANCEL button.
bool new_widgets
Do we wish to use the new library or not.
wfl::function_symbol_table functions_
The formula definitions available for the calculation formulas.
~invalidate_layout_blocker()
void remove()
Removes a tip.
Defines the exception classes for the layout algorithm.
void signal_handler_click_dismiss(const event::ui_event event, bool &handled, bool &halt, const int mouse_button_mask)
The handler for the click dismiss mouse 'event'.
config & child(config_key_type key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
void finalize(const builder_grid &content_grid)
Finishes the initialization of the grid.
void reduce_width(const unsigned maximum_width)
Tries to reduce the width of a container.
Helper for header for the window.
typed_formula< unsigned > maximum_height_
The maximum height if automatic_placement_ is true.
bool does_click_dismiss() const
Does the window close easily?
std::function< bool(window &)> exit_hook_
const std::string message
The message to show on the helptip.
Abstract base class for text items.
void signal_handler_sdl_key_down(const event::ui_event event, bool &handled, const SDL_Keycode key, const SDL_Keymod mod, bool handle_tab)
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
typed_formula< unsigned > h_
The formula to calculate the height of the dialog.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
Key Type Default Description window_width unsigned 0 Width of the application window.
ui_event
The event sent to the dispatcher.
const unsigned horizontal_placement_
Sets the horizontal placement.
virtual void place(const point &origin, const point &size) override
See widget::place.
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
const grid & get_grid() const
A panel is a visible container to hold multiple widgets.
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
Main class to show messages to the user.
void register_hotkey(const hotkey::HOTKEY_COMMAND id, const hotkey_function &function)
Registers a hotkey.
CVideo & video_
Needed so we can change what's drawn on the screen.
The window is new and not yet shown.
void show_non_modal()
Shows the window non modal.
void generate_dot_file(const std::string &, const unsigned)
Helper struct to force widgets the have the same size.
unsigned int get_rows() const
unsigned int consecutive_changed_frames_
In how many consecutive frames the window has changed.
Exception thrown when the height resizing has failed.
void draw()
Draws the window.
The message for MESSAGE_SHOW_HELPTIP.
resolution(const config &cfg)
bool is_in_dialog()
Is a dialog open?
lg::log_domain log_gui_layout("gui/layout")
void signal_handler_sdl_video_resize(const event::ui_event event, bool &handled, const point &new_size)
static CVideo & get_singleton()
static const std::string & type()
Static type getter that does not rely on the widget being constructed.
Contains the event distributor.
unsigned gamemap_width
The size of the map area, if not available equal to the screen size.
void add_to_keyboard_chain(widget *widget)
Adds the widget to the keyboard chain.
surface get_surface_portion(const surface &src, SDL_Rect &area)
Get a portion of the screen.
typed_formula< unsigned > w_
The formula to calculate the width of the dialog.
static std::string _(const char *str)
void signal_handler_message_show_tooltip(const event::ui_event event, bool &handled, const event::message &message)
Definitions for the interface to Wesnoth Markup Language (WML).
const point location
The location where to show the helptip.
int mouse_button_state_
The state of the mouse button.
void get_screen_size_variables(wfl::map_formula_callable &variable)
Gets a formula object with the screen size.
void init_mouse_location()
Initializes the location of the mouse.
int width
The current width of all widgets in the group, -1 if the width is not linked.
SDL_Rect draw_area() const
Returns the size and location of the current drawing area in pixels.
The message callbacks hold a reference to a message.
#define CLOSE_WINDOW_EVENT
static bool is_active(const widget *wgt)
The event handler class for the widget library.
void connect()
Connects the dispatcher to the event handler.
static std::string at(const std::string &file, int line)
status status_
The status of the window.
void reduce_height(const unsigned maximum_height)
Tries to reduce the height of a container.
std::size_t size(const std::string &str)
Length in characters of a UTF-8 string.
std::vector< widget * > widgets
The widgets linked.
surface restorer_
When the window closes this surface is used to undraw the window.
Exception thrown when the width has been modified during resizing.
The dialog was closed automatically as its timeout had been reached.
#define VALIDATE(cond, message)
The macro to use for the validation of WML.
bool suspend_drawing_
Avoid drawing the window.
This file contains the settings handling of the widget library.
bool enter_disabled_
Disable the enter key see our setter for more info.
const SDL_Rect source_rect
The size of the entity requesting to show a helptip.
bool invalidate_layout_blocked_
Is invalidate_layout blocked, see invalidate_layout_blocker.
bool need_layout_
When set the form needs a full layout redraw cycle.
void signal_handler_close_window()
typed_formula< bool > reevaluate_best_size_
The formula to determine whether the size is good.
builder_window::window_resolution::tooltip_info helptip_
The settings for the helptip.
bool is_toplevel_
Whether the window has other windows behind it.
std::vector< dispatcher * > & get_all_dispatchers()
Gets all event dispatchers in the Z order.
static const unsigned HORIZONTAL_ALIGN_RIGHT
static thread_local std::deque< std::string > call_stack
For printing error messages when WFL parsing or evaluation fails, this contains the names of the WFL ...
The window is being shown.
This file contains the definitions for the gui2::event::message class.
unsigned int get_cols() const
typed_formula< unsigned > y_
The formula to calculate the y value of the dialog.
Exception thrown when the width resizing has failed.
virtual std::unique_ptr< widget > build() const override
Basic template class to generate new items.
#define log_scope2(domain, description)
const bool automatic_placement_
Do we wish to place the widget automatically?
typed_formula< unsigned > maximum_width_
The maximum width if automatic_placement_ is true.
void init_linked_size_group(const std::string &id, const bool fixed_width, const bool fixed_height)
Initializes a linked size group.
typed_formula< unsigned > x_
The formula to calculate the x value of the dialog.
std::vector< std::vector< widget * > > dirty_list_
The list with dirty items in the window.
void set_mouse_behavior(const mouse_behavior mouse_behavior)
uint32_t get_mouse_button_mask()
Returns the current mouse button mask.
bool escape_disabled_
Disable the escape key see our setter for more info.
The window has been requested to be closed but still needs to evaluate the request.
virtual std::unique_ptr< widget > build() const override
Inherited from builder_widget.
static window * window_instance(const unsigned handle)
Returns the instance of a window.
void add_linked_widget(const std::string &id, widget *widget)
Adds a widget to a linked size group.
widget * find(const std::string &id, const bool must_be_active) override
See widget::find.
Helper class, don't construct this directly.
static const unsigned VERTICAL_ALIGN_TOP
void remove_from_keyboard_chain(widget *widget)
Remove the widget from the keyboard chain.
std::string id
Text to match against addon_info.tags()
invalidate_layout_blocker(window &window)
int show(const bool restore=true, const unsigned auto_close_timeout=0)
Shows the window.
surface & getDrawingSurface()
Returns a reference to the drawing surface.
Default, unset return value.
#define SHOW_HELPTIP_EVENT
virtual void layout_initialize(const bool full_initialization) override
See widget::layout_initialize.
const unsigned vertical_placement_
Sets the vertical placement.
void undraw_floating_labels(surface screen)
std::vector< widget * > tab_order
List of widgets in the tabbing order.
static const unsigned VERTICAL_ALIGN_CENTER
bool has_linked_size_group(const std::string &id)
Is the linked size group defined for this window?
bool click_dismiss(const int mouse_button_mask)
Handles a mouse click event for dismissing the dialog.
static const unsigned HORIZONTAL_ALIGN_CENTER
unsigned screen_width
The screen resolution and pixel pitch should be available for all widgets since their drawing method ...
The window has been closed.
void set_retval(const int retval, const bool close_window=true)
Sets there return value of the window.
lg::log_domain log_gui_draw("gui/draw")
A generic container base class.
void signal_handler_request_placement(const event::ui_event event, bool &handled)
builder_window::window_resolution::tooltip_info tooltip_
The settings for the tooltip.
show_mode show_mode_
The mode in which the window is shown.
static void layout(window &window, const unsigned maximum_width, const unsigned maximum_height)
Layouts the window.
window_definition(const config &cfg)
static const unsigned VERTICAL_ALIGN_BOTTOM
static retval get_retval_by_id(const std::string &id)
Gets the retval for the default buttons.
point get_mouse_position()
Returns the current mouse position.
void undraw()
Undraws the window.
Contains the SDL_Rect helper code.
void remove_child(const unsigned row, const unsigned col)
Removes and frees a widget in a cell.
void show_tooltip()
Shows the window as a tooltip.
void mouse_capture(const bool capture=true)
bool disable_click_dismiss() const override
See widget::disable_click_dismiss.
bool restore_
Whether the window should undraw the window using restorer_.
void redraw_windows_on_top() const
Schedules windows on top of us (if any) to redraw.
void layout()
Layouts the window.
std::unique_ptr< event::distributor > event_distributor_
void signal_handler_message_show_helptip(const event::ui_event event, bool &handled, const event::message &message)
void invalidate_layout()
Updates the size of the window.
friend class debug_layout_graph
dialogs::modal_dialog * owner_
The dialog that owns the window.
retval
Default window/dialog return values.
virtual void layout_children() override
See widget::layout_children.
static const unsigned HORIZONTAL_ALIGN_LEFT
std::unique_ptr< window > build(const builder_window::window_resolution &definition)
Builds a window.
Dialog was closed with the OK button.
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
void remove_linked_widget(const std::string &id, const widget *widget)
Removes a widget from a linked size group.
map_location coordinate
Contains an x and y coordinate used for starting positions in maps.
void sdl_blit(const surface &src, SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
int height
The current height of all widgets in the group, -1 if the height is not linked.
A config object defines a single node in a WML file, with access to child nodes.
void add_to_tab_order(widget *widget, int at=-1)
Add the widget to the tabbing order.
void set_want_keyboard_input(const bool want_keyboard_input)
std::shared_ptr< halo_record > handle
base class of top level items, the only item which needs to store the final canvases to draw on...
std::map< std::string, linked_size > linked_size_
List of the widgets, whose size are linked together.
wfl::map_formula_callable variables_
The variables of the canvas.
std::string::const_iterator iterator
void initialize_state()
Initializes the state of the keyboard and mouse.
HOTKEY_COMMAND get_id(const std::string &command)
returns get_hotkey_command(command).id
builder_window(const config &cfg)
Contains the implementation details for lexical_cast and shouldn't be used directly.
void draw_floating_labels(surface screen)
void layout_linked_widgets()
Layouts the linked widgets.
std::pair< std::string, unsigned > item
void show(const std::string &window_id, const t_string &message, const point &mouse, const SDL_Rect &source_rect)
Shows a tip.
std::function< void()> callback_next_draw_
Basic exception when the layout doesn't fit.