]> git.saurik.com Git - wxWidgets.git/blob - src/generic/preferencesg.cpp
1481c633025b8b0f6fe3aa95b2dcb9f2fd404866
[wxWidgets.git] / src / generic / preferencesg.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/preferencesg.cpp
3 // Purpose: Implementation of wxPreferencesEditor.
4 // Author: Vaclav Slavik
5 // Created: 2013-02-19
6 // RCS-ID: $Id$
7 // Copyright: (c) 2013 Vaclav Slavik <vslavik@fastmail.fm>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #include "wx/private/preferences.h"
27
28 #ifndef wxHAS_PREF_EDITOR_NATIVE
29
30 #include "wx/dialog.h"
31 #include "wx/notebook.h"
32 #include "wx/sizer.h"
33 #include "wx/sharedptr.h"
34 #include "wx/scopedptr.h"
35 #include "wx/vector.h"
36
37 namespace
38 {
39
40 class wxGenericPrefsDialog : public wxDialog
41 {
42 public:
43 wxGenericPrefsDialog(wxWindow *parent, const wxString& title)
44 : wxDialog(parent, wxID_ANY, title,
45 wxDefaultPosition, wxDefaultSize,
46 wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX))
47 {
48 SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
49
50 wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
51
52 m_notebook = new wxNotebook(this, wxID_ANY);
53 sizer->Add(m_notebook, wxSizerFlags(1).Expand().DoubleBorder());
54
55 #ifdef __WXGTK__
56 SetEscapeId(wxID_CLOSE);
57 sizer->Add(CreateButtonSizer(wxCLOSE), wxSizerFlags().Expand().DoubleBorder(wxBOTTOM));
58 #else
59 sizer->Add(CreateButtonSizer(wxOK | wxCANCEL),
60 wxSizerFlags().Expand().DoubleBorder(wxLEFT|wxRIGHT|wxBOTTOM));
61 #endif
62 SetSizer(sizer);
63 }
64
65 void AddPage(wxPreferencesPage *page)
66 {
67 wxWindow *win = page->CreateWindow(m_notebook);
68 m_notebook->AddPage(win, page->GetName());
69 }
70
71 int GetSelectedPage() const
72 {
73 return m_notebook->GetSelection();
74 }
75
76 void SelectPage(int page)
77 {
78 m_notebook->ChangeSelection(page);
79 }
80
81 private:
82 wxNotebook *m_notebook;
83 };
84
85
86 class wxGenericPreferencesEditorImplBase : public wxPreferencesEditorImpl
87 {
88 public:
89 void SetTitle(const wxString& title)
90 {
91 m_title = title;
92 }
93
94 virtual void AddPage(wxPreferencesPage* page)
95 {
96 m_pages.push_back(wxSharedPtr<wxPreferencesPage>(page));
97 }
98
99 protected:
100 wxGenericPrefsDialog *CreateDialog(wxWindow *parent)
101 {
102 if ( m_title.empty() )
103 m_title = _("Preferences");
104
105 wxGenericPrefsDialog *dlg = new wxGenericPrefsDialog(parent, m_title);
106
107 // TODO: Don't create all pages immediately like this, do it on demand
108 // when a page is selected in the notebook (as is done on OS X).
109 //
110 // Currently, creating all pages is necessary so that the notebook
111 // can determine its best size. We'll need to extend
112 // wxPreferencesPage with a GetBestSize() virtual method to make
113 // it possible to defer the creation.
114 for ( Pages::const_iterator i = m_pages.begin();
115 i != m_pages.end();
116 ++i )
117 {
118 dlg->AddPage(i->get());
119 }
120
121 return dlg;
122 }
123
124 typedef wxVector< wxSharedPtr<wxPreferencesPage> > Pages;
125 Pages m_pages;
126
127 private:
128 wxString m_title;
129 };
130
131
132 #ifdef wxHAS_PREF_EDITOR_MODELESS
133
134 class wxModelessPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
135 {
136 public:
137 virtual ~wxModelessPreferencesEditorImpl()
138 {
139 // m_win may already be destroyed if this destructor is called from
140 // wxApp's destructor. In that case, all windows -- including this
141 // one -- would already be destroyed by now.
142 if ( m_win )
143 m_win->Destroy();
144 }
145
146 virtual void Show(wxWindow* parent)
147 {
148 if ( !m_win )
149 {
150 wxWindow *win = CreateDialog(parent);
151 win->Show();
152 m_win = win;
153 }
154 else
155 {
156 // Ideally, we'd reparent the dialog under 'parent', but it's
157 // probably not worth the hassle. We know the old parent is still
158 // valid, because otherwise Dismiss() would have been called and
159 // m_win cleared.
160 m_win->Raise();
161 }
162 }
163
164 virtual void Dismiss()
165 {
166 if ( m_win )
167 {
168 m_win->Close(/*force=*/true);
169 m_win = NULL;
170 }
171 }
172
173 private:
174 wxWeakRef<wxWindow> m_win;
175 };
176
177 inline
178 wxGenericPreferencesEditorImplBase* NewGenericImpl()
179 {
180 return new wxModelessPreferencesEditorImpl;
181 }
182
183 #else // !wxHAS_PREF_EDITOR_MODELESS
184
185 class wxModalPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
186 {
187 public:
188 wxModalPreferencesEditorImpl()
189 {
190 m_currentPage = -1;
191 }
192
193 virtual void Show(wxWindow* parent)
194 {
195 wxScopedPtr<wxGenericPrefsDialog> dlg(CreateDialog(parent));
196 dlg->Fit();
197
198 // Restore the previously selected page, if any.
199 if ( m_currentPage != -1 )
200 dlg->SelectPage(m_currentPage);
201
202 // Don't remember the last selected page if the dialog was cancelled.
203 if ( dlg->ShowModal() != wxID_CANCEL )
204 m_currentPage = dlg->GetSelectedPage();
205 }
206
207 virtual void Dismiss()
208 {
209 // nothing to do
210 }
211
212 private:
213 int m_currentPage;
214 };
215
216 inline
217 wxGenericPreferencesEditorImplBase* NewGenericImpl()
218 {
219 return new wxModalPreferencesEditorImpl;
220 }
221
222 #endif // !wxHAS_PREF_EDITOR_MODELESS
223
224 } // anonymous namespace
225
226 /*static*/
227 wxPreferencesEditorImpl* wxPreferencesEditorImpl::Create(const wxString& title)
228 {
229 wxGenericPreferencesEditorImplBase* const impl = NewGenericImpl();
230
231 impl->SetTitle(title);
232
233 return impl;
234 }
235
236 #endif // !wxHAS_PREF_EDITOR_NATIVE