The Battle for Wesnoth  1.17.23+dev
custom_tod.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2023
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-editor"
17 
19 
20 #include "desktop/clipboard.hpp"
21 #include "display.hpp"
22 #include "filesystem.hpp"
23 #include "formatter.hpp"
24 #include "gettext.hpp"
25 #include "gui/auxiliary/field.hpp"
27 #include "gui/widgets/button.hpp"
28 #include "gui/widgets/image.hpp"
29 #include "gui/widgets/label.hpp"
30 #include "gui/widgets/settings.hpp"
31 #include "gui/widgets/slider.hpp"
32 #include "gui/widgets/text_box.hpp"
33 
34 #include <functional>
35 
36 namespace gui2::dialogs
37 {
38 
40 {
41  static std::string type = "image";
42  return {type, tod.image};
43 }
44 
46 {
47  static std::string type = "mask";
48  return {type, tod.image_mask};
49 }
50 
52 {
53  static std::string type = "sound";
54  return {type, tod.sounds};
55 }
56 
58 
59 custom_tod::custom_tod(const std::vector<time_of_day>& times, int current_time)
60  : modal_dialog(window_id())
61  , times_(times)
62  , current_tod_(current_time)
63  , color_field_r_(register_integer("tod_red", true))
64  , color_field_g_(register_integer("tod_green", true))
65  , color_field_b_(register_integer("tod_blue", true))
66 {
67  if(times_.empty())
68  {
69  times_.push_back(time_of_day());
70  }
71 }
72 
74 {
75  static std::map<std::string, tod_attribute_getter> metadata_stuff {
76  {"image", tod_getter_image},
77  {"mask", tod_getter_mask },
78  {"sound", tod_getter_sound}
79  };
80 
81  window.add_to_tab_order(find_widget<text_box>(&window, "tod_name", false, true));
82  window.add_to_tab_order(find_widget<text_box>(&window, "tod_id", false, true));
83 
84  for(const auto& data : metadata_stuff) {
85  find_widget<text_box>(&window, "path_" + data.first, false).set_active(false);
86 
87  button& copy_w = find_widget<button>(&window, "copy_" + data.first, false);
88 
90  std::bind(&custom_tod::copy_to_clipboard_callback, this, data.second));
91 
93  copy_w.set_active(false);
94  copy_w.set_tooltip(_("Clipboard support not found, contact your packager"));
95  }
96  }
97 
99  find_widget<button>(&window, "browse_image", false),
100  std::bind(&custom_tod::select_file<tod_getter_image>, this, "data/core/images/misc"));
101 
103  find_widget<button>(&window, "browse_mask", false),
104  std::bind(&custom_tod::select_file<tod_getter_mask>, this, "data/core/images"));
105 
107  find_widget<button>(&window, "browse_sound", false),
108  std::bind(&custom_tod::select_file<tod_getter_sound>, this, "data/core/sounds/ambient"));
109 
111  find_widget<button>(&window, "next_tod", false),
112  std::bind(&custom_tod::do_next_tod, this));
113 
115  find_widget<button>(&window, "previous_tod", false),
116  std::bind(&custom_tod::do_prev_tod, this));
117 
119  find_widget<button>(&window, "new", false),
120  std::bind(&custom_tod::do_new_tod, this));
121 
123  find_widget<button>(&window, "delete", false),
124  std::bind(&custom_tod::do_delete_tod, this));
125 
127  find_widget<slider>(&window, "lawful_bonus", false),
128  std::bind(&custom_tod::update_lawful_bonus, this));
129 
132  std::bind(&custom_tod::color_slider_callback, this));
133 
136  std::bind(&custom_tod::color_slider_callback, this));
137 
140  std::bind(&custom_tod::color_slider_callback, this));
141 
143 }
144 
145 template<custom_tod::string_pair(*fptr)(const time_of_day&)>
146 void custom_tod::select_file(const std::string& default_dir)
147 {
148  const string_pair& data = (*fptr)(get_selected_tod());
149 
150  std::string fn = filesystem::base_name(data.second);
151  std::string dn = filesystem::directory_name(fn);
152  if(dn.empty()) {
153  dn = default_dir;
154  }
155 
157 
158  dlg.set_title(_("Choose File"))
159  .set_ok_label(_("Select"))
160  .set_path(dn)
161  .set_read_only(true);
162 
163  if(dlg.show()) {
164  dn = dlg.path();
165 
166  if(data.first == "image") {
167  times_[current_tod_].image = dn;
168  } else if(data.first == "mask") {
169  times_[current_tod_].image_mask = dn;
170  } else if(data.first == "sound") {
171  times_[current_tod_].sounds = dn;
172  }
173  }
174 
176 }
177 
179 {
180  current_tod_ = (current_tod_ + 1) % times_.size();
182 }
183 
185 {
186  current_tod_ = (current_tod_ ? current_tod_ : times_.size()) - 1;
188 }
189 
191 {
192  times_.insert(times_.begin() + current_tod_, time_of_day());
194 }
195 
197 {
198  assert(times_.begin() + current_tod_ < times_.end());
199 
200  if(times_.size() == 1) {
201  times_.emplace_back();
202  } else {
203  times_.erase(times_.begin() + current_tod_);
204 
205  if(times_.begin() + current_tod_ >= times_.end()) {
206  current_tod_ = times_.size() - 1;
207  }
208  }
209 
211 }
212 
214 {
215  try {
216  return times_.at(current_tod_);
217  } catch(const std::out_of_range&) {
218  throw std::string("Attempted to fetch a non-existant ToD!");
219  }
220 }
221 
223 {
224  time_of_day& current_tod = times_[current_tod_];
225 
226  current_tod.color.r = color_field_r_->get_widget_value();
227  current_tod.color.g = color_field_g_->get_widget_value();
228  current_tod.color.b = color_field_b_->get_widget_value();
229 
231 }
232 
234 {
236  assert(disp && "Display pointer is null!");
237 
238  // The display handles invaliding whatever tiles need invalidating.
239  disp->update_tod(&get_selected_tod());
240 
241  // NOTE: revert to invalidate_layout if necessary to display the ToD mask image.
243 }
244 
246 {
247  times_[current_tod_].lawful_bonus = find_widget<slider>(get_window(), "lawful_bonus", false).get_value();
248 }
249 
251 {
252  const time_of_day& current_tod = get_selected_tod();
253 
254  find_widget<text_box>(get_window(), "tod_name", false).set_value(current_tod.name);
255  find_widget<text_box>(get_window(), "tod_id", false).set_value(current_tod.id);
256 
257  find_widget<text_box>(get_window(), "path_image", false).set_value(current_tod.image);
258  find_widget<text_box>(get_window(), "path_mask", false).set_value(current_tod.image_mask);
259  find_widget<text_box>(get_window(), "path_sound", false).set_value(current_tod.sounds);
260 
261  find_widget<image>(get_window(), "current_tod_image", false).set_image(current_tod.image);
262  find_widget<image>(get_window(), "current_tod_mask", false).set_image(current_tod.image_mask);
263 
264  find_widget<slider>(get_window(), "lawful_bonus", false).set_value(current_tod.lawful_bonus);
265 
266  color_field_r_->set_widget_value(current_tod.color.r);
267  color_field_g_->set_widget_value(current_tod.color.g);
268  color_field_b_->set_widget_value(current_tod.color.b);
269 
270  const std::string new_index_str = formatter() << (current_tod_ + 1) << "/" << times_.size();
271  find_widget<label>(get_window(), "tod_number", false).set_label(new_index_str);
272 
274 }
275 
277 {
279 }
280 
281 void custom_tod::post_show(window& /*window*/)
282 {
284 
285  if(get_retval() == retval::OK) {
286  // TODO: save ToD
287  }
288 }
289 
290 } // namespace dialogs
Sort-of-Singleton that many classes, both GUI and non-GUI, use to access the game data.
Definition: display.hpp:87
void update_tod(const time_of_day *tod_override=nullptr)
Applies r,g,b coloring to the map.
Definition: display.cpp:410
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:101
std::ostringstream wrapper.
Definition: formatter.hpp:40
Simple push button.
Definition: button.hpp:37
virtual void set_active(const bool active) override
See styled_widget::set_active.
Definition: button.cpp:65
This shows the dialog to modify tod schedules.
Definition: custom_tod.hpp:49
std::pair< std::string, std::string > string_pair
The execute function.
Definition: custom_tod.hpp:56
field_integer * color_field_g_
Definition: custom_tod.hpp:96
std::function< string_pair(const time_of_day &)> tod_attribute_getter
Definition: custom_tod.hpp:57
void select_file(const std::string &default_dir)
Definition: custom_tod.cpp:146
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
Definition: custom_tod.cpp:73
std::vector< time_of_day > times_
Available time_of_days.
Definition: custom_tod.hpp:90
void copy_to_clipboard_callback(tod_attribute_getter getter)
Definition: custom_tod.cpp:276
const time_of_day & get_selected_tod() const
Definition: custom_tod.cpp:213
void do_next_tod()
Callback for the next tod button.
Definition: custom_tod.cpp:178
field_integer * color_field_b_
Definition: custom_tod.hpp:97
field_integer * color_field_r_
Definition: custom_tod.hpp:95
int current_tod_
Current ToD index.
Definition: custom_tod.hpp:93
virtual void post_show(window &window) override
Actions to be taken after the window has been shown.
Definition: custom_tod.cpp:281
file_dialog & set_ok_label(const std::string &value)
Sets the OK button label.
file_dialog & set_path(const std::string &value)
Sets the initial file selection.
file_dialog & set_title(const std::string &value)
Sets the current dialog title text.
Definition: file_dialog.hpp:59
file_dialog & set_read_only(bool value)
Whether to provide user interface elements for manipulating existing objects.
std::string path() const
Gets the current file selection.
Abstract base class for all modal dialogs.
bool show(const unsigned auto_close_time=0)
Shows the window.
int get_retval() const
Returns the cached window exit code.
window * get_window()
Returns a pointer to the dialog's window.
styled_widget * get_widget()
Definition: field.hpp:193
void set_widget_value(CT value)
Sets the value of the field.
Definition: field.hpp:344
T get_widget_value()
Gets the value of the field.
Definition: field.hpp:379
void set_tooltip(const t_string &tooltip)
void queue_redraw()
Indicates that this widget should be redrawn.
Definition: widget.cpp:456
base class of top level items, the only item which needs to store the final canvases to draw on.
Definition: window.hpp:67
void add_to_tab_order(widget *widget, int at=-1)
Add the widget to the tabbing order.
Definition: window.cpp:1242
Implements some helper classes to ease adding fields to a dialog and hide the synchronization needed.
Declarations for File-IO.
static std::string _(const char *str)
Definition: gettext.hpp:93
#define REGISTER_DIALOG(window_id)
Wrapper for REGISTER_DIALOG2.
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
Definition: clipboard.cpp:34
bool available()
Whether wesnoth was compiled with support for a clipboard.
Definition: clipboard.cpp:55
std::string base_name(const std::string &file, const bool remove_extension)
Returns the base filename of a file, with directory name stripped.
std::string directory_name(const std::string &file)
Returns the directory name of a file, with filename stripped.
static custom_tod::string_pair tod_getter_mask(const time_of_day &tod)
Definition: custom_tod.cpp:45
static custom_tod::string_pair tod_getter_image(const time_of_day &tod)
Definition: custom_tod.cpp:39
static custom_tod::string_pair tod_getter_sound(const time_of_day &tod)
Definition: custom_tod.cpp:51
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification &signal)
Connects a signal handler for getting a notification upon modification.
Definition: dispatcher.cpp:205
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal &signal)
Connects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:179
@ OK
Dialog was closed with the OK button.
Definition: retval.hpp:35
std::string default_dir()
Definition: editor.cpp:33
std::string_view data
Definition: picture.cpp:199
This file contains the settings handling of the widget library.
Object which defines a time of day with associated bonuses, image, sounds etc.
Definition: time_of_day.hpp:57
std::string id
Definition: time_of_day.hpp:90
tod_color color
The color modifications that should be made to the game board to reflect the time of day.
int lawful_bonus
The % bonus lawful units receive.
Definition: time_of_day.hpp:83
t_string name
Definition: time_of_day.hpp:88
std::string image
The image to be displayed in the game status.
Definition: time_of_day.hpp:87
std::string sounds
List of "ambient" sounds associated with this time_of_day, Played at the beginning of turn.
std::string image_mask
The image that is to be laid over all images while this time of day lasts.
Definition: time_of_day.hpp:96