Code

* don't strech buttons on lpe dialog when resizing the dialog
[inkscape.git] / src / ui / dialog / panel-dialog.h
1 /**
2  * \brief A panel holding dialog
3  *
4  * Authors:
5  *   Gustav Broberg <broberg@kth.se>
6  *
7  * Copyright (C) 2007 Authors
8  *
9  * Released under GNU GPL.  Read the file 'COPYING' for more information.
10  */
12 #ifndef INKSCAPE_PANEL_DIALOG_H
13 #define INKSCAPE_PANEL_DIALOG_H
15 #ifdef HAVE_CONFIG_H
16 # include <config.h>
17 #endif
19 #include <gtkmm/stock.h>
21 #include "verbs.h"
22 #include "dialog.h"
23 #include "dialogs/swatches.h"
24 #include "ui/dialog/floating-behavior.h"
25 #include "ui/dialog/dock-behavior.h"
26 #include "prefs-utils.h"
28 namespace Inkscape {
29 namespace UI {
30 namespace Dialog {
32 class PanelDialogBase {
33 public:
34     PanelDialogBase(Panel &panel, char const */*prefs_path*/, int const /*verb_num*/,
35                     Glib::ustring const &/*apply_label*/) :
36       _panel (panel) { }
38     virtual void present() = 0;
39     virtual ~PanelDialogBase() {}
41     virtual Panel &getPanel() { return _panel; }
43 protected:
44     static void handle_deactivate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) {
45         g_return_if_fail(data != NULL);
46         static_cast<PanelDialogBase *>(data)->_propagateDesktopDeactivated(application, desktop);
47     }
49     static void _handle_activate_desktop(Inkscape::Application *application, SPDesktop *desktop, void *data) {
50         g_return_if_fail(data != NULL);
51         static_cast<PanelDialogBase *>(data)->_propagateDesktopActivated(application, desktop);
52     }
54     inline virtual void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document);
55     inline virtual void _propagateDesktopActivated(Inkscape::Application *, SPDesktop *);
56     inline virtual void _propagateDesktopDeactivated(Inkscape::Application *, SPDesktop *);
58     Panel &_panel;
59     sigc::connection _document_replaced_connection;
60 };
62 template <typename Behavior>
63 class PanelDialog : public PanelDialogBase, public Inkscape::UI::Dialog::Dialog {
65 public:
66     PanelDialog(Panel &contents, char const *prefs_path, int const verb_num,
67                 Glib::ustring const &apply_label);
69     virtual ~PanelDialog() {}
71     template <typename T>
72     static PanelDialog<Behavior> *create();
74     virtual void present() { Dialog::present(); }
76 private:
77     PanelDialog();  // no constructor without params
78     PanelDialog(PanelDialog<Behavior> const &d);                      // no copy
79     PanelDialog<Behavior>& operator=(PanelDialog<Behavior> const &d); // no assign
80 };
83 template <>
84 class PanelDialog<Behavior::FloatingBehavior> :
85         public PanelDialogBase, public Inkscape::UI::Dialog::Dialog {
87 public:
88     inline PanelDialog(Panel &contents, char const *prefs_path, int const verb_num,
89                        Glib::ustring const &apply_label);
91     virtual ~PanelDialog() {}
93     template <typename T>
94     static PanelDialog<Behavior::FloatingBehavior> *create();
96     virtual void present() { Dialog::present(); }
98 private:
99     PanelDialog();  // no constructor without params
100     PanelDialog(PanelDialog<Behavior::FloatingBehavior> const &d); // no copy
101     PanelDialog<Behavior::FloatingBehavior>&
102     operator=(PanelDialog<Behavior::FloatingBehavior> const &d);   // no assign
103 };
107 void
108 PanelDialogBase::_propagateDocumentReplaced(SPDesktop *desktop, SPDocument *document)
110     _panel.signalDocumentReplaced().emit(desktop, document);
113 void
114 PanelDialogBase::_propagateDesktopActivated(Inkscape::Application *application, SPDesktop *desktop)
116     _document_replaced_connection =
117         desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialogBase::_propagateDocumentReplaced));
118     _panel.signalActivateDesktop().emit(application, desktop);
121 void
122 PanelDialogBase::_propagateDesktopDeactivated(Inkscape::Application *application, SPDesktop *desktop)
124     _document_replaced_connection.disconnect();
125     _panel.signalDeactiveDesktop().emit(application, desktop);
129 template <typename B>
130 PanelDialog<B>::PanelDialog(Panel &panel, char const *prefs_path, int const verb_num,
131                             Glib::ustring const &apply_label) :
132     PanelDialogBase(panel, prefs_path, verb_num, apply_label),
133     Dialog(&B::create, prefs_path, verb_num, apply_label)
135     Gtk::VBox *vbox = get_vbox();
136     _panel.signalResponse().connect(sigc::mem_fun(*this, &PanelDialog::_handleResponse));
137     _panel.signalPresent().connect(sigc::mem_fun(*this, &PanelDialog::present));
139     vbox->pack_start(_panel, true, true, 0);
141     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
143     _propagateDesktopActivated(INKSCAPE, desktop);
145     _document_replaced_connection =
146         desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialog::_propagateDocumentReplaced));
148     if (prefs_get_int_attribute ("dialogs", "showclose", 0) || !apply_label.empty()) {
149         // TODO: make the order of buttons obey the global preference
150         if (!apply_label.empty()) {
151             panel.addResponseButton(apply_label, Gtk::RESPONSE_APPLY);
152             panel.setDefaultResponse(Gtk::RESPONSE_APPLY);
153         }
154         panel.addResponseButton(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
155     }
157     show_all_children();
160 template <typename B> template <typename P>
161 PanelDialog<B> *
162 PanelDialog<B>::create()
164     Panel &panel = P::getInstance();
165     return new PanelDialog<B>(panel, panel.getPrefsPath(), panel.getVerb(), panel.getApplyLabel());
169 PanelDialog<Behavior::FloatingBehavior>::PanelDialog(Panel &panel, char const *prefs_path,
170                                                      int const verb_num, Glib::ustring const &apply_label) :
171     PanelDialogBase(panel, prefs_path, verb_num, apply_label),
172     Dialog(&Behavior::FloatingBehavior::create, prefs_path, verb_num, apply_label)
174     Gtk::VBox *vbox = get_vbox();
175     _panel.signalResponse().connect(sigc::mem_fun(*this, &PanelDialog::_handleResponse));
176     _panel.signalPresent().connect(sigc::mem_fun(*this, &PanelDialog::present));
178     vbox->pack_start(_panel, true, true, 0);
180     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
182     _propagateDesktopActivated(INKSCAPE, desktop);
184     _document_replaced_connection =
185         desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialog::_propagateDocumentReplaced));
187     if (prefs_get_int_attribute ("dialogs", "showclose", 0) || !apply_label.empty()) {
188         // TODO: make the order of buttons obey the global preference
189         if (!apply_label.empty()) {
190             panel.addResponseButton(apply_label, Gtk::RESPONSE_APPLY);
191             panel.setDefaultResponse(Gtk::RESPONSE_APPLY);
192         }
193         panel.addResponseButton(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE);
194     }
196     show_all_children();
199 /**
200  * Specialize factory method for panel dialogs with floating behavior in order to make them work as
201  * singletons, i.e. allow them track the current active desktop.
202  */
203 template <typename P>
204 PanelDialog<Behavior::FloatingBehavior> *
205 PanelDialog<Behavior::FloatingBehavior>::create()
207     Panel &panel = P::getInstance();
208     PanelDialog<Behavior::FloatingBehavior> *instance =
209         new PanelDialog<Behavior::FloatingBehavior>(panel, panel.getPrefsPath(),
210                                                     panel.getVerb(), panel.getApplyLabel());
212     g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(_handle_activate_desktop), instance);
213     g_signal_connect(G_OBJECT(INKSCAPE), "deactivate_desktop", G_CALLBACK(handle_deactivate_desktop), instance);
215     return instance;
218 } // namespace Dialog
219 } // namespace UI
220 } // namespace Inkscape
222 #endif //INKSCAPE_PANEL_DIALOG_H
224 /*
225   Local Variables:
226   mode:c++
227   c-file-style:"stroustrup"
228   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
229   indent-tabs-mode:nil
230   fill-column:99
231   End:
232 */
233 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :