]> git.saurik.com Git - wxWidgets.git/blob - src/generic/preferencesg.cpp
Create a small helper class for Unity global menu bug workaround.
[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 class wxGenericPrefsDialog : public wxDialog
38 {
39 public:
40 wxGenericPrefsDialog(wxWindow *parent)
41 : wxDialog(parent, wxID_ANY, _("Preferences"),
42 wxDefaultPosition, wxDefaultSize,
43 wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX))
44 {
45 SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
46
47 wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
48
49 m_notebook = new wxNotebook(this, wxID_ANY);
50 sizer->Add(m_notebook, wxSizerFlags(1).Expand().DoubleBorder());
51
52 #ifdef __WXGTK__
53 SetEscapeId(wxID_CLOSE);
54 sizer->Add(CreateButtonSizer(wxCLOSE), wxSizerFlags().Expand().DoubleBorder(wxBOTTOM));
55 #else
56 sizer->Add(CreateButtonSizer(wxOK | wxCANCEL),
57 wxSizerFlags().Expand().DoubleBorder(wxLEFT|wxRIGHT|wxBOTTOM));
58 #endif
59 SetSizer(sizer);
60 }
61
62 void AddPage(wxPreferencesPage *page)
63 {
64 wxWindow *win = page->CreateWindow(m_notebook);
65 m_notebook->AddPage(win, page->GetName());
66 }
67
68 private:
69 wxNotebook *m_notebook;
70 };
71
72
73 class wxGenericPreferencesEditorImplBase : public wxPreferencesEditorImpl
74 {
75 public:
76 virtual void AddPage(wxPreferencesPage* page)
77 {
78 m_pages.push_back(wxSharedPtr<wxPreferencesPage>(page));
79 }
80
81 protected:
82 virtual wxDialog *CreateWindow(wxWindow *parent)
83 {
84 wxGenericPrefsDialog *dlg = new wxGenericPrefsDialog(parent);
85
86 // TODO: Don't create all pages immediately like this, do it on demand
87 // when a page is selected in the notebook (as is done on OS X).
88 //
89 // Currently, creating all pages is necessary so that the notebook
90 // can determine its best size. We'll need to extend
91 // wxPreferencesPage with a GetBestSize() virtual method to make
92 // it possible to defer the creation.
93 for ( Pages::const_iterator i = m_pages.begin();
94 i != m_pages.end();
95 ++i )
96 {
97 dlg->AddPage(i->get());
98 }
99
100 return dlg;
101 }
102
103 typedef wxVector< wxSharedPtr<wxPreferencesPage> > Pages;
104 Pages m_pages;
105
106 };
107
108
109 #ifdef wxHAS_PREF_EDITOR_MODELESS
110
111 class wxModelessPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
112 {
113 public:
114 virtual ~wxModelessPreferencesEditorImpl()
115 {
116 // m_win may already be destroyed if this destructor is called from
117 // wxApp's destructor. In that case, all windows -- including this
118 // one -- would already be destroyed by now.
119 if ( m_win )
120 m_win->Destroy();
121 }
122
123 virtual void Show(wxWindow* parent)
124 {
125 if ( !m_win )
126 {
127 wxWindow *win = CreateWindow(parent);
128 win->Show();
129 m_win = win;
130 }
131 else
132 {
133 // Ideally, we'd reparent the dialog under 'parent', but it's
134 // probably not worth the hassle. We know the old parent is still
135 // valid, because otherwise Dismiss() would have been called and
136 // m_win cleared.
137 m_win->Raise();
138 }
139 }
140
141 virtual void Dismiss()
142 {
143 if ( m_win )
144 {
145 m_win->Close(/*force=*/true);
146 m_win = NULL;
147 }
148 }
149
150 private:
151 wxWeakRef<wxWindow> m_win;
152 };
153
154 #else // !wxHAS_PREF_EDITOR_MODELESS
155
156 class wxModalPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
157 {
158 public:
159 virtual void Show(wxWindow* parent)
160 {
161 wxScopedPtr<wxDialog> dlg(CreateWindow(parent));
162 dlg->Fit();
163 dlg->ShowModal();
164 }
165
166 virtual void Dismiss()
167 {
168 // nothing to do
169 }
170 };
171
172 #endif // !wxHAS_PREF_EDITOR_MODELESS
173
174
175 /*static*/
176 wxPreferencesEditorImpl* wxPreferencesEditorImpl::Create()
177 {
178 #ifdef wxHAS_PREF_EDITOR_MODELESS
179 return new wxModelessPreferencesEditorImpl();
180 #else
181 return new wxModalPreferencesEditorImpl();
182 #endif
183 }
184
185 #endif // !wxHAS_PREF_EDITOR_NATIVE