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
17class WXDLLIMPEXP_FWD_CORE wxScrollHelperEvtHandler;
18class 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
51class WXDLLEXPORT wxScrollHelper
52{
53public:
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
93    void SetScale(double xs, double ys) { m_scaleX = xs; m_scaleY = ys; }
94    double GetScaleX() const { return m_scaleX; }
95    double GetScaleY() const { return m_scaleY; }
96
97    // translate between scrolled and unscrolled coordinates
98    void CalcScrolledPosition(int x, int y, int *xx, int *yy) const
99        {  DoCalcScrolledPosition(x, y, xx, yy); }
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
107    void CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
108        {  DoCalcUnscrolledPosition(x, y, xx, yy); }
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
132    void SetTargetRect(const wxRect& rect) { m_rectToScroll = rect; }
133    wxRect GetTargetRect() const { return m_rectToScroll; }
134
135    // Override this function to draw the graphic (or just process EVT_PAINT)
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?
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!
172    void OnScroll(wxScrollWinEvent& event) { HandleOnScroll(event); }
173
174protected:
175    // get pointer to our scroll rect if we use it or NULL
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
182    wxSize GetTargetSize() const
183    {
184        return m_rectToScroll.width != 0 ? m_rectToScroll.GetSize()
185                                         : m_targetWindow->GetClientSize();
186    }
187
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()                                         \
246public:                                                                       \
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(); }                                \
253protected:                                                                    \
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
270class WXDLLEXPORT wxScrolledWindow : public wxPanel,
271                                     public wxScrollHelperNative
272{
273public:
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)
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
303protected:
304    // this is needed for wxEVT_PAINT processing hack described in
305    // wxScrollHelperEvtHandler::ProcessEvent()
306    void OnPaint(wxPaintEvent& event);
307
308private:
309    DECLARE_DYNAMIC_CLASS_NO_COPY(wxScrolledWindow)
310    DECLARE_EVENT_TABLE()
311};
312
313#endif // _WX_SCROLWIN_H_BASE_
314
315