add an example of a custom wxValidator-derived class; cleanup a bit the dialog layout

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58566 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Francesco Montorsi
2009-01-31 21:21:08 +00:00
parent cbec0f401a
commit 2e7a6b030c
2 changed files with 114 additions and 23 deletions

View File

@@ -46,7 +46,7 @@ wxString g_listbox_choices[] =
{wxT("one"), wxT("two"), wxT("three")}; {wxT("one"), wxT("two"), wxT("three")};
wxString g_combobox_choices[] = wxString g_combobox_choices[] =
{wxT("yes"), wxT("no"), wxT("maybe")}; {wxT("yes"), wxT("no (doesn't validate)"), wxT("maybe (doesn't validate)")};
wxString g_radiobox_choices[] = wxString g_radiobox_choices[] =
{wxT("green"), wxT("yellow"), wxT("red")}; {wxT("green"), wxT("yellow"), wxT("red")};
@@ -59,13 +59,68 @@ MyData::MyData()
{ {
// This string will be passed to an alpha-only validator, which // This string will be passed to an alpha-only validator, which
// will complain because spaces aren't alpha. Note that validation // will complain because spaces aren't alpha. Note that validation
// is performed only when 'OK' is pressed. It would be nice to // is performed only when 'OK' is pressed.
// enhance this so that validation would occur when the text
// control loses focus.
m_string = wxT("Spaces are invalid here"); m_string = wxT("Spaces are invalid here");
m_listbox_choices.Add(0); m_listbox_choices.Add(0);
} }
// ----------------------------------------------------------------------------
// MyComboBoxValidator
// ----------------------------------------------------------------------------
bool MyComboBoxValidator::Validate(wxWindow *WXUNUSED(parent))
{
wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxComboBox)));
wxComboBox* cb = (wxComboBox*)GetWindow();
if (cb->GetValue() == g_combobox_choices[1] ||
cb->GetValue() == g_combobox_choices[2])
{
// we accept any string != g_combobox_choices[1|2] !
wxLogError("Invalid combo box text!");
return false;
}
if (m_var)
*m_var = cb->GetValue();
return true;
}
bool MyComboBoxValidator::TransferToWindow()
{
wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxComboBox)));
if ( m_var )
{
wxComboBox* cb = (wxComboBox*)GetWindow();
if ( !cb )
return false;
cb->SetValue(*m_var);
}
return true;
}
bool MyComboBoxValidator::TransferFromWindow()
{
wxASSERT(GetWindow()->IsKindOf(CLASSINFO(wxComboBox)));
if ( m_var )
{
wxComboBox* cb = (wxComboBox*)GetWindow();
if ( !cb )
return false;
*m_var = cb->GetValue();
}
return true;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// MyApp // MyApp
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -113,7 +168,7 @@ MyFrame::MyFrame(wxFrame *frame, const wxString&title, int x, int y, int w, int
file_menu->Append(wxID_EXIT, wxT("E&xit")); file_menu->Append(wxID_EXIT, wxT("E&xit"));
wxMenuBar *menu_bar = new wxMenuBar; wxMenuBar *menu_bar = new wxMenuBar;
menu_bar->Append(file_menu, wxT("File")); menu_bar->Append(file_menu, wxT("&File"));
SetMenuBar(menu_bar); SetMenuBar(menu_bar);
// All validators share a common (static) flag that controls // All validators share a common (static) flag that controls
@@ -188,10 +243,10 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
// Pointers to some of these controls are saved in member variables // Pointers to some of these controls are saved in member variables
// so that we can use them elsewhere, like this one. // so that we can use them elsewhere, like this one.
text = new wxTextCtrl(this, VALIDATE_TEXT, wxEmptyString, m_text = new wxTextCtrl(this, VALIDATE_TEXT, wxEmptyString,
wxPoint(10, 10), wxSize(120, wxDefaultCoord), 0, wxDefaultPosition, wxDefaultSize, 0,
wxTextValidator(wxFILTER_ALPHA, &g_data.m_string)); wxTextValidator(wxFILTER_ALPHA, &g_data.m_string));
flexgridsizer->Add(text); flexgridsizer->Add(m_text, 1, wxGROW);
// This wxCheckBox* doesn't need to be assigned to any pointer // This wxCheckBox* doesn't need to be assigned to any pointer
// because we don't use it elsewhere--it can be anonymous. // because we don't use it elsewhere--it can be anonymous.
@@ -199,23 +254,29 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
// can be gotten directly from g_data. // can be gotten directly from g_data.
flexgridsizer->Add(new wxCheckBox(this, VALIDATE_CHECK, wxT("Sample checkbox"), flexgridsizer->Add(new wxCheckBox(this, VALIDATE_CHECK, wxT("Sample checkbox"),
wxPoint(130, 10), wxSize(120, wxDefaultCoord), 0, wxPoint(130, 10), wxSize(120, wxDefaultCoord), 0,
wxGenericValidator(&g_data.m_checkbox_state))); wxGenericValidator(&g_data.m_checkbox_state)),
1, wxALIGN_CENTER);
flexgridsizer->Add(new wxListBox((wxWindow*)this, VALIDATE_LIST, flexgridsizer->Add(new wxListBox((wxWindow*)this, VALIDATE_LIST,
wxPoint(10, 30), wxSize(120, wxDefaultCoord), wxPoint(10, 30), wxSize(120, wxDefaultCoord),
3, g_listbox_choices, wxLB_MULTIPLE, 3, g_listbox_choices, wxLB_MULTIPLE,
wxGenericValidator(&g_data.m_listbox_choices))); wxGenericValidator(&g_data.m_listbox_choices)),
1, wxGROW);
combobox = new wxComboBox((wxWindow*)this, VALIDATE_COMBO, wxEmptyString, m_combobox = new wxComboBox(this, VALIDATE_COMBO, wxEmptyString,
wxPoint(130, 30), wxSize(120, wxDefaultCoord), wxPoint(130, 30), wxSize(120, wxDefaultCoord),
3, g_combobox_choices, 0L, 3, g_combobox_choices, 0L,
wxGenericValidator(&g_data.m_combobox_choice)); MyComboBoxValidator(&g_data.m_combobox_choice));
flexgridsizer->Add(combobox); flexgridsizer->Add(m_combobox, 1, wxALIGN_CENTER);
flexgridsizer->AddGrowableCol(0);
flexgridsizer->AddGrowableCol(1);
flexgridsizer->AddGrowableRow(1);
// setup the button sizer // setup the button sizer
// ---------------------- // ----------------------
wxStdDialogButtonSizer *btn = new wxStdDialogButtonSizer(); wxStdDialogButtonSizer *btn = new wxStdDialogButtonSizer();
btn->AddButton(new wxButton(this, wxID_OK)); btn->AddButton(new wxButton(this, wxID_OK));
btn->AddButton(new wxButton(this, wxID_CANCEL)); btn->AddButton(new wxButton(this, wxID_CANCEL));
@@ -224,7 +285,7 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
// setup the main sizer // setup the main sizer
// -------------------- // --------------------
wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL ); wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );
mainsizer->Add(flexgridsizer, 1, wxGROW | wxALL, 10); mainsizer->Add(flexgridsizer, 1, wxGROW | wxALL, 10);
@@ -233,21 +294,26 @@ MyDialog::MyDialog( wxWindow *parent, const wxString& title,
wxPoint(10, 100), wxDefaultSize, wxPoint(10, 100), wxDefaultSize,
3, g_radiobox_choices, 1, wxRA_SPECIFY_ROWS, 3, g_radiobox_choices, 1, wxRA_SPECIFY_ROWS,
wxGenericValidator(&g_data.m_radiobox_choice)), wxGenericValidator(&g_data.m_radiobox_choice)),
0, wxGROW | wxALL, 10); 0, wxGROW | wxLEFT|wxBOTTOM|wxRIGHT, 10);
mainsizer->Add(btn, 0, wxGROW | wxALL, 10); mainsizer->Add(btn, 0, wxGROW | wxALL, 10);
SetSizer(mainsizer); SetSizer(mainsizer);
mainsizer->SetSizeHints(this); mainsizer->SetSizeHints(this);
// make the dialog a bit bigger than its minimal size:
SetSize(GetBestSize()*1.5);
} }
bool MyDialog::TransferDataToWindow() bool MyDialog::TransferDataToWindow()
{ {
bool r = wxDialog::TransferDataToWindow(); bool r = wxDialog::TransferDataToWindow();
// These function calls have to be made here, after the // These function calls have to be made here, after the
// dialog has been created. // dialog has been created.
text->SetFocus(); m_text->SetFocus();
combobox->SetSelection(0); m_combobox->SetSelection(0);
return r; return r;
} }

