The Battle for Wesnoth  1.15.11+dev
custom_tod.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2018 by Mark de Wever <koraq@xs4all.nl>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #define GETTEXT_DOMAIN "wesnoth-editor"
16 
18 
19 #include "desktop/clipboard.hpp"
20 #include "display.hpp"
21 #include "filesystem.hpp"
22 #include "formatter.hpp"
23 #include "gettext.hpp"
24 #include "gui/auxiliary/field.hpp"
26 #include "gui/widgets/button.hpp"
27 #include "gui/widgets/image.hpp"
28 #include "gui/widgets/label.hpp"
29 #include "gui/widgets/settings.hpp"
30 #include "gui/widgets/slider.hpp"
31 #include "gui/widgets/text_box.hpp"
32 
33 #include <functional>
34 
35 namespace gui2::dialogs
36 {
37 
39 {
40  static std::string type = "image";
41  return {type, tod.image};
42 }
43 
45 {
46  static std::string type = "mask";
47  return {type, tod.image_mask};
48 }
49 
51 {
52  static std::string type = "sound";
53  return {type, tod.sounds};
54 }
55 
57 
58 custom_tod::custom_tod(const std::vector<time_of_day>& times, int current_time)
59  : times_(times)
60  , current_tod_(current_time)
61  , color_field_r_(register_integer("tod_red", true))
62  , color_field_g_(register_integer("tod_green", true))
63  , color_field_b_(register_integer("tod_blue", true))
64 {
65  if(times_.empty())
66  {
67  times_.push_back(time_of_day());
68  }
69 }
70 
72 {
73  static std::map<std::string, tod_attribute_getter> metadata_stuff {
74  {"image", tod_getter_image},
75  {"mask", tod_getter_mask },
76  {"sound", tod_getter_sound}
77  };
78 
79  window.add_to_tab_order(find_widget<text_box>(&window, "tod_name", false, true));
80  window.add_to_tab_order(find_widget<text_box>(&window, "tod_id", false, true));
81 
82  for(const auto& data : metadata_stuff) {
83  find_widget<text_box>(&window, "path_" + data.first, false).set_active(false);
84 
85  button& copy_w = find_widget<button>(&window, "copy_" + data.first, false);
86 
88  std::bind(&custom_tod::copy_to_clipboard_callback, this, data.second));
89 
91  copy_w.set_active(false);
92  copy_w.set_tooltip(_("Clipboard support not found, contact your packager"));
93  }
94  }
95 
97  find_widget<button>(&window, "browse_image", false),
98  std::bind(&custom_tod::select_file<tod_getter_image>, this, "data/core/images/misc"));
99 
101  find_widget<button>(&window, "browse_mask", false),
102  std::bind(&custom_tod::select_file<tod_getter_mask>, this, "data/core/images"));
103 
105  find_widget<button>(&window, "browse_sound", false),
106  std::bind(&custom_tod::select_file<tod_getter_sound>, this, "data/core/sounds/ambient"));
107 
109  find_widget<button>(&window, "next_tod", false),
110  std::bind(&custom_tod::do_next_tod, this));
111 
113  find_widget<button>(&window, "previous_tod", false),
114  std::bind(&custom_tod::do_prev_tod, this));
115 
117  find_widget<button>(&window, "new", false),
118  std::bind(&custom_tod::do_new_tod, this));
119 
121  find_widget<button>(&window, "delete", false),
122  std::bind(&custom_tod::do_delete_tod, this));
123 
125  find_widget<slider>(&window, "lawful_bonus", false),
126  std::bind(&custom_tod::update_lawful_bonus, this));
127 
130  std::bind(&custom_tod::color_slider_callback, this));
131 
134  std::bind(&custom_tod::color_slider_callback, this));
135 
138  std::bind(&custom_tod::color_slider_callback, this));
139 
141 }
142 
143 template<custom_tod::string_pair(*fptr)(const time_of_day&)>
144 void custom_tod::select_file(const std::string& default_dir)
145 {
146  const string_pair& data = (*fptr)(get_selected_tod());
147 
148  std::string fn = filesystem::base_name(data.second);
149  std::string dn = filesystem::directory_name(fn);
150  if(dn.empty()) {
151  dn = default_dir;
152  }
153 
155 
156  dlg.set_title(_("Choose File"))
157  .set_ok_label(_("Select"))
158  .set_path(dn)
159  .set_read_only(true);
160 
161  if(dlg.show()) {
162  dn = dlg.path();
163 
164  if(data.first == "image") {
165  times_[current_tod_].image = dn;
166  } else if(data.first == "mask") {
167  times_[current_tod_].image_mask = dn;
168  } else if(data.first == "sound") {
169  times_[current_tod_].sounds = dn;
170  }
171  }
172 
174 }
175 
177 {
178  current_tod_ = (current_tod_ + 1) % times_.size();
180 }
181 
183 {
184  current_tod_ = (current_tod_ ? current_tod_ : times_.size()) - 1;
186 }
187 
189 {
190  times_.insert(times_.begin() + current_tod_, time_of_day());
192 }
193 
195 {
196  assert(times_.begin() + current_tod_ < times_.end());
197 
198  if(times_.size() == 1) {
199  times_.emplace_back();
200  } else {
201  times_.erase(times_.begin() + current_tod_);
202 
203  if(times_.begin() + current_tod_ >= times_.end()) {
204  current_tod_ = times_.size() - 1;
205  }
206  }
207 
209 }
210 
212 {
213  try {
214  return times_.at(current_tod_);
215  } catch(const std::out_of_range&) {
216  throw std::string("Attempted to fetch a non-existant ToD!");
217  }
218 }
219 
221 {
222  time_of_day& current_tod = times_[current_tod_];
223 
224  current_tod.color.r = color_field_r_->get_widget_value(*get_window());
225  current_tod.color.g = color_field_g_->get_widget_value(*get_window());
226  current_tod.color.b = color_field_b_->get_widget_value(*get_window());
227 
229 }
230 
232 {
234  assert(disp && "Display pointer is null!");
235 
236  // Prevent a floating slice of window appearing alone over the
237  // theme UI sidebar after redrawing tiles and before we have a
238  // chance to redraw the rest of this window.
239  get_window()->undraw();
240 
241  // NOTE: We only really want to re-render the gamemap tiles here.
242  // Redrawing everything is a significantly more expensive task.
243  // At this time, tiles are the only elements on which ToD tint is
244  // meant to have a visible effect. This is very strongly tied to
245  // the image caching mechanism.
246  //
247  // If this ceases to be the case in the future, you'll need to call
248  // redraw_everything() instead.
249 
250  disp->update_tod(&get_selected_tod());
251 
252  // invalidate all tiles so they are redrawn with the new ToD tint next
253  disp->invalidate_all();
254 
255  // redraw tiles
256  disp->draw(false);
257 
258  // NOTE: revert to invalidate_layout if necessary to display the ToD mask image.
259  get_window()->set_is_dirty(true);
260 }
261 
263 {
264  times_[current_tod_].lawful_bonus = find_widget<slider>(get_window(), "lawful_bonus", false).get_value();
265 }
266 
268 {
269  const time_of_day& current_tod = get_selected_tod();
270 
271  find_widget<text_box>(get_window(), "tod_name", false).set_value(current_tod.name);
272  find_widget<text_box>(get_window(), "tod_id", false).set_value(current_tod.id);
273 
274  find_widget<text_box>(get_window(), "path_image", false).set_value(current_tod.image);
275  find_widget<text_box>(get_window(), "path_mask", false).set_value(current_tod.image_mask);
276  find_widget<text_box>(get_window(), "path_sound", false).set_value(current_tod.sounds);
277 
278  find_widget<image>(get_window(), "current_tod_image", false).set_image(current_tod.image);
279  find_widget<image>(get_window(), "current_tod_mask", false).set_image(current_tod.image_mask);
280 
281  find_widget<slider>(get_window(), "lawful_bonus", false).set_value(current_tod.lawful_bonus);
282 
286 
287  const std::string new_index_str = formatter() << (current_tod_ + 1) << "/" << times_.size();
288  find_widget<label>(get_window(), "tod_number", false).set_label(new_index_str);
289 
291 }
292 
294 {
296 }
297 
298 void custom_tod::post_show(window& /*window*/)
299 {
301 
302  if(get_retval() == retval::OK) {
303  // TODO: save ToD
304  }
305 }
306 
307 } // namespace dialogs
std::pair< std::string, std::string > string_pair
The execute function.
Definition: custom_tod.hpp:55
static display * get_singleton()
Returns the display object if a display object exists.
Definition: display.hpp:90
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:95
int current_tod_
Current ToD index.
Definition: custom_tod.hpp:92
std::vector< time_of_day > times_
Available time_of_days.
Definition: custom_tod.hpp:89
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:54
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:89
int lawful_bonus
The % bonus lawful units receive.
Definition: time_of_day.hpp:82
std::string image
The image to be displayed in the game status.
Definition: time_of_day.hpp:86
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:44
virtual void draw()
Draws invalidated items.
Definition: display.cpp:2466
T get_widget_value(window &window)
Gets the value of the field.
Definition: field.hpp:395
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:92
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:50
std::string path() const
Gets the current file selection.
std::string default_dir()
Definition: editor.cpp:32
t_string name
Definition: time_of_day.hpp:87
Object which defines a time of day with associated bonuses, image, sounds etc.
Definition: time_of_day.hpp:55
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:358
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:186
std::function< string_pair(const time_of_day &)> tod_attribute_getter
Definition: custom_tod.hpp:56
const time_of_day & get_selected_tod() const
Definition: custom_tod.cpp:211
This file contains the settings handling of the widget library.
std::ostringstream wrapper.
Definition: formatter.hpp:38
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:171
void set_is_dirty(const bool is_dirty)
Definition: widget.cpp:465
void update_tod(const time_of_day *tod_override=nullptr)
Applies r,g,b coloring to the map.
Definition: display.cpp:456
field_integer * color_field_g_
Definition: custom_tod.hpp:95
field_integer * color_field_b_
Definition: custom_tod.hpp:96
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:38
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:3006
styled_widget * get_widget()
Definition: field.hpp:206
field_integer * color_field_r_
Definition: custom_tod.hpp:94
void select_file(const std::string &default_dir)
Definition: custom_tod.cpp:144
virtual void post_show(window &window) override
Actions to be taken after the window has been shown.
Definition: custom_tod.cpp:298
virtual void pre_show(window &window) override
Actions to be taken before showing the window.
Definition: custom_tod.cpp:71
Declarations for File-IO.
void do_next_tod()
Callback for the next tod button.
Definition: custom_tod.cpp:176
This shows the dialog to modify tod schedules.
Definition: custom_tod.hpp:47
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:773
virtual void set_active(const bool active) override
See styled_widget::set_active.
Definition: button.cpp:62
void copy_to_clipboard(const std::string &text, const bool)
Copies text to the clipboard.
Definition: clipboard.cpp:33
Simple push button.
Definition: button.hpp:35
void copy_to_clipboard_callback(tod_attribute_getter getter)
Definition: custom_tod.cpp:293
Dialog was closed with the OK button.
Definition: retval.hpp:34
void add_to_tab_order(widget *widget, int at=-1)
Add the widget to the tabbing order.
Definition: window.cpp:1291
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:64
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:56