]> git.saurik.com Git - wxWidgets.git/blame - src/generic/scrolwin.cpp
updated i18n sample, french translations are now in the "fr" subdirectory.
[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
2049ba38 23#ifdef __WXMSW__
c801d85f
KB
24#include "windows.h"
25#endif
26
27#ifdef __BORLANDC__
28#pragma hdrstop
29#endif
30
31#include "wx/generic/scrolwin.h"
32
33#if !USE_SHARED_LIBRARY
34BEGIN_EVENT_TABLE(wxScrolledWindow, wxWindow)
139adb6a
RR
35 EVT_SCROLL(wxScrolledWindow::OnScroll)
36 EVT_SIZE(wxScrolledWindow::OnSize)
37 EVT_PAINT(wxScrolledWindow::OnPaint)
c801d85f
KB
38END_EVENT_TABLE()
39
40IMPLEMENT_DYNAMIC_CLASS(wxScrolledWindow, wxWindow)
41#endif
42
43wxScrolledWindow::wxScrolledWindow(void)
44{
139adb6a
RR
45 m_xScrollPixelsPerLine = 0;
46 m_yScrollPixelsPerLine = 0;
47 m_xScrollingEnabled = TRUE;
48 m_yScrollingEnabled = TRUE;
49 m_xScrollPosition = 0;
50 m_yScrollPosition = 0;
51 m_xScrollLines = 0;
52 m_yScrollLines = 0;
53 m_xScrollLinesPerPage = 0;
54 m_yScrollLinesPerPage = 0;
55 m_scaleX = 1.0;
56 m_scaleY = 1.0;
c801d85f
KB
57}
58
debe6624 59bool wxScrolledWindow::Create(wxWindow *parent, wxWindowID id,
c801d85f
KB
60 const wxPoint& pos,
61 const wxSize& size,
debe6624 62 long style,
c801d85f
KB
63 const wxString& name)
64{
139adb6a
RR
65 m_xScrollPixelsPerLine = 0;
66 m_yScrollPixelsPerLine = 0;
67 m_xScrollingEnabled = TRUE;
68 m_yScrollingEnabled = TRUE;
69 m_xScrollPosition = 0;
70 m_yScrollPosition = 0;
71 m_xScrollLines = 0;
72 m_yScrollLines = 0;
73 m_xScrollLinesPerPage = 0;
74 m_yScrollLinesPerPage = 0;
75 m_scaleX = 1.0;
76 m_scaleY = 1.0;
77
78 return wxWindow::Create(parent, id, pos, size, style, name);
c801d85f
KB
79}
80
81/*
82 * pixelsPerUnitX/pixelsPerUnitY: number of pixels per unit (e.g. pixels per text line)
83 * noUnitsX/noUnitsY: : no. units per scrollbar
84 */
debe6624
JS
85void wxScrolledWindow::SetScrollbars (int pixelsPerUnitX, int pixelsPerUnitY,
86 int noUnitsX, int noUnitsY,
87 int xPos, int yPos, bool noRefresh )
c801d85f 88{
139adb6a
RR
89 bool do_refresh =
90 (
c801d85f
KB
91 (noUnitsX != 0 && m_xScrollLines == 0) ||
92 (noUnitsX < m_xScrollPosition) ||
93 (noUnitsY != 0 && m_yScrollLines == 0) ||
94 (noUnitsY < m_yScrollPosition) ||
95 (xPos != m_xScrollPosition) ||
96 (yPos != m_yScrollPosition) ||
97 (pixelsPerUnitX != m_xScrollPixelsPerLine) ||
98 (pixelsPerUnitY != m_yScrollPixelsPerLine)
139adb6a 99 );
c801d85f 100
139adb6a
RR
101 m_xScrollPixelsPerLine = pixelsPerUnitX;
102 m_yScrollPixelsPerLine = pixelsPerUnitY;
103 m_xScrollPosition = xPos;
104 m_yScrollPosition = yPos;
105 m_xScrollLines = noUnitsX;
106 m_yScrollLines = noUnitsY;
d4c99d6f 107
139adb6a 108 AdjustScrollbars();
c801d85f
KB
109
110 if (do_refresh && !noRefresh) Refresh();
111
2049ba38 112#ifdef __WXMSW__
c801d85f
KB
113 UpdateWindow ((HWND) GetHWND());
114#endif
115}
116
117void wxScrolledWindow::OnScroll(wxScrollEvent& event)
118{
139adb6a 119 int orient = event.GetOrientation();
c801d85f 120
139adb6a
RR
121 int nScrollInc = CalcScrollInc(event);
122 if (nScrollInc == 0) return;
c801d85f 123
139adb6a
RR
124 if (orient == wxHORIZONTAL)
125 {
126 int newPos = m_xScrollPosition + nScrollInc;
127 SetScrollPos(wxHORIZONTAL, newPos, TRUE );
128 }
129 else
130 {
131 int newPos = m_yScrollPosition + nScrollInc;
132 SetScrollPos(wxVERTICAL, newPos, TRUE );
133 }
c801d85f 134
139adb6a
RR
135 if (orient == wxHORIZONTAL)
136 {
137 m_xScrollPosition += nScrollInc;
138 }
c801d85f 139 else
139adb6a
RR
140 {
141 m_yScrollPosition += nScrollInc;
142 }
143
144 if (orient == wxHORIZONTAL)
145 {
146 if (m_xScrollingEnabled)
147 ScrollWindow(-m_xScrollPixelsPerLine * nScrollInc, 0, (const wxRect *) NULL);
148 else
149 Refresh();
150 }
c801d85f 151 else
139adb6a
RR
152 {
153 if (m_yScrollingEnabled)
154 ScrollWindow(0, -m_yScrollPixelsPerLine * nScrollInc, (const wxRect *) NULL);
155 else
156 Refresh();
c801d85f 157 }
c801d85f
KB
158}
159
160int wxScrolledWindow::CalcScrollInc(wxScrollEvent& event)
161{
162 int pos = event.GetPosition();
163 int orient = event.GetOrientation();
164
165 int nScrollInc = 0;
166 switch (event.GetEventType())
167 {
f5419957 168 case wxEVT_SCROLL_TOP:
c801d85f
KB
169 {
170 if (orient == wxHORIZONTAL)
171 nScrollInc = - m_xScrollPosition;
172 else
173 nScrollInc = - m_yScrollPosition;
174 break;
175 }
f5419957 176 case wxEVT_SCROLL_BOTTOM:
c801d85f
KB
177 {
178 if (orient == wxHORIZONTAL)
179 nScrollInc = m_xScrollLines - m_xScrollPosition;
180 else
181 nScrollInc = m_yScrollLines - m_yScrollPosition;
182 break;
183 }
f5419957 184 case wxEVT_SCROLL_LINEUP:
c801d85f
KB
185 {
186 nScrollInc = -1;
187 break;
188 }
f5419957 189 case wxEVT_SCROLL_LINEDOWN:
c801d85f
KB
190 {
191 nScrollInc = 1;
192 break;
193 }
f5419957 194 case wxEVT_SCROLL_PAGEUP:
c801d85f
KB
195 {
196 if (orient == wxHORIZONTAL)
197 nScrollInc = -GetScrollPageSize(wxHORIZONTAL);
198 else
199 nScrollInc = -GetScrollPageSize(wxVERTICAL);
200 break;
201 }
f5419957 202 case wxEVT_SCROLL_PAGEDOWN:
c801d85f
KB
203 {
204 if (orient == wxHORIZONTAL)
205 nScrollInc = GetScrollPageSize(wxHORIZONTAL);
206 else
207 nScrollInc = GetScrollPageSize(wxVERTICAL);
208 break;
209 }
f5419957 210 case wxEVT_SCROLL_THUMBTRACK:
c801d85f
KB
211 {
212 if (orient == wxHORIZONTAL)
213 nScrollInc = pos - m_xScrollPosition;
214 else
215 nScrollInc = pos - m_yScrollPosition;
216 break;
217 }
218 default:
219 {
220 break;
221 }
222 }
88150e60 223
c801d85f
KB
224 if (orient == wxHORIZONTAL)
225 {
9d9355c6
VZ
226 if (m_xScrollPixelsPerLine > 0) {
227 int w, h;
228 GetClientSize(&w, &h);
c801d85f 229
9d9355c6
VZ
230 int nMaxWidth = m_xScrollLines*m_xScrollPixelsPerLine;
231 int noPositions = (int) ( ((nMaxWidth - w)/(float)m_xScrollPixelsPerLine) + 0.5 );
232 if (noPositions < 0)
233 noPositions = 0;
c801d85f 234
9d9355c6
VZ
235 if ( (m_xScrollPosition + nScrollInc) < 0 )
236 nScrollInc = -m_xScrollPosition; // As -ve as we can go
237 else if ( (m_xScrollPosition + nScrollInc) > noPositions )
238 nScrollInc = noPositions - m_xScrollPosition; // As +ve as we can go
239 }
240 else
241 Refresh();
c801d85f
KB
242 }
243 else
244 {
9d9355c6
VZ
245 if (m_yScrollPixelsPerLine > 0) {
246 int w, h;
247 GetClientSize(&w, &h);
248
249 int nMaxHeight = m_yScrollLines*m_yScrollPixelsPerLine;
250 int noPositions = (int) ( ((nMaxHeight - h)/(float)m_yScrollPixelsPerLine) + 0.5 );
251 if (noPositions < 0)
252 noPositions = 0;
253
254 if ( (m_yScrollPosition + nScrollInc) < 0 )
255 nScrollInc = -m_yScrollPosition; // As -ve as we can go
256 else if ( (m_yScrollPosition + nScrollInc) > noPositions )
257 nScrollInc = noPositions - m_yScrollPosition; // As +ve as we can go
258 }
259 else
260 Refresh();
c801d85f 261 }
9d9355c6
VZ
262
263 return nScrollInc;
c801d85f
KB
264}
265
266// Adjust the scrollbars - new version.
267void wxScrolledWindow::AdjustScrollbars(void)
268{
139adb6a
RR
269 int w, h;
270 GetClientSize(&w, &h);
c801d85f 271
139adb6a
RR
272 if (m_xScrollLines > 0)
273 {
c801d85f
KB
274 // Calculate page size i.e. number of scroll units you get on the
275 // current client window
139adb6a
RR
276 int noPagePositions = (int) ( (w/(float)m_xScrollPixelsPerLine) + 0.5 );
277 if (noPagePositions < 1) noPagePositions = 1;
c801d85f 278
139adb6a
RR
279 // Correct position if greater than extent of canvas minus
280 // the visible portion of it or if below zero
281 m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition);
282 m_xScrollPosition = wxMax( 0, m_xScrollPosition );
c801d85f 283
139adb6a 284 SetScrollbar(wxHORIZONTAL, m_xScrollPosition, noPagePositions, m_xScrollLines);
88150e60
JS
285 // The amount by which we scroll when paging
286 SetScrollPageSize(wxHORIZONTAL, noPagePositions);
139adb6a
RR
287 }
288 else
289 {
290 m_xScrollPosition = 0;
291 SetScrollbar (wxHORIZONTAL, 0, 0, 0, FALSE);
292 }
293
294 if (m_yScrollLines > 0)
295 {
c801d85f
KB
296 // Calculate page size i.e. number of scroll units you get on the
297 // current client window
139adb6a
RR
298 int noPagePositions = (int) ( (h/(float)m_yScrollPixelsPerLine) + 0.5 );
299 if (noPagePositions < 1) noPagePositions = 1;
c801d85f 300
139adb6a
RR
301 // Correct position if greater than extent of canvas minus
302 // the visible portion of it or if below zero
303 m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition );
304 m_yScrollPosition = wxMax( 0, m_yScrollPosition );
305
306 SetScrollbar(wxVERTICAL, m_yScrollPosition, noPagePositions, m_yScrollLines);
88150e60
JS
307 // The amount by which we scroll when paging
308 SetScrollPageSize(wxVERTICAL, noPagePositions);
139adb6a
RR
309 }
310 else
311 {
312 m_yScrollPosition = 0;
313 SetScrollbar (wxVERTICAL, 0, 0, 0, FALSE);
314 }
c801d85f
KB
315}
316
317// Default OnSize resets scrollbars, if any
318void wxScrolledWindow::OnSize(wxSizeEvent& WXUNUSED(event))
319{
47d67540 320#if wxUSE_CONSTRAINTS
139adb6a 321 if (GetAutoLayout()) Layout();
c801d85f
KB
322#endif
323
139adb6a 324 AdjustScrollbars();
c801d85f
KB
325}
326
327// This calls OnDraw, having adjusted the origin according to the current
328// scroll position
329void wxScrolledWindow::OnPaint(wxPaintEvent& WXUNUSED(event))
330{
139adb6a
RR
331 wxPaintDC dc(this);
332 PrepareDC(dc);
c801d85f 333
139adb6a 334 OnDraw(dc);
c801d85f
KB
335}
336
337// Override this function if you don't want to have wxScrolledWindow
338// automatically change the origin according to the scroll position.
339void wxScrolledWindow::PrepareDC(wxDC& dc)
340{
139adb6a
RR
341 dc.SetDeviceOrigin( -m_xScrollPosition * m_xScrollPixelsPerLine,
342 -m_yScrollPosition * m_yScrollPixelsPerLine );
343 dc.SetUserScale( m_scaleX, m_scaleY );
c801d85f
KB
344}
345
346#if WXWIN_COMPATIBILITY
347void wxScrolledWindow::GetScrollUnitsPerPage (int *x_page, int *y_page) const
348{
349 *x_page = GetScrollPageSize(wxHORIZONTAL);
350 *y_page = GetScrollPageSize(wxVERTICAL);
351}
352#endif
353
354void wxScrolledWindow::GetScrollPixelsPerUnit (int *x_unit, int *y_unit) const
355{
356 *x_unit = m_xScrollPixelsPerLine;
357 *y_unit = m_yScrollPixelsPerLine;
358}
359
360int wxScrolledWindow::GetScrollPageSize(int orient) const
361{
362 if ( orient == wxHORIZONTAL )
363 return m_xScrollLinesPerPage;
364 else
365 return m_yScrollLinesPerPage;
366}
367
368void wxScrolledWindow::SetScrollPageSize(int orient, int pageSize)
369{
370 if ( orient == wxHORIZONTAL )
371 m_xScrollLinesPerPage = pageSize;
372 else
373 m_yScrollLinesPerPage = pageSize;
374}
375
376/*
377 * Scroll to given position (scroll position, not pixel position)
378 */
139adb6a 379void wxScrolledWindow::Scroll( int x_pos, int y_pos )
c801d85f 380{
139adb6a
RR
381 if (((x_pos == -1) || (x_pos == m_xScrollPosition)) &&
382 ((y_pos == -1) || (y_pos == m_yScrollPosition))) return;
383
384 int w, h;
385 GetClientSize(&w, &h);
c801d85f 386
139adb6a 387 if (x_pos != -1)
c801d85f 388 {
139adb6a
RR
389 m_xScrollPosition = x_pos;
390
391 // Calculate page size i.e. number of scroll units you get on the
392 // current client window
393 int noPagePositions = (int) ( (w/(float)m_xScrollPixelsPerLine) + 0.5 );
394 if (noPagePositions < 1) noPagePositions = 1;
395
396 // Correct position if greater than extent of canvas minus
397 // the visible portion of it or if below zero
398 m_xScrollPosition = wxMin( m_xScrollLines-noPagePositions, m_xScrollPosition );
399 m_xScrollPosition = wxMax( 0, m_xScrollPosition );
400
401 SetScrollPos( wxHORIZONTAL, m_xScrollPosition, TRUE );
c801d85f 402 }
139adb6a 403 if (y_pos != -1)
c801d85f 404 {
139adb6a
RR
405 m_yScrollPosition = y_pos;
406
407 // Calculate page size i.e. number of scroll units you get on the
408 // current client window
409 int noPagePositions = (int) ( (h/(float)m_yScrollPixelsPerLine) + 0.5 );
410 if (noPagePositions < 1) noPagePositions = 1;
411
412 // Correct position if greater than extent of canvas minus
413 // the visible portion of it or if below zero
414 m_yScrollPosition = wxMin( m_yScrollLines-noPagePositions, m_yScrollPosition );
415 m_yScrollPosition = wxMax( 0, m_yScrollPosition );
416
417 SetScrollPos( wxVERTICAL, m_yScrollPosition, TRUE );
c801d85f 418 }
139adb6a
RR
419
420 Refresh();
421
2049ba38 422#ifdef __WXMSW__
139adb6a 423 ::UpdateWindow ((HWND) GetHWND());
c801d85f
KB
424#endif
425}
426
debe6624 427void wxScrolledWindow::EnableScrolling (bool x_scroll, bool y_scroll)
c801d85f 428{
139adb6a
RR
429 m_xScrollingEnabled = x_scroll;
430 m_yScrollingEnabled = y_scroll;
c801d85f
KB
431}
432
433void wxScrolledWindow::GetVirtualSize (int *x, int *y) const
434{
139adb6a
RR
435 *x = m_xScrollPixelsPerLine * m_xScrollLines;
436 *y = m_yScrollPixelsPerLine * m_yScrollLines;
c801d85f
KB
437}
438
439// Where the current view starts from
440void wxScrolledWindow::ViewStart (int *x, int *y) const
441{
139adb6a
RR
442 *x = m_xScrollPosition;
443 *y = m_yScrollPosition;
c801d85f
KB
444}
445
debe6624 446void wxScrolledWindow::CalcScrolledPosition(int x, int y, int *xx, int *yy) const
c801d85f 447{
139adb6a
RR
448 *xx = x - m_xScrollPosition * m_xScrollPixelsPerLine;
449 *yy = y - m_yScrollPosition * m_yScrollPixelsPerLine;
c801d85f
KB
450}
451
debe6624 452void wxScrolledWindow::CalcUnscrolledPosition(int x, int y, float *xx, float *yy) const
c801d85f 453{
139adb6a
RR
454 *xx = (float)(x + m_xScrollPosition * m_xScrollPixelsPerLine);
455 *yy = (float)(y + m_yScrollPosition * m_yScrollPixelsPerLine);
c801d85f
KB
456}
457
458