The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
unit_create.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2009 - 2016 by Ignacio R. Morelle <[email protected]>
3  Part of the Battle for Wesnoth Project http://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-lib"
16 
18 
20 #include "gui/core/log.hpp"
21 #include "gui/dialogs/helper.hpp"
22 #ifdef GUI2_EXPERIMENTAL_LISTBOX
23 #include "gui/widgets/list.hpp"
24 #else
25 #include "gui/widgets/listbox.hpp"
26 #endif
27 #include "gui/widgets/settings.hpp"
28 #include "gui/widgets/button.hpp"
29 #include "gui/widgets/image.hpp"
30 #include "gui/widgets/label.hpp"
31 #include "gui/widgets/grid.hpp"
32 #include "gui/widgets/text_box.hpp"
35 #include "gui/widgets/window.hpp"
36 #include "marked-up_text.hpp"
37 #include "help/help.hpp"
38 #include "game_config.hpp"
39 #include "gettext.hpp"
40 #include "play_controller.hpp"
41 #include "resources.hpp"
42 #include "team.hpp"
43 #include "units/types.hpp"
44 
45 #include "utils/functional.hpp"
46 
49 
50 namespace gui2
51 {
52 
53 /*WIKI
54  * @page = GUIWindowDefinitionWML
55  * @order = 2_unit_create
56  *
57  * == Unit create ==
58  *
59  * This shows the debug-mode dialog to create new units on the map.
60  *
61  * @begin{table}{dialog_widgets}
62  *
63  * male_toggle & & toggle_button & m &
64  * Option button to select the "male" gender for created units. $
65  *
66  * female_toggle & & toggle_button & m &
67  * Option button to select the "female" gender for created units. $
68  *
69  * unit_type_list & & listbox & m &
70  * Listbox displaying existing unit types sorted by name and race. $
71  *
72  * -unit_type & & control & m &
73  * Widget which shows the unit type name label. $
74  *
75  * -race & & control & m &
76  * Widget which shows the unit race name label. $
77  *
78  * @end{table}
79  */
80 
81 REGISTER_DIALOG(unit_create)
82 
84  : gender_(last_gender)
85  , choice_(last_chosen_type_id)
86  , last_words_()
87 {
88 }
89 
91 {
92  ttoggle_button& male_toggle
93  = find_widget<ttoggle_button>(&window, "male_toggle", false);
94  ttoggle_button& female_toggle
95  = find_widget<ttoggle_button>(&window, "female_toggle", false);
96 
99 
101 
102  male_toggle.set_callback_state_change(
103  dialog_callback<tunit_create, &tunit_create::gender_toggle_callback>);
104 
105  female_toggle.set_callback_state_change(
106  dialog_callback<tunit_create, &tunit_create::gender_toggle_callback>);
107 
108  tlistbox& list = find_widget<tlistbox>(&window, "unit_type_list", false);
109 
111  = find_widget<ttext_box>(&window, "filter_box", false, true);
112 
114  std::bind(&tunit_create::filter_text_changed, this, _1, _2));
115 
116  window.keyboard_capture(filter);
117 
118 #ifdef GUI2_EXPERIMENTAL_LISTBOX
121  *this,
122  std::ref(window)));
123 #else
125  dialog_callback<tunit_create, &tunit_create::list_item_clicked>);
126 #endif
127 
128  list.clear();
129 
130  for(const auto & i : unit_types.types())
131  {
132  if(i.second.do_not_list())
133  continue;
134 
135  // Make sure this unit type is built with the data we need.
137 
138  units_.push_back(&i.second);
139 
140  std::map<std::string, string_map> row_data;
142 
143  column["label"] = units_.back()->race()->plural_name();
144  row_data.insert(std::make_pair("race", column));
145  column["label"] = units_.back()->type_name();
146  row_data.insert(std::make_pair("unit_type", column));
147 
148  list.add_row(row_data);
149 
150  // Select the previous choice, if any.
151  if(choice_.empty() != true && choice_ == i.first) {
152  list.select_row(list.get_item_count() - 1);
153  }
154  }
155 
156  if(units_.empty()) {
157  ERR_GUI_G << "no unit types found for unit create dialog; not good"
158  << std::endl;
159  }
160 
161  std::vector<tgenerator_::torder_func> order_funcs(2);
162  order_funcs[0] = std::bind(&tunit_create::compare_race, this, _1, _2);
163  order_funcs[1] = std::bind(&tunit_create::compare_race_rev, this, _1, _2);
164  list.set_column_order(0, order_funcs);
165  order_funcs[0] = std::bind(&tunit_create::compare_type, this, _1, _2);
166  order_funcs[1] = std::bind(&tunit_create::compare_type_rev, this, _1, _2);
167  list.set_column_order(1, order_funcs);
168 
169  list_item_clicked(window);
170 }
171 
172 bool tunit_create::compare_type(unsigned i1, unsigned i2) const
173 {
174  return units_[i1]->type_name().str() < units_[i2]->type_name().str();
175 }
176 
177 bool tunit_create::compare_race(unsigned i1, unsigned i2) const
178 {
179  return units_[i1]->race()->plural_name().str() < units_[i2]->race()->plural_name().str();
180 }
181 
182 bool tunit_create::compare_type_rev(unsigned i1, unsigned i2) const
183 {
184  return units_[i1]->type_name().str() > units_[i2]->type_name().str();
185 }
186 
187 bool tunit_create::compare_race_rev(unsigned i1, unsigned i2) const
188 {
189  return units_[i1]->race()->plural_name().str() > units_[i2]->race()->plural_name().str();
190 }
191 
193 {
194  tlistbox& list = find_widget<tlistbox>(&window, "unit_type_list", false);
195 
196  choice_ = "";
197 
198  if(get_retval() != twindow::OK) {
199  return;
200  }
201 
202  const int selected_row = list.get_selected_row();
203  if(selected_row < 0) {
204  return;
205  } else if(static_cast<size_t>(selected_row) >= units_.size()) {
206  // FIXME: maybe assert?
207  ERR_GUI_G << "unit create dialog has more list items than known unit "
208  "types; not good\n";
209  return;
210  }
211 
212  last_chosen_type_id = choice_ = units_[selected_row]->id();
214 }
215 
217 {
218  const int selected_row
219  = find_widget<tlistbox>(&window, "unit_type_list", false).get_selected_row();
220 
221  if(selected_row == -1) {
222  return;
223  }
224 
225  find_widget<tunit_preview_pane>(&window, "unit_details", false)
226  .set_displayed_type(units_[selected_row]);
227 }
228 
230 {
231  twindow& window = *textbox->get_window();
232 
233  tlistbox& list = find_widget<tlistbox>(&window, "unit_type_list", false);
234 
235  const std::vector<std::string> words = utils::split(text, ' ');
236 
237  if(words == last_words_)
238  return;
239  last_words_ = words;
240 
241  std::vector<bool> show_items(list.get_item_count(), true);
242 
243  if(!text.empty()) {
244  for(unsigned int i = 0; i < list.get_item_count(); i++) {
245  tgrid* row = list.get_row_grid(i);
246 
247  tgrid::iterator it = row->begin();
248  tlabel& type_label
249  = find_widget<tlabel>(*it, "unit_type", false);
250 
251  bool found = false;
252  for(const auto & word : words)
253  {
254  found = std::search(type_label.label().str().begin(),
255  type_label.label().str().end(),
256  word.begin(),
257  word.end(),
259  != type_label.label().str().end();
260 
261  if(!found) {
262  // one word doesn't match, we don't reach words.end()
263  break;
264  }
265  }
266 
267  show_items[i] = found;
268  }
269  }
270 
271  list.set_row_shown(show_items);
272 }
273 
275 {
277 }
278 }
Define the common log macros for the gui toolkit.
std::string choice_
Definition: unit_create.hpp:61
int get_retval() const
Definition: dialog.hpp:161
void set_row_shown(const unsigned row, const bool shown)
Makes a row visible or invisible.
Definition: listbox.cpp:150
std::vector< const unit_type * > units_
Definition: unit_create.hpp:57
void connect_signal_notify_modified(tdispatcher &dispatcher, const tsignal_notification_function &signal)
Connects a signal handler for getting a notification upon modification.
Definition: dispatcher.hpp:725
Base container class.
Definition: grid.hpp:29
void gender_toggle_callback(twindow &window)
bool compare_race(unsigned i1, unsigned i2) const
This file contains the window object, this object is a top level container which has the event manage...
bool select_row(const unsigned row, const bool select=true)
Selectes a row.
Definition: listbox.cpp:228
REGISTER_DIALOG(label_settings)
#define ERR_GUI_G
Definition: log.hpp:44
std::vector< std::string > last_words_
Definition: unit_create.hpp:63
void filter_text_changed(ttext_ *textbox, const std::string &text)
unit_type_data unit_types
Definition: types.cpp:1314
Class for a single line text area.
Definition: text_box.hpp:118
Label showing a text.
Definition: label.hpp:29
-file sdl_utils.hpp
void list_item_clicked(twindow &window)
Callbacks.
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
Class for a toggle button.
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
bool chars_equal_insensitive(char a, char b)
Definition: util.hpp:206
Dialog is closed with ok button.
Definition: window.hpp:125
iterator begin()
Definition: grid.hpp:440
This file contains the settings handling of the widget library.
unsigned get_item_count() const
Returns the number of items in the listbox.
Definition: listbox.cpp:138
const unit_type_map & types() const
Definition: types.hpp:313
void add_row(const string_map &item, const int index=-1)
When an item in the list is selected by the user we need to update the state.
Definition: listbox.cpp:74
void set_callback_state_change(std::function< void(twidget &)> callback)
Inherited from tselectable_.
static std::string last_chosen_type_id
Definition: unit_create.cpp:47
void build_unit_type(const unit_type &ut, unit_type::BUILD_STATUS status) const
Makes sure the provided unit_type is built to the specified level.
Definition: types.hpp:326
void set_column_order(unsigned col, const std::vector< tgenerator_::torder_func > &func)
Definition: listbox.cpp:596
Iterator for the tchild items.
Definition: grid.hpp:401
bool compare_race_rev(unsigned i1, unsigned i2) const
const t_string & label() const
Definition: control.hpp:248
static unit_race::GENDER last_gender
Definition: unit_create.cpp:48
void pre_show(twindow &window)
Inherited from tdialog.
Definition: unit_create.cpp:90
std::map< std::string, t_string > string_map
Definition: generator.hpp:23
bool compare_type(unsigned i1, unsigned i2) const
GLenum GLenum GLvoid GLvoid * column
Definition: glew.h:3805
The listbox class.
Definition: listbox.hpp:39
T get_active_member_value()
Returns the value paired with the currently activiely toggled member of the group.
Definition: group.hpp:97
size_t i
Definition: function.cpp:1057
unit_race::GENDER gender_
Definition: unit_create.hpp:59
bool compare_type_rev(unsigned i1, unsigned i2) const
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:3448
GLenum GLenum GLvoid * row
Definition: glew.h:3805
GLenum GLint ref
Definition: glew.h:1813
void set_callback_value_change(const std::function< void(twidget &)> &callback)
Definition: listbox.hpp:225
std::vector< std::string > split(std::string const &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
void add_member(tselectable_ *widget, const T &value)
Adds a widget/value pair to the group vector.
Definition: group.hpp:43
const std::string & str() const
Definition: tstring.hpp:170
twindow * get_window()
Get the parent window.
Definition: widget.cpp:116
int get_selected_row() const
Returns the first selected row.
Definition: listbox.cpp:237
GLsizei const GLcharARB ** string
Definition: glew.h:4503
tgroup< unit_race::GENDER > gender_toggle
Definition: unit_create.hpp:84
void set_member_states(const T &value)
Sets the toggle values for all widgets besides the one associated with the specified value to false...
Definition: group.hpp:113
Abstract base class for text items.
Definition: text.hpp:43
void clear()
Removes all the rows in the listbox, clearing it.
Definition: listbox.cpp:131
void post_show(twindow &window)
Inherited from tdialog.
const tgrid * get_row_grid(const unsigned row) const
Returns the grid of the wanted row.
Definition: listbox.cpp:215
void set_text_changed_callback(std::function< void(ttext_ *textbox, const std::string text)> cb)
Set the text_changed callback.
Definition: text.hpp:87