1 /////////////////////////////////////////////////////////////////////////////
2 // Name: include/wx/scrolwin.h
3 // Purpose: wxScrolledWindow, wxScrolledControl and wxScrollHelper
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #ifndef _WX_SCROLWIN_H_BASE_
13 #define _WX_SCROLWIN_H_BASE_
17 class WXDLLIMPEXP_FWD_CORE wxScrollHelperEvtHandler
;
18 class WXDLLIMPEXP_FWD_BASE wxTimer
;
20 // default scrolled window style: scroll in both directions
21 #define wxScrolledWindowStyle (wxHSCROLL | wxVSCROLL)
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.
36 // wxWindow wxScrollHelperNative
40 // | wxScrolledWindow /
49 // ----------------------------------------------------------------------------
51 class WXDLLIMPEXP_CORE wxScrollHelper
54 // ctor must be given the associated window
55 wxScrollHelper(wxWindow
*winToScroll
);
56 virtual ~wxScrollHelper();
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 );
64 // scroll to the given (in logical coords) position
65 void Scroll(int x
, int y
) { DoScroll(x
, y
); }
66 void Scroll(const wxPoint
& pt
) { DoScroll(pt
.x
, pt
.y
); }
68 // get/set the page size for this orientation (wxVERTICAL/wxHORIZONTAL)
69 int GetScrollPageSize(int orient
) const;
70 void SetScrollPageSize(int orient
, int pageSize
);
72 // get the number of lines the window can scroll,
73 // returns 0 if no scrollbars are there.
74 int GetScrollLines( int orient
) const;
76 // Set the x, y scrolling increments.
77 void SetScrollRate( int xstep
, int ystep
);
79 // get the size of one logical unit in physical ones
80 virtual void GetScrollPixelsPerUnit(int *pixelsPerUnitX
,
81 int *pixelsPerUnitY
) const;
83 // Enable/disable Windows scrolling in either direction. If true, wxWidgets
84 // scrolls the canvas and only a bit of the canvas is invalidated; no
85 // Clear() is necessary. If false, the whole canvas is invalidated and a
86 // Clear() is necessary. Disable for when the scroll increment is used to
87 // actually scroll a non-constant distance
88 virtual void EnableScrolling(bool x_scrolling
, bool y_scrolling
);
91 void GetViewStart(int *x
, int *y
) const { DoGetViewStart(x
, y
); }
93 wxPoint
GetViewStart() const
96 DoGetViewStart(&pt
.x
, &pt
.y
);
100 // Set the scale factor, used in PrepareDC
101 void SetScale(double xs
, double ys
) { m_scaleX
= xs
; m_scaleY
= ys
; }
102 double GetScaleX() const { return m_scaleX
; }
103 double GetScaleY() const { return m_scaleY
; }
105 // translate between scrolled and unscrolled coordinates
106 void CalcScrolledPosition(int x
, int y
, int *xx
, int *yy
) const
107 { DoCalcScrolledPosition(x
, y
, xx
, yy
); }
108 wxPoint
CalcScrolledPosition(const wxPoint
& pt
) const
111 DoCalcScrolledPosition(pt
.x
, pt
.y
, &p2
.x
, &p2
.y
);
115 void CalcUnscrolledPosition(int x
, int y
, int *xx
, int *yy
) const
116 { DoCalcUnscrolledPosition(x
, y
, xx
, yy
); }
117 wxPoint
CalcUnscrolledPosition(const wxPoint
& pt
) const
120 DoCalcUnscrolledPosition(pt
.x
, pt
.y
, &p2
.x
, &p2
.y
);
124 virtual void DoCalcScrolledPosition(int x
, int y
, int *xx
, int *yy
) const;
125 virtual void DoCalcUnscrolledPosition(int x
, int y
, int *xx
, int *yy
) const;
127 // Adjust the scrollbars
128 virtual void AdjustScrollbars(void);
130 // Calculate scroll increment
131 virtual int CalcScrollInc(wxScrollWinEvent
& event
);
133 // Normally the wxScrolledWindow will scroll itself, but in some rare
134 // occasions you might want it to scroll [part of] another window (e.g. a
135 // child of it in order to scroll only a portion the area between the
136 // scrollbars (spreadsheet: only cell area will move).
137 virtual void SetTargetWindow(wxWindow
*target
);
138 virtual wxWindow
*GetTargetWindow() const;
140 void SetTargetRect(const wxRect
& rect
) { m_rectToScroll
= rect
; }
141 wxRect
GetTargetRect() const { return m_rectToScroll
; }
143 // Override this function to draw the graphic (or just process EVT_PAINT)
144 virtual void OnDraw(wxDC
& WXUNUSED(dc
)) { }
146 // change the DC origin according to the scroll position.
147 virtual void DoPrepareDC(wxDC
& dc
);
149 // are we generating the autoscroll events?
150 bool IsAutoScrolling() const { return m_timerAutoScroll
!= NULL
; }
152 // stop generating the scroll events when mouse is held outside the window
153 void StopAutoScrolling();
155 // this method can be overridden in a derived class to forbid sending the
156 // auto scroll events - note that unlike StopAutoScrolling() it doesn't
157 // stop the timer, so it will be called repeatedly and will typically
158 // return different values depending on the current mouse position
160 // the base class version just returns true
161 virtual bool SendAutoScrollEvents(wxScrollWinEvent
& event
) const;
163 // the methods to be called from the window event handlers
164 void HandleOnScroll(wxScrollWinEvent
& event
);
165 void HandleOnSize(wxSizeEvent
& event
);
166 void HandleOnPaint(wxPaintEvent
& event
);
167 void HandleOnChar(wxKeyEvent
& event
);
168 void HandleOnMouseEnter(wxMouseEvent
& event
);
169 void HandleOnMouseLeave(wxMouseEvent
& event
);
171 void HandleOnMouseWheel(wxMouseEvent
& event
);
172 #endif // wxUSE_MOUSEWHEEL
173 void HandleOnChildFocus(wxChildFocusEvent
& event
);
175 // FIXME: this is needed for now for wxPlot compilation, should be removed
177 void OnScroll(wxScrollWinEvent
& event
) { HandleOnScroll(event
); }
180 // get pointer to our scroll rect if we use it or NULL
181 const wxRect
*GetScrollRect() const
183 return m_rectToScroll
.width
!= 0 ?
&m_rectToScroll
: NULL
;
186 // get the size of the target window
187 wxSize
GetTargetSize() const
189 return m_rectToScroll
.width
!= 0 ? m_rectToScroll
.GetSize()
190 : m_targetWindow
->GetClientSize();
193 void GetTargetSize(int *w
, int *h
) const
195 wxSize size
= GetTargetSize();
202 // implementation of public methods with the same name
203 virtual void DoGetViewStart(int *x
, int *y
) const;
204 virtual void DoScroll(int x
, int y
);
206 // implementations of various wxWindow virtual methods which should be
207 // forwarded to us (this can be done by WX_FORWARD_TO_SCROLL_HELPER())
209 void ScrollDoSetVirtualSize(int x
, int y
);
210 wxSize
ScrollGetBestVirtualSize() const;
212 // change just the target window (unlike SetWindow which changes m_win as
214 void DoSetTargetWindow(wxWindow
*target
);
216 // delete the event handler we installed
217 void DeleteEvtHandler();
219 // calls wxScrollHelperEvtHandler::ResetDrawnFlag(), see explanation
220 // in wxScrollHelperEvtHandler::ProcessEvent()
221 void ResetDrawnFlag();
223 // helper of AdjustScrollbars(): does the work for the single scrollbar
225 // notice that the parameters passed by non-const references are modified
227 void AdjustScrollbar(int orient
,
232 int& scrollPosition
);
234 // this function should be overridden to return the size available for
235 // m_targetWindow inside m_win of the given size
237 // the default implementation is only good for m_targetWindow == m_win
238 // case, if we're scrolling a subwindow you must override this method
239 virtual wxSize
GetSizeAvailableForScrollTarget(const wxSize
& size
)
241 // returning just size from here is wrong but it was decided that it is
242 // not wrong enough to break the existing code (which doesn't override
243 // this recently added function at all) by adding this assert
245 // wxASSERT_MSG( m_targetWindow == m_win, "must be overridden" );
257 wxRect m_rectToScroll
;
259 wxTimer
*m_timerAutoScroll
;
261 int m_xScrollPixelsPerLine
;
262 int m_yScrollPixelsPerLine
;
263 int m_xScrollPosition
;
264 int m_yScrollPosition
;
267 int m_xScrollLinesPerPage
;
268 int m_yScrollLinesPerPage
;
270 bool m_xScrollingEnabled
;
271 bool m_yScrollingEnabled
;
275 #endif // wxUSE_MOUSEWHEEL
277 wxScrollHelperEvtHandler
*m_handler
;
280 DECLARE_NO_COPY_CLASS(wxScrollHelper
)
283 // this macro can be used in a wxScrollHelper-derived class to forward wxWindow
284 // methods to corresponding wxScrollHelper methods
285 #define WX_FORWARD_TO_SCROLL_HELPER() \
287 virtual void PrepareDC(wxDC& dc) { DoPrepareDC(dc); } \
288 virtual bool Layout() { return ScrollLayout(); } \
289 virtual void DoSetVirtualSize(int x, int y) \
290 { ScrollDoSetVirtualSize(x, y); } \
291 virtual wxSize GetBestVirtualSize() const \
292 { return ScrollGetBestVirtualSize(); }
294 // include the declaration of wxScrollHelperNative if needed
295 #if defined(__WXGTK20__) && !defined(__WXUNIVERSAL__)
296 #include "wx/gtk/scrolwin.h"
297 #elif defined(__WXGTK__) && !defined(__WXUNIVERSAL__)
298 #include "wx/gtk1/scrolwin.h"
300 typedef wxScrollHelper wxScrollHelperNative
;
303 // ----------------------------------------------------------------------------
304 // wxScrolled<T>: a wxWindow which knows how to scroll
305 // ----------------------------------------------------------------------------
307 // helper class for wxScrolled<T> below
308 struct WXDLLIMPEXP_CORE wxScrolledT_Helper
310 static wxSize
FilterBestSize(const wxWindow
*win
,
311 const wxScrollHelperNative
*helper
,
312 const wxSize
& origBest
);
314 static WXLRESULT
FilterMSWWindowProc(WXUINT nMsg
, WXLRESULT origResult
);
318 // Scrollable window base on window type T. This used to be wxScrolledWindow,
319 // but wxScrolledWindow includes wxControlContainer functionality and that's
320 // not always desirable.
322 class WXDLLIMPEXP_CORE wxScrolled
: public T
,
323 public wxScrollHelperNative
,
324 private wxScrolledT_Helper
327 wxScrolled() : wxScrollHelperNative(this) { }
328 wxScrolled(wxWindow
*parent
,
329 wxWindowID winid
= wxID_ANY
,
330 const wxPoint
& pos
= wxDefaultPosition
,
331 const wxSize
& size
= wxDefaultSize
,
332 long style
= wxScrolledWindowStyle
,
333 const wxString
& name
= wxPanelNameStr
)
334 : wxScrollHelperNative(this)
336 Create(parent
, winid
, pos
, size
, style
, name
);
339 bool Create(wxWindow
*parent
,
341 const wxPoint
& pos
= wxDefaultPosition
,
342 const wxSize
& size
= wxDefaultSize
,
343 long style
= wxScrolledWindowStyle
,
344 const wxString
& name
= wxPanelNameStr
)
346 m_targetWindow
= this;
349 this->MacSetClipChildren(true);
352 this->Connect(wxEVT_PAINT
, wxPaintEventHandler(wxScrolled
::OnPaint
));
354 // by default, we're scrollable in both directions (but if one of the
355 // styles is specified explicitly, we shouldn't add the other one
357 if ( !(style
& (wxHSCROLL
| wxVSCROLL
)) )
358 style
|= wxHSCROLL
| wxVSCROLL
;
360 return T
::Create(parent
, winid
, pos
, size
, style
, name
);
363 // we need to return a special WM_GETDLGCODE value to process just the
364 // arrows but let the other navigation characters through
366 virtual WXLRESULT
MSWWindowProc(WXUINT nMsg
, WXWPARAM wParam
, WXLPARAM lParam
)
368 return FilterMSWWindowProc(nMsg
, T
::MSWWindowProc(nMsg
, wParam
, lParam
));
372 WX_FORWARD_TO_SCROLL_HELPER()
375 virtual wxSize
DoGetBestSize() const
377 return FilterBestSize(this, this, T
::DoGetBestSize());
381 // this is needed for wxEVT_PAINT processing hack described in
382 // wxScrollHelperEvtHandler::ProcessEvent()
383 void OnPaint(wxPaintEvent
& event
)
385 // the user code didn't really draw the window if we got here, so set
386 // this flag to try to call OnDraw() later
391 // VC++ 6 gives warning for the declaration of template member function
392 // without definition
393 #if !defined(__VISUALC__) || wxCHECK_VISUALC_VERSION(7)
394 DECLARE_NO_COPY_CLASS(wxScrolled
)
398 // VC++ <= 6 requires this; it's unlikely any other specializations would
399 // be needed by user code _and_ they were using VC6, so we list only wxWindow
400 // (typical use) and wxPanel (wxScrolledWindow use) specializations here
401 WXDLLIMPEXP_TEMPLATE_INSTANCE_CORE( wxScrolled
<wxPanel
> )
402 WXDLLIMPEXP_TEMPLATE_INSTANCE_CORE( wxScrolled
<wxWindow
> )
404 // for compatibility with existing code, we provide wxScrolledWindow
405 // "typedef" for wxScrolled<wxPanel>. It's not a real typedef because we
406 // want wxScrolledWindow to show in wxRTTI information (the class is widely
407 // used and likelihood of its wxRTTI information being used too is high):
408 class WXDLLIMPEXP_CORE wxScrolledWindow
: public wxScrolled
<wxPanel
>
411 wxScrolledWindow() : wxScrolled
<wxPanel
>() {}
412 wxScrolledWindow(wxWindow
*parent
,
413 wxWindowID winid
= wxID_ANY
,
414 const wxPoint
& pos
= wxDefaultPosition
,
415 const wxSize
& size
= wxDefaultSize
,
416 long style
= wxScrolledWindowStyle
,
417 const wxString
& name
= wxPanelNameStr
)
418 : wxScrolled
<wxPanel
>(parent
, winid
, pos
, size
, style
, name
) {}
420 DECLARE_DYNAMIC_CLASS_NO_COPY(wxScrolledWindow
)
423 typedef wxScrolled
<wxWindow
> wxScrolledCanvas
;
425 #endif // _WX_SCROLWIN_H_BASE_