]> git.saurik.com Git - wxWidgets.git/blame - src/generic/scrolwin.cpp
added demo for bitmaps of different size
[wxWidgets.git] / src / generic / scrolwin.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: scrolwin.cpp
3// Purpose: wxScrolledWindow implementation
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart and Markus Holzem
9// Licence: wxWindows license
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation
14#pragma implementation "scrolwin.h"
15#endif
16
17// For compilers that support precompilation, includes "wx.h".
18#include "wx/wxprec.h"
19
20#include "wx/utils.h"
21#include "wx/dcclient.h"
22
c801d85f
KB
23#ifdef __BORLANDC__
24#pragma hdrstop
25#endif
26
27#include "wx/generic/scrolwin.h"
053f9cc1 28#include "wx/panel.h"
c801d85f 29
053f9cc1 30BEGIN_EVENT_TABLE(wxScrolledWindow, wxPanel)
c5b42c87 31 EVT_SCROLLWIN(wxScrolledWindow::OnScroll)
139adb6a
RR
32 EVT_SIZE(wxScrolledWindow::OnSize)
33 EVT_PAINT(wxScrolledWindow::OnPaint)
c801d85f
KB
34END_EVENT_TABLE()
35
053f9cc1 36IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxPanel)
c801d85f 37
48d1144b
JS
38#ifdef __WXMSW__
39#include "windows.h"
40#endif
41
a91b47e8
JS
42#ifdef __WXMOTIF__
43// For wxRETAINED implementation
338dd992
JJ
44#ifdef __VMS__ //VMS's Xm.h is not (yet) compatible with C++
45 //This code switches off the compiler warnings
46# pragma message disable nosimpint
47#endif
a91b47e8 48#include <Xm/Xm.h>
338dd992
JJ
49#ifdef __VMS__
50# pragma message enable nosimpint
51#endif
a91b47e8
JS
52#endif
53
c5b42c87 54wxScrolledWindow::wxScrolledWindow()
c801d85f 55{
139adb6a
RR
56 m_xScrollPixelsPerLine = 0;
57 m_yScrollPixelsPerLine = 0;
58 m_xScrollingEnabled = TRUE;
59 m_yScrollingEnabled = TRUE;
60 m_xScrollPosition = 0;
61 m_yScrollPosition = 0;
62 m_xScrollLines = 0;
63 m_yScrollLines = 0;
64 m_xScrollLinesPerPage = 0;
65 m_yScrollLinesPerPage = 0;
66 m_scaleX = 1.0;
67 m_scaleY = 1.0;
c801d85f
KB
68}
69
debe6624 70bool wxScrolledWindow::Create(wxWindow *parent, wxWindowID id,
c801d85f
KB
71 const wxPoint& pos,
72 const wxSize& size,
debe6624 73 long style,
c801d85f
KB
74 const wxString& name)
75{
139adb6a
RR
76 m_xScrollPixelsPerLine = 0;
77 m_yScrollPixelsPerLine = 0;
78 m_xScrollingEnabled = TRUE;
79 m_yScrollingEnabled = TRUE;
80 m_xScrollPosition = 0;
81 m_yScrollPosition = 0;
82 m_xScrollLines = 0;
83 m_yScrollLines = 0;
84 m_xScrollLinesPerPage = 0;
85 m_yScrollLinesPerPage = 0;
86 m_scaleX = 1.0;
87 m_scaleY = 1.0;
ecab4dba
RR
88
89 m_targetWindow = this;
139adb6a 90
053f9cc1 91 return wxPanel::Create(parent, id, pos, size, style, name);
c801d85f
KB
92}
93
94/*
95 * pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line)
96 * noUnitsX/noUnitsY: : no. units per scrollbar
97 */
debe6624
JS
98void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
99 int noUnitsX, int noUnitsY,
100 int xPos, int yPos, bool noRefresh )
c801d85f 101{
139adb6a
RR
102 bool do_refresh =
103 (
c801d85f 104 (noUnitsX != 0 && m_xScrollLines == 0) ||
ea5c6ca7 105 (noUnitsX < m_xScrollLines) ||
c801d85f 106 (noUnitsY != 0 && m_yScrollLines == 0) ||
ea5c6ca7 107 (noUnitsY < m_yScrollLines) ||
c801d85f
KB
108 (xPos != m_xScrollPosition) ||
109 (yPos != m_yScrollPosition) ||
110 (pixelsPerUnitX != m_xScrollPixelsPerLine) ||
111 (pixelsPerUnitY != m_yScrollPixelsPerLine)
139adb6a 112 );
c801d85f 113
139adb6a
RR
114 m_xScrollPixelsPerLine = pixelsPerUnitX;
115 m_yScrollPixelsPerLine = pixelsPerUnitY;
116 m_xScrollPosition = xPos;
117 m_yScrollPosition = yPos;
118 m_xScrollLines = noUnitsX;
119 m_yScrollLines = noUnitsY;
a91b47e8
JS
120
121#ifdef __WXMOTIF__
122 // Sorry, some Motif-specific code to implement a backing pixmap
123 // for the wxRETAINED style. Implementing a backing store can't
124 // be entirely generic because it relies on the wxWindowDC implementation
125 // to duplicate X drawing calls for the backing pixmap.
126
127 if ((m_windowStyle & wxRETAINED) == wxRETAINED)
128 {
129 Display* dpy = XtDisplay((Widget) GetMainWidget());
130
131 int totalPixelWidth = m_xScrollLines * m_xScrollPixelsPerLine;
132 int totalPixelHeight = m_yScrollLines * m_yScrollPixelsPerLine;
133 if (m_backingPixmap &&
134 !((m_pixmapWidth == totalPixelWidth) &&
135 (m_pixmapHeight == totalPixelHeight)))
136 {
137 XFreePixmap (dpy, (Pixmap) m_backingPixmap);
138 m_backingPixmap = (WXPixmap) 0;
139 }
140
141 if (!m_backingPixmap &&
142 (noUnitsX != 0) && (noUnitsY != 0))
143 {
144 int depth = wxDisplayDepth();
145 m_pixmapWidth = totalPixelWidth;
146 m_pixmapHeight = totalPixelHeight;
147 m_backingPixmap = (WXPixmap) XCreatePixmap (dpy, RootWindow (dpy, DefaultScreen (dpy)),
148 m_pixmapWidth, m_pixmapHeight, depth);
149 }
150
151 }
152#endif
d4c99d6f 153
139adb6a 154 AdjustScrollbars();
c801d85f 155
ea5c6ca7 156 if (do_refresh && !noRefresh)
d9c09c79 157 m_targetWindow->Refresh();
c801d85f 158
2049ba38 159#ifdef __WXMSW__
d9c09c79
GRG
160 // GRG: if this turns out to be really necessary, we could
161 // at least move it to the above if { ... } so that it is
162 // only done if noRefresh = FALSE (the default). OTOH, if
163 // this doesn't break anything, which seems to be the
164 // case, we could just leave it out.
165
60fe7303
JS
166 // Necessary?
167 // UpdateWindow ((HWND) m_targetWindow->GetHWND());
7c74e7fe
SC
168#endif
169#ifdef __WXMAC__
170 m_targetWindow->MacUpdateImmediately() ;
c801d85f
KB
171#endif
172}
173
ecab4dba
RR
174wxScrolledWindow::~wxScrolledWindow()
175{
176}
177
178void wxScrolledWindow::SetTargetWindow( wxWindow *target )
179{
180 wxASSERT_MSG( target, wxT("target window must not be NULL") );
181 m_targetWindow = target;
182}
183
184wxWindow *wxScrolledWindow::GetTargetWindow()
185{
186 return m_targetWindow;
187}
188
c5b42c87 189void wxScrolledWindow::OnScroll(wxScrollWinEvent& event)
c801d85f 190{
139adb6a 191 int orient = event.GetOrientation();
c801d85f 192
139adb6a
RR
193 int nScrollInc = CalcScrollInc(event);
194 if (nScrollInc == 0) return;
c801d85f 195
139adb6a
RR
196 if (orient == wxHORIZONTAL)
197 {
198 int newPos = m_xScrollPosition + nScrollInc;
199 SetScrollPos(wxHORIZONTAL, newPos, TRUE );
200 }
201 else
202 {
203 int newPos = m_yScrollPosition + nScrollInc;
204 SetScrollPos(wxVERTICAL, newPos, TRUE );
205 }
c801d85f 206
139adb6a
RR
207 if (orient == wxHORIZONTAL)
208 {
209 m_xScrollPosition += nScrollInc;
210 }
c801d85f 211 else
139adb6a
RR
212 {
213 m_yScrollPosition += nScrollInc;
214 }
215
216 if (orient == wxHORIZONTAL)
217 {
218 if (m_xScrollingEnabled)
ecab4dba 219 m_targetWindow->ScrollWindow(-m_xScrollPixelsPerLine * nScrollInc, 0, (const wxRect *) NULL);
139adb6a 220 else
ecab4dba 221 m_targetWindow->Refresh();
139adb6a 222 }
c801d85f 223 else
139adb6a
RR
224 {
225 if (m_yScrollingEnabled)
ecab4dba 226 m_targetWindow->ScrollWindow(0, -m_yScrollPixelsPerLine * nScrollInc, (const wxRect *) NULL);
139adb6a 227 else
ecab4dba 228 m_targetWindow->Refresh();
c801d85f 229 }
7c74e7fe
SC
230#ifdef __WXMAC__
231 m_targetWindow->MacUpdateImmediately() ;
232#endif
c801d85f
KB
233}
234
c5b42c87 235int wxScrolledWindow::CalcScrollInc(wxScrollWinEvent& event)
c801d85f 236{
ecab4dba
RR
237 int pos = event.GetPosition();
238 int orient = event.GetOrientation();
c801d85f 239
ecab4dba
RR
240 int nScrollInc = 0;
241 switch (event.GetEventType())
c801d85f 242 {
ecab4dba
RR
243 case wxEVT_SCROLLWIN_TOP:
244 {
245 if (orient == wxHORIZONTAL)
246 nScrollInc = - m_xScrollPosition;
247 else
248 nScrollInc = - m_yScrollPosition;
249 break;
250 }
251 case wxEVT_SCROLLWIN_BOTTOM:
252 {
253 if (orient == wxHORIZONTAL)
254 nScrollInc = m_xScrollLines - m_xScrollPosition;
255 else
256 nScrollInc = m_yScrollLines - m_yScrollPosition;
257 break;
258 }
259 case wxEVT_SCROLLWIN_LINEUP:
260 {
261 nScrollInc = -1;
262 break;
263 }
264 case wxEVT_SCROLLWIN_LINEDOWN:
265 {
266 nScrollInc = 1;
267 break;
268 }
269 case wxEVT_SCROLLWIN_PAGEUP:
270 {
271 if (orient == wxHORIZONTAL)
272 nScrollInc = -GetScrollPageSize(wxHORIZONTAL);
273 else
274 nScrollInc = -GetScrollPageSize(wxVERTICAL);
275 break;
276 }
277 case wxEVT_SCROLLWIN_PAGEDOWN:
278 {
279 if (orient == wxHORIZONTAL)
280 nScrollInc = GetScrollPageSize(wxHORIZONTAL);
281 else
282 nScrollInc = GetScrollPageSize(wxVERTICAL);
283 break;
284 }
285 case wxEVT_SCROLLWIN_THUMBTRACK:
286 {
287 if (orient == wxHORIZONTAL)
288 nScrollInc = pos - m_xScrollPosition;
289 else
290 nScrollInc = pos - m_yScrollPosition;
291 break;
292 }
293 default:
294 {
295 break;
296 }
c801d85f 297 }
88150e60 298
ecab4dba
RR
299 if (orient == wxHORIZONTAL)
300 {
301 if (m_xScrollPixelsPerLine > 0)
302 {
303 int w, h;
304 m_targetWindow->GetClientSize(&w, &h);
305
306 int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine;
307 int noPositions = (int) ( ((nMaxWidth - w)/(double)m_xScrollPixelsPerLine) + 0.5 );
308 if (noPositions < 0)
309 noPositions = 0;
310
311 if ( (m_xScrollPosition + nScrollInc) < 0 )
312 nScrollInc = -m_xScrollPosition; // As -ve as we can go
313 else if ( (m_xScrollPosition + nScrollInc) > noPositions )
314 nScrollInc = noPositions - m_xScrollPosition; // As +ve as we can go
315 }
316 else
317 m_targetWindow->Refresh();
9d9355c6
VZ
318 }
319 else
ecab4dba
RR
320 {
321 if (m_yScrollPixelsPerLine > 0)
322 {
323 int w, h;
324 m_targetWindow->GetClientSize(&w, &h);
9d9355c6 325
ecab4dba
RR
326 int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine;
327 int noPositions = (int) ( ((nMaxHeight - h)/(double)m_yScrollPixelsPerLine) + 0.5 );
328 if (noPositions < 0)
329 noPositions = 0;
9d9355c6 330
ecab4dba
RR
331 if ( (m_yScrollPosition + nScrollInc) < 0 )
332 nScrollInc = -m_yScrollPosition; // As -ve as we can go
333 else if ( (m_yScrollPosition + nScrollInc) > noPositions )
334 nScrollInc = noPositions - m_yScrollPosition; // As +ve as we can go
335 }
336 else
337 m_targetWindow->Refresh();
9d9355c6 338 }
9d9355c6 339
ecab4dba 340 return nScrollInc;
c801d85f
KB
341}
342
343// Adjust the scrollbars - new version.
27d029c7 344void wxScrolledWindow::AdjustScrollbars()
c801d85f 345{
139adb6a 346 int w, h;
ecab4dba 347 m_targetWindow->GetClientSize(&w, &h);
27d029c7
RR
348
349 int oldXScroll = m_xScrollPosition;
350 int oldYScroll = m_yScrollPosition;
c801d85f 351
139adb6a
RR
352 if (m_xScrollLines > 0)
353 {
cf3da716
RR
354 // Calculate page size i.e. number of scroll units you get on the
355 // current client window
ecab4dba 356 int noPagePositions = (int) ( (w/(double)m_xScrollPixelsPerLine) + 0.5 );
139adb6a 357 if (noPagePositions < 1) noPagePositions = 1;
c801d85f 358
139adb6a 359 // Correct position if greater than extent of canvas minus
cf3da716
RR
360 // the visible portion of it or if below zero
361 m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition);
139adb6a 362 m_xScrollPosition = wxMax( 0, m_xScrollPosition );
c801d85f 363
139adb6a 364 SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, m_xScrollLines);
88150e60
JS
365 // The amount by which we scroll when paging
366 SetScrollPageSize(wxHORIZONTAL, noPagePositions);
139adb6a
RR
367 }
368 else
369 {
370 m_xScrollPosition = 0;
371 SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE);
372 }
373
374 if (m_yScrollLines > 0)
375 {
cf3da716
RR
376 // Calculate page size i.e. number of scroll units you get on the
377 // current client window
ecab4dba 378 int noPagePositions = (int) ( (h/(double)m_yScrollPixelsPerLine) + 0.5 );
139adb6a 379 if (noPagePositions < 1) noPagePositions = 1;
c801d85f 380
139adb6a 381 // Correct position if greater than extent of canvas minus
cf3da716 382 // the visible portion of it or if below zero
139adb6a
RR
383 m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition );
384 m_yScrollPosition = wxMax( 0, m_yScrollPosition );
385
386 SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, m_yScrollLines);
88150e60
JS
387 // The amount by which we scroll when paging
388 SetScrollPageSize(wxVERTICAL, noPagePositions);
139adb6a
RR
389 }
390 else
391 {
392 m_yScrollPosition = 0;
393 SetScrollbar (wxVERTICAL, 0, 0, 0, FALSE);
394 }
27d029c7
RR
395
396 if (oldXScroll != m_xScrollPosition)
397 {
398 if (m_xScrollingEnabled)
ecab4dba 399 m_targetWindow->ScrollWindow( m_xScrollPixelsPerLine * (oldXScroll-m_xScrollPosition), 0, (const wxRect *) NULL );
27d029c7 400 else
ecab4dba 401 m_targetWindow->Refresh();
27d029c7
RR
402 }
403
404 if (oldYScroll != m_yScrollPosition)
405 {
406 if (m_yScrollingEnabled)
ecab4dba 407 m_targetWindow->ScrollWindow( 0, m_yScrollPixelsPerLine * (oldYScroll-m_yScrollPosition), (const wxRect *) NULL );
27d029c7 408 else
ecab4dba 409 m_targetWindow->Refresh();
27d029c7 410 }
c801d85f
KB
411}
412
413// Default OnSize resets scrollbars, if any
414void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event))
415{
47d67540 416#if wxUSE_CONSTRAINTS
139adb6a 417 if (GetAutoLayout()) Layout();
c801d85f
KB
418#endif
419
139adb6a 420 AdjustScrollbars();
c801d85f
KB
421}
422
423// This calls OnDraw, having adjusted the origin according to the current
424// scroll position
425void wxScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
426{
139adb6a
RR
427 wxPaintDC dc(this);
428 PrepareDC(dc);
c801d85f 429
139adb6a 430 OnDraw(dc);
c801d85f
KB
431}
432
433// Override this function if you don't want to have wxScrolledWindow
434// automatically change the origin according to the scroll position.
435void wxScrolledWindow::PrepareDC(wxDC& dc)
436{
139adb6a
RR
437 dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine,
438 -m_yScrollPosition * m_yScrollPixelsPerLine );
439 dc.SetUserScale( m_scaleX, m_scaleY );
c801d85f
KB
440}
441
442#if WXWIN_COMPATIBILITY
443void wxScrolledWindow::GetScrollUnitsPerPage (int *x_page, int *y_page) const
444{
445 *x_page = GetScrollPageSize(wxHORIZONTAL);
446 *y_page = GetScrollPageSize(wxVERTICAL);
447}
a0bc2c1d
VZ
448
449void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const
450{
451 if ( xx )
452 *xx = (float)(x + m_xScrollPosition * m_xScrollPixelsPerLine);
453 if ( yy )
454 *yy = (float)(y + m_yScrollPosition * m_yScrollPixelsPerLine);
455}
456#endif // WXWIN_COMPATIBILITY
c801d85f
KB
457
458void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
459{
a0bc2c1d
VZ
460 if ( x_unit )
461 *x_unit = m_xScrollPixelsPerLine;
462 if ( y_unit )
463 *y_unit = m_yScrollPixelsPerLine;
c801d85f
KB
464}
465
466int wxScrolledWindow::GetScrollPageSize(int orient) const
467{
468 if ( orient == wxHORIZONTAL )
469 return m_xScrollLinesPerPage;
470 else
471 return m_yScrollLinesPerPage;
472}
473
474void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize)
475{
476 if ( orient == wxHORIZONTAL )
477 m_xScrollLinesPerPage = pageSize;
478 else
479 m_yScrollLinesPerPage = pageSize;
480}
481
482/*
483 * Scroll to given position (scroll position, not pixel position)
484 */
139adb6a 485void wxScrolledWindow::Scroll( int x_pos, int y_pos )
c801d85f 486{
139adb6a
RR
487 if (((x_pos == -1) || (x_pos == m_xScrollPosition)) &&
488 ((y_pos == -1) || (y_pos == m_yScrollPosition))) return;
489
490 int w, h;
ecab4dba 491 m_targetWindow->GetClientSize(&w, &h);
c801d85f 492
139adb6a 493 if (x_pos != -1)
c801d85f 494 {
ed673c6a 495 int old_x = m_xScrollPosition;
139adb6a
RR
496 m_xScrollPosition = x_pos;
497
cf3da716
RR
498 // Calculate page size i.e. number of scroll units you get on the
499 // current client window
ecab4dba 500 int noPagePositions = (int) ( (w/(double)m_xScrollPixelsPerLine) + 0.5 );
139adb6a
RR
501 if (noPagePositions < 1) noPagePositions = 1;
502
503 // Correct position if greater than extent of canvas minus
cf3da716 504 // the visible portion of it or if below zero
139adb6a
RR
505 m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition );
506 m_xScrollPosition = wxMax( 0, m_xScrollPosition );
507
ecab4dba 508 m_targetWindow->SetScrollPos( wxHORIZONTAL, m_xScrollPosition, TRUE );
ed673c6a 509
cf3da716 510 m_targetWindow->ScrollWindow( (old_x-m_xScrollPosition)*m_xScrollPixelsPerLine, 0 );
c801d85f 511 }
139adb6a 512 if (y_pos != -1)
c801d85f 513 {
ed673c6a 514 int old_y = m_yScrollPosition;
139adb6a
RR
515 m_yScrollPosition = y_pos;
516
cf3da716
RR
517 // Calculate page size i.e. number of scroll units you get on the
518 // current client window
ecab4dba 519 int noPagePositions = (int) ( (h/(double)m_yScrollPixelsPerLine) + 0.5 );
139adb6a
RR
520 if (noPagePositions < 1) noPagePositions = 1;
521
522 // Correct position if greater than extent of canvas minus
cf3da716 523 // the visible portion of it or if below zero
139adb6a
RR
524 m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition );
525 m_yScrollPosition = wxMax( 0, m_yScrollPosition );
526
ecab4dba 527 m_targetWindow->SetScrollPos( wxVERTICAL, m_yScrollPosition, TRUE );
ed673c6a 528
cf3da716 529 m_targetWindow->ScrollWindow( 0, (old_y-m_yScrollPosition)*m_yScrollPixelsPerLine );
c801d85f 530 }
139adb6a 531
139adb6a 532
7c74e7fe
SC
533#ifdef __WXMAC__
534 m_targetWindow->MacUpdateImmediately() ;
535#endif
c801d85f
KB
536}
537
debe6624 538void wxScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll)
c801d85f 539{
139adb6a
RR
540 m_xScrollingEnabled = x_scroll;
541 m_yScrollingEnabled = y_scroll;
c801d85f
KB
542}
543
544void wxScrolledWindow::GetVirtualSize (int *x, int *y) const
545{
a0bc2c1d
VZ
546 if ( x )
547 *x = m_xScrollPixelsPerLine * m_xScrollLines;
548 if ( y )
549 *y = m_yScrollPixelsPerLine * m_yScrollLines;
c801d85f
KB
550}
551
552// Where the current view starts from
cf3da716 553void wxScrolledWindow::GetViewStart (int *x, int *y) const
c801d85f 554{
a0bc2c1d
VZ
555 if ( x )
556 *x = m_xScrollPosition;
557 if ( y )
558 *y = m_yScrollPosition;
c801d85f
KB
559}
560
debe6624 561void wxScrolledWindow::CalcScrolledPosition(int x, int y, int *xx, int *yy) const
c801d85f 562{
a0bc2c1d
VZ
563 if ( xx )
564 *xx = x - m_xScrollPosition * m_xScrollPixelsPerLine;
565 if ( yy )
566 *yy = y - m_yScrollPosition * m_yScrollPixelsPerLine;
c801d85f
KB
567}
568
a0bc2c1d 569void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, int *xx, int *yy) const
c801d85f 570{
a0bc2c1d
VZ
571 if ( xx )
572 *xx = x + m_xScrollPosition * m_xScrollPixelsPerLine;
573 if ( yy )
574 *yy = y + m_yScrollPosition * m_yScrollPixelsPerLine;
c801d85f 575}