]> git.saurik.com Git - wxWidgets.git/blame_incremental - samples/statbar/statbar.cpp
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / samples / statbar / statbar.cpp
... / ...
CommitLineData
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
61static 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
75class MyApp : public wxApp
76{
77public:
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
88class MyStatusBar : public wxStatusBar
89{
90public:
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
104private:
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
133class MyFrame : public wxMDIParentFrame
134#else
135class MyFrame : public wxFrame
136#endif
137{
138public:
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
160private:
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
187class MyAboutDialog : public wxDialog
188{
189public:
190 MyAboutDialog(wxWindow *parent);
191};
192
193// ----------------------------------------------------------------------------
194// constants
195// ----------------------------------------------------------------------------
196
197// IDs for the controls and the menu commands
198enum
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
229static const int BITMAP_SIZE_X = 32;
230static 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
240BEGIN_EVENT_TABLE(MyFrame, wxMDIParentFrame)
241#else
242BEGIN_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)
275END_EVENT_TABLE()
276
277BEGIN_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)
286END_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)
293IMPLEMENT_APP(MyApp)
294
295// ============================================================================
296// implementation
297// ============================================================================
298
299// ----------------------------------------------------------------------------
300// the application class
301// ----------------------------------------------------------------------------
302
303// `Main program' equivalent: the program execution "starts" here
304bool 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
328MyFrame::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
439void 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
476void 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
486void 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
515void 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()
540static int gs_depth = 0;
541
542void 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
556void 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
572void 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
587void 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
650void 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
662void 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
681void MyFrame::OnUpdateStatusBarToggle(wxUpdateUIEvent& event)
682{
683 event.Check(GetStatusBar() != NULL);
684}
685
686void 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
700void MyFrame::OnRecreateStatusBar(wxCommandEvent& WXUNUSED(event))
701{
702 DoCreateStatusBar(m_statbarKind == StatBar_Custom ? StatBar_Default
703 : StatBar_Custom,
704 wxSTB_DEFAULT_STYLE);
705}
706
707void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
708{
709 // true is to force the frame to close
710 Close(true);
711}
712
713void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
714{
715 MyAboutDialog dlg(this);
716 dlg.ShowModal();
717}
718
719void 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
738void 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
759void 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
778void 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
805void 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
852MyAboutDialog::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
897static const char *numlockIndicators[] = { "OFF", "NUM" };
898static const char *capslockIndicators[] = { "", "CAPS" };
899
900MyStatusBar::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
946MyStatusBar::~MyStatusBar()
947{
948#if wxUSE_TIMER
949 if ( m_timer.IsRunning() )
950 {
951 m_timer.Stop();
952 }
953#endif
954}
955
956void 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
985void MyStatusBar::OnToggleClock(wxCommandEvent& WXUNUSED(event))
986{
987 DoToggle();
988}
989
990void 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
1000void 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
1026void MyStatusBar::UpdateClock()
1027{
1028 SetStatusText(wxDateTime::Now().FormatTime(), Field_Clock);
1029}