1 /***********************************************************************
2     created:    13/4/2004
3     author:     Paul D Turner
4 *************************************************************************/
5 /***************************************************************************
6  *   Copyright (C) 2004 - 2012 Paul D Turner & The CEGUI Development Team
7  *
8  *   Permission is hereby granted, free of charge, to any person obtaining
9  *   a copy of this software and associated documentation files (the
10  *   "Software"), to deal in the Software without restriction, including
11  *   without limitation the rights to use, copy, modify, merge, publish,
12  *   distribute, sublicense, and/or sell copies of the Software, and to
13  *   permit persons to whom the Software is furnished to do so, subject to
14  *   the following conditions:
15  *
16  *   The above copyright notice and this permission notice shall be
17  *   included in all copies or substantial portions of the Software.
18  *
19  *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20  *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21  *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22  *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23  *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  *   OTHER DEALINGS IN THE SOFTWARE.
26  ***************************************************************************/
27 #ifndef _CEGUIScrollbar_h_
28 #define _CEGUIScrollbar_h_
29 
30 #include "../Base.h"
31 #include "../Window.h"
32 
33 #if defined(_MSC_VER)
34 #   pragma warning(push)
35 #   pragma warning(disable : 4251)
36 #endif
37 
38 // Start of CEGUI namespace section
39 namespace CEGUI
40 {
41 //! Base class for Scrollbar window renderer objects.
42 class CEGUIEXPORT ScrollbarWindowRenderer : public WindowRenderer
43 {
44 public:
45     ScrollbarWindowRenderer(const String& name);
46 
47     /*!
48     \brief
49         update the size and location of the thumb to properly represent the
50         current state of the scroll bar
51     */
52     virtual void updateThumb(void) = 0;
53 
54     /*!
55     \brief
56         return value that best represents current scroll bar position given the
57         current location of the thumb.
58 
59     \return
60         float value that, given the thumb widget position, best represents the
61         current position for the scroll bar.
62     */
63     virtual float getValueFromThumb(void) const = 0;
64 
65     /*!
66     \brief
67         Given window location \a pt, return a value indicating what change
68         should be made to the scroll bar.
69 
70     \param pt
71         Point object describing a pixel position in window space.
72 
73     \return
74         - -1 to indicate scroll bar position should be moved to a lower value.
75         -  0 to indicate scroll bar position should not be changed.
76         - +1 to indicate scroll bar position should be moved to a higher value.
77     */
78     virtual float getAdjustDirectionFromPoint(const Vector2f& pt) const  = 0;
79 };
80 
81 /*!
82 \brief
83     Base scroll bar class.
84 
85     This base class for scroll bars does not have any idea of direction - a
86     derived class would add whatever meaning is appropriate according to what
87     that derived class represents to the user.
88 */
89 class CEGUIEXPORT Scrollbar : public Window
90 {
91 public:
92     //! Window factory name
93     static const String WidgetTypeName;
94 
95     //! Namespace for global events
96     static const String EventNamespace;
97     /** Event fired when the scroll bar position value changes.
98      * Handlers are passed a const WindowEventArgs reference with
99      * WindowEventArgs::window set to the Scrollbar whose position value had
100      * changed.
101      */
102     static const String EventScrollPositionChanged;
103     /** Event fired when the user begins dragging the scrollbar thumb.
104      * Handlers are passed a const WindowEventArgs reference with
105      * WindowEventArgs::window set to the Scrollbar whose thumb is being
106      * dragged.
107      */
108     static const String EventThumbTrackStarted;
109     /** Event fired when the user releases the scrollbar thumb.
110      * Handlers are passed a const WindowEventArgs reference with
111      * WindowEventArgs::window set to the Scrollbar whose thumb has been
112      * released.
113      */
114     static const String EventThumbTrackEnded;
115     /** Event fired when the scroll bar configuration data is changed.
116      * Handlers are passed a const WindowEventArgs reference with
117      * WindowEventArgs::window set to the Scrollbar whose configuration
118      * has been changed.
119      */
120     static const String EventScrollConfigChanged;
121 
122     //! Widget name for the thumb component.
123     static const String ThumbName;
124     //! Widget name for the increase button component.
125     static const String IncreaseButtonName;
126     //! Widget name for the decrease button component.
127     static const String DecreaseButtonName;
128 
129     /*!
130     \brief
131         Return the size of the document or data.
132 
133         The document size should be thought of as the total size of the data
134         that is being scrolled through (the number of lines in a text file for
135         example).
136 
137     \note
138         The returned value has no meaning within the Gui system, it is left up
139         to the application to assign appropriate values for the application
140         specific use of the scroll bar.
141 
142     \return
143         float value specifying the currently set document size.
144     */
getDocumentSize(void)145     float getDocumentSize(void) const
146     {
147         return d_documentSize;
148     }
149 
150     /*!
151     \brief
152         Set the size of the document or data.
153 
154         The document size should be thought of as the total size of the data
155         that is being scrolled through (the number of lines in a text file for
156         example).
157 
158     \note
159         The value set has no meaning within the Gui system, it is left up to
160         the application to assign appropriate values for the application
161         specific use of the scroll bar.
162 
163     \param document_size
164         float value specifying the document size.
165     */
166     void setDocumentSize(float document_size);
167 
168     /*!
169     \brief
170         Return the page size for this scroll bar.
171 
172         The page size is typically the amount of data that can be displayed at
173         one time.  This value is also used when calculating the amount the
174         position will change when you click either side of the scroll bar
175         thumb, the amount the position changes will is (pageSize - overlapSize).
176 
177     \note
178         The returned value has no meaning within the Gui system, it is left up
179         to the application to assign appropriate values for the application
180         specific use of the scroll bar.
181 
182     \return
183         float value specifying the currently set page size.
184     */
getPageSize(void)185     float getPageSize(void) const
186     {
187         return d_pageSize;
188     }
189 
190     /*!
191     \brief
192         Set the page size for this scroll bar.
193 
194         The page size is typically the amount of data that can be displayed at
195         one time.  This value is also used when calculating the amount the
196         position will change when you click either side of the scroll bar
197         thumb, the amount the position changes will is (pageSize - overlapSize).
198 
199     \note
200         The value set has no meaning within the Gui system, it is left up to the
201         application to assign appropriate values for the application specific
202         use of the scroll bar.
203 
204     \param page_size
205         float value specifying the page size.
206     */
207     void setPageSize(float page_size);
208 
209     /*!
210     \brief
211         Return the step size for this scroll bar.
212 
213         The step size is typically a single unit of data that can be displayed,
214         this is the amount the position will change when you click either of
215         the arrow buttons on the scroll bar.  (this could be 1 for a single
216         line of text, for example).
217 
218     \note
219         The returned value has no meaning within the Gui system, it is left up
220         to the application to assign appropriate values for the application
221         specific use of the scroll bar.
222 
223     \return
224         float value specifying the currently set step size.
225     */
getStepSize(void)226     float getStepSize(void) const
227     {
228         return d_stepSize;
229     }
230 
231     /*!
232     \brief
233         Set the step size for this scroll bar.
234 
235         The step size is typically a single unit of data that can be displayed,
236         this is the amount the position will change when you click either of the
237         arrow buttons on the scroll bar.  (this could be 1 for a single line of
238         text, for example).
239 
240     \note
241         The value set has no meaning within the Gui system, it is left up to the
242         application to assign appropriate values for the application specific
243         use of the scroll bar.
244 
245     \param step_size
246         float value specifying the step size.
247     */
248     void setStepSize(float step_size);
249 
250     /*!
251     \brief
252         Return the overlap size for this scroll bar.
253 
254         The overlap size is the amount of data from the end of a 'page' that
255         will remain visible when the position is moved by a page.  This is
256         usually used so that the user keeps some context of where they were
257         within the document's data when jumping a page at a time.
258 
259     \note
260         The returned value has no meaning within the Gui system, it is left up
261         to the application to assign appropriate values for the application
262         specific use of the scroll bar.
263 
264     \return
265         float value specifying the currently set overlap size.
266     */
getOverlapSize(void)267     float getOverlapSize(void) const
268     {
269         return d_overlapSize;
270     }
271 
272     /*!
273     \brief
274         Set the overlap size for this scroll bar.
275 
276         The overlap size is the amount of data from the end of a 'page' that
277         will remain visible when the position is moved by a page.  This is
278         usually used so that the user keeps some context of where they were
279         within the document's data when jumping a page at a time.
280 
281     \note
282         The value set has no meaning within the Gui system, it is left up to the
283         application to assign appropriate values for the application specific
284         use of the scroll bar.
285 
286     \param overlap_size
287         float value specifying the overlap size.
288     */
289     void setOverlapSize(float overlap_size);
290 
291     /*!
292     \brief
293         Return the current position of scroll bar within the document.
294 
295         The range of the scroll bar is from 0 to the size of the document minus
296         the size of a page (0 <= position <= (documentSize - pageSize)).
297 
298     \note
299         The returned value has no meaning within the Gui system, it is left up
300         to the application to assign appropriate values for the application
301         specific use of the scroll bar.
302 
303     \return
304         float value specifying the current position of the scroll bar within its
305         document.
306     */
getScrollPosition(void)307     float getScrollPosition(void) const
308     {
309         return d_position;
310     }
311 
312     /*!
313     \brief
314         Set the current position of scroll bar within the document.
315 
316         The range of the scroll bar is from 0 to the size of the document minus
317         the size of a page (0 <= position <= (documentSize - pageSize)), any
318         attempt to set the position outside this range will be adjusted so that
319         it falls within the legal range.
320 
321     \param position
322         float value specifying the position of the scroll bar within its
323         document.
324     */
325     void setScrollPosition(float position);
326 
327     //! return the current scroll position as a value in the interval [0, 1]
328     float getUnitIntervalScrollPosition() const;
329     //! set the current scroll position as a value in the interval [0, 1]
330     void setUnitIntervalScrollPosition(float position);
331 
332     /*!
333     \brief
334         Return a pointer to the 'increase' PushButtoncomponent widget for this
335         Scrollbar.
336 
337     \return
338         Pointer to a PushButton object.
339 
340     \exception UnknownObjectException
341         Thrown if the increase PushButton component does not exist.
342     */
343     PushButton* getIncreaseButton() const;
344 
345     /*!
346     \brief
347         Return a pointer to the 'decrease' PushButton component widget for this
348         Scrollbar.
349 
350     \return
351         Pointer to a PushButton object.
352 
353     \exception UnknownObjectException
354         Thrown if the 'decrease' PushButton component does not exist.
355     */
356     PushButton* getDecreaseButton() const;
357 
358     /*!
359     \brief
360         Return a pointer to the Thumb component widget for this Scrollbar.
361 
362     \return
363         Pointer to a Thumb object.
364 
365     \exception UnknownObjectException
366         Thrown if the Thumb component does not exist.
367     */
368     Thumb* getThumb() const;
369 
370     /*!
371     \brief
372         Sets multiple scrollbar configuration parameters simultaneously.
373 
374         This function is provided in order to be able to minimise the number
375         of internal state updates that occur when modifying the scrollbar
376         parameters.
377 
378     \param document_size
379         Pointer to a float value holding the new value to be used for the
380         scroll bar document size.  If this is 0 the document size is left
381         unchanged.
382 
383     \param page_size
384         Pointer to a float value holding the new value to be used for the scroll
385         bar page size.  If this is 0 the page size is left unchanged.
386 
387     \param step_size
388         Pointer to a float value holding the new value to be used for the scroll
389         bar step size.  If this is 0 the step size is left unchanged.
390 
391     \param overlap_size
392         Pointer to a float value holding the new value to be used for the scroll
393         bar overlap size.  If this is 0 then overlap size is left unchanged.
394 
395     \param position
396         Pointer to a float value holding the new value to be used for the scroll
397         bar current scroll position.  If this is 0 then the current position is
398         left unchanged.
399 
400     \note
401         Even if \a position is 0, the scrollbar position may still change
402         depending on how the other changes affect the scrollbar.
403     */
404     void setConfig(const float* const document_size,
405                    const float* const page_size,
406                    const float* const step_size,
407                    const float* const overlap_size,
408                    const float* const position);
409 
410     /*!
411     \brief
412         Enable or disable the 'end lock' mode for the scrollbar.
413 
414         When enabled and the current position of the scrollbar is at the end of
415         it's travel, the end lock mode of the scrollbar will automatically
416         update the position when the document and/or page size change in order
417         that the scroll position will remain at the end of it's travel.  This
418         can be used to implement auto-scrolling in certain other widget types.
419 
420     \param enabled
421         - true to indicate that end lock mode should be enabled.
422         - false to indicate that end lock mode should be disabled.
423     */
424     void setEndLockEnabled(const bool enabled);
425 
426     /*!
427     \brief
428         Returns whether the 'end lock'mode for the scrollbar is enabled.
429 
430         When enabled, and the current position of the scrollbar is at the end of
431         it's travel, the end lock mode of the scrollbar will automatically
432         update the scrollbar position when the document and/or page size change
433         in order that the scroll position will remain at the end of it's travel.
434         This can be used to implement auto-scrolling in certain other widget
435         types.
436 
437     \return
438         - true to indicate that the end lock mode is enabled.
439         - false to indicate that the end lock mode is disabled.
440     */
441     bool isEndLockEnabled() const;
442 
443     //! move scroll position forwards by the current step size
444     void scrollForwardsByStep();
445     //! move scroll position backwards by the current step size
446     void scrollBackwardsByStep();
447 
448     //! move scroll position forwards by a page (uses appropriate overlap)
449     void scrollForwardsByPage();
450     //! move scroll position backwards by a page (uses appropriate overlap)
451     void scrollBackwardsByPage();
452 
453     Scrollbar(const String& type, const String& name);
454     ~Scrollbar(void);
455 
456     // overrides
457     void initialiseComponents(void);
458 
459 protected:
460     /*!
461     \brief
462         update the size and location of the thumb to properly represent the
463         current state of the scroll bar
464     */
465     void updateThumb(void);
466 
467     /*!
468     \brief
469         return value that best represents current scroll bar position given the
470         current location of the thumb.
471 
472     \return
473         float value that, given the thumb widget position, best represents the
474         current position for the scroll bar.
475     */
476     float getValueFromThumb(void) const;
477 
478     /*!
479     \brief
480         Given window location \a pt, return a value indicating what change
481         should be made to the scroll bar.
482 
483     \param pt
484         Point object describing a pixel position in window space.
485 
486     \return
487         - -1 to indicate scroll bar position should be moved to a lower value.
488         -  0 to indicate scroll bar position should not be changed.
489         - +1 to indicate scroll bar position should be moved to a higher value.
490     */
491     float getAdjustDirectionFromPoint(const Vector2f& pt) const;
492 
493     /** implementation func that updates scroll position value, returns true if
494      * value was changed.  NB: Fires no events and does no other updates.
495      */
496     bool setScrollPosition_impl(const float position);
497 
498     //! return whether the current scroll position is at the end of the range.
499     bool isAtEnd() const;
500 
501     //! return the max allowable scroll position value
502     float getMaxScrollPosition() const;
503 
504     //! handler function for when thumb moves.
505     bool handleThumbMoved(const EventArgs& e);
506 
507     //! handler function for when the increase button is clicked.
508     bool handleIncreaseClicked(const EventArgs& e);
509 
510     //! handler function for when the decrease button is clicked.
511     bool handleDecreaseClicked(const EventArgs& e);
512 
513     //! handler function for when thumb tracking begins
514     bool handleThumbTrackStarted(const EventArgs& e);
515 
516     //! handler function for when thumb tracking begins
517     bool handleThumbTrackEnded(const EventArgs& e);
518 
519     //! validate window renderer
520     virtual bool validateWindowRenderer(const WindowRenderer* renderer) const;
521 
522     // New event handlers for slider widget
523     //! Handler triggered when the scroll position changes
524     virtual void onScrollPositionChanged(WindowEventArgs& e);
525 
526     //! Handler triggered when the user begins to drag the scroll bar thumb.
527     virtual void onThumbTrackStarted(WindowEventArgs& e);
528 
529     //! Handler triggered when the scroll bar thumb is released
530     virtual void onThumbTrackEnded(WindowEventArgs& e);
531 
532     //! Handler triggered when the scroll bar data configuration changes
533     virtual void onScrollConfigChanged(WindowEventArgs& e);
534 
535     // Overridden event handlers
536     virtual void onMouseButtonDown(MouseEventArgs& e);
537     virtual void onMouseWheel(MouseEventArgs& e);
538 
539     // base class overrides
540     void banPropertiesForAutoWindow();
541 
542     // Implementation Data
543     //! The size of the document / data being scrolled thorugh.
544     float d_documentSize;
545     //! The size of a single 'page' of data.
546     float d_pageSize;
547     //! Step size used for increase / decrease button clicks.
548     float d_stepSize;
549     //! Amount of overlap when jumping by a page.
550     float d_overlapSize;
551     //! Current scroll position.
552     float d_position;
553     //! whether 'end lock' mode is enabled.
554     bool d_endLockPosition;
555 
556 private:
557     //! Adds scrollbar specific properties.
558     void addScrollbarProperties(void);
559 };
560 
561 } // End of  CEGUI namespace section
562 
563 #if defined(_MSC_VER)
564 #   pragma warning(pop)
565 #endif
566 
567 #endif  // end of guard _CEGUIScrollbar_h_
568