The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
modal_dialog.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2008 - 2025
3 by Mark de Wever <koraq@xs4all.nl>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#define GETTEXT_DOMAIN "wesnoth-lib"
17
19
20#include "cursor.hpp"
21#include "events.hpp"
23#include "gui/core/gui_definition.hpp" // get_window_builder
27#include "video.hpp"
28
29static lg::log_domain log_display("display");
30#define DBG_DP LOG_STREAM(debug, log_display)
31#define WRN_DP LOG_STREAM(warn, log_display)
32
33namespace gui2::dialogs
34{
35
36modal_dialog::modal_dialog(const std::string& window_id)
37 : window(get_window_builder(window_id))
38 , always_save_fields_(false)
39 , fields_()
40 , focus_()
41 , allow_plugin_skip_(true)
42 , show_even_without_video_(false)
43{
45}
46
50
51bool modal_dialog::show(const unsigned auto_close_time)
52{
54 DBG_DP << "modal_dialog::show denied";
55 return false;
56 }
58 bool skipped = false;
59
61 if (pm && pm->any_running())
62 {
63 plugins_context pc("Dialog");
64 pc.set_callback("skip_dialog", [this, &skipped](const config&) { set_retval(retval::OK); skipped = true; }, false);
65 pc.set_callback("quit", [this, &skipped](const config&) { set_retval(retval::CANCEL); skipped = true; }, false);
66 pc.set_callback("select", [this, &skipped](const config& c) { set_retval(c["retval"].to_int()); skipped = true; }, false);
67 pc.set_accessor_string("id", [this](const config&) { return window_id(); });
68 pc.play_slice();
69 }
70
71 if(skipped) {
72 return false;
73 }
74 }
75
77
78 pre_show();
79
80 {
82 window::show(auto_close_time);
83 }
84
86
87 post_show();
88
89 // post_show may update the window retval
90 return get_retval() == retval::OK;
91}
92
93template<typename T, typename... Args>
95{
96 static_assert(std::is_base_of_v<field_base, T>, "Type is not a field type");
97 auto field = std::make_unique<T>(std::forward<Args>(args)...);
98 T* res = field.get();
99 fields_.push_back(std::move(field));
100 return res;
101}
102
104 const std::string& id,
105 const bool mandatory,
106 const std::function<bool()>& callback_load_value,
107 const std::function<void(bool)>& callback_save_value,
108 const std::function<void(widget&)>& callback_change,
109 const bool initial_fire)
110{
111 field_bool* field = new field_bool(id,
112 mandatory,
113 callback_load_value,
114 callback_save_value,
115 callback_change,
116 initial_fire);
117
118 fields_.emplace_back(field);
119 return field;
120}
121
123modal_dialog::register_bool(const std::string& id,
124 const bool mandatory,
125 bool& linked_variable,
126 const std::function<void(widget&)>& callback_change,
127 const bool initial_fire)
128{
130 = new field_bool(id, mandatory, linked_variable, callback_change, initial_fire);
131
132 fields_.emplace_back(field);
133 return field;
134}
135
137 const std::string& id,
138 const bool mandatory,
139 const std::function<int()>& callback_load_value,
140 const std::function<void(int)>& callback_save_value)
141{
143 id, mandatory, callback_load_value, callback_save_value);
144
145 fields_.emplace_back(field);
146 return field;
147}
148
150 const bool mandatory,
151 int& linked_variable)
152{
153 field_integer* field = new field_integer(id, mandatory, linked_variable);
154
155 fields_.emplace_back(field);
156 return field;
157}
158
160 const std::string& id,
161 const bool mandatory,
162 const std::function<std::string()>& callback_load_value,
163 const std::function<void(const std::string&)>& callback_save_value,
164 const bool capture_focus)
165{
167 id, mandatory, callback_load_value, callback_save_value);
168
169 if(capture_focus) {
170 focus_ = id;
171 }
172
173 fields_.emplace_back(field);
174 return field;
175}
176
178 const bool mandatory,
179 std::string& linked_variable,
180 const bool capture_focus)
181{
182 field_text* field = new field_text(id, mandatory, linked_variable);
183
184 if(capture_focus) {
185 focus_ = id;
186 }
187
188 fields_.emplace_back(field);
189 return field;
190}
191
193 const bool mandatory,
194 const std::string& text,
195 const bool use_markup)
196{
197 field_label* field = new field_label(id, mandatory, text, use_markup);
198
199 fields_.emplace_back(field);
200 return field;
201}
202
204{
205 /* DO NOTHING */
206}
207
209{
210 /* DO NOTHING */
211}
212
214{
215 for(auto& field : fields_)
216 {
217 field->attach_to_window(*this);
219 }
220
221 if(!focus_.empty()) {
222 if(widget* widget = window::find(focus_, false)) {
224 }
225 }
226}
227
228void modal_dialog::finalize_fields(const bool save_fields)
229{
230 for(auto& field : fields_)
231 {
232 if(save_fields) {
234 }
236 }
237}
238
239} // namespace dialogs
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
bool always_save_fields_
Always save the fields upon closing.
void init_fields()
Initializes all fields in the dialog and set the keyboard focus.
field_bool * register_bool(const std::string &id, const bool mandatory, const std::function< bool()> &callback_load_value=nullptr, const std::function< void(bool)> &callback_save_value=nullptr, const std::function< void(widget &)> &callback_change=nullptr, const bool initial_fire=false)
Creates a new boolean field.
virtual void post_show()
Actions to be taken after the window has been shown.
virtual const std::string & window_id() const =0
The ID of the window to build.
field_text * register_text(const std::string &id, const bool mandatory, const std::function< std::string()> &callback_load_value=nullptr, const std::function< void(const std::string &)> &callback_save_value=nullptr, const bool capture_focus=false)
Creates a new text field.
std::string focus_
Contains the widget that should get the focus when the window is shown.
std::vector< std::unique_ptr< class field_base > > fields_
Contains the automatically managed fields.
field_label * register_label(const std::string &id, const bool mandatory, const std::string &text, const bool use_markup=false)
Registers a new styled_widget as a label.
modal_dialog(const std::string &window_id)
virtual void pre_show()
Actions to be taken before showing the window.
bool allow_plugin_skip_
Allow plugins to skip through the dialog? Most dialogs install a plugins context to allow plugins to ...
field_integer * register_integer(const std::string &id, const bool mandatory, const std::function< int()> &callback_load_value=nullptr, const std::function< void(int)> &callback_save_value=nullptr)
Creates a new integer field.
T * register_field(Args &&... args)
Creates a new field of given type with given arguments.
void finalize_fields(const bool save_fields)
When the dialog is closed with the OK status saves all fields.
bool show_even_without_video_
Show the dialog even with –nogui? Some dialogs need to be shown even when –nogui is specified if the ...
bool show(const unsigned auto_close_time=0)
Shows the window.
void widget_finalize()
Finalizes the widget.
Definition field.hpp:113
void widget_init()
Initializes the widget.
Definition field.hpp:96
void detach_from_window()
Detaches the field from a window.
Definition field.hpp:124
void attach_to_window(window &window)
Attaches the field to a window.
Definition field.hpp:74
Specialized field class for boolean.
Definition field.hpp:488
Specialized field class for a styled_widget, used for labels and images.
Definition field.hpp:568
Specialized field class for text.
Definition field.hpp:536
Template class to implement the generic field implementation.
Definition field.hpp:245
Base class for all widgets.
Definition widget.hpp:55
void set_id(const std::string &id)
Definition widget.cpp:98
const std::string & id() const
Definition widget.cpp:110
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition window.hpp:59
void set_retval(const int retval, const bool close_window=true)
Sets there return value of the window.
Definition window.hpp:387
void keyboard_capture(widget *widget)
Definition window.cpp:1197
widget * find(const std::string_view id, const bool must_be_active) override
See widget::find.
Definition window.cpp:776
int show(unsigned auto_close_timeout=0)
Shows the window, running an event loop until it should close.
Definition window.cpp:491
int get_retval()
Definition window.hpp:394
void play_slice()
Definition context.cpp:103
void set_callback(const std::string &name, callback_function)
Definition context.cpp:53
void set_accessor_string(const std::string &name, const std::function< std::string(config)> &)
Definition context.cpp:75
static plugins_manager * get()
Definition manager.cpp:58
bool any_running()
Definition manager.cpp:206
#define DBG_DP
Definition display.cpp:79
Implements some helper classes to ease adding fields to a dialog and hide the synchronization needed.
static lg::log_domain log_display("display")
@ NORMAL
Definition cursor.hpp:28
field< int, integer_selector > field_integer
Definition field-fwd.hpp:38
const builder_window::window_resolution & get_window_builder(const std::string &type)
Returns an reference to the requested builder.
@ OK
Dialog was closed with the OK button.
Definition retval.hpp:35
@ CANCEL
Dialog was closed with the CANCEL button.
Definition retval.hpp:38
bool headless()
The game is running headless.
Definition video.cpp:146
#define c