The Battle for Wesnoth  1.15.9+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
36 {
37 namespace dialogs
38 {
39 
41 {
42  static std::string type = "image";
43  return {type, tod.image};
44 }
45 
47 {
48  static std::string type = "mask";
49  return {type, tod.image_mask};
50 }
51 
53 {
54  static std::string type = "sound";
55  return {type, tod.sounds};
56 }
57 
59 
60 custom_tod::custom_tod(const std::vector<time_of_day>& times, int current_time)
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(*get_window());
227  current_tod.color.g = color_field_g_->get_widget_value(*get_window());
228  current_tod.color.b = color_field_b_->get_widget_value(*get_window());
229 
231 }
232 
234 {
236  assert(disp && "Display pointer is null!");
237 
238  // Prevent a floating slice of window appearing alone over the
239  // theme UI sidebar after redrawing tiles and before we have a
240  // chance to redraw the rest of this window.
241  get_window()->undraw();
242 
243  // NOTE: We only really want to re-render the gamemap tiles here.
244  // Redrawing everything is a significantly more expensive task.
245  // At this time, tiles are the only elements on which ToD tint is
246  // meant to have a visible effect. This is very strongly tied to
247  // the image caching mechanism.
248  //
249  // If this ceases to be the case in the future, you'll need to call
250  // redraw_everything() instead.
251 
252  disp->update_tod(&get_selected_tod());
253 
254  // invalidate all tiles so they are redrawn with the new ToD tint next
255  disp->invalidate_all();
256 
257  // redraw tiles
258  disp->draw(false);
259 
260  // NOTE: revert to invalidate_layout if necessary to display the ToD mask image.
261  get_window()->set_is_dirty(true);
262 }
263 
265 {
266  times_[current_tod_].lawful_bonus = find_widget<slider>(get_window(), "lawful_bonus", false).get_value();
267 }
268 
270 {
271  const time_of_day& current_tod = get_selected_tod();
272 
273  find_widget<text_box>(get_window(), "tod_name", false).set_value(current_tod.name);
274  find_widget<text_box>(get_window(), "tod_id", false).set_value(current_tod.id);
275 
276  find_widget<text_box>(get_window(), "path_image", false).set_value(current_tod.image);
277  find_widget<text_box>(get_window(), "path_mask", false).set_value(current_tod.image_mask);
278  find_widget<text_box>(get_window(), "path_sound", false).set_value(current_tod.sounds);
279 
280  find_widget<image>(get_window(), "current_tod_image", false).set_image(current_tod.image);
281  find_widget<image>(get_window(), "current_tod_mask", false).set_image(current_tod.image_mask);
282 
283  find_widget<slider>(get_window(), "lawful_bonus", false).set_value(current_tod.lawful_bonus);
284 
288 
289  const std::string new_index_str = formatter() << (current_tod_ + 1) << "/" << times_.size();
290  find_widget<label>(get_window(), "tod_number", false).set_label(new_index_str);
291 
293 }
294 
296 {
298 }
299 
300 void custom_tod::post_show(window& /*window*/)
301 {
303 
304  if(get_retval() == retval::OK) {
305  // TODO: save ToD
306  }
307 }
308 
309 } // namespace dialogs
310 } // namespace gui2
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:95
std::vector< time_of_day > times_
Available time_of_days.
Definition: custom_tod.hpp:92
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:46
virtual void draw()
Draws invalidated items.
Definition: display.cpp:2479
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:52
Generic file dialog.
Definition: field-fwd.hpp:22
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:213
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:457
field_integer * color_field_g_
Definition: custom_tod.hpp:98
field_integer * color_field_b_
Definition: custom_tod.hpp:99
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:40
void invalidate_all()
Function to invalidate all tiles.
Definition: display.cpp:3015
Various uncategorised dialogs.
styled_widget * get_widget()
Definition: field.hpp:206
field_integer * color_field_r_
Definition: custom_tod.hpp:97
void select_file(const std::string &default_dir)
Definition: custom_tod.cpp:146
virtual void post_show(window &window) override
Inherited from modal_dialog.
Definition: custom_tod.cpp:300
virtual void pre_show(window &window) override
Inherited from modal_dialog.
Definition: custom_tod.cpp:73
Declarations for File-IO.
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: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:295
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