The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
scrollbar_container.hpp
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 #ifndef GUI_WIDGETS_SCROLLBAR_CONTAINER_HPP_INCLUDED
16 #define GUI_WIDGETS_SCROLLBAR_CONTAINER_HPP_INCLUDED
17 
18 #include "gui/core/notifiee.hpp"
21 
22 namespace gui2
23 {
24 
25 class tspacer;
26 
27 namespace implementation
28 {
29 struct tbuilder_scroll_label;
30 struct tbuilder_scrollbar_panel;
31 }
32 
33 /**
34  * Base class for creating containers with one or two scrollbar(s).
35  *
36  * For now users can't instanciate this class directly and needs to use small
37  * wrapper classes. Maybe in the future users can use the class directly.
38  *
39  * @todo events are not yet send to the content grid.
40  */
42 {
43  friend class tdebug_layout_graph;
44 
47 #ifndef GUI2_EXPERIMENTAL_LISTBOX
48  friend class tlistbox;
49 #endif
50  friend class ttree_view;
52 
53 public:
54  explicit tscrollbar_container(const unsigned canvas_count);
55 
57  {
58  delete content_grid_;
59  }
60 
61  /** The way to handle the showing or hiding of the scrollbar. */
64  * The scrollbar is always shown, whether
65  * needed or not.
66  */
68  * The scrollbar is never shown even not
69  * when needed. There's also no space
70  * reserved for the scrollbar.
71  */
73  * The scrollbar is shown when the number of
74  * items is larger as the visible items. The
75  * space for the scrollbar is always
76  * reserved, just in case it's needed after
77  * the initial sizing (due to adding items).
78  */
80  * Like auto_visible, but when not needed
81  * upon the initial layout phase, the bars
82  * are not shown and no space is reserved
83  * for them. (The algorithm hides them by
84  * default.
85  */
86  };
87 
88  /***** ***** ***** ***** layout functions ***** ***** ***** *****/
89 
90  /** See @ref twidget::layout_initialise. */
91  virtual void layout_initialise(const bool full_initialisation) override;
92 
93  /** See @ref twidget::request_reduce_height. */
94  virtual void request_reduce_height(const unsigned maximum_height) override;
95 
96  /** See @ref twidget::request_reduce_width. */
97  virtual void request_reduce_width(const unsigned maximum_width) override;
98 
99  /**
100  * See @ref twidget::can_wrap.
101  *
102  * @note This function is called before the object is finalised.
103  */
104  virtual bool can_wrap() const override;
105 
106 private:
107  /** See @ref twidget::calculate_best_size. */
108  virtual tpoint calculate_best_size() const override;
109 
110 public:
111  /** See @ref twidget::place. */
112  virtual void place(const tpoint& origin, const tpoint& size) override;
113 
114  /** See @ref twidget::set_origin. */
115  virtual void set_origin(const tpoint& origin) override;
116 
117  /** See @ref twidget::set_visible_rectangle. */
118  virtual void set_visible_rectangle(const SDL_Rect& rectangle) override;
119 
120  /***** ***** ***** inherited ****** *****/
121 
122  /** See @ref tcontrol::get_active. */
123  virtual bool get_active() const override;
124 
125  /** See @ref tcontrol::get_state. */
126  virtual unsigned get_state() const override;
127 
128  /** See @ref twidget::find_at. */
129  virtual twidget* find_at(const tpoint& coordinate,
130  const bool must_be_active) override;
131 
132  /** See @ref twidget::find_at. */
133  virtual const twidget* find_at(const tpoint& coordinate,
134  const bool must_be_active) const override;
135 
136  /** See @ref twidget::find. */
137  twidget* find(const std::string& id, const bool must_be_active) override;
138 
139  /** See @ref twidget::find. */
140  const twidget* find(const std::string& id,
141  const bool must_be_active) const override;
142 
143  /** See @ref twidget::disable_click_dismiss. */
144  bool disable_click_dismiss() const override;
145 
146  /***** ***** ***** setters / getters for members ***** ****** *****/
147 
148  /** @note shouldn't be called after being shown in a dialog. */
149  void set_vertical_scrollbar_mode(const tscrollbar_mode scrollbar_mode);
151  {
153  }
154 
155  /** @note shouldn't be called after being shown in a dialog. */
156  void set_horizontal_scrollbar_mode(const tscrollbar_mode scrollbar_mode);
158  {
160  }
161 
163  {
164  return content_grid_;
165  }
166  const tgrid* content_grid() const
167  {
168  return content_grid_;
169  }
170 
171  const SDL_Rect& content_visible_area() const
172  {
173  return content_visible_area_;
174  }
175 
176  /***** ***** ***** scrollbar helpers ***** ****** *****/
177 
178  /* Returns at_end status of the vertical scrollbar.
179  *
180  */
182 
183  /**
184  * Returns current position of the vertical scrollbar.
185  *
186  */
187  unsigned get_vertical_scrollbar_item_position() const;
188 
189  /**
190  * Move the vertical scrollbar to a position.
191  *
192  * @param position The position to scroll to.
193  */
194  void set_vertical_scrollbar_item_position(const unsigned position);
195 
196  /**
197  * Scrolls the vertical scrollbar.
198  *
199  * @param scroll The position to scroll to.
200  */
202 
203  /**
204  * Scrolls the horizontal scrollbar.
205  *
206  * @param scroll The position to scroll to.
207  */
209 
210  /**
211  * Callback when the scrollbar moves (NOTE maybe only one callback needed).
212  * Maybe also make protected or private and add a friend.
213  */
215  {
216  scrollbar_moved();
217  }
218 
220  {
221  scrollbar_moved();
222  }
223 
224 protected:
225  /**
226  * Shows a certain part of the content.
227  *
228  * When the part to be shown is bigger as the visible viewport the top
229  * left of the wanted rect will be the top left of the viewport.
230  *
231  * @param rect The rect which should be visible.
232  */
233  void show_content_rect(const SDL_Rect& rect);
234 
235  /*
236  * The widget contains the following three grids.
237  *
238  * * _vertical_scrollbar_grid containing at least a widget named
239  * _vertical_scrollbar
240  *
241  * * _horizontal_scrollbar_grid containing at least a widget named
242  * _horizontal_scrollbar
243  *
244  * * _content_grid a grid which holds the contents of the area.
245  *
246  * NOTE maybe just hardcode these in the finalize phase...
247  *
248  */
249 
250  /**
251  * Sets the status of the scrollbar buttons.
252  *
253  * This is needed after the scrollbar moves so the status of the buttons
254  * will be active or inactive as needed.
255  */
257 
258  /**
259  * Notification if the content of a child needs a resize.
260  *
261  * When a resize is required the container first can try to handle it
262  * itself. If it can't honor the request the function will call @ref
263  * twindow::invalidate_layout().
264  *
265  * @note Calling this function on a widget with size == (0, 0) results
266  * false but doesn't call invalidate_layout, the engine expects to be in
267  * build up phase with the layout already invalidated.
268  *
269  * @param force_sizing If the contents fit do we want to force a
270  * resize? This is needed in the MP lobby since
271  * items might not be properly placed yet.
272  * (The listboxes with the player info need it.)
273  *
274  * @returns True if the resize is handled, false
275  * otherwise.
276  */
277  bool content_resize_request(const bool force_sizing = false);
278 
279  /**
280  * Request from the content to modify the size of the container.
281  *
282  * When the wanted resize fails the function will call @ref
283  * twindow::invalidate_layout().
284  *
285  *
286  * @note Calling this function on a widget with size == (0, 0) results
287  * false but doesn't call invalidate_layout, the engine expects to be in
288  * build up phase with the layout already invalidated.
289  *
290  * @note If @ref twindow::get_need_layout() is true the function returns
291  * false and doesn't try to fit the contents since a layout phase will be
292  * triggered anyway.
293  *
294  * @note This function might replace the @ref content_resize_request above.
295  *
296  * @param width_modification The wanted modification to the width:
297  * * negative values reduce width.
298  * * zero leave width as is.
299  * * positive values increase width.
300  * @param height_modification The wanted modification to the height:
301  * * negative values reduce height.
302  * * zero leave height as is.
303  * * positive values increase height.
304  * @param width_modification_pos
305  * The position where the additional content was
306  * inserted/removed, defaults to -1 whcih means
307  * 'at end'
308  * @param height_modification_po
309  * The position where the additional content was
310  * inserted/removed, defaults to -1 whcih means
311  * 'at end'
312  *
313  * @returns True is wanted modification is accepted false
314  * otherwise.
315  */
316  bool content_resize_request(const int width_modification,
317  const int height_modification,
318  const int width_modification_pos = -1,
319  const int height_modification_pos = -1);
320 
321 private:
322  /**
323  * Helper for @ref content_resize_request.
324  *
325  * Handle the width modification.
326  */
327  bool content_resize_width(const int width_modification, const int width_modification_pos);
328 
329  /**
330  * Helper for @ref content_resize_request.
331  *
332  * Handle the height modification.
333  */
334  bool content_resize_height(const int height_modification, const int width_modification_pos);
335 
336 protected:
337  /***** ***** ***** ***** keyboard functions ***** ***** ***** *****/
338 
339  /**
340  * Home key pressed.
341  *
342  * @param modifier The SDL keyboard modifier when the key was
343  * pressed.
344  * @param handled If the function handles the key it should
345  * set handled to true else do not modify it.
346  * This is used in the keyboard event
347  * changing.
348  */
349  virtual void handle_key_home(SDLMod modifier, bool& handled);
350 
351  /**
352  * End key pressed.
353  *
354  * @param modifier The SDL keyboard modifier when the key was
355  * pressed.
356  * @param handled If the function handles the key it should
357  * set handled to true else do not modify it.
358  * This is used in the keyboard event
359  * changing.
360  */
361  virtual void handle_key_end(SDLMod modifier, bool& handled);
362 
363  /**
364  * Page up key pressed.
365  *
366  * @param modifier The SDL keyboard modifier when the key was
367  * pressed.
368  * @param handled If the function handles the key it should
369  * set handled to true else do not modify it.
370  * This is used in the keyboard event
371  * changing.
372  */
373  virtual void handle_key_page_up(SDLMod modifier, bool& handled);
374 
375  /**
376  * Page down key pressed.
377  *
378  * @param modifier The SDL keyboard modifier when the key was
379  * pressed.
380  * @param handled If the function handles the key it should
381  * set handled to true else do not modify it.
382  * This is used in the keyboard event
383  * changing.
384  */
385  virtual void handle_key_page_down(SDLMod modifier, bool& handled);
386 
387 
388  /**
389  * Up arrow key pressed.
390  *
391  * @param modifier The SDL keyboard modifier when the key was
392  * pressed.
393  * @param handled If the function handles the key it should
394  * set handled to true else do not modify it.
395  * This is used in the keyboard event
396  * changing.
397  */
398  virtual void handle_key_up_arrow(SDLMod modifier, bool& handled);
399 
400  /**
401  * Down arrow key pressed.
402  *
403  * @param modifier The SDL keyboard modifier when the key was
404  * pressed.
405  * @param handled If the function handles the key it should
406  * set handled to true else do not modify it.
407  * This is used in the keyboard event
408  * changing.
409  */
410  virtual void handle_key_down_arrow(SDLMod modifier, bool& handled);
411 
412  /**
413  * Left arrow key pressed.
414  *
415  * @param modifier The SDL keyboard modifier when the key was
416  * pressed.
417  * @param handled If the function handles the key it should
418  * set handled to true else do not modify it.
419  * This is used in the keyboard event
420  * changing.
421  */
422  virtual void handle_key_left_arrow(SDLMod modifier, bool& handled);
423 
424  /**
425  * Right arrow key pressed.
426  *
427  * @param modifier The SDL keyboard modifier when the key was
428  * pressed.
429  * @param handled If the function handles the key it should
430  * set handled to true else do not modify it.
431  * This is used in the keyboard event
432  * changing.
433  */
434  virtual void handle_key_right_arrow(SDLMod modifier, bool& handled);
435 
436 private:
437  /**
438  * Possible states of the widget.
439  *
440  * Note the order of the states must be the same as defined in settings.hpp.
441  */
442  enum tstate {
446  };
447 
448  /**
449  * Current state of the widget.
450  *
451  * The state of the widget determines what to render and how the widget
452  * reacts to certain 'events'.
453  */
455 
456  /**
457  * The mode of how to show the scrollbar.
458  *
459  * This value should only be modified before showing, doing it while
460  * showing results in UB.
461  */
463 
464  /** These are valid after finalize_setup(). */
466 
467  /** These are valid after finalize_setup(). */
469 
470  /** The grid that holds the content. */
472 
473  /** Dummy spacer to hold the contents location. */
475 
476  /**
477  * Cache for the visible area for the content.
478  *
479  * The visible area for the content needs to be updated when scrolling.
480  */
482 
483  /** The builder needs to call us so we do our setup. */
484  void finalize_setup(); // FIXME make protected
485 
486  /**
487  * Function for the subclasses to do their setup.
488  *
489  * This function is called at the end of finalize_setup().
490  */
491  virtual void finalize_subclass()
492  {
493  }
494 
495  /** See @ref twidget::layout_children. */
496  virtual void layout_children() override;
497 
498  /** See @ref twidget::impl_draw_children. */
499  virtual void impl_draw_children(surface& frame_buffer,
500  int x_offset,
501  int y_offset) override;
502 
503  /** See @ref twidget::child_populate_dirty_list. */
504  virtual void
506  const std::vector<twidget*>& call_stack) override;
507 
508  /**
509  * Sets the size of the content grid.
510  *
511  * This function normally just updates the content grid but can be
512  * overridden by a subclass.
513  *
514  * @param origin The origin for the content.
515  * @param size The size of the content.
516  */
517  virtual void set_content_size(const tpoint& origin, const tpoint& size);
518 
519  /** Helper function which needs to be called after the scollbar moved. */
520  void scrollbar_moved();
521 
522  /** See @ref tcontrol::get_control_type. */
523  virtual const std::string& get_control_type() const override;
524 
525  /***** ***** ***** signal handlers ***** ****** *****/
526 
528  bool& handled,
529  const SDLKey key,
530  SDLMod modifier);
531 
532  void signal_handler_sdl_wheel_up(const event::tevent event, bool& handled);
534  bool& handled);
536  bool& handled);
538  bool& handled);
539 };
540 
541 } // namespace gui2
542 
543 #endif
Like auto_visible, but when not needed upon the initial layout phase, the bars are not shown and no s...
void set_vertical_scrollbar_item_position(const unsigned position)
Move the vertical scrollbar to a position.
virtual void set_visible_rectangle(const SDL_Rect &rectangle) override
See twidget::set_visible_rectangle.
virtual void request_reduce_height(const unsigned maximum_height) override
See twidget::request_reduce_height.
twidget * find(const std::string &id, const bool must_be_active) override
See twidget::find.
#define SDLMod
Definition: compat.hpp:30
tspacer * content_
Dummy spacer to hold the contents location.
virtual bool get_active() const override
See tcontrol::get_active.
virtual void layout_initialise(const bool full_initialisation) override
See twidget::layout_initialise.
virtual const std::string & get_control_type() const override
See tcontrol::get_control_type.
virtual void child_populate_dirty_list(twindow &caller, const std::vector< twidget * > &call_stack) override
See twidget::child_populate_dirty_list.
Base container class.
Definition: grid.hpp:29
virtual void handle_key_end(SDLMod modifier, bool &handled)
End key pressed.
void scroll_vertical_scrollbar(const tscrollbar_::tscroll scroll)
Scrolls the vertical scrollbar.
virtual twidget * find_at(const tpoint &coordinate, const bool must_be_active) override
See twidget::find_at.
Base class for a scroll bar.
Definition: scrollbar.hpp:41
void scroll_horizontal_scrollbar(const tscrollbar_::tscroll scroll)
Scrolls the horizontal scrollbar.
void signal_handler_sdl_key_down(const event::tevent event, bool &handled, const SDLKey key, SDLMod modifier)
virtual void set_origin(const tpoint &origin) override
See twidget::set_origin.
virtual bool can_wrap() const override
See twidget::can_wrap.
unsigned get_vertical_scrollbar_item_position() const
Returns current position of the vertical scrollbar.
#define SDLKey
Definition: compat.hpp:29
The scrollbar is never shown even not when needed.
base class of top level items, the only item which needs to store the final canvases to draw on ...
Definition: window.hpp:62
virtual void impl_draw_children(surface &frame_buffer, int x_offset, int y_offset) override
See twidget::impl_draw_children.
tscrollbar_mode get_horizontal_scrollbar_mode() const
virtual void handle_key_home(SDLMod modifier, bool &handled)
Home key pressed.
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
tscrollbar_ * vertical_scrollbar_
These are valid after finalize_setup().
void signal_handler_sdl_wheel_up(const event::tevent event, bool &handled)
virtual void handle_key_down_arrow(SDLMod modifier, bool &handled)
Down arrow key pressed.
tgrid * vertical_scrollbar_grid_
These are valid after finalize_setup().
bool content_resize_request(const bool force_sizing=false)
Notification if the content of a child needs a resize.
void set_vertical_scrollbar_mode(const tscrollbar_mode scrollbar_mode)
SDL_Rect content_visible_area_
Cache for the visible area for the content.
void set_scrollbar_button_status()
Sets the status of the scrollbar buttons.
const SDL_Rect & content_visible_area() const
virtual tpoint calculate_best_size() const override
See twidget::calculate_best_size.
tscrollbar_container(const unsigned canvas_count)
virtual void request_reduce_width(const unsigned maximum_width) override
See twidget::request_reduce_width.
bool disable_click_dismiss() const override
See twidget::disable_click_dismiss.
An empty widget.
Definition: spacer.hpp:38
void signal_handler_sdl_wheel_down(const event::tevent event, bool &handled)
void show_content_rect(const SDL_Rect &rect)
Shows a certain part of the content.
tscrollbar_mode
The way to handle the showing or hiding of the scrollbar.
bool content_resize_width(const int width_modification, const int width_modification_pos)
Helper for content_resize_request.
tevent
The event send to the dispatcher.
Definition: handler.hpp:54
void finalize_setup()
The builder needs to call us so we do our setup.
tgrid * content_grid_
The grid that holds the content.
virtual void set_content_size(const tpoint &origin, const tpoint &size)
Sets the size of the content grid.
void signal_handler_sdl_wheel_left(const event::tevent event, bool &handled)
tscrollbar_mode vertical_scrollbar_mode_
The mode of how to show the scrollbar.
The listbox class.
Definition: listbox.hpp:39
Holds a 2D point.
Definition: point.hpp:24
void set_horizontal_scrollbar_mode(const tscrollbar_mode scrollbar_mode)
virtual void layout_children() override
See twidget::layout_children.
The scrollbar is always shown, whether needed or not.
bool content_resize_height(const int height_modification, const int width_modification_pos)
Helper for content_resize_request.
virtual void handle_key_up_arrow(SDLMod modifier, bool &handled)
Up arrow key pressed.
virtual void handle_key_right_arrow(SDLMod modifier, bool &handled)
Right arrow key pressed.
tscrollbar_mode horizontal_scrollbar_mode_
A generic container base class.
Definition: container.hpp:32
GLsizeiptr size
Definition: glew.h:1649
void signal_handler_sdl_wheel_right(const event::tevent event, bool &handled)
virtual void place(const tpoint &origin, const tpoint &size) override
See twidget::place.
Helper to implement private functions without modifying the header.
cl_event event
Definition: glew.h:3070
const tgrid * content_grid() const
Base class for all widgets.
Definition: widget.hpp:49
tstate
Possible states of the widget.
virtual unsigned get_state() const override
See tcontrol::get_state.
void scrollbar_moved()
Helper function which needs to be called after the scollbar moved.
The scrollbar is shown when the number of items is larger as the visible items.
void vertical_scrollbar_moved()
Callback when the scrollbar moves (NOTE maybe only one callback needed).
tscrollbar_mode get_vertical_scrollbar_mode() const
virtual void handle_key_left_arrow(SDLMod modifier, bool &handled)
Left arrow key pressed.
GLsizei const GLcharARB ** string
Definition: glew.h:4503
tstate state_
Current state of the widget.
Contains the implementation details for lexical_cast and shouldn't be used directly.
virtual void finalize_subclass()
Function for the subclasses to do their setup.
virtual void handle_key_page_up(SDLMod modifier, bool &handled)
Page up key pressed.
Base class for creating containers with one or two scrollbar(s).
virtual void handle_key_page_down(SDLMod modifier, bool &handled)
Page down key pressed.
tscroll
scroll 'step size'.
Definition: scrollbar.hpp:55