The Battle for Wesnoth  1.13.10+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
iterator.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2017 by Mark de Wever <koraq@xs4all.nl>
3  Part of the Battle for Wesnoth Project http://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 #define GETTEXT_DOMAIN "wesnoth-lib"
16 
18 
19 namespace gui2
20 {
21 
22 namespace iteration
23 {
24 
25 
26 } // namespace iteration
27 
28 } // namespace gui2
29 
30 
31 /**
32  * @page gui2_iterator GUI2 Iterator.
33  *
34  * The iterator class allows the user to iterate over a group of widgets.
35  * The idea is to add a visitor class later as well, where the two classes
36  * can be combined.
37  *
38  * This page describes how the iterator class works. The iterator is build
39  * from several parts:
40  * - level, the part and subparts of the widget to visit.
41  * - walker, iterates over a single widget at several levels.
42  * - visit policy, whether a level should be visited or not.
43  * - order policy, the order in which the several levels are traversed.
44  * - iterator, the user interface for iteration.
45  *
46  *
47  * @section gui2_iterator_level Level
48  *
49  * The levels are defined in @ref gui2::iteration::walker_base::level. The
50  * level allows the user to only visit a part of the widget tree.
51  *
52  * @note At the moment when gui2::iteration::walker_base::widget is skipped the
53  * child class also skips its children. This behavior might change.
54  *
55  *
56  * @section gui2_iterator_walker Walker
57  *
58  * The is a group of classes inheriting from @ref gui2::iteration::walker_base
59  * the objects are created from @ref gui2::widget::create_walker. The
60  * walker allows to visit the several levels of the widget. This means
61  * several widgets need to override the function in a subclass. For example
62  * most @em simple widgets don't have a grid or children so they can use the
63  * walker created from @ref gui2::styled_widget. But containers need to create a
64  * different walker.
65  *
66  *
67  * @section gui2_iterator_visit_policy Visit policy
68  *
69  * This policy simply defines whether or not to visit the widgets at a
70  * certain level. There are two visit policies:
71  * - @ref gui2::iteration::policy::visit::visit_level visits the widget at the level.
72  * - @ref gui2::iteration::policy::visit::skip_level skips the widget at the level.
73  *
74  * There are no more visit policies expected for the future. These policies
75  * are normally not used directly, but set from the @ref
76  * gui2_iterator_order_policy.
77  *
78  *
79  * @section gui2_iterator_order_policy Order policy
80  *
81  * This policy determines in which order the widgets are traversed, children
82  * first, this level before diving down etc. @ref tests/gui/iterator.cpp
83  * shows more information.
84  * The following policies have been defined:
85  * - @ref gui2::iteration::policy::order::top_down
86  * - @ref gui2::iteration::policy::order::bottom_up
87  *
88  * The next sections describe in which order the widgets are visited. In the
89  * description we use the following widget tree.
90  *
91  * [0] @n
92  * \ @n
93  * [1|2|3|4] @n
94  * \ @n
95  * [5|6|7|8] @n
96  *
97  * The types are:
98  * - grid 0, 1
99  * - styled_widget 2, 3, 4, 6, 7, 8
100  *
101  * The examples assume all levels will be visited.
102  *
103  *
104  * @subsection gui2_iterator_visit_policy_top_down Top down
105  *
106  * The widgets visited first is the initial widget. After that it tries to go
107  * down to a child widget and will continue down. Once that fails it will visit
108  * the siblings at that level before going up again.
109  *
110  * @todo Write the entire visiting algorithm.
111  *
112  * The visiting order in our example is:
113  * 0, 1, 5, 6, 7, 8, 2, 3, 4
114  *
115  *
116  * @subsection gui2_iterator_visit_policy_bottom_up Bottom up
117  *
118  * When the iterator is created the iterator tries to go down all the child
119  * widgets to get at the bottom level. That widget will be visited first. Then
120  * it will first visit all siblings before going up the the next layer.
121  *
122  * @todo Write the entire visiting algorithm.
123  *
124  * The visiting order in our example is:
125  * 5, 6, 7, 8, 1, 2, 3, 4, 0
126  *
127  *
128  * @section gui2_iterator_iterator Iterator
129  *
130  * The iterator is the class the users should care about. The user creates the
131  * iterator with the selected policy and the root widget. Then the user can
132  * visit the widgets.
133  *
134  * When during the iteration a widget is added to or removed from the
135  * widget-tree being walked the iterator becomes invalid. Using the iterator
136  * when it is invalid results in Undefined Behavior.
137  *
138  * When it's certain there's at least one widget to visit a simple do while loop
139  * can be used. It the policy visits the widget, it's certain there is at least
140  * one widget to visit. Below some sample code:
141 @code
142 iterator<policy> itor(root);
143 assert(!itor.at_end());
144 do {
145  ...
146  ...
147 } while(itor.next());
148 @endcode
149  *
150  * When there might be no widget to visit a simple for loop can be used:
151 @code
152 for(iterator<policy> itor(root); !itor.at_end(); ++itor) {
153  ...
154  ...
155 }
156 @endcode
157  *
158  *
159  * @subsection gui2_iterator_iterator_design Design
160  *
161  * As seen in the examples above the iterator doesn't look like a iterator in
162  * the C++ standard library. The iterator is more designed after the iterator
163  * design of the Gang of Four [GoF]. The reason for the different design is that
164  * GoF design fits better to the classes as a normal C++ iterator. The rest of
165  * this section explains some of the reasons why this design is chosen. The main
166  * reason is simple; the iteration of the widgets feels better suited for the
167  * GoF-style iteration as the C++-style iteration.
168  *
169  * The iterator is not lightweight like most C++ iterators, therefore the class
170  * in non-copyable. (This is for example also the reason why a std::list has no
171  * operator[].) Since operator++(int) should return a copy of the original
172  * object it's also omitted.
173  *
174  * The design makes it hard to back-track the iteration (or costs more memory),
175  * so the iterator is forward only. The order policy is added to allow the
176  * wanted walking direction, but one-way only.
177  *
178  * The iterator has a begin, but it's not easy to go back to it and the
179  * operation involves rewinding the state, which might be costly. Therefore no
180  * begin() function.
181  *
182  * The end is known at the moment it's reached, but not upfront. That combined
183  * with the forward only, makes implementing an end() hard and therefore it is
184  * omitted.
185  *
186  *
187  * [GoF] http://en.wikipedia.org/wiki/Design_Patterns_%28book%29
188  */
Generic file dialog.
Definition: text.hpp:37
Contains the base iterator class for the gui2 widgets.