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: widgets.cpp 58192 2009-01-18 12:29:22Z JS $ 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/treebook.h" 46#include "wx/sizer.h" 47#include "wx/colordlg.h" 48#include "wx/fontdlg.h" 49#include "wx/textdlg.h" 50#include "wx/imaglist.h" 51#include "wx/wupdlock.h" 52 53#include "widgets.h" 54 55#include "../sample.xpm" 56 57// ---------------------------------------------------------------------------- 58// constants 59// ---------------------------------------------------------------------------- 60 61// control ids 62enum 63{ 64 Widgets_ClearLog = 100, 65 Widgets_Quit, 66 67 Widgets_BookCtrl, 68 69#if wxUSE_TOOLTIPS 70 Widgets_SetTooltip, 71#endif // wxUSE_TOOLTIPS 72 Widgets_SetFgColour, 73 Widgets_SetBgColour, 74 Widgets_SetFont, 75 Widgets_Enable, 76 77 Widgets_BorderNone, 78 Widgets_BorderStatic, 79 Widgets_BorderSimple, 80 Widgets_BorderRaised, 81 Widgets_BorderSunken, 82 Widgets_BorderDouble, 83 Widgets_BorderDefault, 84 85 Widgets_GlobalBusyCursor, 86 Widgets_BusyCursor, 87 88 Widgets_GoToPage, 89 Widgets_GoToPageLast = Widgets_GoToPage + 100 90}; 91 92const wxChar *WidgetsCategories[MAX_PAGES] = { 93#if defined(__WXUNIVERSAL__) 94 wxT("Universal"), 95#else 96 wxT("Native"), 97#endif 98 wxT("Generic"), 99 wxT("Pickers"), 100 wxT("Comboboxes"), 101 wxT("With items"), 102 wxT("Editable"), 103 wxT("Books"), 104 wxT("All controls") 105}; 106 107// ---------------------------------------------------------------------------- 108// our classes 109// ---------------------------------------------------------------------------- 110 111// Define a new application type, each program should derive a class from wxApp 112class WidgetsApp : public wxApp 113{ 114public: 115 // override base class virtuals 116 // ---------------------------- 117 118 // this one is called on application startup and is a good place for the app 119 // initialization (doing it here and not in the ctor allows to have an error 120 // return: if OnInit() returns false, the application terminates) 121 virtual bool OnInit(); 122}; 123 124// Define a new frame type: this is going to be our main frame 125class WidgetsFrame : public wxFrame 126{ 127public: 128 // ctor(s) and dtor 129 WidgetsFrame(const wxString& title); 130 virtual ~WidgetsFrame(); 131 132protected: 133 // event handlers 134#if USE_LOG 135 void OnButtonClearLog(wxCommandEvent& event); 136#endif // USE_LOG 137 void OnExit(wxCommandEvent& event); 138 139#if wxUSE_MENUS 140 void OnPageChanging(WidgetsBookCtrlEvent& event); 141 void OnPageChanged(WidgetsBookCtrlEvent& event); 142 void OnGoToPage(wxCommandEvent& event); 143 144#if wxUSE_TOOLTIPS 145 void OnSetTooltip(wxCommandEvent& event); 146#endif // wxUSE_TOOLTIPS 147 void OnSetFgCol(wxCommandEvent& event); 148 void OnSetBgCol(wxCommandEvent& event); 149 void OnSetFont(wxCommandEvent& event); 150 void OnEnable(wxCommandEvent& event); 151 void OnSetBorder(wxCommandEvent& event); 152 153 void OnToggleGlobalBusyCursor(wxCommandEvent& event); 154 void OnToggleBusyCursor(wxCommandEvent& event); 155#endif // wxUSE_MENUS 156 157 // initialize the book: add all pages to it 158 void InitBook(); 159 160 // return the currently selected page (never NULL) 161 WidgetsPage *CurrentPage(); 162 163private: 164 // the panel containing everything 165 wxPanel *m_panel; 166 167#if USE_LOG 168 // the listbox for logging messages 169 wxListBox *m_lboxLog; 170 171 // the log target we use to redirect messages to the listbox 172 wxLog *m_logTarget; 173#endif // USE_LOG 174 175 // the book containing the test pages 176 WidgetsBookCtrl *m_book; 177 178#if wxUSE_MENUS 179 // last chosen fg/bg colours and font 180 wxColour m_colFg, 181 m_colBg; 182 wxFont m_font; 183#endif // wxUSE_MENUS 184 185 // any class wishing to process wxWidgets events must use this macro 186 DECLARE_EVENT_TABLE() 187}; 188 189#if USE_LOG 190// A log target which just redirects the messages to a listbox 191class LboxLogger : public wxLog 192{ 193public: 194 LboxLogger(wxListBox *lbox, wxLog *logOld) 195 { 196 m_lbox = lbox; 197 //m_lbox->Disable(); -- looks ugly under MSW 198 m_logOld = logOld; 199 } 200 201 virtual ~LboxLogger() 202 { 203 wxLog::SetActiveTarget(m_logOld); 204 } 205 206private: 207 // implement sink functions 208 virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t) 209 { 210 // don't put trace messages into listbox or we can get into infinite 211 // recursion 212 if ( level == wxLOG_Trace ) 213 { 214 if ( m_logOld ) 215 { 216 // cast is needed to call protected method 217 ((LboxLogger *)m_logOld)->DoLog(level, szString, t); 218 } 219 } 220 else 221 { 222 wxLog::DoLog(level, szString, t); 223 } 224 } 225 226 virtual void DoLogString(const wxChar *szString, time_t WXUNUSED(t)) 227 { 228 wxString msg; 229 TimeStamp(&msg); 230 msg += szString; 231 232 #ifdef __WXUNIVERSAL__ 233 m_lbox->AppendAndEnsureVisible(msg); 234 #else // other ports don't have this method yet 235 m_lbox->Append(msg); 236 m_lbox->SetFirstItem(m_lbox->GetCount() - 1); 237 #endif 238 } 239 240 // the control we use 241 wxListBox *m_lbox; 242 243 // the old log target 244 wxLog *m_logOld; 245}; 246#endif // USE_LOG 247 248// array of pages 249WX_DEFINE_ARRAY_PTR(WidgetsPage *, ArrayWidgetsPage); 250 251// ---------------------------------------------------------------------------- 252// misc macros 253// ---------------------------------------------------------------------------- 254 255IMPLEMENT_APP(WidgetsApp) 256 257// ---------------------------------------------------------------------------- 258// event tables 259// ---------------------------------------------------------------------------- 260 261BEGIN_EVENT_TABLE(WidgetsFrame, wxFrame) 262#if USE_LOG 263 EVT_BUTTON(Widgets_ClearLog, WidgetsFrame::OnButtonClearLog) 264#endif // USE_LOG 265 EVT_BUTTON(Widgets_Quit, WidgetsFrame::OnExit) 266 267#if wxUSE_TOOLTIPS 268 EVT_MENU(Widgets_SetTooltip, WidgetsFrame::OnSetTooltip) 269#endif // wxUSE_TOOLTIPS 270 271#if wxUSE_MENUS 272 EVT_WIDGETS_PAGE_CHANGING(wxID_ANY, WidgetsFrame::OnPageChanging) 273 EVT_MENU_RANGE(Widgets_GoToPage, Widgets_GoToPageLast, 274 WidgetsFrame::OnGoToPage) 275 276 EVT_MENU(Widgets_SetFgColour, WidgetsFrame::OnSetFgCol) 277 EVT_MENU(Widgets_SetBgColour, WidgetsFrame::OnSetBgCol) 278 EVT_MENU(Widgets_SetFont, WidgetsFrame::OnSetFont) 279 EVT_MENU(Widgets_Enable, WidgetsFrame::OnEnable) 280 281 EVT_MENU_RANGE(Widgets_BorderNone, Widgets_BorderDefault, 282 WidgetsFrame::OnSetBorder) 283 284 EVT_MENU(Widgets_GlobalBusyCursor, WidgetsFrame::OnToggleGlobalBusyCursor) 285 EVT_MENU(Widgets_BusyCursor, WidgetsFrame::OnToggleBusyCursor) 286 287 EVT_MENU(wxID_EXIT, WidgetsFrame::OnExit) 288#endif // wxUSE_MENUS 289END_EVENT_TABLE() 290 291// ============================================================================ 292// implementation 293// ============================================================================ 294 295// ---------------------------------------------------------------------------- 296// app class 297// ---------------------------------------------------------------------------- 298 299bool WidgetsApp::OnInit() 300{ 301 if ( !wxApp::OnInit() ) 302 return false; 303 304 // the reason for having these ifdef's is that I often run two copies of 305 // this sample side by side and it is useful to see which one is which 306 wxString title; 307#if defined(__WXUNIVERSAL__) 308 title = _T("wxUniv/"); 309#endif 310 311#if defined(__WXMSW__) 312 title += _T("wxMSW"); 313#elif defined(__WXGTK__) 314 title += _T("wxGTK"); 315#elif defined(__WXMAC__) 316 title += _T("wxMAC"); 317#elif defined(__WXMOTIF__) 318 title += _T("wxMOTIF"); 319#else 320 title += _T("wxWidgets"); 321#endif 322 323 wxFrame *frame = new WidgetsFrame(title + _T(" widgets demo")); 324 frame->Show(); 325 326 //wxLog::AddTraceMask(_T("listbox")); 327 //wxLog::AddTraceMask(_T("scrollbar")); 328 //wxLog::AddTraceMask(_T("focus")); 329 330 return true; 331} 332 333// ---------------------------------------------------------------------------- 334// WidgetsFrame construction 335// ---------------------------------------------------------------------------- 336 337WidgetsFrame::WidgetsFrame(const wxString& title) 338 : wxFrame(NULL, wxID_ANY, title) 339{ 340 // set the frame icon 341 SetIcon(wxICON(sample)); 342 343 // init everything 344#if USE_LOG 345 m_lboxLog = (wxListBox *)NULL; 346 m_logTarget = (wxLog *)NULL; 347#endif // USE_LOG 348 m_book = (WidgetsBookCtrl *)NULL; 349 350#if wxUSE_MENUS 351 // create the menubar 352 wxMenuBar *mbar = new wxMenuBar; 353 wxMenu *menuWidget = new wxMenu; 354#if wxUSE_TOOLTIPS 355 menuWidget->Append(Widgets_SetTooltip, _T("Set &tooltip...\tCtrl-T")); 356 menuWidget->AppendSeparator(); 357#endif // wxUSE_TOOLTIPS 358 menuWidget->Append(Widgets_SetFgColour, _T("Set &foreground...\tCtrl-F")); 359 menuWidget->Append(Widgets_SetBgColour, _T("Set &background...\tCtrl-B")); 360 menuWidget->Append(Widgets_SetFont, _T("Set f&ont...\tCtrl-O")); 361 menuWidget->AppendCheckItem(Widgets_Enable, _T("&Enable/disable\tCtrl-E")); 362 363 wxMenu *menuBorders = new wxMenu; 364 menuBorders->AppendRadioItem(Widgets_BorderDefault, _T("De&fault\tCtrl-Shift-9")); 365 menuBorders->AppendRadioItem(Widgets_BorderNone, _T("&None\tCtrl-Shift-0")); 366 menuBorders->AppendRadioItem(Widgets_BorderSimple, _T("&Simple\tCtrl-Shift-1")); 367 menuBorders->AppendRadioItem(Widgets_BorderDouble, _T("&Double\tCtrl-Shift-2")); 368 menuBorders->AppendRadioItem(Widgets_BorderStatic, _T("Stati&c\tCtrl-Shift-3")); 369 menuBorders->AppendRadioItem(Widgets_BorderRaised, _T("&Raised\tCtrl-Shift-4")); 370 menuBorders->AppendRadioItem(Widgets_BorderSunken, _T("S&unken\tCtrl-Shift-5")); 371 menuWidget->AppendSubMenu(menuBorders, _T("Set &border")); 372 373 menuWidget->AppendSeparator(); 374 menuWidget->AppendCheckItem(Widgets_GlobalBusyCursor, 375 _T("Toggle &global busy cursor\tCtrl-Shift-U")); 376 menuWidget->AppendCheckItem(Widgets_BusyCursor, 377 _T("Toggle b&usy cursor\tCtrl-U")); 378 379 menuWidget->AppendSeparator(); 380 menuWidget->Append(wxID_EXIT, _T("&Quit\tCtrl-Q")); 381 mbar->Append(menuWidget, _T("&Widget")); 382 SetMenuBar(mbar); 383 384 mbar->Check(Widgets_Enable, true); 385#endif // wxUSE_MENUS 386 387 // create controls 388 m_panel = new wxPanel(this, wxID_ANY); 389 390 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL); 391 392 // we have 2 panes: book with pages demonstrating the controls in the 393 // upper one and the log window with some buttons in the lower 394 395 int style = wxBK_DEFAULT; 396 // Uncomment to suppress page theme (draw in solid colour) 397 //style |= wxNB_NOPAGETHEME; 398 399 m_book = new WidgetsBookCtrl(m_panel, Widgets_BookCtrl, wxDefaultPosition, 400#ifdef __WXMOTIF__ 401 wxSize(500, wxDefaultCoord), // under Motif, height is a function of the width... 402#else 403 wxDefaultSize, 404#endif 405 style); 406 InitBook(); 407 408#ifndef __WXHANDHELD__ 409 // the lower one only has the log listbox and a button to clear it 410#if USE_LOG 411 wxSizer *sizerDown = new wxStaticBoxSizer( 412 new wxStaticBox( m_panel, wxID_ANY, _T("&Log window") ), 413 wxVERTICAL); 414 415 m_lboxLog = new wxListBox(m_panel, wxID_ANY); 416 sizerDown->Add(m_lboxLog, 1, wxGROW | wxALL, 5); 417 sizerDown->SetMinSize(100, 150); 418#else 419 wxSizer *sizerDown = new wxBoxSizer(wxVERTICAL); 420#endif // USE_LOG 421 422 wxBoxSizer *sizerBtns = new wxBoxSizer(wxHORIZONTAL); 423 wxButton *btn; 424#if USE_LOG 425 btn = new wxButton(m_panel, Widgets_ClearLog, _T("Clear &log")); 426 sizerBtns->Add(btn); 427 sizerBtns->Add(10, 0); // spacer 428#endif // USE_LOG 429 btn = new wxButton(m_panel, Widgets_Quit, _T("E&xit")); 430 sizerBtns->Add(btn); 431 sizerDown->Add(sizerBtns, 0, wxALL | wxALIGN_RIGHT, 5); 432 433 // put everything together 434 sizerTop->Add(m_book, 1, wxGROW | (wxALL & ~(wxTOP | wxBOTTOM)), 10); 435 sizerTop->Add(0, 5, 0, wxGROW); // spacer in between 436 sizerTop->Add(sizerDown, 0, wxGROW | (wxALL & ~wxTOP), 10); 437 438#else // !__WXHANDHELD__/__WXHANDHELD__ 439 440 sizerTop->Add(m_book, 1, wxGROW | wxALL ); 441 442#endif // __WXHANDHELD__ 443 444 m_panel->SetSizer(sizerTop); 445 446 sizerTop->Fit(this); 447 sizerTop->SetSizeHints(this); 448 449#if USE_LOG && !defined(__WXCOCOA__) 450 // wxCocoa's listbox is too flakey to use for logging right now 451 // now that everything is created we can redirect the log messages to the 452 // listbox 453 m_logTarget = new LboxLogger(m_lboxLog, wxLog::GetActiveTarget()); 454 wxLog::SetActiveTarget(m_logTarget); 455#endif 456} 457 458void WidgetsFrame::InitBook() 459{ 460#if USE_ICONS_IN_BOOK 461 wxImageList *imageList = new wxImageList(32, 32); 462 463 imageList->Add(wxBitmap(sample_xpm)); 464#else 465 wxImageList *imageList = NULL; 466#endif 467 468#if !USE_TREEBOOK 469 WidgetsBookCtrl *books[MAX_PAGES]; 470#endif 471 472 ArrayWidgetsPage pages[MAX_PAGES]; 473 wxArrayString labels[MAX_PAGES]; 474 475 wxMenu *menuPages = new wxMenu; 476 unsigned int nPage = 0, nFKey = 0; 477 int cat, imageId = 1; 478 479 // we need to first create all pages and only then add them to the book 480 // as we need the image list first 481 // 482 // we also construct the pages menu during this first iteration 483 for ( cat = 0; cat < MAX_PAGES; cat++ ) 484 { 485#if USE_TREEBOOK 486 nPage++; // increase for parent page 487#else 488 books[cat] = new WidgetsBookCtrl(m_book, 489 wxID_ANY, 490 wxDefaultPosition, 491 wxDefaultSize, 492 wxBK_DEFAULT); 493#endif 494 495 for ( WidgetsPageInfo *info = WidgetsPage::ms_widgetPages; 496 info; 497 info = info->GetNext() ) 498 { 499 if( (info->GetCategories() & ( 1 << cat )) == 0) 500 continue; 501 502 WidgetsPage *page = (*info->GetCtor())( 503#if USE_TREEBOOK 504 m_book 505#else 506 books[cat] 507#endif 508 , imageList); 509 pages[cat].Add(page); 510 511 labels[cat].Add(info->GetLabel()); 512 if ( cat == ALL_PAGE ) 513 { 514 wxString radioLabel(info->GetLabel()); 515 nFKey++; 516 if ( nFKey <= 12 ) 517 { 518 radioLabel << wxT("\tF" ) << nFKey; 519 } 520 521 menuPages->AppendRadioItem( 522 Widgets_GoToPage + nPage, 523 radioLabel 524 ); 525#if !USE_TREEBOOK 526 // consider only for book in book architecture 527 nPage++; 528#endif 529 } 530 531#if USE_TREEBOOK 532 // consider only for treebook architecture (with subpages) 533 nPage++; 534#endif 535 } 536 } 537 538 GetMenuBar()->Append(menuPages, _T("&Page")); 539 540#if USE_ICONS_IN_BOOK 541 m_book->AssignImageList(imageList); 542#endif 543 544 for ( cat = 0; cat < MAX_PAGES; cat++ ) 545 { 546#if USE_TREEBOOK 547 m_book->AddPage(NULL,WidgetsCategories[cat],false,0); 548#else 549 m_book->AddPage(books[cat],WidgetsCategories[cat],false,0); 550#if USE_ICONS_IN_BOOK 551 books[cat]->SetImageList(imageList); 552#endif 553#endif 554 555 // now do add them 556 size_t count = pages[cat].GetCount(); 557 for ( size_t n = 0; n < count; n++ ) 558 { 559#if USE_TREEBOOK 560 m_book->AddSubPage 561#else 562 books[cat]->AddPage 563#endif 564 ( 565 pages[cat][n], 566 labels[cat][n], 567 false, // don't select 568 imageId++ 569 ); 570 } 571 } 572 573 Connect( wxID_ANY, 574 wxEVT_COMMAND_WIDGETS_PAGE_CHANGED, 575 wxWidgetsbookEventHandler(WidgetsFrame::OnPageChanged) ); 576 577#if USE_TREEBOOK 578 // for treebook page #0 is empty parent page only so select the first page 579 // with some contents 580 m_book->SetSelection(1); 581 582 // but ensure that the top of the tree is shown nevertheless 583 wxTreeCtrl * const tree = m_book->GetTreeCtrl(); 584 585 wxTreeItemIdValue cookie; 586 tree->EnsureVisible(tree->GetFirstChild(tree->GetRootItem(), cookie)); 587#else 588 // for other books set selection twice to force connected event handler 589 // to force lazy creation of initial visible content 590 m_book->SetSelection(1); 591 m_book->SetSelection(0); 592#endif // USE_TREEBOOK 593} 594 595WidgetsPage *WidgetsFrame::CurrentPage() 596{ 597 wxWindow *page = m_book->GetCurrentPage(); 598 599#if !USE_TREEBOOK 600 WidgetsBookCtrl *subBook = wxStaticCast(page, WidgetsBookCtrl); 601 wxCHECK_MSG( subBook, NULL, _T("no WidgetsBookCtrl?") ); 602 603 page = subBook->GetCurrentPage(); 604#endif // !USE_TREEBOOK 605 606 return wxStaticCast(page, WidgetsPage); 607} 608 609WidgetsFrame::~WidgetsFrame() 610{ 611#if USE_LOG 612 delete m_logTarget; 613#endif // USE_LOG 614} 615 616// ---------------------------------------------------------------------------- 617// WidgetsFrame event handlers 618// ---------------------------------------------------------------------------- 619 620void WidgetsFrame::OnExit(wxCommandEvent& WXUNUSED(event)) 621{ 622 Close(); 623} 624 625#if USE_LOG 626void WidgetsFrame::OnButtonClearLog(wxCommandEvent& WXUNUSED(event)) 627{ 628 m_lboxLog->Clear(); 629} 630#endif // USE_LOG 631 632#if wxUSE_MENUS 633 634void WidgetsFrame::OnPageChanging(WidgetsBookCtrlEvent& event) 635{ 636#if USE_TREEBOOK 637 // don't allow selection of entries without pages (categories) 638 if ( !m_book->GetPage(event.GetSelection()) ) 639 event.Veto(); 640#else 641 wxUnusedVar(event); 642#endif 643} 644 645void WidgetsFrame::OnPageChanged(WidgetsBookCtrlEvent& event) 646{ 647 const int sel = event.GetSelection(); 648 649 // adjust "Page" menu selection 650 wxMenuItem *item = GetMenuBar()->FindItem(Widgets_GoToPage + sel); 651 if ( item ) 652 item->Check(); 653 654 GetMenuBar()->Check(Widgets_BusyCursor, false); 655 656 // create the pages on demand, otherwise the sample startup is too slow as 657 // it creates hundreds of controls 658 WidgetsPage *page = CurrentPage(); 659 if ( page->GetChildren().empty() ) 660 { 661 wxWindowUpdateLocker noUpdates(page); 662 page->CreateContent(); 663 //page->Layout(); 664 page->GetSizer()->Fit(page); 665 666 WidgetsBookCtrl *book = wxStaticCast(page->GetParent(), WidgetsBookCtrl); 667 wxSize size; 668 for ( size_t i = 0; i < book->GetPageCount(); ++i ) 669 { 670 wxWindow *page = book->GetPage(i); 671 if ( page ) 672 { 673 size.IncTo(page->GetSize()); 674 } 675 } 676 page->SetSize(size); 677 } 678 679 event.Skip(); 680} 681 682void WidgetsFrame::OnGoToPage(wxCommandEvent& event) 683{ 684#if USE_TREEBOOK 685 m_book->SetSelection(event.GetId() - Widgets_GoToPage); 686#else 687 m_book->SetSelection(m_book->GetPageCount()-1); 688 WidgetsBookCtrl *book = wxStaticCast(m_book->GetCurrentPage(), WidgetsBookCtrl); 689 book->SetSelection(event.GetId() - Widgets_GoToPage); 690#endif 691} 692 693#if wxUSE_TOOLTIPS 694 695void WidgetsFrame::OnSetTooltip(wxCommandEvent& WXUNUSED(event)) 696{ 697 static wxString s_tip = _T("This is a tooltip"); 698 699 wxTextEntryDialog dialog 700 ( 701 this, 702 _T("Tooltip text (may use \\n, leave empty to remove): "), 703 _T("Widgets sample"), 704 s_tip 705 ); 706 707 if ( dialog.ShowModal() != wxID_OK ) 708 return; 709 710 s_tip = dialog.GetValue(); 711 s_tip.Replace(_T("\\n"), _T("\n")); 712 713 WidgetsPage *page = CurrentPage(); 714 715 page->GetWidget()->SetToolTip(s_tip); 716 717 wxControl *ctrl2 = page->GetWidget2(); 718 if ( ctrl2 ) 719 ctrl2->SetToolTip(s_tip); 720} 721 722#endif // wxUSE_TOOLTIPS 723 724void WidgetsFrame::OnSetFgCol(wxCommandEvent& WXUNUSED(event)) 725{ 726#if wxUSE_COLOURDLG 727 // allow for debugging the default colour the first time this is called 728 WidgetsPage *page = CurrentPage(); 729 730 if (!m_colFg.Ok()) 731 m_colFg = page->GetForegroundColour(); 732 733 wxColour col = wxGetColourFromUser(this, m_colFg); 734 if ( !col.Ok() ) 735 return; 736 737 m_colFg = col; 738 739 page->GetWidget()->SetForegroundColour(m_colFg); 740 page->GetWidget()->Refresh(); 741 742 wxControl *ctrl2 = page->GetWidget2(); 743 if ( ctrl2 ) 744 { 745 ctrl2->SetForegroundColour(m_colFg); 746 ctrl2->Refresh(); 747 } 748#else 749 wxLogMessage(_T("Colour selection dialog not available in current build.")); 750#endif 751} 752 753void WidgetsFrame::OnSetBgCol(wxCommandEvent& WXUNUSED(event)) 754{ 755#if wxUSE_COLOURDLG 756 WidgetsPage *page = CurrentPage(); 757 758 if ( !m_colBg.Ok() ) 759 m_colBg = page->GetBackgroundColour(); 760 761 wxColour col = wxGetColourFromUser(this, m_colBg); 762 if ( !col.Ok() ) 763 return; 764 765 m_colBg = col; 766 767 page->GetWidget()->SetBackgroundColour(m_colBg); 768 page->GetWidget()->Refresh(); 769 770 wxControl *ctrl2 = page->GetWidget2(); 771 if ( ctrl2 ) 772 { 773 ctrl2->SetBackgroundColour(m_colFg); 774 ctrl2->Refresh(); 775 } 776#else 777 wxLogMessage(_T("Colour selection dialog not available in current build.")); 778#endif 779} 780 781void WidgetsFrame::OnSetFont(wxCommandEvent& WXUNUSED(event)) 782{ 783#if wxUSE_FONTDLG 784 WidgetsPage *page = CurrentPage(); 785 786 if (!m_font.Ok()) 787 m_font = page->GetFont(); 788 789 wxFont font = wxGetFontFromUser(this, m_font); 790 if ( !font.Ok() ) 791 return; 792 793 m_font = font; 794 795 page->GetWidget()->SetFont(m_font); 796 page->GetWidget()->Refresh(); 797 798 wxControl *ctrl2 = page->GetWidget2(); 799 if ( ctrl2 ) 800 { 801 ctrl2->SetFont(m_font); 802 ctrl2->Refresh(); 803 } 804#else 805 wxLogMessage(_T("Font selection dialog not available in current build.")); 806#endif 807} 808 809void WidgetsFrame::OnEnable(wxCommandEvent& event) 810{ 811 CurrentPage()->GetWidget()->Enable(event.IsChecked()); 812 if (CurrentPage()->GetWidget2()) 813 CurrentPage()->GetWidget2()->Enable(event.IsChecked()); 814} 815 816void WidgetsFrame::OnSetBorder(wxCommandEvent& event) 817{ 818 int border; 819 switch ( event.GetId() ) 820 { 821 case Widgets_BorderNone: border = wxBORDER_NONE; break; 822 case Widgets_BorderStatic: border = wxBORDER_STATIC; break; 823 case Widgets_BorderSimple: border = wxBORDER_SIMPLE; break; 824 case Widgets_BorderRaised: border = wxBORDER_RAISED; break; 825 case Widgets_BorderSunken: border = wxBORDER_SUNKEN; break; 826 case Widgets_BorderDouble: border = wxBORDER_DOUBLE; break; 827 828 default: 829 wxFAIL_MSG( _T("unknown border style") ); 830 // fall through 831 832 case Widgets_BorderDefault: border = wxBORDER_DEFAULT; break; 833 } 834 835 WidgetsPage::ms_defaultFlags &= ~wxBORDER_MASK; 836 WidgetsPage::ms_defaultFlags |= border; 837 838 WidgetsPage *page = CurrentPage(); 839 840 page->RecreateWidget(); 841} 842 843void WidgetsFrame::OnToggleGlobalBusyCursor(wxCommandEvent& event) 844{ 845 if ( event.IsChecked() ) 846 wxBeginBusyCursor(); 847 else 848 wxEndBusyCursor(); 849} 850 851void WidgetsFrame::OnToggleBusyCursor(wxCommandEvent& event) 852{ 853 CurrentPage()->GetWidget()->SetCursor(*(event.IsChecked() 854 ? wxHOURGLASS_CURSOR 855 : wxSTANDARD_CURSOR)); 856} 857 858#endif // wxUSE_MENUS 859 860// ---------------------------------------------------------------------------- 861// WidgetsPageInfo 862// ---------------------------------------------------------------------------- 863 864WidgetsPageInfo::WidgetsPageInfo(Constructor ctor, const wxChar *label, int categories) 865 : m_label(label) 866 , m_categories(categories) 867{ 868 m_ctor = ctor; 869 870 m_next = NULL; 871 872 // dummy sorting: add and immediately sort in the list according to label 873 if ( WidgetsPage::ms_widgetPages ) 874 { 875 WidgetsPageInfo *node_prev = WidgetsPage::ms_widgetPages; 876 if ( wxStrcmp(label, node_prev->GetLabel().c_str()) < 0 ) 877 { 878 // add as first 879 m_next = node_prev; 880 WidgetsPage::ms_widgetPages = this; 881 } 882 else 883 { 884 WidgetsPageInfo *node_next; 885 do 886 { 887 node_next = node_prev->GetNext(); 888 if ( node_next ) 889 { 890 // add if between two 891 if ( wxStrcmp(label, node_next->GetLabel().c_str()) < 0 ) 892 { 893 node_prev->SetNext(this); 894 m_next = node_next; 895 // force to break loop 896 node_next = NULL; 897 } 898 } 899 else 900 { 901 // add as last 902 node_prev->SetNext(this); 903 m_next = node_next; 904 } 905 node_prev = node_next; 906 } 907 while ( node_next ); 908 } 909 } 910 else 911 { 912 // add when first 913 WidgetsPage::ms_widgetPages = this; 914 } 915} 916 917// ---------------------------------------------------------------------------- 918// WidgetsPage 919// ---------------------------------------------------------------------------- 920 921int WidgetsPage::ms_defaultFlags = wxBORDER_DEFAULT; 922WidgetsPageInfo *WidgetsPage::ms_widgetPages = NULL; 923 924WidgetsPage::WidgetsPage(WidgetsBookCtrl *book, 925 wxImageList *imaglist, 926 const char* icon[]) 927 : wxPanel(book, wxID_ANY, 928 wxDefaultPosition, wxDefaultSize, 929 wxNO_FULL_REPAINT_ON_RESIZE | 930 wxCLIP_CHILDREN | 931 wxTAB_TRAVERSAL) 932{ 933#if USE_ICONS_IN_BOOK 934 imaglist->Add(wxBitmap(icon)); 935#else 936 wxUnusedVar(imaglist); 937 wxUnusedVar(icon); 938#endif 939} 940 941wxSizer *WidgetsPage::CreateSizerWithText(wxControl *control, 942 wxWindowID id, 943 wxTextCtrl **ppText) 944{ 945 wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL); 946 wxTextCtrl *text = new wxTextCtrl(this, id, wxEmptyString, 947 wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); 948 949 sizerRow->Add(control, 0, wxRIGHT | wxALIGN_CENTRE_VERTICAL, 5); 950 sizerRow->Add(text, 1, wxLEFT | wxALIGN_CENTRE_VERTICAL, 5); 951 952 if ( ppText ) 953 *ppText = text; 954 955 return sizerRow; 956} 957 958// create a sizer containing a label and a text ctrl 959wxSizer *WidgetsPage::CreateSizerWithTextAndLabel(const wxString& label, 960 wxWindowID id, 961 wxTextCtrl **ppText) 962{ 963 return CreateSizerWithText(new wxStaticText(this, wxID_ANY, label), 964 id, ppText); 965} 966 967// create a sizer containing a button and a text ctrl 968wxSizer *WidgetsPage::CreateSizerWithTextAndButton(wxWindowID idBtn, 969 const wxString& label, 970 wxWindowID id, 971 wxTextCtrl **ppText) 972{ 973 return CreateSizerWithText(new wxButton(this, idBtn, label), id, ppText); 974} 975 976wxCheckBox *WidgetsPage::CreateCheckBoxAndAddToSizer(wxSizer *sizer, 977 const wxString& label, 978 wxWindowID id) 979{ 980 wxCheckBox *checkbox = new wxCheckBox(this, id, label); 981 sizer->Add(checkbox, 0, wxLEFT | wxRIGHT, 5); 982 sizer->Add(0, 2, 0, wxGROW); // spacer 983 984 return checkbox; 985} 986