]> git.saurik.com Git - wxWidgets.git/blame - samples/vscroll/vstest.cpp
allowing the suppression of SetValue event-triggering (needed for composite controls)
[wxWidgets.git] / samples / vscroll / vstest.cpp
CommitLineData
cf7d6329 1/////////////////////////////////////////////////////////////////////////////
cb7d7375 2// Name: samples/vscroll/vstest.cpp
be5a51fb 3// Purpose: VScroll wxWidgets sample
cf7d6329 4// Author: Vadim Zeitlin
d77836e4 5// Modified by: Brad Anderson
cf7d6329
VZ
6// Created: 04/01/98
7// RCS-ID: $Id$
be5a51fb 8// Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwidgets.org>
cf7d6329
VZ
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx/wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27// for all others, include the necessary headers (this file is usually all you
be5a51fb 28// need because it includes almost all "standard" wxWidgets headers)
cf7d6329 29#ifndef WX_PRECOMP
dacaa6f1 30 #include "wx/wx.h"
cf7d6329
VZ
31 #include "wx/app.h"
32 #include "wx/frame.h"
33#endif
34
35// we need to include the headers not included from wx/wx.h explicitly anyhow
36#include "wx/vscroll.h"
37
38// ----------------------------------------------------------------------------
39// resources
40// ----------------------------------------------------------------------------
41
42// the application icon (under Windows and OS/2 it is in resources)
cb7d7375 43#if !defined(__WXMSW__) && !defined(__WXPM__)
96ed08f7 44 #include "../sample.xpm"
cf7d6329
VZ
45#endif
46
d77836e4
RR
47// ----------------------------------------------------------------------------
48// definitions
49// ----------------------------------------------------------------------------
50
51#define MAX_LINES 200
52
cf7d6329
VZ
53// ----------------------------------------------------------------------------
54// private classes
55// ----------------------------------------------------------------------------
56
57// Define a new application type, each program should derive a class from wxApp
d77836e4 58class VarScrollApp : public wxApp
cf7d6329
VZ
59{
60public:
61 // create our main window
62 virtual bool OnInit();
63};
64
65// Define a new frame type: this is going to be our main frame
d77836e4 66class VarScrollFrame : public wxFrame
cf7d6329
VZ
67{
68public:
69 // ctor
d77836e4 70 VarScrollFrame();
cf7d6329
VZ
71
72 // event handlers (these functions should _not_ be virtual)
73 void OnQuit(wxCommandEvent& event);
d77836e4
RR
74 void OnModeVScroll(wxCommandEvent& event);
75 void OnModeHVScroll(wxCommandEvent& event);
cf7d6329
VZ
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();
87728739 85 SetStatusText(wxString::Format(_T("%dx%d"), sz.x, sz.y), 1);
cf7d6329
VZ
86 }
87#endif // wxUSE_STATUSBAR
88
89 event.Skip();
90 }
91
92private:
be5a51fb 93 // any class wishing to process wxWidgets events must use this macro
cf7d6329 94 DECLARE_EVENT_TABLE()
d77836e4
RR
95
96 // either a wxVScrolledWindow or a wxHVScrolled window, depending on current mode
97 wxPanel *m_scrollWindow;
cf7d6329
VZ
98};
99
100class VScrollWindow : public wxVScrolledWindow
101{
102public:
540a08d2 103 VScrollWindow(wxFrame *frame) : wxVScrolledWindow(frame, wxID_ANY)
cf7d6329
VZ
104 {
105 m_frame = frame;
106
d77836e4 107 SetLineCount(MAX_LINES);
cf7d6329 108
d77836e4
RR
109 int i;
110 for ( i = 0; i < MAX_LINES; ++i )
111 m_heights[i] = rand()%25+16; // low: 15; high: 40
112
cf7d6329
VZ
113 m_changed = true;
114 }
115
116 void OnIdle(wxIdleEvent&)
117 {
8520f137 118#if wxUSE_STATUSBAR
cf7d6329
VZ
119 m_frame->SetStatusText(wxString::Format
120 (
87728739 121 _T("Page size = %d, pos = %d, max = %d"),
cf7d6329
VZ
122 GetScrollThumb(wxVERTICAL),
123 GetScrollPos(wxVERTICAL),
124 GetScrollRange(wxVERTICAL)
125 ));
8520f137 126#endif // wxUSE_STATUSBAR
cf7d6329
VZ
127 m_changed = false;
128 }
129
130 void OnPaint(wxPaintEvent&)
131 {
132 wxPaintDC dc(this);
133
d77836e4 134 dc.SetPen(*wxBLACK_PEN);
cf7d6329 135
d77836e4
RR
136 const size_t lineFirst = GetVisibleBegin(),
137 lineLast = GetVisibleEnd();
cf7d6329
VZ
138
139 const wxCoord hText = dc.GetCharHeight();
140
d77836e4
RR
141 wxSize clientSize = GetClientSize();
142
cf7d6329 143 wxCoord y = 0;
d77836e4 144 for ( size_t line = lineFirst; line < lineLast; line++ )
cf7d6329 145 {
d77836e4 146 dc.DrawLine(0, y, clientSize.GetWidth(), y);
cf7d6329
VZ
147
148 wxCoord hLine = OnGetLineHeight(line);
149 dc.DrawText(wxString::Format(_T("Line %lu"), (unsigned long)line),
d77836e4 150 2, y + (hLine - hText) / 2);
cf7d6329
VZ
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
165 virtual wxCoord OnGetLineHeight(size_t n) const
166 {
167 wxASSERT( n < GetLineCount() );
168
d77836e4 169 return m_heights[n];
cf7d6329
VZ
170 }
171
172private:
173 wxFrame *m_frame;
174
d77836e4
RR
175 int m_heights[MAX_LINES];
176
cf7d6329
VZ
177 bool m_changed;
178
179 DECLARE_EVENT_TABLE()
180};
181
182BEGIN_EVENT_TABLE(VScrollWindow, wxVScrolledWindow)
183 EVT_IDLE(VScrollWindow::OnIdle)
184 EVT_PAINT(VScrollWindow::OnPaint)
185 EVT_SCROLLWIN(VScrollWindow::OnScroll)
186END_EVENT_TABLE()
187
d77836e4
RR
188class HVScrollWindow : public wxHVScrolledWindow
189{
190public:
191 HVScrollWindow(wxFrame *frame) : wxHVScrolledWindow(frame, wxID_ANY)
192 {
193 m_frame = frame;
194
195 SetRowColumnCounts(MAX_LINES, MAX_LINES);
196
197 int i;
198 for ( i = 0; i < MAX_LINES; ++i )
199 {
200 m_heights[i] = rand()%30+31; // low: 30; high: 60
201 m_widths[i] = rand()%30+61; // low: 60; high: 90
202 }
203
204 m_changed = true;
205 }
206
207 void OnIdle(wxIdleEvent&)
208 {
209#if wxUSE_STATUSBAR
210 m_frame->SetStatusText(wxString::Format
211 (
212 _T("Page size = %d rows %d columns; pos = row: %d, column: %d; max = %d rows, %d columns"),
213 GetScrollThumb(wxVERTICAL),
214 GetScrollThumb(wxHORIZONTAL),
215 GetScrollPos(wxVERTICAL),
216 GetScrollPos(wxHORIZONTAL),
217 GetScrollRange(wxVERTICAL),
218 GetScrollRange(wxHORIZONTAL)
219 ));
220#endif // wxUSE_STATUSBAR
221 m_changed = false;
222 }
223
224 void OnPaint(wxPaintEvent&)
225 {
226 wxPaintDC dc(this);
227
228 dc.SetPen(*wxBLACK_PEN);
229
230 const size_t rowFirst = GetVisibleRowsBegin(),
231 rowLast = GetVisibleRowsEnd();
232 const size_t columnFirst = GetVisibleColumnsBegin(),
233 columnLast = GetVisibleColumnsEnd();
234
235 const wxCoord hText = dc.GetCharHeight();
236
237 wxSize clientSize = GetClientSize();
238
239 wxCoord y = 0;
240 wxCoord x = 0;
241 for ( size_t row = rowFirst; row < rowLast; row++ )
242 {
243 wxCoord rowHeight = OnGetRowHeight(row);
244 dc.DrawLine(0, y, clientSize.GetWidth(), y);
245
246 x = 0;
247 for ( size_t col = columnFirst; col < columnLast; col++ )
248 {
249 wxCoord colWidth = OnGetColumnWidth(col);
250
251 if ( row == rowFirst )
252 dc.DrawLine(x, 0, x, clientSize.GetHeight());
253
254 dc.DrawText(wxString::Format(_T("Row %lu"), (unsigned long)row),
255 x + 2, y + rowHeight / 2 - hText);
256 dc.DrawText(wxString::Format(_T("Col %lu"), (unsigned long)col),
257 x + 2, y + rowHeight / 2);
258
259 x += colWidth;
260 if ( row == rowFirst)
261 dc.DrawLine(x, 0, x, clientSize.GetHeight());
262 }
263
264 y += rowHeight;
265 dc.DrawLine(0, y, clientSize.GetWidth(), y);
266 }
267 }
268
269 void OnScroll(wxScrollWinEvent& event)
270 {
271 m_changed = true;
272
273 event.Skip();
274 }
275
276
277 virtual wxCoord OnGetRowHeight(size_t n) const
278 {
279 wxASSERT( n < GetRowCount() );
280
281 return m_heights[n];
282 }
283
284 virtual wxCoord OnGetColumnWidth(size_t n) const
285 {
286 wxASSERT( n < GetColumnCount() );
287
288 return m_widths[n];
289 }
290
291private:
292 wxFrame *m_frame;
293
294 int m_heights[MAX_LINES];
295 int m_widths[MAX_LINES];
296
297 bool m_changed;
298
299 DECLARE_EVENT_TABLE()
300};
301
302BEGIN_EVENT_TABLE(HVScrollWindow, wxHVScrolledWindow)
303 EVT_IDLE(HVScrollWindow::OnIdle)
304 EVT_PAINT(HVScrollWindow::OnPaint)
305 EVT_SCROLLWIN(HVScrollWindow::OnScroll)
306END_EVENT_TABLE()
307
cf7d6329
VZ
308// ----------------------------------------------------------------------------
309// constants
310// ----------------------------------------------------------------------------
311
312// IDs for the controls and the menu commands
313enum
314{
315 // menu items
91b07357 316 VScroll_Quit = wxID_EXIT,
cf7d6329
VZ
317
318 // it is important for the id corresponding to the "About" command to have
319 // this standard value as otherwise it won't be handled properly under Mac
320 // (where it is special and put into the "Apple" menu)
d77836e4
RR
321 VScroll_About = wxID_ABOUT,
322
323 VScroll_VScrollMode = wxID_HIGHEST + 1,
324 VScroll_HVScrollMode
cf7d6329
VZ
325};
326
327// ----------------------------------------------------------------------------
be5a51fb 328// event tables and other macros for wxWidgets
cf7d6329
VZ
329// ----------------------------------------------------------------------------
330
be5a51fb 331// the event tables connect the wxWidgets events with the functions (event
cf7d6329
VZ
332// handlers) which process them. It can be also done at run-time, but for the
333// simple menu events like this the static method is much simpler.
d77836e4
RR
334BEGIN_EVENT_TABLE(VarScrollFrame, wxFrame)
335 EVT_MENU(VScroll_Quit, VarScrollFrame::OnQuit)
336 EVT_MENU(VScroll_VScrollMode, VarScrollFrame::OnModeVScroll)
337 EVT_MENU(VScroll_HVScrollMode, VarScrollFrame::OnModeHVScroll)
338 EVT_MENU(VScroll_About, VarScrollFrame::OnAbout)
339 EVT_SIZE(VarScrollFrame::OnSize)
cf7d6329
VZ
340END_EVENT_TABLE()
341
be5a51fb 342// Create a new application object: this macro will allow wxWidgets to create
cf7d6329
VZ
343// the application object during program execution (it's better than using a
344// static object for many reasons) and also declares the accessor function
d77836e4 345// wxGetApp() which will return the reference of the right type (i.e. VarScrollApp and
cf7d6329 346// not wxApp)
d77836e4 347IMPLEMENT_APP(VarScrollApp)
cf7d6329
VZ
348
349// ============================================================================
350// implementation
351// ============================================================================
352
353// ----------------------------------------------------------------------------
354// the application class
355// ----------------------------------------------------------------------------
356
357// 'Main program' equivalent: the program execution "starts" here
d77836e4 358bool VarScrollApp::OnInit()
cf7d6329
VZ
359{
360 // create the main application window
d77836e4 361 VarScrollFrame *frame = new VarScrollFrame;
cf7d6329
VZ
362
363 // and show it (the frames, unlike simple controls, are not shown when
364 // created initially)
540a08d2 365 frame->Show(true);
cf7d6329
VZ
366
367 // ok
540a08d2 368 return true;
cf7d6329
VZ
369}
370
371// ----------------------------------------------------------------------------
372// main frame
373// ----------------------------------------------------------------------------
374
375// frame constructor
d77836e4
RR
376VarScrollFrame::VarScrollFrame()
377 : wxFrame(NULL,
378 wxID_ANY,
379 _T("VScroll wxWidgets Sample"),
380 wxDefaultPosition,
381 wxSize(400, 350)),
382 m_scrollWindow(NULL)
cf7d6329
VZ
383{
384 // set the frame icon
96ed08f7 385 SetIcon(wxICON(sample));
cf7d6329
VZ
386
387#if wxUSE_MENUS
388 // create a menu bar
389 wxMenu *menuFile = new wxMenu;
390
d77836e4
RR
391 wxMenu *menuMode = new wxMenu;
392
cf7d6329
VZ
393 // the "About" item should be in the help menu
394 wxMenu *menuHelp = new wxMenu;
395 menuHelp->Append(VScroll_About, _T("&About...\tF1"), _T("Show about dialog"));
396
d77836e4
RR
397#ifdef wxHAS_RADIO_MENU_ITEMS
398 menuMode->AppendRadioItem(VScroll_VScrollMode, _T("&Vertical\tAlt-V"),
399 _T("Vertical scrolling only"));
400 menuMode->AppendRadioItem(VScroll_HVScrollMode,
401 _T("&Horizontal/Vertical\tAlt-H"),
402 _T("Horizontal and vertical scrolling"));
403 menuMode->Check(VScroll_VScrollMode, true);
404#else
405 menuMode->Append(VScroll_VScrollMode, _T("&Vertical\tAlt-V"),
406 _T("Vertical scrolling only"));
407 menuMode->Append(VScroll_HVScrollMode, _T("&Horizontal/Vertical\tAlt-H"),
408 _T("Horizontal and vertical scrolling"));
409#endif
410
cf7d6329
VZ
411 menuFile->Append(VScroll_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
412
413 // now append the freshly created menu to the menu bar...
414 wxMenuBar *menuBar = new wxMenuBar;
415 menuBar->Append(menuFile, _T("&File"));
d77836e4 416 menuBar->Append(menuMode, _T("&Mode"));
cf7d6329
VZ
417 menuBar->Append(menuHelp, _T("&Help"));
418
419 // ... and attach this menu bar to the frame
420 SetMenuBar(menuBar);
421#endif // wxUSE_MENUS
422
423#if wxUSE_STATUSBAR
424 // create a status bar just for fun (by default with 1 pane only)
425 CreateStatusBar(2);
be5a51fb 426 SetStatusText(_T("Welcome to wxWidgets!"));
d77836e4
RR
427 int widths[2];
428 widths[0] = -1;
429 widths[1] = 100;
430 SetStatusWidths(2, widths);
cf7d6329
VZ
431#endif // wxUSE_STATUSBAR
432
433 // create our one and only child -- it will take our entire client area
d77836e4
RR
434 if ( menuMode->IsChecked(VScroll_VScrollMode) )
435 m_scrollWindow = new VScrollWindow(this);
436 else if ( menuMode->IsChecked(VScroll_VScrollMode) )
437 m_scrollWindow = new HVScrollWindow(this);
cf7d6329
VZ
438}
439
440// ----------------------------------------------------------------------------
441// event handlers
442// ----------------------------------------------------------------------------
443
d77836e4 444void VarScrollFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
cf7d6329 445{
540a08d2
WS
446 // true is to force the frame to close
447 Close(true);
cf7d6329
VZ
448}
449
d77836e4
RR
450void VarScrollFrame::OnModeVScroll(wxCommandEvent& WXUNUSED(event))
451{
452 if ( m_scrollWindow )
453 m_scrollWindow->Destroy();
454
455 m_scrollWindow = new VScrollWindow(this);
456 SendSizeEvent();
457}
458
459void VarScrollFrame::OnModeHVScroll(wxCommandEvent& WXUNUSED(event))
460{
461 if ( m_scrollWindow )
462 m_scrollWindow->Destroy();
463
464 m_scrollWindow = new HVScrollWindow(this);
465 SendSizeEvent();
466}
467
468void VarScrollFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
cf7d6329
VZ
469{
470 wxMessageBox(_T("VScroll shows how to implement scrolling with\n")
d77836e4 471 _T("variable line widths and heights.\n")
749bfe9a 472 _T("(c) 2003 Vadim Zeitlin"),
cf7d6329
VZ
473 _T("About VScroll"),
474 wxOK | wxICON_INFORMATION,
475 this);
476}