View File

@@ -48,30 +48,55 @@ public:
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
const long style = wxDEFAULT_DIALOG_STYLE); const long style = wxDEFAULT_DIALOG_STYLE);
bool TransferDataToWindow(); bool TransferDataToWindow();
wxTextCtrl *text; wxTextCtrl *m_text;
wxComboBox *combobox; wxComboBox *m_combobox;
}; };
class MyData class MyData
{ {
public: public:
MyData(); MyData();
// These data members are designed for transfer to and from // These data members are designed for transfer to and from
// controls, via validators. For instance, a text control's // controls, via validators. For instance, a text control's
// transferred value is a string: // transferred value is a string:
wxString m_string; wxString m_string;
// Listboxes may permit multiple selections, so their state // Listboxes may permit multiple selections, so their state
// is transferred to an integer-array class. // is transferred to an integer-array class.
wxArrayInt m_listbox_choices; wxArrayInt m_listbox_choices;
bool m_checkbox_state;
// Comboboxes differ from listboxes--validators transfer // Comboboxes differ from listboxes--validators transfer
// the string entered in the combobox's text-edit field. // the string entered in the combobox's text-edit field.
wxString m_combobox_choice; wxString m_combobox_choice;
bool m_checkbox_state;
int m_radiobox_choice; int m_radiobox_choice;
}; };
enum { class MyComboBoxValidator : public wxValidator
{
public:
MyComboBoxValidator(const MyComboBoxValidator& tocopy) { m_var=tocopy.m_var; }
MyComboBoxValidator(wxString* var) { m_var=var; }
virtual bool Validate(wxWindow* parent);
virtual wxObject* Clone() const { return new MyComboBoxValidator(*this); }
// Called to transfer data to the window
virtual bool TransferToWindow();
// Called to transfer data from the window
virtual bool TransferFromWindow();
protected:
wxString* m_var;
};
enum
{
VALIDATE_DIALOG_ID = wxID_HIGHEST, VALIDATE_DIALOG_ID = wxID_HIGHEST,
VALIDATE_TEST_DIALOG, VALIDATE_TEST_DIALOG,