| 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$ |
| 8 | // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com) |
| 9 | // Licence: wxWindows license |
| 10 | /////////////////////////////////////////////////////////////////////////////// |
| 11 | |
| 12 | #ifndef _WX_UNIV_SCROLBAR_H_ |
| 13 | #define _WX_UNIV_SCROLBAR_H_ |
| 14 | |
| 15 | #ifdef __GNUG__ |
| 16 | #pragma interface "univscrolbar.h" |
| 17 | #endif |
| 18 | |
| 19 | class WXDLLEXPORT wxScrollTimer; |
| 20 | |
| 21 | #include "wx/univ/scrarrow.h" |
| 22 | |
| 23 | // ---------------------------------------------------------------------------- |
| 24 | // the actions supported by this control |
| 25 | // ---------------------------------------------------------------------------- |
| 26 | |
| 27 | // scroll the bar |
| 28 | #define wxACTION_SCROLL_START _T("start") // to the beginning |
| 29 | #define wxACTION_SCROLL_END _T("end") // to the end |
| 30 | #define wxACTION_SCROLL_LINE_UP _T("lineup") // one line up/left |
| 31 | #define wxACTION_SCROLL_PAGE_UP _T("pageup") // one page up/left |
| 32 | #define wxACTION_SCROLL_LINE_DOWN _T("linedown") // one line down/right |
| 33 | #define wxACTION_SCROLL_PAGE_DOWN _T("pagedown") // one page down/right |
| 34 | |
| 35 | // the scrollbar thumb may be dragged |
| 36 | #define wxACTION_SCROLL_THUMB_DRAG _T("thumbdrag") |
| 37 | #define wxACTION_SCROLL_THUMB_MOVE _T("thumbmove") |
| 38 | #define wxACTION_SCROLL_THUMB_RELEASE _T("thumbrelease") |
| 39 | |
| 40 | // ---------------------------------------------------------------------------- |
| 41 | // wxScrollBar |
| 42 | // ---------------------------------------------------------------------------- |
| 43 | |
| 44 | class WXDLLEXPORT wxScrollBar : public wxScrollBarBase, |
| 45 | public wxControlWithArrows |
| 46 | { |
| 47 | public: |
| 48 | // scrollbar elements: they correspond to wxHT_SCROLLBAR_XXX constants but |
| 49 | // start from 0 which allows to use them as array indices |
| 50 | enum Element |
| 51 | { |
| 52 | Element_Arrow_Line_1, |
| 53 | Element_Arrow_Line_2, |
| 54 | Element_Arrow_Page_1, |
| 55 | Element_Arrow_Page_2, |
| 56 | Element_Thumb, |
| 57 | Element_Bar_1, |
| 58 | Element_Bar_2, |
| 59 | Element_Max |
| 60 | }; |
| 61 | |
| 62 | wxScrollBar(); |
| 63 | wxScrollBar(wxWindow *parent, |
| 64 | wxWindowID id, |
| 65 | const wxPoint& pos = wxDefaultPosition, |
| 66 | const wxSize& size = wxDefaultSize, |
| 67 | long style = wxSB_HORIZONTAL, |
| 68 | const wxValidator& validator = wxDefaultValidator, |
| 69 | const wxString& name = wxScrollBarNameStr); |
| 70 | |
| 71 | bool Create(wxWindow *parent, |
| 72 | wxWindowID id, |
| 73 | const wxPoint& pos = wxDefaultPosition, |
| 74 | const wxSize& size = wxDefaultSize, |
| 75 | long style = wxSB_HORIZONTAL, |
| 76 | const wxValidator& validator = wxDefaultValidator, |
| 77 | const wxString& name = wxScrollBarNameStr); |
| 78 | |
| 79 | virtual ~wxScrollBar(); |
| 80 | |
| 81 | // implement base class pure virtuals |
| 82 | virtual int GetThumbPosition() const; |
| 83 | virtual int GetThumbSize() const; |
| 84 | virtual int GetPageSize() const; |
| 85 | virtual int GetRange() const; |
| 86 | |
| 87 | virtual void SetThumbPosition(int thumbPos); |
| 88 | virtual void SetScrollbar(int position, int thumbSize, |
| 89 | int range, int pageSize, |
| 90 | bool refresh = TRUE); |
| 91 | |
| 92 | // wxScrollBar actions |
| 93 | void ScrollToStart(); |
| 94 | void ScrollToEnd(); |
| 95 | bool ScrollLines(int nLines); |
| 96 | bool ScrollPages(int nPages); |
| 97 | |
| 98 | virtual bool PerformAction(const wxControlAction& action, |
| 99 | long numArg = 0, |
| 100 | const wxString& strArg = wxEmptyString); |
| 101 | |
| 102 | // wxScrollBar sub elements state (combination of wxCONTROL_XXX) |
| 103 | void SetState(Element which, int flags); |
| 104 | int GetState(Element which) const; |
| 105 | |
| 106 | // implement wxControlWithArrows methods |
| 107 | virtual wxRenderer *GetRenderer() const { return m_renderer; } |
| 108 | virtual wxWindow *GetWindow() { return this; } |
| 109 | virtual bool IsVertical() const { return wxScrollBarBase::IsVertical(); } |
| 110 | virtual int GetArrowState(wxScrollArrows::Arrow arrow) const; |
| 111 | virtual void SetArrowFlag(wxScrollArrows::Arrow arrow, int flag, bool set); |
| 112 | virtual bool OnArrow(wxScrollArrows::Arrow arrow); |
| 113 | virtual wxScrollArrows::Arrow HitTest(const wxPoint& pt) const; |
| 114 | |
| 115 | // for wxControlRenderer::DrawScrollbar() only |
| 116 | const wxScrollArrows& GetArrows() const { return m_arrows; } |
| 117 | |
| 118 | protected: |
| 119 | virtual wxSize DoGetBestClientSize() const; |
| 120 | virtual void DoDraw(wxControlRenderer *renderer); |
| 121 | virtual wxBorder GetDefaultBorder() const { return wxBORDER_NONE; } |
| 122 | |
| 123 | // event handlers |
| 124 | void OnIdle(wxIdleEvent& event); |
| 125 | |
| 126 | // SetThumbPosition() helper |
| 127 | void DoSetThumb(int thumbPos); |
| 128 | |
| 129 | // common part of all ctors |
| 130 | void Init(); |
| 131 | |
| 132 | private: |
| 133 | // total range of the scrollbar in logical units |
| 134 | int m_range; |
| 135 | |
| 136 | // the current and previous (after last refresh - this is used for |
| 137 | // repainting optimisation) size of the thumb in logical units (from 0 to |
| 138 | // m_range) and its position (from 0 to m_range - m_thumbSize) |
| 139 | int m_thumbSize, |
| 140 | m_thumbPos, |
| 141 | m_thumbPosOld; |
| 142 | |
| 143 | // the page size, i.e. the number of lines by which to scroll when page |
| 144 | // up/down action is performed |
| 145 | int m_pageSize; |
| 146 | |
| 147 | // the state of the sub elements |
| 148 | int m_elementsState[Element_Max]; |
| 149 | |
| 150 | // the dirty flag: if set, scrollbar must be updated |
| 151 | bool m_dirty; |
| 152 | |
| 153 | // the object handling the arrows |
| 154 | wxScrollArrows m_arrows; |
| 155 | |
| 156 | DECLARE_EVENT_TABLE() |
| 157 | DECLARE_DYNAMIC_CLASS(wxScrollBar) |
| 158 | }; |
| 159 | |
| 160 | // ---------------------------------------------------------------------------- |
| 161 | // common scrollbar input handler: it manages clicks on the standard scrollbar |
| 162 | // elements (line arrows, bar, thumb) |
| 163 | // ---------------------------------------------------------------------------- |
| 164 | |
| 165 | class WXDLLEXPORT wxStdScrollBarInputHandler : public wxStdInputHandler |
| 166 | { |
| 167 | public: |
| 168 | // constructor takes a renderer (used for scrollbar hit testing) and the |
| 169 | // base handler to which all unhandled events are forwarded |
| 170 | wxStdScrollBarInputHandler(wxRenderer *renderer, |
| 171 | wxInputHandler *inphand); |
| 172 | |
| 173 | virtual bool HandleKey(wxInputConsumer *consumer, |
| 174 | const wxKeyEvent& event, |
| 175 | bool pressed); |
| 176 | virtual bool HandleMouse(wxInputConsumer *consumer, |
| 177 | const wxMouseEvent& event); |
| 178 | virtual bool HandleMouseMove(wxInputConsumer *consumer, const wxMouseEvent& event); |
| 179 | |
| 180 | virtual ~wxStdScrollBarInputHandler(); |
| 181 | |
| 182 | // this method is called by wxScrollBarTimer only and may be overridden |
| 183 | // |
| 184 | // return TRUE to continue scrolling, FALSE to stop the timer |
| 185 | virtual bool OnScrollTimer(wxScrollBar *scrollbar, |
| 186 | const wxControlAction& action); |
| 187 | |
| 188 | protected: |
| 189 | // the methods which must be overridden in the derived class |
| 190 | |
| 191 | // return TRUE if the mouse button can be used to activate scrollbar, FALSE |
| 192 | // if not (only left mouse button can do it under Windows, any button under |
| 193 | // GTK+) |
| 194 | virtual bool IsAllowedButton(int button) = 0; |
| 195 | |
| 196 | // set or clear the specified flag on the scrollbar element corresponding |
| 197 | // to m_htLast |
| 198 | void SetElementState(wxScrollBar *scrollbar, int flag, bool doIt); |
| 199 | |
| 200 | // [un]highlight the scrollbar element corresponding to m_htLast |
| 201 | virtual void Highlight(wxScrollBar *scrollbar, bool doIt) |
| 202 | { SetElementState(scrollbar, wxCONTROL_CURRENT, doIt); } |
| 203 | |
| 204 | // [un]press the scrollbar element corresponding to m_htLast |
| 205 | virtual void Press(wxScrollBar *scrollbar, bool doIt) |
| 206 | { SetElementState(scrollbar, wxCONTROL_PRESSED, doIt); } |
| 207 | |
| 208 | // stop scrolling because we reached the end point |
| 209 | void StopScrolling(wxScrollBar *scrollbar); |
| 210 | |
| 211 | // get the mouse coordinates in the scrollbar direction from the event |
| 212 | wxCoord GetMouseCoord(const wxScrollBar *scrollbar, |
| 213 | const wxMouseEvent& event) const; |
| 214 | |
| 215 | // generate a "thumb move" action for this mouse event |
| 216 | void HandleThumbMove(wxScrollBar *scrollbar, const wxMouseEvent& event); |
| 217 | |
| 218 | // the window (scrollbar) which has capture or NULL and the flag telling if |
| 219 | // the mouse is inside the element which captured it or not |
| 220 | wxWindow *m_winCapture; |
| 221 | bool m_winHasMouse; |
| 222 | int m_btnCapture; // the mouse button which has captured mouse |
| 223 | |
| 224 | // the position where we started scrolling by page |
| 225 | wxPoint m_ptStartScrolling; |
| 226 | |
| 227 | // one of wxHT_SCROLLBAR_XXX value: where has the mouse been last time? |
| 228 | wxHitTest m_htLast; |
| 229 | |
| 230 | // the renderer (we use it only for hit testing) |
| 231 | wxRenderer *m_renderer; |
| 232 | |
| 233 | // the offset of the top/left of the scrollbar relative to the mouse to |
| 234 | // keep during the thumb drag |
| 235 | int m_ofsMouse; |
| 236 | |
| 237 | // the timer for generating scroll events when the mouse stays pressed on |
| 238 | // a scrollbar |
| 239 | wxScrollTimer *m_timerScroll; |
| 240 | }; |
| 241 | |
| 242 | #endif // _WX_UNIV_SCROLBAR_H_ |
| 243 | |