]> git.saurik.com Git - wxWidgets.git/blame - src/generic/scrlwing.cpp
Integrated fixes from latest UNIX version.
[wxWidgets.git] / src / generic / scrlwing.cpp
CommitLineData
c801d85f 1/////////////////////////////////////////////////////////////////////////////
d80cd92a 2// Name: generic/scrolwin.cpp
fa3541bd 3// Purpose: wxGenericScrolledWindow implementation
c801d85f 4// Author: Julian Smart
566d84a7
RL
5// Modified by: Vadim Zeitlin on 31.08.00: wxScrollHelper allows to implement.
6// Ron Lee on 10.4.02: virtual size / auto scrollbars et al.
c801d85f
KB
7// Created: 01/02/97
8// RCS-ID: $Id$
1e6feb95 9// Copyright: (c) wxWindows team
a58a12e9 10// Licence: wxWindows license
c801d85f
KB
11/////////////////////////////////////////////////////////////////////////////
12
d80cd92a
VZ
13// ============================================================================
14// declarations
15// ============================================================================
16
17// ----------------------------------------------------------------------------
18// headers
19// ----------------------------------------------------------------------------
20
c801d85f 21#ifdef __GNUG__
3a8c693a 22 #pragma implementation "genscrolwin.h"
c801d85f
KB
23#endif
24
bcd055ae
JJ
25#ifdef __VMS
26#define XtDisplay XTDISPLAY
27#endif
28
c801d85f
KB
29// For compilers that support precompilation, includes "wx.h".
30#include "wx/wxprec.h"
31
c801d85f 32#ifdef __BORLANDC__
d80cd92a 33 #pragma hdrstop
c801d85f
KB
34#endif
35
3a8c693a
VZ
36#if !defined(__WXGTK__) || defined(__WXUNIVERSAL__)
37
d80cd92a
VZ
38#include "wx/utils.h"
39#include "wx/dcclient.h"
40
1e6feb95 41#include "wx/scrolwin.h"
053f9cc1 42#include "wx/panel.h"
1e6feb95 43#include "wx/timer.h"
95d60b24 44#include "wx/sizer.h"
c801d85f 45
48d1144b 46#ifdef __WXMSW__
1e6feb95 47 #include <windows.h> // for DLGC_WANTARROWS
48d1144b
JS
48#endif
49
a91b47e8
JS
50#ifdef __WXMOTIF__
51// For wxRETAINED implementation
338dd992
JJ
52#ifdef __VMS__ //VMS's Xm.h is not (yet) compatible with C++
53 //This code switches off the compiler warnings
54# pragma message disable nosimpint
55#endif
a91b47e8 56#include <Xm/Xm.h>
338dd992
JJ
57#ifdef __VMS__
58# pragma message enable nosimpint
59#endif
a91b47e8
JS
60#endif
61
fa3541bd 62IMPLEMENT_CLASS(wxScrolledWindow, wxGenericScrolledWindow)
fa3541bd 63
d80cd92a 64// ----------------------------------------------------------------------------
1e6feb95
VZ
65// wxScrollHelperEvtHandler: intercept the events from the window and forward
66// them to wxScrollHelper
d80cd92a
VZ
67// ----------------------------------------------------------------------------
68
349efbaa 69class WXDLLEXPORT wxScrollHelperEvtHandler : public wxEvtHandler
1e6feb95
VZ
70{
71public:
72 wxScrollHelperEvtHandler(wxScrollHelper *scrollHelper)
73 {
74 m_scrollHelper = scrollHelper;
75 }
d80cd92a 76
1e6feb95
VZ
77 virtual bool ProcessEvent(wxEvent& event);
78
349efbaa
VZ
79 void ResetDrawnFlag() { m_hasDrawnWindow = FALSE; }
80
1e6feb95
VZ
81private:
82 wxScrollHelper *m_scrollHelper;
349efbaa
VZ
83
84 bool m_hasDrawnWindow;
1e6feb95
VZ
85};
86
87// ----------------------------------------------------------------------------
88// wxAutoScrollTimer: the timer used to generate a stream of scroll events when
89// a captured mouse is held outside the window
90// ----------------------------------------------------------------------------
91
92class wxAutoScrollTimer : public wxTimer
93{
94public:
95 wxAutoScrollTimer(wxWindow *winToScroll, wxScrollHelper *scroll,
96 wxEventType eventTypeToSend,
97 int pos, int orient);
98
99 virtual void Notify();
100
101private:
102 wxWindow *m_win;
103 wxScrollHelper *m_scrollHelper;
104 wxEventType m_eventType;
105 int m_pos,
106 m_orient;
107};
d80cd92a
VZ
108
109// ============================================================================
110// implementation
111// ============================================================================
112
113// ----------------------------------------------------------------------------
1e6feb95 114// wxAutoScrollTimer
d80cd92a
VZ
115// ----------------------------------------------------------------------------
116
1e6feb95
VZ
117wxAutoScrollTimer::wxAutoScrollTimer(wxWindow *winToScroll,
118 wxScrollHelper *scroll,
119 wxEventType eventTypeToSend,
120 int pos, int orient)
c801d85f 121{
1e6feb95
VZ
122 m_win = winToScroll;
123 m_scrollHelper = scroll;
124 m_eventType = eventTypeToSend;
125 m_pos = pos;
126 m_orient = orient;
c801d85f
KB
127}
128
1e6feb95 129void wxAutoScrollTimer::Notify()
c801d85f 130{
1e6feb95
VZ
131 // only do all this as long as the window is capturing the mouse
132 if ( wxWindow::GetCapture() != m_win )
133 {
134 Stop();
135 }
136 else // we still capture the mouse, continue generating events
137 {
138 // first scroll the window if we are allowed to do it
139 wxScrollWinEvent event1(m_eventType, m_pos, m_orient);
140 event1.SetEventObject(m_win);
141 if ( m_scrollHelper->SendAutoScrollEvents(event1) &&
142 m_win->GetEventHandler()->ProcessEvent(event1) )
143 {
144 // and then send a pseudo mouse-move event to refresh the selection
145 wxMouseEvent event2(wxEVT_MOTION);
146 wxGetMousePosition(&event2.m_x, &event2.m_y);
147
148 // the mouse event coordinates should be client, not screen as
149 // returned by wxGetMousePosition
150 wxWindow *parentTop = m_win;
151 while ( parentTop->GetParent() )
152 parentTop = parentTop->GetParent();
153 wxPoint ptOrig = parentTop->GetPosition();
154 event2.m_x -= ptOrig.x;
155 event2.m_y -= ptOrig.y;
156
157 event2.SetEventObject(m_win);
158
159 // FIXME: we don't fill in the other members - ok?
160
161 m_win->GetEventHandler()->ProcessEvent(event2);
162 }
163 else // can't scroll further, stop
164 {
165 Stop();
166 }
167 }
168}
169
170// ----------------------------------------------------------------------------
171// wxScrollHelperEvtHandler
172// ----------------------------------------------------------------------------
173
174bool wxScrollHelperEvtHandler::ProcessEvent(wxEvent& event)
175{
9a268018 176 wxEventType evType = event.GetEventType();
2feed004 177
349efbaa
VZ
178 // the explanation of wxEVT_PAINT processing hack: for historic reasons
179 // there are 2 ways to process this event in classes deriving from
180 // wxScrolledWindow. The user code may
181 //
182 // 1. override wxScrolledWindow::OnDraw(dc)
183 // 2. define its own OnPaint() handler
184 //
185 // In addition, in wxUniversal wxWindow defines OnPaint() itself and
186 // always processes the draw event, so we can't just try the window
187 // OnPaint() first and call our HandleOnPaint() if it doesn't process it
188 // (the latter would never be called in wxUniversal).
189 //
190 // So the solution is to have a flag telling us whether the user code drew
191 // anything in the window. We set it to true here but reset it to false in
192 // wxScrolledWindow::OnPaint() handler (which wouldn't be called if the
193 // user code defined OnPaint() in the derived class)
194 m_hasDrawnWindow = TRUE;
195
ff186591
VZ
196 // pass it on to the real handler
197 bool processed = wxEvtHandler::ProcessEvent(event);
198
199 // always process the size events ourselves, even if the user code handles
200 // them as well, as we need to AdjustScrollbars()
201 //
202 // NB: it is important to do it after processing the event in the normal
203 // way as HandleOnSize() may generate a wxEVT_SIZE itself if the
204 // scrollbar[s] (dis)appear and it should be seen by the user code
205 // after this one
206 if ( evType == wxEVT_SIZE )
207 {
208 m_scrollHelper->HandleOnSize((wxSizeEvent &)event);
209
210 return TRUE;
211 }
212
213 if ( processed )
349efbaa
VZ
214 {
215 // normally, nothing more to do here - except if it was a paint event
216 // which wasn't really processed, then we'll try to call our
217 // OnDraw() below (from HandleOnPaint)
993cfa87 218 if ( m_hasDrawnWindow )
349efbaa
VZ
219 {
220 return TRUE;
221 }
222 }
2feed004 223
1e6feb95
VZ
224 // reset the skipped flag to FALSE as it might have been set to TRUE in
225 // ProcessEvent() above
226 event.Skip(FALSE);
227
e421922f
VZ
228 if ( evType == wxEVT_PAINT )
229 {
230 m_scrollHelper->HandleOnPaint((wxPaintEvent &)event);
231 return TRUE;
232 }
1e6feb95 233
e421922f
VZ
234 if ( evType == wxEVT_SCROLLWIN_TOP ||
235 evType == wxEVT_SCROLLWIN_BOTTOM ||
236 evType == wxEVT_SCROLLWIN_LINEUP ||
237 evType == wxEVT_SCROLLWIN_LINEDOWN ||
238 evType == wxEVT_SCROLLWIN_PAGEUP ||
239 evType == wxEVT_SCROLLWIN_PAGEDOWN ||
240 evType == wxEVT_SCROLLWIN_THUMBTRACK ||
241 evType == wxEVT_SCROLLWIN_THUMBRELEASE )
242 {
243 m_scrollHelper->HandleOnScroll((wxScrollWinEvent &)event);
1e6feb95 244 return !event.GetSkipped();
e421922f 245 }
1e6feb95 246
e421922f
VZ
247 if ( evType == wxEVT_ENTER_WINDOW )
248 {
249 m_scrollHelper->HandleOnMouseEnter((wxMouseEvent &)event);
250 }
251 else if ( evType == wxEVT_LEAVE_WINDOW )
252 {
253 m_scrollHelper->HandleOnMouseLeave((wxMouseEvent &)event);
254 }
255#if wxUSE_MOUSEWHEEL
256 else if ( evType == wxEVT_MOUSEWHEEL )
257 {
258 m_scrollHelper->HandleOnMouseWheel((wxMouseEvent &)event);
259 }
260#endif // wxUSE_MOUSEWHEEL
e421922f
VZ
261 else if ( evType == wxEVT_CHAR )
262 {
263 m_scrollHelper->HandleOnChar((wxKeyEvent &)event);
264 return !event.GetSkipped();
1e6feb95
VZ
265 }
266
267 return FALSE;
268}
269
270// ----------------------------------------------------------------------------
271// wxScrollHelper construction
272// ----------------------------------------------------------------------------
273
274wxScrollHelper::wxScrollHelper(wxWindow *win)
275{
276 m_xScrollPixelsPerLine =
277 m_yScrollPixelsPerLine =
278 m_xScrollPosition =
279 m_yScrollPosition =
280 m_xScrollLines =
281 m_yScrollLines =
282 m_xScrollLinesPerPage =
139adb6a 283 m_yScrollLinesPerPage = 0;
1e6feb95
VZ
284
285 m_xScrollingEnabled =
286 m_yScrollingEnabled = TRUE;
287
288 m_scaleX =
139adb6a 289 m_scaleY = 1.0;
24ce4c18 290#if wxUSE_MOUSEWHEEL
d2c52078 291 m_wheelRotation = 0;
24ce4c18 292#endif
a58a12e9 293
1e6feb95
VZ
294 m_win =
295 m_targetWindow = (wxWindow *)NULL;
139adb6a 296
1e6feb95 297 m_timerAutoScroll = (wxTimer *)NULL;
d7da9756 298
349efbaa
VZ
299 m_handler = NULL;
300
1e6feb95
VZ
301 if ( win )
302 SetWindow(win);
303}
d7da9756 304
1e6feb95 305wxScrollHelper::~wxScrollHelper()
d80cd92a 306{
1e6feb95
VZ
307 StopAutoScrolling();
308
349efbaa 309 DeleteEvtHandler();
d80cd92a
VZ
310}
311
312// ----------------------------------------------------------------------------
313// setting scrolling parameters
314// ----------------------------------------------------------------------------
315
1e6feb95
VZ
316void wxScrollHelper::SetScrollbars(int pixelsPerUnitX,
317 int pixelsPerUnitY,
318 int noUnitsX,
319 int noUnitsY,
320 int xPos,
321 int yPos,
322 bool noRefresh)
c801d85f 323{
b0486e0d
SN
324 int xpos, ypos;
325
326 CalcUnscrolledPosition(xPos, yPos, &xpos, &ypos);
139adb6a
RR
327 bool do_refresh =
328 (
c801d85f 329 (noUnitsX != 0 && m_xScrollLines == 0) ||
566d84a7 330 (noUnitsX < m_xScrollLines && xpos > pixelsPerUnitX * noUnitsX) ||
b0486e0d 331
c801d85f 332 (noUnitsY != 0 && m_yScrollLines == 0) ||
566d84a7 333 (noUnitsY < m_yScrollLines && ypos > pixelsPerUnitY * noUnitsY) ||
c801d85f 334 (xPos != m_xScrollPosition) ||
b0486e0d 335 (yPos != m_yScrollPosition)
139adb6a 336 );
a58a12e9 337
139adb6a
RR
338 m_xScrollPixelsPerLine = pixelsPerUnitX;
339 m_yScrollPixelsPerLine = pixelsPerUnitY;
340 m_xScrollPosition = xPos;
341 m_yScrollPosition = yPos;
a91b47e8 342
566d84a7 343 m_targetWindow->SetVirtualSizeHints( noUnitsX * pixelsPerUnitX, noUnitsY * pixelsPerUnitY );
a58a12e9 344
dc429f89
VZ
345 AdjustScrollbars();
346
a58a12e9 347 if (do_refresh && !noRefresh)
1e6feb95 348 m_targetWindow->Refresh(TRUE, GetRect());
a58a12e9 349
7c74e7fe 350#ifdef __WXMAC__
d80cd92a 351 m_targetWindow->MacUpdateImmediately() ;
c801d85f
KB
352#endif
353}
354
d80cd92a 355// ----------------------------------------------------------------------------
af4088f1 356// [target] window handling
d80cd92a 357// ----------------------------------------------------------------------------
ecab4dba 358
349efbaa 359void wxScrollHelper::DeleteEvtHandler()
ecab4dba 360{
248d771c
VZ
361 // search for m_handler in the handler list
362 if ( m_win && m_handler )
349efbaa 363 {
74f6bbf9 364 if ( m_win->RemoveEventHandler(m_handler) )
248d771c 365 {
74f6bbf9 366 delete m_handler;
248d771c 367 }
74f6bbf9
VZ
368 //else: something is very wrong, so better [maybe] leak memory than
369 // risk a crash because of double deletion
248d771c 370
74f6bbf9 371 m_handler = NULL;
349efbaa
VZ
372 }
373}
374
375void wxScrollHelper::SetWindow(wxWindow *win)
376{
377 wxCHECK_RET( win, _T("wxScrollHelper needs a window to scroll") );
378
379 m_win = win;
380
af4088f1
VZ
381 // by default, the associated window is also the target window
382 DoSetTargetWindow(win);
349efbaa
VZ
383}
384
af4088f1 385void wxScrollHelper::DoSetTargetWindow(wxWindow *target)
349efbaa 386{
ecab4dba 387 m_targetWindow = target;
349efbaa
VZ
388
389 // install the event handler which will intercept the events we're
af4088f1
VZ
390 // interested in (but only do it for our real window, not the target window
391 // which we scroll - we don't need to hijack its events)
392 if ( m_targetWindow == m_win )
13ff9344 393 {
248d771c
VZ
394 // if we already have a handler, delete it first
395 DeleteEvtHandler();
396
13ff9344
JS
397 m_handler = new wxScrollHelperEvtHandler(this);
398 m_targetWindow->PushEventHandler(m_handler);
399 }
349efbaa
VZ
400}
401
af4088f1 402void wxScrollHelper::SetTargetWindow(wxWindow *target)
349efbaa
VZ
403{
404 wxCHECK_RET( target, wxT("target window must not be NULL") );
405
406 if ( target == m_targetWindow )
407 return;
408
af4088f1 409 DoSetTargetWindow(target);
ecab4dba
RR
410}
411
1e6feb95 412wxWindow *wxScrollHelper::GetTargetWindow() const
ecab4dba
RR
413{
414 return m_targetWindow;
415}
416
d80cd92a
VZ
417// ----------------------------------------------------------------------------
418// scrolling implementation itself
419// ----------------------------------------------------------------------------
420
1e6feb95 421void wxScrollHelper::HandleOnScroll(wxScrollWinEvent& event)
c801d85f 422{
139adb6a 423 int nScrollInc = CalcScrollInc(event);
1e6feb95 424 if ( nScrollInc == 0 )
139adb6a 425 {
1e6feb95
VZ
426 // can't scroll further
427 event.Skip();
428
429 return;
139adb6a 430 }
c801d85f 431
1e6feb95 432 int orient = event.GetOrientation();
139adb6a
RR
433 if (orient == wxHORIZONTAL)
434 {
435 m_xScrollPosition += nScrollInc;
5f3286d1 436 m_win->SetScrollPos(wxHORIZONTAL, m_xScrollPosition);
139adb6a 437 }
c801d85f 438 else
139adb6a
RR
439 {
440 m_yScrollPosition += nScrollInc;
5f3286d1 441 m_win->SetScrollPos(wxVERTICAL, m_yScrollPosition);
139adb6a 442 }
a58a12e9 443
1e6feb95
VZ
444 bool needsRefresh = FALSE;
445 int dx = 0,
446 dy = 0;
139adb6a
RR
447 if (orient == wxHORIZONTAL)
448 {
1e6feb95
VZ
449 if ( m_xScrollingEnabled )
450 {
451 dx = -m_xScrollPixelsPerLine * nScrollInc;
452 }
139adb6a 453 else
1e6feb95
VZ
454 {
455 needsRefresh = TRUE;
456 }
139adb6a 457 }
c801d85f 458 else
139adb6a 459 {
1e6feb95
VZ
460 if ( m_yScrollingEnabled )
461 {
462 dy = -m_yScrollPixelsPerLine * nScrollInc;
463 }
139adb6a 464 else
1e6feb95
VZ
465 {
466 needsRefresh = TRUE;
467 }
468 }
469
470 if ( needsRefresh )
471 {
472 m_targetWindow->Refresh(TRUE, GetRect());
473 }
474 else
475 {
476 m_targetWindow->ScrollWindow(dx, dy, GetRect());
3d2b9c20 477 }
1e6feb95 478
7c74e7fe 479#ifdef __WXMAC__
d80cd92a 480 m_targetWindow->MacUpdateImmediately() ;
7c74e7fe 481#endif
c801d85f
KB
482}
483
1e6feb95 484int wxScrollHelper::CalcScrollInc(wxScrollWinEvent& event)
c801d85f 485{
ecab4dba
RR
486 int pos = event.GetPosition();
487 int orient = event.GetOrientation();
c801d85f 488
ecab4dba 489 int nScrollInc = 0;
1a8caf94 490 if (event.GetEventType() == wxEVT_SCROLLWIN_TOP)
c801d85f 491 {
ecab4dba
RR
492 if (orient == wxHORIZONTAL)
493 nScrollInc = - m_xScrollPosition;
494 else
495 nScrollInc = - m_yScrollPosition;
1a8caf94
RR
496 } else
497 if (event.GetEventType() == wxEVT_SCROLLWIN_BOTTOM)
498 {
ecab4dba
RR
499 if (orient == wxHORIZONTAL)
500 nScrollInc = m_xScrollLines - m_xScrollPosition;
501 else
502 nScrollInc = m_yScrollLines - m_yScrollPosition;
1a8caf94
RR
503 } else
504 if (event.GetEventType() == wxEVT_SCROLLWIN_LINEUP)
505 {
ecab4dba 506 nScrollInc = -1;
1a8caf94
RR
507 } else
508 if (event.GetEventType() == wxEVT_SCROLLWIN_LINEDOWN)
509 {
ecab4dba 510 nScrollInc = 1;
1a8caf94
RR
511 } else
512 if (event.GetEventType() == wxEVT_SCROLLWIN_PAGEUP)
513 {
ecab4dba
RR
514 if (orient == wxHORIZONTAL)
515 nScrollInc = -GetScrollPageSize(wxHORIZONTAL);
516 else
517 nScrollInc = -GetScrollPageSize(wxVERTICAL);
1a8caf94
RR
518 } else
519 if (event.GetEventType() == wxEVT_SCROLLWIN_PAGEDOWN)
520 {
ecab4dba
RR
521 if (orient == wxHORIZONTAL)
522 nScrollInc = GetScrollPageSize(wxHORIZONTAL);
523 else
524 nScrollInc = GetScrollPageSize(wxVERTICAL);
1a8caf94
RR
525 } else
526 if ((event.GetEventType() == wxEVT_SCROLLWIN_THUMBTRACK) ||
527 (event.GetEventType() == wxEVT_SCROLLWIN_THUMBRELEASE))
528 {
ecab4dba
RR
529 if (orient == wxHORIZONTAL)
530 nScrollInc = pos - m_xScrollPosition;
531 else
532 nScrollInc = pos - m_yScrollPosition;
c801d85f 533 }
88150e60 534
ecab4dba
RR
535 if (orient == wxHORIZONTAL)
536 {
a58a12e9 537 if (m_xScrollPixelsPerLine > 0)
ecab4dba
RR
538 {
539 int w, h;
1e6feb95 540 GetTargetSize(&w, &h);
ecab4dba
RR
541
542 int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine;
543 int noPositions = (int) ( ((nMaxWidth - w)/(double)m_xScrollPixelsPerLine) + 0.5 );
544 if (noPositions < 0)
d80cd92a 545 noPositions = 0;
ecab4dba
RR
546
547 if ( (m_xScrollPosition + nScrollInc) < 0 )
d80cd92a 548 nScrollInc = -m_xScrollPosition; // As -ve as we can go
ecab4dba 549 else if ( (m_xScrollPosition + nScrollInc) > noPositions )
d80cd92a 550 nScrollInc = noPositions - m_xScrollPosition; // As +ve as we can go
ecab4dba
RR
551 }
552 else
1e6feb95 553 m_targetWindow->Refresh(TRUE, GetRect());
9d9355c6
VZ
554 }
555 else
ecab4dba 556 {
a58a12e9 557 if (m_yScrollPixelsPerLine > 0)
d80cd92a 558 {
ecab4dba 559 int w, h;
1e6feb95 560 GetTargetSize(&w, &h);
a58a12e9 561
ecab4dba
RR
562 int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine;
563 int noPositions = (int) ( ((nMaxHeight - h)/(double)m_yScrollPixelsPerLine) + 0.5 );
564 if (noPositions < 0)
d80cd92a 565 noPositions = 0;
a58a12e9 566
ecab4dba 567 if ( (m_yScrollPosition + nScrollInc) < 0 )
d80cd92a 568 nScrollInc = -m_yScrollPosition; // As -ve as we can go
ecab4dba 569 else if ( (m_yScrollPosition + nScrollInc) > noPositions )
d80cd92a 570 nScrollInc = noPositions - m_yScrollPosition; // As +ve as we can go
ecab4dba
RR
571 }
572 else
1e6feb95 573 m_targetWindow->Refresh(TRUE, GetRect());
9d9355c6 574 }
9d9355c6 575
ecab4dba 576 return nScrollInc;
c801d85f
KB
577}
578
579// Adjust the scrollbars - new version.
1e6feb95 580void wxScrollHelper::AdjustScrollbars()
c801d85f 581{
aeb313f3
SC
582#ifdef __WXMAC__
583 m_targetWindow->MacUpdateImmediately();
584#endif
585
566d84a7
RL
586 int w = 0, h = 0;
587 int oldw, oldh;
a58a12e9 588
27d029c7
RR
589 int oldXScroll = m_xScrollPosition;
590 int oldYScroll = m_yScrollPosition;
c801d85f 591
566d84a7
RL
592 do {
593 GetTargetSize(&w, 0);
c801d85f 594
566d84a7
RL
595 if (m_xScrollPixelsPerLine == 0)
596 {
597 m_xScrollLines = 0;
598 m_xScrollPosition = 0;
599 m_win->SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE);
600 }
601 else
602 {
603 m_xScrollLines = m_targetWindow->GetVirtualSize().GetWidth() / m_xScrollPixelsPerLine;
604
605 // Calculate page size i.e. number of scroll units you get on the
606 // current client window
607 int noPagePositions = (int) ( (w/(double)m_xScrollPixelsPerLine) + 0.5 );
608 if (noPagePositions < 1) noPagePositions = 1;
609 if ( noPagePositions > m_xScrollLines )
610 noPagePositions = m_xScrollLines;
611
612 // Correct position if greater than extent of canvas minus
613 // the visible portion of it or if below zero
614 m_xScrollPosition = wxMin( m_xScrollLines - noPagePositions, m_xScrollPosition);
615 m_xScrollPosition = wxMax( 0, m_xScrollPosition );
616
617 m_win->SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, m_xScrollLines);
618 // The amount by which we scroll when paging
619 SetScrollPageSize(wxHORIZONTAL, noPagePositions);
620 }
c801d85f 621
566d84a7 622 GetTargetSize(0, &h);
a58a12e9 623
566d84a7
RL
624 if (m_yScrollPixelsPerLine == 0)
625 {
626 m_yScrollLines = 0;
627 m_yScrollPosition = 0;
628 m_win->SetScrollbar (wxVERTICAL, 0, 0, 0, FALSE);
629 }
630 else
631 {
632 m_yScrollLines = m_targetWindow->GetVirtualSize().GetHeight() / m_yScrollPixelsPerLine;
633
634 // Calculate page size i.e. number of scroll units you get on the
635 // current client window
636 int noPagePositions = (int) ( (h/(double)m_yScrollPixelsPerLine) + 0.5 );
637 if (noPagePositions < 1) noPagePositions = 1;
638 if ( noPagePositions > m_yScrollLines )
639 noPagePositions = m_yScrollLines;
640
641 // Correct position if greater than extent of canvas minus
642 // the visible portion of it or if below zero
643 m_yScrollPosition = wxMin( m_yScrollLines - noPagePositions, m_yScrollPosition );
644 m_yScrollPosition = wxMax( 0, m_yScrollPosition );
645
646 m_win->SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, m_yScrollLines);
647 // The amount by which we scroll when paging
648 SetScrollPageSize(wxVERTICAL, noPagePositions);
649 }
c801d85f 650
566d84a7 651 // If a scrollbar (dis)appeared as a result of this, adjust them again.
139adb6a 652
566d84a7
RL
653 oldw = w;
654 oldh = h;
655
656 GetTargetSize( &w, &h );
657 } while ( w != oldw && h != oldh );
658
659#ifdef __WXMOTIF__
660 // Sorry, some Motif-specific code to implement a backing pixmap
661 // for the wxRETAINED style. Implementing a backing store can't
662 // be entirely generic because it relies on the wxWindowDC implementation
663 // to duplicate X drawing calls for the backing pixmap.
664
665 if ( m_targetWindow->GetWindowStyle() & wxRETAINED )
139adb6a 666 {
566d84a7
RL
667 Display* dpy = XtDisplay((Widget)m_targetWindow->GetMainWidget());
668
669 int totalPixelWidth = m_xScrollLines * m_xScrollPixelsPerLine;
670 int totalPixelHeight = m_yScrollLines * m_yScrollPixelsPerLine;
671 if (m_targetWindow->GetBackingPixmap() &&
672 !((m_targetWindow->GetPixmapWidth() == totalPixelWidth) &&
673 (m_targetWindow->GetPixmapHeight() == totalPixelHeight)))
674 {
675 XFreePixmap (dpy, (Pixmap) m_targetWindow->GetBackingPixmap());
676 m_targetWindow->SetBackingPixmap((WXPixmap) 0);
677 }
678
679 if (!m_targetWindow->GetBackingPixmap() &&
9b66c26a 680 (m_xScrollLines != 0) && (m_yScrollLines != 0))
566d84a7
RL
681 {
682 int depth = wxDisplayDepth();
683 m_targetWindow->SetPixmapWidth(totalPixelWidth);
684 m_targetWindow->SetPixmapHeight(totalPixelHeight);
685 m_targetWindow->SetBackingPixmap((WXPixmap) XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)),
686 m_targetWindow->GetPixmapWidth(), m_targetWindow->GetPixmapHeight(), depth));
687 }
688
139adb6a 689 }
566d84a7 690#endif // Motif
a58a12e9 691
27d029c7
RR
692 if (oldXScroll != m_xScrollPosition)
693 {
694 if (m_xScrollingEnabled)
566d84a7 695 m_targetWindow->ScrollWindow( m_xScrollPixelsPerLine * (oldXScroll - m_xScrollPosition), 0,
1e6feb95 696 GetRect() );
27d029c7 697 else
1e6feb95 698 m_targetWindow->Refresh(TRUE, GetRect());
27d029c7 699 }
a58a12e9 700
27d029c7
RR
701 if (oldYScroll != m_yScrollPosition)
702 {
703 if (m_yScrollingEnabled)
1e6feb95
VZ
704 m_targetWindow->ScrollWindow( 0, m_yScrollPixelsPerLine * (oldYScroll-m_yScrollPosition),
705 GetRect() );
27d029c7 706 else
1e6feb95 707 m_targetWindow->Refresh(TRUE, GetRect());
27d029c7 708 }
aeb313f3
SC
709
710#ifdef __WXMAC__
711 m_targetWindow->MacUpdateImmediately();
712#endif
c801d85f
KB
713}
714
1e6feb95 715void wxScrollHelper::DoPrepareDC(wxDC& dc)
c801d85f 716{
1e6feb95
VZ
717 wxPoint pt = dc.GetDeviceOrigin();
718 dc.SetDeviceOrigin( pt.x - m_xScrollPosition * m_xScrollPixelsPerLine,
719 pt.y - m_yScrollPosition * m_yScrollPixelsPerLine );
139adb6a 720 dc.SetUserScale( m_scaleX, m_scaleY );
c801d85f
KB
721}
722
566d84a7
RL
723void wxScrollHelper::SetScrollRate( int xstep, int ystep )
724{
725 int old_x = m_xScrollPixelsPerLine * m_xScrollPosition;
726 int old_y = m_yScrollPixelsPerLine * m_yScrollPosition;
727
728 m_xScrollPixelsPerLine = xstep;
729 m_yScrollPixelsPerLine = ystep;
730
731 int new_x = m_xScrollPixelsPerLine * m_xScrollPosition;
732 int new_y = m_yScrollPixelsPerLine * m_yScrollPosition;
733
734 m_win->SetScrollPos( wxHORIZONTAL, m_xScrollPosition );
735 m_win->SetScrollPos( wxVERTICAL, m_yScrollPosition );
736 m_targetWindow->ScrollWindow( old_x - new_x, old_y - new_y );
737
738 AdjustScrollbars();
739}
740
1e6feb95 741void wxScrollHelper::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
c801d85f 742{
a0bc2c1d
VZ
743 if ( x_unit )
744 *x_unit = m_xScrollPixelsPerLine;
745 if ( y_unit )
746 *y_unit = m_yScrollPixelsPerLine;
c801d85f
KB
747}
748
1e6feb95 749int wxScrollHelper::GetScrollPageSize(int orient) const
c801d85f
KB
750{
751 if ( orient == wxHORIZONTAL )
752 return m_xScrollLinesPerPage;
753 else
754 return m_yScrollLinesPerPage;
755}
756
1e6feb95 757void wxScrollHelper::SetScrollPageSize(int orient, int pageSize)
c801d85f
KB
758{
759 if ( orient == wxHORIZONTAL )
760 m_xScrollLinesPerPage = pageSize;
761 else
762 m_yScrollLinesPerPage = pageSize;
763}
764
765/*
766 * Scroll to given position (scroll position, not pixel position)
767 */
1e6feb95 768void wxScrollHelper::Scroll( int x_pos, int y_pos )
c801d85f 769{
8b089c5e
JS
770 if (!m_targetWindow)
771 return;
772
a58a12e9 773 if (((x_pos == -1) || (x_pos == m_xScrollPosition)) &&
139adb6a 774 ((y_pos == -1) || (y_pos == m_yScrollPosition))) return;
a58a12e9 775
aeb313f3
SC
776#ifdef __WXMAC__
777 m_targetWindow->MacUpdateImmediately();
778#endif
779
139adb6a 780 int w, h;
1e6feb95 781 GetTargetSize(&w, &h);
c801d85f 782
8775b357 783 if ((x_pos != -1) && (m_xScrollPixelsPerLine))
c801d85f 784 {
ed673c6a 785 int old_x = m_xScrollPosition;
139adb6a 786 m_xScrollPosition = x_pos;
a58a12e9 787
3d2b9c20
RR
788 // Calculate page size i.e. number of scroll units you get on the
789 // current client window
ecab4dba 790 int noPagePositions = (int) ( (w/(double)m_xScrollPixelsPerLine) + 0.5 );
139adb6a
RR
791 if (noPagePositions < 1) noPagePositions = 1;
792
793 // Correct position if greater than extent of canvas minus
3d2b9c20 794 // the visible portion of it or if below zero
139adb6a
RR
795 m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition );
796 m_xScrollPosition = wxMax( 0, m_xScrollPosition );
a58a12e9 797
f6bcfd97 798 if (old_x != m_xScrollPosition) {
5f3286d1 799 m_win->SetScrollPos( wxHORIZONTAL, m_xScrollPosition );
1e6feb95
VZ
800 m_targetWindow->ScrollWindow( (old_x-m_xScrollPosition)*m_xScrollPixelsPerLine, 0,
801 GetRect() );
f6bcfd97 802 }
c801d85f 803 }
8775b357 804 if ((y_pos != -1) && (m_yScrollPixelsPerLine))
c801d85f 805 {
ed673c6a 806 int old_y = m_yScrollPosition;
139adb6a 807 m_yScrollPosition = y_pos;
a58a12e9 808
3d2b9c20
RR
809 // Calculate page size i.e. number of scroll units you get on the
810 // current client window
ecab4dba 811 int noPagePositions = (int) ( (h/(double)m_yScrollPixelsPerLine) + 0.5 );
139adb6a
RR
812 if (noPagePositions < 1) noPagePositions = 1;
813
814 // Correct position if greater than extent of canvas minus
3d2b9c20 815 // the visible portion of it or if below zero
139adb6a
RR
816 m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition );
817 m_yScrollPosition = wxMax( 0, m_yScrollPosition );
d2c52078 818
f6bcfd97 819 if (old_y != m_yScrollPosition) {
5f3286d1 820 m_win->SetScrollPos( wxVERTICAL, m_yScrollPosition );
1e6feb95
VZ
821 m_targetWindow->ScrollWindow( 0, (old_y-m_yScrollPosition)*m_yScrollPixelsPerLine,
822 GetRect() );
f6bcfd97 823 }
c801d85f 824 }
a58a12e9 825
7c74e7fe 826#ifdef __WXMAC__
3d2b9c20 827 m_targetWindow->MacUpdateImmediately();
7c74e7fe 828#endif
aeb313f3 829
c801d85f
KB
830}
831
1e6feb95 832void wxScrollHelper::EnableScrolling (bool x_scroll, bool y_scroll)
c801d85f 833{
139adb6a
RR
834 m_xScrollingEnabled = x_scroll;
835 m_yScrollingEnabled = y_scroll;
c801d85f
KB
836}
837
c801d85f 838// Where the current view starts from
1e6feb95 839void wxScrollHelper::GetViewStart (int *x, int *y) const
c801d85f 840{
a0bc2c1d
VZ
841 if ( x )
842 *x = m_xScrollPosition;
843 if ( y )
844 *y = m_yScrollPosition;
c801d85f
KB
845}
846
8c2f3797 847void wxScrollHelper::DoCalcScrolledPosition(int x, int y, int *xx, int *yy) const
c801d85f 848{
a0bc2c1d
VZ
849 if ( xx )
850 *xx = x - m_xScrollPosition * m_xScrollPixelsPerLine;
851 if ( yy )
852 *yy = y - m_yScrollPosition * m_yScrollPixelsPerLine;
c801d85f
KB
853}
854
8c2f3797 855void wxScrollHelper::DoCalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
c801d85f 856{
a0bc2c1d
VZ
857 if ( xx )
858 *xx = x + m_xScrollPosition * m_xScrollPixelsPerLine;
859 if ( yy )
860 *yy = y + m_yScrollPosition * m_yScrollPixelsPerLine;
c801d85f 861}
d80cd92a
VZ
862
863// ----------------------------------------------------------------------------
864// event handlers
865// ----------------------------------------------------------------------------
866
867// Default OnSize resets scrollbars, if any
1e6feb95 868void wxScrollHelper::HandleOnSize(wxSizeEvent& WXUNUSED(event))
d80cd92a 869{
dc429f89 870 if ( m_targetWindow != m_win )
566d84a7
RL
871 m_targetWindow->SetVirtualSize( m_targetWindow->GetClientSize() );
872
873 m_win->SetVirtualSize( m_win->GetClientSize() );
874
dc429f89
VZ
875 AdjustScrollbars();
876
566d84a7
RL
877#if wxUSE_CONSTRAINTS
878 if (m_win->GetAutoLayout())
879 m_win->Layout();
880#endif
d80cd92a
VZ
881}
882
883// This calls OnDraw, having adjusted the origin according to the current
884// scroll position
1e6feb95 885void wxScrollHelper::HandleOnPaint(wxPaintEvent& WXUNUSED(event))
d80cd92a 886{
af4088f1
VZ
887 // don't use m_targetWindow here, this is always called for ourselves
888 wxPaintDC dc(m_win);
1e6feb95 889 DoPrepareDC(dc);
d80cd92a
VZ
890
891 OnDraw(dc);
892}
893
438e3558
VZ
894// kbd handling: notice that we use OnChar() and not OnKeyDown() for
895// compatibility here - if we used OnKeyDown(), the programs which process
896// arrows themselves in their OnChar() would never get the message and like
897// this they always have the priority
1e6feb95 898void wxScrollHelper::HandleOnChar(wxKeyEvent& event)
d80cd92a
VZ
899{
900 int stx, sty, // view origin
901 szx, szy, // view size (total)
902 clix, cliy; // view size (on screen)
903
1e6feb95
VZ
904 GetViewStart(&stx, &sty);
905 GetTargetSize(&clix, &cliy);
566d84a7 906 m_targetWindow->GetVirtualSize(&szx, &szy);
56dade3c
RL
907
908 if( m_xScrollPixelsPerLine )
909 {
910 clix /= m_xScrollPixelsPerLine;
d7da9756 911 szx /= m_xScrollPixelsPerLine;
56dade3c
RL
912 }
913 else
914 {
915 clix = 0;
d7da9756 916 szx = -1;
56dade3c
RL
917 }
918 if( m_yScrollPixelsPerLine )
919 {
920 cliy /= m_yScrollPixelsPerLine;
921 szy /= m_yScrollPixelsPerLine;
922 }
923 else
924 {
925 cliy = 0;
d7da9756 926 szy = -1;
56dade3c 927 }
d80cd92a 928
39c869a6
VZ
929 int xScrollOld = m_xScrollPosition,
930 yScrollOld = m_yScrollPosition;
931
ecb01792 932 int dsty;
d80cd92a
VZ
933 switch ( event.KeyCode() )
934 {
935 case WXK_PAGEUP:
936 case WXK_PRIOR:
ecb01792
RL
937 dsty = sty - (5 * cliy / 6);
938 Scroll(-1, (dsty == -1) ? 0 : dsty);
d80cd92a
VZ
939 break;
940
941 case WXK_PAGEDOWN:
942 case WXK_NEXT:
943 Scroll(-1, sty + (5 * cliy / 6));
944 break;
945
d80cd92a
VZ
946 case WXK_HOME:
947 Scroll(0, event.ControlDown() ? 0 : -1);
948 break;
949
950 case WXK_END:
4acd108c 951 Scroll(szx - clix, event.ControlDown() ? szy - cliy : -1);
d80cd92a
VZ
952 break;
953
954 case WXK_UP:
955 Scroll(-1, sty - 1);
956 break;
957
958 case WXK_DOWN:
959 Scroll(-1, sty + 1);
960 break;
961
962 case WXK_LEFT:
963 Scroll(stx - 1, -1);
964 break;
965
966 case WXK_RIGHT:
967 Scroll(stx + 1, -1);
968 break;
969
970 default:
971 // not for us
972 event.Skip();
973 }
39c869a6
VZ
974
975 if ( m_xScrollPosition != xScrollOld )
976 {
977 wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBTRACK, m_xScrollPosition,
978 wxHORIZONTAL);
979 event.SetEventObject(m_win);
980 m_win->GetEventHandler()->ProcessEvent(event);
981 }
982
983 if ( m_yScrollPosition != yScrollOld )
984 {
985 wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBTRACK, m_yScrollPosition,
986 wxVERTICAL);
987 event.SetEventObject(m_win);
988 m_win->GetEventHandler()->ProcessEvent(event);
989 }
d80cd92a 990}
d2c52078 991
1e6feb95
VZ
992// ----------------------------------------------------------------------------
993// autoscroll stuff: these functions deal with sending fake scroll events when
994// a captured mouse is being held outside the window
995// ----------------------------------------------------------------------------
996
997bool wxScrollHelper::SendAutoScrollEvents(wxScrollWinEvent& event) const
998{
999 // only send the event if the window is scrollable in this direction
1000 wxWindow *win = (wxWindow *)event.GetEventObject();
1001 return win->HasScrollbar(event.GetOrientation());
1002}
1003
1004void wxScrollHelper::StopAutoScrolling()
1005{
1006 if ( m_timerAutoScroll )
1007 {
1008 delete m_timerAutoScroll;
1009 m_timerAutoScroll = (wxTimer *)NULL;
1010 }
1011}
d2c52078 1012
1e6feb95 1013void wxScrollHelper::HandleOnMouseEnter(wxMouseEvent& event)
d2c52078 1014{
1e6feb95
VZ
1015 StopAutoScrolling();
1016
1017 event.Skip();
1018}
d2c52078 1019
1e6feb95
VZ
1020void wxScrollHelper::HandleOnMouseLeave(wxMouseEvent& event)
1021{
1022 // don't prevent the usual processing of the event from taking place
1023 event.Skip();
1024
1025 // when a captured mouse leave a scrolled window we start generate
1026 // scrolling events to allow, for example, extending selection beyond the
1027 // visible area in some controls
1028 if ( wxWindow::GetCapture() == m_targetWindow )
1029 {
1030 // where is the mouse leaving?
1031 int pos, orient;
1032 wxPoint pt = event.GetPosition();
1033 if ( pt.x < 0 )
1034 {
1035 orient = wxHORIZONTAL;
1036 pos = 0;
1037 }
1038 else if ( pt.y < 0 )
1039 {
1040 orient = wxVERTICAL;
1041 pos = 0;
1042 }
1043 else // we're lower or to the right of the window
1044 {
1045 wxSize size = m_targetWindow->GetClientSize();
1046 if ( pt.x > size.x )
1047 {
1048 orient = wxHORIZONTAL;
1049 pos = m_xScrollLines;
1050 }
1051 else if ( pt.y > size.y )
1052 {
1053 orient = wxVERTICAL;
1054 pos = m_yScrollLines;
1055 }
1056 else // this should be impossible
1057 {
1058 // but seems to happen sometimes under wxMSW - maybe it's a bug
1059 // there but for now just ignore it
1060
1061 //wxFAIL_MSG( _T("can't understand where has mouse gone") );
1062
1063 return;
1064 }
1065 }
1066
1067 // only start the auto scroll timer if the window can be scrolled in
1068 // this direction
1069 if ( !m_targetWindow->HasScrollbar(orient) )
1070 return;
1071
1072 delete m_timerAutoScroll;
1073 m_timerAutoScroll = new wxAutoScrollTimer
1074 (
1075 m_targetWindow, this,
1076 pos == 0 ? wxEVT_SCROLLWIN_LINEUP
1077 : wxEVT_SCROLLWIN_LINEDOWN,
1078 pos,
1079 orient
1080 );
1081 m_timerAutoScroll->Start(50); // FIXME: make configurable
1082 }
1083}
1084
e421922f
VZ
1085#if wxUSE_MOUSEWHEEL
1086
1e6feb95
VZ
1087void wxScrollHelper::HandleOnMouseWheel(wxMouseEvent& event)
1088{
d2c52078 1089 m_wheelRotation += event.GetWheelRotation();
1e6feb95 1090 int lines = m_wheelRotation / event.GetWheelDelta();
d2c52078
RD
1091 m_wheelRotation -= lines * event.GetWheelDelta();
1092
1e6feb95
VZ
1093 if (lines != 0)
1094 {
1e6feb95 1095
b6b85bdc
JS
1096 wxScrollWinEvent newEvent;
1097
ac6f6ffc 1098 newEvent.SetPosition(0);
b6b85bdc
JS
1099 newEvent.SetOrientation(wxVERTICAL);
1100 newEvent.m_eventObject = m_win;
b6b85bdc 1101
9b9337da 1102 if (event.IsPageScroll())
4b056ef5
RD
1103 {
1104 if (lines > 0)
1105 newEvent.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
1106 else
1107 newEvent.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
1108
b6b85bdc 1109 m_win->GetEventHandler()->ProcessEvent(newEvent);
4b056ef5
RD
1110 }
1111 else
1112 {
1113 lines *= event.GetLinesPerAction();
1114 if (lines > 0)
1115 newEvent.m_eventType = wxEVT_SCROLLWIN_LINEUP;
1116 else
1117 newEvent.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
b6b85bdc 1118
4b056ef5
RD
1119 int times = abs(lines);
1120 for (; times > 0; times--)
1121 m_win->GetEventHandler()->ProcessEvent(newEvent);
1122 }
d2c52078
RD
1123 }
1124}
1125
e421922f
VZ
1126#endif // wxUSE_MOUSEWHEEL
1127
1e6feb95
VZ
1128// ----------------------------------------------------------------------------
1129// wxGenericScrolledWindow implementation
1130// ----------------------------------------------------------------------------
1131
1132IMPLEMENT_DYNAMIC_CLASS(wxGenericScrolledWindow, wxPanel)
1133
349efbaa
VZ
1134BEGIN_EVENT_TABLE(wxGenericScrolledWindow, wxPanel)
1135 EVT_PAINT(wxGenericScrolledWindow::OnPaint)
1136END_EVENT_TABLE()
1137
1e6feb95
VZ
1138bool wxGenericScrolledWindow::Create(wxWindow *parent,
1139 wxWindowID id,
1140 const wxPoint& pos,
1141 const wxSize& size,
1142 long style,
1143 const wxString& name)
1144{
1145 m_targetWindow = this;
1146
1147 bool ok = wxPanel::Create(parent, id, pos, size, style, name);
1148
1e6feb95
VZ
1149 return ok;
1150}
1151
1152wxGenericScrolledWindow::~wxGenericScrolledWindow()
1153{
1154}
d2c52078 1155
30486297
RD
1156bool wxGenericScrolledWindow::Layout()
1157{
566d84a7 1158 if (GetSizer() && m_targetWindow == this)
30486297 1159 {
566d84a7
RL
1160 // If we're the scroll target, take into account the
1161 // virtual size and scrolled position of the window.
1162
30486297
RD
1163 int x, y, w, h;
1164 CalcScrolledPosition(0,0, &x,&y);
1165 GetVirtualSize(&w, &h);
1166 GetSizer()->SetDimension(x, y, w, h);
1167 return TRUE;
1168 }
7152f0c6
VZ
1169
1170 // fall back to default for LayoutConstraints
1171 return wxPanel::Layout();
30486297
RD
1172}
1173
349efbaa
VZ
1174void wxGenericScrolledWindow::OnPaint(wxPaintEvent& event)
1175{
1176 // the user code didn't really draw the window if we got here, so set this
1177 // flag to try to call OnDraw() later
1178 m_handler->ResetDrawnFlag();
1179
1180 event.Skip();
1181}
1182
0cf5b099
VZ
1183#ifdef __WXMSW__
1184long
1185wxGenericScrolledWindow::MSWWindowProc(WXUINT nMsg,
1186 WXWPARAM wParam,
1187 WXLPARAM lParam)
1188{
1189 long rc = wxPanel::MSWWindowProc(nMsg, wParam, lParam);
1190
1191 // we need to process arrows ourselves for scrolling
1192 if ( nMsg == WM_GETDLGCODE )
1193 {
1194 rc |= DLGC_WANTARROWS;
1195 }
1196
1197 return rc;
1198}
1199
1200#endif // __WXMSW__
1201
1e6feb95 1202#if WXWIN_COMPATIBILITY
349efbaa 1203
1e6feb95
VZ
1204void wxGenericScrolledWindow::GetScrollUnitsPerPage (int *x_page, int *y_page) const
1205{
1206 *x_page = GetScrollPageSize(wxHORIZONTAL);
1207 *y_page = GetScrollPageSize(wxVERTICAL);
1208}
d2c52078 1209
1e6feb95
VZ
1210void wxGenericScrolledWindow::CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const
1211{
1212 if ( xx )
1213 *xx = (float)(x + m_xScrollPosition * m_xScrollPixelsPerLine);
1214 if ( yy )
1215 *yy = (float)(y + m_yScrollPosition * m_yScrollPixelsPerLine);
1216}
349efbaa 1217
1e6feb95 1218#endif // WXWIN_COMPATIBILITY
d2c52078 1219
3a8c693a
VZ
1220#endif // !wxGTK
1221
566d84a7 1222// vi:sts=4:sw=4:et