The Battle for Wesnoth  1.19.8+dev
units_dialog.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2016 - 2024
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 #pragma once
16 
18 #include "gui/widgets/button.hpp"
19 #include "gui/widgets/group.hpp"
20 #include "gui/widgets/listbox.hpp"
23 #include "team.hpp"
24 #include "units/ptr.hpp"
25 #include "units/types.hpp"
26 
27 #include <string>
28 #include <vector>
29 
30 class team;
31 
32 namespace gui2::dialogs
33 {
34 
35 class units_dialog : public modal_dialog
36 {
37 public:
38  units_dialog();
39 
40  int get_selected_index() const
41  {
42  return selected_index_;
43  }
44 
45  bool is_selected() const
46  {
47  return selected_index_ != -1;
48  }
49 
50  /** Gender choice from the user. */
52  {
53  return gender_;
54  }
55 
56  /** Variation choice from the user. */
57  std::string variation() const
58  {
59  return variation_;
60  }
61 
63  {
64  variation_.clear();
65  }
66 
67  // } --------------- BUILDER HELPERS -------------- {
68 
69  units_dialog& set_title(const std::string& title)
70  {
71  title_ = title;
72  return *this;
73  }
74 
75  units_dialog& set_ok_label(const std::string& ok_label)
76  {
77  ok_label_ = ok_label;
78  return *this;
79  }
80 
81  units_dialog& set_cancel_label(const std::string& cancel_label)
82  {
83  cancel_label_ = cancel_label;
84  return *this;
85  }
86 
88  {
90  return *this;
91  }
92 
94  {
96  return *this;
97  }
98 
100  {
102  return *this;
103  }
104 
105  units_dialog& set_help_topic(const std::string& topic_id)
106  {
107  topic_id_ = topic_id;
108  return *this;
109  }
110 
111  units_dialog& set_row_num(const std::size_t row_num)
112  {
113  num_rows_ = row_num;
114  return *this;
115  }
116 
117  /**
118  * Registers an function which will fired on NOTIFY_MODIFIED dialog events.
119  *
120  * @param f The update function. This should return a const reference to the
121  * appropriate unit or unit type to display in the sidebar.
122  */
123  template<typename Func>
124  void on_modified(const Func& f)
125  {
126  connect_signal<event::NOTIFY_MODIFIED>([this, f](widget& w, auto&&...) {
127  w.find_widget<unit_preview_pane>("unit_details").set_display_data(f(get_selected_index()));
128  });
129  }
130 
131  template<typename Value, typename Func>
132  static auto make_index_wrapper(const std::vector<Value>& list, const Func& func)
133  {
134  return [&list, func](std::size_t index) { return func(list[index]); };
135  }
136 
137  template<typename Sorter>
138  void set_sorter(std::string_view id, const Sorter& sorter)
139  {
140  find_widget<gui2::listbox>("main_list").set_single_sorter(id, sorter);
141  }
142 
143  /** Controls the sort behavior for functions returned by @ref make_column_builder. */
144  enum class sort_type { generator, none };
145 
146  /**
147  * Creates a generator function which registers secondary generator and sorter
148  * functions for the list column associated with the given ID.
149  *
150  * @param list A list of values to associate with the generator functions.
151  * These will be used to populate the dialog's listbox.
152  *
153  * @returns A function which takes takes the following arguments:
154  * - The widget ID whose value will be generated.
155  * - The function which returns said widget's display value.
156  * - A @ref sort_type flag or a function used to order the list.
157  * If sort_type::generator is specified, the second argument
158  * will be used as the sorter.
159  */
160  template<typename Value>
161  auto make_column_builder(const std::vector<Value>& list)
162  {
163  return [this, &list](std::string_view id, const auto& generator, const auto& sorter) {
164  auto wrapper = make_index_wrapper(list, generator);
165  column_generators_.try_emplace(id, wrapper);
166 
167  if constexpr(std::is_invocable_v<decltype(sorter), const Value&>) {
168  set_sorter(id, make_index_wrapper(list, sorter));
169  } else {
170  if(sorter != sort_type::generator) return;
171  set_sorter(id, wrapper);
172  }
173  };
174  }
175 
176  /** Sets the generator function for the tooltips. */
177  template<typename Generator>
179  {
181  return *this;
182  }
183 
184  // } -------------------- BUILDERS -------------------- {
185 
186  static std::unique_ptr<units_dialog> build_create_dialog(const std::vector<const unit_type*>& types_list);
187  static std::unique_ptr<units_dialog> build_recruit_dialog(const std::vector<const unit_type*>& recruit_list, const team& team);
188  static std::unique_ptr<units_dialog> build_recall_dialog(std::vector<unit_const_ptr>& recall_list, const team& team);
189  static std::unique_ptr<units_dialog> build_unit_list_dialog(std::vector<unit_const_ptr>& units_list);
190 
191 private:
193  std::size_t num_rows_;
194 
195  std::string title_;
196  std::string ok_label_;
197  std::string cancel_label_;
198  std::string topic_id_;
199 
203 
204  std::map<std::string_view, std::function<std::string(std::size_t)>> column_generators_;
205  std::function<std::string(std::size_t)> tooltip_gen_;
206 
208  std::string variation_;
209 
210  std::vector<std::string> filter_options_;
212 
214  return gender_toggle_;
215  }
216 
217  /** Callbacks */
218  void list_item_clicked();
219  void filter_text_changed(const std::string& text);
220 
221  // FIXME only thing needing team
222  void dismiss_unit(std::vector<unit_const_ptr>& unit_list, const team& team);
223  void rename_unit(std::vector<unit_const_ptr>& unit_list);
224 
225  void show_list(listbox& list);
226  void show_help() const;
227 
228  void update_gender(const unit_race::GENDER val);
229  void update_variation();
230 
231  virtual const std::string& window_id() const override;
232 
233  virtual void pre_show() override;
234  virtual void post_show() override;
235 };
236 
237 } // namespace gui2::dialogs
Abstract base class for all modal dialogs.
bool show(const unsigned auto_close_time=0)
Shows the window.
static auto make_index_wrapper(const std::vector< Value > &list, const Func &func)
units_dialog & set_tooltip_generator(const Generator &generator)
Sets the generator function for the tooltips.
void show_list(listbox &list)
static std::unique_ptr< units_dialog > build_recruit_dialog(const std::vector< const unit_type * > &recruit_list, const team &team)
std::vector< std::string > filter_options_
units_dialog & set_ok_label(const std::string &ok_label)
auto make_column_builder(const std::vector< Value > &list)
Creates a generator function which registers secondary generator and sorter functions for the list co...
units_dialog & set_show_dismiss(bool show=true)
std::function< std::string(std::size_t)> tooltip_gen_
virtual void post_show() override
Actions to be taken after the window has been shown.
void set_sorter(std::string_view id, const Sorter &sorter)
void rename_unit(std::vector< unit_const_ptr > &unit_list)
std::string variation() const
Variation choice from the user.
units_dialog & set_help_topic(const std::string &topic_id)
units_dialog & set_show_variations(bool show=true)
units_dialog & set_cancel_label(const std::string &cancel_label)
sort_type
Controls the sort behavior for functions returned by make_column_builder.
group< unit_race::GENDER > & get_toggle()
group< unit_race::GENDER > gender_toggle_
void filter_text_changed(const std::string &text)
static std::unique_ptr< units_dialog > build_unit_list_dialog(std::vector< unit_const_ptr > &units_list)
units_dialog & set_show_rename(bool show=true)
units_dialog & set_row_num(const std::size_t row_num)
static std::unique_ptr< units_dialog > build_create_dialog(const std::vector< const unit_type * > &types_list)
void dismiss_unit(std::vector< unit_const_ptr > &unit_list, const team &team)
void on_modified(const Func &f)
Registers an function which will fired on NOTIFY_MODIFIED dialog events.
std::map< std::string_view, std::function< std::string(std::size_t)> > column_generators_
virtual const std::string & window_id() const override
The ID of the window to build.
virtual void pre_show() override
Actions to be taken before showing the window.
void list_item_clicked()
Callbacks.
unit_race::GENDER gender() const
Gender choice from the user.
units_dialog & set_title(const std::string &title)
static std::unique_ptr< units_dialog > build_recall_dialog(std::vector< unit_const_ptr > &recall_list, const team &team)
void update_gender(const unit_race::GENDER val)
Basic template class to generate new items.
The listbox class.
Definition: listbox.hpp:41
Base class for all widgets.
Definition: widget.hpp:55
const std::string & id() const
Definition: widget.cpp:110
This class stores all the data for a single 'side' (in game nomenclature).
Definition: team.hpp:75
int w
std::size_t index(std::string_view str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:70
#define f