The Battle for Wesnoth  1.17.0-dev
custom_tod.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2021
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  : times_(times)
61  , current_tod_(current_time)
62  , color_field_r_(register_integer("tod_red", true))
63  , color_field_g_(register_integer("tod_green", true))
64  , color_field_b_(register_integer("tod_blue", true))
65 {
66  if(times_.empty())
67  {
68  times_.push_back(time_of_day());
69  }
70 }
71 
73 {
74  static std::map<std::string, tod_attribute_getter> metadata_stuff {
75  {"image", tod_getter_image},
76  {"mask", tod_getter_mask },
77  {"sound", tod_getter_sound}
78  };
79 
80  window.add_to_tab_order(find_widget<text_box>(&window, "tod_name", false, true));
81  window.add_to_tab_order(find_widget<text_box>(&window, "tod_id", false, true));
82 
83  for(const auto& data : metadata_stuff) {
84  find_widget<text_box>(&window, "path_" + data.first, false).set_active(false);
85 
86  button& copy_w = find_widget<button>(&window, "copy_" + data.first, false);
87 
89  std::bind(&custom_tod::copy_to_clipboard_callback, this, data.second));
90 
92  copy_w.set_active(false);
93  copy_w.set_tooltip(_("Clipboard support not found, contact your packager"));
94  }
95  }
96 
98  find_widget<button>(&window, "browse_image", false),
99  std::bind(&custom_tod::select_file<tod_getter_image>, this, "data/core/images/misc"));
100 
102  find_widget<button>(&window, "browse_mask", false),
103  std::bind(&custom_tod::select_file<tod_getter_mask>, this, "data/core/images"));
104 
106  find_widget<button>(&window, "browse_sound", false),
107  std::bind(&custom_tod::select_file<tod_getter_sound>, this, "data/core/sounds/ambient"));
108 
110  find_widget<button>(&window, "next_tod", false),
111  std::bind(&custom_tod::do_next_tod, this));
112 
114  find_widget<button>(&window, "previous_tod", false),
115  std::bind(&custom_tod::do_prev_tod, this));
116 
118  find_widget<button>(&window, "new", false),
119  std::bind(&custom_tod::do_new_tod, this));
120 
122  find_widget<button>(&window, "delete", false),
123  std::bind(&custom_tod::do_delete_tod, this));
124 
126  find_widget<slider>(&window, "lawful_bonus", false),
127  std::bind(&custom_tod::update_lawful_bonus, this));
128 
131  std::bind(&custom_tod::color_slider_callback, this));
132 
135  std::bind(&custom_tod::color_slider_callback, this));
136 
139  std::bind(&custom_tod::color_slider_callback, this));
140 
142 }
143 
144 template<custom_tod::string_pair(*fptr)(const time_of_day&)>
145 void custom_tod::select_file(const std::string& default_dir)
146 {
147  const string_pair& data = (*fptr)(get_selected_tod());
148 
149  std::string fn = filesystem::base_name(data.second);
150  std::string dn = filesystem::directory_name(fn);
151  if(dn.empty()) {
152  dn = default_dir;
153  }
154 
156 
157  dlg.set_title(_("Choose File"))
158  .set_ok_label(_("Select"))
159  .set_path(dn)
160  .set_read_only(true);
161 
162  if(dlg.show()) {
163  dn = dlg.path();
164 
165  if(data.first == "image") {
166  times_[current_tod_].image = dn;
167  } else if(data.first == "mask") {
168  times_[current_tod_].image_mask = dn;
169  } else if(data.first == "sound") {
170  times_[current_tod_].sounds = dn;
171  }
172  }
173 
175 }
176 
178 {
179  current_tod_ = (current_tod_ + 1) % times_.size();
181 }
182 
184 {
185  current_tod_ = (current_tod_ ? current_tod_ : times_.size()) - 1;
187 }
188 
190 {
191  times_.insert(times_.begin() + current_tod_, time_of_day());
193 }
194 
196 {
197  assert(times_.begin() + current_tod_ < times_.end());
198 
199  if(times_.size() == 1) {
200  times_.emplace_back();
201  } else {
202  times_.erase(times_.begin() + current_tod_);
203 
204  if(times_.begin() + current_tod_ >= times_.end()) {
205  current_tod_ = times_.size() - 1;
206  }
207  }
208 
210 }
211 
213 {
214  try {
215  return times_.at(current_tod_);
216  } catch(const std::out_of_range&) {
217  throw std::string("Attempted to fetch a non-existant ToD!");
218  }
219 }
220 
222 {
223  time_of_day& current_tod = times_[current_tod_];
224 
225  current_tod.color.r = color_field_r_->get_widget_value(*get_window());
226  current_tod.color.g = color_field_g_->get_widget_value(*get_window());
227  current_tod.color.b = color_field_b_->get_widget_value(*get_window());
228 
230 }
231 
233 {
235  assert(disp && "Display pointer is null!");
236 
237  // Prevent a floating slice of window appearing alone over the
238  // theme UI sidebar after redrawing tiles and before we have a
239  // chance to redraw the rest of this window.
240  get_window()->undraw();
241 
242  // NOTE: We only really want to re-render the gamemap tiles here.
243  // Redrawing everything is a significantly more expensive task.
244  // At this time, tiles are the only elements on which ToD tint is
245  // meant to have a visible effect. This is very strongly tied to
246  // the image caching mechanism.
247  //
248  // If this ceases to be the case in the future, you'll need to call
249  // redraw_everything() instead.
250 
251  disp->update_tod(&get_selected_tod());
252 
253  // invalidate all tiles so they are redrawn with the new ToD tint next
254  disp->invalidate_all();
255 
256  // redraw tiles
257  disp->draw(false);
258 
259  // NOTE: revert to invalidate_layout if necessary to display the ToD mask image.
260  get_window()->set_is_dirty(true);
261 }
262 
264 {
265  times_[current_tod_].lawful_bonus = find_widget<slider>(get_window(), "lawful_bonus", false).get_value();
266 }
267 
269 {
270  const time_of_day& current_tod = get_selected_tod();
271 
272  find_widget<text_box>(get_window(), "tod_name", false).set_value(current_tod.name);
273  find_widget<text_box>(get_window(), "tod_id", false).set_value(current_tod.id);
274 
275  find_widget<text_box>(get_window(), "path_image", false).set_value(current_tod.image);
276  find_widget<text_box>(get_window(), "path_mask", false).set_value(current_tod.image_mask);
277  find_widget<text_box>(get_window(), "path_sound", false).set_value(current_tod.sounds);
278 
279  find_widget<image>(get_window(), "current_tod_image", false).set_image(current_tod.image);
280  find_widget<image>(get_window(), "current_tod_mask", false).set_image(current_tod.image_mask);
281 
282  find_widget<slider>(get_window(), "lawful_bonus", false).set_value(current_tod.lawful_bonus);
283 
287 
288  const std::string new_index_str = formatter() << (current_tod_ + 1) << "/" << times_.size();
289  find_widget<label>(get_window(), "tod_number", false).set_label(new_index_str);
290 
292 }
293 
295 {
297 }
298 
299 void custom_tod::post_show(window& /*window*/)
300 {
302 
303  if(get_retval() == retval::OK) {
304  // TODO: save ToD
305  }
306 }
307 
308 } // namespace dialogs
std::pair< std::string, std::string > string_pair
The execute function.
Definition: custom_tod.hpp:56
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:92
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
int current_tod_
Current ToD index.
Definition: custom_tod.hpp:93
std::vector< time_of_day > times_
Available time_of_days.
Definition: custom_tod.hpp:90
tod_color color
The color modifications that should be made to the game board to reflect the time of day...
bool available()
Whether wesnoth was compiled with support for a clipboard.
Definition: clipboard.cpp:55
file_dialog & set_path(const std::string &value)
Sets the initial file selection.
file_dialog & set_ok_label(const std::string &value)
Sets the OK button label.
std::string sounds
List of "ambient" sounds associated with this time_of_day, Played at the beginning of turn...
std::string id
Definition: time_of_day.hpp:90
int lawful_bonus
The % bonus lawful units receive.
Definition: time_of_day.hpp:83
std::string image
The image to be displayed in the game status.
Definition: time_of_day.hpp:87
STL namespace.
window * get_window() const
Returns a pointer to the dialog&#39;s window.
static custom_tod::string_pair tod_getter_mask(const time_of_day &tod)
Definition: custom_tod.cpp:45
virtual void draw()
Draws invalidated items.
Definition: display.cpp:2478
T get_widget_value(window &window)
Gets the value of the field.
Definition: field.hpp:396
Implements some helper classes to ease adding fields to a dialog and hide the synchronization needed...
static std::string _(const char *str)
Definition: gettext.hpp:93
bool show(const unsigned auto_close_time=0)
Shows the window.
static custom_tod::string_pair tod_getter_sound(const time_of_day &tod)
Definition: custom_tod.cpp:51
std::string path() const
Gets the current file selection.
std::string default_dir()
Definition: editor.cpp:33
t_string name
Definition: time_of_day.hpp:88
Object which defines a time of day with associated bonuses, image, sounds etc.
Definition: time_of_day.hpp:56
file_dialog & set_read_only(bool value)
Whether to provide user interface elements for manipulating existing objects.
void set_widget_value(window &window, CT value)
Sets the value of the field.
Definition: field.hpp:359
void set_tooltip(const t_string &tooltip)
void connect_signal_notify_modified(dispatcher &dispatcher, const signal_notification_function &signal)
Connects a signal handler for getting a notification upon modification.
Definition: dispatcher.cpp:187
std::function< string_pair(const time_of_day &)> tod_attribute_getter
Definition: custom_tod.hpp:57
const time_of_day & get_selected_tod() const
Definition: custom_tod.cpp:212
This file contains the settings handling of the widget library.
std::ostringstream wrapper.
Definition: formatter.hpp:39
void connect_signal_mouse_left_click(dispatcher &dispatcher, const signal_function &signal)
Connects a signal handler for a left mouse button click.
Definition: dispatcher.cpp:172
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:466
void update_tod(const time_of_day *tod_override=nullptr)
Applies r,g,b coloring to the map.
Definition: display.cpp:459
field_integer * color_field_g_
Definition: custom_tod.hpp:96
field_integer * color_field_b_
Definition: custom_tod.hpp:97
map_display and display: classes which take care of displaying the map and game-data on the screen...
static custom_tod::string_pair tod_getter_image(const time_of_day &tod)
Definition: custom_tod.cpp:39
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:3019
styled_widget * get_widget()
Definition: field.hpp:207
field_integer * color_field_r_
Definition: custom_tod.hpp:95
void select_file(const std::string &default_dir)
Definition: custom_tod.cpp:145
virtual void post_show(window &window) override
Actions to be taken after the window has been shown.
Definition: custom_tod.cpp:299
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
Definition: custom_tod.cpp:72
Declarations for File-IO.
void do_next_tod()
Callback for the next tod button.
Definition: custom_tod.cpp:177
This shows the dialog to modify tod schedules.
Definition: custom_tod.hpp:48
std::string base_name(const std::string &file, const bool remove_extension)
Returns the base filename of a file, with directory name stripped.
int get_retval() const
Returns the cached window exit code.
void undraw()
Undraws the window.
Definition: window.cpp:776
virtual void set_active(const bool active) override
See styled_widget::set_active.
Definition: button.cpp:63
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
Definition: clipboard.cpp:34
Simple push button.
Definition: button.hpp:36
void copy_to_clipboard_callback(tod_attribute_getter getter)
Definition: custom_tod.cpp:294
Dialog was closed with the OK button.
Definition: retval.hpp:35
void add_to_tab_order(widget *widget, int at=-1)
Add the widget to the tabbing order.
Definition: window.cpp:1294
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:65
std::string directory_name(const std::string &file)
Returns the directory name of a file, with filename stripped.
file_dialog & set_title(const std::string &value)
Sets the current dialog title text.
Definition: file_dialog.hpp:57