1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        include/wx/scrolwin.h
3 // Purpose:     wxScrolledWindow, wxScrolledControl and wxScrollHelper
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     30.08.00
7 // RCS-ID:      $Id: scrolwin.h 50864 2007-12-20 18:36:19Z VS $
8 // Copyright:   (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _WX_SCROLWIN_H_BASE_
13 #define _WX_SCROLWIN_H_BASE_
14 
15 #include "wx/panel.h"
16 
17 class WXDLLIMPEXP_FWD_CORE wxScrollHelperEvtHandler;
18 class WXDLLIMPEXP_FWD_CORE wxTimer;
19 
20 // default scrolled window style: scroll in both directions
21 #define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL)
22 
23 // ----------------------------------------------------------------------------
24 // The hierarchy of scrolling classes is a bit complicated because we want to
25 // put as much functionality as possible in a mix-in class not deriving from
26 // wxWindow so that other classes could derive from the same base class on all
27 // platforms irrespectively of whether they are native controls (and hence
28 // don't use our scrolling) or not.
29 //
30 // So we have
31 //
32 //                             wxScrollHelper
33 //                                   |
34 //                                   |
35 //                                  \|/
36 //      wxWindow            wxScrollHelperNative
37 //       |  \                   /        /
38 //       |   \                 /        /
39 //       |    _|             |_        /
40 //       |     wxScrolledWindow       /
41 //       |                           /
42 //      \|/                         /
43 //   wxControl                     /
44 //         \                      /
45 //          \                    /
46 //           _|                |_
47 //            wxScrolledControl
48 //
49 // ----------------------------------------------------------------------------
50 
51 class WXDLLEXPORT wxScrollHelper
52 {
53 public:
54     // ctor must be given the associated window
55     wxScrollHelper(wxWindow *winToScroll);
56     virtual ~wxScrollHelper();
57 
58     // configure the scrolling
59     virtual void SetScrollbars(int pixelsPerUnitX, int pixelsPerUnitY,
60                                int noUnitsX, int noUnitsY,
61                                int xPos = 0, int yPos = 0,
62                                bool noRefresh = false );
63 
64     // scroll to the given (in logical coords) position
65     virtual void Scroll(int x, int y);
66 
67     // get/set the page size for this orientation (wxVERTICAL/wxHORIZONTAL)
68     int GetScrollPageSize(int orient) const;
69     void SetScrollPageSize(int orient, int pageSize);
70 
71     // get the number of lines the window can scroll,
72     // returns 0 if no scrollbars are there.
73     int GetScrollLines( int orient ) const;
74 
75     // Set the x, y scrolling increments.
76     void SetScrollRate( int xstep, int ystep );
77 
78     // get the size of one logical unit in physical ones
79     virtual void GetScrollPixelsPerUnit(int *pixelsPerUnitX,
80                                         int *pixelsPerUnitY) const;
81 
82     // Enable/disable Windows scrolling in either direction. If true, wxWidgets
83     // scrolls the canvas and only a bit of the canvas is invalidated; no
84     // Clear() is necessary. If false, the whole canvas is invalidated and a
85     // Clear() is necessary. Disable for when the scroll increment is used to
86     // actually scroll a non-constant distance
87     virtual void EnableScrolling(bool x_scrolling, bool y_scrolling);
88 
89     // Get the view start
90     virtual void GetViewStart(int *x, int *y) const;
91 
92     // Set the scale factor, used in PrepareDC
SetScale(double xs,double ys)93     void SetScale(double xs, double ys) { m_scaleX = xs; m_scaleY = ys; }
GetScaleX()94     double GetScaleX() const { return m_scaleX; }
GetScaleY()95     double GetScaleY() const { return m_scaleY; }
96 
97     // translate between scrolled and unscrolled coordinates
CalcScrolledPosition(int x,int y,int * xx,int * yy)98     void CalcScrolledPosition(int x, int y, int *xx, int *yy) const
99         {  DoCalcScrolledPosition(x, y, xx, yy); }
CalcScrolledPosition(const wxPoint & pt)100     wxPoint CalcScrolledPosition(const wxPoint& pt) const
101     {
102         wxPoint p2;
103         DoCalcScrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
104         return p2;
105     }
106 
CalcUnscrolledPosition(int x,int y,int * xx,int * yy)107     void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
108         {  DoCalcUnscrolledPosition(x, y, xx, yy); }
CalcUnscrolledPosition(const wxPoint & pt)109     wxPoint CalcUnscrolledPosition(const wxPoint& pt) const
110     {
111         wxPoint p2;
112         DoCalcUnscrolledPosition(pt.x, pt.y, &p2.x, &p2.y);
113         return p2;
114     }
115 
116     virtual void DoCalcScrolledPosition(int x, int y, int *xx, int *yy) const;
117     virtual void DoCalcUnscrolledPosition(int x, int y, int *xx, int *yy) const;
118 
119     // Adjust the scrollbars
120     virtual void AdjustScrollbars(void);
121 
122     // Calculate scroll increment
123     virtual int CalcScrollInc(wxScrollWinEvent& event);
124 
125     // Normally the wxScrolledWindow will scroll itself, but in some rare
126     // occasions you might want it to scroll [part of] another window (e.g. a
127     // child of it in order to scroll only a portion the area between the
128     // scrollbars (spreadsheet: only cell area will move).
129     virtual void SetTargetWindow(wxWindow *target);
130     virtual wxWindow *GetTargetWindow() const;
131 
SetTargetRect(const wxRect & rect)132     void SetTargetRect(const wxRect& rect) { m_rectToScroll = rect; }
GetTargetRect()133     wxRect GetTargetRect() const { return m_rectToScroll; }
134 
135     // Override this function to draw the graphic (or just process EVT_PAINT)
OnDraw(wxDC & WXUNUSED (dc))136     virtual void OnDraw(wxDC& WXUNUSED(dc)) { }
137 
138     // change the DC origin according to the scroll position.
139     virtual void DoPrepareDC(wxDC& dc);
140 
141     // are we generating the autoscroll events?
IsAutoScrolling()142     bool IsAutoScrolling() const { return m_timerAutoScroll != NULL; }
143 
144     // stop generating the scroll events when mouse is held outside the window
145     void StopAutoScrolling();
146 
147     // this method can be overridden in a derived class to forbid sending the
148     // auto scroll events - note that unlike StopAutoScrolling() it doesn't
149     // stop the timer, so it will be called repeatedly and will typically
150     // return different values depending on the current mouse position
151     //
152     // the base class version just returns true
153     virtual bool SendAutoScrollEvents(wxScrollWinEvent& event) const;
154 
155     // the methods to be called from the window event handlers
156     void HandleOnScroll(wxScrollWinEvent& event);
157     void HandleOnSize(wxSizeEvent& event);
158     void HandleOnPaint(wxPaintEvent& event);
159     void HandleOnChar(wxKeyEvent& event);
160     void HandleOnMouseEnter(wxMouseEvent& event);
161     void HandleOnMouseLeave(wxMouseEvent& event);
162 #if wxUSE_MOUSEWHEEL
163     void HandleOnMouseWheel(wxMouseEvent& event);
164 #endif // wxUSE_MOUSEWHEEL
165 
166 #if wxABI_VERSION >= 20808
167     void HandleOnChildFocus(wxChildFocusEvent& event);
168 #endif
169 
170     // FIXME: this is needed for now for wxPlot compilation, should be removed
171     //        once it is fixed!
OnScroll(wxScrollWinEvent & event)172     void OnScroll(wxScrollWinEvent& event) { HandleOnScroll(event); }
173 
174 protected:
175     // get pointer to our scroll rect if we use it or NULL
GetScrollRect()176     const wxRect *GetScrollRect() const
177     {
178         return m_rectToScroll.width != 0 ? &m_rectToScroll : NULL;
179     }
180 
181     // get the size of the target window
GetTargetSize()182     wxSize GetTargetSize() const
183     {
184         return m_rectToScroll.width != 0 ? m_rectToScroll.GetSize()
185                                          : m_targetWindow->GetClientSize();
186     }
187 
GetTargetSize(int * w,int * h)188     void GetTargetSize(int *w, int *h) const
189     {
190         wxSize size = GetTargetSize();
191         if ( w )
192             *w = size.x;
193         if ( h )
194             *h = size.y;
195     }
196 
197     // implementations of various wxWindow virtual methods which should be
198     // forwarded to us (this can be done by WX_FORWARD_TO_SCROLL_HELPER())
199     bool ScrollLayout();
200     void ScrollDoSetVirtualSize(int x, int y);
201     wxSize ScrollGetBestVirtualSize() const;
202     wxSize ScrollGetWindowSizeForVirtualSize(const wxSize& size) const;
203 
204     // change just the target window (unlike SetWindow which changes m_win as
205     // well)
206     void DoSetTargetWindow(wxWindow *target);
207 
208     // delete the event handler we installed
209     void DeleteEvtHandler();
210 
211 
212     double                m_scaleX;
213     double                m_scaleY;
214 
215     wxWindow             *m_win,
216                          *m_targetWindow;
217 
218     wxRect                m_rectToScroll;
219 
220     wxTimer              *m_timerAutoScroll;
221 
222     int                   m_xScrollPixelsPerLine;
223     int                   m_yScrollPixelsPerLine;
224     int                   m_xScrollPosition;
225     int                   m_yScrollPosition;
226     int                   m_xScrollLines;
227     int                   m_yScrollLines;
228     int                   m_xScrollLinesPerPage;
229     int                   m_yScrollLinesPerPage;
230 
231     bool                  m_xScrollingEnabled;
232     bool                  m_yScrollingEnabled;
233 
234 #if wxUSE_MOUSEWHEEL
235     int m_wheelRotation;
236 #endif // wxUSE_MOUSEWHEEL
237 
238     wxScrollHelperEvtHandler *m_handler;
239 
240     DECLARE_NO_COPY_CLASS(wxScrollHelper)
241 };
242 
243 // this macro can be used in a wxScrollHelper-derived class to forward wxWindow
244 // methods to corresponding wxScrollHelper methods
245 #define WX_FORWARD_TO_SCROLL_HELPER()                                         \
246 public:                                                                       \
247     virtual void PrepareDC(wxDC& dc) { DoPrepareDC(dc); }                     \
248     virtual bool Layout() { return ScrollLayout(); }                          \
249     virtual void DoSetVirtualSize(int x, int y)                               \
250         { ScrollDoSetVirtualSize(x, y); }                                     \
251     virtual wxSize GetBestVirtualSize() const                                 \
252         { return ScrollGetBestVirtualSize(); }                                \
253 protected:                                                                    \
254     virtual wxSize GetWindowSizeForVirtualSize(const wxSize& size) const      \
255         { return ScrollGetWindowSizeForVirtualSize(size); }
256 
257 // include the declaration of wxScrollHelperNative if needed
258 #if defined(__WXGTK20__) && !defined(__WXUNIVERSAL__)
259     #include "wx/gtk/scrolwin.h"
260 #elif defined(__WXGTK__) && !defined(__WXUNIVERSAL__)
261     #include "wx/gtk1/scrolwin.h"
262 #else
263     typedef wxScrollHelper wxScrollHelperNative;
264 #endif
265 
266 // ----------------------------------------------------------------------------
267 // wxScrolledWindow: a wxWindow which knows how to scroll
268 // ----------------------------------------------------------------------------
269 
270 class WXDLLEXPORT wxScrolledWindow : public wxPanel,
271                                      public wxScrollHelperNative
272 {
273 public:
wxScrolledWindow()274     wxScrolledWindow() : wxScrollHelperNative(this) { }
275     wxScrolledWindow(wxWindow *parent,
276                      wxWindowID winid = wxID_ANY,
277                      const wxPoint& pos = wxDefaultPosition,
278                      const wxSize& size = wxDefaultSize,
279                      long style = wxScrolledWindowStyle,
280                      const wxString& name = wxPanelNameStr)
wxScrollHelperNative(this)281         : wxScrollHelperNative(this)
282     {
283         Create(parent, winid, pos, size, style, name);
284     }
285 
286     virtual ~wxScrolledWindow();
287 
288     bool Create(wxWindow *parent,
289                 wxWindowID winid,
290                 const wxPoint& pos = wxDefaultPosition,
291                 const wxSize& size = wxDefaultSize,
292                 long style = wxScrolledWindowStyle,
293                 const wxString& name = wxPanelNameStr);
294 
295     // we need to return a special WM_GETDLGCODE value to process just the
296     // arrows but let the other navigation characters through
297 #ifdef __WXMSW__
298     virtual WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam);
299 #endif // __WXMSW__
300 
301     WX_FORWARD_TO_SCROLL_HELPER()
302 
303 protected:
304     // this is needed for wxEVT_PAINT processing hack described in
305     // wxScrollHelperEvtHandler::ProcessEvent()
306     void OnPaint(wxPaintEvent& event);
307 
308 private:
309     DECLARE_DYNAMIC_CLASS_NO_COPY(wxScrolledWindow)
310     DECLARE_EVENT_TABLE()
311 };
312 
313 #endif // _WX_SCROLWIN_H_BASE_
314 
315