[Home]  [Prev]  [Next]    Guidelines for designing applications with a consistent look and feel

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; }