The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
multi_page.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2016 by Mark de Wever <[email protected]>
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 
21 #include "gui/widgets/settings.hpp"
23 
24 #include "gettext.hpp"
25 
26 #include "utils/functional.hpp"
27 
28 namespace gui2
29 {
30 
31 // ------------ WIDGET -----------{
32 
33 REGISTER_WIDGET(multi_page)
35  : tcontainer_(0)
36  , generator_(
37  tgenerator_::build(true, true, tgenerator_::independent, false))
38  , page_builder_(nullptr)
39 {
40 }
41 
43 {
44  assert(generator_);
45  generator_->create_item(-1, page_builder_, item, nullptr);
46 }
47 
49  const std::map<std::string /* widget id */, string_map>& data)
50 {
51  assert(generator_);
52  generator_->create_item(-1, page_builder_, data, nullptr);
53 }
54 
55 void tmulti_page::remove_page(const unsigned page, unsigned count)
56 {
57  assert(generator_);
58 
59  if(page >= get_page_count()) {
60  return;
61  }
62 
63  if(!count || count > get_page_count()) {
64  count = get_page_count();
65  }
66 
67  for(; count; --count) {
68  generator_->delete_item(page);
69  }
70 }
71 
73 {
74  assert(generator_);
75  generator_->clear();
76 }
77 
79 {
80  assert(generator_);
81  return generator_->get_item_count();
82 }
83 
84 void tmulti_page::select_page(const unsigned page, const bool select)
85 {
86  assert(generator_);
87  generator_->select_item(page, select);
88 }
89 
91 {
92  assert(generator_);
93  return generator_->get_selected_item();
94 }
95 
96 const tgrid& tmulti_page::page_grid(const unsigned page) const
97 {
98  assert(generator_);
99  return generator_->item(page);
100 }
101 
102 tgrid& tmulti_page::page_grid(const unsigned page)
103 {
104  assert(generator_);
105  return generator_->item(page);
106 }
107 
109 {
110  return true;
111 }
112 
113 unsigned tmulti_page::get_state() const
114 {
115  return 0;
116 }
117 
118 namespace
119 {
120 
121 /**
122  * Swaps an item in a grid for another one.*/
123 void swap_grid(tgrid* grid,
124  tgrid* content_grid,
125  twidget* widget,
126  const std::string& id)
127 {
128  assert(content_grid);
129  assert(widget);
130 
131  // Make sure the new child has same id.
132  widget->set_id(id);
133 
134  // Get the container containing the wanted widget.
135  tgrid* parent_grid = nullptr;
136  if(grid) {
137  parent_grid = find_widget<tgrid>(grid, id, false, false);
138  }
139  if(!parent_grid) {
140  parent_grid = find_widget<tgrid>(content_grid, id, true, false);
141  }
142  parent_grid = dynamic_cast<tgrid*>(parent_grid->parent());
143  assert(parent_grid);
144 
145  // Replace the child.
146  widget = parent_grid->swap_child(id, widget, false);
147  assert(widget);
148 
149  delete widget;
150 }
151 
152 } // namespace
153 
154 void tmulti_page::finalize(const std::vector<string_map>& page_data)
155 {
156  assert(generator_);
157  generator_->create_items(-1, page_builder_, page_data, nullptr);
158  swap_grid(nullptr, &grid(), generator_, "_content_grid");
159 }
160 
162  ,
163  int /*x_offset*/
164  ,
165  int /*y_offset*/)
166 {
167  /* DO NOTHING */
168 }
169 
171 {
172  static const std::string type = "multi_page";
173  return type;
174 }
175 
176 void tmulti_page::set_self_active(const bool /*active*/)
177 {
178  /* DO NOTHING */
179 }
180 
181 // }---------- DEFINITION ---------{
182 
184  : tcontrol_definition(cfg)
185 {
186  DBG_GUI_P << "Parsing multipage " << id << '\n';
187 
188  load_resolutions<tresolution>(cfg);
189 }
190 
191 /*WIKI
192  * @page = GUIWidgetDefinitionWML
193  * @order = 1_multi_page
194  *
195  * == Multi page ==
196  *
197  * @begin{parent}{name="gui/"}
198  * @begin{tag}{name="multi_page_definition"}{min=0}{max=-1}{super="generic/widget_definition"}
199  * @macro = multi_page_description
200  *
201  * @begin{tag}{name="resolution"}{min=0}{max=-1}{super="generic/widget_definition/resolution"}
202  * @begin{table}{config}
203  * grid & grid & & A grid containing the widgets for main
204  * widget. $
205  * @end{table}
206  * @allow{link}{name="gui/window/resolution/grid"}
207  * @end{tag}{name="resolution"}
208  * @end{tag}{name="multi_page_definition"}
209  * @end{parent}{name="gui/"}
210  * A multipage has no states.
211  */
213  : tresolution_definition_(cfg), grid(nullptr)
214 {
215  const config& child = cfg.child("grid");
216  VALIDATE(child, _("No grid defined."));
217 
218  grid = new tbuilder_grid(child);
219 }
220 
221 // }---------- BUILDER -----------{
222 
223 /*WIKI_MACRO
224  * @begin{macro}{multi_page_description}
225  *
226  * A multi page is a control that contains several 'pages' of which
227  * only one is visible. The pages can contain the same widgets containing
228  * the same 'kind' of data or look completely different.
229  * @end{macro}
230  */
231 
232 /*WIKI
233  * @page = GUIWidgetInstanceWML
234  * @order = 2_multi_page
235  * @begin{parent}{name="gui/window/resolution/grid/row/column/"}
236  * @begin{tag}{name="multi_page"}{min=0}{max=-1}{super="generic/widget_instance"}
237  * == Multi page ==
238  *
239  * @macro = multi_page_description
240  *
241  * List with the multi page specific variables:
242  * @begin{table}{config}
243  * page_definition & section & & This defines how a multi page item
244  * looks. It must contain the grid
245  * definition for at least one page. $
246  *
247  * page_data & section & [] & A grid alike section which stores the
248  * initial data for the multi page. Every
249  * row must have the same number of columns
250  * as the 'page_definition'. $
251  * horizontal_scrollbar_mode & scrollbar_mode & initial_auto &
252  * Determines whether or not to show the
253  * scrollbar.
254  * vertical_scrollbar_mode & scrollbar_mode & initial_auto &
255  * Determines whether or not to show the
256  * scrollbar.
257  * @end{table}
258  * @begin{tag}{name="page_definition"}{min=0}{max=1}{super="gui/window/resolution/grid"}
259  * @end{tag}{name="page_definition"}
260  * @begin{tag}{name="page_data"}{min=0}{max=1}{super="gui/window/resolution/grid"}
261  * @end{tag}{name="page_data"}
262  * @end{tag}{name="multi_page"}
263  * @end{parent}{name="gui/window/resolution/grid/row/column/"}
264  */
265 
266 namespace implementation
267 {
268 
269 tbuilder_multi_page::tbuilder_multi_page(const config& cfg)
270  : implementation::tbuilder_control(cfg), builder(nullptr), data()
271 {
272  const config& page = cfg.child("page_definition");
273 
274  VALIDATE(page, _("No page defined."));
275  builder = new tbuilder_grid(page);
276  assert(builder);
277 
278  /** @todo This part is untested. */
279  const config& d = cfg.child("page_data");
280  if(!d) {
281  return;
282  }
283 
284  for(const auto & row : d.child_range("row"))
285  {
286  unsigned col = 0;
287 
288  for(const auto & column : row.child_range("column"))
289  {
290  data.push_back(string_map());
291  for(const auto & i : column.attribute_range())
292  {
293  data.back()[i.first] = i.second;
294  }
295  ++col;
296  }
297 
298  VALIDATE(col == builder->cols,
299  _("'list_data' must have "
300  "the same number of columns as the 'list_definition'."));
301  }
302 }
303 
305 {
306  tmulti_page* widget = new tmulti_page();
307 
308  init_control(widget);
309 
310  widget->set_page_builder(builder);
311 
312  DBG_GUI_G << "Window builder: placed multi_page '" << id
313  << "' with definition '" << definition << "'.\n";
314 
316  conf = boost::
317  dynamic_pointer_cast<const tmulti_page_definition::tresolution>(
318  widget->config());
319  assert(conf);
320 
321  widget->init_grid(conf->grid);
322 
323  widget->finalize(data);
324 
325  return widget;
326 }
327 
328 } // namespace implementation
329 
330 // }------------ END --------------
331 
332 } // namespace gui2
#define DBG_GUI_P
Definition: log.hpp:69
child_itors child_range(const std::string &key)
Definition: config.cpp:613
Abstract base class for the generator.
Definition: generator.hpp:41
virtual void select_item(const unsigned index, const bool select)=0
(De)selects an item.
const tgrid & grid() const
Definition: container.hpp:229
void set_page_builder(tbuilder_grid_ptr page_builder)
Definition: multi_page.hpp:137
twindow * build(CVideo &video, const twindow_builder::tresolution *definition)
Builds a window.
virtual void clear()=0
Deletes all items.
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1221
virtual unsigned get_state() const override
See tcontrol::get_state.
Definition: multi_page.cpp:113
Base container class.
Definition: grid.hpp:29
tresolution_definition_ptr config()
Definition: control.hpp:299
virtual int get_selected_item() const =0
Returns the selected item.
virtual tgrid & item(const unsigned index)=0
Gets the grid of an item.
#define d
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
Definition: glew.h:1347
const tgrid & page_grid(const unsigned page) const
Returns the grid for the page.
Definition: multi_page.cpp:96
Base class of a resolution, contains the common keys for a resolution.
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
void init_control(tcontrol *control) const
Definition: control.cpp:675
std::string definition
Parameters for the control.
Definition: control.hpp:530
twidget * parent()
Definition: widget.cpp:155
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
#define VALIDATE(cond, message)
The macro to use for the validation of WML.
This file contains the settings handling of the widget library.
virtual const std::string & get_control_type() const override
See tcontrol::get_control_type.
Definition: multi_page.cpp:170
virtual unsigned get_item_count() const =0
Returns the number of items.
virtual tgrid & create_item(const int index, tbuilder_grid_const_ptr list_builder, const string_map &item_data, const std::function< void(twidget &)> &callback)=0
Creates a new item.
void finalize(const std::vector< string_map > &page_data)
Finishes the building initialization of the widget.
Definition: multi_page.cpp:154
void init_grid(const boost::intrusive_ptr< tbuilder_grid > &grid_builder)
Initializes and builds the grid.
Definition: container.cpp:209
int get_selected_page() const
Returns the selected page.
Definition: multi_page.cpp:90
void add_page(const string_map &item)
Adds single page to the grid.
Definition: multi_page.cpp:42
The multi page class.
Definition: multi_page.hpp:37
void set_id(const std::string &id)
Definition: widget.cpp:97
static size_t id
Ids for the timers.
Definition: timer.cpp:39
GLuint GLuint GLsizei count
Definition: glew.h:1221
#define REGISTER_WIDGET(id)
Wrapper for REGISTER_WIDGET3.
tmulti_page_definition(const config &cfg)
Definition: multi_page.cpp:183
std::map< std::string, t_string > string_map
Definition: generator.hpp:23
virtual void set_self_active(const bool active) override
See tcontainer_::set_self_active.
Definition: multi_page.cpp:176
unsigned get_page_count() const
Returns the number of pages.
Definition: multi_page.cpp:78
GLenum GLenum GLvoid GLvoid * column
Definition: glew.h:3805
tgenerator_ * generator_
Contains a pointer to the generator.
Definition: multi_page.hpp:157
void remove_page(const unsigned page, unsigned count=1)
Removes a page in the multi page.
Definition: multi_page.cpp:55
size_t i
Definition: function.cpp:1057
twidget * swap_child(const std::string &id, twidget *widget, const bool recurse, twidget *new_parent=nullptr)
Exchanges a child in the grid.
Definition: grid.cpp:99
virtual void impl_draw_background(surface &frame_buffer, int x_offset, int y_offset) override
See twidget::impl_draw_background.
Definition: multi_page.cpp:161
virtual void create_items(const int index, tbuilder_grid_const_ptr list_builder, const std::vector< string_map > &data, const std::function< void(twidget &)> &callback)=0
Creates one or more new item(s).
void clear()
Removes all pages in the multi page, clearing it.
Definition: multi_page.cpp:72
void select_page(const unsigned page, const bool select=true)
Selectes a page.
Definition: multi_page.cpp:84
A generic container base class.
Definition: container.hpp:32
GLenum GLenum GLvoid * row
Definition: glew.h:3805
config & child(const std::string &key, int n=0)
Returns the nth child with the given key, or a reference to an invalid config if there is none...
Definition: config.cpp:658
Base class for all widgets.
Definition: widget.hpp:49
virtual bool get_active() const override
See tcontrol::get_active.
Definition: multi_page.cpp:108
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
#define DBG_GUI_G
Definition: log.hpp:41
GLsizei const GLcharARB ** string
Definition: glew.h:4503
Contains the implementation details for lexical_cast and shouldn't be used directly.
tbuilder_grid_const_ptr page_builder_
Contains the builder for the new items.
Definition: multi_page.hpp:160
virtual void delete_item(const unsigned index)=0
Deletes an item.