The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
scrollbar.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_HPP_INCLUDED
16 #define GUI_WIDGETS_SCROLLBAR_HPP_INCLUDED
17 
18 #include "gui/core/notifier.hpp"
19 #include "gui/widgets/control.hpp"
20 
21 #include "utils/functional.hpp"
22 
23 namespace gui2
24 {
25 
26 /**
27  * Base class for a scroll bar.
28  *
29  * class will be subclassed for the horizontal and vertical scroll bar.
30  * It might be subclassed for a slider class.
31  *
32  * To make this class generic we talk a lot about offset and length and use
33  * pure virtual functions. The classes implementing us can use the heights or
34  * widths, whichever is applicable.
35  *
36  * The NOTIFY_MODIFIED event is send when the position of scrollbar is changed.
37  *
38  * Common signal handlers:
39  * - connect_signal_notify_modified
40  */
41 class tscrollbar_ : public tcontrol
42 {
43  /** @todo Abstract the code so this friend is no longer needed. */
44  friend class tslider;
45 
46 public:
47  tscrollbar_();
48 
49  /**
50  * scroll 'step size'.
51  *
52  * When scrolling we always scroll a 'fixed' amount, these are the
53  * parameters for these amounts.
54  */
55  enum tscroll {
56  BEGIN, /**< Go to begin position. */
57  ITEM_BACKWARDS, /**< Go one item towards the begin. */
58  HALF_JUMP_BACKWARDS, /**< Go half the visible items towards the begin.
59  */
60  JUMP_BACKWARDS, /**< Go the visibile items towards the begin. */
61  END, /**< Go to the end position. */
62  ITEM_FORWARD, /**< Go one item towards the end. */
63  HALF_JUMP_FORWARD, /**< Go half the visible items towards the end. */
65  }; /**< Go the visible items towards the end. */
66 
67  /**
68  * Sets the item position.
69  *
70  * We scroll a predefined step.
71  *
72  * @param scroll 'step size' to scroll.
73  */
74  void scroll(const tscroll scroll);
75 
76  /** Is the positioner at the beginning of the scrollbar? */
77  bool at_begin() const
78  {
79  return item_position_ == 0;
80  }
81 
82  /**
83  * Is the positioner at the and of the scrollbar?
84  *
85  * Note both begin and end might be true at the same time.
86  */
87  bool at_end() const
88  {
90  }
91 
92  /** Are all items visible? */
93  bool all_items_visible() const
94  {
95  return visible_items_ >= item_count_;
96  }
97 
98  /***** ***** ***** ***** layout functions ***** ***** ***** *****/
99 
100  /** See @ref twidget::place. */
101  virtual void place(const tpoint& origin, const tpoint& size) override;
102 
103  /***** ***** ***** ***** Inherited ***** ***** ***** *****/
104 
105  /** See @ref tcontrol::set_active. */
106  virtual void set_active(const bool active) override;
107 
108  /** See @ref tcontrol::get_active. */
109  virtual bool get_active() const override;
110 
111  /** See @ref tcontrol::get_state. */
112  virtual unsigned get_state() const override;
113 
114  /***** ***** ***** setters / getters for members ***** ****** *****/
115 
116  void set_item_count(const unsigned item_count)
117  {
118  item_count_ = item_count;
119  recalculate();
120  }
121  unsigned get_item_count() const
122  {
123  return item_count_;
124  }
125 
126  /**
127  * Note the position isn't guaranteed to be the wanted position
128  * the step size is honored. The value will be rouded down.
129  */
130  void set_item_position(const unsigned item_position);
131  unsigned get_item_position() const
132  {
133  return item_position_;
134  }
135 
136  unsigned get_visible_items() const
137  {
138  return visible_items_;
139  }
140  void set_visible_items(const unsigned visible_items)
141  {
142  visible_items_ = visible_items;
143  recalculate();
144  }
145 
146  unsigned get_step_size() const
147  {
148  return step_size_;
149  }
150  void set_step_size(const unsigned step_size)
151  {
152  step_size_ = step_size;
153  recalculate();
154  }
155 
156 protected:
157  unsigned get_positioner_offset() const
158  {
159  return positioner_offset_;
160  }
161 
162  unsigned get_positioner_length() const
163  {
164  return positioner_length_;
165  }
166 
167  /**
168  * See @ref tcontrol::update_canvas.
169  *
170  * After a recalculation the canvasses also need to be updated.
171  */
172  virtual void update_canvas() override;
173 
174  /**
175  * Callback for subclasses to get notified about positioner movement.
176  *
177  * @todo This is a kind of hack due to the fact there's no simple
178  * callback slot mechanism. See whether we can implement a generic way to
179  * attach callback which would remove quite some extra code.
180  */
182  {
183  }
184 
185 private:
186  /**
187  * Possible states of the widget.
188  *
189  * Note the order of the states must be the same as defined in settings.hpp.
190  */
191  enum tstate {
197  };
198 
199  void set_state(const tstate state);
200  /**
201  * Current state of the widget.
202  *
203  * The state of the widget determines what to render and how the widget
204  * reacts to certain 'events'.
205  */
207 
208  /** The number of items the scrollbar 'holds'. */
209  unsigned item_count_;
210 
211  /** The item the positioner is at, starts at 0. */
212  unsigned item_position_;
213 
214  /**
215  * The number of items which can be shown at the same time.
216  *
217  * As long as all items are visible we don't need to scroll.
218  */
219  unsigned visible_items_;
220 
221  /**
222  * Number of items moved when scrolling.
223  *
224  * The step size is the minimum number of items we scroll through when we
225  * move. Normally this value is 1, we can move per item. But for example
226  * sliders want for example to move per 5 items.
227  */
228  unsigned step_size_;
229 
230  /**
231  * Number of pixels per step.
232  *
233  * The number of pixels the positioner needs to move to go to the next step.
234  * Note if there is too little space it can happen 1 pixel does more than 1
235  * step.
236  */
238 
239  /**
240  * The position the mouse was at the last movement.
241  *
242  * This is used during dragging the positioner.
243  */
245 
246  /**
247  * The start offset of the positioner.
248  *
249  * This takes the offset before in consideration.
250  */
252 
253  /** The current length of the positioner. */
255 
256  /***** ***** ***** ***** Pure virtual functions ***** ***** ***** *****/
257 
258  /** Get the length of the scrollbar. */
259  virtual unsigned get_length() const = 0;
260 
261  /** The minimum length of the positioner. */
262  virtual unsigned minimum_positioner_length() const = 0;
263 
264  /** The maximum length of the positioner. */
265  virtual unsigned maximum_positioner_length() const = 0;
266 
267  /**
268  * The number of pixels we can't use since they're used for borders.
269  *
270  * These are the pixels before the widget (left side if horizontal,
271  * top side if vertical).
272  */
273  virtual unsigned offset_before() const = 0;
274 
275  /**
276  * The number of pixels we can't use since they're used for borders.
277  *
278  * These are the pixels after the widget (right side if horizontal,
279  * bottom side if vertical).
280  */
281  virtual unsigned offset_after() const = 0;
282 
283  /**
284  * Is the coordinate on the positioner?
285  *
286  * @param coordinate Coordinate to test whether it's on the
287  * positioner.
288  *
289  * @returns Whether the location on the positioner is.
290  */
291  virtual bool on_positioner(const tpoint& coordinate) const = 0;
292 
293  /**
294  * Is the coordinate on the bar?
295  *
296  * @param coordinate Coordinate to test whether it's on the
297  * bar.
298  *
299  * @returns Whether the location on the bar is.
300  * @retval -1 Coordinate is on the bar before positioner.
301  * @retval 0 Coordinate is not on the bar.
302  * @retval 1 Coordinate is on the bar after the positioner.
303  */
304  virtual int on_bar(const tpoint& coordinate) const = 0;
305 
306  /**
307  * Is the coordinate in the bar's orthogonal range?
308  *
309  * @param coordinate Coordinate to test whether it's in-range.
310  *
311  * @returns Whether the location is in the bar's.
312  * orthogonal range.
313  */
314  virtual bool in_orthogonal_range(const tpoint& coordinate) const = 0;
315 
316  /**
317  * Gets the relevant difference in between the two positions.
318  *
319  * This function is used to determine how much the positioner needs to be
320  * moved.
321  */
322  virtual int get_length_difference(const tpoint& original,
323  const tpoint& current) const = 0;
324 
325  /***** ***** ***** ***** Private functions ***** ***** ***** *****/
326 
327  /**
328  * Updates the scrollbar.
329  *
330  * Needs to be called when someting changes eg number of items
331  * or available size. It can only be called once we have a size
332  * otherwise we can't calulate a thing.
333  */
334  void recalculate();
335 
336  /**
337  * Updates the positioner.
338  *
339  * This is a helper for recalculate().
340  */
341  void recalculate_positioner();
342 
343  /**
344  * Moves the positioner.
345  *
346  * @param distance The distance moved, negative to begin, positive
347  * to end.
348  */
349  void move_positioner(const int distance);
350 
351  /** Inherited from tcontrol. */
352  void load_config_extra();
353 
354  /***** ***** ***** signal handlers ***** ****** *****/
355 
357  bool& handled,
358  bool& halt);
359 
361  bool& handled,
362  bool& halt,
363  const tpoint& coordinate);
364 
365  void signal_handler_mouse_leave(const event::tevent event, bool& handled);
366 
368  bool& handled);
369 
371  bool& handled);
372 };
373 
374 } // namespace gui2
375 
376 #endif
void signal_handler_left_button_down(const event::tevent event, bool &handled)
Definition: scrollbar.cpp:384
unsigned positioner_offset_
The start offset of the positioner.
Definition: scrollbar.hpp:251
unsigned positioner_length_
The current length of the positioner.
Definition: scrollbar.hpp:254
void set_step_size(const unsigned step_size)
Definition: scrollbar.hpp:150
void set_item_count(const unsigned item_count)
Definition: scrollbar.hpp:116
void signal_handler_mouse_motion(const event::tevent event, bool &handled, bool &halt, const tpoint &coordinate)
Definition: scrollbar.cpp:326
Go the visibile items towards the begin.
Definition: scrollbar.hpp:60
virtual void child_callback_positioner_moved()
Callback for subclasses to get notified about positioner movement.
Definition: scrollbar.hpp:181
virtual unsigned get_state() const override
See tcontrol::get_state.
Definition: scrollbar.cpp:122
virtual bool get_active() const override
See tcontrol::get_active.
Definition: scrollbar.cpp:117
Go to the end position.
Definition: scrollbar.hpp:61
void load_config_extra()
Inherited from tcontrol.
Definition: scrollbar.cpp:306
Base class for a scroll bar.
Definition: scrollbar.hpp:41
void signal_handler_left_button_up(const event::tevent event, bool &handled)
Definition: scrollbar.cpp:417
virtual void place(const tpoint &origin, const tpoint &size) override
See twidget::place.
Definition: scrollbar.cpp:102
Go one item towards the begin.
Definition: scrollbar.hpp:57
virtual int get_length_difference(const tpoint &original, const tpoint &current) const =0
Gets the relevant difference in between the two positions.
bool all_items_visible() const
Are all items visible?
Definition: scrollbar.hpp:93
virtual void set_active(const bool active) override
See tcontrol::set_active.
Definition: scrollbar.cpp:110
virtual bool on_positioner(const tpoint &coordinate) const =0
Is the coordinate on the positioner?
unsigned get_item_count() const
Definition: scrollbar.hpp:121
virtual unsigned get_length() const =0
Get the length of the scrollbar.
A class inherited from ttext_box that displays its input as stars.
Definition: field-fwd.hpp:23
virtual unsigned offset_before() const =0
The number of pixels we can't use since they're used for borders.
void recalculate()
Updates the scrollbar.
Definition: scrollbar.cpp:168
void move_positioner(const int distance)
Moves the positioner.
Definition: scrollbar.cpp:254
unsigned get_item_position() const
Definition: scrollbar.hpp:131
virtual unsigned offset_after() const =0
The number of pixels we can't use since they're used for borders.
void set_state(const tstate state)
Definition: scrollbar.cpp:160
tevent
The event send to the dispatcher.
Definition: handler.hpp:54
Go half the visible items towards the begin.
Definition: scrollbar.hpp:58
unsigned step_size_
Number of items moved when scrolling.
Definition: scrollbar.hpp:228
void set_visible_items(const unsigned visible_items)
Definition: scrollbar.hpp:140
virtual bool in_orthogonal_range(const tpoint &coordinate) const =0
Is the coordinate in the bar's orthogonal range?
bool at_end() const
Is the positioner at the and of the scrollbar?
Definition: scrollbar.hpp:87
unsigned item_position_
The item the positioner is at, starts at 0.
Definition: scrollbar.hpp:212
unsigned item_count_
The number of items the scrollbar 'holds'.
Definition: scrollbar.hpp:209
virtual void update_canvas() override
See tcontrol::update_canvas.
Definition: scrollbar.cpp:149
unsigned get_positioner_offset() const
Definition: scrollbar.hpp:157
void signal_handler_mouse_leave(const event::tevent event, bool &handled)
Definition: scrollbar.cpp:372
Holds a 2D point.
Definition: point.hpp:24
Go to begin position.
Definition: scrollbar.hpp:56
virtual int on_bar(const tpoint &coordinate) const =0
Is the coordinate on the bar?
void signal_handler_mouse_enter(const event::tevent event, bool &handled, bool &halt)
Definition: scrollbar.cpp:316
Base class for all visible items.
Definition: control.hpp:34
unsigned get_visible_items() const
Definition: scrollbar.hpp:136
virtual unsigned maximum_positioner_length() const =0
The maximum length of the positioner.
GLsizeiptr size
Definition: glew.h:1649
tpoint mouse_
The position the mouse was at the last movement.
Definition: scrollbar.hpp:244
void scroll(const tscroll scroll)
Sets the item position.
Definition: scrollbar.cpp:54
unsigned visible_items_
The number of items which can be shown at the same time.
Definition: scrollbar.hpp:219
cl_event event
Definition: glew.h:3070
tstate state_
Current state of the widget.
Definition: scrollbar.hpp:206
void set_item_position(const unsigned item_position)
Note the position isn't guaranteed to be the wanted position the step size is honored.
Definition: scrollbar.cpp:127
tstate
Possible states of the widget.
Definition: scrollbar.hpp:191
bool at_begin() const
Is the positioner at the beginning of the scrollbar?
Definition: scrollbar.hpp:77
Go one item towards the end.
Definition: scrollbar.hpp:62
A slider.
Definition: slider.hpp:30
unsigned get_step_size() const
Definition: scrollbar.hpp:146
void recalculate_positioner()
Updates the positioner.
Definition: scrollbar.cpp:240
virtual unsigned minimum_positioner_length() const =0
The minimum length of the positioner.
unsigned get_positioner_length() const
Definition: scrollbar.hpp:162
Go half the visible items towards the end.
Definition: scrollbar.hpp:63
float pixels_per_step_
Number of pixels per step.
Definition: scrollbar.hpp:237
tscroll
scroll 'step size'.
Definition: scrollbar.hpp:55