The Battle for Wesnoth  1.15.1+dev
unit_recruit.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2016 - 2018 by the Battle for Wesnoth Project https://www.wesnoth.org/
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY.
10 
11  See the COPYING file for more details.
12 */
13 
14 #define GETTEXT_DOMAIN "wesnoth-lib"
15 
18 #include "gui/widgets/button.hpp"
19 #include "gui/widgets/image.hpp"
20 #include "gui/widgets/label.hpp"
21 #include "gui/widgets/listbox.hpp"
23 #include "gui/widgets/settings.hpp"
24 #include "gui/widgets/text_box.hpp"
26 #include "gui/widgets/window.hpp"
27 #include "gettext.hpp"
28 #include "help/help.hpp"
29 #include "play_controller.hpp"
30 #include "resources.hpp"
31 #include "team.hpp"
32 #include "units/types.hpp"
33 #include "whiteboard/manager.hpp"
34 
35 #include "utils/functional.hpp"
36 
37 namespace gui2
38 {
39 namespace dialogs
40 {
41 
42 REGISTER_DIALOG(unit_recruit)
43 
44 unit_recruit::unit_recruit(std::vector<const unit_type*>& recruit_list, team& team)
45  : recruit_list_(recruit_list)
46  , team_(team)
47  , selected_index_(0)
48 {
49  // Ensure the recruit list is sorted by name
50  std::sort(recruit_list_.begin(), recruit_list_.end(), [](const unit_type* t1, const unit_type* t2) {
51  return t1->type_name().str() < t2->type_name().str();
52  });
53 }
54 
55 static std::string can_afford_unit(const std::string& text, const bool can_afford)
56 {
57  return can_afford ? text : "<span color='#ff0000'>" + text + "</span>";
58 }
59 
60 // Compare unit_create::filter_text_change
61 void unit_recruit::filter_text_changed(text_box_base* textbox, const std::string& text)
62 {
63  window& window = *textbox->get_window();
64 
65  listbox& list = find_widget<listbox>(&window, "recruit_list", false);
66 
67  const std::vector<std::string> words = utils::split(text, ' ');
68 
69  if(words == last_words_)
70  return;
71  last_words_ = words;
72 
73  boost::dynamic_bitset<> show_items;
74  show_items.resize(list.get_item_count(), true);
75 
76  if(!text.empty()) {
77  for(unsigned int i = 0; i < list.get_item_count(); i++) {
78  assert(i < recruit_list_.size());
79  const unit_type* type = recruit_list_[i];
80  if(!type) continue;
81 
82  bool found = false;
83  for(const auto & word : words)
84  {
85  // Search for the name in the local language.
86  // In debug mode, also search for the type id.
87  found = (game_config::debug && translation::ci_search(type->id(), word)) ||
88  translation::ci_search(type->type_name(), word);
89 
90  if(!found) {
91  // one word doesn't match, we don't reach words.end()
92  break;
93  }
94  }
95 
96  show_items[i] = found;
97  }
98  }
99 
100  list.set_row_shown(show_items);
101 }
102 
104 {
105  text_box* filter = find_widget<text_box>(&window, "filter_box", false, true);
107  std::bind(&unit_recruit::filter_text_changed, this, _1, _2));
108 
109  listbox& list = find_widget<listbox>(&window, "recruit_list", false);
110 
111  connect_signal_notify_modified(list, std::bind(&unit_recruit::list_item_clicked, this, std::ref(window)));
112 
113  window.keyboard_capture(filter);
114  window.add_to_keyboard_chain(&list);
115 
117  find_widget<button>(&window, "show_help", false),
118  std::bind(&unit_recruit::show_help, this));
119 
120  for(const auto& recruit : recruit_list_)
121  {
122  std::map<std::string, string_map> row_data;
123  string_map column;
124 
125  std::string image_string = recruit->image() + "~RC(" + recruit->flag_rgb() + ">"
126  + team_.color() + ")";
127 
128  int wb_gold = 0;
130  if(const std::shared_ptr<wb::manager>& whiteb = resources::controller->get_whiteboard()) {
131  wb::future_map future; // So gold takes into account planned spending
132  wb_gold = whiteb->get_spent_gold_for(team_.side());
133  }
134  }
135 
136  const bool can_afford = recruit->cost() <= team_.gold() - wb_gold;
137 
138  const std::string cost_string = std::to_string(recruit->cost());
139 
140  column["use_markup"] = "true";
141 
142  column["label"] = image_string;
143  row_data.emplace("unit_image", column);
144 
145  column["label"] = can_afford_unit(recruit->type_name(), can_afford);
146  row_data.emplace("unit_type", column);
147 
148  column["label"] = can_afford_unit(cost_string, can_afford);
149  row_data.emplace("unit_cost", column);
150 
151  list.add_row(row_data);
152  }
153 
154  list_item_clicked(window);
155 }
156 
158 {
159  const int selected_row
160  = find_widget<listbox>(&window, "recruit_list", false).get_selected_row();
161 
162  if(selected_row == -1) {
163  return;
164  }
165 
166  find_widget<unit_preview_pane>(&window, "recruit_details", false)
167  .set_displayed_type(*recruit_list_[selected_row]);
168 }
169 
171 {
172  help::show_help("recruit_and_recall");
173 }
174 
176 {
177  if(get_retval() == retval::OK) {
178  selected_index_ = find_widget<listbox>(&window, "recruit_list", false)
179  .get_selected_row();
180  }
181 }
182 
183 } // namespace dialogs
184 } // namespace gui2
play_controller * controller
Definition: resources.cpp:21
void set_text_changed_callback(std::function< void(text_box_base *textbox, const std::string text)> cb)
Set the text_changed callback.
void show_help(const std::string &show_topic, int xloc, int yloc)
Open the help browser, show topic with id show_topic.
Definition: help.cpp:116
Abstract base class for text items.
static std::string can_afford_unit(const std::string &text, const bool can_afford)
This file contains the window object, this object is a top level container which has the event manage...
STL namespace.
-file sdl_utils.hpp
std::vector< std::string > split(const std::string &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
A single unit type that the player may recruit.
Definition: types.hpp:42
Class for a single line text area.
Definition: text_box.hpp:121
Generic file dialog.
Definition: field-fwd.hpp:22
int gold() const
Definition: team.hpp:189
The listbox class.
Definition: listbox.hpp:40
This class stores all the data for a single &#39;side&#39; (in game nomenclature).
Definition: team.hpp:44
virtual void post_show(window &window) override
Actions to be taken after the window has been shown.
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:248
virtual void pre_show(window &window) override
Inherited from modal_dialog.
This file contains the settings handling of the widget library.
const t_string & type_name() const
The name of the unit in the current language setting.
Definition: types.hpp:135
Applies the planned unit map for the duration of the struct&#39;s life.
Definition: manager.hpp:251
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:233
unsigned get_item_count() const
Returns the number of items in the listbox.
Definition: listbox.cpp:131
Various uncategorised dialogs.
bool ci_search(const std::string &s1, const std::string &s2)
Definition: gettext.cpp:518
std::size_t i
Definition: function.cpp:933
window * get_window()
Get the parent window.
Definition: widget.cpp:114
void list_item_clicked(window &window)
std::map< std::string, t_string > string_map
Definition: widget.hpp:24
grid & 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:66
const bool & debug
static int sort(lua_State *L)
Definition: ltablib.cpp:411
std::vector< const unit_type * > & recruit_list_
const std::string & color() const
Definition: team.hpp:256
void filter_text_changed(text_box_base *textbox, const std::string &text)
Dialog was closed with the OK button.
Definition: retval.hpp:34
int side() const
Definition: team.hpp:188
std::vector< std::string > last_words_
const std::string & str() const
Definition: tstring.hpp:186
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:63
void set_row_shown(const unsigned row, const bool shown)
Makes a row visible or invisible.
Definition: listbox.cpp:143