The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
tree_view_node.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2010 - 2025
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
19#include "gui/widgets/grid.hpp"
20
21#include <memory>
22
23namespace gui2
24{
25
26class selectable_item;
27class tree_view;
28
29class tree_view_node : public widget
30{
32 friend class tree_view;
33
34public:
35 using node_children_vector = std::vector<std::shared_ptr<tree_view_node>>;
36
37 bool operator==(const tree_view_node& node)
38 {
39 return &node == this;
40 }
41
43 const std::string& id,
45 tree_view& parent_tree_view,
46 const widget_data& data);
47
49
50 /**
51 * Constructs a new child node.
52 *
53 * @param id The id of the node definition to use for the
54 * new node.
55 * @param data The data to send to the set_members of the
56 * widgets. If the member id is not an empty
57 * string it is only send to the widget that has
58 * the wanted id (if any). If the member id is an
59 * empty string, it is send to all members.
60 * Having both empty and non-empty id's gives
61 * undefined behavior.
62 * @param index The item before which to add the new item,
63 * 0 == begin, -1 == end.
64 */
65 tree_view_node& add_child(const std::string& id,
66 const widget_data& data,
67 const int index = -1)
68 {
69 return add_child_impl(std::make_shared<tree_view_node>(id, this, get_tree_view(), data), index);
70 }
71
72 /**
73 * Replaces all children of this tree with new children.
74 * The motivation here is to provide a way to add multiple children without calculating the trees size for each child added.
75 * This is a waste of time since the results of that resizing will be immediately thrown out except for the final child added.
76 *
77 * @param id The id of the node definition to use for the new nodes.
78 * @param data A vector of the data to provide to the tree_node_view's constructor.
79 * @return A vector of pointers to the newly created nodes.
80 */
81 std::vector<std::shared_ptr<gui2::tree_view_node>> replace_children(const std::string& id, const std::vector<widget_data>& data);
82
83 /**
84 * Adds a previously-constructed node as a child of this node at the given position.
85 *
86 * @param new_node A smart pointer to the node object to insert.
87 * @param index The item before which to add the new item,
88 * 0 == begin, -1 == end.
89 */
90 tree_view_node& add_child(std::shared_ptr<tree_view_node> new_node, const int index = -1)
91 {
92 new_node->parent_node_ = this;
93 return add_child_impl(std::move(new_node), index);
94 }
95
96 /**
97 * Adds a sibling for a node at the end of the list.
98 *
99 * @param id The id of the node definition to use for the
100 * new node.
101 * @param data The data to send to the set_members of the
102 * widgets. If the member id is not an empty
103 * string it is only send to the widget that has
104 * the wanted id (if any). If the member id is an
105 * empty string, it is send to all members.
106 * Having both empty and non-empty id's gives
107 * undefined behavior.
108 */
110 add_sibling(const std::string& id,
111 const widget_data& data)
112 {
113 assert(!is_root_node());
114 return parent_node().add_child(id, data);
115 }
116
117private:
118 /** Implementation detail for @ref add_child. */
119 tree_view_node& add_child_impl(std::shared_ptr<tree_view_node>&& new_node, const int index);
120
121public:
122 /**
123 * Is this node the root node?
124 *
125 * When the parent tree view is created it adds one special node, the root
126 * node. This node has no parent node and some other special features so
127 * several code paths need to check whether they are the parent node.
128 *
129 * This also returns true for a detached node returned with @ref tree_view::remove_node.
130 */
131 bool is_root_node() const
132 {
133 return parent_node_ == nullptr;
134 }
135
136 /**
137 * The indentation level of the node.
138 *
139 * The root node starts at level 0.
140 */
141 unsigned get_indentation_level() const;
142
143 /** Does the node have children? */
144 bool empty() const
145 {
146 return children_.empty();
147 }
148
149 /** Is the node folded? */
150 bool is_folded() const
151 {
152 return !unfolded_;
153 }
154
155#if 0
156 // TODO: implement if different expand modes become necessary
157 enum expand_mode {
158 recursive_restore, // recursively restores collapse mode
159 recursive_expand, // recursively expands the children
160 not_recursive
161 };
162#endif
163
164 void fold(const bool recursive = false);
165 void unfold(const bool recursive = false);
166
167 /**
168 * See @ref widget::create_walker.
169 *
170 * @todo Implement properly.
171 */
172 virtual iteration::walker_ptr create_walker() override;
173
175 {
176 return children_;
177 }
178
180 {
181 assert(!is_root_node());
182 return parent_node().children();
183 }
184
185 /** See @ref widget::find_at. */
186 virtual widget* find_at(const point& coordinate,
187 const bool must_be_active) override;
188
189 /** See @ref widget::find_at. */
190 virtual const widget* find_at(const point& coordinate,
191 const bool must_be_active) const override;
192
193 /** See @ref widget::find. */
194 widget* find(const std::string_view id, const bool must_be_active) override;
195
196 /** See @ref widget::find. */
197 const widget* find(const std::string_view id, const bool must_be_active) const override;
198
199 /**
200 * The number of children in this widget.
201 */
202 std::size_t count_children() const
203 {
204 return children_.size();
205 }
206
207 /**
208 * Removes all child items from the widget.
209 */
210 void clear();
211
212 /***** ***** ***** setters / getters for members ***** ****** *****/
213
214 /**
215 * Returns the parent node.
216 *
217 * @pre is_root_node() == false.
218 */
220
221 /** The const version of @ref parent_node. */
222 const tree_view_node& parent_node() const;
223
225 {
226 return *tree_view_;
227 }
228
230 {
231 return *tree_view_;
232 }
233
234 tree_view_node& get_child_at(int index);
235
236 /**
237 * Calculates the node indices needed to get from the root node to this node.
238 */
239 std::vector<int> describe_path() const;
240
246 void select_node(bool expand_parents = false, bool fire_event = true);
247 grid& get_grid() { return grid_; }
248 void layout_initialize(const bool full_initialization) override;
249
251
252private:
253 int calculate_ypos();
254
255 /** See @ref widget::request_reduce_width. */
256 virtual void request_reduce_width(const unsigned maximum_width) override;
257
258 /**
259 * Our parent node.
260 *
261 * All nodes except the root node have a parent node.
262 */
264
265 /** The tree view that owns us. */
267
268 /** Grid holding our contents. */
270
271 /**
272 * Our children.
273 *
274 * We want the returned child nodes to remain stable so store pointers.
275 */
277
278 /** The toggle for the folded state. */
280
281 /** The label to show our selected state. */
283
285 void fold_internal();
286 void unfold_internal();
287
288 /** See @ref widget::calculate_best_size. */
289 virtual point calculate_best_size() const override;
290
291 /** See @ref widget::disable_click_dismiss. */
292 bool disable_click_dismiss() const override;
293
294 point calculate_best_size(const int indentation_level,
295 const unsigned indentation_step_size) const;
296 /** @param assume_visible if false (default) it will return 0 if the parent node is folded*/
297 point get_current_size(bool assume_visible = false) const;
298 point get_folded_size() const;
299 point get_unfolded_size() const;
300
301 /** See @ref widget::set_origin. */
302 virtual void set_origin(const point& origin) override;
303
304 /** See @ref widget::place. */
305 virtual void place(const point& origin, const point& size) override;
306
307 unsigned
308 place(const unsigned indentation_step_size, point origin, unsigned width);
309
310 /** See @ref widget::set_visible_rectangle. */
311 virtual void set_visible_rectangle(const rect& rectangle) override;
312
313 /** See @ref widget::impl_draw_children. */
314 virtual void impl_draw_children() override;
315
317
319 bool& handled,
320 bool& halt);
321
322 void
324 const widget_data& data);
325
326 /**
327 * Returns the control_type of the @ref tree_view_node.
328 *
329 * This class does not derive from @ref styled_widget but the function behaves
330 * similar as @ref styled_widget::get_control_type.
331 */
332 const std::string& get_control_type() const;
333};
334
335} // namespace gui2
Base container class.
Definition grid.hpp:32
Small abstract helper class.
grid grid_
Grid holding our contents.
std::vector< int > describe_path() const
Calculates the node indices needed to get from the root node to this node.
point get_current_size(bool assume_visible=false) const
void signal_handler_label_left_button_click(const event::ui_event event, bool &handled, bool &halt)
void clear()
Removes all child items from the widget.
const tree_view & get_tree_view() const
selectable_item * toggle_
The toggle for the folded state.
tree_view_node & add_child(std::shared_ptr< tree_view_node > new_node, const int index=-1)
Adds a previously-constructed node as a child of this node at the given position.
tree_view_node & get_child_at(int index)
tree_view * tree_view_
The tree view that owns us.
void fold(const bool recursive=false)
void select_node(bool expand_parents=false, bool fire_event=true)
node_children_vector & siblings()
bool is_folded() const
Is the node folded?
point get_folded_size() const
bool is_root_node() const
Is this node the root node?
virtual void set_origin(const point &origin) override
See widget::set_origin.
node_children_vector & children()
void signal_handler_toggle_left_click(const event::ui_event event)
bool empty() const
Does the node have children?
tree_view_node & parent_node()
Returns the parent node.
std::vector< std::shared_ptr< gui2::tree_view_node > > replace_children(const std::string &id, const std::vector< widget_data > &data)
Replaces all children of this tree with new children.
virtual void request_reduce_width(const unsigned maximum_width) override
See widget::request_reduce_width.
const std::string & get_control_type() const
Returns the control_type of the tree_view_node.
selectable_item * label_
The label to show our selected state.
tree_view_node * get_selectable_node_above()
tree_view_node * parent_node_
Our parent node.
tree_view_node & add_sibling(const std::string &id, const widget_data &data)
Adds a sibling for a node at the end of the list.
virtual iteration::walker_ptr create_walker() override
See widget::create_walker.
virtual void set_visible_rectangle(const rect &rectangle) override
See widget::set_visible_rectangle.
tree_view & get_tree_view()
void unfold(const bool recursive=false)
tree_view_node & add_child_impl(std::shared_ptr< tree_view_node > &&new_node, const int index)
Implementation detail for add_child.
virtual widget * find_at(const point &coordinate, const bool must_be_active) override
See widget::find_at.
node_children_vector children_
Our children.
point get_unfolded_size() const
widget * find(const std::string_view id, const bool must_be_active) override
See widget::find.
tree_view_node * get_node_above()
unsigned get_indentation_level() const
The indentation level of the node.
std::size_t count_children() const
The number of children in this widget.
void init_grid(grid *grid, const widget_data &data)
void layout_initialize(const bool full_initialization) override
How the layout engine works.
tree_view_node & add_child(const std::string &id, const widget_data &data, const int index=-1)
Constructs a new child node.
virtual point calculate_best_size() const override
See widget::calculate_best_size.
std::vector< std::shared_ptr< tree_view_node > > node_children_vector
bool operator==(const tree_view_node &node)
tree_view_node * get_last_visible_parent_node()
virtual void impl_draw_children() override
See widget::impl_draw_children.
bool disable_click_dismiss() const override
See widget::disable_click_dismiss.
tree_view_node * get_node_below()
tree_view_node * get_selectable_node_below()
virtual void place(const point &origin, const point &size) override
See widget::place.
Base class for all widgets.
Definition widget.hpp:55
ui_event
The event sent to the dispatcher.
Definition handler.hpp:115
std::unique_ptr< class walker_base > walker_ptr
Definition widget.hpp:44
Generic file dialog.
std::map< std::string, widget_item > widget_data
Definition widget.hpp:36
std::string_view data
Definition picture.cpp:188
Holds a 2D point.
Definition point.hpp:25
An abstract description of a rectangle with integer coordinates.
Definition rect.hpp:49