20 #define GETTEXT_DOMAIN "wesnoth-lib"
53 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
68 namespace game_logic {
class function_symbol_table; }
69 namespace gui2 {
class tbutton; }
72 #define LOG_SCOPE_HEADER get_control_type() + " [" + id() + "] " + __func__
73 #define LOG_HEADER LOG_SCOPE_HEADER + ':'
75 #define LOG_IMPL_SCOPE_HEADER \
76 window.get_control_type() + " [" + window.id() + "] " + __func__
77 #define LOG_IMPL_HEADER LOG_IMPL_SCOPE_HEADER + ':'
106 unsigned twindow::sunset_ = 0;
110 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
111 const unsigned SHOW = tdebug_layout_graph::SHOW;
112 const unsigned LAYOUT = tdebug_layout_graph::LAYOUT;
115 const unsigned SHOW = 0;
116 const unsigned LAYOUT = 0;
126 static int draw_interval = 0;
135 static Uint32 draw_timer(Uint32,
void*)
144 data.data1 =
nullptr;
145 data.data2 =
nullptr;
150 SDL_PushEvent(&event);
151 return draw_interval;
161 static Uint32 delay_event_callback(
const Uint32,
void*
event)
163 SDL_PushEvent(static_cast<SDL_Event*>(event));
176 static void delay_event(
const SDL_Event& event,
const Uint32 delay)
178 SDL_AddTimer(delay, delay_event_callback,
new SDL_Event(event));
186 static bool helptip()
188 DBG_GUI_E <<
"Pushing SHOW_HELPTIP_EVENT event in queue.\n";
195 data.data1 =
nullptr;
196 data.data2 =
nullptr;
201 SDL_PushEvent(&event);
217 static tmanager& instance();
219 void add(twindow& window);
221 void remove(twindow& window);
223 unsigned get_id(twindow& window);
225 twindow* window(
const unsigned id);
237 tmanager& tmanager::instance()
239 static tmanager window_manager;
240 return window_manager;
243 void tmanager::add(twindow& window)
256 if(
itor->second == &window) {
270 if(
itor->second == &window) {
279 twindow* tmanager::window(
const unsigned id)
299 const bool automatic_placement,
300 const unsigned horizontal_placement,
301 const unsigned vertical_placement,
302 const unsigned maximum_width,
303 const unsigned maximum_height,
316 , invalidate_layout_blocked_(false)
317 , suspend_drawing_(true)
320 , automatic_placement_(automatic_placement)
321 , horizontal_placement_(horizontal_placement)
322 , vertical_placement_(vertical_placement)
329 , reevaluate_best_size_(reevaluate_best_size)
330 , functions_(functions)
333 , click_dismiss_(false)
334 , enter_disabled_(false)
335 , escape_disabled_(false)
337 , mouse_button_state_(0)
339 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
340 , debug_layout_(new tdebug_layout_graph(this))
342 , event_distributor_(
343 new event::tdistributor(*this, event::tdispatcher::front_child))
350 tmanager::instance().add(*
this);
354 connect_signal<event::DRAW>(std::bind(&
twindow::draw,
this));
356 connect_signal<event::SDL_VIDEO_RESIZE>(std::bind(
359 connect_signal<event::SDL_ACTIVATE>(std::bind(
362 connect_signal<event::SDL_LEFT_BUTTON_UP>(
370 connect_signal<event::SDL_MIDDLE_BUTTON_UP>(
378 connect_signal<event::SDL_RIGHT_BUTTON_UP>(
387 connect_signal<event::SDL_KEY_DOWN>(
391 connect_signal<event::SDL_KEY_DOWN>(std::bind(
394 connect_signal<event::MESSAGE_SHOW_TOOLTIP>(
402 connect_signal<event::MESSAGE_SHOW_HELPTIP>(
410 connect_signal<event::REQUEST_PLACEMENT>(
444 tmanager::instance().remove(*
this);
446 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
448 delete debug_layout_;
456 return tmanager::instance().window(handle);
463 if(draw_interval == 0) {
475 if(rect_gm.w && rect_gm.h) {
499 }
else if(
id ==
"cancel") {
510 }
else if(
id ==
"tutorial") {
512 }
else if(
id ==
"editor") {
514 }
else if(
id ==
"credits") {
516 }
else if(
id ==
"quit") {
524 }
else if(
id ==
"help") {
526 }
else if(
id ==
"campaign") {
528 }
else if(
id ==
"multiplayer") {
530 }
else if(
id ==
"load") {
532 }
else if(
id ==
"addons") {
534 }
else if(
id ==
"cores") {
536 }
else if(
id ==
"language") {
538 }
else if(
id ==
"preferences") {
609 class tdraw_interval_setter
612 tdraw_interval_setter() : interval_(draw_interval)
616 SDL_AddTimer(draw_interval, draw_timer,
nullptr);
624 ~tdraw_interval_setter()
626 draw_interval = interval_;
639 tdraw_interval_setter draw_interval_setter;
649 if(auto_close_timeout) {
658 data.code = tmanager::instance().get_id(*
this);
659 data.data1 =
nullptr;
660 data.data2 =
nullptr;
665 delay_event(event, auto_close_timeout);
672 bool mouse_button_state_initialised =
false;
678 if(!mouse_button_state_initialised) {
690 mouse_button_state_initialised =
true;
777 dirty_list_.push_back(std::vector<twidget*>(1,
this));
784 std::vector<twidget*> call_stack;
790 dirty_list_.push_back(std::vector<twidget*>(1,
this));
801 static unsigned i = 0;
802 if(++i % sunset_ == 0) {
804 0, 0, frame_buffer->w, frame_buffer->h);
806 = SDL_MapRGBA(frame_buffer->format, 0, 0, 0, SDL_ALPHA_OPAQUE);
819 assert(!item.empty());
821 const SDL_Rect dirty_rect
823 : item.back()->get_dirty_rectangle();
829 dirty_list_.push_back(std::vector<twidget*>(1,
this));
861 || (**itor).get_drawing_action()
868 (**citor).set_is_dirty(
false);
871 item.erase(itor, item.end());
887 (**itor).draw_background(frame_buffer, 0, 0);
892 item.back()->draw_children(frame_buffer, 0, 0);
896 for(std::vector<twidget*>::reverse_iterator ritor = item.rbegin();
897 ritor != item.rend();
900 (**ritor).draw_foreground(frame_buffer, 0, 0);
901 (**ritor).set_is_dirty(
false);
909 std::vector<twidget*> call_stack;
911 assert(dirty_list_.empty());
937 assert(window_.invalidate_layout_blocked_);
938 window_.invalidate_layout_blocked_ =
false;
953 const bool must_be_active)
const
970 const bool fixed_width,
971 const bool fixed_height)
973 assert(fixed_width || fixed_height);
990 if(
std::find(widgets.begin(), widgets.end(), widget) == widgets.end()) {
991 widgets.push_back(widget);
1003 =
std::find(widgets.begin(), widgets.end(), widget);
1005 if(itor != widgets.end()) {
1006 widgets.erase(itor);
1008 assert(
std::find(widgets.begin(), widgets.end(), widget)
1043 tbutton* click_dismiss_button =
nullptr;
1044 if((click_dismiss_button
1045 = find_widget<tbutton>(
this,
"click_dismiss",
false,
false))) {
1050 tbutton* button = find_widget<tbutton>(
this,
"ok",
false,
false);
1053 click_dismiss_button = button;
1056 _(
"Click dismiss needs a 'click_dismiss' or 'ok' button."));
1074 std::stringstream sstr;
1075 sstr << __FILE__ <<
":" << __LINE__ <<
" in function '" << __func__
1076 <<
"' found the following problem: Failed to size window;"
1078 << maximum_width <<
',' << maximum_height <<
" screen size "
1082 "which doesn't fit on the screen."),
1088 assert(click_dismiss_button);
1092 *click_dismiss_button,
1103 *
this, maximum_width, maximum_height);
1110 std::stringstream sstr;
1111 sstr << __FILE__ <<
":" << __LINE__ <<
" in function '" << __func__
1112 <<
"' found the following problem: Failed to size window;"
1114 << maximum_width <<
',' << maximum_height <<
" screen size "
1119 "which doesn't fit on the screen."),
1127 assert(size.
x <= maximum_width && size.
y <= maximum_height);
1186 place(origin, size);
1203 for(
auto widget : linked_size.second.widgets)
1208 if(size.
x > max_size.
x) {
1209 max_size.
x = size.
x;
1211 if(size.
y > max_size.
y) {
1212 max_size.
y = size.
y;
1215 if(linked_size.second.width != -1) {
1216 linked_size.second.width = max_size.
x;
1218 if(linked_size.second.height != -1) {
1219 linked_size.second.height = max_size.
y;
1223 for(
auto widget : linked_size.second.widgets)
1228 if(linked_size.second.width != -1) {
1229 size.
x = max_size.
x;
1231 if(linked_size.second.height != -1) {
1232 size.
y = max_size.
y;
1235 widget->set_layout_size(size);
1265 tgrid* content_grid,
1269 assert(content_grid);
1276 tgrid* parent_grid =
nullptr;
1278 parent_grid = find_widget<tgrid>(
grid,
id,
false,
false);
1281 parent_grid = find_widget<tgrid>(content_grid,
id,
true,
false);
1282 assert(parent_grid);
1284 if(tgrid*
g = dynamic_cast<tgrid*>(parent_grid->
parent())) {
1285 widget =
g->swap_child(
id, widget,
false);
1287 = dynamic_cast<tcontainer_*>(parent_grid->
parent())) {
1289 widget =
c->grid().swap_child(
id, widget,
true);
1303 swap_grid(
nullptr, &
grid(), content_grid->build(),
"_window_content_grid");
1306 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
1309 const unsigned domain)
1311 debug_layout_->generate_dot_file(generator, domain);
1316 const unsigned maximum_width,
1317 const unsigned maximum_height)
1332 <<
" maximum size : " << maximum_width <<
','
1333 << maximum_height <<
".\n";
1334 if(size.
x <= static_cast<int>(maximum_width)
1335 && size.
y <= static_cast<int>(maximum_height)) {
1341 if(size.
x > static_cast<int>(maximum_width)) {
1345 if(size.
x > static_cast<int>(maximum_width)) {
1347 <<
" Wanted width " << maximum_width
1348 <<
" resulting width " << size.
x <<
".\n";
1352 <<
" Status: Resize width succeeded.\n";
1355 if(size.
y > static_cast<int>(maximum_height)) {
1359 if(size.
y > static_cast<int>(maximum_height)) {
1361 <<
" Wanted height " << maximum_height
1362 <<
" resulting height " << size.
y <<
".\n";
1366 <<
" Status: Resize height succeeded.\n";
1369 assert(size.
x <= static_cast<int>(maximum_width)
1370 && size.
y <= static_cast<int>(maximum_height));
1379 <<
" Status: Width has been modified, rerun.\n";
1383 layout(window, maximum_width, maximum_height);
1430 const Uint8 mouse_button_mask)
1433 <<
static_cast<unsigned>(mouse_button_mask) <<
".\n";
1444 if(!
enter_disabled_ && (key == SDLK_KP_ENTER || key == SDLK_RETURN)) {
1450 }
else if(key == SDLK_SPACE) {
1453 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
1454 if(key == SDLK_F12) {
1455 debug_layout_->generate_dot_file(
"manual", tdebug_layout_graph::MANUAL);
1467 event::tmessage_show_tooltip& request
1468 =
dynamic_cast<event::tmessage_show_tooltip&
>(
message);
1481 event::tmessage_show_helptip& request
1482 =
dynamic_cast<event::tmessage_show_helptip&
>(
message);
1523 DBG_GUI_P <<
"Parsing window " <<
id <<
'\n';
1525 load_resolutions<tresolution>(cfg);
Define the common log macros for the gui toolkit.
bool escape_disabled_
Disable the escape key see our setter for more info.
bool new_widgets
Do we wish to use the new library or not.
virtual void layout_initialise(const bool full_initialisation) override
See twidget::layout_initialise.
~tinvalidate_layout_blocker()
Defines the exception classes for the layout algorithm.
tformula< unsigned > x_
The x coordinate of the rectangle.
void remove_child(const unsigned row, const unsigned col)
Removes and frees a widget in a cell.
unsigned maximum_height_
The maximum height if automatic_placement_ is true.
Helper for header for the window.
twidget * find(const std::string &id, const bool must_be_active) override
See twidget::find.
static display * get_singleton()
Returns the display object if a display object exists.
const tgrid & grid() const
tformula< unsigned > x_
The formula to calulate the x value of the dialog.
tformula< int > maximum_height_
The maximum height for the text.
bool enter_disabled_
Disable the enter key see our setter for more info.
bool does_click_dismiss() const
Does the window close easily?
void remove_from_keyboard_chain(twidget *widget)
Remove the widget from the keyboard chain.
Play single scenario against humans or AI.
Add a special kind of assert to validate whether the input from WML doesn't contain any problems that...
rng * generator
This generator is automatically synced during synced context.
tretval
Default return values.
GLuint GLuint GLsizei GLenum type
void set_want_keyboard_input(const bool want_keyboard_input)
game_logic::function_symbol_table functions_
The formula definitions available for the calulation formulas.
tresolution_definition_ptr config()
static const unsigned HORIZONTAL_ALIGN_RIGHT
twindow_builder::tresolution::ttip tooltip_
The settings for the tooltip.
void signal_handler_message_show_helptip(const event::tevent event, bool &handled, event::tmessage &message)
std::vector< std::vector< twidget * > > dirty_list_
The list with dirty items in the window.
void signal_handler_sdl_key_down(const event::tevent event, bool &handled, const SDLKey key)
const unsigned horizontal_placement_
Sets the horizontal placement.
twidget * find(const std::string &id, const bool must_be_active) override
See twidget::find.
void add_to_keyboard_chain(twidget *widget)
Adds the widget to the keyboard chain.
static void update_screen_size()
Update the size of the screen variables in settings.
The window has been requested to be closed but still needs to evaluate the request.
surface restorer_
When the window closes this surface is used to undraw the window.
unsigned int get_rows() const
lg::log_domain log_gui_layout("gui/layout")
void connect_signal_mouse_left_click(tdispatcher &dispatcher, const tsignal_function &signal)
Connects a signal handler for a left mouse button click.
void register_hotkey(const hotkey::HOTKEY_COMMAND id, const thotkey_function &function)
Registers a hotkey.
static tretval get_retval_by_id(const std::string &id)
Gets the retval for the default buttons.
GLint GLint GLint GLint GLint GLint y
Contains the event distributor.
void undraw()
Undraws the window.
unsigned gamemap_width
The size of the map area, if not available equal to the screen size.
virtual const std::string & get_control_type() const override
See tcontrol::get_control_type.
std::map< std::string, tlinked_size > linked_size_
List of the widgets, whose size are linked together.
surface get_surface_portion(const surface &src, SDL_Rect &area)
Get a portion of the screen.
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
static twindow * window_instance(const unsigned handle)
Returns the instance of a window.
Definitions for the interface to Wesnoth Markup Language (WML).
The window is new and not yet shown.
The window is being shown.
tcontainer_(const unsigned canvas_count)
Start special campaign 'tutorial'.
bool suspend_drawing_
Avoid drawing the window.
base class of top level items, the only item which needs to store the final canvases to draw on ...
void init_mouse_location()
Initializes the location of the mouse.
A class inherited from ttext_box that displays its input as stars.
#define CLOSE_WINDOW_EVENT
static const unsigned HORIZONTAL_ALIGN_LEFT
void initialize_state()
Initializes the state of the keyboard and mouse.
void signal_handler_sdl_video_resize(const event::tevent event, bool &handled, const tpoint &new_size)
void finalize(const boost::intrusive_ptr< tbuilder_grid > &content_grid)
Finishes the initialization of the grid.
static UNUSEDNOWARN std::string _(const char *str)
bool disable_click_dismiss() const override
See twidget::disable_click_dismiss.
Dialog is closed with ok button.
#define VALIDATE(cond, message)
The macro to use for the validation of WML.
void signal_handler_click_dismiss(const event::tevent event, bool &handled, bool &halt, const Uint8 mouse_button_mask)
The handler for the click dismiss mouse 'event'.
Dialog is closed with no return value, should be rare but eg a message popup can do it...
void draw()
Draws the window.
void remove()
Removes a tip.
void show_tooltip()
Shows the window as a tooltip.
int show(const bool restore=true, const unsigned auto_close_timeout=0)
Shows the window.
static void layout(twindow &window, const unsigned maximum_width, const unsigned maximum_height)
Layouts the window.
Dialog is closed with the cancel button.
GLubyte GLubyte GLubyte GLubyte w
Uint8 mouse_button_state_
The state of the mouse button.
const t_string & tooltip() const
void connect()
Connects the dispatcher to the event handler.
twindow_builder::tresolution::ttip helptip_
The settings for the helptip.
This file contains the defintions for the gui2::event::tmessage class.
void set_retval(const int retval, const bool close_window=true)
Sets there return value of the window.
tpoint get_mouse_position()
Returns the current mouse position.
void generate_dot_file(const std::string &, const unsigned)
virtual void place(const tpoint &origin, const tpoint &size) override
See twidget::place.
tinvalidate_layout_blocker(twindow &window)
#define log_scope2(domain, description)
void init_linked_size_group(const std::string &id, const bool fixed_width, const bool fixed_height)
Initializes a linked size group.
map_display and display: classes which take care of displaying the map and game-data on the screen...
tformula< unsigned > h_
The formula to calulate the height of the dialog.
Exception thrown when the width has been modified during resizing.
void load_config()
Loads the configuration of the widget.
static const unsigned VERTICAL_ALIGN_TOP
tevent
The event send to the dispatcher.
void signal_handler_request_placement(const event::tevent event, bool &handled)
Exception thrown when the width resizing has failed.
Visible container to hold multiple widgets.
tformula< bool > reevaluate_best_size_
The formula to determine whether the size is good.
void layout()
Layouts the window.
void set_mouse_behavior(const tmouse_behavior mouse_behavior)
void show(CVideo &video, const std::string &window_id, const t_string &message, const tpoint &mouse)
Shows a tip.
void reduce_width(const unsigned maximum_width)
Tries to reduce the width of a container.
bool invalidate_layout_blocked_
Is invalidate layout blocked see tinvalidate_layout_blocker.
virtual void layout_children() override
See twidget::layout_children.
bool restore_
Whether the window should undraw the window using restorer_.
std::map< std::string, tfilter >::iterator itor
virtual twidget * find_at(const tpoint &coordinate, const bool must_be_active) override
See twidget::find_at.
#define SHOW_HELPTIP_EVENT
unsigned gamemap_x_offset
The offset between the left edge of the screen and the gamemap.
GLfloat GLfloat GLfloat GLfloat h
void undraw_floating_labels(surface screen)
GLint GLint GLint GLint GLint x
unsigned screen_width
The screen resolution should be available for all widgets since their drawing method will depend on i...
Helper struct to store information about the tips.
virtual twidget * find_at(const tpoint &coordinate, const bool must_be_active) override
See twidget::find_at.
tformula< unsigned > y_
The y coordinate of the rectangle.
tshow_mode show_mode_
The mode in which the window is shown.
GLdouble GLdouble GLdouble r
lg::log_domain log_gui_draw("gui/draw")
static const unsigned VERTICAL_ALIGN_CENTER
void show_non_modal()
Shows the window non modal.
surface & get_video_surface()
tformula< unsigned > y_
The formula to calulate the y value of the dialog.
SDL_Rect create_rect(const int x, const int y, const int w, const int h)
Creates an empty SDL_Rect.
tformula< int > maximum_width_
The maximum width for the text.
Let user select a campaign to play.
Basic exception when the layout doesn't fit.
bool has_linked_size_group(const std::string &id)
Is the linked size group defined for this window?
GLenum GLenum GLvoid * row
Contains the SDL_Rect helper code.
void add_linked_widget(const std::string &id, twidget *widget)
Adds a widget to a linked size group.
twindow_definition(const config &cfg)
tbuilder_window(const config &cfg)
void fill_rect_alpha(SDL_Rect &rect, Uint32 color, Uint8 alpha, surface target)
Fills a specified area of a surface with a given color and opacity.
tstatus status_
The status of the window.
void reduce_height(const unsigned maximum_height)
Tries to reduce the height of a container.
bool find(E event, F functor)
Tests whether an event handler is available.
tresolution(const config &cfg)
const unsigned vertical_placement_
Sets the vertical placement.
Helper struct to force widgets the have the same size.
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
static const unsigned HORIZONTAL_ALIGN_CENTER
void mouse_capture(const bool capture=true)
const SDL_Rect & map_outside_area() const
Returns the available area for a map, this may differ from the above.
GLsizei GLenum GLuint GLuint GLsizei char * message
const std::string remove
remove directive
unsigned maximum_width_
The maximum width if automatic_placement_ is true.
void layout_linked_widgets()
Layouts the linked widgets.
void get_screen_size_variables(game_logic::map_formula_callable &variable)
Gets a formula object with the screen size.
void set_definition(const std::string &definition)
Sets the definition.
const bool automatic_placement_
Do we wish to place the widget automatically?
void sdl_blit(const surface &src, SDL_Rect *src_rect, surface &dst, SDL_Rect *dst_rect)
void keyboard_capture(twidget *widget)
tformula< unsigned > w_
The formula to calulate the width of the dialog.
A config object defines a single node in a WML file, with access to child nodes.
Helper class, don't construct this directly.
void remove_linked_widget(const std::string &id, const twidget *widget)
Removes a widget from a linked size group.
Exception thrown when the height resizing has failed.
static const unsigned VERTICAL_ALIGN_BOTTOM
CVideo & video_
Needed so we can change what's drawn on the screen.
void update_rect(const SDL_Rect &)
game_logic::map_formula_callable variables_
The variables of the canvas.
unsigned int get_cols() const
bool click_dismiss_
Do we want to have easy close behavior?
GLsizei const GLcharARB ** string
bool click_dismiss(const Uint8 mouse_button_mask)
Handles a mouse click event for dismissing the dialogue.
void signal_handler_message_show_tooltip(const event::tevent event, bool &handled, event::tmessage &message)
HOTKEY_COMMAND get_id(const std::string &command)
returns get_hotkey_command(command).id
event::tdistributor * event_distributor_
Contains the implementation details for lexical_cast and shouldn't be used directly.
void draw_floating_labels(surface screen)
void invalidate_layout()
Updates the size of the window.
static unsigned sunset_
Controls the sunset feature.
boost::shared_ptr< halo_record > handle
bool need_layout_
When set the form needs a full layout redraw cycle.