1///////////////////////////////////////////////////////////////////////////////
2// Name:        wx/univ/scrolbar.h
3// Purpose:     wxScrollBar for wxUniversal
4// Author:      Vadim Zeitlin
5// Modified by:
6// Created:     20.08.00
7// RCS-ID:      $Id: scrolbar.h 61872 2009-09-09 22:37:05Z VZ $
8// Copyright:   (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9// Licence:     wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12#ifndef _WX_UNIV_SCROLBAR_H_
13#define _WX_UNIV_SCROLBAR_H_
14
15class WXDLLEXPORT wxScrollTimer;
16
17#include "wx/univ/scrarrow.h"
18#include "wx/renderer.h"
19
20// ----------------------------------------------------------------------------
21// the actions supported by this control
22// ----------------------------------------------------------------------------
23
24// scroll the bar
25#define wxACTION_SCROLL_START       wxT("start")     // to the beginning
26#define wxACTION_SCROLL_END         wxT("end")       // to the end
27#define wxACTION_SCROLL_LINE_UP     wxT("lineup")    // one line up/left
28#define wxACTION_SCROLL_PAGE_UP     wxT("pageup")    // one page up/left
29#define wxACTION_SCROLL_LINE_DOWN   wxT("linedown")  // one line down/right
30#define wxACTION_SCROLL_PAGE_DOWN   wxT("pagedown")  // one page down/right
31
32// the scrollbar thumb may be dragged
33#define wxACTION_SCROLL_THUMB_DRAG      wxT("thumbdrag")
34#define wxACTION_SCROLL_THUMB_MOVE      wxT("thumbmove")
35#define wxACTION_SCROLL_THUMB_RELEASE   wxT("thumbrelease")
36
37// ----------------------------------------------------------------------------
38// wxScrollBar
39// ----------------------------------------------------------------------------
40
41class WXDLLEXPORT wxScrollBar : public wxScrollBarBase,
42                                public wxControlWithArrows
43{
44public:
45    // scrollbar elements: they correspond to wxHT_SCROLLBAR_XXX constants but
46    // start from 0 which allows to use them as array indices
47    enum Element
48    {
49        Element_Arrow_Line_1,
50        Element_Arrow_Line_2,
51        Element_Arrow_Page_1,
52        Element_Arrow_Page_2,
53        Element_Thumb,
54        Element_Bar_1,
55        Element_Bar_2,
56        Element_Max
57    };
58
59    wxScrollBar();
60    wxScrollBar(wxWindow *parent,
61                wxWindowID id,
62                const wxPoint& pos = wxDefaultPosition,
63                const wxSize& size = wxDefaultSize,
64                long style = wxSB_HORIZONTAL,
65                const wxValidator& validator = wxDefaultValidator,
66                const wxString& name = wxScrollBarNameStr);
67
68    bool Create(wxWindow *parent,
69                wxWindowID id,
70                const wxPoint& pos = wxDefaultPosition,
71                const wxSize& size = wxDefaultSize,
72                long style = wxSB_HORIZONTAL,
73                const wxValidator& validator = wxDefaultValidator,
74                const wxString& name = wxScrollBarNameStr);
75
76    virtual ~wxScrollBar();
77
78    // implement base class pure virtuals
79    virtual int GetThumbPosition() const;
80    virtual int GetThumbSize() const;
81    virtual int GetPageSize() const;
82    virtual int GetRange() const;
83
84    virtual void SetThumbPosition(int thumbPos);
85    virtual void SetScrollbar(int position, int thumbSize,
86                              int range, int pageSize,
87                              bool refresh = true);
88
89    // wxScrollBar actions
90    void ScrollToStart();
91    void ScrollToEnd();
92    bool ScrollLines(int nLines);
93    bool ScrollPages(int nPages);
94
95    virtual bool PerformAction(const wxControlAction& action,
96                               long numArg = 0,
97                               const wxString& strArg = wxEmptyString);
98
99    static wxInputHandler *GetStdInputHandler(wxInputHandler *handlerDef);
100    virtual wxInputHandler *DoGetStdInputHandler(wxInputHandler *handlerDef)
101    {
102        return GetStdInputHandler(handlerDef);
103    }
104
105    // scrollbars around a normal window should not receive the focus
106    virtual bool AcceptsFocus() const;
107
108    // wxScrollBar sub elements state (combination of wxCONTROL_XXX)
109    void SetState(Element which, int flags);
110    int GetState(Element which) const;
111
112    // implement wxControlWithArrows methods
113    virtual wxRenderer *GetRenderer() const { return m_renderer; }
114    virtual wxWindow *GetWindow() { return this; }
115    virtual bool IsVertical() const { return wxScrollBarBase::IsVertical(); }
116    virtual int GetArrowState(wxScrollArrows::Arrow arrow) const;
117    virtual void SetArrowFlag(wxScrollArrows::Arrow arrow, int flag, bool set);
118    virtual bool OnArrow(wxScrollArrows::Arrow arrow);
119    virtual wxScrollArrows::Arrow HitTestArrow(const wxPoint& pt) const;
120
121    // for wxControlRenderer::DrawScrollbar() only
122    const wxScrollArrows& GetArrows() const { return m_arrows; }
123
124    // returns one of wxHT_SCROLLBAR_XXX constants
125    wxHitTest HitTestBar(const wxPoint& pt) const;
126
127    // idle processing
128    virtual void OnInternalIdle();
129
130protected:
131    virtual wxSize DoGetBestClientSize() const;
132    virtual void DoDraw(wxControlRenderer *renderer);
133    virtual wxBorder GetDefaultBorder() const { return wxBORDER_NONE; }
134
135    // forces update of thumb's visual appearence (does nothing if m_dirty=false)
136    void UpdateThumb();
137
138    // SetThumbPosition() helper
139    void DoSetThumb(int thumbPos);
140
141    // common part of all ctors
142    void Init();
143
144    // is this scrollbar attached to a window or a standalone control?
145    bool IsStandalone() const;
146
147    // scrollbar geometry methods:
148
149    // gets the bounding box for a scrollbar element for the given (by default
150    // - current) thumb position
151    wxRect GetScrollbarRect(wxScrollBar::Element elem, int thumbPos = -1) const;
152
153    // returns the size of the scrollbar shaft excluding the arrows
154    wxCoord GetScrollbarSize() const;
155
156    // translate the scrollbar position (in logical units) into physical
157    // coordinate (in pixels) and the other way round
158    wxCoord ScrollbarToPixel(int thumbPos = -1);
159    int PixelToScrollbar(wxCoord coord);
160
161    // return the starting and ending positions, in pixels, of the thumb of a
162    // scrollbar with the given logical position, thumb size and range and the
163    // given physical length
164    static void GetScrollBarThumbSize(wxCoord length,
165                                      int thumbPos,
166                                      int thumbSize,
167                                      int range,
168                                      wxCoord *thumbStart,
169                                      wxCoord *thumbEnd);
170
171private:
172    // total range of the scrollbar in logical units
173    int m_range;
174
175    // the current and previous (after last refresh - this is used for
176    // repainting optimisation) size of the thumb in logical units (from 0 to
177    // m_range) and its position (from 0 to m_range - m_thumbSize)
178    int m_thumbSize,
179        m_thumbPos,
180        m_thumbPosOld;
181
182    // the page size, i.e. the number of lines by which to scroll when page
183    // up/down action is performed
184    int m_pageSize;
185
186    // the state of the sub elements
187    int m_elementsState[Element_Max];
188
189    // the dirty flag: if set, scrollbar must be updated
190    bool m_dirty;
191
192    // the object handling the arrows
193    wxScrollArrows m_arrows;
194
195    friend WXDLLEXPORT class wxControlRenderer; // for geometry methods
196    friend class wxStdScrollBarInputHandler; // for geometry methods
197
198    DECLARE_EVENT_TABLE()
199    DECLARE_DYNAMIC_CLASS(wxScrollBar)
200};
201
202// ----------------------------------------------------------------------------
203// Standard scrollbar input handler which can be used as a base class
204// ----------------------------------------------------------------------------
205
206class WXDLLEXPORT wxStdScrollBarInputHandler : public wxStdInputHandler
207{
208public:
209    // constructor takes a renderer (used for scrollbar hit testing) and the
210    // base handler to which all unhandled events are forwarded
211    wxStdScrollBarInputHandler(wxRenderer *renderer,
212                               wxInputHandler *inphand);
213
214    virtual bool HandleKey(wxInputConsumer *consumer,
215                           const wxKeyEvent& event,
216                           bool pressed);
217    virtual bool HandleMouse(wxInputConsumer *consumer,
218                             const wxMouseEvent& event);
219    virtual bool HandleMouseMove(wxInputConsumer *consumer, const wxMouseEvent& event);
220
221    virtual ~wxStdScrollBarInputHandler();
222
223    // this method is called by wxScrollBarTimer only and may be overridden
224    //
225    // return true to continue scrolling, false to stop the timer
226    virtual bool OnScrollTimer(wxScrollBar *scrollbar,
227                               const wxControlAction& action);
228
229protected:
230    // return true if the mouse button can be used to activate scrollbar, false
231    // if not (any button under GTK+ unlike left button only which is default)
232    virtual bool IsAllowedButton(int button) const
233        { return button == wxMOUSE_BTN_LEFT; }
234
235    // set or clear the specified flag on the scrollbar element corresponding
236    // to m_htLast
237    void SetElementState(wxScrollBar *scrollbar, int flag, bool doIt);
238
239    // [un]highlight the scrollbar element corresponding to m_htLast
240    virtual void Highlight(wxScrollBar *scrollbar, bool doIt)
241        { SetElementState(scrollbar, wxCONTROL_CURRENT, doIt); }
242
243    // [un]press the scrollbar element corresponding to m_htLast
244    virtual void Press(wxScrollBar *scrollbar, bool doIt)
245        { SetElementState(scrollbar, wxCONTROL_PRESSED, doIt); }
246
247    // stop scrolling because we reached the end point
248    void StopScrolling(wxScrollBar *scrollbar);
249
250    // get the mouse coordinates in the scrollbar direction from the event
251    wxCoord GetMouseCoord(const wxScrollBar *scrollbar,
252                          const wxMouseEvent& event) const;
253
254    // generate a "thumb move" action for this mouse event
255    void HandleThumbMove(wxScrollBar *scrollbar, const wxMouseEvent& event);
256
257
258    // the window (scrollbar) which has capture or NULL and the flag telling if
259    // the mouse is inside the element which captured it or not
260    wxWindow *m_winCapture;
261    bool      m_winHasMouse;
262    int       m_btnCapture;  // the mouse button which has captured mouse
263
264    // the position where we started scrolling by page
265    wxPoint m_ptStartScrolling;
266
267    // one of wxHT_SCROLLBAR_XXX value: where has the mouse been last time?
268    wxHitTest m_htLast;
269
270    // the renderer (we use it only for hit testing)
271    wxRenderer *m_renderer;
272
273    // the offset of the top/left of the scrollbar relative to the mouse to
274    // keep during the thumb drag
275    int m_ofsMouse;
276
277    // the timer for generating scroll events when the mouse stays pressed on
278    // a scrollbar
279    wxScrollTimer *m_timerScroll;
280};
281
282#endif // _WX_UNIV_SCROLBAR_H_
283
284