// Copyright: (c) Julian Smart
// (c) 2004 ABX
// (c) Vadim Zeitlin
-// Licence: wxWindows license
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/sysopt.h"
#include "wx/notifmsg.h"
+#if wxUSE_RICHMSGDLG
+ #include "wx/richmsgdlg.h"
+#endif // wxUSE_RICHMSGDLG
+
#if wxUSE_COLOURDLG
#include "wx/colordlg.h"
#endif // wxUSE_COLOURDLG
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
#if wxUSE_MSGDLG
EVT_MENU(DIALOGS_MESSAGE_BOX, MyFrame::MessageBox)
+ EVT_MENU(DIALOGS_MESSAGE_BOX_WINDOW_MODAL, MyFrame::MessageBoxWindowModal)
EVT_MENU(DIALOGS_MESSAGE_DIALOG, MyFrame::MessageBoxDialog)
EVT_MENU(DIALOGS_MESSAGE_BOX_WXINFO, MyFrame::MessageBoxInfo)
#endif // wxUSE_MSGDLG
+#if wxUSE_RICHMSGDLG
+ EVT_MENU(DIALOGS_RICH_MESSAGE_DIALOG, MyFrame::RichMessageDialog)
+#endif // wxUSE_RICHMSGDLG
#if wxUSE_COLOURDLG
EVT_MENU(DIALOGS_CHOOSE_COLOUR, MyFrame::ChooseColour)
EVT_MENU(DIALOGS_GET_COLOUR, MyFrame::GetColour)
#endif // wxUSE_INFOBAR
#if wxUSE_TEXTDLG
+ EVT_MENU(DIALOGS_LINE_ENTRY, MyFrame::LineEntry)
EVT_MENU(DIALOGS_TEXT_ENTRY, MyFrame::TextEntry)
EVT_MENU(DIALOGS_PASSWORD_ENTRY, MyFrame::PasswordEntry)
#endif // wxUSE_TEXTDLG
EVT_RADIOBUTTON(wxID_ANY, StdButtonSizerDialog::OnEvent)
END_EVENT_TABLE()
+#if wxUSE_CMDLINE_PARSER
+
+#include "wx/cmdline.h"
+
+static const char *PROGRESS_SWITCH = "progress";
+
+void MyApp::OnInitCmdLine(wxCmdLineParser& parser)
+{
+ wxApp::OnInitCmdLine(parser);
+
+ parser.AddOption("", PROGRESS_SWITCH,
+ "Style for the startup progress dialog (wxPD_XXX)",
+ wxCMD_LINE_VAL_NUMBER);
+}
+
+bool MyApp::OnCmdLineParsed(wxCmdLineParser& parser)
+{
+ if ( !wxApp::OnCmdLineParsed(parser) )
+ return false;
+
+ parser.Found(PROGRESS_SWITCH, &m_startupProgressStyle);
+
+ return true;
+}
+
+#endif // wxUSE_CMDLINE_PARSER
+
// `Main program' equivalent, creating windows and returning main app frame
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;
+#if wxUSE_PROGRESSDLG
+ if ( m_startupProgressStyle != -1 )
+ {
+ // Show a test progress dialog before the main event loop is started:
+ // it should still work.
+ const int PROGRESS_COUNT = 100;
+ wxProgressDialog dlg
+ (
+ "Progress in progress",
+ "Please wait, starting...",
+ PROGRESS_COUNT,
+ NULL,
+ m_startupProgressStyle
+ );
+ for ( int i = 0; i <= PROGRESS_COUNT; i++ )
+ {
+ if ( !dlg.Update(i) )
+ break;
+
+ wxMilliSleep(50);
+ }
+ }
+#endif // wxUSE_PROGRESSDLG
+
#if wxUSE_IMAGE
wxInitAllImageHandlers();
#endif
wxMenu *menuDlg = new wxMenu;
menuDlg->Append(DIALOGS_MESSAGE_BOX, wxT("&Message box\tCtrl-M"));
+ menuDlg->Append(DIALOGS_MESSAGE_BOX_WINDOW_MODAL, wxT("Window-Modal Message box "));
menuDlg->Append(DIALOGS_MESSAGE_DIALOG, wxT("Message dialog\tShift-Ctrl-M"));
+#if wxUSE_RICHMSGDLG
+ menuDlg->Append(DIALOGS_RICH_MESSAGE_DIALOG, wxT("Rich message dialog"));
+#endif // wxUSE_RICHMSGDLG
#if wxUSE_COLOURDLG || wxUSE_FONTDLG || wxUSE_CHOICEDLG
wxMenu *entry_menu = new wxMenu;
#if wxUSE_TEXTDLG
- entry_menu->Append(DIALOGS_TEXT_ENTRY, wxT("Text &entry\tCtrl-E"));
+ entry_menu->Append(DIALOGS_LINE_ENTRY, wxT("Single line &entry\tCtrl-E"));
+ entry_menu->Append(DIALOGS_TEXT_ENTRY, wxT("Multi line text &entry\tShift-Ctrl-E"));
entry_menu->Append(DIALOGS_PASSWORD_ENTRY, wxT("&Password entry\tCtrl-P"));
#endif // wxUSE_TEXTDLG
menuHelp->Append(DIALOGS_ABOUTDLG_CUSTOM, wxT("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 = new wxMenuBar;
menubar->Append(menuDlg, wxT("&Dialogs"));
+
+ menubar->Append(editMenu, wxT("&Edit"));
+
#if wxUSE_ABOUTDLG
menubar->Append(menuHelp, wxT("&Help"));
#endif // wxUSE_ABOUTDLG
MyFrame::MyFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title)
{
- SetIcon(sample_xpm);
+ SetIcon(wxICON(sample));
#if USE_MODAL_PRESENTATION
m_dialog = (MyModelessDialog *)NULL;
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);
- m_infoBarAdvanced = NULL;
+
+ // 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->Connect(wxID_REDO, wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(MyFrame::OnInfoBarRedo),
+ NULL,
+ this);
+
+ // 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->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());
#endif // wxUSE_INFOBAR
}
void MyFrame::InfoBarAdvanced(wxCommandEvent& WXUNUSED(event))
{
+ m_infoBarAdvanced->ShowMessage("Sorry, it didn't work out.", wxICON_WARNING);
+}
+
+void MyFrame::OnInfoBarRedo(wxCommandEvent& WXUNUSED(event))
+{
+ m_infoBarAdvanced->ShowMessage("Still no, sorry again.", wxICON_ERROR);
}
#endif // wxUSE_INFOBAR
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(wxT("You pressed \"Yes\""));
+ break;
+
+ case wxID_NO:
+ wxLogStatus(wxT("You pressed \"No\""));
+ break;
+
+ case wxID_CANCEL:
+ wxLogStatus(wxT("You pressed \"Cancel\""));
+ break;
+
+ default:
+ wxLogError(wxT("Unexpected wxMessageDialog return code!"));
+ }
+}
+
+void MyFrame::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",
extmsg = "Custom button labels are not supported on this platform,\n"
"so the default \"Yes\"/\"No\"/\"Cancel\" buttons are used.";
}
- dialog.SetExtendedMessage(extmsg);
+ dialog->SetExtendedMessage(extmsg);
+ dialog->Connect( wxEVT_WINDOW_MODAL_DIALOG_CLOSED, wxWindowModalDialogEventHandler(MyFrame::MessageBoxWindowModalClosed), NULL, this );
+ dialog->ShowWindowModal();
+}
- switch ( dialog.ShowModal() )
+void MyFrame::MessageBoxWindowModalClosed(wxWindowModalDialogEvent& event)
+{
+ wxDialog* dialog = event.GetDialog();
+ switch ( dialog->GetReturnCode() )
{
case wxID_YES:
wxLogStatus(wxT("You pressed \"Yes\""));
default:
wxLogError(wxT("Unexpected wxMessageDialog return code!"));
}
+ delete dialog;
}
void MyFrame::MessageBoxDialog(wxCommandEvent& WXUNUSED(event))
{
TestMessageBoxDialog dlg(this);
+ dlg.Create();
dlg.ShowModal();
}
}
#endif // wxUSE_MSGDLG
+#if wxUSE_RICHMSGDLG
+void MyFrame::RichMessageDialog(wxCommandEvent& WXUNUSED(event))
+{
+ TestRichMessageDialog dlg(this);
+ dlg.Create();
+ dlg.ShowModal();
+}
+#endif // wxUSE_RICHMSGDLG
+
#if wxUSE_NUMBERDLG
void MyFrame::NumericEntry(wxCommandEvent& WXUNUSED(event))
{
}
}
-void MyFrame::TextEntry(wxCommandEvent& WXUNUSED(event))
+void MyFrame::LineEntry(wxCommandEvent& WXUNUSED(event))
{
wxTextEntryDialog dialog(this,
wxT("This is a small sample\n")
wxMessageBox(dialog.GetValue(), wxT("Got string"), wxOK | wxICON_INFORMATION, this);
}
}
+
+void MyFrame::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(), wxT("Got text"), wxOK | wxICON_INFORMATION, this);
+ }
+}
#endif // wxUSE_TEXTDLG
#if wxUSE_CHOICEDLG
{
static const int max = 100;
- wxProgressDialog dialog(wxT("Progress dialog example"),
- wxT("An informative message"),
+ 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_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
+ wxPD_REMAINING_TIME |
+ wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small
);
bool cont = true;
for ( int i = 0; i <= max; i++ )
{
- wxMilliSleep(200);
-
wxString msg;
// test both modes of wxProgressDialog behaviour: start in
if ( i == max )
{
- msg = wxT("That's all, folks!");
+ msg = "That's all, folks!\n"
+ "\n"
+ "Nothing to see here any more.";
}
else if ( !determinate )
{
- msg = wxT("Testing indeterminate mode");
+ 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 = wxT("Now in standard determinate mode");
+ 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
// each skip will move progress about quarter forward
if ( skip )
+ {
i += max/4;
+ if ( i >= 100 )
+ i = 99;
+ }
+
if ( !cont )
{
if ( wxMessageBox(wxT("Do you really want to cancel?"),
cont = true;
dialog.Resume();
}
+
+ wxMilliSleep(200);
}
if ( !cont )
{
if ( m_dlgReplace )
{
- delete m_dlgReplace;
- m_dlgReplace = NULL;
+ wxDELETE(m_dlgReplace);
}
else
{
{
if ( m_dlgFind )
{
- delete m_dlgFind;
- m_dlgFind = NULL;
+ wxDELETE(m_dlgFind);
}
else
{
{
if ( event.GetEventObject() == m_btnDelete )
{
- delete m_btnModal;
- m_btnModal = NULL;
-
+ wxDELETE(m_btnModal);
m_btnDelete->Disable();
}
else if ( event.GetEventObject() == m_btnModal )
return panel;
}
+#endif // USE_SETTINGS_DIALOG
+
+#if wxUSE_MSGDLG
// ----------------------------------------------------------------------------
// TestMessageBoxDialog
// ----------------------------------------------------------------------------
: wxDialog(parent, wxID_ANY, "Message Box Test Dialog",
wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
+{
+}
+
+bool TestMessageBoxDialog::Create()
{
wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL);
sizerTop->Add(sizerMsgs, wxSizerFlags(1).Expand().Border());
+ // if a derived class provides more message configurations, add these.
+ AddAdditionalTextOptions(sizerTop);
// this one is for configuring the buttons
+ wxSizer * const
+ sizerBtnsBox = new wxStaticBoxSizer(wxVERTICAL, this, "&Buttons");
+
wxFlexGridSizer * const sizerBtns = new wxFlexGridSizer(2, 5, 5);
sizerBtns->AddGrowableCol(1);
this);
}
- wxSizer * const
- sizerBtnsBox = new wxStaticBoxSizer(wxVERTICAL, this, "&Buttons");
sizerBtnsBox->Add(sizerBtns, wxSizerFlags(1).Expand());
sizerTop->Add(sizerBtnsBox, wxSizerFlags().Expand().Border());
// icon choice
- const wxString icons[] = {
- "&None", "&Information", "&Question", "&Warning", "&Error"
+ const wxString icons[] =
+ {
+ "&Not specified",
+ "E&xplicitly none",
+ "&Information icon",
+ "&Question icon",
+ "&Warning icon",
+ "&Error icon"
};
- m_icons = new wxRadioBox(this, wxID_ANY, "&Icons",
+ wxCOMPILE_TIME_ASSERT( WXSIZEOF(icons) == MsgDlgIcon_Max, IconMismatch );
+
+ m_icons = new wxRadioBox(this, wxID_ANY, "&Icon style",
wxDefaultPosition, wxDefaultSize,
- WXSIZEOF(icons), icons);
+ WXSIZEOF(icons), icons,
+ 2, wxRA_SPECIFY_ROWS);
// Make the 'Information' icon the default one:
- m_icons->SetSelection(1);
+ m_icons->SetSelection(MsgDlgIcon_Info);
sizerTop->Add(m_icons, wxSizerFlags().Expand().Border());
m_chkCentre = new wxCheckBox(this, wxID_ANY, "Centre on &parent");
sizerFlags->Add(m_chkCentre, wxSizerFlags(1).Border());
+ // add any additional flag from subclasses
+ AddAdditionalFlags(sizerFlags);
+
sizerTop->Add(sizerFlags, wxSizerFlags().Expand().Border());
// finally buttons to show the resulting message box and close this dialog
SetSizerAndFit(sizerTop);
m_buttons[Btn_Ok]->SetValue(true);
+
+ return true;
}
void TestMessageBoxDialog::OnUpdateLabelUI(wxUpdateUIEvent& event)
event.Enable( m_buttons[Btn_No]->IsChecked() );
}
-void TestMessageBoxDialog::OnApply(wxCommandEvent& WXUNUSED(event))
+long TestMessageBoxDialog::GetStyle()
{
long style = 0;
switch ( m_icons->GetSelection() )
{
- case 0: style |= wxICON_NONE; break;
- case 1: style |= wxICON_INFORMATION; break;
- case 2: style |= wxICON_QUESTION; break;
- case 3: style |= wxICON_WARNING; break;
- case 4: style |= wxICON_ERROR; break;
+ case MsgDlgIcon_Max:
+ wxFAIL_MSG( "unexpected selection" );
+
+ case MsgDlgIcon_No:
+ break;
+
+ case MsgDlgIcon_None:
+ style |= wxICON_NONE;
+ break;
+
+ case MsgDlgIcon_Info:
+ style |= wxICON_INFORMATION;
+ break;
+
+ case MsgDlgIcon_Question:
+ style |= wxICON_QUESTION;
+ break;
+
+ case MsgDlgIcon_Warning:
+ style |= wxICON_WARNING;
+ break;
+
+ case MsgDlgIcon_Error:
+ style |= wxICON_ERROR;
+ break;
}
if ( m_chkCentre->IsChecked() )
if ( m_chkNoDefault->IsEnabled() && m_chkNoDefault->IsChecked() )
style |= wxNO_DEFAULT;
+ return style;
+}
+
+void TestMessageBoxDialog::PrepareMessageDialog(wxMessageDialogBase &dlg)
+{
+ long style = dlg.GetMessageDialogStyle();
- wxMessageDialog dlg(this, m_textMsg->GetValue(), "Test Message Box",
- style);
if ( !m_textExtMsg->IsEmpty() )
dlg.SetExtendedMessage(m_textExtMsg->GetValue());
dlg.SetOKLabel(m_labels[Btn_Ok]->GetValue());
}
}
+}
+
+void TestMessageBoxDialog::OnApply(wxCommandEvent& WXUNUSED(event))
+{
+ wxMessageDialog dlg(this, GetMessage(), "Test Message Box", GetStyle());
+ PrepareMessageDialog(dlg);
dlg.ShowModal();
}
{
EndModal(wxID_CANCEL);
}
+#endif // wxUSE_MSGDLG
-#endif // USE_SETTINGS_DIALOG
+#if wxUSE_RICHMSGDLG
+// ----------------------------------------------------------------------------
+// TestRichMessageDialog
+// ----------------------------------------------------------------------------
+
+BEGIN_EVENT_TABLE(TestRichMessageDialog, TestMessageBoxDialog)
+ EVT_BUTTON(wxID_APPLY, TestRichMessageDialog::OnApply)
+END_EVENT_TABLE()
+
+TestRichMessageDialog::TestRichMessageDialog(wxWindow *parent)
+ : TestMessageBoxDialog(parent)
+{
+ SetTitle("Rich Message Dialog Test Dialog");
+}
+
+void TestRichMessageDialog::AddAdditionalTextOptions(wxSizer *sizer)
+{
+ wxSizer * const sizerMsgs = new wxStaticBoxSizer(wxVERTICAL, this,
+ "&Additional Elements");
+
+ // add a option to show a check box.
+ wxFlexGridSizer * const sizerCheckBox = new wxFlexGridSizer(2, 5, 5);
+ sizerCheckBox->AddGrowableCol(1);
+ sizerCheckBox->Add(new wxStaticText(this, wxID_ANY, "&Check box:"));
+ m_textCheckBox = new wxTextCtrl(this, wxID_ANY);
+ sizerCheckBox->Add(m_textCheckBox, wxSizerFlags(1).Expand().Border(wxBOTTOM));
+ sizerMsgs->Add(sizerCheckBox, wxSizerFlags(1).Expand());
+
+ // add option to show a detailed text.
+ sizerMsgs->Add(new wxStaticText(this, wxID_ANY, "&Detailed message:"));
+ m_textDetailed = new wxTextCtrl(this, wxID_ANY, "",
+ wxDefaultPosition, wxDefaultSize,
+ wxTE_MULTILINE);
+ sizerMsgs->Add(m_textDetailed, wxSizerFlags(1).Expand());
+
+ sizer->Add(sizerMsgs, wxSizerFlags(1).Expand().Border());
+}
+
+void TestRichMessageDialog::AddAdditionalFlags(wxSizer *sizer)
+{
+ // add checkbox to set the initial state for the checkbox shown
+ // in the dialog.
+ m_initialValueCheckBox =
+ new wxCheckBox(this, wxID_ANY, "Checkbox initially checked");
+ sizer->Add(m_initialValueCheckBox, wxSizerFlags(1).Border());
+}
+
+void TestRichMessageDialog::OnApply(wxCommandEvent& WXUNUSED(event))
+{
+ wxRichMessageDialog dlg(this, GetMessage(), "Test Rich Message Dialog",
+ GetStyle());
+ PrepareMessageDialog(dlg);
+
+ dlg.ShowCheckBox(m_textCheckBox->GetValue(),
+ m_initialValueCheckBox->GetValue());
+ dlg.ShowDetailedText(m_textDetailed->GetValue());
+
+ dlg.ShowModal();
+}
+
+#endif // wxUSE_RICHMSGDLG
#if wxUSE_LOG