6. Preferences
Preferences allow a user to customize the application in certain areas. Preferences can be set in two different ways, either through a preferences dialog or through menu commands.
6.1 Preferences dialog
The preference dialog is the usual place to specify any setting a user may configure to his liking. When the dialog is left with the OK button the current preferences are save and persists until they are changed again with this dialog.
Sample code
#include "prefdlg.h" // Preferences dialog
class AppFrame: public wxFrame {
...
void OnPreferences (wxCommandEvent &event);
...
}
BEGIN_EVENT_TABLE (AppFrame, wxFrame)
...
EVT_MENU (myID_PREFS, AppFrame::OnPreferences)
...
END_EVENT_TABLE ()
void AppFrame::OnPreferences (wxCommandEvent &event) {
PreferenceDlg (this);
}
...
BEGIN_EVENT_TABLE (PreferenceDlg, wxDialog)
EVT_BUTTON (wxID_APPLY, PreferenceDlg::OnApply)
EVT_BUTTON (wxID_CANCEL, PreferenceDlg::OnCancel)
EVT_BUTTON (wxID_OK, PreferenceDlg::OnOkay)
EVT_BUTTON (wxID_RESET, PreferenceDlg::OnReset)
END_EVENT_TABLE()
PreferenceDlg::PreferenceDlg (wxWindow *parent,
long style)
: wxDialog (parent, -1, _("Preferences"),
wxDefaultPosition, wxDefaultSize) {
// load configuration
LoadValues ();
// create preference panel
wxPanel *panel = new wxPanel (this, -1, wxDefaultPosition, wxDefaultSize,
wxTAB_TRAVERSAL|wxCLIP_CHILDREN|wxNO_BORDER);
// lauout the buttons
wxButton *resetButton = new wxButton (panel, wxID_RESET, _("Default"));
wxButton *okButton = new wxButton (panel, wxID_OK, _("OK"));
okButton->SetDefault();
wxButton *applyButton = new wxButton (panel, wxID_APPLY, _("Apply"));
wxButton *cancelButton = new wxButton (panel, wxID_CANCEL, _("Cancel"));
wxBoxSizer *buttonpane = new wxBoxSizer (wxHORIZONTAL);
buttonpane->Add (resetButton, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL);
buttonpane->Add (16, 0, 1);
buttonpane->Add (okButton, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL);
buttonpane->Add (6, 0);
buttonpane->Add (applyButton, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL);
buttonpane->Add (6, 0);
buttonpane->Add (cancelButton, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL);
// set sizer
wxBoxSizer *panelsizer = new wxBoxSizer (wxVERTICAL);
panelsizer->Add (...
panelsizer->Add (0, 6);
panelsizer->Add (buttonpane, 0, wxEXPAND|wxLEFT|wxRIGHT|wxBOTTOM, 10);
panel->SetSizer (panelsizer);
panelsizer->Fit (this);
Centre (wxBOTH);
ShowModal();
}
PreferenceDlg::~PreferenceDlg () {
}
//----------------------------------------------------------------------------
// event handlers
void PreferenceDlg::OnApply (wxCommandEvent &WXUNUSED(event)) {
...
SaveValues ();
}
void PreferenceDlg::OnCancel (wxCommandEvent &WXUNUSED(event)) {
EndModal (wxID_CANCEL);
}
void PreferenceDlg::OnOkay (wxCommandEvent &WXUNUSED(event)) {
...
SaveValues ();
EndModal (wxID_OK);
}
void PreferenceDlg::OnReset (wxCommandEvent &WXUNUSED(event)) {
...
}
void PreferenceDlg::LoadValues () {
wxString key = KEYNAME;
key.Append (_T("/"));
wxConfig *cfg = new wxConfig (wxTheApp->GetAppName());
cfg->Read (key + VALUENAME, ...);
...
delete cfg;
}
void PreferenceDlg::SaveValues () {
wxString key = KEYNAME;
key.Append (_T("/"));
wxConfig *cfg = new wxConfig (wxTheApp->GetAppName());
cfg->Write (key + VALUENAME, ...);
...
delete cfg;
}
6.2 Preferences in the menu
Setting preferences via menu command allow changing them for the current session. When the application ends these settings are lost. Usually only the immediately necessary settings are available as menu commands.
Sample code
class AppFrame: public wxFrame {
...
// View menu
wxMenu *menuView = new wxMenu;
menuView->AppendCheckItem (myID_TOOLBARS, _("Tool &bar"));
menuView->AppendCheckItem (myID_STATUSBAR, _("Status b&ar"));
...
}
6.3 Load/save of preferences
Preferences are usually stored with in the registry (Windows) or config file (Linux, etc.). wxWiggets supports this through wxConfig choosing the platform specific solution itself. Be carefully when keeping the preferences open over a longer time period. For safety reason keep this period as small as possible.
One might use wxFileConfig instead to force the use of config file even on Windows. The default location of the config file is based on the $HOME variable on Linux, etc. and $HOMEDRIVE + HOMEPATH on Windows. The file will only be written back to disk when the config objected is deleted or the Flush() method is called.
Sample code
#include <wx/config.h> // configuration support
const wxString PAGE_COMMON = _T("Common");
...
const wxString NOSPLASH = _T("NoSplashScreen");
const wxString SHOWTOOLBAR = _T("ShowToolbar");
const wxString SHOWSTATUSBAR = _T("ShowStatusbar");
const wxString USEPAGES = _T("UsePages");
CommonPrefs g_CommonPrefs = {
// application prefs
false, // noSplash
true, // showToolbar
true, // showStatusbar
false, // usePages
};
...
void PreferenceDlg::LoadValuesPageCommon () {
wxString key = PAGE_COMMON;
key.Append (_T("/"));
// common prefs
wxConfig *cfg = new wxConfig (wxTheApp->GetAppName());
cfg->Read (key + NOSPLASH, &g_CommonPrefs.noSplash);
cfg->Read (key + SHOWTOOLBAR, &g_CommonPrefs.showToolbar);
cfg->Read (key + SHOWSTATUSBAR, &g_CommonPrefs.showStatusbar);
cfg->Read (key + USEPAGES, &g_CommonPrefs.usePages);
delete cfg;
}
void PreferenceDlg::SaveValuesPageCommon () {
wxString key = PAGE_COMMON;
key.Append (_T("/"));
// common prefs
wxConfig *cfg = new wxConfig (wxTheApp->GetAppName());
cfg->Write (key + NOSPLASH, g_CommonPrefs.noSplash);
cfg->Write (key + SHOWTOOLBAR, g_CommonPrefs.showToolbar);
cfg->Write (key + SHOWSTATUSBAR, g_CommonPrefs.showStatusbar);
cfg->Write (key + USEPAGES, g_CommonPrefs.usePages);
delete cfg;
}