Clean up status bar sample.
[wxWidgets.git] / samples / statbar / statbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: statbar.cpp
3 // Purpose: wxStatusBar sample
4 // Author: Vadim Zeitlin
5 // Created: 04.02.00
6 // RCS-ID: $Id$
7 // Copyright: (c) Vadim Zeitlin
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 #if !wxUSE_STATUSBAR
27 #error "You need to set wxUSE_STATUSBAR to 1 to compile this sample"
28 #endif // wxUSE_STATUSBAR
29
30 // for all others, include the necessary headers
31 #ifndef WX_PRECOMP
32 #include "wx/app.h"
33 #include "wx/log.h"
34 #include "wx/frame.h"
35 #include "wx/statusbr.h"
36 #include "wx/timer.h"
37 #include "wx/checkbox.h"
38 #include "wx/statbmp.h"
39 #include "wx/menu.h"
40 #include "wx/msgdlg.h"
41 #include "wx/textdlg.h"
42 #include "wx/sizer.h"
43 #include "wx/stattext.h"
44 #include "wx/bmpbuttn.h"
45 #include "wx/dcmemory.h"
46 #endif
47
48 #include "wx/datetime.h"
49 #include "wx/numdlg.h"
50 #include "wx/fontdlg.h"
51
52 #ifndef __WXMSW__
53 #include "../sample.xpm"
54 #endif
55
56
57 // define this for the platforms which don't support wxBitmapButton (such as
58 // Motif), else a wxBitmapButton will be used
59 #ifdef __WXMOTIF__
60 #define USE_STATIC_BITMAP
61 #endif
62
63 //#define USE_MDI_PARENT_FRAME 1
64
65 #ifdef USE_MDI_PARENT_FRAME
66 #include "wx/mdi.h"
67 #endif // USE_MDI_PARENT_FRAME
68
69 static const char *SAMPLE_DIALOGS_TITLE = "wxWidgets statbar sample";
70
71 // ----------------------------------------------------------------------------
72 // resources
73 // ----------------------------------------------------------------------------
74
75 #ifdef USE_STATIC_BITMAP
76 #include "green.xpm"
77 #include "red.xpm"
78 #endif // USE_STATIC_BITMAP
79
80 // ----------------------------------------------------------------------------
81 // private classes
82 // ----------------------------------------------------------------------------
83
84 // Define a new application type, each program should derive a class from wxApp
85 class MyApp : public wxApp
86 {
87 public:
88 // override base class virtuals
89 // ----------------------------
90
91 // this one is called on application startup and is a good place for the app
92 // initialization (doing it here and not in the ctor allows to have an error
93 // return: if OnInit() returns false, the application terminates)
94 virtual bool OnInit();
95 };
96
97 // A custom status bar which contains controls, icons &c
98 class MyStatusBar : public wxStatusBar
99 {
100 public:
101 MyStatusBar(wxWindow *parent, long style = wxSTB_DEFAULT_STYLE);
102 virtual ~MyStatusBar();
103
104 void UpdateClock();
105
106 // event handlers
107 #if wxUSE_TIMER
108 void OnTimer(wxTimerEvent& WXUNUSED(event)) { UpdateClock(); }
109 #endif
110 void OnSize(wxSizeEvent& event);
111 void OnToggleClock(wxCommandEvent& event);
112 void OnButton(wxCommandEvent& event);
113
114 private:
115 // toggle the state of the status bar controls
116 void DoToggle();
117
118 wxBitmap CreateBitmapForButton(bool on = false);
119
120 enum
121 {
122 Field_Text,
123 Field_Checkbox,
124 Field_Bitmap,
125 Field_Clock,
126 Field_Max
127 };
128
129 #if wxUSE_TIMER
130 wxTimer m_timer;
131 #endif
132
133 #if wxUSE_CHECKBOX
134 wxCheckBox *m_checkbox;
135 #endif
136 #ifdef USE_STATIC_BITMAP
137 wxStaticBitmap *m_statbmp;
138 #else
139 wxBitmapButton *m_statbmp;
140 #endif
141
142 DECLARE_EVENT_TABLE()
143 };
144
145 // Define a new frame type: this is going to be our main frame
146 #ifdef USE_MDI_PARENT_FRAME
147 class MyFrame : public wxMDIParentFrame
148 #else
149 class MyFrame : public wxFrame
150 #endif
151 {
152 public:
153 // ctor(s)
154 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
155
156 // event handlers (these functions should _not_ be virtual)
157 void OnQuit(wxCommandEvent& event);
158 void OnAbout(wxCommandEvent& event);
159
160 void OnSetStatusField(wxCommandEvent& event);
161 void OnSetStatusText(wxCommandEvent& event);
162 void OnPushStatusText(wxCommandEvent& event);
163 void OnPopStatusText(wxCommandEvent& event);
164
165 void OnResetFieldsWidth(wxCommandEvent& event);
166 void OnSetStatusFields(wxCommandEvent& event);
167 void OnSetStatusFont(wxCommandEvent& event);
168 void OnRecreateStatusBar(wxCommandEvent& event);
169
170 void OnSetPaneStyle(wxCommandEvent& event);
171 void OnSetStyle(wxCommandEvent& event);
172
173 private:
174 enum StatusBarKind
175 {
176 StatBar_Default,
177 StatBar_Custom,
178 StatBar_Max
179 } m_statbarKind;
180
181
182 void OnUpdateForDefaultStatusbar(wxUpdateUIEvent& event);
183 void OnUpdateStatusBarToggle(wxUpdateUIEvent& event);
184 void OnUpdateSetPaneStyle(wxUpdateUIEvent& event);
185 void OnUpdateSetStyle(wxUpdateUIEvent& event);
186 void OnStatusBarToggle(wxCommandEvent& event);
187 void DoCreateStatusBar(StatusBarKind kind, long style);
188 void ApplyPaneStyle();
189
190 int m_statbarPaneStyle;
191
192 // the index of the field used by some commands
193 int m_field;
194
195 // any class wishing to process wxWidgets events must use this macro
196 DECLARE_EVENT_TABLE()
197 };
198
199 // Our about dialog ith its status bar
200 class MyAboutDialog : public wxDialog
201 {
202 public:
203 MyAboutDialog(wxWindow *parent);
204 };
205
206 // ----------------------------------------------------------------------------
207 // constants
208 // ----------------------------------------------------------------------------
209
210 // IDs for the controls and the menu commands
211 enum
212 {
213 // menu items
214 StatusBar_Quit = wxID_EXIT,
215 StatusBar_About = wxID_ABOUT,
216
217 StatusBar_SetFields = wxID_HIGHEST+1,
218 StatusBar_SetField,
219 StatusBar_SetText,
220 StatusBar_PushText,
221 StatusBar_PopText,
222 StatusBar_SetFont,
223 StatusBar_ResetFieldsWidth,
224
225 StatusBar_Recreate,
226 StatusBar_Toggle,
227 StatusBar_Checkbox,
228 StatusBar_SetPaneStyle,
229 StatusBar_SetPaneStyleNormal,
230 StatusBar_SetPaneStyleFlat,
231 StatusBar_SetPaneStyleRaised,
232
233 StatusBar_SetStyleSizeGrip,
234 StatusBar_SetStyleEllipsizeStart,
235 StatusBar_SetStyleEllipsizeMiddle,
236 StatusBar_SetStyleEllipsizeEnd,
237 StatusBar_SetStyleShowTips
238 };
239
240 static const int BITMAP_SIZE_X = 32;
241 static const int BITMAP_SIZE_Y = 15;
242
243 // ----------------------------------------------------------------------------
244 // event tables and other macros for wxWidgets
245 // ----------------------------------------------------------------------------
246
247 // the event tables connect the wxWidgets events with the functions (event
248 // handlers) which process them. It can be also done at run-time, but for the
249 // simple menu events like this the static method is much simpler.
250 #ifdef USE_MDI_PARENT_FRAME
251 BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
252 #else
253 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
254 #endif
255 EVT_MENU(StatusBar_Quit, MyFrame::OnQuit)
256 EVT_MENU(StatusBar_SetFields, MyFrame::OnSetStatusFields)
257 EVT_MENU(StatusBar_SetField, MyFrame::OnSetStatusField)
258 EVT_MENU(StatusBar_SetText, MyFrame::OnSetStatusText)
259 EVT_MENU(StatusBar_PushText, MyFrame::OnPushStatusText)
260 EVT_MENU(StatusBar_PopText, MyFrame::OnPopStatusText)
261 EVT_MENU(StatusBar_SetFont, MyFrame::OnSetStatusFont)
262 EVT_MENU(StatusBar_ResetFieldsWidth, MyFrame::OnResetFieldsWidth)
263 EVT_MENU(StatusBar_Recreate, MyFrame::OnRecreateStatusBar)
264 EVT_MENU(StatusBar_About, MyFrame::OnAbout)
265 EVT_MENU(StatusBar_Toggle, MyFrame::OnStatusBarToggle)
266 EVT_MENU(StatusBar_SetPaneStyleNormal, MyFrame::OnSetPaneStyle)
267 EVT_MENU(StatusBar_SetPaneStyleFlat, MyFrame::OnSetPaneStyle)
268 EVT_MENU(StatusBar_SetPaneStyleRaised, MyFrame::OnSetPaneStyle)
269
270 EVT_MENU(StatusBar_SetStyleSizeGrip, MyFrame::OnSetStyle)
271 EVT_MENU(StatusBar_SetStyleEllipsizeStart, MyFrame::OnSetStyle)
272 EVT_MENU(StatusBar_SetStyleEllipsizeMiddle, MyFrame::OnSetStyle)
273 EVT_MENU(StatusBar_SetStyleEllipsizeEnd, MyFrame::OnSetStyle)
274 EVT_MENU(StatusBar_SetStyleShowTips, MyFrame::OnSetStyle)
275
276 EVT_UPDATE_UI_RANGE(StatusBar_SetFields, StatusBar_ResetFieldsWidth,
277 MyFrame::OnUpdateForDefaultStatusbar)
278 EVT_UPDATE_UI(StatusBar_Toggle, MyFrame::OnUpdateStatusBarToggle)
279 EVT_UPDATE_UI_RANGE(StatusBar_SetPaneStyleNormal,
280 StatusBar_SetPaneStyleRaised,
281 MyFrame::OnUpdateSetPaneStyle)
282 EVT_UPDATE_UI_RANGE(StatusBar_SetStyleSizeGrip, StatusBar_SetStyleShowTips,
283 MyFrame::OnUpdateSetStyle)
284 END_EVENT_TABLE()
285
286 BEGIN_EVENT_TABLE(MyStatusBar, wxStatusBar)
287 EVT_SIZE(MyStatusBar::OnSize)
288 #if wxUSE_CHECKBOX
289 EVT_CHECKBOX(StatusBar_Checkbox, MyStatusBar::OnToggleClock)
290 #endif
291 EVT_BUTTON(wxID_ANY, MyStatusBar::OnButton)
292 #if wxUSE_TIMER
293 EVT_TIMER(wxID_ANY, MyStatusBar::OnTimer)
294 #endif
295 END_EVENT_TABLE()
296
297 // Create a new application object: this macro will allow wxWidgets to create
298 // the application object during program execution (it's better than using a
299 // static object for many reasons) and also declares the accessor function
300 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
301 // not wxApp)
302 IMPLEMENT_APP(MyApp)
303
304 // ============================================================================
305 // implementation
306 // ============================================================================
307
308 // ----------------------------------------------------------------------------
309 // the application class
310 // ----------------------------------------------------------------------------
311
312 // `Main program' equivalent: the program execution "starts" here
313 bool MyApp::OnInit()
314 {
315 if ( !wxApp::OnInit() )
316 return false;
317
318 // create the main application window
319 MyFrame *frame = new MyFrame(wxT("wxStatusBar sample"),
320 wxPoint(50, 50), wxSize(450, 340));
321
322 // and show it (the frames, unlike simple controls, are not shown when
323 // created initially)
324 frame->Show(true);
325
326 // success: wxApp::OnRun() will be called which will enter the main message
327 // loop and the application will run. If we returned 'false' here, the
328 // application would exit immediately.
329 return true;
330 }
331
332 // ----------------------------------------------------------------------------
333 // main frame
334 // ----------------------------------------------------------------------------
335
336 // frame constructor
337 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
338 #ifdef USE_MDI_PARENT_FRAME
339 : wxMDIParentFrame(NULL, wxID_ANY, title, pos, size)
340 #else
341 : wxFrame(NULL, wxID_ANY, title, pos, size)
342 #endif
343 {
344 SetIcon(wxICON(sample));
345
346 m_statbarPaneStyle = wxSB_NORMAL;
347 m_field = 1;
348
349 // create a menu bar
350 wxMenu *menuFile = new wxMenu;
351 menuFile->Append(StatusBar_Quit, wxT("E&xit\tAlt-X"),
352 wxT("Quit this program"));
353
354 wxMenu *statbarMenu = new wxMenu;
355
356 wxMenu *statbarStyleMenu = new wxMenu;
357 statbarStyleMenu->Append(StatusBar_SetStyleSizeGrip, wxT("wxSTB_SIZE_GRIP"),
358 wxT("Toggles the wxSTB_SIZE_GRIP style"), true);
359 statbarStyleMenu->Append(StatusBar_SetStyleShowTips, wxT("wxSTB_SHOW_TIPS"),
360 wxT("Toggles the wxSTB_SHOW_TIPS style"), true);
361 statbarStyleMenu->AppendSeparator();
362 statbarStyleMenu->AppendCheckItem(StatusBar_SetStyleEllipsizeStart,
363 wxT("wxSTB_ELLIPSIZE_START"),
364 wxT("Toggle wxSTB_ELLIPSIZE_START style"));
365 statbarStyleMenu->AppendCheckItem(StatusBar_SetStyleEllipsizeMiddle,
366 wxT("wxSTB_ELLIPSIZE_MIDDLE"),
367 wxT("Toggle wxSTB_ELLIPSIZE_MIDDLE style"));
368 statbarStyleMenu->AppendCheckItem(StatusBar_SetStyleEllipsizeEnd,
369 wxT("wxSTB_ELLIPSIZE_END"),
370 wxT("Toggle wxSTB_ELLIPSIZE_END style"));
371 statbarMenu->Append(StatusBar_SetPaneStyle, wxT("Status bar style"),
372 statbarStyleMenu);
373 statbarMenu->AppendSeparator();
374
375 statbarMenu->Append(StatusBar_SetField, "Set active field &number\tCtrl-N",
376 "Set the number of field used by the next commands.");
377 statbarMenu->Append(StatusBar_SetText, wxT("Set field &text\tCtrl-T"),
378 wxT("Set the text of the selected field."));
379 statbarMenu->Append(StatusBar_PushText, "P&ush field text\tCtrl-P",
380 "Push a message on top the selected field.");
381 statbarMenu->Append(StatusBar_PopText, "&Pop field text\tShift-Ctrl-P",
382 "Restore the previous contents of the selected field.");
383 statbarMenu->AppendSeparator();
384
385 statbarMenu->Append(StatusBar_SetFields, wxT("&Set field count\tCtrl-C"),
386 wxT("Set the number of status bar fields"));
387 statbarMenu->Append(StatusBar_SetFont, wxT("&Set field font\tCtrl-F"),
388 wxT("Set the font to use for status bar fields"));
389
390 wxMenu *statbarPaneStyleMenu = new wxMenu;
391 statbarPaneStyleMenu->AppendCheckItem
392 (
393 StatusBar_SetPaneStyleNormal,
394 wxT("&Normal"),
395 wxT("Sets the style of the first field to normal (sunken) look")
396 );
397 statbarPaneStyleMenu->AppendCheckItem
398 (
399 StatusBar_SetPaneStyleFlat,
400 wxT("&Flat"),
401 wxT("Sets the style of the first field to flat look")
402 );
403 statbarPaneStyleMenu->AppendCheckItem
404 (
405 StatusBar_SetPaneStyleRaised,
406 wxT("&Raised"),
407 wxT("Sets the style of the first field to raised look")
408 );
409 statbarMenu->Append(StatusBar_SetPaneStyle, wxT("Field style"),
410 statbarPaneStyleMenu);
411
412 statbarMenu->Append(StatusBar_ResetFieldsWidth, wxT("Reset field widths"),
413 wxT("Sets all fields to the same width"));
414 statbarMenu->AppendSeparator();
415
416 statbarMenu->AppendCheckItem(StatusBar_Toggle, wxT("&Toggle Status Bar"),
417 wxT("Toggle the status bar display"));
418 statbarMenu->Append(StatusBar_Recreate, wxT("&Recreate\tCtrl-R"),
419 wxT("Toggle status bar format"));
420
421 wxMenu *helpMenu = new wxMenu;
422 helpMenu->Append(StatusBar_About, wxT("&About...\tCtrl-A"),
423 wxT("Show about dialog"));
424
425 // now append the freshly created menu to the menu bar...
426 wxMenuBar *menuBar = new wxMenuBar();
427 menuBar->Append(menuFile, wxT("&File"));
428 menuBar->Append(statbarMenu, wxT("&Status bar"));
429 menuBar->Append(helpMenu, wxT("&Help"));
430
431 // ... and attach this menu bar to the frame
432 SetMenuBar(menuBar);
433
434 // create default status bar to start with
435 DoCreateStatusBar(StatBar_Default, wxSTB_DEFAULT_STYLE);
436 SetStatusText(wxT("Welcome to wxWidgets!"));
437 }
438
439 void MyFrame::DoCreateStatusBar(MyFrame::StatusBarKind kind, long style)
440 {
441 wxStatusBar *statbarOld = GetStatusBar();
442 if ( statbarOld )
443 {
444 SetStatusBar(NULL);
445 delete statbarOld;
446 }
447
448 wxStatusBar *statbarNew = NULL;
449 switch ( kind )
450 {
451 case StatBar_Default:
452 statbarNew = new wxStatusBar(this, wxID_ANY, style, "wxStatusBar");
453 statbarNew->SetFieldsCount(2);
454 break;
455
456 case StatBar_Custom:
457 statbarNew = new MyStatusBar(this, style);
458 break;
459
460 default:
461 wxFAIL_MSG(wxT("unknown status bar kind"));
462 }
463
464 SetStatusBar(statbarNew);
465 ApplyPaneStyle();
466 PositionStatusBar();
467
468 m_statbarKind = kind;
469 }
470
471
472 // ----------------------------------------------------------------------------
473 // main frame - event handlers
474 // ----------------------------------------------------------------------------
475
476 void MyFrame::OnUpdateForDefaultStatusbar(wxUpdateUIEvent& event)
477 {
478 // only allow this feature for the default status bar
479 wxStatusBar *sb = GetStatusBar();
480 if (!sb)
481 return;
482
483 event.Enable(sb->GetName() == "wxStatusBar");
484 }
485
486 void MyFrame::OnSetStatusField(wxCommandEvent& WXUNUSED(event))
487 {
488 wxStatusBar *sb = GetStatusBar();
489 if (!sb)
490 return;
491
492 long rc = wxGetNumberFromUser
493 (
494 "Configure the field index to be used by the set, push "
495 "and pop text commands in the menu.\n"
496 "\n"
497 "0 corresponds to the first field, 1 to the second one "
498 "and so on.",
499 "Field &index:",
500 SAMPLE_DIALOGS_TITLE,
501 m_field,
502 0,
503 sb->GetFieldsCount() - 1,
504 NULL
505 );
506
507 if ( rc == -1 )
508 return;
509
510 m_field = rc;
511
512 wxLogStatus("Status bar text will be set for field #%d", m_field);
513 }
514
515 void MyFrame::OnSetStatusText(wxCommandEvent& WXUNUSED(event))
516 {
517 wxStatusBar *sb = GetStatusBar();
518 if (!sb)
519 return;
520
521 wxString txt = wxGetTextFromUser
522 (
523 wxString::Format
524 (
525 "Enter the text from for the field #%d",
526 m_field
527 ),
528 SAMPLE_DIALOGS_TITLE,
529 sb->GetStatusText(m_field),
530 this
531 );
532
533 if ( txt.empty() )
534 return;
535
536 sb->SetStatusText(txt, m_field);
537 }
538
539 // the current depth of the stack used by Push/PopStatusText()
540 static int gs_depth = 0;
541
542 void MyFrame::OnPushStatusText(wxCommandEvent& WXUNUSED(event))
543 {
544 wxStatusBar *sb = GetStatusBar();
545 if (!sb)
546 return;
547
548 static int s_countPush = 0;
549 sb->PushStatusText(wxString::Format
550 (
551 "Pushed message #%d (depth = %d)",
552 ++s_countPush, ++gs_depth
553 ), m_field);
554 }
555
556 void MyFrame::OnPopStatusText(wxCommandEvent& WXUNUSED(event))
557 {
558 wxStatusBar *sb = GetStatusBar();
559 if (!sb)
560 return;
561
562 if ( !gs_depth )
563 {
564 wxLogStatus("No message to pop.");
565 return;
566 }
567
568 gs_depth--;
569 sb->PopStatusText(m_field);
570 }
571
572 void MyFrame::OnSetStatusFont(wxCommandEvent& WXUNUSED(event))
573 {
574 wxStatusBar *sb = GetStatusBar();
575 if (!sb)
576 return;
577
578 wxFont
579 fnt = wxGetFontFromUser(this, sb->GetFont(), "Choose status bar font");
580 if (fnt.IsOk())
581 {
582 sb->SetFont(fnt);
583 sb->SetSize(sb->GetBestSize());
584 }
585 }
586
587 void MyFrame::OnSetStatusFields(wxCommandEvent& WXUNUSED(event))
588 {
589 wxStatusBar *sb = GetStatusBar();
590 if (!sb)
591 return;
592
593 long nFields = wxGetNumberFromUser
594 (
595 wxT("Select the number of fields in the status bar"),
596 wxT("Fields:"),
597 SAMPLE_DIALOGS_TITLE,
598 sb->GetFieldsCount(),
599 1, 5,
600 this
601 );
602
603 // we don't check if the number changed at all on purpose: calling
604 // SetFieldsCount() with the same number of fields should be ok
605 if ( nFields != -1 )
606 {
607 static const int widthsFor2Fields[] = { 200, -1 };
608 static const int widthsFor3Fields[] = { -1, -2, -1 };
609 static const int widthsFor4Fields[] = { 100, -1, 100, -2, 100 };
610
611 static const int *widthsAll[] =
612 {
613 NULL, // 1 field: default
614 widthsFor2Fields, // 2 fields: 1 fixed, 1 var
615 widthsFor3Fields, // 3 fields: 3 var
616 widthsFor4Fields, // 4 fields: 3 fixed, 2 vars
617 NULL // 5 fields: default (all have same width)
618 };
619
620 const int * const widths = widthsAll[nFields - 1];
621 sb->SetFieldsCount(nFields, widths);
622
623 wxString s;
624 for ( long n = 0; n < nFields; n++ )
625 {
626 if ( widths )
627 {
628 if ( widths[n] > 0 )
629 s.Printf(wxT("fixed (%d)"), widths[n]);
630 else
631 s.Printf(wxT("variable (*%d)"), -widths[n]);
632 }
633 else
634 {
635 s = wxT("default");
636 }
637
638 SetStatusText(s, n);
639 }
640
641 if ( m_field >= nFields )
642 m_field = nFields - 1;
643 }
644 else
645 {
646 wxLogStatus(this, wxT("Cancelled"));
647 }
648 }
649
650 void MyFrame::OnResetFieldsWidth(wxCommandEvent& WXUNUSED(event))
651 {
652 wxStatusBar *pStat = GetStatusBar();
653 if ( !pStat )
654 return;
655
656 const int n = pStat->GetFieldsCount();
657 pStat->SetStatusWidths(n, NULL);
658 for ( int i = 0; i < n; i++ )
659 pStat->SetStatusText("same size", i);
660 }
661
662 void MyFrame::OnUpdateStatusBarToggle(wxUpdateUIEvent& event)
663 {
664 event.Check(GetStatusBar() != NULL);
665 }
666
667 void MyFrame::OnStatusBarToggle(wxCommandEvent& WXUNUSED(event))
668 {
669 wxStatusBar *statbarOld = GetStatusBar();
670 if ( statbarOld )
671 {
672 SetStatusBar(NULL);
673 delete statbarOld;
674 }
675 else
676 {
677 DoCreateStatusBar(m_statbarKind, wxSTB_DEFAULT_STYLE);
678 }
679 }
680
681 void MyFrame::OnRecreateStatusBar(wxCommandEvent& WXUNUSED(event))
682 {
683 DoCreateStatusBar(m_statbarKind == StatBar_Custom ? StatBar_Default
684 : StatBar_Custom,
685 wxSTB_DEFAULT_STYLE);
686 }
687
688 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
689 {
690 // true is to force the frame to close
691 Close(true);
692 }
693
694 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
695 {
696 MyAboutDialog dlg(this);
697 dlg.ShowModal();
698 }
699
700 void MyFrame::OnUpdateSetPaneStyle(wxUpdateUIEvent& event)
701 {
702 switch (event.GetId())
703 {
704 case StatusBar_SetPaneStyleNormal:
705 event.Check(m_statbarPaneStyle == wxSB_NORMAL);
706 break;
707 case StatusBar_SetPaneStyleFlat:
708 event.Check(m_statbarPaneStyle == wxSB_FLAT);
709 break;
710 case StatusBar_SetPaneStyleRaised:
711 event.Check(m_statbarPaneStyle == wxSB_RAISED);
712 break;
713 }
714 }
715
716 void MyFrame::OnSetPaneStyle(wxCommandEvent& event)
717 {
718 switch (event.GetId())
719 {
720 case StatusBar_SetPaneStyleNormal:
721 m_statbarPaneStyle = wxSB_NORMAL;
722 break;
723 case StatusBar_SetPaneStyleFlat:
724 m_statbarPaneStyle = wxSB_FLAT;
725 break;
726 case StatusBar_SetPaneStyleRaised:
727 m_statbarPaneStyle = wxSB_RAISED;
728 break;
729 }
730
731 ApplyPaneStyle();
732 }
733
734 void MyFrame::ApplyPaneStyle()
735 {
736 wxStatusBar *sb = GetStatusBar();
737 if (!sb)
738 return;
739
740 int fields = sb->GetFieldsCount();
741 int *styles = new int[fields];
742
743 for (int i = 1; i < fields; i++)
744 styles[i] = wxSB_NORMAL;
745
746 styles[0] = m_statbarPaneStyle;
747
748 sb->SetStatusStyles(fields, styles);
749
750 delete [] styles;
751 }
752
753 void MyFrame::OnUpdateSetStyle(wxUpdateUIEvent& event)
754 {
755 long currentStyle = wxSTB_DEFAULT_STYLE;
756 if (GetStatusBar())
757 currentStyle = GetStatusBar()->GetWindowStyle();
758
759 switch (event.GetId())
760 {
761 case StatusBar_SetStyleSizeGrip:
762 event.Check((currentStyle & wxSTB_SIZEGRIP) != 0);
763 break;
764 case StatusBar_SetStyleShowTips:
765 event.Check((currentStyle & wxSTB_SHOW_TIPS) != 0);
766 break;
767
768 case StatusBar_SetStyleEllipsizeStart:
769 event.Check((currentStyle & wxSTB_ELLIPSIZE_START) != 0);
770 break;
771 case StatusBar_SetStyleEllipsizeMiddle:
772 event.Check((currentStyle & wxSTB_ELLIPSIZE_MIDDLE) != 0);
773 break;
774 case StatusBar_SetStyleEllipsizeEnd:
775 event.Check((currentStyle & wxSTB_ELLIPSIZE_END) != 0);
776 break;
777 }
778 }
779
780 void MyFrame::OnSetStyle(wxCommandEvent& event)
781 {
782 long oldStyle = wxSTB_DEFAULT_STYLE;
783 if (GetStatusBar())
784 oldStyle = GetStatusBar()->GetWindowStyle();
785
786 #define STB_ELLIPSIZE_MASK \
787 (wxSTB_ELLIPSIZE_START|wxSTB_ELLIPSIZE_MIDDLE|wxSTB_ELLIPSIZE_END)
788
789 long newStyle = oldStyle;
790 long newStyleBit = 0;
791 switch (event.GetId())
792 {
793 case StatusBar_SetStyleSizeGrip:
794 newStyleBit = wxSTB_SIZEGRIP;
795 break;
796 case StatusBar_SetStyleShowTips:
797 newStyleBit = wxSTB_SHOW_TIPS;
798 break;
799
800 case StatusBar_SetStyleEllipsizeStart:
801 newStyleBit = wxSTB_ELLIPSIZE_START;
802 newStyle &= ~STB_ELLIPSIZE_MASK;
803 break;
804 case StatusBar_SetStyleEllipsizeMiddle:
805 newStyleBit = wxSTB_ELLIPSIZE_MIDDLE;
806 newStyle &= ~STB_ELLIPSIZE_MASK;
807 break;
808 case StatusBar_SetStyleEllipsizeEnd:
809 newStyleBit = wxSTB_ELLIPSIZE_END;
810 newStyle &= ~STB_ELLIPSIZE_MASK;
811 break;
812 }
813
814 newStyle = event.IsChecked() ? (newStyle | newStyleBit) :
815 (newStyle & ~newStyleBit);
816 if (newStyle != oldStyle)
817 {
818 DoCreateStatusBar(m_statbarKind, newStyle);
819 SetStatusText("Status bar recreated with a new style");
820 }
821 }
822
823 // ----------------------------------------------------------------------------
824 // MyAboutDialog
825 // ----------------------------------------------------------------------------
826
827 MyAboutDialog::MyAboutDialog(wxWindow *parent)
828 : wxDialog(parent, wxID_ANY, wxString(wxT("About statbar")),
829 wxDefaultPosition, wxDefaultSize,
830 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
831 {
832 wxStaticText *text = new wxStaticText(this, wxID_ANY,
833 wxT("wxStatusBar sample\n")
834 wxT("(c) 2000 Vadim Zeitlin"));
835
836 wxButton *btn = new wxButton(this, wxID_OK, wxT("&Close"));
837
838 // create the top status bar without the size grip (default style),
839 // otherwise it looks weird
840 wxStatusBar *statbarTop = new wxStatusBar(this, wxID_ANY, 0);
841 statbarTop->SetFieldsCount(3);
842 statbarTop->SetStatusText(wxT("This is a top status bar"), 0);
843 statbarTop->SetStatusText(wxT("in a dialog"), 1);
844 statbarTop->SetStatusText(wxT("Great, isn't it?"), 2);
845
846 wxStatusBar *statbarBottom = new wxStatusBar(this, wxID_ANY);
847 statbarBottom->SetFieldsCount(2);
848 statbarBottom->SetStatusText(wxT("This is a bottom status bar"), 0);
849 statbarBottom->SetStatusText(wxT("in a dialog"), 1);
850
851 wxBoxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
852 sizerTop->Add(statbarTop, 0, wxGROW);
853 sizerTop->Add(-1, 10, 1, wxGROW);
854 sizerTop->Add(text, 0, wxCENTRE | wxRIGHT | wxLEFT, 20);
855 sizerTop->Add(-1, 10, 1, wxGROW);
856 sizerTop->Add(btn, 0, wxCENTRE | wxRIGHT | wxLEFT, 20);
857 sizerTop->Add(-1, 10, 1, wxGROW);
858 sizerTop->Add(statbarBottom, 0, wxGROW);
859
860 SetSizerAndFit(sizerTop);
861 }
862
863 // ----------------------------------------------------------------------------
864 // MyStatusBar
865 // ----------------------------------------------------------------------------
866
867 #ifdef __VISUALC__
868 // 'this' : used in base member initializer list -- so what??
869 #pragma warning(disable: 4355)
870 #endif
871
872 MyStatusBar::MyStatusBar(wxWindow *parent, long style)
873 : wxStatusBar(parent, wxID_ANY, style, "MyStatusBar")
874 #if wxUSE_TIMER
875 , m_timer(this)
876 #endif
877 #if wxUSE_CHECKBOX
878 , m_checkbox(NULL)
879 #endif
880 {
881 static const int widths[Field_Max] = { -1, 150, BITMAP_SIZE_X, 100 };
882
883 SetFieldsCount(Field_Max);
884 SetStatusWidths(Field_Max, widths);
885
886 #if wxUSE_CHECKBOX
887 m_checkbox = new wxCheckBox(this, StatusBar_Checkbox, wxT("&Toggle clock"));
888 m_checkbox->SetValue(true);
889 #endif
890
891 #ifdef USE_STATIC_BITMAP
892 m_statbmp = new wxStaticBitmap(this, wxID_ANY, wxIcon(green_xpm));
893 #else
894 m_statbmp = new wxBitmapButton(this, wxID_ANY, CreateBitmapForButton(),
895 wxDefaultPosition, wxDefaultSize,
896 wxBU_EXACTFIT);
897 #endif
898
899 #if wxUSE_TIMER
900 m_timer.Start(1000);
901 #endif
902
903 SetMinHeight(wxMax(m_statbmp->GetBestSize().GetHeight(),
904 m_checkbox->GetBestSize().GetHeight()));
905
906 UpdateClock();
907 }
908
909 #ifdef __VISUALC__
910 #pragma warning(default: 4355)
911 #endif
912
913 MyStatusBar::~MyStatusBar()
914 {
915 #if wxUSE_TIMER
916 if ( m_timer.IsRunning() )
917 {
918 m_timer.Stop();
919 }
920 #endif
921 }
922
923 #define BMP_BUTTON_SIZE_X 10
924 #define BMP_BUTTON_SIZE_Y 10
925
926 wxBitmap MyStatusBar::CreateBitmapForButton(bool on)
927 {
928 wxBitmap bitmap(BMP_BUTTON_SIZE_X+1, BMP_BUTTON_SIZE_Y+1);
929 wxMemoryDC dc;
930 dc.SelectObject(bitmap);
931 dc.SetBrush(on ? *wxGREEN_BRUSH : *wxRED_BRUSH);
932 dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT);
933 dc.Clear();
934 dc.DrawEllipse(0, 0, BMP_BUTTON_SIZE_X, BMP_BUTTON_SIZE_Y);
935 dc.SelectObject(wxNullBitmap);
936
937 return bitmap;
938 }
939
940 void MyStatusBar::OnSize(wxSizeEvent& event)
941 {
942 #if wxUSE_CHECKBOX
943 if ( !m_checkbox )
944 return;
945 #endif
946
947 // TEMPORARY HACK: TODO find a more general solution
948 #ifdef wxStatusBarGeneric
949 wxStatusBar::OnSize(event);
950 #endif
951
952 wxRect rect;
953 if (!GetFieldRect(Field_Checkbox, rect))
954 {
955 event.Skip();
956 return;
957 }
958
959 #if wxUSE_CHECKBOX
960 wxRect rectCheck = rect;
961 rectCheck.Deflate(2);
962 m_checkbox->SetSize(rectCheck);
963 #endif
964
965 GetFieldRect(Field_Bitmap, rect);
966 wxSize size = m_statbmp->GetSize();
967
968 m_statbmp->Move(rect.x + (rect.width - size.x) / 2,
969 rect.y + (rect.height - size.y) / 2);
970
971 event.Skip();
972 }
973
974 void MyStatusBar::OnButton(wxCommandEvent& WXUNUSED(event))
975 {
976 #if wxUSE_CHECKBOX
977 m_checkbox->SetValue(!m_checkbox->GetValue());
978 #endif
979
980 DoToggle();
981 }
982
983 void MyStatusBar::OnToggleClock(wxCommandEvent& WXUNUSED(event))
984 {
985 DoToggle();
986 }
987
988 void MyStatusBar::DoToggle()
989 {
990 #if wxUSE_CHECKBOX
991 if ( m_checkbox->GetValue() )
992 {
993 #if wxUSE_TIMER
994 m_timer.Start(1000);
995 #endif
996
997 #ifdef USE_STATIC_BITMAP
998 m_statbmp->SetIcon(wxIcon(green_xpm));
999 #else
1000 m_statbmp->SetBitmapLabel(CreateBitmapForButton(false));
1001 m_statbmp->Refresh();
1002 #endif
1003
1004 UpdateClock();
1005 }
1006 else // don't show clock
1007 {
1008 #if wxUSE_TIMER
1009 m_timer.Stop();
1010 #endif
1011
1012 #ifdef USE_STATIC_BITMAP
1013 m_statbmp->SetIcon(wxIcon(red_xpm));
1014 #else
1015 m_statbmp->SetBitmapLabel(CreateBitmapForButton(true));
1016 m_statbmp->Refresh();
1017 #endif
1018
1019 SetStatusText(wxEmptyString, Field_Clock);
1020 }
1021 #endif
1022 }
1023
1024 void MyStatusBar::UpdateClock()
1025 {
1026 SetStatusText(wxDateTime::Now().FormatTime(), Field_Clock);
1027 }