// SPDX-License-Identifier: GPL-2.0-or-later /** @file * @brief A panel holding dialog */ /* Authors: * C 2007 Gustav Broberg * C 2012 Kris De Gussem * * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ #ifndef INKSCAPE_PANEL_DIALOG_H #define INKSCAPE_PANEL_DIALOG_H #include #include #include "verbs.h" #include "dialog.h" #include "ui/dialog/swatches.h" #include "ui/dialog/floating-behavior.h" #include "ui/dialog/dock-behavior.h" #include "inkscape.h" #include "desktop.h" namespace Inkscape { namespace UI { namespace Dialog { /** * Auxiliary class for the link between UI::Dialog::PanelDialog and UI::Dialog::Dialog. * * PanelDialog handles signals emitted when a desktop changes, either changing to a * different desktop or a new document. */ class PanelDialogBase { public: PanelDialogBase(UI::Widget::Panel &panel, char const */*prefs_path*/, int const /*verb_num*/) : _panel (panel) { } virtual void present() = 0; virtual ~PanelDialogBase() = default; virtual UI::Widget::Panel &getPanel() { return _panel; } protected: inline virtual void _propagateDocumentReplaced(SPDesktop* desktop, SPDocument *document); inline virtual void _propagateDesktopActivated(SPDesktop *); inline virtual void _propagateDesktopDeactivated(SPDesktop *); UI::Widget::Panel &_panel; sigc::connection _document_replaced_connection; }; /** * Bridges UI::Widget::Panel and UI::Dialog::Dialog. * * Where Dialog handles window behaviour, such as closing, position, etc, and where * Panel is the actual container for dialog child widgets (and from where the dialog * content is made), PanelDialog links these two classes together to create a * dockable and floatable dialog. The link with Dialog is made via PanelDialogBase. */ template class PanelDialog : public PanelDialogBase, public Inkscape::UI::Dialog::Dialog { public: /** * Constructor. * * @param contents panel with the actual dialog content. * @param prefs_path characteristic path for loading/saving dialog position. * @param verb_num the dialog verb. */ PanelDialog(UI::Widget::Panel &contents, char const *prefs_path, int const verb_num); ~PanelDialog() override = default; template static PanelDialog *create(); inline void present() override; private: template static PanelDialog *_create(); inline void _presentDialog(); PanelDialog() = delete; PanelDialog(PanelDialog const &d) = delete; // no copy PanelDialog& operator=(PanelDialog const &d) = delete; // no assign }; void PanelDialogBase::_propagateDocumentReplaced(SPDesktop *desktop, SPDocument *document) { _panel.signalDocumentReplaced().emit(desktop, document); } void PanelDialogBase::_propagateDesktopActivated(SPDesktop *desktop) { _document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialogBase::_propagateDocumentReplaced)); _panel.signalActivateDesktop().emit(desktop); } void PanelDialogBase::_propagateDesktopDeactivated(SPDesktop *desktop) { _document_replaced_connection.disconnect(); _panel.signalDeactiveDesktop().emit(desktop); } template PanelDialog::PanelDialog(Widget::Panel &panel, char const *prefs_path, int const verb_num) : PanelDialogBase(panel, prefs_path, verb_num), Dialog(&B::create, prefs_path, verb_num) { Gtk::Box *vbox = get_vbox(); _panel.signalResponse().connect(sigc::mem_fun(*this, &PanelDialog::_handleResponse)); _panel.signalPresent().connect(sigc::mem_fun(*this, &PanelDialog::_presentDialog)); vbox->pack_start(_panel, true, true, 0); SPDesktop *desktop = SP_ACTIVE_DESKTOP; _propagateDesktopActivated(desktop); _document_replaced_connection = desktop->connectDocumentReplaced(sigc::mem_fun(*this, &PanelDialog::_propagateDocumentReplaced)); show_all_children(); } template template PanelDialog *PanelDialog::create() { return _create

(); } template template PanelDialog *PanelDialog::_create() { UI::Widget::Panel &panel = P::getInstance(); return new PanelDialog(panel, panel.getPrefsPath(), panel.getVerb()); } template void PanelDialog::present() { _panel.present(); } template void PanelDialog::_presentDialog() { Dialog::present(); } template <> inline void PanelDialog::present() { Dialog::present(); _panel.present(); } template <> inline void PanelDialog::_presentDialog() { } /** * Specialized factory method for panel dialogs with floating behavior in order to make them work as * singletons, i.e. allow them track the current active desktop. */ template <> template PanelDialog *PanelDialog::create() { auto instance = _create

(); INKSCAPE.signal_activate_desktop.connect( sigc::mem_fun(*instance, &PanelDialog::_propagateDesktopActivated) ); INKSCAPE.signal_deactivate_desktop.connect( sigc::mem_fun(*instance, &PanelDialog::_propagateDesktopDeactivated) ); return instance; } } // namespace Dialog } // namespace UI } // namespace Inkscape #endif //INKSCAPE_PANEL_DIALOG_H /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :