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