Update OpenVMS makefile
[wxWidgets.git] / samples / vscroll / vstest.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: samples/vscroll/vstest.cpp
3 // Purpose: VScroll wxWidgets sample
4 // Author: Vadim Zeitlin
5 // Modified by: Brad Anderson
6 // Created: 04/01/98
7 // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 // for all others, include the necessary headers (this file is usually all you
27 // need because it includes almost all "standard" wxWidgets headers)
28 #ifndef WX_PRECOMP
29 #include "wx/wx.h"
30 #include "wx/app.h"
31 #include "wx/frame.h"
32 #endif
33
34 // we need to include the headers not included from wx/wx.h explicitly anyhow
35 #include "wx/vscroll.h"
36
37 // ----------------------------------------------------------------------------
38 // resources
39 // ----------------------------------------------------------------------------
40
41 // the application icon (under Windows and OS/2 it is in resources)
42 #ifndef wxHAS_IMAGES_IN_RESOURCES
43 #include "../sample.xpm"
44 #endif
45
46 // ----------------------------------------------------------------------------
47 // definitions
48 // ----------------------------------------------------------------------------
49
50 #define MAX_LINES 10000
51
52 // ----------------------------------------------------------------------------
53 // private classes
54 // ----------------------------------------------------------------------------
55
56 // Define a new application type, each program should derive a class from wxApp
57 class VarScrollApp : public wxApp
58 {
59 public:
60 // create our main window
61 virtual bool OnInit();
62 };
63
64 // Define a new frame type: this is going to be our main frame
65 class VarScrollFrame : public wxFrame
66 {
67 public:
68 // ctor
69 VarScrollFrame();
70
71 // event handlers (these functions should _not_ be virtual)
72 void OnQuit(wxCommandEvent& event);
73 void OnModeVScroll(wxCommandEvent& event);
74 void OnModeHScroll(wxCommandEvent& event);
75 void OnModeHVScroll(wxCommandEvent& event);
76 void OnAbout(wxCommandEvent& event);
77
78 void OnSize(wxSizeEvent& event)
79 {
80 // show current size in the status bar
81 #if wxUSE_STATUSBAR
82 if ( m_frameStatusBar )
83 {
84 wxSize sz = GetClientSize();
85 SetStatusText(wxString::Format(wxT("%dx%d"), sz.x, sz.y), 1);
86 }
87 #endif // wxUSE_STATUSBAR
88
89 event.Skip();
90 }
91
92 private:
93 // either a wxVScrolledWindow or a wxHVScrolled window, depending on current mode
94 wxPanel *m_scrollWindow;
95
96 // any class wishing to process wxWidgets events must use this macro
97 DECLARE_EVENT_TABLE()
98 };
99
100 class VScrollWindow : public wxVScrolledWindow
101 {
102 public:
103 VScrollWindow(wxFrame *frame) : wxVScrolledWindow(frame, wxID_ANY)
104 {
105 m_frame = frame;
106
107 SetRowCount(MAX_LINES);
108
109 int i;
110 for ( i = 0; i < MAX_LINES; ++i )
111 m_heights[i] = rand()%25+16; // low: 16; high: 40
112
113 m_changed = true;
114 }
115
116 void OnIdle(wxIdleEvent&)
117 {
118 #if wxUSE_STATUSBAR
119 m_frame->SetStatusText(wxString::Format
120 (
121 wxT("Page size = %d, pos = %d, max = %d"),
122 GetScrollThumb(wxVERTICAL),
123 GetScrollPos(wxVERTICAL),
124 GetScrollRange(wxVERTICAL)
125 ));
126 #endif // wxUSE_STATUSBAR
127 m_changed = false;
128 }
129
130 void OnPaint(wxPaintEvent&)
131 {
132 wxPaintDC dc(this);
133
134 dc.SetPen(*wxBLACK_PEN);
135
136 const size_t lineFirst = GetVisibleBegin(),
137 lineLast = GetVisibleEnd();
138
139 const wxCoord hText = dc.GetCharHeight();
140
141 wxSize clientSize = GetClientSize();
142
143 wxCoord y = 0;
144 for ( size_t line = lineFirst; line < lineLast; line++ )
145 {
146 dc.DrawLine(0, y, clientSize.GetWidth(), y);
147
148 wxCoord hLine = OnGetRowHeight(line);
149 dc.DrawText(wxString::Format(wxT("Line %lu"), (unsigned long)line),
150 2, y + (hLine - hText) / 2);
151
152 y += hLine;
153 dc.DrawLine(0, y, 1000, y);
154 }
155 }
156
157 void OnScroll(wxScrollWinEvent& event)
158 {
159 m_changed = true;
160
161 event.Skip();
162 }
163
164 void OnMouse(wxMouseEvent& event)
165 {
166 if(event.LeftDown())
167 CaptureMouse();
168 else if(event.LeftUp())
169 ReleaseMouse();
170 event.Skip();
171 }
172
173 virtual wxCoord OnGetRowHeight(size_t n) const
174 {
175 wxASSERT( n < GetRowCount() );
176
177 return m_heights[n];
178 }
179
180 private:
181 wxFrame *m_frame;
182
183 int m_heights[MAX_LINES];
184
185 bool m_changed;
186
187 DECLARE_EVENT_TABLE()
188 };
189
190 BEGIN_EVENT_TABLE(VScrollWindow, wxVScrolledWindow)
191 EVT_IDLE(VScrollWindow::OnIdle)
192 EVT_PAINT(VScrollWindow::OnPaint)
193 EVT_SCROLLWIN(VScrollWindow::OnScroll)
194 EVT_MOUSE_EVENTS(VScrollWindow::OnMouse)
195 END_EVENT_TABLE()
196
197 class HScrollWindow : public wxHScrolledWindow
198 {
199 public:
200 HScrollWindow(wxFrame *frame) : wxHScrolledWindow(frame, wxID_ANY)
201 {
202 m_frame = frame;
203
204 SetColumnCount(MAX_LINES);
205
206 int i;
207 for ( i = 0; i < MAX_LINES; ++i )
208 m_heights[i] = rand()%25+16; // low: 15; high: 40
209
210 m_changed = true;
211 }
212
213 void OnIdle(wxIdleEvent&)
214 {
215 #if wxUSE_STATUSBAR
216 m_frame->SetStatusText(wxString::Format
217 (
218 wxT("Page size = %d, pos = %d, max = %d"),
219 GetScrollThumb(wxVERTICAL),
220 GetScrollPos(wxVERTICAL),
221 GetScrollRange(wxVERTICAL)
222 ));
223 #endif // wxUSE_STATUSBAR
224 m_changed = false;
225 }
226
227 void OnPaint(wxPaintEvent&)
228 {
229 wxPaintDC dc(this);
230
231 dc.SetPen(*wxBLACK_PEN);
232
233 const size_t lineFirst = GetVisibleBegin(),
234 lineLast = GetVisibleEnd();
235
236 const wxCoord hText = dc.GetCharHeight();
237
238 wxSize clientSize = GetClientSize();
239
240 wxCoord x = 0;
241 for ( size_t line = lineFirst; line < lineLast; line++ )
242 {
243 dc.DrawLine(x, 0, x, clientSize.GetHeight());
244
245 wxCoord wLine = OnGetColumnWidth(line);
246 dc.DrawRotatedText(wxString::Format(wxT("Line %lu"), (unsigned long)line),
247 x + (wLine - hText) / 2, clientSize.GetHeight() - 5, 90);
248
249 x += wLine;
250 dc.DrawLine(x, 0, x, 1000);
251 }
252 }
253
254 void OnScroll(wxScrollWinEvent& event)
255 {
256 m_changed = true;
257
258 event.Skip();
259 }
260
261 void OnMouse(wxMouseEvent& event)
262 {
263 if(event.LeftDown())
264 CaptureMouse();
265 else if(event.LeftUp())
266 ReleaseMouse();
267 event.Skip();
268 }
269
270 virtual wxCoord OnGetColumnWidth(size_t n) const
271 {
272 wxASSERT( n < GetColumnCount() );
273
274 return m_heights[n];
275 }
276
277 private:
278 wxFrame *m_frame;
279
280 int m_heights[MAX_LINES];
281
282 bool m_changed;
283
284 DECLARE_EVENT_TABLE()
285 };
286
287 BEGIN_EVENT_TABLE(HScrollWindow, wxHScrolledWindow)
288 EVT_IDLE(HScrollWindow::OnIdle)
289 EVT_PAINT(HScrollWindow::OnPaint)
290 EVT_SCROLLWIN(HScrollWindow::OnScroll)
291 EVT_MOUSE_EVENTS(HScrollWindow::OnMouse)
292 END_EVENT_TABLE()
293
294 class HVScrollWindow : public wxHVScrolledWindow
295 {
296 public:
297 HVScrollWindow(wxFrame *frame) : wxHVScrolledWindow(frame, wxID_ANY)
298 {
299 m_frame = frame;
300
301 SetRowColumnCount(MAX_LINES, MAX_LINES);
302
303 int i;
304 for ( i = 0; i < MAX_LINES; ++i )
305 {
306 m_heights[i] = rand()%30+31; // low: 30; high: 60
307 m_widths[i] = rand()%30+61; // low: 60; high: 90
308 }
309
310 m_changed = true;
311 }
312
313 void OnIdle(wxIdleEvent&)
314 {
315 #if wxUSE_STATUSBAR
316 m_frame->SetStatusText(wxString::Format
317 (
318 wxT("Page size = %d rows %d columns; pos = row: %d, column: %d; max = %d rows, %d columns"),
319 GetScrollThumb(wxVERTICAL),
320 GetScrollThumb(wxHORIZONTAL),
321 GetScrollPos(wxVERTICAL),
322 GetScrollPos(wxHORIZONTAL),
323 GetScrollRange(wxVERTICAL),
324 GetScrollRange(wxHORIZONTAL)
325 ));
326 #endif // wxUSE_STATUSBAR
327 m_changed = false;
328 }
329
330 void OnPaint(wxPaintEvent&)
331 {
332 wxPaintDC dc(this);
333
334 dc.SetPen(*wxBLACK_PEN);
335
336 const size_t rowFirst = GetVisibleRowsBegin(),
337 rowLast = GetVisibleRowsEnd();
338 const size_t columnFirst = GetVisibleColumnsBegin(),
339 columnLast = GetVisibleColumnsEnd();
340
341 const wxCoord hText = dc.GetCharHeight();
342
343 wxSize clientSize = GetClientSize();
344
345 wxCoord y = 0;
346 wxCoord x = 0;
347 for ( size_t row = rowFirst; row < rowLast; row++ )
348 {
349 wxCoord rowHeight = OnGetRowHeight(row);
350 dc.DrawLine(0, y, clientSize.GetWidth(), y);
351
352 x = 0;
353 for ( size_t col = columnFirst; col < columnLast; col++ )
354 {
355 wxCoord colWidth = OnGetColumnWidth(col);
356
357 if ( row == rowFirst )
358 dc.DrawLine(x, 0, x, clientSize.GetHeight());
359
360 dc.DrawText(wxString::Format(wxT("Row %lu"), (unsigned long)row),
361 x + 2, y + rowHeight / 2 - hText);
362 dc.DrawText(wxString::Format(wxT("Col %lu"), (unsigned long)col),
363 x + 2, y + rowHeight / 2);
364
365 x += colWidth;
366 if ( row == rowFirst)
367 dc.DrawLine(x, 0, x, clientSize.GetHeight());
368 }
369
370 y += rowHeight;
371 dc.DrawLine(0, y, clientSize.GetWidth(), y);
372 }
373 }
374
375 void OnScroll(wxScrollWinEvent& event)
376 {
377 m_changed = true;
378
379 event.Skip();
380 }
381
382 void OnMouse(wxMouseEvent& event)
383 {
384 if(event.LeftDown())
385 CaptureMouse();
386 else if(event.LeftUp())
387 ReleaseMouse();
388 event.Skip();
389 }
390
391 virtual wxCoord OnGetRowHeight(size_t n) const
392 {
393 wxASSERT( n < GetRowCount() );
394
395 return m_heights[n];
396 }
397
398 virtual wxCoord OnGetColumnWidth(size_t n) const
399 {
400 wxASSERT( n < GetColumnCount() );
401
402 return m_widths[n];
403 }
404
405 private:
406 wxFrame *m_frame;
407
408 int m_heights[MAX_LINES];
409 int m_widths[MAX_LINES];
410
411 bool m_changed;
412
413 DECLARE_EVENT_TABLE()
414 };
415
416 BEGIN_EVENT_TABLE(HVScrollWindow, wxHVScrolledWindow)
417 EVT_IDLE(HVScrollWindow::OnIdle)
418 EVT_PAINT(HVScrollWindow::OnPaint)
419 EVT_SCROLLWIN(HVScrollWindow::OnScroll)
420 EVT_MOUSE_EVENTS(HVScrollWindow::OnMouse)
421 END_EVENT_TABLE()
422
423 // ----------------------------------------------------------------------------
424 // constants
425 // ----------------------------------------------------------------------------
426
427 // IDs for the controls and the menu commands
428 enum
429 {
430 // menu items
431 VScroll_Quit = wxID_EXIT,
432
433 // it is important for the id corresponding to the "About" command to have
434 // this standard value as otherwise it won't be handled properly under Mac
435 // (where it is special and put into the "Apple" menu)
436 VScroll_About = wxID_ABOUT,
437
438 VScroll_VScrollMode = wxID_HIGHEST + 1,
439 VScroll_HScrollMode,
440 VScroll_HVScrollMode
441 };
442
443 // ----------------------------------------------------------------------------
444 // event tables and other macros for wxWidgets
445 // ----------------------------------------------------------------------------
446
447 // the event tables connect the wxWidgets events with the functions (event
448 // handlers) which process them. It can be also done at run-time, but for the
449 // simple menu events like this the static method is much simpler.
450 BEGIN_EVENT_TABLE(VarScrollFrame, wxFrame)
451 EVT_MENU(VScroll_Quit, VarScrollFrame::OnQuit)
452 EVT_MENU(VScroll_VScrollMode, VarScrollFrame::OnModeVScroll)
453 EVT_MENU(VScroll_HScrollMode, VarScrollFrame::OnModeHScroll)
454 EVT_MENU(VScroll_HVScrollMode, VarScrollFrame::OnModeHVScroll)
455 EVT_MENU(VScroll_About, VarScrollFrame::OnAbout)
456 EVT_SIZE(VarScrollFrame::OnSize)
457 END_EVENT_TABLE()
458
459 // Create a new application object: this macro will allow wxWidgets to create
460 // the application object during program execution (it's better than using a
461 // static object for many reasons) and also declares the accessor function
462 // wxGetApp() which will return the reference of the right type (i.e. VarScrollApp and
463 // not wxApp)
464 IMPLEMENT_APP(VarScrollApp)
465
466 // ============================================================================
467 // implementation
468 // ============================================================================
469
470 // ----------------------------------------------------------------------------
471 // the application class
472 // ----------------------------------------------------------------------------
473
474 // 'Main program' equivalent: the program execution "starts" here
475 bool VarScrollApp::OnInit()
476 {
477 if ( !wxApp::OnInit() )
478 return false;
479
480 // create the main application window
481 VarScrollFrame *frame = new VarScrollFrame;
482
483 // and show it (the frames, unlike simple controls, are not shown when
484 // created initially)
485 frame->Show(true);
486
487 // ok
488 return true;
489 }
490
491 // ----------------------------------------------------------------------------
492 // main frame
493 // ----------------------------------------------------------------------------
494
495 // frame constructor
496 VarScrollFrame::VarScrollFrame()
497 : wxFrame(NULL,
498 wxID_ANY,
499 wxT("VScroll wxWidgets Sample"),
500 wxDefaultPosition,
501 wxSize(400, 350)),
502 m_scrollWindow(NULL)
503 {
504 // set the frame icon
505 SetIcon(wxICON(sample));
506
507 #if wxUSE_MENUS
508 // create a menu bar
509 wxMenu *menuFile = new wxMenu;
510
511 wxMenu *menuMode = new wxMenu;
512
513 // the "About" item should be in the help menu
514 wxMenu *menuHelp = new wxMenu;
515 menuHelp->Append(VScroll_About, wxT("&About\tF1"), wxT("Show about dialog"));
516
517 #ifdef wxHAS_RADIO_MENU_ITEMS
518 menuMode->AppendRadioItem(VScroll_VScrollMode, wxT("&Vertical\tAlt-V"),
519 wxT("Vertical scrolling only"));
520 menuMode->AppendRadioItem(VScroll_HScrollMode, wxT("&Horizontal\tAlt-H"),
521 wxT("Horizontal scrolling only"));
522 menuMode->AppendRadioItem(VScroll_HVScrollMode,
523 wxT("Hori&zontal/Vertical\tAlt-Z"),
524 wxT("Horizontal and vertical scrolling"));
525 menuMode->Check(VScroll_VScrollMode, true);
526 #else
527 menuMode->Append(VScroll_VScrollMode, wxT("&Vertical\tAlt-V"),
528 wxT("Vertical scrolling only"));
529 menuMode->Append(VScroll_HScrollMode, wxT("&Horizontal\tAlt-H"),
530 wxT("Horizontal scrolling only"));
531 menuMode->Append(VScroll_HVScrollMode, wxT("Hori&zontal/Vertical\tAlt-Z"),
532 wxT("Horizontal and vertical scrolling"));
533 #endif
534
535 menuFile->Append(VScroll_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
536
537 // now append the freshly created menu to the menu bar...
538 wxMenuBar *menuBar = new wxMenuBar;
539 menuBar->Append(menuFile, wxT("&File"));
540 menuBar->Append(menuMode, wxT("&Mode"));
541 menuBar->Append(menuHelp, wxT("&Help"));
542
543 // ... and attach this menu bar to the frame
544 SetMenuBar(menuBar);
545 #endif // wxUSE_MENUS
546
547 #if wxUSE_STATUSBAR
548 // create a status bar just for fun (by default with 1 pane only)
549 CreateStatusBar(2);
550 SetStatusText(wxT("Welcome to wxWidgets!"));
551 int widths[2];
552 widths[0] = -1;
553 widths[1] = 100;
554 SetStatusWidths(2, widths);
555 #endif // wxUSE_STATUSBAR
556
557 // create our one and only child -- it will take our entire client area
558 if ( menuMode->IsChecked(VScroll_VScrollMode) )
559 m_scrollWindow = new VScrollWindow(this);
560 else if ( menuMode->IsChecked(VScroll_HScrollMode) )
561 m_scrollWindow = new HScrollWindow(this);
562 else
563 m_scrollWindow = new HVScrollWindow(this);
564 }
565
566 // ----------------------------------------------------------------------------
567 // event handlers
568 // ----------------------------------------------------------------------------
569
570 void VarScrollFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
571 {
572 // true is to force the frame to close
573 Close(true);
574 }
575
576 void VarScrollFrame::OnModeVScroll(wxCommandEvent& WXUNUSED(event))
577 {
578 if ( m_scrollWindow )
579 m_scrollWindow->Destroy();
580
581 m_scrollWindow = new VScrollWindow(this);
582 SendSizeEvent();
583 }
584
585 void VarScrollFrame::OnModeHScroll(wxCommandEvent& WXUNUSED(event))
586 {
587 if ( m_scrollWindow )
588 m_scrollWindow->Destroy();
589
590 m_scrollWindow = new HScrollWindow(this);
591 SendSizeEvent();
592 }
593
594 void VarScrollFrame::OnModeHVScroll(wxCommandEvent& WXUNUSED(event))
595 {
596 if ( m_scrollWindow )
597 m_scrollWindow->Destroy();
598
599 m_scrollWindow = new HVScrollWindow(this);
600 SendSizeEvent();
601 }
602
603 void VarScrollFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
604 {
605 wxMessageBox(wxT("VScroll shows how to implement scrolling with\n")
606 wxT("variable line widths and heights.\n")
607 wxT("(c) 2003 Vadim Zeitlin"),
608 wxT("About VScroll"),
609 wxOK | wxICON_INFORMATION,
610 this);
611 }