Unicode build fix.
[wxWidgets.git] / samples / widgets / widgets.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Program: wxWidgets Widgets Sample
3 // Name: samples/widgets/widgets.cpp
4 // Purpose: Sample showing most of the simple wxWidgets widgets
5 // Author: Vadim Zeitlin
6 // Created: 27.03.01
7 // Id: $Id$
8 // Copyright: (c) 2001 Vadim Zeitlin
9 // License: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // for compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 // for all others, include the necessary headers
28 #ifndef WX_PRECOMP
29 #include "wx/app.h"
30 #include "wx/log.h"
31 #include "wx/frame.h"
32 #include "wx/menu.h"
33
34 #include "wx/button.h"
35 #include "wx/checkbox.h"
36 #include "wx/listbox.h"
37 #include "wx/statbox.h"
38 #include "wx/stattext.h"
39 #include "wx/textctrl.h"
40 #include "wx/msgdlg.h"
41 #endif
42
43 #include "wx/sysopt.h"
44 #include "wx/bookctrl.h"
45 #include "wx/sizer.h"
46 #include "wx/colordlg.h"
47 #include "wx/fontdlg.h"
48 #include "wx/textdlg.h"
49
50 #include "widgets.h"
51
52 // ----------------------------------------------------------------------------
53 // constants
54 // ----------------------------------------------------------------------------
55
56 // control ids
57 enum
58 {
59 Widgets_ClearLog = 100,
60 Widgets_Quit,
61
62 Widgets_BookCtrl,
63
64 #if wxUSE_TOOLTIPS
65 Widgets_SetTooltip,
66 #endif // wxUSE_TOOLTIPS
67 Widgets_SetFgColour,
68 Widgets_SetBgColour,
69 Widgets_SetFont,
70 Widgets_Enable,
71
72 Widgets_BorderNone,
73 Widgets_BorderStatic,
74 Widgets_BorderSimple,
75 Widgets_BorderRaised,
76 Widgets_BorderSunken,
77 Widgets_BorderDouble,
78 Widgets_BorderDefault,
79
80 Widgets_GoToPage,
81 Widgets_GoToPageLast = Widgets_GoToPage + 100
82 };
83
84 // ----------------------------------------------------------------------------
85 // our classes
86 // ----------------------------------------------------------------------------
87
88 // Define a new application type, each program should derive a class from wxApp
89 class WidgetsApp : public wxApp
90 {
91 public:
92 // override base class virtuals
93 // ----------------------------
94
95 // this one is called on application startup and is a good place for the app
96 // initialization (doing it here and not in the ctor allows to have an error
97 // return: if OnInit() returns false, the application terminates)
98 virtual bool OnInit();
99 };
100
101 // Define a new frame type: this is going to be our main frame
102 class WidgetsFrame : public wxFrame
103 {
104 public:
105 // ctor(s) and dtor
106 WidgetsFrame(const wxString& title);
107 virtual ~WidgetsFrame();
108
109 protected:
110 // event handlers
111 #if USE_LOG
112 void OnButtonClearLog(wxCommandEvent& event);
113 #endif // USE_LOG
114 void OnExit(wxCommandEvent& event);
115
116 #if wxUSE_MENUS
117 void OnPageChanged(wxBookCtrlEvent& event);
118 void OnGoToPage(wxCommandEvent& event);
119
120 #if wxUSE_TOOLTIPS
121 void OnSetTooltip(wxCommandEvent& event);
122 #endif // wxUSE_TOOLTIPS
123 void OnSetFgCol(wxCommandEvent& event);
124 void OnSetBgCol(wxCommandEvent& event);
125 void OnSetFont(wxCommandEvent& event);
126 void OnEnable(wxCommandEvent& event);
127 void OnSetBorder(wxCommandEvent& event);
128 #endif // wxUSE_MENUS
129
130 // initialize the book: add all pages to it
131 void InitBook();
132
133 private:
134 // the panel containing everything
135 wxPanel *m_panel;
136
137 #if USE_LOG
138 // the listbox for logging messages
139 wxListBox *m_lboxLog;
140
141 // the log target we use to redirect messages to the listbox
142 wxLog *m_logTarget;
143 #endif // USE_LOG
144
145 // the book containing the test pages
146 wxBookCtrlBase *m_book;
147
148 // and the image list for it
149 wxImageList *m_imaglist;
150
151 #if wxUSE_MENUS
152 // last chosen fg/bg colours and font
153 wxColour m_colFg,
154 m_colBg;
155 wxFont m_font;
156 #endif // wxUSE_MENUS
157
158 // any class wishing to process wxWidgets events must use this macro
159 DECLARE_EVENT_TABLE()
160 };
161
162 #if USE_LOG
163 // A log target which just redirects the messages to a listbox
164 class LboxLogger : public wxLog
165 {
166 public:
167 LboxLogger(wxListBox *lbox, wxLog *logOld)
168 {
169 m_lbox = lbox;
170 //m_lbox->Disable(); -- looks ugly under MSW
171 m_logOld = logOld;
172 }
173
174 virtual ~LboxLogger()
175 {
176 wxLog::SetActiveTarget(m_logOld);
177 }
178
179 private:
180 // implement sink functions
181 virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t)
182 {
183 // don't put trace messages into listbox or we can get into infinite
184 // recursion
185 if ( level == wxLOG_Trace )
186 {
187 if ( m_logOld )
188 {
189 // cast is needed to call protected method
190 ((LboxLogger *)m_logOld)->DoLog(level, szString, t);
191 }
192 }
193 else
194 {
195 wxLog::DoLog(level, szString, t);
196 }
197 }
198
199 virtual void DoLogString(const wxChar *szString, time_t WXUNUSED(t))
200 {
201 wxString msg;
202 TimeStamp(&msg);
203 msg += szString;
204
205 #ifdef __WXUNIVERSAL__
206 m_lbox->AppendAndEnsureVisible(msg);
207 #else // other ports don't have this method yet
208 m_lbox->Append(msg);
209 m_lbox->SetFirstItem(m_lbox->GetCount() - 1);
210 #endif
211 }
212
213 // the control we use
214 wxListBox *m_lbox;
215
216 // the old log target
217 wxLog *m_logOld;
218 };
219 #endif // USE_LOG
220
221 // array of pages
222 WX_DEFINE_ARRAY_PTR(WidgetsPage *, ArrayWidgetsPage);
223
224 // ----------------------------------------------------------------------------
225 // misc macros
226 // ----------------------------------------------------------------------------
227
228 IMPLEMENT_APP(WidgetsApp)
229
230 // ----------------------------------------------------------------------------
231 // event tables
232 // ----------------------------------------------------------------------------
233
234 BEGIN_EVENT_TABLE(WidgetsFrame, wxFrame)
235 #if USE_LOG
236 EVT_BUTTON(Widgets_ClearLog, WidgetsFrame::OnButtonClearLog)
237 #endif // USE_LOG
238 EVT_BUTTON(Widgets_Quit, WidgetsFrame::OnExit)
239
240 #if wxUSE_TOOLTIPS
241 EVT_MENU(Widgets_SetTooltip, WidgetsFrame::OnSetTooltip)
242 #endif // wxUSE_TOOLTIPS
243
244 #if wxUSE_MENUS
245 EVT_BOOKCTRL_PAGE_CHANGED(Widgets_BookCtrl, WidgetsFrame::OnPageChanged)
246 EVT_MENU_RANGE(Widgets_GoToPage, Widgets_GoToPageLast,
247 WidgetsFrame::OnGoToPage)
248
249 EVT_MENU(Widgets_SetFgColour, WidgetsFrame::OnSetFgCol)
250 EVT_MENU(Widgets_SetBgColour, WidgetsFrame::OnSetBgCol)
251 EVT_MENU(Widgets_SetFont, WidgetsFrame::OnSetFont)
252 EVT_MENU(Widgets_Enable, WidgetsFrame::OnEnable)
253
254 EVT_MENU_RANGE(Widgets_BorderNone, Widgets_BorderDefault,
255 WidgetsFrame::OnSetBorder)
256
257 EVT_MENU(wxID_EXIT, WidgetsFrame::OnExit)
258 #endif // wxUSE_MENUS
259 END_EVENT_TABLE()
260
261 // ============================================================================
262 // implementation
263 // ============================================================================
264
265 // ----------------------------------------------------------------------------
266 // app class
267 // ----------------------------------------------------------------------------
268
269 bool WidgetsApp::OnInit()
270 {
271 if ( !wxApp::OnInit() )
272 return false;
273
274 // the reason for having these ifdef's is that I often run two copies of
275 // this sample side by side and it is useful to see which one is which
276 wxString title;
277 #if defined(__WXUNIVERSAL__)
278 title = _T("wxUniv/");
279 #endif
280
281 #if defined(__WXMSW__)
282 title += _T("wxMSW");
283 #elif defined(__WXGTK__)
284 title += _T("wxGTK");
285 #elif defined(__WXMAC__)
286 title += _T("wxMAC");
287 #elif defined(__WXMOTIF__)
288 title += _T("wxMOTIF");
289 #else
290 title += _T("wxWidgets");
291 #endif
292
293 wxFrame *frame = new WidgetsFrame(title + _T(" widgets demo"));
294 frame->Show();
295
296 //wxLog::AddTraceMask(_T("listbox"));
297 //wxLog::AddTraceMask(_T("scrollbar"));
298 //wxLog::AddTraceMask(_T("focus"));
299
300 return true;
301 }
302
303 // ----------------------------------------------------------------------------
304 // WidgetsFrame construction
305 // ----------------------------------------------------------------------------
306
307 WidgetsFrame::WidgetsFrame(const wxString& title)
308 : wxFrame(NULL, wxID_ANY, title,
309 wxPoint(0, 50), wxDefaultSize,
310 wxDEFAULT_FRAME_STYLE |
311 wxNO_FULL_REPAINT_ON_RESIZE |
312 wxCLIP_CHILDREN |
313 wxTAB_TRAVERSAL)
314 {
315 // init everything
316 #if USE_LOG
317 m_lboxLog = (wxListBox *)NULL;
318 m_logTarget = (wxLog *)NULL;
319 #endif // USE_LOG
320 m_book = (wxBookCtrlBase *)NULL;
321 m_imaglist = (wxImageList *)NULL;
322
323 #if wxUSE_MENUS
324 // create the menubar
325 wxMenuBar *mbar = new wxMenuBar;
326 wxMenu *menuWidget = new wxMenu;
327 #if wxUSE_TOOLTIPS
328 menuWidget->Append(Widgets_SetTooltip, _T("Set &tooltip...\tCtrl-T"));
329 menuWidget->AppendSeparator();
330 #endif // wxUSE_TOOLTIPS
331 menuWidget->Append(Widgets_SetFgColour, _T("Set &foreground...\tCtrl-F"));
332 menuWidget->Append(Widgets_SetBgColour, _T("Set &background...\tCtrl-B"));
333 menuWidget->Append(Widgets_SetFont, _T("Set f&ont...\tCtrl-O"));
334 menuWidget->AppendCheckItem(Widgets_Enable, _T("&Enable/disable\tCtrl-E"));
335
336 wxMenu *menuBorders = new wxMenu;
337 menuBorders->AppendRadioItem(Widgets_BorderDefault, _T("De&fault\tCtrl-Shift-9"));
338 menuBorders->AppendRadioItem(Widgets_BorderNone, _T("&None\tCtrl-Shift-0"));
339 menuBorders->AppendRadioItem(Widgets_BorderSimple, _T("&Simple\tCtrl-Shift-1"));
340 menuBorders->AppendRadioItem(Widgets_BorderDouble, _T("&Double\tCtrl-Shift-2"));
341 menuBorders->AppendRadioItem(Widgets_BorderStatic, _T("Stati&c\tCtrl-Shift-3"));
342 menuBorders->AppendRadioItem(Widgets_BorderRaised, _T("&Raised\tCtrl-Shift-4"));
343 menuBorders->AppendRadioItem(Widgets_BorderSunken, _T("S&unken\tCtrl-Shift-5"));
344 menuWidget->AppendSubMenu(menuBorders, _T("Set &border"));
345
346 menuWidget->AppendSeparator();
347 menuWidget->Append(wxID_EXIT, _T("&Quit\tCtrl-Q"));
348 mbar->Append(menuWidget, _T("&Widget"));
349 SetMenuBar(mbar);
350
351 mbar->Check(Widgets_Enable, true);
352 #endif // wxUSE_MENUS
353
354 // create controls
355 m_panel = new wxPanel(this, wxID_ANY,
356 wxDefaultPosition, wxDefaultSize, wxCLIP_CHILDREN);
357
358 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
359
360 // we have 2 panes: book with pages demonstrating the controls in the
361 // upper one and the log window with some buttons in the lower
362
363 int style = wxNO_FULL_REPAINT_ON_RESIZE|wxCLIP_CHILDREN|wxBK_DEFAULT;
364 // Uncomment to suppress page theme (draw in solid colour)
365 //style |= wxNB_NOPAGETHEME;
366
367 m_book = new wxBookCtrl(m_panel, Widgets_BookCtrl, wxDefaultPosition,
368 #ifdef __WXMOTIF__
369 wxSize(500, wxDefaultCoord), // under Motif, height is a function of the width...
370 #else
371 wxDefaultSize,
372 #endif
373 style);
374 InitBook();
375
376 #ifndef __SMARTPHONE__
377 // the lower one only has the log listbox and a button to clear it
378 #if USE_LOG
379 wxSizer *sizerDown = new wxStaticBoxSizer(
380 new wxStaticBox( m_panel, wxID_ANY, _T("&Log window") ),
381 wxVERTICAL);
382
383 m_lboxLog = new wxListBox(m_panel, wxID_ANY);
384 sizerDown->Add(m_lboxLog, 1, wxGROW | wxALL, 5);
385 sizerDown->SetMinSize(100, 150);
386 #else
387 wxSizer *sizerDown = new wxBoxSizer(wxVERTICAL);
388 #endif // USE_LOG
389
390 wxBoxSizer *sizerBtns = new wxBoxSizer(wxHORIZONTAL);
391 wxButton *btn;
392 #if USE_LOG
393 btn = new wxButton(m_panel, Widgets_ClearLog, _T("Clear &log"));
394 sizerBtns->Add(btn);
395 sizerBtns->Add(10, 0); // spacer
396 #endif // USE_LOG
397 btn = new wxButton(m_panel, Widgets_Quit, _T("E&xit"));
398 sizerBtns->Add(btn);
399 sizerDown->Add(sizerBtns, 0, wxALL | wxALIGN_RIGHT, 5);
400
401 // put everything together
402 sizerTop->Add(m_book, 1, wxGROW | (wxALL & ~(wxTOP | wxBOTTOM)), 10);
403 sizerTop->Add(0, 5, 0, wxGROW); // spacer in between
404 sizerTop->Add(sizerDown, 0, wxGROW | (wxALL & ~wxTOP), 10);
405
406 #else // !__SMARTPHONE__/__SMARTPHONE__
407
408 sizerTop->Add(m_book, 1, wxGROW | wxALL );
409
410 #endif // __SMARTPHONE__
411
412 m_panel->SetSizer(sizerTop);
413
414 sizerTop->Fit(this);
415 sizerTop->SetSizeHints(this);
416
417 #if USE_LOG && !defined(__WXCOCOA__)
418 // wxCocoa's listbox is too flakey to use for logging right now
419 // now that everything is created we can redirect the log messages to the
420 // listbox
421 m_logTarget = new LboxLogger(m_lboxLog, wxLog::GetActiveTarget());
422 wxLog::SetActiveTarget(m_logTarget);
423 #endif
424 }
425
426 void WidgetsFrame::InitBook()
427 {
428 m_imaglist = new wxImageList(32, 32);
429
430 ArrayWidgetsPage pages;
431 wxArrayString labels;
432
433 wxMenu *menuPages = new wxMenu;
434 unsigned nPage = 0;
435
436 // we need to first create all pages and only then add them to the book
437 // as we need the image list first
438 //
439 // we also construct the pages menu during this first iteration
440 for ( WidgetsPageInfo *info = WidgetsPage::ms_widgetPages;
441 info;
442 info = info->GetNext(), nPage++ )
443 {
444 WidgetsPage *page = (*info->GetCtor())(m_book, m_imaglist);
445 pages.Add(page);
446
447 labels.Add(info->GetLabel());
448 menuPages->AppendRadioItem
449 (
450 Widgets_GoToPage + nPage,
451 wxString::Format(wxT("%s\tF%u"),
452 info->GetLabel().c_str(), nPage + 1)
453 );
454 }
455
456 GetMenuBar()->Append(menuPages, _T("&Page"));
457
458 m_book->SetImageList(m_imaglist);
459
460 // now do add them
461 size_t count = pages.GetCount();
462 for ( size_t n = 0; n < count; n++ )
463 {
464 m_book->AddPage(
465 pages[n],
466 labels[n],
467 false, // don't select
468 n // image id
469 );
470 }
471 }
472
473 WidgetsFrame::~WidgetsFrame()
474 {
475 #if USE_LOG
476 delete m_logTarget;
477 #endif // USE_LOG
478 delete m_imaglist;
479 }
480
481 // ----------------------------------------------------------------------------
482 // WidgetsFrame event handlers
483 // ----------------------------------------------------------------------------
484
485 void WidgetsFrame::OnExit(wxCommandEvent& WXUNUSED(event))
486 {
487 Close();
488 }
489
490 #if USE_LOG
491 void WidgetsFrame::OnButtonClearLog(wxCommandEvent& WXUNUSED(event))
492 {
493 m_lboxLog->Clear();
494 }
495 #endif // USE_LOG
496
497 #if wxUSE_MENUS
498
499 void WidgetsFrame::OnPageChanged(wxBookCtrlEvent& event)
500 {
501 GetMenuBar()->Check(Widgets_GoToPage + event.GetSelection(), true);
502 event.Skip();
503 }
504
505 void WidgetsFrame::OnGoToPage(wxCommandEvent& event)
506 {
507 m_book->SetSelection(event.GetId() - Widgets_GoToPage);
508 }
509
510 #if wxUSE_TOOLTIPS
511
512 void WidgetsFrame::OnSetTooltip(wxCommandEvent& WXUNUSED(event))
513 {
514 static wxString s_tip = _T("This is a tooltip");
515
516 wxString s = wxGetTextFromUser
517 (
518 _T("Tooltip text: "),
519 _T("Widgets sample"),
520 s_tip,
521 this
522 );
523
524 if ( s.empty() )
525 return;
526
527 s_tip = s;
528
529 if( wxMessageBox( _T("Test multiline tooltip text?"),
530 _T("Widgets sample"),
531 wxYES_NO,
532 this
533 ) == wxYES )
534 {
535 s = _T("#1 ") + s_tip + _T("\n") + _T("#2 ") + s_tip;
536 }
537
538 WidgetsPage *page = wxStaticCast(m_book->GetCurrentPage(), WidgetsPage);
539 page->GetWidget()->SetToolTip(s);
540
541 wxControl *ctrl2 = page->GetWidget2();
542 if ( ctrl2 )
543 ctrl2->SetToolTip(s);
544 }
545
546 #endif // wxUSE_TOOLTIPS
547
548 void WidgetsFrame::OnSetFgCol(wxCommandEvent& WXUNUSED(event))
549 {
550 #if wxUSE_COLOURDLG
551 // allow for debugging the default colour the first time this is called
552 WidgetsPage *page = wxStaticCast(m_book->GetCurrentPage(), WidgetsPage);
553 if (!m_colFg.Ok())
554 m_colFg = page->GetForegroundColour();
555
556 wxColour col = wxGetColourFromUser(this, m_colFg);
557 if ( !col.Ok() )
558 return;
559
560 m_colFg = col;
561
562 page->GetWidget()->SetForegroundColour(m_colFg);
563 page->GetWidget()->Refresh();
564
565 wxControl *ctrl2 = page->GetWidget2();
566 if ( ctrl2 )
567 {
568 ctrl2->SetForegroundColour(m_colFg);
569 ctrl2->Refresh();
570 }
571 #else
572 wxLogMessage(_T("Colour selection dialog not available in current build."));
573 #endif
574 }
575
576 void WidgetsFrame::OnSetBgCol(wxCommandEvent& WXUNUSED(event))
577 {
578 #if wxUSE_COLOURDLG
579 WidgetsPage *page = wxStaticCast(m_book->GetCurrentPage(), WidgetsPage);
580 if ( !m_colBg.Ok() )
581 m_colBg = page->GetBackgroundColour();
582
583 wxColour col = wxGetColourFromUser(this, m_colBg);
584 if ( !col.Ok() )
585 return;
586
587 m_colBg = col;
588
589 page->GetWidget()->SetBackgroundColour(m_colBg);
590 page->GetWidget()->Refresh();
591
592 wxControl *ctrl2 = page->GetWidget2();
593 if ( ctrl2 )
594 {
595 ctrl2->SetBackgroundColour(m_colFg);
596 ctrl2->Refresh();
597 }
598 #else
599 wxLogMessage(_T("Colour selection dialog not available in current build."));
600 #endif
601 }
602
603 void WidgetsFrame::OnSetFont(wxCommandEvent& WXUNUSED(event))
604 {
605 #if wxUSE_FONTDLG
606 WidgetsPage *page = wxStaticCast(m_book->GetCurrentPage(), WidgetsPage);
607 if (!m_font.Ok())
608 m_font = page->GetFont();
609
610 wxFont font = wxGetFontFromUser(this, m_font);
611 if ( !font.Ok() )
612 return;
613
614 m_font = font;
615
616 page->GetWidget()->SetFont(m_font);
617 page->GetWidget()->Refresh();
618
619 wxControl *ctrl2 = page->GetWidget2();
620 if ( ctrl2 )
621 {
622 ctrl2->SetFont(m_font);
623 ctrl2->Refresh();
624 }
625 #else
626 wxLogMessage(_T("Font selection dialog not available in current build."));
627 #endif
628 }
629
630 void WidgetsFrame::OnEnable(wxCommandEvent& event)
631 {
632 WidgetsPage *page = wxStaticCast(m_book->GetCurrentPage(), WidgetsPage);
633 page->GetWidget()->Enable(event.IsChecked());
634 }
635
636 void WidgetsFrame::OnSetBorder(wxCommandEvent& event)
637 {
638 int border;
639 switch ( event.GetId() )
640 {
641 case Widgets_BorderNone: border = wxBORDER_NONE; break;
642 case Widgets_BorderStatic: border = wxBORDER_STATIC; break;
643 case Widgets_BorderSimple: border = wxBORDER_SIMPLE; break;
644 case Widgets_BorderRaised: border = wxBORDER_RAISED; break;
645 case Widgets_BorderSunken: border = wxBORDER_SUNKEN; break;
646 case Widgets_BorderDouble: border = wxBORDER_DOUBLE; break;
647
648 default:
649 wxFAIL_MSG( _T("unknown border style") );
650 // fall through
651
652 case Widgets_BorderDefault: border = wxBORDER_DEFAULT; break;
653 }
654
655 WidgetsPage::ms_defaultFlags &= ~wxBORDER_MASK;
656 WidgetsPage::ms_defaultFlags |= border;
657
658 WidgetsPage *page = wxStaticCast(m_book->GetCurrentPage(), WidgetsPage);
659 page->RecreateWidget();
660 }
661
662 #endif // wxUSE_MENUS
663
664 // ----------------------------------------------------------------------------
665 // WidgetsPageInfo
666 // ----------------------------------------------------------------------------
667
668 WidgetsPageInfo::WidgetsPageInfo(Constructor ctor, const wxChar *label)
669 : m_label(label)
670 {
671 m_ctor = ctor;
672
673 m_next = NULL;
674
675 // dummy sorting: add and immediately sort in the list according to label
676 if ( WidgetsPage::ms_widgetPages )
677 {
678 WidgetsPageInfo *node_prev = WidgetsPage::ms_widgetPages;
679 if ( wxStrcmp(label, node_prev->GetLabel().c_str()) < 0 )
680 {
681 // add as first
682 m_next = node_prev;
683 WidgetsPage::ms_widgetPages = this;
684 }
685 else
686 {
687 WidgetsPageInfo *node_next;
688 do
689 {
690 node_next = node_prev->GetNext();
691 if ( node_next )
692 {
693 // add if between two
694 if ( wxStrcmp(label, node_next->GetLabel().c_str()) < 0 )
695 {
696 node_prev->SetNext(this);
697 m_next = node_next;
698 // force to break loop
699 node_next = NULL;
700 }
701 }
702 else
703 {
704 // add as last
705 node_prev->SetNext(this);
706 m_next = node_next;
707 }
708 node_prev = node_next;
709 }
710 while ( node_next );
711 }
712 }
713 else
714 {
715 // add when first
716 WidgetsPage::ms_widgetPages = this;
717 }
718 }
719
720 // ----------------------------------------------------------------------------
721 // WidgetsPage
722 // ----------------------------------------------------------------------------
723
724 int WidgetsPage::ms_defaultFlags = wxBORDER_DEFAULT;
725 WidgetsPageInfo *WidgetsPage::ms_widgetPages = NULL;
726
727 WidgetsPage::WidgetsPage(wxBookCtrlBase *book)
728 : wxPanel(book, wxID_ANY,
729 wxDefaultPosition, wxDefaultSize,
730 wxNO_FULL_REPAINT_ON_RESIZE |
731 wxCLIP_CHILDREN |
732 wxTAB_TRAVERSAL)
733 {
734 }
735
736 wxSizer *WidgetsPage::CreateSizerWithText(wxControl *control,
737 wxWindowID id,
738 wxTextCtrl **ppText)
739 {
740 wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
741 wxTextCtrl *text = new wxTextCtrl(this, id, wxEmptyString,
742 wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
743
744 sizerRow->Add(control, 0, wxRIGHT | wxALIGN_CENTRE_VERTICAL, 5);
745 sizerRow->Add(text, 1, wxLEFT | wxALIGN_CENTRE_VERTICAL, 5);
746
747 if ( ppText )
748 *ppText = text;
749
750 return sizerRow;
751 }
752
753 // create a sizer containing a label and a text ctrl
754 wxSizer *WidgetsPage::CreateSizerWithTextAndLabel(const wxString& label,
755 wxWindowID id,
756 wxTextCtrl **ppText)
757 {
758 return CreateSizerWithText(new wxStaticText(this, wxID_ANY, label),
759 id, ppText);
760 }
761
762 // create a sizer containing a button and a text ctrl
763 wxSizer *WidgetsPage::CreateSizerWithTextAndButton(wxWindowID idBtn,
764 const wxString& label,
765 wxWindowID id,
766 wxTextCtrl **ppText)
767 {
768 return CreateSizerWithText(new wxButton(this, idBtn, label), id, ppText);
769 }
770
771 wxCheckBox *WidgetsPage::CreateCheckBoxAndAddToSizer(wxSizer *sizer,
772 const wxString& label,
773 wxWindowID id)
774 {
775 wxCheckBox *checkbox = new wxCheckBox(this, id, label);
776 sizer->Add(checkbox, 0, wxLEFT | wxRIGHT, 5);
777 sizer->Add(0, 2, 0, wxGROW); // spacer
778
779 return checkbox;
780 }