#include "stdafx.h" wxBEGIN_EVENT_TABLE(Frame, wxFrame) #if wxUSE_MSGDLG EVT_MENU(DIALOGS_MESSAGE_BOX, Frame::MessageBox) EVT_MENU(DIALOGS_MESSAGE_DIALOG, Frame::MessageBoxDialog) EVT_MENU(DIALOGS_MESSAGE_BOX_WXINFO, Frame::MessageBoxInfo) #endif // wxUSE_MSGDLG #if wxUSE_RICHMSGDLG EVT_MENU(DIALOGS_RICH_MESSAGE_DIALOG, Frame::RichMessageDialog) #endif // wxUSE_RICHMSGDLG #if wxUSE_COLOURDLG EVT_MENU(DIALOGS_CHOOSE_COLOUR, Frame::ChooseColour) EVT_MENU(DIALOGS_CHOOSE_COLOUR_ALPHA, Frame::ChooseColour) EVT_MENU(DIALOGS_GET_COLOUR, Frame::GetColour) #endif // wxUSE_COLOURDLG #if wxUSE_FONTDLG EVT_MENU(DIALOGS_CHOOSE_FONT, Frame::ChooseFont) #endif // wxUSE_FONTDLG #if wxUSE_LOG_DIALOG EVT_MENU(DIALOGS_LOG_DIALOG, Frame::LogDialog) #endif // wxUSE_LOG_DIALOG #if wxUSE_INFOBAR EVT_MENU(DIALOGS_INFOBAR_SIMPLE, Frame::InfoBarSimple) EVT_MENU(DIALOGS_INFOBAR_SIMPLE_WRAPPED, Frame::InfoBarSimpleWrapped) EVT_MENU(DIALOGS_INFOBAR_ADVANCED, Frame::InfoBarAdvanced) #endif // wxUSE_INFOBAR #if wxUSE_TEXTDLG EVT_MENU(DIALOGS_LINE_ENTRY, Frame::LineEntry) EVT_MENU(DIALOGS_TEXT_ENTRY, Frame::TextEntry) EVT_MENU(DIALOGS_PASSWORD_ENTRY, Frame::PasswordEntry) #endif // wxUSE_TEXTDLG #if wxUSE_CREDENTIALDLG EVT_MENU(DIALOGS_CREDENTIAL_ENTRY, Frame::CredentialEntry) #endif // wxUSE_CREDENTIALDLG #if wxUSE_NUMBERDLG EVT_MENU(DIALOGS_NUM_ENTRY, Frame::NumericEntry) #endif // wxUSE_NUMBERDLG #if wxUSE_CHOICEDLG EVT_MENU(DIALOGS_SINGLE_CHOICE, Frame::SingleChoice) EVT_MENU(DIALOGS_MULTI_CHOICE, Frame::MultiChoice) #endif // wxUSE_CHOICEDLG #if wxUSE_REARRANGECTRL EVT_MENU(DIALOGS_REARRANGE, Frame::Rearrange) #endif // wxUSE_REARRANGECTRL #if wxUSE_ADDREMOVECTRL EVT_MENU(DIALOGS_ADDREMOVE, Frame::AddRemove) #endif // wxUSE_ADDREMOVECTRL #if wxUSE_FILEDLG EVT_MENU(DIALOGS_FILE_OPEN, Frame::OnFileOpen) EVT_MENU(DIALOGS_FILE_OPEN2, Frame::FileOpen2) EVT_MENU(DIALOGS_FILES_OPEN, Frame::FilesOpen) EVT_MENU(DIALOGS_FILE_SAVE, Frame::OnSaveNew) EVT_MENU(DIALOGS_MAC_TOGGLE_ALWAYS_SHOW_TYPES, Frame::MacToggleAlwaysShowTypes) #endif // wxUSE_FILEDLG #if wxUSE_DIRDLG EVT_MENU(DIALOGS_DIR_CHOOSE, Frame::DirChoose) EVT_MENU(DIALOGS_DIRNEW_CHOOSE, Frame::DirChooseNew) EVT_MENU(DIALOGS_DIRMULTIPLE_CHOOSE, Frame::DirChooseMultiple) #endif // wxUSE_DIRDLG #if USE_MODAL_PRESENTATION EVT_MENU(DIALOGS_MODAL, Frame::ModalDlg) #endif // USE_MODAL_PRESENTATION EVT_MENU(DIALOGS_MODELESS, Frame::ModelessDlg) EVT_MENU(DIALOGS_CENTRE_SCREEN, Frame::DlgCenteredScreen) EVT_MENU(DIALOGS_CENTRE_PARENT, Frame::DlgCenteredParent) #if wxUSE_MINIFRAME EVT_MENU(DIALOGS_MINIFRAME, Frame::MiniFrame) #endif // wxUSE_MINIFRAME EVT_MENU(DIALOGS_ONTOP, Frame::DlgOnTop) #if wxUSE_STARTUP_TIPS EVT_MENU(DIALOGS_TIP, Frame::ShowTip) #endif // wxUSE_STARTUP_TIPS #if wxUSE_ABOUTDLG EVT_MENU(DIALOGS_ABOUTDLG_SIMPLE, Frame::ShowSimpleAboutDialog) EVT_MENU(DIALOGS_ABOUTDLG_FANCY, Frame::ShowFancyAboutDialog) EVT_MENU(DIALOGS_ABOUTDLG_FULL, Frame::ShowFullAboutDialog) EVT_MENU(DIALOGS_ABOUTDLG_CUSTOM, Frame::ShowCustomAboutDialog) #endif // wxUSE_ABOUTDLG #if wxUSE_BUSYINFO EVT_MENU(DIALOGS_BUSYINFO, Frame::ShowBusyInfo) EVT_MENU(DIALOGS_BUSYINFO_RICH, Frame::ShowRichBusyInfo) #endif // wxUSE_BUSYINFO #if wxUSE_FINDREPLDLG EVT_MENU(DIALOGS_FIND, Frame::ShowFindDialog) EVT_MENU(DIALOGS_REPLACE, Frame::ShowReplaceDialog) EVT_FIND(wxID_ANY, Frame::OnFindDialog) EVT_FIND_NEXT(wxID_ANY, Frame::OnFindDialog) EVT_FIND_REPLACE(wxID_ANY, Frame::OnFindDialog) EVT_FIND_REPLACE_ALL(wxID_ANY, Frame::OnFindDialog) EVT_FIND_CLOSE(wxID_ANY, Frame::OnFindDialog) #endif // wxUSE_FINDREPLDLG #if USE_SETTINGS_DIALOG EVT_MENU(DIALOGS_PROPERTY_SHEET, Frame::OnPropertySheet) EVT_MENU(DIALOGS_PROPERTY_SHEET_TOOLBOOK, Frame::OnPropertySheet) EVT_MENU(DIALOGS_PROPERTY_SHEET_BUTTONTOOLBOOK, Frame::OnPropertySheet) #endif // USE_SETTINGS_DIALOG EVT_MENU(DIALOGS_STANDARD_BUTTON_SIZER_DIALOG, Frame::OnStandardButtonsSizerDialog) EVT_MENU(DIALOGS_TEST_DEFAULT_ACTION, Frame::OnTestDefaultActionDialog) EVT_MENU(DIALOGS_MODAL_HOOK, Frame::OnModalHook) EVT_MENU(DIALOGS_SIMULATE_UNSAVED, Frame::OnSimulatedUnsaved) EVT_MENU(DIALOGS_REQUEST, Frame::OnRequestUserAttention) #if wxUSE_NOTIFICATION_MESSAGE EVT_MENU(DIALOGS_NOTIFY_MSG, Frame::OnNotifMsg) #endif // wxUSE_NOTIFICATION_MESSAGE #if wxUSE_TIPWINDOW EVT_MENU(DIALOGS_SHOW_TIP, Frame::OnShowTip) EVT_UPDATE_UI(DIALOGS_SHOW_TIP, Frame::OnUpdateShowTipUI) #endif // wxUSE_TIPWINDOW #if wxUSE_RICHTOOLTIP EVT_MENU(DIALOGS_RICHTIP_DIALOG, Frame::OnRichTipDialog) #endif // wxUSE_RICHTOOLTIP EVT_MENU(wxID_EXIT, Frame::OnExit) EVT_CLOSE(Frame::OnClose) wxEND_EVENT_TABLE() void Frame::RestorePositionFromConfig(const wxSize& bestSize) { wxConfigBase* pConfig = wxConfigBase::Get(); if (pConfig) { // SetPath() understands ".." but you should probably never use it. pConfig->SetPath(wxT("/MainFrame")); wxPoint scr{ wxSystemSettings::GetMetric(wxSYS_SCREEN_X), wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) }; // restore frame position and size int x = pConfig->ReadLong(wxT("x"), scr.x / 4); int y = pConfig->ReadLong(wxT("y"), scr.y / 4); int w = pConfig->ReadLong(wxT("w"), scr.x / 2); int h = pConfig->ReadLong(wxT("h"), scr.y / 2); w = std::min(std::max(std::max(w, scr.x / 5), bestSize.GetWidth()), 8 * scr.x / 9); h = std::min(std::max(std::max(h, scr.y / 9), bestSize.GetHeight()), 4 * scr.y / 5); x = std::max(scr.x / 12, std::min(x, scr.x - w - scr.x / 12)); y = std::max(scr.y / 10, std::min(y, scr.y - h - scr.y / 10)); this->Move(x, y); this->Maximize(pConfig->ReadBool(wxT("Maximized"), false)); this->SetSize(w, h); pConfig->SetPath(wxT("/TipOfTheDay")); m_showTipsAtStartup = pConfig->Read("show", true); m_TipOfTheDayIndex = pConfig->Read("index", int(-1)); pConfig->SetPath(wxT("/FileDialog")); m_FileDialogFilterIndex = pConfig->Read("index", int(0)); m_strLastUsedFile=pConfig->Read("LastUsed",wxEmptyString).utf8_str(); pConfig->SetPath(wxT("/")); } } void Frame::StorePositionToConfig() { wxConfigBase* pConfig = wxConfigBase::Get(); if (pConfig) { pConfig->SetPath(wxT("/MainFrame")); if (this->IsMaximized()) { pConfig->Write(wxT("Maximized"), true); } else { // save the frame position int x, y, w, h; this->GetSize(&w, &h); this->GetPosition(&x, &y); pConfig->Write(wxT("x"), (long)x); pConfig->Write(wxT("y"), (long)y); pConfig->Write(wxT("w"), (long)w); pConfig->Write(wxT("h"), (long)h); pConfig->Write(wxT("Maximized"), false); } pConfig->SetPath(wxT("/")); } } // My frame constructor Frame::Frame(const wxString& title) : wxFrame(NULL, wxID_ANY, title), m_confirmExit(false) { SetIcon(wxICON(sample)); #if USE_MODAL_PRESENTATION m_dialog = (MyModelessDialog*)NULL; #endif // USE_MODAL_PRESENTATION #if wxUSE_FINDREPLDLG m_dlgFind = m_dlgReplace = NULL; #endif #if wxUSE_COLOURDLG m_clrData.SetChooseFull(true); for (int i = 0; i < wxColourData::NUM_CUSTOM; i++) { unsigned char n = i * 16; m_clrData.SetCustomColour(i, wxColour(n, n, n)); } #endif // wxUSE_COLOURDLG #if wxUSE_STATUSBAR CreateStatusBar(); #endif // wxUSE_STATUSBAR m_canvas = new MyCanvas(this); #if wxUSE_INFOBAR // an info bar can be created very simply and used without any extra effort m_infoBarSimple = new wxInfoBar(this); // or it can also be customized by m_infoBarAdvanced = new wxInfoBar(this); // ... adding extra buttons (but more than two will usually be too many) m_infoBarAdvanced->AddButton(wxID_UNDO); m_infoBarAdvanced->AddButton(wxID_REDO); m_infoBarAdvanced->Bind(wxEVT_BUTTON, &Frame::OnInfoBarRedo, this, wxID_REDO); // adding and removing a button immediately doesn't make sense here, of // course, it's done just to show that it is possible m_infoBarAdvanced->AddButton(wxID_EXIT); m_infoBarAdvanced->RemoveButton(wxID_EXIT); // ... changing the colours and/or fonts m_infoBarAdvanced->SetOwnBackgroundColour(0xc8ffff); m_infoBarAdvanced->SetForegroundColour(0x123312); m_infoBarAdvanced->SetFont(GetFont().Bold().Larger()); // ... and changing the effect (only does anything under MSW currently) m_infoBarAdvanced->SetShowHideEffects(wxSHOW_EFFECT_EXPAND, wxSHOW_EFFECT_EXPAND); m_infoBarAdvanced->SetEffectDuration(1500); // to use the info bars we need to use sizer for the window layout wxBoxSizer* const sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(m_infoBarSimple, wxSizerFlags().Expand()); sizer->Add(m_canvas, wxSizerFlags(1).Expand()); sizer->Add(m_infoBarAdvanced, wxSizerFlags().Expand()); SetSizer(sizer); // final touch: under MSW the info bars are shown progressively and parts // of the parent window can be seen during the process, so use the same // background colour for our background as for the canvas window which // covers our entire client area to avoid jarring colour jumps SetOwnBackgroundColour(m_canvas->GetBackgroundColour()); wxMenuBar* menuBar = new wxMenuBar; SetIcon(wxICON(AAArho)); //Does not appear to do anything. Maybe it does something in Unix. //wxICON is a namestring on windows, and a symbol on Unix wxMenu* menuFile = new wxMenu; menuFile->Append(wxID_OPEN, "&Open file\tCtrl-O"); menuFile->Bind(wxEVT_MENU, &Frame::OnFileOpen, this, wxID_OPEN); menuFile->Append(wxID_NEW, "Sa&ve file\tCtrl-S"); menuFile->Bind(wxEVT_MENU, &Frame::OnSaveNew, this, wxID_NEW); menuFile->Append(wxID_EXIT); menuFile->Bind(wxEVT_MENU, &Frame::OnExit, this, wxID_EXIT); menuBar->Append(menuFile, "&File"); // Make a menubar wxMenu* menuDlg = new wxMenu; menuDlg->Append(DIALOGS_MESSAGE_BOX, "&Message box\tCtrl-M"); menuDlg->Append(DIALOGS_MESSAGE_DIALOG, "Message dialog\tShift-Ctrl-M"); #if wxUSE_RICHMSGDLG menuDlg->Append(DIALOGS_RICH_MESSAGE_DIALOG, "Rich message dialog"); #endif // wxUSE_RICHMSGDLG #if wxUSE_COLOURDLG || wxUSE_FONTDLG || wxUSE_CHOICEDLG wxMenu* choices_menu = new wxMenu; #if wxUSE_COLOURDLG wxMenu* choices_bg_colour = new wxMenu; choices_bg_colour->Append(DIALOGS_CHOOSE_COLOUR, "&No opacity"); choices_bg_colour->Append(DIALOGS_CHOOSE_COLOUR_ALPHA, "&With opacity"); choices_menu->Append(wxID_ANY, "&Choose bg colour", choices_bg_colour); choices_menu->Append(DIALOGS_GET_COLOUR, "&Choose fg colour"); #endif // wxUSE_COLOURDLG #if wxUSE_FONTDLG choices_menu->Append(DIALOGS_CHOOSE_FONT, "Choose &font\tShift-Ctrl-N"); #endif // wxUSE_FONTDLG #if wxUSE_CHOICEDLG choices_menu->Append(DIALOGS_SINGLE_CHOICE, "&Single choice\tCtrl-C"); choices_menu->Append(DIALOGS_MULTI_CHOICE, "M&ultiple choice\tCtrl-U"); #endif // wxUSE_CHOICEDLG #if wxUSE_REARRANGECTRL choices_menu->Append(DIALOGS_REARRANGE, "&Rearrange dialog\tCtrl-R"); #endif // wxUSE_REARRANGECTRL #if wxUSE_ADDREMOVECTRL choices_menu->Append(DIALOGS_ADDREMOVE, "&Add/remove items control\tCtrl-A"); #endif // wxUSE_ADDREMOVECTRL menuDlg->Append(wxID_ANY, "&Choices and selectors", choices_menu); #endif // wxUSE_COLOURDLG || wxUSE_FONTDLG || wxUSE_CHOICEDLG #if wxUSE_TEXTDLG || wxUSE_NUMBERDLG || wxUSE_CREDENTIALDLG wxMenu* entry_menu = new wxMenu; #if wxUSE_TEXTDLG entry_menu->Append(DIALOGS_LINE_ENTRY, "Single line &entry\tCtrl-E"); entry_menu->Append(DIALOGS_TEXT_ENTRY, "Multi line text &entry\tShift-Ctrl-E"); entry_menu->Append(DIALOGS_PASSWORD_ENTRY, "&Password entry\tCtrl-P"); #endif // wxUSE_TEXTDLG #if wxUSE_CREDENTIALDLG entry_menu->Append(DIALOGS_CREDENTIAL_ENTRY, "&Credential entry\tShift-Ctrl-C"); #endif // wxUSE_CREDENTIALDLG #if wxUSE_NUMBERDLG entry_menu->Append(DIALOGS_NUM_ENTRY, "&Numeric entry\tCtrl-N"); #endif // wxUSE_NUMBERDLG menuDlg->Append(wxID_ANY, "&Entry dialogs", entry_menu); #endif // wxUSE_TEXTDLG || wxUSE_NUMBERDLG #if wxUSE_FILEDLG wxMenu* filedlg_menu = new wxMenu; filedlg_menu->Append(DIALOGS_FILE_OPEN2, "&Second open file\tCtrl-2"); filedlg_menu->Append(DIALOGS_FILES_OPEN, "Open &files\tShift-Ctrl-O"); filedlg_menu->AppendSeparator(); filedlg_menu->AppendRadioItem( DIALOGS_FILE_USE_CUSTOMIZER, "Use new customization API", "Use wxFileDialog::SetCustomizeHook() for file dialog customization" ); filedlg_menu->AppendRadioItem( DIALOGS_FILE_USE_EXTRA_CONTROL_CREATOR, "Use old customization API", "Use wxFileDialog::SetExtraControlCreator() for file dialog customization" ); #ifdef __WXOSX_COCOA__ filedlg_menu->AppendSeparator(); filedlg_menu->AppendCheckItem(DIALOGS_MAC_TOGGLE_ALWAYS_SHOW_TYPES, "macOS only: Toggle open file " "\"Always show types\"\tRawCtrl+Ctrl+S"); #endif menuDlg->Append(wxID_ANY, "&File operations", filedlg_menu); #endif // wxUSE_FILEDLG #if wxUSE_DIRDLG wxMenu* dir_menu = new wxMenu; dir_menu->Append(DIALOGS_DIR_CHOOSE, "&Choose a directory\tCtrl-D"); dir_menu->Append(DIALOGS_DIRNEW_CHOOSE, "Choose a directory (with \"Ne&w\" button)\tShift-Ctrl-D"); dir_menu->Append(DIALOGS_DIRMULTIPLE_CHOOSE, "Choose multiple and hidden directories\tAlt-Ctrl-D"); menuDlg->Append(wxID_ANY, "&Directory operations", dir_menu); #endif // wxUSE_DIRDLG #if wxUSE_STARTUP_TIPS || \ wxUSE_PROGRESSDLG || \ wxUSE_BUSYINFO || \ wxUSE_LOG_DIALOG || \ wxUSE_MSGDLG wxMenu* info_menu = new wxMenu; #if wxUSE_STARTUP_TIPS info_menu->Append(DIALOGS_TIP, "&Tip of the day\tCtrl-T"); #endif // wxUSE_STARTUP_TIPS #if wxUSE_LOG_DIALOG info_menu->Append(DIALOGS_LOG_DIALOG, "&Log dialog\tCtrl-L"); #endif // wxUSE_LOG_DIALOG #if wxUSE_INFOBAR info_menu->Append(DIALOGS_INFOBAR_SIMPLE, "Simple &info bar\tCtrl-I"); info_menu->Append(DIALOGS_INFOBAR_SIMPLE_WRAPPED, "Simple info bar with wrapped text"); info_menu->Append(DIALOGS_INFOBAR_ADVANCED, "&Advanced info bar\tShift-Ctrl-I"); #endif // wxUSE_INFOBAR #if wxUSE_MSGDLG info_menu->Append(DIALOGS_MESSAGE_BOX_WXINFO, "&wxWidgets information\tCtrl-W"); #endif // wxUSE_MSGDLG menuDlg->Append(wxID_ANY, "&Informative dialogs", info_menu); #endif // wxUSE_STARTUP_TIPS || wxUSE_PROGRESSDLG || wxUSE_BUSYINFO || wxUSE_LOG_DIALOG #if wxUSE_FINDREPLDLG wxMenu* find_menu = new wxMenu; find_menu->AppendCheckItem(DIALOGS_FIND, "&Find dialog\tCtrl-F"); find_menu->AppendCheckItem(DIALOGS_REPLACE, "Find and &replace dialog\tShift-Ctrl-F"); menuDlg->Append(wxID_ANY, "&Searching", find_menu); #endif // wxUSE_FINDREPLDLG wxMenu* dialogs_menu = new wxMenu; #if USE_MODAL_PRESENTATION dialogs_menu->Append(DIALOGS_MODAL, "&Modal dialog\tShift-Ctrl-W"); #endif // USE_MODAL_PRESENTATION dialogs_menu->AppendCheckItem(DIALOGS_MODELESS, "Mode&less dialog\tShift-Ctrl-Z"); dialogs_menu->Append(DIALOGS_CENTRE_SCREEN, "Centered on &screen\tShift-Ctrl-1"); dialogs_menu->Append(DIALOGS_CENTRE_PARENT, "Centered on &parent\tShift-Ctrl-2"); #if wxUSE_MINIFRAME dialogs_menu->Append(DIALOGS_MINIFRAME, "&Mini frame"); #endif // wxUSE_MINIFRAME dialogs_menu->Append(DIALOGS_ONTOP, "Dialog staying on &top"); menuDlg->Append(wxID_ANY, "&Generic dialogs", dialogs_menu); #if USE_SETTINGS_DIALOG wxMenu* sheet_menu = new wxMenu; sheet_menu->Append(DIALOGS_PROPERTY_SHEET, "&Standard property sheet\tShift-Ctrl-P"); sheet_menu->Append(DIALOGS_PROPERTY_SHEET_TOOLBOOK, "&Toolbook sheet\tShift-Ctrl-T"); if (wxPlatformIs(wxPORT_MAC)) sheet_menu->Append(DIALOGS_PROPERTY_SHEET_BUTTONTOOLBOOK, "Button &Toolbook sheet\tShift-Ctrl-U"); /* #ifdef __WXMAC__ sheet_menu->Append(DIALOGS_PROPERTY_SHEET_BUTTONTOOLBOOK, "Button &Toolbook sheet\tShift-Ctrl-U"); #endif */ menuDlg->Append(wxID_ANY, "&Property sheets", sheet_menu); #endif // USE_SETTINGS_DIALOG wxMenu* menuNotif = new wxMenu; menuNotif->Append(DIALOGS_REQUEST, "&Request user attention\tCtrl-Shift-R"); #if wxUSE_NOTIFICATION_MESSAGE menuNotif->AppendSeparator(); menuNotif->Append(DIALOGS_NOTIFY_MSG, "User &Notification\tCtrl-Shift-N"); #endif // wxUSE_NOTIFICATION_MESSAGE menuDlg->AppendSubMenu(menuNotif, "&User notifications"); #if wxUSE_TIPWINDOW menuDlg->AppendCheckItem(DIALOGS_SHOW_TIP, "Show &tip window\tShift-Ctrl-H"); #endif // wxUSE_TIPWINDOW #if wxUSE_RICHTOOLTIP menuDlg->Append(DIALOGS_RICHTIP_DIALOG, "Rich &tooltip dialog...\tCtrl-H"); menuDlg->AppendSeparator(); #endif // wxUSE_RICHTOOLTIP menuDlg->Append(DIALOGS_STANDARD_BUTTON_SIZER_DIALOG, "&Standard Buttons Sizer Dialog"); menuDlg->Append(DIALOGS_TEST_DEFAULT_ACTION, "&Test dialog default action"); menuDlg->AppendCheckItem(DIALOGS_MODAL_HOOK, "Enable modal dialog hook"); menuDlg->AppendCheckItem(DIALOGS_SIMULATE_UNSAVED, "Simulate an unsaved document at exit"); menuDlg->AppendSeparator(); menuDlg->Append(wxID_EXIT, "E&xit\tAlt-X"); #if wxUSE_ABOUTDLG wxMenu* menuHelp = new wxMenu; menuHelp->Append(DIALOGS_ABOUTDLG_SIMPLE, "&About (simple)...\tF1"); menuHelp->Append(DIALOGS_ABOUTDLG_FANCY, "About (&fancy)...\tShift-F1"); menuHelp->Append(DIALOGS_ABOUTDLG_FULL, "About (f&ull)...\tCtrl-F1"); menuHelp->Append(DIALOGS_ABOUTDLG_CUSTOM, "About (&custom)...\tCtrl-Shift-F1"); #endif // wxUSE_ABOUTDLG wxMenu* editMenu = new wxMenu; editMenu->Append(wxID_UNDO, "&Undo\tCtrl+Z"); editMenu->Append(wxID_REDO, "&Redo\tCtrl+Y"); editMenu->AppendSeparator(); editMenu->Append(wxID_CUT, "Cu&t\tCtrl+X"); editMenu->Append(wxID_COPY, "&Copy\tCtrl+C"); editMenu->Append(wxID_PASTE, "&Paste\tCtrl+V"); editMenu->Append(wxID_CLEAR, "&Delete"); editMenu->AppendSeparator(); editMenu->Append(wxID_SELECTALL, "Select All\tCtrl+A"); //wxMenuBar* menubar = frame->GetMenuBar(); menuBar->Append(menuDlg, "&Dialogs"); menuBar->Append(editMenu, "&Edit"); #if wxUSE_ABOUTDLG menuBar->Append(menuHelp, "&Help"); #endif // wxUSE_ABOUTDLG SetMenuBar(menuBar); this->SetMenuBar(menuBar); #endif // wxUSE_INFOBAR #if wxUSE_TIPWINDOW m_tipWindow = NULL; #endif // wxUSE_TIPWINDOW #ifdef __WXMSW__ // Test MSW-specific function allowing to access the "system" menu. wxMenu* const menu = MSWGetSystemMenu(); if (menu) { menu->AppendSeparator(); // The ids of the menu commands in MSW system menu must be multiple of // 16 so we can't use DIALOGS_ABOUTDLG_SIMPLE here because it might not // satisfy this condition and need to define and connect a separate id. static const int DIALOGS_SYSTEM_ABOUT = 0x4010; menu->Append(DIALOGS_SYSTEM_ABOUT, "&About"); Bind(wxEVT_MENU, &Frame::ShowSimpleAboutDialog, this, DIALOGS_SYSTEM_ABOUT); } this->RestorePositionFromConfig(ClientToWindowSize(m_canvas->GetBestSize())); SetClientSize(GetClientSize()); #endif // __WXMSW__ } #if wxUSE_COLOURDLG void Frame::DoApplyColour(const wxColour& colour) { if (colour == m_canvas->GetBackgroundColour()) return; m_canvas->SetBackgroundColour(colour); m_canvas->ClearBackground(); m_canvas->Refresh(); } void Frame::OnColourChanged(wxColourDialogEvent& event) { DoApplyColour(event.GetColour()); } void Frame::ChooseColour(wxCommandEvent& event) { m_clrData.SetColour(m_canvas->GetBackgroundColour()); m_clrData.SetChooseAlpha(event.GetId() == DIALOGS_CHOOSE_COLOUR_ALPHA); wxColourDialog dialog(this, &m_clrData); dialog.Bind(wxEVT_COLOUR_CHANGED, &Frame::OnColourChanged, this); dialog.SetTitle("Please choose the background colour"); if (dialog.ShowModal() == wxID_OK) { m_clrData = dialog.GetColourData(); } DoApplyColour(m_clrData.GetColour()); } void Frame::GetColour(wxCommandEvent& WXUNUSED(event)) { wxColour clr = wxGetColourFromUser ( this, m_canvas->GetForegroundColour(), "Please choose the foreground colour" ); if (clr.IsOk()) { m_canvas->SetForegroundColour(clr); m_canvas->Refresh(); } //else: dialog cancelled by user } #endif // wxUSE_COLOURDLG #if wxUSE_FONTDLG void Frame::ChooseFont(wxCommandEvent& WXUNUSED(event)) { wxFontData data; data.SetInitialFont(m_canvas->GetFont()); data.SetColour(m_canvas->GetForegroundColour()); // you might also do this: // // wxFontDialog dialog; // if ( !dialog.Create(this, data) { ... error ... } // wxFontDialog dialog(this, data); if (dialog.ShowModal() == wxID_OK) { wxFontData retData = dialog.GetFontData(); m_canvas->SetFont(retData.GetChosenFont()); m_canvas->SetForegroundColour(retData.GetColour()); m_canvas->Refresh(); } //else: cancelled by the user, don't change the font } #endif // wxUSE_FONTDLG #if wxUSE_LOG_DIALOG void Frame::LogDialog(wxCommandEvent& WXUNUSED(event)) { // calling wxYield() (as ~wxBusyCursor does) shouldn't result in messages // being flushed -- test it { wxBusyCursor bc; wxLogMessage("This is some message - everything is ok so far."); wxLogMessage("Another message...\n... this one is on multiple lines"); wxLogWarning("And then something went wrong!"); // and if ~wxBusyCursor doesn't do it, then call it manually wxYield(); } wxLogError("Intermediary error handler decided to abort."); wxLogError("The top level caller detected an unrecoverable error."); wxLog::FlushActive(); wxLogMessage("And this is the same dialog but with only one message."); } #endif // wxUSE_LOG_DIALOG #if wxUSE_INFOBAR void Frame::InfoBarSimple(wxCommandEvent& WXUNUSED(event)) { static int s_count = 0; m_infoBarSimple->ShowMessage ( wxString::Format("Message #%d in the info bar.", ++s_count) ); } void Frame::InfoBarSimpleWrapped(wxCommandEvent& WXUNUSED(event)) { m_infoBarSimple->ShowMessage("This is very very long message to try the label wrapping on the info bar"); } void Frame::InfoBarAdvanced(wxCommandEvent& WXUNUSED(event)) { m_infoBarAdvanced->ShowMessage("Sorry, it didn't work out.", wxICON_WARNING); } void Frame::OnInfoBarRedo(wxCommandEvent& WXUNUSED(event)) { m_infoBarAdvanced->ShowMessage("Still no, sorry again.", wxICON_ERROR); } #endif // wxUSE_INFOBAR #if wxUSE_MSGDLG void Frame::MessageBox(wxCommandEvent& WXUNUSED(event)) { wxMessageDialog dialog(this, "This is a message box\n" "This is a long, long string to test out if the message box " "is laid out properly.", "Message box text", wxCENTER | wxNO_DEFAULT | wxYES_NO | wxCANCEL | wxICON_INFORMATION); wxString extmsg; if (dialog.SetYesNoCancelLabels ( "Answer &Yes", "Answer &No", "Refuse to answer" )) { extmsg = "This platform supports custom button labels,\n" "so you should see the descriptive labels below."; } else { extmsg = "Custom button labels are not supported on this platform,\n" "so the default \"Yes\"/\"No\"/\"Cancel\" buttons are used."; } dialog.SetExtendedMessage(extmsg); switch (dialog.ShowModal()) { case wxID_YES: wxLogStatus("You pressed \"Yes\""); break; case wxID_NO: wxLogStatus("You pressed \"No\""); break; case wxID_CANCEL: wxLogStatus("You pressed \"Cancel\""); break; default: wxLogError("Unexpected wxMessageDialog return code!"); } } void Frame::MessageBoxWindowModal(wxCommandEvent& WXUNUSED(event)) { wxMessageDialog* dialog = new wxMessageDialog(this, "This is a message box\n" "This is a long, long string to test out if the message box " "is laid out properly.", "Message box text", wxCENTER | wxNO_DEFAULT | wxYES_NO | wxCANCEL | wxICON_INFORMATION); wxString extmsg; if (dialog->SetYesNoCancelLabels ( "Answer &Yes", "Answer &No", "Refuse to answer" )) { extmsg = "This platform supports custom button labels,\n" "so you should see the descriptive labels below."; } else { extmsg = "Custom button labels are not supported on this platform,\n" "so the default \"Yes\"/\"No\"/\"Cancel\" buttons are used."; } dialog->SetExtendedMessage(extmsg); dialog->Bind(wxEVT_WINDOW_MODAL_DIALOG_CLOSED, &Frame::MessageBoxWindowModalClosed, this); dialog->ShowWindowModal(); } void Frame::MessageBoxWindowModalClosed(wxWindowModalDialogEvent& event) { wxDialog* dialog = event.GetDialog(); switch (dialog->GetReturnCode()) { case wxID_YES: wxLogStatus("You pressed \"Yes\""); break; case wxID_NO: wxLogStatus("You pressed \"No\""); break; case wxID_CANCEL: wxLogStatus("You pressed \"Cancel\""); break; default: wxLogError("Unexpected wxMessageDialog return code!"); } delete dialog; } void Frame::MessageBoxDialog(wxCommandEvent& WXUNUSED(event)) { TestMessageBoxDialog dlg(this); dlg.Create(); dlg.ShowModal(); } void Frame::MessageBoxDialogWindowModal(wxCommandEvent& WXUNUSED(event)) { TestMessageBoxDialog* dlg = new TestMessageBoxDialog(this); dlg->Create(); dlg->ShowWindowModal(); } void Frame::MessageBoxDialogWindowModalClosed(wxWindowModalDialogEvent& event) { TestMessageBoxDialog* dialog = dynamic_cast(event.GetDialog()); delete dialog; } void Frame::MessageBoxInfo(wxCommandEvent& WXUNUSED(event)) { ::wxInfoMessageBox(this); } #endif // wxUSE_MSGDLG #if wxUSE_RICHMSGDLG void Frame::RichMessageDialog(wxCommandEvent& WXUNUSED(event)) { TestRichMessageDialog dlg(this); dlg.Create(); dlg.ShowModal(); } #endif // wxUSE_RICHMSGDLG #if wxUSE_NUMBERDLG void Frame::NumericEntry(wxCommandEvent& WXUNUSED(event)) { long res = wxGetNumberFromUser("This is some text, actually a lot of text.\n" "Even two rows of text.", "Enter a number:", "Numeric input test", 50, 0, 100, this); wxString msg; int icon; if (res == -1) { msg = "Invalid number entered or dialog cancelled."; icon = wxICON_HAND; } else { msg.Printf("You've entered %lu", res); icon = wxICON_INFORMATION; } wxMessageBox(msg, "Numeric test result", wxOK | icon, this); } #endif // wxUSE_NUMBERDLG #if wxUSE_TEXTDLG void Frame::PasswordEntry(wxCommandEvent& WXUNUSED(event)) { wxString pwd = wxGetPasswordFromUser("Enter password:", "Password entry dialog", wxEmptyString, this); if (!pwd.empty()) { wxMessageBox(wxString::Format("Your password is '%s'", pwd), "Got password", wxOK | wxICON_INFORMATION, this); } } void Frame::LineEntry(wxCommandEvent& WXUNUSED(event)) { wxTextEntryDialog dialog(this, "This is a small sample\n" "A long, long string to test out the text entrybox", "Please enter a string", "Default value", wxOK | wxCANCEL); if (dialog.ShowModal() == wxID_OK) { wxMessageBox(dialog.GetValue(), "Got string", wxOK | wxICON_INFORMATION, this); } } void Frame::TextEntry(wxCommandEvent& WXUNUSED(event)) { wxTextEntryDialog dialog(this, "You can enter a multiline string here.", "Please enter some text", "First line\nSecond one\nAnd another one too", wxOK | wxCANCEL | wxTE_MULTILINE); if (dialog.ShowModal() == wxID_OK) { wxMessageBox(dialog.GetValue(), "Got text", wxOK | wxICON_INFORMATION, this); } } #endif // wxUSE_TEXTDLG #if wxUSE_CREDENTIALDLG void Frame::CredentialEntry(wxCommandEvent& WXUNUSED(event)) { wxCredentialEntryDialog dialog(this, "A login is required", "Credentials"); if (dialog.ShowModal() == wxID_OK) { const wxWebCredentials credentials = dialog.GetCredentials(); const wxString& password = wxSecretString(credentials.GetPassword()); wxMessageBox ( wxString::Format ( "User: %s Password: %s", credentials.GetUser(), password ), "Credentials", wxOK | wxICON_INFORMATION, this ); } } #endif // wxUSE_CREDENTIALDLG #if wxUSE_CHOICEDLG void Frame::SingleChoice(wxCommandEvent& WXUNUSED(event)) { const wxString choices[] = { "One", "Two", "Three", "Four", "Five" }; wxSingleChoiceDialog dialog(this, "This is a small sample\n" "A single-choice convenience dialog", "Please select a value", WXSIZEOF(choices), choices); dialog.SetSelection(2); if (dialog.ShowModal() == wxID_OK) { wxMessageDialog dialog2(this, dialog.GetStringSelection(), "Got string"); dialog2.ShowModal(); } } void Frame::MultiChoice(wxCommandEvent& WXUNUSED(event)) { const wxString choices[] = { "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Seventeen", }; wxArrayInt selections; const int count = wxGetSelectedChoices(selections, "This is a small sample\n" "A multi-choice convenience dialog", "Please select a value", WXSIZEOF(choices), choices, this); if (count >= 0) { wxString msg; if (count == 0) { msg = "You did not select any items"; } else { msg.Printf("You selected %u items:\n", (unsigned)count); for (int n = 0; n < count; n++) { msg += wxString::Format("\t%u: %u (%s)\n", (unsigned)n, (unsigned)selections[n], choices[selections[n]]); } } wxLogMessage(msg); } //else: cancelled } #endif // wxUSE_CHOICEDLG #if wxUSE_REARRANGECTRL // custom rearrange dialog: it adds the possibility to rename an item to the // base class functionality class MyRearrangeDialog : public wxRearrangeDialog { public: MyRearrangeDialog(wxWindow* parent, wxArrayInt& order, wxArrayString& labels, wxArrayString& labelsOrig) : wxRearrangeDialog ( parent, "Configure the columns shown:", "wxRearrangeDialog example", order, labels ), m_order(order), m_labels(labels), m_labelsOrig(labelsOrig) { m_sel = wxNOT_FOUND; wxPanel* const panel = new wxPanel(this); wxSizer* const sizer = new wxBoxSizer(wxHORIZONTAL); m_labelOrig = new wxStaticText(panel, wxID_ANY, ""); sizer->Add(m_labelOrig, wxSizerFlags().Centre().Border(wxRIGHT)); m_text = new wxTextCtrl(panel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); sizer->Add(m_text, wxSizerFlags().Centre().Border(wxRIGHT)); sizer->Add(new wxButton(panel, wxID_APPLY, "&Rename"), wxSizerFlags().Centre()); panel->SetSizer(sizer); // call this first to ensure that the controls have a reasonable best // size before they're added DoUpdateExtraControls(GetList()->GetSelection()); AddExtraControls(panel); // another customization not directly supported by the dialog: add a // custom button wxWindow* const btnOk = FindWindow(wxID_OK); wxCHECK_RET(btnOk, "no Ok button?"); wxSizer* const sizerBtns = btnOk->GetContainingSizer(); wxCHECK_RET(sizerBtns, "no buttons sizer?"); sizerBtns->Add(new wxButton(this, wxID_RESET, "&Reset all"), wxSizerFlags().Border(wxLEFT)); } // call this instead of ShowModal() to update order and labels array in // case the dialog was not cancelled bool Rearrange() { switch (ShowModal()) { case wxID_CANCEL: return false; case wxID_OK: m_order = GetOrder(); break; case wxID_RESET: // order already reset break; } return true; } private: void OnSelChange(wxCommandEvent& event) { DoUpdateExtraControls(event.GetInt()); } void OnUpdateUIRename(wxUpdateUIEvent& event) { event.Enable(CanRename()); } void OnRename(wxCommandEvent& WXUNUSED(event)) { if (!CanRename()) return; m_labels[m_sel] = m_text->GetValue(); GetList()->SetString(m_sel, m_labels[m_sel]); } void OnReset(wxCommandEvent& WXUNUSED(event)) { // in a real program we should probably ask if the user really wants to // do this but here we just go ahead and reset all columns labels and // their order without confirmation const unsigned count = m_order.size(); for (unsigned n = 0; n < count; n++) { m_order[n] = n; m_labels[n] = m_labelsOrig[n]; } EndModal(wxID_RESET); } bool CanRename() const { // only allow renaming if the user modified the currently selected item // text (which presupposes that we do have a current item) return m_sel != wxNOT_FOUND && m_text->GetValue() != m_labels[m_sel]; } void DoUpdateExtraControls(int sel) { m_sel = sel; if (m_sel == wxNOT_FOUND) { m_labelOrig->SetLabel(""); m_text->Clear(); m_text->Disable(); } else // have valid item { m_labelOrig->SetLabelText(m_labelsOrig[m_sel]); m_text->Enable(); m_text->SetValue(m_labels[m_sel]); } } wxArrayInt& m_order; wxArrayString& m_labels, m_labelsOrig; int m_sel; wxStaticText* m_labelOrig; wxTextCtrl* m_text; wxDECLARE_EVENT_TABLE(); wxDECLARE_NO_COPY_CLASS(MyRearrangeDialog); }; wxBEGIN_EVENT_TABLE(MyRearrangeDialog, wxRearrangeDialog) EVT_LISTBOX(wxID_ANY, MyRearrangeDialog::OnSelChange) EVT_UPDATE_UI(wxID_APPLY, MyRearrangeDialog::OnUpdateUIRename) EVT_TEXT_ENTER(wxID_ANY, MyRearrangeDialog::OnRename) EVT_BUTTON(wxID_APPLY, MyRearrangeDialog::OnRename) EVT_BUTTON(wxID_RESET, MyRearrangeDialog::OnReset) wxEND_EVENT_TABLE() void Frame::Rearrange(wxCommandEvent& WXUNUSED(event)) { // the arrays are static so that we preserve the items order between calls // to this function static wxArrayInt s_order; static wxArrayString s_labels, s_labelsOrig; // initialize them on the first call if (s_labelsOrig.empty()) { static const struct ItemInfo { const char* label; const char* labelOrig; int order; } items[] = { { "File name", "Name", 0 }, { "File type", "Ext", 1 }, { "Size", "Size", 2 }, { "Creation time", "Ctime", ~3 }, // negated so hidden { "Last accessed", "Atime", ~4 }, { "Last modified", "Mtime", 5 }, }; s_order.reserve(WXSIZEOF(items)); s_labels.reserve(WXSIZEOF(items)); s_labelsOrig.reserve(WXSIZEOF(items)); for (unsigned n = 0; n < WXSIZEOF(items); n++) { const ItemInfo& item = items[n]; s_order.push_back(item.order); s_labels.push_back(item.label); s_labelsOrig.push_back(item.labelOrig); } } MyRearrangeDialog dlg(this, s_order, s_labels, s_labelsOrig); if (!dlg.Rearrange()) return; wxString columns; for (unsigned n = 0; n < s_order.size(); n++) { columns += wxString::Format("\n %u: ", n); int idx = s_order[n]; if (idx < 0) { columns += "[hidden] "; idx = ~idx; } columns += s_labels[idx]; if (s_labels[idx] != s_labelsOrig[idx]) { columns += wxString::Format(" (original label: \"%s\")", s_labelsOrig[idx]); } } wxLogMessage("The columns order now is:%s", columns); } #endif // wxUSE_REARRANGECTRL #if wxUSE_ADDREMOVECTRL void Frame::AddRemove(wxCommandEvent& WXUNUSED(event)) { wxDialog dlg(this, wxID_ANY, "wxAddRemoveCtrl test", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER); wxAddRemoveCtrl* const ctrl = new wxAddRemoveCtrl(&dlg); ctrl->SetInitialSize(wxSize(-1, 12 * GetCharHeight())); const wxString items[] = { "some", "items", "for", "testing", "wxAddRemoveCtrl", }; wxListBox* const lbox = new wxListBox(ctrl, wxID_ANY, wxDefaultPosition, wxDefaultSize, WXSIZEOF(items), items); // Test adaptor class connecting wxAddRemoveCtrl with wxListBox we use // inside it. class ListBoxAdaptor : public wxAddRemoveAdaptor { public: explicit ListBoxAdaptor(wxListBox* lbox) : m_lbox(lbox) { } wxWindow* GetItemsCtrl() const wxOVERRIDE { return m_lbox; } bool CanAdd() const wxOVERRIDE { // Restrict the maximal number of items to 10 just for testing. return m_lbox->GetCount() <= 10; } bool CanRemove() const wxOVERRIDE { // We must have a selected item in order to be able to delete it. return m_lbox->GetSelection() != wxNOT_FOUND; } void OnAdd() wxOVERRIDE { // A real program would use a wxDataViewCtrl or wxListCtrl and // allow editing the newly edited item in place, here we just use a // hardcoded item value instead. static int s_item = 0; m_lbox->Append(wxString::Format("new item #%d", ++s_item)); } void OnRemove() wxOVERRIDE { // Notice that we don't need to check if we have a valid selection, // we can be only called if CanRemove(), which already checks for // this, had returned true. const unsigned pos = m_lbox->GetSelection(); m_lbox->Delete(pos); m_lbox->SetSelection(pos == m_lbox->GetCount() ? pos - 1 : pos); } private: wxListBox* const m_lbox; }; ctrl->SetAdaptor(new ListBoxAdaptor(lbox)); ctrl->SetButtonsToolTips("Add up to 10 items", "Remove current item"); wxSizer* const sizerTop = new wxBoxSizer(wxVERTICAL); sizerTop->Add(ctrl, wxSizerFlags(1).Expand().Border()); sizerTop->Add(dlg.CreateStdDialogButtonSizer(wxOK | wxCANCEL), wxSizerFlags().Expand().Border()); dlg.SetSizerAndFit(sizerTop); dlg.ShowModal(); } #endif // wxUSE_ADDREMOVECTRL #if wxUSE_FILEDLG // Simple function showing the current wxFileDialog state. wxString GetFileDialogStateDescription(wxFileDialogBase* dialog) { const wxString fn = dialog->GetCurrentlySelectedFilename(); wxString msg; if (fn.empty()) msg = "Nothing"; else if (wxFileName::FileExists(fn)) msg = "File"; else if (wxFileName::DirExists(fn)) msg = "Directory"; else msg = "Something else"; msg += " selected"; const int filter = dialog->GetCurrentlySelectedFilterIndex(); if (filter != wxNOT_FOUND) msg += wxString::Format(" (filter=%d)", filter); return msg; } // Another helper translating demo combobox selection. wxString GetFileDialogPaperSize(int selection) { switch (selection) { case -1: return ""; case 0: return "A4"; case 1: return "Letter"; default: return "INVALID"; } } // panel with custom controls for file dialog class MyExtraPanel : public wxPanel { public: MyExtraPanel(wxWindow* parent); wxString GetInfo() const { return wxString::Format("paper=%s (%s), enabled=%d, text=\"%s\"", m_paperSize, m_paperOrient, m_checked, m_str); } private: void OnCheckBox(wxCommandEvent& event) { m_checked = event.IsChecked(); m_btn->Enable(m_checked); } void OnRadioButton(wxCommandEvent& event) { if (event.GetEventObject() == m_radioPortrait) m_paperOrient = "portrait"; else if (event.GetEventObject() == m_radioLandscape) m_paperOrient = "landscape"; else m_paperOrient = "unknown"; } void OnChoice(wxCommandEvent& event) { m_paperSize = GetFileDialogPaperSize(event.GetSelection()); } void OnText(wxCommandEvent& event) { m_str = event.GetString(); } void OnUpdateLabelUI(wxUpdateUIEvent& event) { // In this sample, the dialog may be either wxFileDialog itself, or // wxGenericFileDialog, so we need to cast to the base class. In a // typical application, we would cast to just wxFileDialog instead. wxFileDialogBase* const dialog = wxStaticCast(GetParent(), wxFileDialogBase); event.SetText(GetFileDialogStateDescription(dialog)); } wxString m_str; bool m_checked; wxString m_paperSize; wxString m_paperOrient; wxButton* m_btn; wxCheckBox* m_cb; wxRadioButton* m_radioPortrait; wxRadioButton* m_radioLandscape; wxStaticText* m_label; wxTextCtrl* m_text; }; MyExtraPanel::MyExtraPanel(wxWindow* parent) : wxPanel(parent), m_str("extra text"), m_checked(false) { m_btn = new wxButton(this, -1, "Custom Button"); m_btn->Enable(false); m_cb = new wxCheckBox(this, -1, "Enable Custom Button"); m_cb->Bind(wxEVT_CHECKBOX, &MyExtraPanel::OnCheckBox, this); wxChoice* choiceSize = new wxChoice(this, wxID_ANY); choiceSize->Append("A4"); choiceSize->Append("Letter"); choiceSize->Bind(wxEVT_CHOICE, &MyExtraPanel::OnChoice, this); m_radioPortrait = new wxRadioButton(this, wxID_ANY, "&Portrait", wxDefaultPosition, wxDefaultSize, wxRB_GROUP); m_radioPortrait->Bind(wxEVT_RADIOBUTTON, &MyExtraPanel::OnRadioButton, this); m_radioLandscape = new wxRadioButton(this, wxID_ANY, "&Landscape"); m_radioLandscape->Bind(wxEVT_RADIOBUTTON, &MyExtraPanel::OnRadioButton, this); m_label = new wxStaticText(this, wxID_ANY, "Nothing selected"); m_label->Bind(wxEVT_UPDATE_UI, &MyExtraPanel::OnUpdateLabelUI, this); m_text = new wxTextCtrl(this, -1, m_str, wxDefaultPosition, wxSize(40 * GetCharWidth(), -1)); m_text->Bind(wxEVT_TEXT, &MyExtraPanel::OnText, this); wxBoxSizer* sizerTop = new wxBoxSizer(wxHORIZONTAL); sizerTop->Add(new wxStaticText(this, wxID_ANY, "Just some extra text:"), wxSizerFlags().Centre().Border()); sizerTop->Add(m_text, wxSizerFlags(1).Centre().Border()); sizerTop->AddSpacer(10); sizerTop->Add(choiceSize, wxSizerFlags().Centre().Border(wxRIGHT)); sizerTop->Add(m_radioPortrait, wxSizerFlags().Centre().Border()); sizerTop->Add(m_radioLandscape, wxSizerFlags().Centre().Border()); sizerTop->Add(m_cb, wxSizerFlags().Centre().Border()); sizerTop->AddSpacer(5); sizerTop->Add(m_btn, wxSizerFlags().Centre().Border()); sizerTop->AddSpacer(5); sizerTop->Add(m_label, wxSizerFlags(1).Centre().Border()); SetSizerAndFit(sizerTop); } // a static method can be used instead of a function with most of compilers static wxWindow* createMyExtraPanel(wxWindow* parent) { return new MyExtraPanel(parent); } // This class does the same thing as MyExtraPanel above, but uses newer API for // wxFileDialog customization. class MyCustomizeHook : public wxFileDialogCustomizeHook { public: // Normally we would just use wxFileDialog, but this sample allows using // both the real wxFileDialog and wxGenericFileDialog, so allow passing // either of them here. explicit MyCustomizeHook(wxFileDialogBase& dialog) : m_dialog(&dialog) { } // Override pure virtual base class method to add our custom controls. virtual void AddCustomControls(wxFileDialogCustomize& customizer) wxOVERRIDE { // Note: all the pointers created here cease to be valid once // ShowModal() returns, TransferDataFromCustomControls() is the latest // moment when they can still be used. m_text = customizer.AddTextCtrl("Just some extra text:"); const wxString sizes[] = { "A4", "Letter" }; m_choiceSize = customizer.AddChoice(WXSIZEOF(sizes), sizes); m_radioPortrait = customizer.AddRadioButton("&Portrait"); m_radioLandscape = customizer.AddRadioButton("&Landscape"); m_cb = customizer.AddCheckBox("Enable Custom Button"); m_cb->Bind(wxEVT_CHECKBOX, &MyCustomizeHook::OnCheckBox, this); m_btn = customizer.AddButton("Custom Button"); m_btn->Bind(wxEVT_BUTTON, &MyCustomizeHook::OnButton, this); m_label = customizer.AddStaticText("Nothing selected"); } // Override another method called whenever something changes in the dialog. virtual void UpdateCustomControls() wxOVERRIDE { // Enable the button if and only if the checkbox is checked. m_btn->Enable(m_cb->GetValue()); // Enable radio buttons only if a file is selected. bool hasFile = wxFileName::FileExists( m_dialog->GetCurrentlySelectedFilename() ); m_radioPortrait->Enable(hasFile); m_radioLandscape->Enable(hasFile); // Also show the current dialog state. m_label->SetLabelText(GetFileDialogStateDescription(m_dialog)); } // And another one called when the dialog is accepted. virtual void TransferDataFromCustomControls() wxOVERRIDE { m_info.Printf("paper=%s (%s), enabled=%d, text=\"%s\"", GetFileDialogPaperSize(m_choiceSize->GetSelection()), m_radioPortrait->GetValue() ? "portrait" : "landscape", m_cb->GetValue(), m_text->GetValue()); } // This is just a helper function allowing to show the values of the custom // controls. wxString GetInfo() const { return m_info; } private: void OnCheckBox(wxCommandEvent& event) { m_btn->Enable(event.IsChecked()); } void OnButton(wxCommandEvent& WXUNUSED(event)) { wxMessageBox("Custom button pressed", "wxWidgets dialogs sample", wxOK | wxICON_INFORMATION, m_dialog); } wxFileDialogBase* const m_dialog; wxFileDialogButton* m_btn; wxFileDialogCheckBox* m_cb; wxFileDialogChoice* m_choiceSize; wxFileDialogRadioButton* m_radioPortrait; wxFileDialogRadioButton* m_radioLandscape; wxFileDialogTextCtrl* m_text; wxFileDialogStaticText* m_label; wxString m_info; wxDECLARE_NO_COPY_CLASS(MyCustomizeHook); }; void Frame::OnFileOpen(wxCommandEvent& WXUNUSED(event)) { wxFileName fnLastUsed(wxString::FromUTF8(m_strLastUsedFile)); wxFileDialog dialog ( this, "Testing open file dialog", fnLastUsed.GetPath(), fnLastUsed.GetFullName(), wxString::Format ( "Html (*.htm;*.html)|*.htm;*.html|Text files (*.txt)|*.txt|" "Document files (*.doc;*.ods)|*.doc;*.ods|Markdown (*.md)|*.md|" "All (%s)|%s|C++ files (*.cpp;*.h)|*.cpp;*.h", wxFileSelectorDefaultWildcardStr, wxFileSelectorDefaultWildcardStr ) ); dialog.SetFilterIndex(m_FileDialogFilterIndex); // For demonstration purposes, add wxWidgets directories to the sidebar. wxString wxdir; if (wxGetEnv("WXWIN", &wxdir)) { dialog.AddShortcut(wxdir + "/src"); // By default shortcuts are added at the bottom, but we can override // this in the ports that support it (currently only wxMSW) and add a // shortcut added later at the top instead. dialog.AddShortcut(wxdir + "/include", wxFD_SHORTCUT_TOP); } // Note: this object must remain alive until ShowModal() returns. MyCustomizeHook myCustomizer(dialog); // Normal programs would use either SetCustomizeHook() (preferred) or // SetExtraControlCreator() (if its extra flexibility is really required), // but, for demonstration purposes, this sample allows either one or the // other. const bool useExtra = GetMenuBar()->IsChecked(DIALOGS_FILE_USE_EXTRA_CONTROL_CREATOR); const bool hasExtra = useExtra ? dialog.SetExtraControlCreator(&createMyExtraPanel) : dialog.SetCustomizeHook(myCustomizer); dialog.CentreOnParent(); if (dialog.ShowModal() == wxID_OK) { wxString extraInfo; if (hasExtra) { if (useExtra) { wxWindow* const extra = dialog.GetExtraControl(); extraInfo = static_cast(extra)->GetInfo(); } else { extraInfo = myCustomizer.GetInfo(); } } else { extraInfo = ""; } m_FileDialogFilterIndex = dialog.GetFilterIndex(); m_strLastUsedFile = dialog.GetPath().ToUTF8(); wxString info; info.Printf("Full file name: %s\n" "Path: %s\n" "Name: %s\n" "Custom window: %s", dialog.GetPath(), dialog.GetDirectory(), dialog.GetFilename(), extraInfo); wxMessageDialog dialog2(this, info, "Selected file"); dialog2.ShowModal(); } } // this shows how to take advantage of specifying a default extension in the // call to wxFileSelector: it is remembered after each new call and the next // one will use it by default void Frame::FileOpen2(wxCommandEvent& WXUNUSED(event)) { static wxString s_extDef; wxString path = wxFileSelector( "Select the file to load", wxEmptyString, wxEmptyString, s_extDef, wxString::Format ( "Waveform (*.wav)|*.wav|Plain text (*.txt)|*.txt|All files (%s)|%s", wxFileSelectorDefaultWildcardStr, wxFileSelectorDefaultWildcardStr ), wxFD_OPEN | wxFD_CHANGE_DIR | wxFD_PREVIEW | wxFD_NO_FOLLOW | wxFD_SHOW_HIDDEN, this ); if (!path) return; // it is just a sample, would use wxSplitPath in real program s_extDef = path.AfterLast('.'); wxLogMessage("You selected the file '%s', remembered extension '%s'", path, s_extDef); } void Frame::FilesOpen(wxCommandEvent& WXUNUSED(event)) { wxString wildcards = #ifdef __WXMOTIF__ "C++ files (*.cpp)|*.cpp"; #else wxString::Format ( "All files (%s)|%s|C++ files (*.cpp;*.h)|*.cpp;*.h", wxFileSelectorDefaultWildcardStr, wxFileSelectorDefaultWildcardStr ); #endif wxFileDialog dialog(this, "Testing open multiple file dialog", wxEmptyString, wxEmptyString, wildcards, wxFD_OPEN | wxFD_MULTIPLE); dialog.Centre(wxCENTER_ON_SCREEN); if (dialog.ShowModal() == wxID_OK) { wxArrayString paths, filenames; dialog.GetPaths(paths); dialog.GetFilenames(filenames); wxString msg, s; size_t count = paths.GetCount(); for (size_t n = 0; n < count; n++) { s.Printf("File %d: %s (%s)\n", (int)n, paths[n], filenames[n]); msg += s; } s.Printf("Filter index: %d", dialog.GetFilterIndex()); msg += s; wxMessageDialog dialog2(this, msg, "Selected files"); dialog2.ShowModal(); } } void Frame::OnSaveNew(wxCommandEvent& WXUNUSED(event)) { wxFileName fnLastUsed(wxString::FromUTF8(m_strLastUsedFile)); wxFileDialog dialog(this, "Testing save file dialog", fnLastUsed.GetPath(), fnLastUsed.GetFullName(), wxString::Format ( "Html (*.htm;*.html)|*.htm;*.html|Text files (*.txt)|*.txt|" "Document files (*.doc;*.ods)|*.doc;*.ods|Markdown (*.md)|*.md|" "All (%s)|%s|C++ files (*.cpp;*.h)|*.cpp;*.h", wxFileSelectorDefaultWildcardStr, wxFileSelectorDefaultWildcardStr ), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); dialog.SetFilterIndex(m_FileDialogFilterIndex); // This tests the (even more simplified) example from the docs. class EncryptHook : public wxFileDialogCustomizeHook { public: EncryptHook() : m_encrypt(false) { } void AddCustomControls(wxFileDialogCustomize& customizer) wxOVERRIDE { m_checkbox = customizer.AddCheckBox("Encrypt"); } void TransferDataFromCustomControls() wxOVERRIDE { m_encrypt = m_checkbox->GetValue(); } bool Encrypt() const { return m_encrypt; } private: wxFileDialogCheckBox* m_checkbox; bool m_encrypt; }; EncryptHook customHook; dialog.SetCustomizeHook(customHook); if (dialog.ShowModal() == wxID_OK) { m_FileDialogFilterIndex = dialog.GetFilterIndex(); m_strLastUsedFile = dialog.GetPath().ToUTF8(); wxLogMessage("%s,\n filter %d%s", dialog.GetPath(), m_FileDialogFilterIndex, customHook.Encrypt() ? ", encrypt" : ""); } } #endif // wxUSE_FILEDLG void Frame::MacToggleAlwaysShowTypes(wxCommandEvent& event) { #ifdef wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES wxSystemOptions::SetOption(wxOSX_FILEDIALOG_ALWAYS_SHOW_TYPES, event.IsChecked()); #else wxUnusedVar(event); #endif } #if wxUSE_DIRDLG void Frame::DoDirChoose(int style) { // pass some initial dir to wxDirDialog wxString dirHome; wxGetHomeDir(&dirHome); wxDirDialog dialog(this, "Testing directory picker", dirHome, style); if (dialog.ShowModal() == wxID_OK) { wxLogMessage("Selected path: %s", dialog.GetPath()); } } void Frame::DirChoose(wxCommandEvent& WXUNUSED(event)) { DoDirChoose(wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST); } void Frame::DirChooseNew(wxCommandEvent& WXUNUSED(event)) { DoDirChoose(wxDD_DEFAULT_STYLE & ~wxDD_DIR_MUST_EXIST); } void Frame::DirChooseMultiple(wxCommandEvent& WXUNUSED(event)) { // pass some initial dir and the style to wxDirDialog int style = wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST | wxDD_MULTIPLE | wxDD_SHOW_HIDDEN; wxString dirHome; wxGetHomeDir(&dirHome); wxDirDialog dialog(this, "Testing multiple directory picker", dirHome, style); if (dialog.ShowModal() == wxID_OK) { wxArrayString paths; dialog.GetPaths(paths); wxString msg, s; size_t count = paths.GetCount(); for (size_t n = 0; n < count; n++) { s.Printf("Directory %d: %s\n", (int)n, paths[n]); msg += s; } wxMessageDialog dialog2(this, msg, "Selected directories"); dialog2.ShowModal(); } } void Frame::DirChooseWindowModal(wxCommandEvent& WXUNUSED(event)) { // pass some initial dir to wxDirDialog wxString dirHome; wxGetHomeDir(&dirHome); wxDirDialog* dialog = new wxDirDialog(this, "Testing directory picker", dirHome, wxDD_DEFAULT_STYLE | wxDD_DIR_MUST_EXIST); dialog->Bind(wxEVT_WINDOW_MODAL_DIALOG_CLOSED, &Frame::DirChooseWindowModalClosed, this); dialog->ShowWindowModal(); } void Frame::DirChooseWindowModalClosed(wxWindowModalDialogEvent& event) { wxDirDialog* dialog = dynamic_cast(event.GetDialog()); if (dialog->GetReturnCode() == wxID_OK) { wxLogMessage("Selected path: %s", dialog->GetPath()); } delete dialog; } #endif // wxUSE_DIRDLG #if USE_MODAL_PRESENTATION void Frame::ModalDlg(wxCommandEvent& WXUNUSED(event)) { MyModalDialog dlg(this); dlg.ShowModal(); } #endif // USE_MODAL_PRESENTATION void Frame::ModelessDlg(wxCommandEvent& event) { bool show = GetMenuBar()->IsChecked(event.GetId()); if (show) { if (!m_dialog) { m_dialog = new MyModelessDialog(this); } m_dialog->Show(true); } else // hide { // If m_dialog is NULL, then possibly the system // didn't report the checked menu item status correctly. // It should be true just after the menu item was selected, // if there was no modeless dialog yet. wxASSERT(m_dialog != NULL); if (m_dialog) m_dialog->Hide(); } } void Frame::DlgCenteredScreen(wxCommandEvent& WXUNUSED(event)) { wxDialog dlg(this, wxID_ANY, "Dialog centered on screen", wxDefaultPosition, wxSize(200, 100)); (new wxButton(&dlg, wxID_OK, "Close"))->Centre(); dlg.CentreOnScreen(); dlg.ShowModal(); } void Frame::DlgCenteredParent(wxCommandEvent& WXUNUSED(event)) { wxDialog dlg(this, wxID_ANY, "Dialog centered on parent", wxDefaultPosition, wxSize(200, 100)); (new wxButton(&dlg, wxID_OK, "Close"))->Centre(); dlg.CentreOnParent(); dlg.ShowModal(); } #if wxUSE_MINIFRAME void Frame::MiniFrame(wxCommandEvent& WXUNUSED(event)) { wxFrame* frame = new wxMiniFrame(this, wxID_ANY, "Mini frame", wxDefaultPosition, wxSize(300, 100), wxCAPTION | wxCLOSE_BOX); new wxStaticText(frame, wxID_ANY, "Mini frames have slightly different appearance", wxPoint(5, 5)); new wxStaticText(frame, wxID_ANY, "from the normal frames but that's the only difference.", wxPoint(5, 25)); frame->CentreOnParent(); frame->Show(); } #endif // wxUSE_MINIFRAME void Frame::DlgOnTop(wxCommandEvent& WXUNUSED(event)) { wxDialog dlg(this, wxID_ANY, "Dialog staying on top of other windows", wxDefaultPosition, wxSize(300, 100), wxDEFAULT_DIALOG_STYLE | wxSTAY_ON_TOP); (new wxButton(&dlg, wxID_OK, "Close"))->Centre(); dlg.ShowModal(); } #if wxUSE_STARTUP_TIPS void Frame::ShowTip(wxCommandEvent& WXUNUSED(event)) { wxFileName fnResources; wxStandardPaths::Get().DontIgnoreAppSubDir(); fnResources.AssignDir(wxStandardPaths::Get().GetResourcesDir()); fnResources.SetFullName("tips.txt"); wxTipProvider* tipProvider = wxCreateFileTipProvider(fnResources.GetFullPath(), m_TipOfTheDayIndex); m_showTipsAtStartup = wxShowTip(this, tipProvider, m_showTipsAtStartup); m_TipOfTheDayIndex = tipProvider->GetCurrentTip(); delete tipProvider; } #endif // wxUSE_STARTUP_TIPS #if USE_SETTINGS_DIALOG void Frame::OnPropertySheet(wxCommandEvent& event) { SettingsDialog dialog(this, m_settingsData, event.GetId()); dialog.ShowModal(); } #endif // USE_SETTINGS_DIALOG void Frame::OnRequestUserAttention(wxCommandEvent& WXUNUSED(event)) { wxLogStatus("Sleeping for 3 seconds to allow you to switch to another window"); wxSleep(3); RequestUserAttention(wxUSER_ATTENTION_ERROR); } #if wxUSE_RICHTOOLTIP || wxUSE_NOTIFICATION_MESSAGE #include "tip.xpm" #endif #if wxUSE_NOTIFICATION_MESSAGE // ---------------------------------------------------------------------------- // TestNotificationMessageDialog // ---------------------------------------------------------------------------- class TestNotificationMessageWindow : public wxFrame { public: TestNotificationMessageWindow(wxWindow* parent) : wxFrame(parent, wxID_ANY, "User Notification Test Dialog") { #ifdef __WXMSW__ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); #endif wxSizer* const sizerTop = new wxBoxSizer(wxVERTICAL); wxSizer* sizerText = new wxStaticBoxSizer(wxVERTICAL, this, "Notification Texts"); sizerText->Add(new wxStaticText(this, wxID_ANY, "&Title:"), wxSizerFlags()); m_textTitle = new wxTextCtrl(this, wxID_ANY, "Notification Title"); sizerText->Add(m_textTitle, wxSizerFlags().Expand()); sizerText->Add(new wxStaticText(this, wxID_ANY, "&Message:"), wxSizerFlags()); m_textMessage = new wxTextCtrl(this, wxID_ANY, "A message within the notification", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); m_textMessage->SetMinSize(wxSize(300, -1)); sizerText->Add(m_textMessage, wxSizerFlags().Expand()); sizerTop->Add(sizerText, wxSizerFlags().Expand().Border()); const wxString icons[] = { "De&fault", "None", "&Information", "&Warning", "&Error", "&Custom" }; wxCOMPILE_TIME_ASSERT(WXSIZEOF(icons) == Icon_Max, IconMismatch); m_icons = new wxRadioBox(this, wxID_ANY, "Ic&on in notification", wxDefaultPosition, wxDefaultSize, WXSIZEOF(icons), icons, 1, wxRA_SPECIFY_ROWS); m_icons->SetSelection(Icon_Default); sizerTop->Add(m_icons, wxSizerFlags().Expand().Border()); const wxString timeouts[] = { "&Automatic", "&Never", "&5 sec", "&15 sec" }; m_showTimeout = new wxRadioBox(this, wxID_ANY, "&Timeout for notification", wxDefaultPosition, wxDefaultSize, WXSIZEOF(timeouts), timeouts, 1, wxRA_SPECIFY_ROWS); m_showTimeout->SetSelection(0); sizerTop->Add(m_showTimeout, wxSizerFlags().Expand().Border()); wxSizer* sizerActions = new wxStaticBoxSizer(wxVERTICAL, this, "Additional Actions"); m_actionList = new wxListBox(this, wxID_ANY); sizerActions->Add(m_actionList, wxSizerFlags().Expand()); wxSizer* sizerActionMod = new wxBoxSizer(wxHORIZONTAL); sizerActionMod->Add(new wxStaticText(this, wxID_ANY, "ID:"), wxSizerFlags().Center()); const wxString actionIds[] = { "wxID_DELETE", "wxID_CLOSE", "wxID_OK", "wxID_CANCEL" }; m_actionChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, WXSIZEOF(actionIds), actionIds ); m_actionChoice->SetSelection(0); sizerActionMod->Add(m_actionChoice); sizerActionMod->Add(new wxStaticText(this, wxID_ANY, "Custom label:"), wxSizerFlags().Center()); m_actionCaption = new wxTextCtrl(this, wxID_ANY); sizerActionMod->Add(m_actionCaption); wxButton* actionAddBtn = new wxButton(this, wxID_ADD); actionAddBtn->Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnActionAddClicked, this); sizerActionMod->Add(actionAddBtn); wxButton* actionRemoveBtn = new wxButton(this, wxID_REMOVE); actionRemoveBtn->Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnActionRemoveClicked, this); sizerActionMod->Add(actionRemoveBtn); sizerActions->Add(sizerActionMod, wxSizerFlags().Border()); sizerTop->Add(sizerActions, wxSizerFlags().Expand().Border()); wxSizer* sizerSettings = new wxStaticBoxSizer(wxVERTICAL, this, "Notification Settings"); #ifdef wxHAS_NATIVE_NOTIFICATION_MESSAGE m_useGeneric = new wxCheckBox(this, wxID_ANY, "Use &generic notifications"); sizerSettings->Add(m_useGeneric); #endif m_delayShow = new wxCheckBox(this, wxID_ANY, "&Delay show"); #if defined(__WXOSX__) m_delayShow->SetValue(true); #endif sizerSettings->Add(m_delayShow); m_handleEvents = new wxCheckBox(this, wxID_ANY, "&Handle events"); m_handleEvents->SetValue(true); sizerSettings->Add(m_handleEvents); #if defined(__WXMSW__) && wxUSE_TASKBARICON m_taskbarIcon = NULL; m_useTaskbar = new wxCheckBox(this, wxID_ANY, "Use persistent &taskbar icon"); m_useTaskbar->SetValue(false); sizerSettings->Add(m_useTaskbar); #endif sizerTop->Add(sizerSettings, wxSizerFlags().Expand().Border()); m_textStatus = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxST_NO_AUTORESIZE | wxALIGN_CENTRE_HORIZONTAL); m_textStatus->SetForegroundColour(*wxBLUE); sizerTop->Add(m_textStatus, wxSizerFlags().Expand().Border()); wxSizer* sizerButtons = new wxBoxSizer(wxHORIZONTAL); sizerButtons->Add(new wxButton(this, wxID_NEW, "&Show")); m_closeButton = new wxButton(this, wxID_CLOSE, "&Close"); m_closeButton->Disable(); sizerButtons->Add(m_closeButton); sizerTop->Add(sizerButtons, wxSizerFlags().Center()); SetSizerAndFit(sizerTop); Center(); Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnShowClicked, this, wxID_NEW); Bind(wxEVT_BUTTON, &TestNotificationMessageWindow::OnCloseClicked, this, wxID_CLOSE); } private: enum { Icon_Default, Icon_None, Icon_Info, Icon_Warning, Icon_Error, Icon_Custom, Icon_Max }; class ActionInfo : public wxClientData { public: ActionInfo(wxWindowID actionId, const wxString& actionCaption) : id(actionId), customCaption(actionCaption) { } wxWindowID id; wxString customCaption; }; wxTextCtrl* m_textTitle; wxTextCtrl* m_textMessage; wxRadioBox* m_icons; wxRadioBox* m_showTimeout; wxListBox* m_actionList; wxChoice* m_actionChoice; wxTextCtrl* m_actionCaption; #ifdef wxHAS_NATIVE_NOTIFICATION_MESSAGE wxCheckBox* m_useGeneric; #endif wxCheckBox* m_delayShow; wxCheckBox* m_handleEvents; wxStaticText* m_textStatus; wxButton* m_closeButton; #if defined(__WXMSW__) && wxUSE_TASKBARICON wxCheckBox* m_useTaskbar; wxTaskBarIcon* m_taskbarIcon; #endif wxSharedPtr< wxNotificationMessageBase> m_notif; void DoShowNotification() { if (m_delayShow->GetValue()) { ShowStatus("Sleeping for 3 seconds to allow you to switch to another window"); wxYield(); wxSleep(3); } m_closeButton->Enable(); ShowStatus("Showing notification..."); #ifdef wxHAS_NATIVE_NOTIFICATION_MESSAGE if (m_useGeneric->GetValue()) m_notif = new wxGenericNotificationMessage( m_textTitle->GetValue(), m_textMessage->GetValue(), this); else #endif { m_notif = new wxNotificationMessage( m_textTitle->GetValue(), m_textMessage->GetValue(), this); #if defined(__WXMSW__) && wxUSE_TASKBARICON if (m_useTaskbar->GetValue()) { if (!m_taskbarIcon) { m_taskbarIcon = new wxTaskBarIcon(); m_taskbarIcon->SetIcon(reinterpret_cast(GetParent())->GetIcon(), "Dialogs Sample (Persistent)"); } wxNotificationMessage::UseTaskBarIcon(m_taskbarIcon); } else if (m_taskbarIcon) { wxNotificationMessage::UseTaskBarIcon(NULL); delete m_taskbarIcon; m_taskbarIcon = NULL; } #endif } switch (m_icons->GetSelection()) { case Icon_Default: // Don't call SetFlags or SetIcon to see the implementations default break; case Icon_None: m_notif->SetFlags(0); break; case Icon_Info: m_notif->SetFlags(wxICON_INFORMATION); break; case Icon_Warning: m_notif->SetFlags(wxICON_WARNING); break; case Icon_Error: m_notif->SetFlags(wxICON_ERROR); break; case Icon_Custom: m_notif->SetIcon(tip_xpm); break; } int timeout; switch (m_showTimeout->GetSelection()) { case 1: timeout = wxNotificationMessage::Timeout_Never; break; case 2: timeout = 5; break; case 3: timeout = 10; break; default: timeout = wxNotificationMessage::Timeout_Auto; break; } for (unsigned int i = 0; i < m_actionList->GetCount(); i++) { ActionInfo* ai = reinterpret_cast(m_actionList->GetClientObject(i)); if (!m_notif->AddAction(ai->id, ai->customCaption)) wxLogWarning("Could not add action: %s", m_actionList->GetString(i)); } if (m_handleEvents->GetValue()) { m_notif->Bind(wxEVT_NOTIFICATION_MESSAGE_ACTION, &TestNotificationMessageWindow::OnNotificationAction, this); m_notif->Bind(wxEVT_NOTIFICATION_MESSAGE_CLICK, &TestNotificationMessageWindow::OnNotificationClicked, this); m_notif->Bind(wxEVT_NOTIFICATION_MESSAGE_DISMISSED, &TestNotificationMessageWindow::OnNotificationDismissed, this); } m_notif->Show(timeout); // Free the notification if we don't handle it's events if (!m_handleEvents->GetValue()) { // Notice that the notification remains shown even after the // wxNotificationMessage object itself is destroyed so we can show simple // notifications using temporary objects. m_notif.reset(); ShowStatus("Showing notification, deleted object"); } } void OnShowClicked(wxCommandEvent& WXUNUSED(event)) { DoShowNotification(); } void OnCloseClicked(wxCommandEvent& WXUNUSED(event)) { if (m_notif) m_notif->Close(); } void OnActionAddClicked(wxCommandEvent& WXUNUSED(event)) { wxWindowID actionId; switch (m_actionChoice->GetSelection()) { case 1: actionId = wxID_CLOSE; break; case 2: actionId = wxID_OK; break; case 3: actionId = wxID_CANCEL; break; default: actionId = wxID_DELETE; break; } wxString actionCaption = m_actionCaption->GetValue(); wxString desc = m_actionChoice->GetStringSelection(); if (!actionCaption.empty()) desc += " (" + actionCaption + ")"; m_actionList->SetSelection(m_actionList->Append(desc, new ActionInfo(actionId, actionCaption))); } void OnActionRemoveClicked(wxCommandEvent& WXUNUSED(event)) { int pos = m_actionList->GetSelection(); if (pos != wxNOT_FOUND) { m_actionList->Delete(pos); if (pos > 0 && m_actionList->GetCount() > 0) m_actionList->SetSelection(pos - 1); } else wxLogError("No action selected"); } void OnNotificationClicked(wxCommandEvent& event) { ShowStatus("Notification was clicked"); Raise(); event.Skip(); } void OnNotificationDismissed(wxCommandEvent& event) { ShowStatus("Notification was dismissed"); Raise(); event.Skip(); } void OnNotificationAction(wxCommandEvent& event) { ShowStatus(wxString::Format("Selected %s action in notification", wxGetStockLabel(event.GetId(), 0))); event.Skip(); } void ShowStatus(const wxString& text) { m_textStatus->SetLabelText(text); } }; void Frame::OnNotifMsg(wxCommandEvent& WXUNUSED(event)) { #ifdef __WXMSW__ // Try to enable toast notifications (available since Win8) if (!wxNotificationMessage::MSWUseToasts()) { wxLogDebug("Toast notifications not available."); } #endif TestNotificationMessageWindow* dlg = new TestNotificationMessageWindow(this); dlg->Show(); } #endif // wxUSE_NOTIFICATION_MESSAGE #if wxUSE_TIPWINDOW void Frame::OnShowTip(wxCommandEvent& WXUNUSED(event)) { if (m_tipWindow) { m_tipWindow->Close(); } else { m_tipWindow = new wxTipWindow ( this, "This is just some text to be shown in the tip " "window, broken into multiple lines, each less " "than 60 logical pixels wide.", FromDIP(60), &m_tipWindow ); } } void Frame::OnUpdateShowTipUI(wxUpdateUIEvent& event) { event.Check(m_tipWindow != NULL); } #endif // wxUSE_TIPWINDOW #if wxUSE_RICHTOOLTIP #include "wx/richtooltip.h" class RichTipDialog : public wxDialog { public: RichTipDialog(wxWindow* parent) : wxDialog(parent, wxID_ANY, "wxRichToolTip Test", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER) { // Create the controls. m_textTitle = new wxTextCtrl(this, wxID_ANY, "Tooltip title"); m_textBody = new wxTextCtrl(this, wxID_ANY, "Main tooltip text\n" "possibly on several\n" "lines.", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE); wxButton* btnShowText = new wxButton(this, wxID_ANY, "Show for &text"); wxButton* btnShowBtn = new wxButton(this, wxID_ANY, "Show for &button"); const wxString icons[] = { "&None", "&Information", "&Warning", "&Error", "&Custom" }; wxCOMPILE_TIME_ASSERT(WXSIZEOF(icons) == Icon_Max, IconMismatch); m_icons = new wxRadioBox(this, wxID_ANY, "&Icon choice:", wxDefaultPosition, wxDefaultSize, WXSIZEOF(icons), icons, 1, wxRA_SPECIFY_ROWS); m_icons->SetSelection(Icon_Info); const wxString tipKinds[] = { "&None", "Top left", "Top", "Top right", "Bottom left", "Bottom", "Bottom right", "&Auto" }; m_tipKinds = new wxRadioBox(this, wxID_ANY, "Tip &kind:", wxDefaultPosition, wxDefaultSize, WXSIZEOF(tipKinds), tipKinds, 4, wxRA_SPECIFY_COLS); m_tipKinds->SetSelection(wxTipKind_Auto); const wxString bgStyles[] = { "&Default", "&Solid", "&Gradient", }; wxCOMPILE_TIME_ASSERT(WXSIZEOF(bgStyles) == Bg_Max, BgMismatch); m_bgStyles = new wxRadioBox(this, wxID_ANY, "Background style:", wxDefaultPosition, wxDefaultSize, WXSIZEOF(bgStyles), bgStyles, 1, wxRA_SPECIFY_ROWS); const wxString timeouts[] = { "&None", "&Default (no delay)", "&3 seconds" }; wxCOMPILE_TIME_ASSERT(WXSIZEOF(timeouts) == Timeout_Max, TmMismatch); m_timeouts = new wxRadioBox(this, wxID_ANY, "Timeout:", wxDefaultPosition, wxDefaultSize, WXSIZEOF(timeouts), timeouts, 1, wxRA_SPECIFY_ROWS); m_timeouts->SetSelection(Timeout_Default); m_timeDelay = new wxCheckBox(this, wxID_ANY, "Delay show"); // Lay them out. m_textBody->SetMinSize(wxSize(300, 200)); wxBoxSizer* const sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(m_textTitle, wxSizerFlags().Expand().Border()); sizer->Add(m_textBody, wxSizerFlags(1).Expand().Border()); sizer->Add(m_icons, wxSizerFlags().Expand().Border()); sizer->Add(m_tipKinds, wxSizerFlags().Centre().Border()); sizer->Add(m_bgStyles, wxSizerFlags().Centre().Border()); sizer->Add(m_timeouts, wxSizerFlags().Centre().Border()); sizer->Add(m_timeDelay, wxSizerFlags().Centre().Border()); wxBoxSizer* const sizerBtns = new wxBoxSizer(wxHORIZONTAL); sizerBtns->Add(btnShowText, wxSizerFlags().Border(wxRIGHT)); sizerBtns->Add(btnShowBtn, wxSizerFlags().Border(wxLEFT)); sizer->Add(sizerBtns, wxSizerFlags().Centre().Border()); sizer->Add(CreateStdDialogButtonSizer(wxOK), wxSizerFlags().Expand().Border()); SetSizerAndFit(sizer); // And connect the event handlers. btnShowText->Bind(wxEVT_BUTTON, &RichTipDialog::OnShowTipForText, this); btnShowBtn->Bind(wxEVT_BUTTON, &RichTipDialog::OnShowTipForBtn, this); } private: enum { Icon_None, Icon_Info, Icon_Warning, Icon_Error, Icon_Custom, Icon_Max }; enum { Bg_Default, Bg_Solid, Bg_Gradient, Bg_Max }; enum { Timeout_None, Timeout_Default, Timeout_3sec, Timeout_Max }; void OnShowTipForText(wxCommandEvent& WXUNUSED(event)) { DoShowTip(m_textTitle); } void OnShowTipForBtn(wxCommandEvent& WXUNUSED(event)) { DoShowTip(FindWindow(wxID_OK)); } void DoShowTip(wxWindow* win) { wxRichToolTip tip(m_textTitle->GetValue(), m_textBody->GetValue()); const int iconSel = m_icons->GetSelection(); if (iconSel == Icon_Custom) { tip.SetIcon(tip_xpm); } else // Use a standard icon. { static const int stdIcons[] = { wxICON_NONE, wxICON_INFORMATION, wxICON_WARNING, wxICON_ERROR, }; tip.SetIcon(stdIcons[iconSel]); } switch (m_bgStyles->GetSelection()) { case Bg_Default: break; case Bg_Solid: tip.SetBackgroundColour(*wxLIGHT_GREY); break; case Bg_Gradient: tip.SetBackgroundColour(*wxWHITE, wxColour(0xe4, 0xe5, 0xf0)); break; } int delay = m_timeDelay->IsChecked() ? 500 : 0; switch (m_timeouts->GetSelection()) { case Timeout_None: // Don't call SetTimeout unnecessarily // or msw will show generic impl if (delay) tip.SetTimeout(0, delay); break; case Timeout_Default: break; case Timeout_3sec: tip.SetTimeout(3000, delay); break; } tip.SetTipKind(static_cast(m_tipKinds->GetSelection())); tip.ShowFor(win); } wxTextCtrl* m_textTitle; wxTextCtrl* m_textBody; wxRadioBox* m_icons; wxRadioBox* m_tipKinds; wxRadioBox* m_bgStyles; wxRadioBox* m_timeouts; wxCheckBox* m_timeDelay; }; void Frame::OnRichTipDialog(wxCommandEvent& WXUNUSED(event)) { RichTipDialog dialog(this); dialog.ShowModal(); } #endif // wxUSE_RICHTOOLTIP void Frame::OnStandardButtonsSizerDialog(wxCommandEvent& WXUNUSED(event)) { StdButtonSizerDialog dialog(this); dialog.ShowModal(); } // TestDefaultAction #define ID_CATCH_LISTBOX_DCLICK 100 #define ID_LISTBOX 101 #define ID_DISABLE_OK 102 #define ID_DISABLE_CANCEL 103 wxBEGIN_EVENT_TABLE(TestDefaultActionDialog, wxDialog) EVT_CHECKBOX(ID_CATCH_LISTBOX_DCLICK, TestDefaultActionDialog::OnCatchListBoxDClick) EVT_CHECKBOX(ID_DISABLE_OK, TestDefaultActionDialog::OnDisableOK) EVT_CHECKBOX(ID_DISABLE_CANCEL, TestDefaultActionDialog::OnDisableCancel) EVT_LISTBOX_DCLICK(ID_LISTBOX, TestDefaultActionDialog::OnListBoxDClick) EVT_TEXT_ENTER(wxID_ANY, TestDefaultActionDialog::OnTextEnter) wxEND_EVENT_TABLE() // TODO-C++11: We can't declare this class inside TestDefaultActionDialog // itself when using C++98, so we have to do it here instead. namespace { // We have to define a new class in order to actually handle pressing // Enter, if we didn't do it, pressing it would still close the dialog. class EnterHandlingTextCtrl : public wxTextCtrl { public: EnterHandlingTextCtrl(wxWindow* parent, int id, const wxString& value) : wxTextCtrl(parent, id, value, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER) { Bind(wxEVT_TEXT_ENTER, &EnterHandlingTextCtrl::OnEnter, this); SetInitialSize(GetSizeFromTextSize(GetTextExtent(value).x)); } private: void OnEnter(wxCommandEvent& WXUNUSED(event)) { wxLogMessage("Enter pressed"); } }; } // anonymous namespace TestDefaultActionDialog::TestDefaultActionDialog(wxWindow* parent) : wxDialog(parent, -1, "Test default action") { m_catchListBoxDClick = false; wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); const int border = wxSizerFlags::GetDefaultBorder(); wxFlexGridSizer* grid_sizer = new wxFlexGridSizer(2, wxSize(border, border)); #if wxUSE_LISTBOX wxListBox* listbox = new wxListBox(this, ID_LISTBOX); listbox->Append("String 1"); listbox->Append("String 2"); listbox->Append("String 3"); listbox->Append("String 4"); grid_sizer->Add(listbox); #endif // wxUSE_LISTBOX grid_sizer->Add(new wxCheckBox(this, ID_CATCH_LISTBOX_DCLICK, "Catch DoubleClick from wxListBox"), wxSizerFlags().CentreVertical()); grid_sizer->Add(new wxTextCtrl(this, wxID_ANY, "Enter here closes the dialog"), wxSizerFlags().Expand().CentreVertical()); grid_sizer->Add(new wxStaticText(this, wxID_ANY, "wxTextCtrl without wxTE_PROCESS_ENTER"), wxSizerFlags().CentreVertical()); grid_sizer->Add(new EnterHandlingTextCtrl(this, wxID_ANY, "Enter here is handled by the application"), wxSizerFlags().CentreVertical()); grid_sizer->Add(new wxStaticText(this, wxID_ANY, "wxTextCtrl with wxTE_PROCESS_ENTER"), wxSizerFlags().CentreVertical()); grid_sizer->Add(new wxTextCtrl(this, wxID_ANY, "Enter here adds another line,\n" "while Ctrl-Enter closes the dialog", wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE), wxSizerFlags().Expand()); grid_sizer->Add(new wxStaticText(this, wxID_ANY, "wxTextCtrl without wxTE_PROCESS_ENTER"), wxSizerFlags().CentreVertical()); grid_sizer->Add(new wxCheckBox(this, ID_DISABLE_OK, "Disable \"OK\""), wxSizerFlags().CentreVertical()); grid_sizer->Add(new wxCheckBox(this, ID_DISABLE_CANCEL, "Disable \"Cancel\""), wxSizerFlags().CentreVertical()); main_sizer->Add(grid_sizer, wxSizerFlags().DoubleBorder()); wxSizer* button_sizer = CreateSeparatedButtonSizer(wxOK | wxCANCEL); if (button_sizer) main_sizer->Add(button_sizer, wxSizerFlags().Expand().Border()); SetSizerAndFit(main_sizer); } void TestDefaultActionDialog::OnDisableOK(wxCommandEvent& event) { FindWindow(wxID_OK)->Enable(!event.IsChecked()); } void TestDefaultActionDialog::OnDisableCancel(wxCommandEvent& event) { FindWindow(wxID_CANCEL)->Enable(!event.IsChecked()); } void TestDefaultActionDialog::OnListBoxDClick(wxCommandEvent& event) { event.Skip(!m_catchListBoxDClick); } void TestDefaultActionDialog::OnCatchListBoxDClick(wxCommandEvent& WXUNUSED(event)) { m_catchListBoxDClick = !m_catchListBoxDClick; } void TestDefaultActionDialog::OnTextEnter(wxCommandEvent& event) { const wxString& text = event.GetString(); if (text.empty()) { event.Skip(); return; } wxLogMessage("Text \"%s\" entered.", text); } void Frame::OnTestDefaultActionDialog(wxCommandEvent& WXUNUSED(event)) { TestDefaultActionDialog dialog(this); dialog.ShowModal(); } void Frame::OnModalHook(wxCommandEvent& event) { class TestModalHook : public wxModalDialogHook { protected: virtual int Enter(wxDialog* dialog) wxOVERRIDE { wxLogStatus("Showing %s modal dialog", dialog->GetClassInfo()->GetClassName()); return wxID_NONE; } virtual void Exit(wxDialog* dialog) wxOVERRIDE { wxLogStatus("Leaving %s modal dialog", dialog->GetClassInfo()->GetClassName()); } }; static TestModalHook s_hook; if (event.IsChecked()) s_hook.Register(); else s_hook.Unregister(); } void Frame::OnSimulatedUnsaved(wxCommandEvent& event) { m_confirmExit = event.IsChecked(); } void Frame::OnExit(wxCommandEvent& WXUNUSED(event)) { Close(true); } void Frame::OnClose(wxCloseEvent& event) { if (m_confirmExit && event.CanVeto()) { wxMessageDialog dialog(this, "You have an unsaved file; save before closing?", "OnClose", wxCENTER | wxYES_NO | wxCANCEL | wxICON_QUESTION); dialog.SetYesNoLabels( "&Save", "&Discard changes" ); switch (dialog.ShowModal()) { case wxID_CANCEL: event.Veto(); wxLogStatus("You cancelled closing the application."); // Return without calling event.Skip() to prevent closing the frame. // The application should resume operation as if closing it had not // been attempted. return; case wxID_YES: wxMessageBox("You chose to save your file.", "OnClose", wxOK); // In a real application, do something to save the // file(s), possibly asking for a file name and location // using wxFileDialog. break; default: wxLogError("Unexpected wxMessageDialog return code!"); wxFALLTHROUGH; case wxID_NO: // Don't save anything, and simply continue with closing the frame. break; } } // Continue with closing the frame. event.Skip(); } #if wxUSE_PROGRESSDLG static const int max_ = 100; void Frame::ShowProgress(wxCommandEvent& WXUNUSED(event)) { wxProgressDialog dialog("Progress dialog example", // "Reserve" enough space for the multiline // messages below, we'll change it anyhow // immediately in the loop below wxString(' ', 100) + "\n\n\n\n", max_, // range this, // parent wxPD_CAN_ABORT | wxPD_CAN_SKIP | wxPD_APP_MODAL | //wxPD_AUTO_HIDE | // -- try this as well wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME | wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small ); DoShowProgress(dialog); } #ifdef wxHAS_NATIVE_PROGRESSDIALOG void Frame::ShowProgressGeneric(wxCommandEvent& WXUNUSED(event)) { wxGenericProgressDialog dialog("Generic progress dialog example", wxString(' ', 100) + "\n\n\n\n", max_, this, wxPD_CAN_ABORT | wxPD_CAN_SKIP | wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME | wxPD_SMOOTH); DoShowProgress(dialog); } #endif // wxHAS_NATIVE_PROGRESSDIALOG void Frame::DoShowProgress(wxGenericProgressDialog& dialog) { bool cont = true; for (int i = 0; i <= max_; i++) { wxString msg; // test both modes of wxProgressDialog behaviour: start in // indeterminate mode but switch to the determinate one later const bool determinate = i > max_ / 2; if (i == max_) { msg = "That's all, folks!\n" "\n" "Nothing to see here any more."; } else if (!determinate) { msg = "Testing indeterminate mode\n" "\n" "This mode allows you to show to the user\n" "that something is going on even if you don't know\n" "when exactly will you finish."; } else if (determinate) { msg = "Now in standard determinate mode\n" "\n" "This is the standard usage mode in which you\n" "update the dialog after performing each new step of work.\n" "It requires knowing the total number of steps in advance."; } // will be set to true if "Skip" button was pressed bool skip = false; if (determinate) { cont = dialog.Update(i, msg, &skip); } else { cont = dialog.Pulse(msg, &skip); } // each skip will move progress about quarter forward if (skip) { i += max_ / 4; if (i >= max_) i = max_ - 1; } if (!cont) { if (wxMessageBox("Do you really want to cancel?", "Progress dialog question", // caption wxYES_NO | wxICON_QUESTION) == wxYES) break; cont = true; dialog.Resume(); } wxMilliSleep(100); } if (!cont) { wxLogStatus("Progress dialog aborted!"); } else { wxLogStatus("Countdown from %d finished", max_); } } #endif // wxUSE_PROGRESSDLG void Frame::ShowAppProgress(wxCommandEvent& WXUNUSED(event)) { wxAppProgressIndicator progress(this); if (!progress.IsAvailable()) { wxLogStatus("Progress indicator not available under this platform."); return; } wxLogStatus("Using application progress indicator..."); const int range = 10; progress.SetRange(range); for (int i = 0; i < range; i++) { progress.SetValue(i); wxMilliSleep(200); } wxLogStatus("Progress finished"); } #if USE_MODAL_PRESENTATION wxBEGIN_EVENT_TABLE(MyModalDialog, wxDialog) EVT_BUTTON(wxID_ANY, MyModalDialog::OnButton) wxEND_EVENT_TABLE() wxBEGIN_EVENT_TABLE(MyModelessDialog, wxDialog) EVT_BUTTON(DIALOGS_MODELESS_BTN, MyModelessDialog::OnButton) EVT_CLOSE(MyModelessDialog::OnClose) wxEND_EVENT_TABLE() #endif // USE_MODAL_PRESENTATION wxBEGIN_EVENT_TABLE(StdButtonSizerDialog, wxDialog) EVT_CHECKBOX(wxID_ANY, StdButtonSizerDialog::OnEvent) EVT_RADIOBUTTON(wxID_ANY, StdButtonSizerDialog::OnEvent) wxEND_EVENT_TABLE() #if wxUSE_ABOUTDLG static void InitAboutInfoMinimal(wxAboutDialogInfo& info) { info.SetName("Dialogs Sample"); info.SetVersion(wxVERSION_NUM_DOT_STRING, wxString::Format ( "%s version %s", wxMINOR_VERSION % 2 ? "Development" : "Stable", wxVERSION_NUM_DOT_STRING )); info.SetDescription("This sample shows different wxWidgets dialogs"); info.SetCopyright("(C) 1998-2006 wxWidgets dev team"); info.AddDeveloper("Vadim Zeitlin"); } static void InitAboutInfoWebsite(wxAboutDialogInfo& info) { InitAboutInfoMinimal(info); info.SetWebSite("http://www.wxwidgets.org/", "wxWidgets web site"); } static void InitAboutInfoAll(wxAboutDialogInfo& info) { InitAboutInfoWebsite(info); // we can add a second developer info.AddDeveloper("A.N. Other"); // or we can add several persons at once like this wxArrayString docwriters; docwriters.Add("First D. Writer"); docwriters.Add("Second One"); info.SetDocWriters(docwriters); info.SetLicence(wxString::FromAscii( " wxWindows Library Licence, Version 3.1\n" " ======================================\n" "\n" " Copyright (c) 1998-2018 Julian Smart, Robert Roebling et al\n" "\n" " Everyone is permitted to copy and distribute verbatim copies\n" " of this licence document, but changing it is not allowed.\n" "\n" " WXWINDOWS LIBRARY LICENCE\n" " TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n" "\n" " ...and so on and so forth...\n" )); info.AddTranslator("Wun Ngo Wen (Martian)"); } void Frame::ShowSimpleAboutDialog(wxCommandEvent& WXUNUSED(event)) { wxAboutDialogInfo info; InitAboutInfoMinimal(info); wxAboutBox(info, this); } void Frame::ShowFancyAboutDialog(wxCommandEvent& WXUNUSED(event)) { wxAboutDialogInfo info; InitAboutInfoWebsite(info); wxAboutBox(info, this); } void Frame::ShowFullAboutDialog(wxCommandEvent& WXUNUSED(event)) { wxAboutDialogInfo info; InitAboutInfoAll(info); wxAboutBox(info, this); } // a trivial example of a custom dialog class class MyAboutDialog : public wxGenericAboutDialog { public: MyAboutDialog(const wxAboutDialogInfo& info, wxWindow* parent) { Create(info, parent); } // add some custom controls virtual void DoAddCustomControls() wxOVERRIDE { AddControl(new wxStaticLine(this), wxSizerFlags().Expand()); AddText("Some custom text"); AddControl(new wxStaticLine(this), wxSizerFlags().Expand()); } }; void Frame::ShowCustomAboutDialog(wxCommandEvent& WXUNUSED(event)) { wxAboutDialogInfo info; InitAboutInfoAll(info); MyAboutDialog dlg(info, this); dlg.ShowModal(); } #endif // wxUSE_ABOUTDLG #if wxUSE_BUSYINFO void Frame::ShowBusyInfo(wxCommandEvent& WXUNUSED(event)) { wxWindowDisabler disableAll; wxBusyInfo info("Working, please wait...", this); for (int i = 0; i < 18; i++) { wxMilliSleep(100); wxTheApp->Yield(); } wxSleep(2); } void Frame::ShowRichBusyInfo(wxCommandEvent& WXUNUSED(event)) { wxWindowDisabler disableAll; // This is just an example and not an encouragement for printing // synchronously from the main thread. wxBusyInfo info ( wxBusyInfoFlags() .Parent(this) .Icon(wxArtProvider::GetIcon(wxART_PRINT, wxART_OTHER, wxSize(128, 128))) .Title("Printing your document") .Text("Please wait...") .Foreground(*wxWHITE) .Background(*wxBLACK) .Transparency(4 * wxALPHA_OPAQUE / 5) ); wxSleep(5); } #endif // wxUSE_BUSYINFO #if wxUSE_FINDREPLDLG void Frame::ShowReplaceDialog(wxCommandEvent& WXUNUSED(event)) { if (m_dlgReplace) { m_dlgReplace->Destroy(); m_dlgReplace = NULL; } else { m_dlgReplace = new wxFindReplaceDialog ( this, &m_findData, "Find and replace dialog", wxFR_REPLACEDIALOG ); m_dlgReplace->Show(true); } } void Frame::ShowFindDialog(wxCommandEvent& WXUNUSED(event)) { if (m_dlgFind) { m_dlgFind->Destroy(); m_dlgFind = NULL; } else { m_dlgFind = new wxFindReplaceDialog ( this, &m_findData, "Find dialog", // just for testing wxFR_NOWHOLEWORD ); m_dlgFind->Show(true); } } static wxString DecodeFindDialogEventFlags(int flags) { wxString str; str << (flags & wxFR_DOWN ? "down" : "up") << ", " << (flags & wxFR_WHOLEWORD ? "whole words only, " : "") << (flags & wxFR_MATCHCASE ? "" : "not ") << "case sensitive"; return str; } void Frame::OnFindDialog(wxFindDialogEvent& event) { wxEventType type = event.GetEventType(); if (type == wxEVT_FIND || type == wxEVT_FIND_NEXT) { wxLogMessage("Find %s'%s' (flags: %s)", type == wxEVT_FIND_NEXT ? "next " : "", event.GetFindString(), DecodeFindDialogEventFlags(event.GetFlags())); } else if (type == wxEVT_FIND_REPLACE || type == wxEVT_FIND_REPLACE_ALL) { wxLogMessage("Replace %s'%s' with '%s' (flags: %s)", type == wxEVT_FIND_REPLACE_ALL ? "all " : "", event.GetFindString(), event.GetReplaceString(), DecodeFindDialogEventFlags(event.GetFlags())); } else if (type == wxEVT_FIND_CLOSE) { wxFindReplaceDialog* dlg = event.GetDialog(); int idMenu; wxString txt; if (dlg == m_dlgFind) { txt = "Find"; idMenu = DIALOGS_FIND; m_dlgFind = NULL; } else if (dlg == m_dlgReplace) { txt = "Replace"; idMenu = DIALOGS_REPLACE; m_dlgReplace = NULL; } else { txt = "Unknown"; idMenu = wxID_ANY; wxFAIL_MSG("unexpected event"); } wxLogMessage("%s dialog is being closed.", txt); if (idMenu != wxID_ANY) { GetMenuBar()->Check(idMenu, false); } dlg->Destroy(); } else { wxLogError("Unknown find dialog event!"); } } #endif // wxUSE_FINDREPLDLG Frame::~Frame() { wxConfigBase* pConfig = wxConfigBase::Get(); if (pConfig == NULL) return; StorePositionToConfig(); pConfig->SetPath(wxT("/TipOfTheDay")); pConfig->Write("show", (int)m_showTipsAtStartup); pConfig->Write("index", (int)m_TipOfTheDayIndex); pConfig->SetPath(wxT("/FileDialog")); pConfig->Write("index", (int)m_FileDialogFilterIndex); pConfig->Write("LastUsed", wxString::FromUTF8(m_strLastUsedFile)); pConfig->SetPath(wxT("/")); }