The Battle for Wesnoth  1.17.0-dev
tree_view.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010 - 2021
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 
70 
71  ~tree_view();
72 
74 
76  {
77  return *root_node_;
78  }
79 
81  add_node(const std::string& id,
82  const std::map<std::string /* widget id */, string_map>& data,
83  const int index = -1);
84 
85  /**
86  * Removes the given node as a child of its parent node.
87  *
88  * @param node A pointer to the node to remove.
89  *
90  * @returns A pair consisting of a smart pointer managing the removed
91  * node, and its position before removal.
92  */
93  std::pair<std::shared_ptr<tree_view_node>, int> remove_node(tree_view_node* node);
94 
95  void clear();
96 
97  /** See @ref widget::child_populate_dirty_list. */
98  virtual void
99  child_populate_dirty_list(window& caller,
100  const std::vector<widget*>& call_stack) override;
101 
102  /** See @ref container_base::set_self_active. */
103  virtual void set_self_active(const bool active) override;
104 
105  bool empty() const;
106 
107  /** See @ref widget::layout_children. */
108  virtual void layout_children() override;
109 
110  /***** ***** ***** setters / getters for members ***** ****** *****/
111 
112  void set_indentation_step_size(const unsigned indentation_step_size)
113  {
114  indentation_step_size_ = indentation_step_size;
115  }
116 
118  {
119  return selected_item_;
120  }
121 
123  {
124  return selected_item_;
125  }
126 
127  const std::vector<node_definition>& get_node_definitions() const
128  {
129  return node_definitions_;
130  }
131 
132 protected:
133  /***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
134 
135  /** Inherited from scrollbar_container. */
136  void handle_key_up_arrow(SDL_Keymod modifier, bool& handled) override;
137 
138  /** Inherited from scrollbar_container. */
139  void handle_key_down_arrow(SDL_Keymod modifier, bool& handled) override;
140 
141  /** Inherited from scrollbar_container. */
142  void handle_key_left_arrow(SDL_Keymod modifier, bool& handled) override;
143 
144  /** Inherited from scrollbar_container. */
145  void handle_key_right_arrow(SDL_Keymod modifier, bool& handled) override;
146 
147 private:
148  static inline const std::string root_node_id = "root";
149 
150  /**
151  * @todo evaluate which way the dependency should go.
152  *
153  * We no depend on the implementation, maybe the implementation should
154  * depend on us instead.
155  */
156  const std::vector<node_definition> node_definitions_;
157 
159 
161 
163 
165 
166  /**
167  * Resizes the content.
168  *
169  * The resize either happens due to resizing the content or invalidate the
170  * layout of the window.
171  *
172  * @param width_modification The wanted modification to the width:
173  * * negative values reduce width.
174  * * zero leave width as is.
175  * * positive values increase width.
176  * @param height_modification The wanted modification to the height:
177  * * negative values reduce height.
178  * * zero leave height as is.
179  * * positive values increase height.
180  * @param width_modification_pos
181  * @param height_modification_pos
182  */
183  void resize_content(const int width_modification,
184  const int height_modification,
185  const int width_modification_pos = -1,
186  const int height_modification_pos = -1);
187 
188  /** Layouts the children if needed. */
189  void layout_children(const bool force);
190 
191  /** Inherited from container_base. */
192  virtual void finalize_setup();
193 
194 public:
195  /** Static type getter that does not rely on the widget being constructed. */
196  static const std::string& type();
197 
198  /** Optionally returns the node definition with the given id, or nullopt if not found. */
199  std::optional<decltype(node_definitions_)::const_iterator> get_node_definition(const std::string& id) const
200  {
201  const auto def = std::find_if(
202  node_definitions_.begin(), node_definitions_.end(), [&id](const auto& d) { return d.id == id; });
203  return def != node_definitions_.end() ? std::optional{def} : std::nullopt;
204  }
205 
206 private:
207  /** Inherited from styled_widget, implemented by REGISTER_WIDGET. */
208  virtual const std::string& get_control_type() const override;
209 
210  /***** ***** ***** signal handlers ***** ****** *****/
211 
212  void signal_handler_left_button_down(const event::ui_event event);
213 
214  template<tree_view_node* (tree_view_node::*func) ()>
215  tree_view_node* get_next_node();
216 
217  template<tree_view_node* (tree_view_node::*func) ()>
218  bool handle_up_down_arrow();
219 };
220 
221 // }---------- DEFINITION ---------{
222 
224 {
225 
226  explicit tree_view_definition(const config& cfg);
227 
229  {
230  explicit resolution(const config& cfg);
231 
233  };
234 };
235 
236 // }---------- BUILDER -----------{
237 
238 namespace implementation
239 {
240 
242 {
243  explicit builder_tree_view(const config& cfg);
244 
246 
247  virtual widget* build() const override;
248 
251 
253 
254  /**
255  * The types of nodes in the tree view.
256  *
257  * Since we expect the amount of nodes to remain low it's stored in a
258  * vector and not in a map.
259  */
260  std::vector<tree_node> nodes;
261 
262  /*
263  * NOTE this class doesn't have a data section, so it can only be filled
264  * with data by the engine. I think this poses no limit on the usage since
265  * I don't foresee that somebody wants to pre-fill a tree view. If the need
266  * arises the data part can be added.
267  */
268 };
269 
270 } // namespace implementation
271 
272 // }------------ END --------------
273 
274 } // namespace gui2
Base class of a resolution, contains the common keys for a resolution.
virtual widget * build() const =0
void finalize_setup()
The builder needs to call us so we do our setup.
unsigned indentation_step_size_
Definition: tree_view.hpp:158
tree_view_node & get_root_node()
Definition: tree_view.hpp:75
Base class for all widgets.
Definition: widget.hpp:49
void clear(const std::string &key)
Definition: general.cpp:186
tree_view_node * selected_item()
Definition: tree_view.hpp:117
scrollbar_container::scrollbar_mode vertical_scrollbar_mode
Definition: tree_view.hpp:249
#define d
const tree_view_node * selected_item() const
Definition: tree_view.hpp:122
Generic file dialog.
Definition: field-fwd.hpp:23
tree_view_node * selected_item_
Definition: tree_view.hpp:164
static thread_local std::deque< std::string > call_stack
For printing error messages when WFL parsing or evaluation fails, this contains the names of the WFL ...
Definition: function.cpp:47
tree_view_node * root_node_
Definition: tree_view.hpp:162
std::vector< tree_node > nodes
The types of nodes in the tree view.
Definition: tree_view.hpp:260
A tree view is a control that holds several items of the same or different types. ...
Definition: tree_view.hpp:60
void set_indentation_step_size(const unsigned indentation_step_size)
Definition: tree_view.hpp:112
Base class for creating containers with one or two scrollbar(s).
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:199
implementation::tree_node node_definition
Definition: tree_view.hpp:67
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
scrollbar_mode
The way to handle the showing or hiding of the scrollbar.
scrollbar_container::scrollbar_mode horizontal_scrollbar_mode
Definition: tree_view.hpp:250
point resolution()
Definition: general.cpp:393
std::unique_ptr< window > build(const builder_window::window_resolution &definition)
Builds a window.
const std::vector< node_definition > node_definitions_
Definition: tree_view.hpp:156
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:61
base class of top level items, the only item which needs to store the final canvases to draw on...
Definition: window.hpp:65
std::shared_ptr< builder_grid > builder_grid_ptr
const std::vector< node_definition > & get_node_definitions() const
Definition: tree_view.hpp:127
Contains the implementation details for lexical_cast and shouldn&#39;t be used directly.
ui_event
The event send to the dispatcher.
Definition: handler.hpp:48
tree_node(const config &cfg)
Definition: tree_view.cpp:327