]> git.saurik.com Git - wxWidgets.git/blame - samples/scroll/scroll.cpp
demonstrate tab order
[wxWidgets.git] / samples / scroll / scroll.cpp
CommitLineData
fdd3ed7a
RR
1/*
2 * Program: scroll
3 *
4 * Author: Robert Roebling
5 *
6 * Copyright: (C) 1998, Robert Roebling
2b5f62a0 7 * 2002, Ron Lee
fdd3ed7a
RR
8 *
9 */
10
11// For compilers that support precompilation, includes "wx/wx.h".
12#include "wx/wxprec.h"
13
14#ifdef __BORLANDC__
15#pragma hdrstop
16#endif
17
18#ifndef WX_PRECOMP
19#include "wx/wx.h"
20#endif
21
22#include "wx/image.h"
053f9cc1 23#include "wx/listctrl.h"
ed673c6a
RR
24#include "wx/sizer.h"
25#include "wx/log.h"
26
fdd3ed7a
RR
27
28// derived classes
29
30class MyFrame;
31class MyApp;
32
33// MyCanvas
34
35class MyCanvas: public wxScrolledWindow
36{
37public:
8a73bf3d 38 MyCanvas() {}
fdd3ed7a
RR
39 MyCanvas( wxWindow *parent, wxWindowID, const wxPoint &pos, const wxSize &size );
40 ~MyCanvas();
41 void OnPaint( wxPaintEvent &event );
307f16e8 42 void OnQueryPosition( wxCommandEvent &event );
ed673c6a
RR
43 void OnAddButton( wxCommandEvent &event );
44 void OnDeleteButton( wxCommandEvent &event );
45 void OnMoveButton( wxCommandEvent &event );
46 void OnScrollWin( wxCommandEvent &event );
bf0c00c6 47 void OnMouseDown( wxMouseEvent &event );
ed673c6a
RR
48
49 wxButton *m_button;
fdd3ed7a
RR
50
51 DECLARE_DYNAMIC_CLASS(MyCanvas)
52 DECLARE_EVENT_TABLE()
53};
54
2b5f62a0
VZ
55
56// ----------------------------------------------------------------------------
57// Autoscrolling example.
58// ----------------------------------------------------------------------------
59
60// this class uses the 'virtual' size attribute along with an internal
61// sizer to automatically set up scrollbars as needed
62
63class MyAutoScrollWindow : public wxScrolledWindow
64{
65private:
66
67 wxButton *m_button;
68
69public:
70
71 MyAutoScrollWindow( wxWindow *parent );
72
73 void OnResizeClick( wxCommandEvent &WXUNUSED( event ) );
74
75 DECLARE_EVENT_TABLE()
76};
77
78
8a73bf3d
VZ
79// ----------------------------------------------------------------------------
80// MyScrolledWindow classes: examples of wxScrolledWindow usage
81// ----------------------------------------------------------------------------
82
83// base class for both of them
84class MyScrolledWindowBase : public wxScrolledWindow
85{
86public:
2b5f62a0
VZ
87 MyScrolledWindowBase(wxWindow *parent)
88 : wxScrolledWindow(parent)
89 , m_nLines( 100 )
8a73bf3d 90 {
2b5f62a0
VZ
91 wxClientDC dc(this);
92 dc.GetTextExtent(_T("Line 17"), NULL, &m_hLine);
8a73bf3d
VZ
93 }
94
95protected:
8a73bf3d
VZ
96 // the height of one line on screen
97 wxCoord m_hLine;
98
99 // the number of lines we draw
100 size_t m_nLines;
101};
102
103// this class does "stupid" redrawing - it redraws everything each time
2b5f62a0
VZ
104// and sets the scrollbar extent directly.
105
8a73bf3d
VZ
106class MyScrolledWindowDumb : public MyScrolledWindowBase
107{
108public:
2b5f62a0
VZ
109 MyScrolledWindowDumb(wxWindow *parent) : MyScrolledWindowBase(parent)
110 {
111 // no horz scrolling
b62ca03d 112 SetScrollbars(0, m_hLine, 0, m_nLines + 1, 0, 0, true /* no refresh */);
2b5f62a0 113 }
8a73bf3d
VZ
114
115 virtual void OnDraw(wxDC& dc);
116};
117
118// this class does "smart" redrawing - only redraws the lines which must be
2b5f62a0
VZ
119// redrawn and sets the scroll rate and virtual size to affect the
120// scrollbars.
121//
122// Note that this class should produce identical results to the one above.
123
8a73bf3d
VZ
124class MyScrolledWindowSmart : public MyScrolledWindowBase
125{
126public:
2b5f62a0
VZ
127 MyScrolledWindowSmart(wxWindow *parent) : MyScrolledWindowBase(parent)
128 {
129 // no horz scrolling
130 SetScrollRate( 0, m_hLine );
131 SetVirtualSize( -1, ( m_nLines + 1 ) * m_hLine );
132 }
8a73bf3d
VZ
133
134 virtual void OnDraw(wxDC& dc);
135};
136
2b5f62a0 137
8a73bf3d 138// ----------------------------------------------------------------------------
fdd3ed7a 139// MyFrame
8a73bf3d 140// ----------------------------------------------------------------------------
fdd3ed7a
RR
141
142class MyFrame: public wxFrame
143{
144public:
145 MyFrame();
146
147 void OnAbout( wxCommandEvent &event );
148 void OnQuit( wxCommandEvent &event );
8e217128
RR
149 void OnDeleteAll( wxCommandEvent &event );
150 void OnInsertNew( wxCommandEvent &event );
fdd3ed7a
RR
151
152 MyCanvas *m_canvas;
ed673c6a 153 wxTextCtrl *m_log;
fdd3ed7a
RR
154
155 DECLARE_DYNAMIC_CLASS(MyFrame)
156 DECLARE_EVENT_TABLE()
157};
158
159// MyApp
160
161class MyApp: public wxApp
162{
163public:
164 virtual bool OnInit();
165};
166
167// main program
168
169IMPLEMENT_APP(MyApp)
170
ed673c6a
RR
171// ids
172
2b5f62a0
VZ
173const long ID_ADDBUTTON = wxNewId();
174const long ID_DELBUTTON = wxNewId();
175const long ID_MOVEBUTTON = wxNewId();
176const long ID_SCROLLWIN = wxNewId();
177const long ID_QUERYPOS = wxNewId();
ed673c6a 178
2b5f62a0 179const long ID_NEWBUTTON = wxNewId();
ed673c6a 180
fdd3ed7a
RR
181// MyCanvas
182
183IMPLEMENT_DYNAMIC_CLASS(MyCanvas, wxScrolledWindow)
184
185BEGIN_EVENT_TABLE(MyCanvas, wxScrolledWindow)
307f16e8 186 EVT_PAINT( MyCanvas::OnPaint)
2b5f62a0 187 EVT_MOUSE_EVENTS( MyCanvas::OnMouseDown)
307f16e8 188 EVT_BUTTON( ID_QUERYPOS, MyCanvas::OnQueryPosition)
ed673c6a
RR
189 EVT_BUTTON( ID_ADDBUTTON, MyCanvas::OnAddButton)
190 EVT_BUTTON( ID_DELBUTTON, MyCanvas::OnDeleteButton)
191 EVT_BUTTON( ID_MOVEBUTTON, MyCanvas::OnMoveButton)
192 EVT_BUTTON( ID_SCROLLWIN, MyCanvas::OnScrollWin)
fdd3ed7a
RR
193END_EVENT_TABLE()
194
195MyCanvas::MyCanvas( wxWindow *parent, wxWindowID id,
196 const wxPoint &pos, const wxSize &size )
2b5f62a0 197 : wxScrolledWindow( parent, id, pos, size, wxSUNKEN_BORDER | wxTAB_TRAVERSAL, _T("test canvas") )
fdd3ed7a 198{
2b5f62a0
VZ
199 SetScrollRate( 10, 10 );
200 SetVirtualSize( 500, 1000 );
201
202 (void) new wxButton( this, ID_ADDBUTTON, _T("add button"), wxPoint(10,10) );
203 (void) new wxButton( this, ID_DELBUTTON, _T("del button"), wxPoint(10,40) );
204 (void) new wxButton( this, ID_MOVEBUTTON, _T("move button"), wxPoint(150,10) );
205 (void) new wxButton( this, ID_SCROLLWIN, _T("scroll win"), wxPoint(250,10) );
ed673c6a 206
aa06a8fd
DW
207#if 0
208
fdd3ed7a
RR
209 wxString choices[] =
210 {
211 "This",
212 "is one of my",
213 "really",
214 "wonderful",
215 "examples."
216 };
aa06a8fd 217
307f16e8 218 m_button = new wxButton( this, ID_QUERYPOS, "Query position", wxPoint(10,110) );
aa06a8fd 219
b62ca03d 220 (void) new wxTextCtrl( this, wxID_ANY, "wxTextCtrl", wxPoint(10,150), wxSize(80,wxDefaultSize.y) );
aa06a8fd 221
b62ca03d 222 (void) new wxRadioButton( this, wxID_ANY, "Disable", wxPoint(10,190) );
aa06a8fd 223
b62ca03d 224 (void) new wxComboBox( this, wxID_ANY, "This", wxPoint(10,230), wxDefaultSize, 5, choices );
aa06a8fd 225
b62ca03d 226 (void) new wxRadioBox( this, wxID_ANY, "This", wxPoint(10,310), wxDefaultSize, 5, choices, 2, wxRA_SPECIFY_COLS );
053f9cc1 227
b62ca03d 228 (void) new wxRadioBox( this, wxID_ANY, "This", wxPoint(10,440), wxDefaultSize, 5, choices, 2, wxRA_SPECIFY_ROWS );
e9158f7d 229
ed673c6a 230 wxListCtrl *m_listCtrl = new wxListCtrl(
b62ca03d 231 this, wxID_ANY, wxPoint(200, 110), wxSize(180, 120),
8a73bf3d 232 wxLC_REPORT | wxSIMPLE_BORDER | wxLC_SINGLE_SEL );
053f9cc1 233
ed673c6a
RR
234 m_listCtrl->InsertColumn(0, "First", wxLIST_FORMAT_LEFT, 90);
235 m_listCtrl->InsertColumn(1, "Last", wxLIST_FORMAT_LEFT, 90);
053f9cc1 236
ed673c6a
RR
237 for ( int i=0; i < 30; i++)
238 {
239 char buf[20];
240 sprintf(buf, "Item %d", i);
241 m_listCtrl->InsertItem(i, buf);
242 }
243 m_listCtrl->SetItemState( 3, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED );
053f9cc1 244
b62ca03d 245 (void) new wxListBox( this, wxID_ANY, wxPoint(260,280), wxSize(120,120), 5, choices, wxLB_ALWAYS_SB );
5e014a0c 246
aa06a8fd
DW
247#endif
248
b62ca03d 249 wxPanel *test = new wxPanel( this, wxID_ANY, wxPoint(10, 110), wxSize(130,50), wxSIMPLE_BORDER | wxTAB_TRAVERSAL );
a60b1f5d 250 test->SetBackgroundColour( wxT("WHEAT") );
aa06a8fd
DW
251
252#if 0
253
b62ca03d 254 wxButton *test2 = new wxButton( test, wxID_ANY, "Hallo", wxPoint(10,10) );
aa06a8fd 255
b62ca03d 256 test = new wxPanel( this, wxID_ANY, wxPoint(160, 530), wxSize(130,120), wxSUNKEN_BORDER | wxTAB_TRAVERSAL );
a60b1f5d 257 test->SetBackgroundColour( wxT("WHEAT") );
ed673c6a 258 test->SetCursor( wxCursor( wxCURSOR_NO_ENTRY ) );
b62ca03d 259 test2 = new wxButton( test, wxID_ANY, "Hallo", wxPoint(10,10) );
ed673c6a 260 test2->SetCursor( wxCursor( wxCURSOR_PENCIL ) );
aa06a8fd 261
b62ca03d 262 test = new wxPanel( this, wxID_ANY, wxPoint(310, 530), wxSize(130,120), wxRAISED_BORDER | wxTAB_TRAVERSAL );
a60b1f5d 263 test->SetBackgroundColour( wxT("WHEAT") );
ed673c6a 264 test->SetCursor( wxCursor( wxCURSOR_PENCIL ) );
b62ca03d 265 test2 = new wxButton( test, wxID_ANY, "Hallo", wxPoint(10,10) );
ed673c6a 266 test2->SetCursor( wxCursor( wxCURSOR_NO_ENTRY ) );
5e014a0c 267
aa06a8fd
DW
268#endif
269
a60b1f5d 270 SetBackgroundColour( wxT("BLUE") );
aa06a8fd 271
ed673c6a 272 SetCursor( wxCursor( wxCURSOR_IBEAM ) );
fdd3ed7a
RR
273}
274
275MyCanvas::~MyCanvas()
276{
277}
278
bf0c00c6
RR
279void MyCanvas::OnMouseDown( wxMouseEvent &event )
280{
a3e7d24d
RR
281 if (event.LeftDown())
282 {
283 wxPoint pt( event.GetPosition() );
284 int x,y;
285 CalcUnscrolledPosition( pt.x, pt.y, &x, &y );
4693b20c 286 wxLogMessage( wxT("Mouse down event at: %d %d, scrolled: %d %d"), pt.x, pt.y, x, y );
f6bcfd97
BP
287
288 if ( !event.LeftIsDown() )
b62ca03d 289 wxLogMessage( wxT("Error: LeftIsDown() should be true if for LeftDown()") );
a3e7d24d 290 }
bf0c00c6
RR
291}
292
293void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) )
294{
295 wxPaintDC dc( this );
296 PrepareDC( dc );
297
2b5f62a0 298 dc.DrawText( _T("Press mouse button to test calculations!"), 160, 50 );
bf0c00c6 299
2b5f62a0 300 dc.DrawText( _T("Some text"), 140, 140 );
aa06a8fd 301
bf0c00c6
RR
302 dc.DrawRectangle( 100, 160, 200, 200 );
303}
304
307f16e8
RR
305void MyCanvas::OnQueryPosition( wxCommandEvent &WXUNUSED(event) )
306{
307 wxPoint pt( m_button->GetPosition() );
4693b20c 308 wxLogMessage( wxT("Position of \"Query position\" is %d %d"), pt.x, pt.y );
bf0c00c6 309 pt = ClientToScreen( pt );
4693b20c 310 wxLogMessage( wxT("Position of \"Query position\" on screen is %d %d"), pt.x, pt.y );
307f16e8
RR
311}
312
ed673c6a
RR
313void MyCanvas::OnAddButton( wxCommandEvent &WXUNUSED(event) )
314{
4693b20c 315 wxLogMessage( wxT("Inserting button at position 10,70...") );
2b5f62a0 316 wxButton *button = new wxButton( this, ID_NEWBUTTON, wxT("new button"), wxPoint(10,70), wxSize(80,25) );
bf0c00c6 317 wxPoint pt( button->GetPosition() );
4693b20c 318 wxLogMessage( wxT("-> Position after inserting %d %d"), pt.x, pt.y );
ed673c6a
RR
319}
320
256b8649 321void MyCanvas::OnDeleteButton( wxCommandEvent &WXUNUSED(event) )
ed673c6a 322{
4693b20c 323 wxLogMessage( wxT("Deleting button inserted with \"Add button\"...") );
ed673c6a
RR
324 wxWindow *win = FindWindow( ID_NEWBUTTON );
325 if (win)
326 win->Destroy();
327 else
4693b20c 328 wxLogMessage( wxT("-> No window with id = ID_NEWBUTTON found.") );
ed673c6a
RR
329}
330
331void MyCanvas::OnMoveButton( wxCommandEvent &event )
332{
4693b20c 333 wxLogMessage( wxT("Moving button 10 pixels downward..") );
ed673c6a 334 wxWindow *win = FindWindow( event.GetId() );
bf0c00c6 335 wxPoint pt( win->GetPosition() );
4693b20c 336 wxLogMessage( wxT("-> Position before move is %d %d"), pt.x, pt.y );
b62ca03d 337 win->Move( wxDefaultPosition.x, pt.y + 10 );
bf0c00c6 338 pt = win->GetPosition();
4693b20c 339 wxLogMessage( wxT("-> Position after move is %d %d"), pt.x, pt.y );
ed673c6a
RR
340}
341
342void MyCanvas::OnScrollWin( wxCommandEvent &WXUNUSED(event) )
343{
4693b20c 344 wxLogMessage( wxT("Scrolling 2 units up.\nThe white square and the controls should move equally!") );
ed673c6a 345 int x,y;
8073eb40 346 GetViewStart( &x, &y );
ed673c6a
RR
347 Scroll( -1, y+2 );
348}
349
2b5f62a0
VZ
350// MyAutoScrollWindow
351
352const long ID_RESIZEBUTTON = wxNewId();
353const wxSize SMALL_BUTTON( 100, 50 );
354const wxSize LARGE_BUTTON( 300, 100 );
355
356BEGIN_EVENT_TABLE( MyAutoScrollWindow, wxScrolledWindow)
357 EVT_BUTTON( ID_RESIZEBUTTON, MyAutoScrollWindow::OnResizeClick)
358END_EVENT_TABLE()
359
360MyAutoScrollWindow::MyAutoScrollWindow( wxWindow *parent )
361 : wxScrolledWindow( parent )
362{
363 SetBackgroundColour( wxT("GREEN") );
364
365 // Set the rate we'd like for scrolling.
366
367 SetScrollRate( 5, 5 );
368
369 // Populate a sizer with a 'resizing' button and some
370 // other static decoration
371
372 wxFlexGridSizer *innersizer = new wxFlexGridSizer( 2, 2 );
373
374 m_button = new wxButton( this,
375 ID_RESIZEBUTTON,
376 _T("Press me"),
377 wxDefaultPosition,
378 SMALL_BUTTON );
379
380 // We need to do this here, because wxADJUST_MINSIZE below
381 // will cause the initial size to be ignored for Best/Min size.
382 // It would be nice to fix the sizers to handle this a little
383 // more cleanly.
384
385 m_button->SetSizeHints( SMALL_BUTTON.GetWidth(), SMALL_BUTTON.GetHeight() );
386
387 innersizer->Add( m_button,
388 0,
389 wxALIGN_CENTER | wxALL | wxADJUST_MINSIZE,
390 20 );
391
b62ca03d 392 innersizer->Add( new wxStaticText( this, wxID_ANY, _T("This is just") ),
2b5f62a0
VZ
393 0,
394 wxALIGN_CENTER );
395
b62ca03d 396 innersizer->Add( new wxStaticText( this, wxID_ANY, _T("some decoration") ),
2b5f62a0
VZ
397 0,
398 wxALIGN_CENTER );
399
b62ca03d 400 innersizer->Add( new wxStaticText( this, wxID_ANY, _T("for you to scroll...") ),
2b5f62a0
VZ
401 0,
402 wxALIGN_CENTER );
403
404 // Then use the sizer to set the scrolled region size.
405
406 SetSizer( innersizer );
407}
408
409void MyAutoScrollWindow::OnResizeClick( wxCommandEvent &WXUNUSED( event ) )
410{
411 // Arbitrarily resize the button to change the minimum size of
412 // the (scrolled) sizer.
413
414 if( m_button->GetSize() == SMALL_BUTTON )
415 m_button->SetSizeHints( LARGE_BUTTON.GetWidth(), LARGE_BUTTON.GetHeight() );
416 else
417 m_button->SetSizeHints( SMALL_BUTTON.GetWidth(), SMALL_BUTTON.GetHeight() );
418
419 // Force update layout and scrollbars, since nothing we do here
420 // necessarily generates a size event which would do it for us.
421
422 FitInside();
423}
424
fdd3ed7a
RR
425// MyFrame
426
2b5f62a0
VZ
427const long ID_QUIT = wxNewId();
428const long ID_ABOUT = wxNewId();
429const long ID_DELETE_ALL = wxNewId();
430const long ID_INSERT_NEW = wxNewId();
fdd3ed7a
RR
431
432IMPLEMENT_DYNAMIC_CLASS( MyFrame, wxFrame )
433
434BEGIN_EVENT_TABLE(MyFrame,wxFrame)
8e217128
RR
435 EVT_MENU (ID_DELETE_ALL, MyFrame::OnDeleteAll)
436 EVT_MENU (ID_INSERT_NEW, MyFrame::OnInsertNew)
fdd3ed7a
RR
437 EVT_MENU (ID_ABOUT, MyFrame::OnAbout)
438 EVT_MENU (ID_QUIT, MyFrame::OnQuit)
439END_EVENT_TABLE()
440
441MyFrame::MyFrame()
b62ca03d 442 : wxFrame( (wxFrame *)NULL, wxID_ANY, _T("wxScrolledWindow sample"),
ed673c6a 443 wxPoint(20,20), wxSize(470,500) )
fdd3ed7a 444{
ed673c6a 445 wxMenu *file_menu = new wxMenu();
2b5f62a0
VZ
446 file_menu->Append( ID_DELETE_ALL, _T("Delete all"));
447 file_menu->Append( ID_INSERT_NEW, _T("Insert new"));
448 file_menu->Append( ID_ABOUT, _T("&About.."));
449 file_menu->Append( ID_QUIT, _T("E&xit\tAlt-X"));
fdd3ed7a 450
ed673c6a 451 wxMenuBar *menu_bar = new wxMenuBar();
2b5f62a0 452 menu_bar->Append(file_menu, _T("&File"));
fdd3ed7a 453
ed673c6a 454 SetMenuBar( menu_bar );
fdd3ed7a 455
ed673c6a
RR
456 CreateStatusBar(2);
457 int widths[] = { -1, 100 };
458 SetStatusWidths( 2, widths );
fdd3ed7a 459
2b5f62a0
VZ
460 wxBoxSizer *topsizer = new wxBoxSizer( wxVERTICAL );
461
462 // Setting an explicit size here is superfluous, it will be overridden
463 // by the sizer in any case.
b62ca03d 464 m_canvas = new MyCanvas( this, wxID_ANY, wxPoint(0,0), wxSize(100,100) );
8a73bf3d 465
2b5f62a0
VZ
466 // This is done with ScrollRate/VirtualSize in MyCanvas ctor now,
467 // both should produce identical results.
468 //m_canvas->SetScrollbars( 10, 10, 50, 100 );
aa06a8fd 469
ed673c6a 470 topsizer->Add( m_canvas, 1, wxEXPAND );
2b5f62a0 471 topsizer->Add( new MyAutoScrollWindow( this ), 1, wxEXPAND );
8a73bf3d
VZ
472
473 wxSizer *sizerBtm = new wxBoxSizer(wxHORIZONTAL);
474 sizerBtm->Add( new MyScrolledWindowDumb(this), 1, wxEXPAND );
475 sizerBtm->Add( new MyScrolledWindowSmart(this), 1, wxEXPAND );
476 topsizer->Add( sizerBtm, 1, wxEXPAND );
ed673c6a 477
ed673c6a 478 SetSizer( topsizer );
fdd3ed7a
RR
479}
480
8e217128
RR
481void MyFrame::OnDeleteAll( wxCommandEvent &WXUNUSED(event) )
482{
483 m_canvas->DestroyChildren();
484}
485
486void MyFrame::OnInsertNew( wxCommandEvent &WXUNUSED(event) )
487{
b62ca03d 488 (void)new wxButton( m_canvas, wxID_ANY, _T("Hello"), wxPoint(100,100) );
8e217128
RR
489}
490
fdd3ed7a
RR
491void MyFrame::OnQuit( wxCommandEvent &WXUNUSED(event) )
492{
b62ca03d 493 Close( true );
fdd3ed7a
RR
494}
495
496void MyFrame::OnAbout( wxCommandEvent &WXUNUSED(event) )
497{
b62ca03d
WS
498 (void)wxMessageBox( _T("wxScroll demo\n")
499 _T("Robert Roebling (c) 1998\n")
500 _T("Autoscrolling examples\n")
501 _T("Ron Lee (c) 2002"),
2b5f62a0
VZ
502 _T("About wxScroll Demo"),
503 wxICON_INFORMATION | wxOK );
fdd3ed7a
RR
504}
505
506//-----------------------------------------------------------------------------
507// MyApp
508//-----------------------------------------------------------------------------
509
510bool MyApp::OnInit()
511{
512 wxFrame *frame = new MyFrame();
b62ca03d 513 frame->Show( true );
fdd3ed7a 514
b62ca03d 515 return true;
fdd3ed7a
RR
516}
517
8a73bf3d
VZ
518// ----------------------------------------------------------------------------
519// MyScrolledWindowXXX
520// ----------------------------------------------------------------------------
521
8a73bf3d
VZ
522void MyScrolledWindowDumb::OnDraw(wxDC& dc)
523{
524 // this is useful to see which lines are redrawn
525 static size_t s_redrawCount = 0;
526 dc.SetTextForeground(s_redrawCount++ % 2 ? *wxRED : *wxBLUE);
527
528 wxCoord y = 0;
529 for ( size_t line = 0; line < m_nLines; line++ )
530 {
531 wxCoord yPhys;
532 CalcScrolledPosition(0, y, NULL, &yPhys);
533
534 dc.DrawText(wxString::Format(_T("Line %u (logical %d, physical %d)"),
535 line, y, yPhys), 0, y);
536 y += m_hLine;
537 }
538}
539
540void MyScrolledWindowSmart::OnDraw(wxDC& dc)
541{
542 // this is useful to see which lines are redrawn
543 static size_t s_redrawCount = 0;
544 dc.SetTextForeground(s_redrawCount++ % 2 ? *wxRED : *wxBLUE);
545
546 // update region is always in device coords, translate to logical ones
547 wxRect rectUpdate = GetUpdateRegion().GetBox();
548 CalcUnscrolledPosition(rectUpdate.x, rectUpdate.y,
549 &rectUpdate.x, &rectUpdate.y);
550
551 size_t lineFrom = rectUpdate.y / m_hLine,
552 lineTo = rectUpdate.GetBottom() / m_hLine;
553
554 if ( lineTo > m_nLines - 1)
555 lineTo = m_nLines - 1;
556
557 wxCoord y = lineFrom*m_hLine;
558 for ( size_t line = lineFrom; line <= lineTo; line++ )
559 {
560 wxCoord yPhys;
561 CalcScrolledPosition(0, y, NULL, &yPhys);
562
563 dc.DrawText(wxString::Format(_T("Line %u (logical %d, physical %d)"),
564 line, y, yPhys), 0, y);
565 y += m_hLine;
566 }
567}