The rounded corners look really dumb at this size.
[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 // Copyright: (c) Vadim Zeitlin
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // ============================================================================
11 // declarations
12 // ============================================================================
13
14 // ----------------------------------------------------------------------------
15 // headers
16 // ----------------------------------------------------------------------------
17
18 // For compilers that support precompilation, includes "wx/wx.h".
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 #if !wxUSE_STATUSBAR
26 #error "You need to set wxUSE_STATUSBAR to 1 to compile this sample"
27 #endif // wxUSE_STATUSBAR
28
29 // for all others, include the necessary headers
30 #ifndef WX_PRECOMP
31 #include "wx/app.h"
32 #include "wx/dcclient.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 wxHAS_IMAGES_IN_RESOURCES
53 #include "../sample.xpm"
54 #endif
55
56 //#define USE_MDI_PARENT_FRAME 1
57 #ifdef USE_MDI_PARENT_FRAME
58 #include "wx/mdi.h"
59 #endif // USE_MDI_PARENT_FRAME
60
61 static const char *SAMPLE_DIALOGS_TITLE = "wxWidgets statbar sample";
62
63 // ----------------------------------------------------------------------------
64 // resources
65 // ----------------------------------------------------------------------------
66
67 #include "green.xpm"
68 #include "red.xpm"
69
70 // ----------------------------------------------------------------------------
71 // private classes
72 // ----------------------------------------------------------------------------
73
74 // Define a new application type, each program should derive a class from wxApp
75 class MyApp : public wxApp
76 {
77 public:
78 // override base class virtuals
79 // ----------------------------
80
81 // this one is called on application startup and is a good place for the app
82 // initialization (doing it here and not in the ctor allows to have an error
83 // return: if OnInit() returns false, the application terminates)
84 virtual bool OnInit();
85 };
86
87 // A custom status bar which contains controls, icons &c
88 class MyStatusBar : public wxStatusBar
89 {
90 public:
91 MyStatusBar(wxWindow *parent, long style = wxSTB_DEFAULT_STYLE);
92 virtual ~MyStatusBar();
93
94 void UpdateClock();
95
96 // event handlers
97 #if wxUSE_TIMER
98 void OnTimer(wxTimerEvent& WXUNUSED(event)) { UpdateClock(); }
99 #endif
100 void OnSize(wxSizeEvent& event);
101 void OnToggleClock(wxCommandEvent& event);
102 void OnIdle(wxIdleEvent& event);
103
104 private:
105 // toggle the state of the status bar controls
106 void DoToggle();
107
108 enum
109 {
110 Field_Text,
111 Field_Checkbox,
112 Field_Bitmap,
113 Field_NumLockIndicator,
114 Field_Clock,
115 Field_CapsLockIndicator,
116 Field_Max
117 };
118
119 #if wxUSE_TIMER
120 wxTimer m_timer;
121 #endif
122
123 #if wxUSE_CHECKBOX
124 wxCheckBox *m_checkbox;
125 #endif
126 wxStaticBitmap *m_statbmp;
127
128 DECLARE_EVENT_TABLE()
129 };
130
131 // Define a new frame type: this is going to be our main frame
132 #ifdef USE_MDI_PARENT_FRAME
133 class MyFrame : public wxMDIParentFrame
134 #else
135 class MyFrame : public wxFrame
136 #endif
137 {
138 public:
139 // ctor(s)
140 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
141
142 // event handlers (these functions should _not_ be virtual)
143 void OnQuit(wxCommandEvent& event);
144 void OnAbout(wxCommandEvent& event);
145
146 void OnSetStatusField(wxCommandEvent& event);
147 void OnSetStatusText(wxCommandEvent& event);
148 void OnPushStatusText(wxCommandEvent& event);
149 void OnPopStatusText(wxCommandEvent& event);
150
151 void OnResetFieldsWidth(wxCommandEvent& event);
152 void OnShowFieldsRect(wxCommandEvent& event);
153 void OnSetStatusFields(wxCommandEvent& event);
154 void OnSetStatusFont(wxCommandEvent& event);
155 void OnRecreateStatusBar(wxCommandEvent& event);
156
157 void OnSetPaneStyle(wxCommandEvent& event);
158 void OnSetStyle(wxCommandEvent& event);
159
160 private:
161 enum StatusBarKind
162 {
163 StatBar_Default,
164 StatBar_Custom,
165 StatBar_Max
166 } m_statbarKind;
167
168
169 void OnUpdateForDefaultStatusbar(wxUpdateUIEvent& event);
170 void OnUpdateStatusBarToggle(wxUpdateUIEvent& event);
171 void OnUpdateSetPaneStyle(wxUpdateUIEvent& event);
172 void OnUpdateSetStyle(wxUpdateUIEvent& event);
173 void OnStatusBarToggle(wxCommandEvent& event);
174 void DoCreateStatusBar(StatusBarKind kind, long style);
175 void ApplyPaneStyle();
176
177 int m_statbarPaneStyle;
178
179 // the index of the field used by some commands
180 int m_field;
181
182 // any class wishing to process wxWidgets events must use this macro
183 DECLARE_EVENT_TABLE()
184 };
185
186 // Our about dialog ith its status bar
187 class MyAboutDialog : public wxDialog
188 {
189 public:
190 MyAboutDialog(wxWindow *parent);
191 };
192
193 // ----------------------------------------------------------------------------
194 // constants
195 // ----------------------------------------------------------------------------
196
197 // IDs for the controls and the menu commands
198 enum
199 {
200 // menu items
201 StatusBar_Quit = wxID_EXIT,
202 StatusBar_About = wxID_ABOUT,
203
204 StatusBar_SetFields = wxID_HIGHEST+1,
205 StatusBar_SetField,
206 StatusBar_SetText,
207 StatusBar_PushText,
208 StatusBar_PopText,
209 StatusBar_SetFont,
210 StatusBar_ResetFieldsWidth,
211 StatusBar_ShowFieldsRect,
212
213 StatusBar_Recreate,
214 StatusBar_Toggle,
215 StatusBar_Checkbox,
216 StatusBar_SetPaneStyle,
217 StatusBar_SetPaneStyleNormal,
218 StatusBar_SetPaneStyleFlat,
219 StatusBar_SetPaneStyleRaised,
220 StatusBar_SetPaneStyleSunken,
221
222 StatusBar_SetStyleSizeGrip,
223 StatusBar_SetStyleEllipsizeStart,
224 StatusBar_SetStyleEllipsizeMiddle,
225 StatusBar_SetStyleEllipsizeEnd,
226 StatusBar_SetStyleShowTips
227 };
228
229 static const int BITMAP_SIZE_X = 32;
230 static const int BITMAP_SIZE_Y = 15;
231
232 // ----------------------------------------------------------------------------
233 // event tables and other macros for wxWidgets
234 // ----------------------------------------------------------------------------
235
236 // the event tables connect the wxWidgets events with the functions (event
237 // handlers) which process them. It can be also done at run-time, but for the
238 // simple menu events like this the static method is much simpler.
239 #ifdef USE_MDI_PARENT_FRAME
240 BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
241 #else
242 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
243 #endif
244 EVT_MENU(StatusBar_Quit, MyFrame::OnQuit)
245 EVT_MENU(StatusBar_SetFields, MyFrame::OnSetStatusFields)
246 EVT_MENU(StatusBar_SetField, MyFrame::OnSetStatusField)
247 EVT_MENU(StatusBar_SetText, MyFrame::OnSetStatusText)
248 EVT_MENU(StatusBar_PushText, MyFrame::OnPushStatusText)
249 EVT_MENU(StatusBar_PopText, MyFrame::OnPopStatusText)
250 EVT_MENU(StatusBar_SetFont, MyFrame::OnSetStatusFont)
251 EVT_MENU(StatusBar_ResetFieldsWidth, MyFrame::OnResetFieldsWidth)
252 EVT_MENU(StatusBar_ShowFieldsRect, MyFrame::OnShowFieldsRect)
253 EVT_MENU(StatusBar_Recreate, MyFrame::OnRecreateStatusBar)
254 EVT_MENU(StatusBar_About, MyFrame::OnAbout)
255 EVT_MENU(StatusBar_Toggle, MyFrame::OnStatusBarToggle)
256 EVT_MENU(StatusBar_SetPaneStyleNormal, MyFrame::OnSetPaneStyle)
257 EVT_MENU(StatusBar_SetPaneStyleFlat, MyFrame::OnSetPaneStyle)
258 EVT_MENU(StatusBar_SetPaneStyleRaised, MyFrame::OnSetPaneStyle)
259 EVT_MENU(StatusBar_SetPaneStyleSunken, MyFrame::OnSetPaneStyle)
260
261 EVT_MENU(StatusBar_SetStyleSizeGrip, MyFrame::OnSetStyle)
262 EVT_MENU(StatusBar_SetStyleEllipsizeStart, MyFrame::OnSetStyle)
263 EVT_MENU(StatusBar_SetStyleEllipsizeMiddle, MyFrame::OnSetStyle)
264 EVT_MENU(StatusBar_SetStyleEllipsizeEnd, MyFrame::OnSetStyle)
265 EVT_MENU(StatusBar_SetStyleShowTips, MyFrame::OnSetStyle)
266
267 EVT_UPDATE_UI_RANGE(StatusBar_SetFields, StatusBar_ResetFieldsWidth,
268 MyFrame::OnUpdateForDefaultStatusbar)
269 EVT_UPDATE_UI(StatusBar_Toggle, MyFrame::OnUpdateStatusBarToggle)
270 EVT_UPDATE_UI_RANGE(StatusBar_SetPaneStyleNormal,
271 StatusBar_SetPaneStyleSunken,
272 MyFrame::OnUpdateSetPaneStyle)
273 EVT_UPDATE_UI_RANGE(StatusBar_SetStyleSizeGrip, StatusBar_SetStyleShowTips,
274 MyFrame::OnUpdateSetStyle)
275 END_EVENT_TABLE()
276
277 BEGIN_EVENT_TABLE(MyStatusBar, wxStatusBar)
278 EVT_SIZE(MyStatusBar::OnSize)
279 #if wxUSE_CHECKBOX
280 EVT_CHECKBOX(StatusBar_Checkbox, MyStatusBar::OnToggleClock)
281 #endif
282 #if wxUSE_TIMER
283 EVT_TIMER(wxID_ANY, MyStatusBar::OnTimer)
284 #endif
285 EVT_IDLE(MyStatusBar::OnIdle)
286 END_EVENT_TABLE()
287
288 // Create a new application object: this macro will allow wxWidgets to create
289 // the application object during program execution (it's better than using a
290 // static object for many reasons) and also declares the accessor function
291 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
292 // not wxApp)
293 IMPLEMENT_APP(MyApp)
294
295 // ============================================================================
296 // implementation
297 // ============================================================================
298
299 // ----------------------------------------------------------------------------
300 // the application class
301 // ----------------------------------------------------------------------------
302
303 // `Main program' equivalent: the program execution "starts" here
304 bool MyApp::OnInit()
305 {
306 if ( !wxApp::OnInit() )
307 return false;
308
309 // create the main application window
310 MyFrame *frame = new MyFrame(wxT("wxStatusBar sample"),
311 wxPoint(50, 50), wxSize(450, 340));
312
313 // and show it (the frames, unlike simple controls, are not shown when
314 // created initially)
315 frame->Show(true);
316
317 // success: wxApp::OnRun() will be called which will enter the main message
318 // loop and the application will run. If we returned 'false' here, the
319 // application would exit immediately.
320 return true;
321 }
322
323 // ----------------------------------------------------------------------------
324 // main frame
325 // ----------------------------------------------------------------------------
326
327 // frame constructor
328 MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
329 #ifdef USE_MDI_PARENT_FRAME
330 : wxMDIParentFrame(NULL, wxID_ANY, title, pos, size)
331 #else
332 : wxFrame(NULL, wxID_ANY, title, pos, size)
333 #endif
334 {
335 SetIcon(wxICON(sample));
336
337 m_statbarPaneStyle = wxSB_NORMAL;
338 m_field = 1;
339
340 // create a menu bar
341 wxMenu *menuFile = new wxMenu;
342 menuFile->Append(StatusBar_Quit, wxT("E&xit\tAlt-X"),
343 wxT("Quit this program"));
344
345 wxMenu *statbarMenu = new wxMenu;
346
347 wxMenu *statbarStyleMenu = new wxMenu;
348 statbarStyleMenu->Append(StatusBar_SetStyleSizeGrip, wxT("wxSTB_SIZE_GRIP"),
349 wxT("Toggles the wxSTB_SIZE_GRIP style"), true);
350 statbarStyleMenu->Append(StatusBar_SetStyleShowTips, wxT("wxSTB_SHOW_TIPS"),
351 wxT("Toggles the wxSTB_SHOW_TIPS style"), true);
352 statbarStyleMenu->AppendSeparator();
353 statbarStyleMenu->AppendCheckItem(StatusBar_SetStyleEllipsizeStart,
354 wxT("wxSTB_ELLIPSIZE_START"),
355 wxT("Toggle wxSTB_ELLIPSIZE_START style"));
356 statbarStyleMenu->AppendCheckItem(StatusBar_SetStyleEllipsizeMiddle,
357 wxT("wxSTB_ELLIPSIZE_MIDDLE"),
358 wxT("Toggle wxSTB_ELLIPSIZE_MIDDLE style"));
359 statbarStyleMenu->AppendCheckItem(StatusBar_SetStyleEllipsizeEnd,
360 wxT("wxSTB_ELLIPSIZE_END"),
361 wxT("Toggle wxSTB_ELLIPSIZE_END style"));
362 statbarMenu->Append(StatusBar_SetPaneStyle, wxT("Status bar style"),
363 statbarStyleMenu);
364 statbarMenu->AppendSeparator();
365
366 statbarMenu->Append(StatusBar_SetField, "Set active field &number\tCtrl-N",
367 "Set the number of field used by the next commands.");
368 statbarMenu->Append(StatusBar_SetText, wxT("Set field &text\tCtrl-T"),
369 wxT("Set the text of the selected field."));
370 statbarMenu->Append(StatusBar_PushText, "P&ush field text\tCtrl-P",
371 "Push a message on top the selected field.");
372 statbarMenu->Append(StatusBar_PopText, "&Pop field text\tShift-Ctrl-P",
373 "Restore the previous contents of the selected field.");
374 statbarMenu->AppendSeparator();
375
376 statbarMenu->Append(StatusBar_SetFields, wxT("&Set field count\tCtrl-C"),
377 wxT("Set the number of status bar fields"));
378 statbarMenu->Append(StatusBar_SetFont, wxT("&Set field font\tCtrl-F"),
379 wxT("Set the font to use for status bar fields"));
380
381 wxMenu *statbarPaneStyleMenu = new wxMenu;
382 statbarPaneStyleMenu->AppendCheckItem
383 (
384 StatusBar_SetPaneStyleNormal,
385 wxT("&Normal"),
386 wxT("Sets the style of the first field to normal (sunken) look")
387 );
388 statbarPaneStyleMenu->AppendCheckItem
389 (
390 StatusBar_SetPaneStyleFlat,
391 wxT("&Flat"),
392 wxT("Sets the style of the first field to flat look")
393 );
394 statbarPaneStyleMenu->AppendCheckItem
395 (
396 StatusBar_SetPaneStyleRaised,
397 wxT("&Raised"),
398 wxT("Sets the style of the first field to raised look")
399 );
400 statbarPaneStyleMenu->AppendCheckItem
401 (
402 StatusBar_SetPaneStyleSunken,
403 wxT("&Sunken"),
404 wxT("Sets the style of the first field to sunken look")
405 );
406 statbarMenu->Append(StatusBar_SetPaneStyle, wxT("Field style"),
407 statbarPaneStyleMenu);
408
409 statbarMenu->Append(StatusBar_ResetFieldsWidth, wxT("Reset field widths"),
410 wxT("Sets all fields to the same width"));
411 statbarMenu->Append(StatusBar_ShowFieldsRect,
412 wxT("Sho&w field rectangles\tCtrl-W"),
413 wxT("Visually show field rectangles"));
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::OnShowFieldsRect(wxCommandEvent& WXUNUSED(event))
663 {
664 wxStatusBar *pStat = GetStatusBar();
665 if ( !pStat )
666 return;
667
668 wxClientDC dc(pStat);
669 dc.SetPen(*wxRED_PEN);
670 dc.SetBrush(*wxTRANSPARENT_BRUSH);
671
672 const int n = pStat->GetFieldsCount();
673 for ( int i = 0; i < n; i++ )
674 {
675 wxRect r;
676 if ( pStat->GetFieldRect(i, r) )
677 dc.DrawRectangle(r);
678 }
679 }
680
681 void MyFrame::OnUpdateStatusBarToggle(wxUpdateUIEvent& event)
682 {
683 event.Check(GetStatusBar() != NULL);
684 }
685
686 void MyFrame::OnStatusBarToggle(wxCommandEvent& WXUNUSED(event))
687 {
688 wxStatusBar *statbarOld = GetStatusBar();
689 if ( statbarOld )
690 {
691 SetStatusBar(NULL);
692 delete statbarOld;
693 }
694 else
695 {
696 DoCreateStatusBar(m_statbarKind, wxSTB_DEFAULT_STYLE);
697 }
698 }
699
700 void MyFrame::OnRecreateStatusBar(wxCommandEvent& WXUNUSED(event))
701 {
702 DoCreateStatusBar(m_statbarKind == StatBar_Custom ? StatBar_Default
703 : StatBar_Custom,
704 wxSTB_DEFAULT_STYLE);
705 }
706
707 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
708 {
709 // true is to force the frame to close
710 Close(true);
711 }
712
713 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
714 {
715 MyAboutDialog dlg(this);
716 dlg.ShowModal();
717 }
718
719 void MyFrame::OnUpdateSetPaneStyle(wxUpdateUIEvent& event)
720 {
721 switch (event.GetId())
722 {
723 case StatusBar_SetPaneStyleNormal:
724 event.Check(m_statbarPaneStyle == wxSB_NORMAL);
725 break;
726 case StatusBar_SetPaneStyleFlat:
727 event.Check(m_statbarPaneStyle == wxSB_FLAT);
728 break;
729 case StatusBar_SetPaneStyleRaised:
730 event.Check(m_statbarPaneStyle == wxSB_RAISED);
731 break;
732 case StatusBar_SetPaneStyleSunken:
733 event.Check(m_statbarPaneStyle == wxSB_SUNKEN);
734 break;
735 }
736 }
737
738 void MyFrame::OnSetPaneStyle(wxCommandEvent& event)
739 {
740 switch (event.GetId())
741 {
742 case StatusBar_SetPaneStyleNormal:
743 m_statbarPaneStyle = wxSB_NORMAL;
744 break;
745 case StatusBar_SetPaneStyleFlat:
746 m_statbarPaneStyle = wxSB_FLAT;
747 break;
748 case StatusBar_SetPaneStyleRaised:
749 m_statbarPaneStyle = wxSB_RAISED;
750 break;
751 case StatusBar_SetPaneStyleSunken:
752 m_statbarPaneStyle = wxSB_SUNKEN;
753 break;
754 }
755
756 ApplyPaneStyle();
757 }
758
759 void MyFrame::ApplyPaneStyle()
760 {
761 wxStatusBar *sb = GetStatusBar();
762 if (!sb)
763 return;
764
765 int fields = sb->GetFieldsCount();
766 int *styles = new int[fields];
767
768 for (int i = 1; i < fields; i++)
769 styles[i] = wxSB_NORMAL;
770
771 styles[0] = m_statbarPaneStyle;
772
773 sb->SetStatusStyles(fields, styles);
774
775 delete [] styles;
776 }
777
778 void MyFrame::OnUpdateSetStyle(wxUpdateUIEvent& event)
779 {
780 long currentStyle = wxSTB_DEFAULT_STYLE;
781 if (GetStatusBar())
782 currentStyle = GetStatusBar()->GetWindowStyle();
783
784 switch (event.GetId())
785 {
786 case StatusBar_SetStyleSizeGrip:
787 event.Check((currentStyle & wxSTB_SIZEGRIP) != 0);
788 break;
789 case StatusBar_SetStyleShowTips:
790 event.Check((currentStyle & wxSTB_SHOW_TIPS) != 0);
791 break;
792
793 case StatusBar_SetStyleEllipsizeStart:
794 event.Check((currentStyle & wxSTB_ELLIPSIZE_START) != 0);
795 break;
796 case StatusBar_SetStyleEllipsizeMiddle:
797 event.Check((currentStyle & wxSTB_ELLIPSIZE_MIDDLE) != 0);
798 break;
799 case StatusBar_SetStyleEllipsizeEnd:
800 event.Check((currentStyle & wxSTB_ELLIPSIZE_END) != 0);
801 break;
802 }
803 }
804
805 void MyFrame::OnSetStyle(wxCommandEvent& event)
806 {
807 long oldStyle = wxSTB_DEFAULT_STYLE;
808 if (GetStatusBar())
809 oldStyle = GetStatusBar()->GetWindowStyle();
810
811 #define STB_ELLIPSIZE_MASK \
812 (wxSTB_ELLIPSIZE_START|wxSTB_ELLIPSIZE_MIDDLE|wxSTB_ELLIPSIZE_END)
813
814 long newStyle = oldStyle;
815 long newStyleBit = 0;
816 switch (event.GetId())
817 {
818 case StatusBar_SetStyleSizeGrip:
819 newStyleBit = wxSTB_SIZEGRIP;
820 break;
821 case StatusBar_SetStyleShowTips:
822 newStyleBit = wxSTB_SHOW_TIPS;
823 break;
824
825 case StatusBar_SetStyleEllipsizeStart:
826 newStyleBit = wxSTB_ELLIPSIZE_START;
827 newStyle &= ~STB_ELLIPSIZE_MASK;
828 break;
829 case StatusBar_SetStyleEllipsizeMiddle:
830 newStyleBit = wxSTB_ELLIPSIZE_MIDDLE;
831 newStyle &= ~STB_ELLIPSIZE_MASK;
832 break;
833 case StatusBar_SetStyleEllipsizeEnd:
834 newStyleBit = wxSTB_ELLIPSIZE_END;
835 newStyle &= ~STB_ELLIPSIZE_MASK;
836 break;
837 }
838
839 newStyle = event.IsChecked() ? (newStyle | newStyleBit) :
840 (newStyle & ~newStyleBit);
841 if (newStyle != oldStyle)
842 {
843 DoCreateStatusBar(m_statbarKind, newStyle);
844 SetStatusText("Status bar recreated with a new style");
845 }
846 }
847
848 // ----------------------------------------------------------------------------
849 // MyAboutDialog
850 // ----------------------------------------------------------------------------
851
852 MyAboutDialog::MyAboutDialog(wxWindow *parent)
853 : wxDialog(parent, wxID_ANY, wxString(wxT("About statbar")),
854 wxDefaultPosition, wxDefaultSize,
855 wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
856 {
857 wxStaticText *text = new wxStaticText(this, wxID_ANY,
858 wxT("wxStatusBar sample\n")
859 wxT("(c) 2000 Vadim Zeitlin"));
860
861 wxButton *btn = new wxButton(this, wxID_OK, wxT("&Close"));
862
863 // create the top status bar without the size grip (default style),
864 // otherwise it looks weird
865 wxStatusBar *statbarTop = new wxStatusBar(this, wxID_ANY, 0);
866 statbarTop->SetFieldsCount(3);
867 statbarTop->SetStatusText(wxT("This is a top status bar"), 0);
868 statbarTop->SetStatusText(wxT("in a dialog"), 1);
869 statbarTop->SetStatusText(wxT("Great, isn't it?"), 2);
870
871 wxStatusBar *statbarBottom = new wxStatusBar(this, wxID_ANY);
872 statbarBottom->SetFieldsCount(2);
873 statbarBottom->SetStatusText(wxT("This is a bottom status bar"), 0);
874 statbarBottom->SetStatusText(wxT("in a dialog"), 1);
875
876 wxBoxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
877 sizerTop->Add(statbarTop, 0, wxGROW);
878 sizerTop->Add(-1, 10, 1, wxGROW);
879 sizerTop->Add(text, 0, wxCENTRE | wxRIGHT | wxLEFT, 20);
880 sizerTop->Add(-1, 10, 1, wxGROW);
881 sizerTop->Add(btn, 0, wxCENTRE | wxRIGHT | wxLEFT, 20);
882 sizerTop->Add(-1, 10, 1, wxGROW);
883 sizerTop->Add(statbarBottom, 0, wxGROW);
884
885 SetSizerAndFit(sizerTop);
886 }
887
888 // ----------------------------------------------------------------------------
889 // MyStatusBar
890 // ----------------------------------------------------------------------------
891
892 #ifdef __VISUALC__
893 // 'this' : used in base member initializer list -- so what??
894 #pragma warning(disable: 4355)
895 #endif
896
897 static const char *numlockIndicators[] = { "OFF", "NUM" };
898 static const char *capslockIndicators[] = { "", "CAPS" };
899
900 MyStatusBar::MyStatusBar(wxWindow *parent, long style)
901 : wxStatusBar(parent, wxID_ANY, style, "MyStatusBar")
902 #if wxUSE_TIMER
903 , m_timer(this)
904 #endif
905 #if wxUSE_CHECKBOX
906 , m_checkbox(NULL)
907 #endif
908 {
909 // compute the size needed for num lock indicator pane
910 wxClientDC dc(this);
911 wxSize sizeNumLock = dc.GetTextExtent(numlockIndicators[0]);
912 sizeNumLock.IncTo(dc.GetTextExtent(numlockIndicators[1]));
913
914 int widths[Field_Max];
915 widths[Field_Text] = -1; // growable
916 widths[Field_Checkbox] = 150;
917 widths[Field_Bitmap] = BITMAP_SIZE_X;
918 widths[Field_NumLockIndicator] = sizeNumLock.x;
919 widths[Field_Clock] = 100;
920 widths[Field_CapsLockIndicator] = dc.GetTextExtent(capslockIndicators[1]).x;
921
922 SetFieldsCount(Field_Max);
923 SetStatusWidths(Field_Max, widths);
924
925 #if wxUSE_CHECKBOX
926 m_checkbox = new wxCheckBox(this, StatusBar_Checkbox, wxT("&Toggle clock"));
927 m_checkbox->SetValue(true);
928 #endif
929
930 m_statbmp = new wxStaticBitmap(this, wxID_ANY, wxIcon(green_xpm));
931
932 #if wxUSE_TIMER
933 m_timer.Start(1000);
934 #endif
935
936 SetMinHeight(wxMax(m_statbmp->GetBestSize().GetHeight(),
937 m_checkbox->GetBestSize().GetHeight()));
938
939 UpdateClock();
940 }
941
942 #ifdef __VISUALC__
943 #pragma warning(default: 4355)
944 #endif
945
946 MyStatusBar::~MyStatusBar()
947 {
948 #if wxUSE_TIMER
949 if ( m_timer.IsRunning() )
950 {
951 m_timer.Stop();
952 }
953 #endif
954 }
955
956 void MyStatusBar::OnSize(wxSizeEvent& event)
957 {
958 #if wxUSE_CHECKBOX
959 if ( !m_checkbox )
960 return;
961 #endif
962
963 wxRect rect;
964 if (!GetFieldRect(Field_Checkbox, rect))
965 {
966 event.Skip();
967 return;
968 }
969
970 #if wxUSE_CHECKBOX
971 wxRect rectCheck = rect;
972 rectCheck.Deflate(2);
973 m_checkbox->SetSize(rectCheck);
974 #endif
975
976 GetFieldRect(Field_Bitmap, rect);
977 wxSize size = m_statbmp->GetSize();
978
979 m_statbmp->Move(rect.x + (rect.width - size.x) / 2,
980 rect.y + (rect.height - size.y) / 2);
981
982 event.Skip();
983 }
984
985 void MyStatusBar::OnToggleClock(wxCommandEvent& WXUNUSED(event))
986 {
987 DoToggle();
988 }
989
990 void MyStatusBar::OnIdle(wxIdleEvent& event)
991 {
992 SetStatusText(numlockIndicators[wxGetKeyState(WXK_NUMLOCK)],
993 Field_NumLockIndicator);
994 SetStatusText(capslockIndicators[wxGetKeyState(WXK_CAPITAL)],
995 Field_CapsLockIndicator);
996
997 event.Skip();
998 }
999
1000 void MyStatusBar::DoToggle()
1001 {
1002 #if wxUSE_CHECKBOX
1003 if ( m_checkbox->GetValue() )
1004 {
1005 #if wxUSE_TIMER
1006 m_timer.Start(1000);
1007 #endif
1008
1009 m_statbmp->SetIcon(wxIcon(green_xpm));
1010
1011 UpdateClock();
1012 }
1013 else // don't show clock
1014 {
1015 #if wxUSE_TIMER
1016 m_timer.Stop();
1017 #endif
1018
1019 m_statbmp->SetIcon(wxIcon(red_xpm));
1020
1021 SetStatusText(wxEmptyString, Field_Clock);
1022 }
1023 #endif // wxUSE_CHECKBOX
1024 }
1025
1026 void MyStatusBar::UpdateClock()
1027 {
1028 SetStatusText(wxDateTime::Now().FormatTime(), Field_Clock);
1029 }