The Battle for Wesnoth  1.17.12+dev
custom_tod.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2022
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
window(const builder_window::window_resolution &definition)
< Needs to be initialized in show.
Definition: window.cpp:263
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:98
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.
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
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
void set_widget_value(CT value)
Sets the value of the field.
Definition: field.hpp:344
std::string_view data
Definition: picture.cpp:206
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.
static custom_tod::string_pair tod_getter_mask(const time_of_day &tod)
Definition: custom_tod.cpp:45
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
virtual void set_label(const t_string &label)
file_dialog & set_read_only(bool value)
Whether to provide user interface elements for manipulating existing objects.
void set_tooltip(const t_string &tooltip)
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:213
This file contains the settings handling of the widget library.
std::ostringstream wrapper.
Definition: formatter.hpp:39
void update_tod(const time_of_day *tod_override=nullptr)
Applies r,g,b coloring to the map.
Definition: display.cpp:429
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
window * get_window()
Returns a pointer to the dialog&#39;s window.
styled_widget * get_widget()
Definition: field.hpp:193
field_integer * color_field_r_
Definition: custom_tod.hpp:95
void select_file(const std::string &default_dir)
Definition: custom_tod.cpp:146
void queue_redraw()
Indicates that this widget should be redrawn.
Definition: widget.cpp:442
virtual void post_show(window &window) override
Actions to be taken after the window has been shown.
Definition: custom_tod.cpp:281
T get_widget_value()
Gets the value of the field.
Definition: field.hpp:379
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
Definition: custom_tod.cpp:73
Declarations for File-IO.
virtual void set_active(const bool active) override
See styled_widget::set_active.
void do_next_tod()
Callback for the next tod button.
Definition: custom_tod.cpp:178
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.
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
Abstract base class for all modal dialogs.
Simple push button.
Definition: button.hpp:36
void copy_to_clipboard_callback(tod_attribute_getter getter)
Definition: custom_tod.cpp:276
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:1149
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:66
std::string directory_name(const std::string &file)
Returns the directory name of a file, with filename stripped.
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
file_dialog & set_title(const std::string &value)
Sets the current dialog title text.
Definition: file_dialog.hpp:57