]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/preferencesg.cpp
Add wxPreferencesEditor class.
[wxWidgets.git] / src / generic / preferencesg.cpp
diff --git a/src/generic/preferencesg.cpp b/src/generic/preferencesg.cpp
new file mode 100644 (file)
index 0000000..a19cc44
--- /dev/null
@@ -0,0 +1,184 @@
+///////////////////////////////////////////////////////////////////////////////
+// Name:        src/generic/preferencesg.cpp
+// Purpose:     Implementation of wxPreferencesEditor.
+// Author:      Vaclav Slavik
+// Created:     2013-02-19
+// RCS-ID:      $Id$
+// Copyright:   (c) 2013 Vaclav Slavik <vslavik@fastmail.fm>
+// Licence:     wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+    #pragma hdrstop
+#endif
+
+#include "wx/private/preferences.h"
+
+#ifndef wxHAS_PREF_EDITOR_NATIVE
+
+#include "wx/dialog.h"
+#include "wx/notebook.h"
+#include "wx/sizer.h"
+#include "wx/sharedptr.h"
+#include "wx/scopedptr.h"
+#include "wx/vector.h"
+
+class wxGenericPrefsDialog : public wxDialog
+{
+public:
+    wxGenericPrefsDialog(wxWindow *parent)
+        : wxDialog(parent, wxID_ANY, _("Preferences"),
+                   wxDefaultPosition, wxDefaultSize,
+                   wxDEFAULT_FRAME_STYLE & ~(wxRESIZE_BORDER | wxMAXIMIZE_BOX | wxMINIMIZE_BOX))
+    {
+        SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);
+
+        wxSizer *sizer = new wxBoxSizer(wxVERTICAL);
+
+        m_notebook = new wxNotebook(this, wxID_ANY);
+        sizer->Add(m_notebook, wxSizerFlags(1).Expand().DoubleBorder());
+
+#ifdef __WXGTK__
+        SetEscapeId(wxID_CLOSE);
+        sizer->Add(CreateButtonSizer(wxCLOSE), wxSizerFlags().Expand().DoubleBorder(wxBOTTOM));
+#else
+        sizer->Add(CreateButtonSizer(wxOK | wxCANCEL),
+                   wxSizerFlags().Expand().DoubleBorder(wxLEFT|wxRIGHT|wxBOTTOM));
+#endif
+        SetSizer(sizer);
+    }
+
+    void AddPage(wxPreferencesPage *page)
+    {
+        wxWindow *win = page->CreateWindow(m_notebook);
+        m_notebook->AddPage(win, page->GetName());
+    }
+
+private:
+    wxNotebook *m_notebook;
+};
+
+
+class wxGenericPreferencesEditorImplBase : public wxPreferencesEditorImpl
+{
+public:
+    virtual void AddPage(wxPreferencesPage* page)
+    {
+        m_pages.push_back(wxSharedPtr<wxPreferencesPage>(page));
+    }
+
+protected:
+    virtual wxDialog *CreateWindow(wxWindow *parent)
+    {
+        wxGenericPrefsDialog *dlg = new wxGenericPrefsDialog(parent);
+
+        // TODO: Don't create all pages immediately like this, do it on demand
+        //       when a page is selected in the notebook (as is done on OS X).
+        //
+        //       Currently, creating all pages is necessary so that the notebook
+        //       can determine its best size. We'll need to extend
+        //       wxPreferencesPage with a GetBestSize() virtual method to make
+        //       it possible to defer the creation.
+        for ( Pages::const_iterator i = m_pages.begin();
+              i != m_pages.end();
+              ++i )
+        {
+            dlg->AddPage(i->get());
+        }
+
+        return dlg;
+    }
+
+    typedef wxVector< wxSharedPtr<wxPreferencesPage> > Pages;
+    Pages m_pages;
+
+};
+
+
+#ifdef wxHAS_PREF_EDITOR_MODELESS
+
+class wxModelessPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
+{
+public:
+    virtual ~wxModelessPreferencesEditorImpl()
+    {
+        // m_win may already be destroyed if this destructor is called from
+        // wxApp's destructor. In that case, all windows -- including this
+        // one -- would already be destroyed by now.
+        if ( m_win )
+            m_win->Destroy();
+    }
+
+    virtual void Show(wxWindow* parent)
+    {
+        if ( !m_win )
+        {
+            wxWindow *win = CreateWindow(parent);
+            win->Show();
+            m_win = win;
+        }
+        else
+        {
+            // Ideally, we'd reparent the dialog under 'parent', but it's
+            // probably not worth the hassle. We know the old parent is still
+            // valid, because otherwise Dismiss() would have been called and
+            // m_win cleared.
+            m_win->Raise();
+        }
+    }
+
+    virtual void Dismiss()
+    {
+        if ( m_win )
+        {
+            m_win->Close(/*force=*/true);
+            m_win = NULL;
+        }
+    }
+
+private:
+    wxWeakRef<wxWindow> m_win;
+};
+
+#else // !wxHAS_PREF_EDITOR_MODELESS
+
+class wxModalPreferencesEditorImpl : public wxGenericPreferencesEditorImplBase
+{
+public:
+    virtual void Show(wxWindow* parent)
+    {
+        wxScopedPtr<wxDialog> dlg(CreateWindow(parent));
+        dlg->ShowModal();
+    }
+
+    virtual void Dismiss()
+    {
+        // nothing to do
+    }
+};
+
+#endif // !wxHAS_PREF_EDITOR_MODELESS
+
+
+/*static*/
+wxPreferencesEditorImpl* wxPreferencesEditorImpl::Create()
+{
+#ifdef wxHAS_PREF_EDITOR_MODELESS
+    return new wxModelessPreferencesEditorImpl();
+#else
+    return new wxModalPreferencesEditorImpl();
+#endif
+}
+
+#endif // !wxHAS_PREF_EDITOR_NATIVE