The Battle for Wesnoth  1.17.21+dev
tree_view.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 - 2023
3  by Mark de Wever <koraq@xs4all.nl>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
20 
21 namespace gui2
22 {
23 
24 namespace implementation {
25  struct builder_tree_view;
26  struct tree_node
27  {
28  explicit tree_node(const config& cfg);
29 
30  std::string id;
31  bool unfolded;
33  };
34 }
35 
36 // ------------ WIDGET -----------{
37 
38 class tree_view_node;
39 
40 /**
41  * @ingroup GUIWidgetWML
42  *
43  * A tree view is a control that holds several items of the same or different types.
44  * The items shown are called tree view nodes and when a node has children, these can be shown or hidden.
45  * Nodes that contain children need to provide a clickable button in order to fold or unfold the children.
46  *
47  * The following states exist:
48  * * state_enabled - the listbox is enabled.
49  * * state_disabled - the listbox is disabled.
50  * List with the tree view specific variables:
51  * Key |Type |Default |Description
52  * -------------------------|------------------------------------------------|------------|-------------
53  * vertical_scrollbar_mode | @ref guivartype_scrollbar_mode "scrollbar_mode"|initial_auto|Determines whether or not to show the scrollbar.
54  * horizontal_scrollbar_mode| @ref guivartype_scrollbar_mode "scrollbar_mode"|initial_auto|Determines whether or not to show the scrollbar.
55  * indention_step_size | @ref guivartype_unsigned "unsigned" |0 |The number of pixels every level of nodes is indented from the previous level.
56  * node | @ref guivartype_unsigned "unsigned" |mandatory |The tree view can contain multiple node sections. This part needs more documentation.
57  * id | @ref guivartype_unsigned "unsigned" |"" |.
58  * return_value_id | @ref guivartype_unsigned "unsigned" |"" |.
59  */
61 {
64  friend class tree_view_node;
65 
66 public:
68 
69  explicit tree_view(const implementation::builder_tree_view& builder);
70 
71  ~tree_view();
72 
74 
76  {
77  return *root_node_;
78  }
79 
81  const std::string& id, const widget_data& data, const int index = -1);
82 
83  /**
84  * Removes the given node as a child of its parent node.
85  *
86  * @param node A pointer to the node to remove.
87  *
88  * @returns A pair consisting of a smart pointer managing the removed
89  * node, and its position before removal.
90  */
91  std::pair<std::shared_ptr<tree_view_node>, int> remove_node(tree_view_node* node);
92 
93  void clear();
94 
95  /** See @ref container_base::set_self_active. */
96  virtual void set_self_active(const bool active) override;
97 
98  bool empty() const;
99 
100  /** See @ref widget::layout_children. */
101  virtual void layout_children() override;
102 
103  /***** ***** ***** setters / getters for members ***** ****** *****/
104 
105  void set_indentation_step_size(const unsigned indentation_step_size)
106  {
107  indentation_step_size_ = indentation_step_size;
108  }
109 
111  {
112  return selected_item_;
113  }
114 
116  {
117  return selected_item_;
118  }
119 
120  const std::vector<node_definition>& get_node_definitions() const
121  {
122  return node_definitions_;
123  }
124 
125 protected:
126  /***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
127 
128  /** Inherited from scrollbar_container. */
129  void handle_key_up_arrow(SDL_Keymod modifier, bool& handled) override;
130 
131  /** Inherited from scrollbar_container. */
132  void handle_key_down_arrow(SDL_Keymod modifier, bool& handled) override;
133 
134  /** Inherited from scrollbar_container. */
135  void handle_key_left_arrow(SDL_Keymod modifier, bool& handled) override;
136 
137  /** Inherited from scrollbar_container. */
138  void handle_key_right_arrow(SDL_Keymod modifier, bool& handled) override;
139 
140 private:
141  static inline const std::string root_node_id = "root";
142 
143  /**
144  * @todo evaluate which way the dependency should go.
145  *
146  * We no depend on the implementation, maybe the implementation should
147  * depend on us instead.
148  */
149  const std::vector<node_definition> node_definitions_;
150 
152 
154 
156 
158 
159  /**
160  * Resizes the content.
161  *
162  * The resize either happens due to resizing the content or invalidate the
163  * layout of the window.
164  *
165  * @param width_modification The wanted modification to the width:
166  * * negative values reduce width.
167  * * zero leave width as is.
168  * * positive values increase width.
169  * @param height_modification The wanted modification to the height:
170  * * negative values reduce height.
171  * * zero leave height as is.
172  * * positive values increase height.
173  * @param width_modification_pos
174  * @param height_modification_pos
175  */
176  void resize_content(const int width_modification,
177  const int height_modification,
178  const int width_modification_pos = -1,
179  const int height_modification_pos = -1);
180 
181  /** Layouts the children if needed. */
182  void layout_children(const bool force);
183 
184  /** Inherited from container_base. */
185  virtual void finalize_setup();
186 
187 public:
188  /** Static type getter that does not rely on the widget being constructed. */
189  static const std::string& type();
190 
191  /** Optionally returns the node definition with the given id, or nullopt if not found. */
192  std::optional<decltype(node_definitions_)::const_iterator> get_node_definition(const std::string& id) const
193  {
194  const auto def = std::find_if(
195  node_definitions_.begin(), node_definitions_.end(), [&id](const auto& d) { return d.id == id; });
196  return def != node_definitions_.end() ? std::optional{def} : std::nullopt;
197  }
198 
199 private:
200  /** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
201  virtual const std::string& get_control_type() const override;
202 
203  /***** ***** ***** signal handlers ***** ****** *****/
204 
206 
207  template<tree_view_node* (tree_view_node::*func) ()>
209 
210  template<tree_view_node* (tree_view_node::*func) ()>
211  bool handle_up_down_arrow();
212 };
213 
214 // }---------- DEFINITION ---------{
215 
217 {
218 
219  explicit tree_view_definition(const config& cfg);
220 
222  {
223  explicit resolution(const config& cfg);
224 
226  };
227 };
228 
229 // }---------- BUILDER -----------{
230 
231 namespace implementation
232 {
233 
235 {
236  explicit builder_tree_view(const config& cfg);
237 
239 
240  virtual std::unique_ptr<widget> build() const override;
241 
244 
246 
247  /**
248  * The types of nodes in the tree view.
249  *
250  * Since we expect the amount of nodes to remain low it's stored in a
251  * vector and not in a map.
252  */
253  std::vector<tree_node> nodes;
254 
255  /*
256  * NOTE this class doesn't have a data section, so it can only be filled
257  * with data by the engine. I think this poses no limit on the usage since
258  * I don't foresee that somebody wants to pre-fill a tree view. If the need
259  * arises the data part can be added.
260  */
261 };
262 
263 } // namespace implementation
264 
265 // }------------ END --------------
266 
267 } // namespace gui2
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:161
Base class for creating containers with one or two scrollbar(s).
scrollbar_mode
The way to handle the showing or hiding of the scrollbar.
void finalize_setup()
The builder needs to call us so we do our setup.
A tree view is a control that holds several items of the same or different types.
Definition: tree_view.hpp:61
void set_indentation_step_size(const unsigned indentation_step_size)
Definition: tree_view.hpp:105
void resize_content(const int width_modification, const int height_modification, const int width_modification_pos=-1, const int height_modification_pos=-1)
Resizes the content.
Definition: tree_view.cpp:110
unsigned indentation_step_size_
Definition: tree_view.hpp:151
const tree_view_node * selected_item() const
Definition: tree_view.hpp:115
tree_view_node * selected_item_
Definition: tree_view.hpp:157
void handle_key_right_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from scrollbar_container.
Definition: tree_view.cpp:241
virtual void set_self_active(const bool active) override
See container_base::set_self_active.
Definition: tree_view.cpp:95
static const std::string root_node_id
Definition: tree_view.hpp:141
tree_view_node * get_next_node()
Definition: tree_view.cpp:180
tree_view_node & get_root_node()
Definition: tree_view.hpp:75
tree_view_node * root_node_
Definition: tree_view.hpp:155
virtual void finalize_setup()
Inherited from container_base.
Definition: tree_view.cpp:158
bool empty() const
Definition: tree_view.cpp:100
void handle_key_up_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from scrollbar_container.
Definition: tree_view.cpp:211
void handle_key_left_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from scrollbar_container.
Definition: tree_view.cpp:229
static const std::string & type()
Static type getter that does not rely on the widget being constructed.
tree_view_node & add_node(const std::string &id, const widget_data &data, const int index=-1)
Definition: tree_view.cpp:57
void signal_handler_left_button_down(const event::ui_event event)
Definition: tree_view.cpp:172
const std::vector< node_definition > node_definitions_
Definition: tree_view.hpp:149
implementation::tree_node node_definition
Definition: tree_view.hpp:67
tree_view_node * selected_item()
Definition: tree_view.hpp:110
virtual const std::string & get_control_type() const override
Inherited from styled_widget, implemented by REGISTER_WIDGET.
void handle_key_down_arrow(SDL_Keymod modifier, bool &handled) override
Inherited from scrollbar_container.
Definition: tree_view.cpp:220
std::optional< decltype(node_definitions_)::const_iterator > get_node_definition(const std::string &id) const
Optionally returns the node definition with the given id, or nullopt if not found.
Definition: tree_view.hpp:192
virtual void layout_children() override
See widget::layout_children.
Definition: tree_view.cpp:105
bool handle_up_down_arrow()
Definition: tree_view.cpp:196
std::pair< std::shared_ptr< tree_view_node >, int > remove_node(tree_view_node *node)
Removes the given node as a child of its parent node.
Definition: tree_view.cpp:63
const std::vector< node_definition > & get_node_definitions() const
Definition: tree_view.hpp:120
const std::string & id() const
Definition: widget.cpp:111
ui_event
The event sent to the dispatcher.
Definition: handler.hpp:115
Generic file dialog.
std::shared_ptr< builder_grid > builder_grid_ptr
std::map< std::string, widget_item > widget_data
Definition: widget.hpp:35
Contains the implementation details for lexical_cast and shouldn't be used directly.
std::size_t index(const std::string &str, const std::size_t index)
Codepoint index corresponding to the nth character in a UTF-8 string.
Definition: unicode.cpp:72
std::string_view data
Definition: picture.cpp:199
virtual std::unique_ptr< widget > build() const=0
std::vector< tree_node > nodes
The types of nodes in the tree view.
Definition: tree_view.hpp:253
scrollbar_container::scrollbar_mode vertical_scrollbar_mode
Definition: tree_view.hpp:242
scrollbar_container::scrollbar_mode horizontal_scrollbar_mode
Definition: tree_view.hpp:243
virtual std::unique_ptr< widget > build() const override
Definition: tree_view.cpp:294
tree_node(const config &cfg)
Definition: tree_view.cpp:318
Base class of a resolution, contains the common keys for a resolution.
tree_view_definition(const config &cfg)
Definition: tree_view.cpp:255
#define d