new sample: statbar
[wxWidgets.git] / samples / statbar / statbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: statbar.cpp
3 // Purpose: wxStatusBar sample
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 04.02.00
7 // RCS-ID: $Id$
8 // Copyright: (c) Vadim Zeitlin
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "statbar.cpp"
22 #pragma interface "statbar.cpp"
23 #endif
24
25 // For compilers that support precompilation, includes "wx/wx.h".
26 #include "wx/wxprec.h"
27
28 #ifdef __BORLANDC__
29 #pragma hdrstop
30 #endif
31
32 #if !wxUSE_STATUSBAR
33 #error "You need to set wxUSE_STATUSBAR to 1 to compile this sample"
34 #endif // wxUSE_STATUSBAR
35
36 // for all others, include the necessary headers (this file is usually all you
37 // need because it includes almost all "standard" wxWindows headers
38 #ifndef WX_PRECOMP
39 #include "wx/app.h"
40 #include "wx/frame.h"
41 #include "wx/statusbr.h"
42 #include "wx/datetime.h"
43 #include "wx/timer.h"
44 #include "wx/checkbox.h"
45 #include "wx/statbmp.h"
46 #include "wx/menu.h"
47 #include "wx/msgdlg.h"
48 #endif
49
50 // ----------------------------------------------------------------------------
51 // resources
52 // ----------------------------------------------------------------------------
53
54 #include "green.xpm"
55 #include "red.xpm"
56
57 // ----------------------------------------------------------------------------
58 // private classes
59 // ----------------------------------------------------------------------------
60
61 // Define a new application type, each program should derive a class from wxApp
62 class MyApp : public wxApp
63 {
64 public:
65 // override base class virtuals
66 // ----------------------------
67
68 // this one is called on application startup and is a good place for the app
69 // initialization (doing it here and not in the ctor allows to have an error
70 // return: if OnInit() returns false, the application terminates)
71 virtual bool OnInit();
72 };
73
74 // A custom status bar which contains controls, icons &c
75 class MyStatusBar : public wxStatusBar
76 {
77 public:
78 MyStatusBar(wxWindow *parent);
79 virtual ~MyStatusBar();
80
81 void UpdateClock();
82
83 // event handlers
84 void OnSize(wxSizeEvent& event);
85 void OnToggleClock(wxCommandEvent& event);
86
87 private:
88 enum
89 {
90 Field_Text,
91 Field_Checkbox,
92 Field_Bitmap,
93 Field_Clock,
94 Field_Max
95 };
96
97 class MyTimer : public wxTimer
98 {
99 public:
100 MyTimer(MyStatusBar *statbar) {m_statbar = statbar; }
101
102 virtual void Notify() { m_statbar->UpdateClock(); }
103
104 private:
105 MyStatusBar *m_statbar;
106 } m_timer;
107
108 wxCheckBox *m_checkbox;
109 wxStaticBitmap *m_statbmp;
110
111 DECLARE_EVENT_TABLE()
112 };
113
114 // Define a new frame type: this is going to be our main frame
115 class MyFrame : public wxFrame
116 {
117 public:
118 // ctor(s)
119 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
120 virtual ~MyFrame();
121
122 // event handlers (these functions should _not_ be virtual)
123 void OnQuit(wxCommandEvent& event);
124 void OnAbout(wxCommandEvent& event);
125 void OnRecreateStatusBar(wxCommandEvent& event);
126
127 private:
128 enum StatBarKind
129 {
130 StatBar_Default,
131 StatBar_Custom,
132 StatBar_Max
133 } m_statbarKind;
134
135 void DoCreateStatusBar(StatBarKind kind);
136
137 wxStatusBar *m_statbarDefault;
138 MyStatusBar *m_statbarCustom;
139
140 // any class wishing to process wxWindows events must use this macro
141 DECLARE_EVENT_TABLE()
142 };
143
144 // ----------------------------------------------------------------------------
145 // constants
146 // ----------------------------------------------------------------------------
147
148 // IDs for the controls and the menu commands
149 enum
150 {
151 // menu items
152 StatusBar_Quit = 1,
153 StatusBar_Recreate,
154 StatusBar_About,
155 StatusBar_Checkbox = 1000
156 };
157
158 static const int BITMAP_SIZE_X = 32;
159 static const int BITMAP_SIZE_Y = 15;
160
161 // ----------------------------------------------------------------------------
162 // event tables and other macros for wxWindows
163 // ----------------------------------------------------------------------------
164
165 // the event tables connect the wxWindows events with the functions (event
166 // handlers) which process them. It can be also done at run-time, but for the
167 // simple menu events like this the static method is much simpler.
168 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
169 EVT_MENU(StatusBar_Quit, MyFrame::OnQuit)
170 EVT_MENU(StatusBar_Recreate, MyFrame::OnRecreateStatusBar)
171 EVT_MENU(StatusBar_About, MyFrame::OnAbout)
172 END_EVENT_TABLE()
173
174 BEGIN_EVENT_TABLE(MyStatusBar, wxStatusBar)
175 EVT_SIZE(MyStatusBar::OnSize)
176 EVT_CHECKBOX(StatusBar_Checkbox, MyStatusBar::OnToggleClock)
177 END_EVENT_TABLE()
178
179 // Create a new application object: this macro will allow wxWindows to create
180 // the application object during program execution (it's better than using a
181 // static object for many reasons) and also declares the accessor function
182 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
183 // not wxApp)
184 IMPLEMENT_APP(MyApp)
185
186 // ============================================================================
187 // implementation
188 // ============================================================================
189
190 // ----------------------------------------------------------------------------
191 // the application class
192 // ----------------------------------------------------------------------------
193
194 // `Main program' equivalent: the program execution "starts" here
195 bool MyApp::OnInit()
196 {
197 // create the main application window
198 MyFrame *frame = new MyFrame("wxStatusBar sample",
199 wxPoint(50, 50), wxSize(450, 340));
200
201 // and show it (the frames, unlike simple controls, are not shown when
202 // created initially)
203 frame->Show(TRUE);
204
205 // success: wxApp::OnRun() will be called which will enter the main message
206 // loop and the application will run. If we returned FALSE here, the
207 // application would exit immediately.
208 return TRUE;
209 }
210
211 // ----------------------------------------------------------------------------
212 // main frame
213 // ----------------------------------------------------------------------------
214
215 // frame constructor
216 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
217 : wxFrame((wxFrame *)NULL, -1, title, pos, size)
218 {
219 m_statbarDefault = NULL;
220 m_statbarCustom = NULL;
221
222 #ifdef __WXMAC__
223 // we need this in order to allow the about menu relocation, since ABOUT is
224 // not the default id of the about menu
225 wxApp::s_macAboutMenuItemId = StatusBar_About;
226 #endif
227
228 // create a menu bar
229 wxMenu *menuFile = new wxMenu;
230 menuFile->Append(StatusBar_Quit, "E&xit\tAlt-X", "Quit this program");
231
232 wxMenu *statbarMenu = new wxMenu;
233 statbarMenu->Append(StatusBar_Recreate, "&Recreate\tCtrl-R",
234 "Toggle status bar format");
235
236 wxMenu *helpMenu = new wxMenu;
237 helpMenu->Append(StatusBar_About, "&About...\tCtrl-A", "Show about dialog");
238
239 // now append the freshly created menu to the menu bar...
240 wxMenuBar *menuBar = new wxMenuBar();
241 menuBar->Append(menuFile, "&File");
242 menuBar->Append(statbarMenu, "&Status bar");
243 menuBar->Append(helpMenu, "&Help");
244
245 // ... and attach this menu bar to the frame
246 SetMenuBar(menuBar);
247
248 // create default status bar to start with
249 CreateStatusBar(2);
250 SetStatusText("Welcome to wxWindows!");
251
252 m_statbarDefault = GetStatusBar();
253 }
254
255 MyFrame::~MyFrame()
256 {
257 SetStatusBar(NULL);
258
259 delete m_statbarDefault;
260 delete m_statbarCustom;
261 }
262
263 void MyFrame::DoCreateStatusBar(MyFrame::StatBarKind kind)
264 {
265 wxStatusBar *statbarOld = GetStatusBar();
266 if ( statbarOld )
267 {
268 statbarOld->Hide();
269 }
270
271 switch ( kind )
272 {
273 case StatBar_Default:
274 SetStatusBar(m_statbarDefault);
275 break;
276
277 case StatBar_Custom:
278 if ( !m_statbarCustom )
279 {
280 m_statbarCustom = new MyStatusBar(this);
281 }
282 SetStatusBar(m_statbarCustom);
283 break;
284
285 default:
286 wxFAIL_MSG("unknown stat bar kind");
287 }
288
289 PositionStatusBar();
290 GetStatusBar()->Show();
291
292 m_statbarKind = kind;
293 }
294
295 // event handlers
296 void MyFrame::OnRecreateStatusBar(wxCommandEvent& WXUNUSED(event))
297 {
298 DoCreateStatusBar(m_statbarKind == StatBar_Custom ? StatBar_Default
299 : StatBar_Custom);
300 }
301
302 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
303 {
304 // TRUE is to force the frame to close
305 Close(TRUE);
306 }
307
308 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
309 {
310 wxMessageBox("wxStatusBar sample\n(c) 2000 Vadim Zeitlin",
311 "About statbar", wxOK | wxICON_INFORMATION, this);
312 }
313
314 // ----------------------------------------------------------------------------
315 // MyStatusBar
316 // ----------------------------------------------------------------------------
317
318 MyStatusBar::MyStatusBar(wxWindow *parent)
319 : wxStatusBar(parent, -1), m_timer(this)
320 {
321 static const int widths[Field_Max] = { -1, 150, BITMAP_SIZE_X, 100 };
322
323 SetFieldsCount(Field_Max);
324 SetStatusWidths(Field_Max, widths);
325
326 m_checkbox = new wxCheckBox(this, StatusBar_Checkbox, _T("&Toggle clock"));
327 m_checkbox->SetValue(TRUE);
328
329 m_statbmp = new wxStaticBitmap(this, -1, wxICON(green));
330
331 m_timer.Start(1000);
332
333 UpdateClock();
334 }
335
336 MyStatusBar::~MyStatusBar()
337 {
338 if ( m_timer.IsRunning() )
339 {
340 m_timer.Stop();
341 }
342 }
343
344 void MyStatusBar::OnSize(wxSizeEvent& event)
345 {
346 wxRect rect;
347 GetFieldRect(Field_Checkbox, rect);
348
349 m_checkbox->SetSize(rect.x + 2, rect.y + 2, rect.width - 4, rect.height - 4);
350
351 GetFieldRect(Field_Bitmap, rect);
352 m_statbmp->Move(rect.x + (rect.width - BITMAP_SIZE_X) / 2,
353 rect.y + (rect.height - BITMAP_SIZE_Y) / 2);
354
355 event.Skip();
356 }
357
358 void MyStatusBar::OnToggleClock(wxCommandEvent& event)
359 {
360 if ( m_checkbox->GetValue() )
361 {
362 m_timer.Start(1000);
363
364 m_statbmp->SetIcon(wxICON(green));
365
366 UpdateClock();
367 }
368 else // don't show clock
369 {
370 m_timer.Stop();
371
372 m_statbmp->SetIcon(wxICON(red));
373
374 SetStatusText("", Field_Clock);
375 }
376 }
377
378 void MyStatusBar::UpdateClock()
379 {
380 SetStatusText(wxDateTime::Now().FormatTime(), Field_Clock);
381 }