1. demo of status bar at the top in 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
37 #ifndef WX_PRECOMP
38 #include "wx/app.h"
39 #include "wx/frame.h"
40 #include "wx/statusbr.h"
41 #include "wx/timer.h"
42 #include "wx/checkbox.h"
43 #include "wx/statbmp.h"
44 #include "wx/menu.h"
45 #include "wx/msgdlg.h"
46 #include "wx/textdlg.h"
47 #include "wx/sizer.h"
48 #endif
49
50 #include "wx/datetime.h"
51
52 // ----------------------------------------------------------------------------
53 // resources
54 // ----------------------------------------------------------------------------
55
56 #include "green.xpm"
57 #include "red.xpm"
58
59 // ----------------------------------------------------------------------------
60 // private classes
61 // ----------------------------------------------------------------------------
62
63 // Define a new application type, each program should derive a class from wxApp
64 class MyApp : public wxApp
65 {
66 public:
67 // override base class virtuals
68 // ----------------------------
69
70 // this one is called on application startup and is a good place for the app
71 // initialization (doing it here and not in the ctor allows to have an error
72 // return: if OnInit() returns false, the application terminates)
73 virtual bool OnInit();
74 };
75
76 // A custom status bar which contains controls, icons &c
77 class MyStatusBar : public wxStatusBar
78 {
79 public:
80 MyStatusBar(wxWindow *parent);
81 virtual ~MyStatusBar();
82
83 void UpdateClock();
84
85 // event handlers
86 void OnTimer(wxTimerEvent& event) { UpdateClock(); }
87 void OnSize(wxSizeEvent& event);
88 void OnToggleClock(wxCommandEvent& event);
89
90 private:
91 enum
92 {
93 Field_Text,
94 Field_Checkbox,
95 Field_Bitmap,
96 Field_Clock,
97 Field_Max
98 };
99
100 wxTimer m_timer;
101
102 wxCheckBox *m_checkbox;
103 wxStaticBitmap *m_statbmp;
104
105 DECLARE_EVENT_TABLE()
106 };
107
108 // Define a new frame type: this is going to be our main frame
109 class MyFrame : public wxFrame
110 {
111 public:
112 // ctor(s)
113 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
114 virtual ~MyFrame();
115
116 // event handlers (these functions should _not_ be virtual)
117 void OnQuit(wxCommandEvent& event);
118 void OnAbout(wxCommandEvent& event);
119
120 void OnSetStatusFields(wxCommandEvent& event);
121 void OnRecreateStatusBar(wxCommandEvent& event);
122
123 private:
124 enum StatBarKind
125 {
126 StatBar_Default,
127 StatBar_Custom,
128 StatBar_Max
129 } m_statbarKind;
130
131 void DoCreateStatusBar(StatBarKind kind);
132
133 wxStatusBar *m_statbarDefault;
134 MyStatusBar *m_statbarCustom;
135
136 // any class wishing to process wxWindows events must use this macro
137 DECLARE_EVENT_TABLE()
138 };
139
140 // Our about dialog ith its status bar
141 class MyAboutDialog : public wxDialog
142 {
143 public:
144 MyAboutDialog(wxWindow *parent);
145 };
146
147 // ----------------------------------------------------------------------------
148 // constants
149 // ----------------------------------------------------------------------------
150
151 // IDs for the controls and the menu commands
152 enum
153 {
154 // menu items
155 StatusBar_Quit = 1,
156 StatusBar_SetFields,
157 StatusBar_Recreate,
158 StatusBar_About,
159 StatusBar_Checkbox = 1000
160 };
161
162 static const int BITMAP_SIZE_X = 32;
163 static const int BITMAP_SIZE_Y = 15;
164
165 // ----------------------------------------------------------------------------
166 // event tables and other macros for wxWindows
167 // ----------------------------------------------------------------------------
168
169 // the event tables connect the wxWindows events with the functions (event
170 // handlers) which process them. It can be also done at run-time, but for the
171 // simple menu events like this the static method is much simpler.
172 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
173 EVT_MENU(StatusBar_Quit, MyFrame::OnQuit)
174 EVT_MENU(StatusBar_SetFields, MyFrame::OnSetStatusFields)
175 EVT_MENU(StatusBar_Recreate, MyFrame::OnRecreateStatusBar)
176 EVT_MENU(StatusBar_About, MyFrame::OnAbout)
177 END_EVENT_TABLE()
178
179 BEGIN_EVENT_TABLE(MyStatusBar, wxStatusBar)
180 EVT_SIZE(MyStatusBar::OnSize)
181 EVT_CHECKBOX(StatusBar_Checkbox, MyStatusBar::OnToggleClock)
182 EVT_TIMER(-1, MyStatusBar::OnTimer)
183 END_EVENT_TABLE()
184
185 // Create a new application object: this macro will allow wxWindows to create
186 // the application object during program execution (it's better than using a
187 // static object for many reasons) and also declares the accessor function
188 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
189 // not wxApp)
190 IMPLEMENT_APP(MyApp)
191
192 // ============================================================================
193 // implementation
194 // ============================================================================
195
196 // ----------------------------------------------------------------------------
197 // the application class
198 // ----------------------------------------------------------------------------
199
200 // `Main program' equivalent: the program execution "starts" here
201 bool MyApp::OnInit()
202 {
203 // create the main application window
204 MyFrame *frame = new MyFrame("wxStatusBar sample",
205 wxPoint(50, 50), wxSize(450, 340));
206
207 // and show it (the frames, unlike simple controls, are not shown when
208 // created initially)
209 frame->Show(TRUE);
210
211 // success: wxApp::OnRun() will be called which will enter the main message
212 // loop and the application will run. If we returned FALSE here, the
213 // application would exit immediately.
214 return TRUE;
215 }
216
217 // ----------------------------------------------------------------------------
218 // main frame
219 // ----------------------------------------------------------------------------
220
221 // frame constructor
222 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
223 : wxFrame((wxFrame *)NULL, -1, title, pos, size)
224 {
225 m_statbarDefault = NULL;
226 m_statbarCustom = NULL;
227
228 #ifdef __WXMAC__
229 // we need this in order to allow the about menu relocation, since ABOUT is
230 // not the default id of the about menu
231 wxApp::s_macAboutMenuItemId = StatusBar_About;
232 #endif
233
234 // create a menu bar
235 wxMenu *menuFile = new wxMenu;
236 menuFile->Append(StatusBar_Quit, "E&xit\tAlt-X", "Quit this program");
237
238 wxMenu *statbarMenu = new wxMenu;
239 statbarMenu->Append(StatusBar_SetFields, "&Set field count\tCtrl-C",
240 "Set the number of status bar fields");
241 statbarMenu->Append(StatusBar_Recreate, "&Recreate\tCtrl-R",
242 "Toggle status bar format");
243
244 wxMenu *helpMenu = new wxMenu;
245 helpMenu->Append(StatusBar_About, "&About...\tCtrl-A", "Show about dialog");
246
247 // now append the freshly created menu to the menu bar...
248 wxMenuBar *menuBar = new wxMenuBar();
249 menuBar->Append(menuFile, "&File");
250 menuBar->Append(statbarMenu, "&Status bar");
251 menuBar->Append(helpMenu, "&Help");
252
253 // ... and attach this menu bar to the frame
254 SetMenuBar(menuBar);
255
256 // create default status bar to start with
257 CreateStatusBar(2);
258 SetStatusText("Welcome to wxWindows!");
259
260 m_statbarDefault = GetStatusBar();
261 }
262
263 MyFrame::~MyFrame()
264 {
265 SetStatusBar(NULL);
266
267 delete m_statbarDefault;
268 delete m_statbarCustom;
269 }
270
271 void MyFrame::DoCreateStatusBar(MyFrame::StatBarKind kind)
272 {
273 wxStatusBar *statbarOld = GetStatusBar();
274 if ( statbarOld )
275 {
276 statbarOld->Hide();
277 }
278
279 switch ( kind )
280 {
281 case StatBar_Default:
282 SetStatusBar(m_statbarDefault);
283 break;
284
285 case StatBar_Custom:
286 if ( !m_statbarCustom )
287 {
288 m_statbarCustom = new MyStatusBar(this);
289 }
290 SetStatusBar(m_statbarCustom);
291 break;
292
293 default:
294 wxFAIL_MSG("unknown stat bar kind");
295 }
296
297 PositionStatusBar();
298 GetStatusBar()->Show();
299
300 m_statbarKind = kind;
301 }
302
303 // event handlers
304 void MyFrame::OnSetStatusFields(wxCommandEvent& WXUNUSED(event))
305 {
306 wxStatusBar *sb = GetStatusBar();
307
308 long nFields = wxGetNumberFromUser
309 (
310 "Select the number of fields in the status bar",
311 "Fields:",
312 "wxWindows statusbar sample",
313 sb->GetFieldsCount(),
314 1, 5,
315 this
316 );
317
318 // we don't check if the number changed at all on purpose: calling
319 // SetFieldsCount() with the same number of fields should be ok
320 if ( nFields != -1 )
321 {
322 // we set the widths only for 2 of them, otherwise let all the fields
323 // have equal width (the default behaviour)
324 const int *widths = NULL;
325 if ( nFields == 2 )
326 {
327 static const int widthsFor2Fields[2] = { 200, -1 };
328 widths = widthsFor2Fields;
329 }
330
331 sb->SetFieldsCount(nFields, widths);
332
333 wxLogStatus(this,
334 wxString::Format("Status bar now has %ld fields", nFields));
335 }
336 else
337 {
338 wxLogStatus(this, "Cancelled");
339 }
340 }
341
342 void MyFrame::OnRecreateStatusBar(wxCommandEvent& WXUNUSED(event))
343 {
344 DoCreateStatusBar(m_statbarKind == StatBar_Custom ? StatBar_Default
345 : StatBar_Custom);
346 }
347
348 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
349 {
350 // TRUE is to force the frame to close
351 Close(TRUE);
352 }
353
354 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
355 {
356 MyAboutDialog dlg(this);
357 dlg.ShowModal();
358 }
359
360 // ----------------------------------------------------------------------------
361 // MyAboutDialog
362 // ----------------------------------------------------------------------------
363
364 MyAboutDialog::MyAboutDialog(wxWindow *parent)
365 : wxDialog(parent, -1, wxString("About statbar"),
366 wxDefaultPosition, wxDefaultSize,
367 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
368 {
369 wxStaticText *text = new wxStaticText(this, -1,
370 "wxStatusBar sample\n"
371 "(c) 2000 Vadim Zeitlin");
372
373 // create the top status bar without the size grip (default style),
374 // otherwise it looks weird
375 wxStatusBar *statbarTop = new wxStatusBar(this, -1, 0);
376 statbarTop->SetFieldsCount(3);
377 statbarTop->SetStatusText("This is a top status bar", 0);
378 statbarTop->SetStatusText("in a dialog", 1);
379 statbarTop->SetStatusText("Great, isn't it?", 2);
380
381 wxStatusBar *statbarBottom = new wxStatusBar(this, -1);
382 statbarBottom->SetFieldsCount(2);
383 statbarBottom->SetStatusText("This is a bottom status bar", 0);
384 statbarBottom->SetStatusText("in a dialog", 1);
385
386 wxBoxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
387 sizerTop->Add(statbarTop, 0, wxGROW);
388 sizerTop->Add(-1, 10, 1, wxGROW);
389 sizerTop->Add(text, 0, wxCENTRE);
390 sizerTop->Add(-1, 10, 1, wxGROW);
391 sizerTop->Add(statbarBottom, 0, wxGROW);
392
393 SetAutoLayout(TRUE);
394 SetSizer(sizerTop);
395
396 sizerTop->Fit(this);
397 sizerTop->SetSizeHints(this);
398 }
399
400 // ----------------------------------------------------------------------------
401 // MyStatusBar
402 // ----------------------------------------------------------------------------
403
404 #ifdef __VISUALC__
405 // 'this' : used in base member initializer list -- so what??
406 #pragma warning(disable: 4355)
407 #endif
408
409 MyStatusBar::MyStatusBar(wxWindow *parent)
410 : wxStatusBar(parent, -1), m_timer(this)
411 {
412 static const int widths[Field_Max] = { -1, 150, BITMAP_SIZE_X, 100 };
413
414 SetFieldsCount(Field_Max);
415 SetStatusWidths(Field_Max, widths);
416
417 m_checkbox = new wxCheckBox(this, StatusBar_Checkbox, _T("&Toggle clock"));
418 m_checkbox->SetValue(TRUE);
419
420 m_statbmp = new wxStaticBitmap(this, -1, wxIcon(green_xpm));
421
422 m_timer.Start(1000);
423
424 SetMinHeight(BITMAP_SIZE_Y);
425
426 UpdateClock();
427 }
428
429 #ifdef __VISUALC__
430 #pragma warning(default: 4355)
431 #endif
432
433 MyStatusBar::~MyStatusBar()
434 {
435 if ( m_timer.IsRunning() )
436 {
437 m_timer.Stop();
438 }
439 }
440
441 void MyStatusBar::OnSize(wxSizeEvent& event)
442 {
443 wxRect rect;
444 GetFieldRect(Field_Checkbox, rect);
445
446 m_checkbox->SetSize(rect.x + 2, rect.y + 2, rect.width - 4, rect.height - 4);
447
448 GetFieldRect(Field_Bitmap, rect);
449 m_statbmp->Move(rect.x + (rect.width - BITMAP_SIZE_X) / 2,
450 rect.y + (rect.height - BITMAP_SIZE_Y) / 2);
451
452 event.Skip();
453 }
454
455 void MyStatusBar::OnToggleClock(wxCommandEvent& event)
456 {
457 if ( m_checkbox->GetValue() )
458 {
459 m_timer.Start(1000);
460
461 m_statbmp->SetIcon(wxIcon(green_xpm));
462
463 UpdateClock();
464 }
465 else // don't show clock
466 {
467 m_timer.Stop();
468
469 m_statbmp->SetIcon(wxIcon(red_xpm));
470
471 SetStatusText("", Field_Clock);
472 }
473 }
474
475 void MyStatusBar::UpdateClock()
476 {
477 SetStatusText(wxDateTime::Now().FormatTime(), Field_Clock);
478 }