From 8a915294ce73ce81e8077663f5b986bb3934d12b Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Fri, 2 Apr 2010 23:08:32 -0700 Subject: [PATCH] Split dynamic desktop tracking into common, shared code. --- src/ui/dialog/Makefile_insert | 2 + src/ui/dialog/desktop-tracker.cpp | 159 ++++++++++++++++++++++++++++++ src/ui/dialog/desktop-tracker.h | 73 ++++++++++++++ src/ui/dialog/fill-and-stroke.cpp | 58 ++++------- src/ui/dialog/fill-and-stroke.h | 11 +-- src/ui/dialog/glyphs.cpp | 22 ++++- src/ui/dialog/glyphs.h | 9 +- 7 files changed, 284 insertions(+), 50 deletions(-) create mode 100644 src/ui/dialog/desktop-tracker.cpp create mode 100644 src/ui/dialog/desktop-tracker.h diff --git a/src/ui/dialog/Makefile_insert b/src/ui/dialog/Makefile_insert index 7546bc195..da9be1e7c 100644 --- a/src/ui/dialog/Makefile_insert +++ b/src/ui/dialog/Makefile_insert @@ -22,6 +22,8 @@ ink_common_sources += \ ui/dialog/color-item.h \ ui/dialog/debug.cpp \ ui/dialog/debug.h \ + ui/dialog/desktop-tracker.cpp \ + ui/dialog/desktop-tracker.h \ ui/dialog/dialog.cpp \ ui/dialog/dialog.h \ ui/dialog/dialog-manager.cpp \ diff --git a/src/ui/dialog/desktop-tracker.cpp b/src/ui/dialog/desktop-tracker.cpp new file mode 100644 index 000000000..f527f1c05 --- /dev/null +++ b/src/ui/dialog/desktop-tracker.cpp @@ -0,0 +1,159 @@ +/** + * Glyph selector dialog. + */ + +/* Authors: + * Jon A. Cruz + * + * Copyright (C) 2010 Jon A. Cruz + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "desktop-tracker.h" + +#include "inkscape.h" +#include "desktop.h" +#include "widgets/desktop-widget.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + +DesktopTracker::DesktopTracker() : + base(0), + desktop(0), + widget(0), + hierID(0), + inkID(0), + trackActive(false), + desktopChangedSig() +{ +} + +DesktopTracker::~DesktopTracker() +{ + disconnect(); +} + +void DesktopTracker::connect(GtkWidget *widget) +{ + disconnect(); + + this->widget = widget; + + // Use C/gobject callbacks to avoid gtkmm rewrap-during-destruct issues: + hierID = g_signal_connect( G_OBJECT(widget), "hierarchy-changed", G_CALLBACK(hierarchyChangeCB), this ); + inkID = g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(activateDesktopCB), this ); + + GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET); + if (wdgt && !base) { + SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt); + if (dtw && dtw->desktop) { + setBase(dtw->desktop); // may also set desktop + } + } +} + +void DesktopTracker::disconnect() +{ + if (hierID) { + if (widget) { + g_signal_handler_disconnect(G_OBJECT(widget), hierID); + } + hierID = 0; + } + if (inkID) { + if (INKSCAPE) { + g_signal_handler_disconnect(G_OBJECT(INKSCAPE), inkID); + } + inkID = 0; + } +} + +void DesktopTracker::setBase(SPDesktop *desktop) +{ + if (this->base != desktop) { + base = desktop; + // Do not override an existing target desktop + if (!this->desktop) { + setDesktop(desktop); + } + } +} + +SPDesktop *DesktopTracker::getBase() const +{ + return base; +} + +SPDesktop *DesktopTracker::getDesktop() const +{ + return desktop; +} + +sigc::connection DesktopTracker::connectDesktopChanged( const sigc::slot & slot ) +{ + return desktopChangedSig.connect(slot); +} + +gboolean DesktopTracker::activateDesktopCB(Inkscape::Application */*inkscape*/, SPDesktop *desktop, DesktopTracker *self ) +{ + if (self && self->trackActive) { + self->setDesktop(desktop); + } + return FALSE; +} + +bool DesktopTracker::hierarchyChangeCB(GtkWidget * /*widget*/, GtkWidget* /*prev*/, DesktopTracker *self) +{ + if (self) { + self->handleHierarchyChange(); + } + return false; +} + +void DesktopTracker::handleHierarchyChange() +{ + GtkWidget *wdgt = gtk_widget_get_ancestor(widget, SP_TYPE_DESKTOP_WIDGET); + bool newFlag = (wdgt == 0); // true means not in an SPDesktopWidget, thus floating. + if (wdgt && !base) { + SPDesktopWidget *dtw = SP_DESKTOP_WIDGET(wdgt); + if (dtw && dtw->desktop) { + setBase(dtw->desktop); // may also set desktop + } + } + if (newFlag != trackActive) { + trackActive = newFlag; + if (trackActive) { + setDesktop(SP_ACTIVE_DESKTOP); + } else if (desktop != base) { + setDesktop(getBase()); + } + } +} + +void DesktopTracker::setDesktop(SPDesktop *desktop) +{ + if (desktop != this->desktop) { + this->desktop = desktop; + desktopChangedSig.emit(desktop); + } +} + + +} // namespace Dialog +} // namespace UI +} // namespace Inkscape + +/* + 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:encoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/desktop-tracker.h b/src/ui/dialog/desktop-tracker.h new file mode 100644 index 000000000..7a5bc39c2 --- /dev/null +++ b/src/ui/dialog/desktop-tracker.h @@ -0,0 +1,73 @@ +/** + * Glyph selector dialog. + */ + +/* Authors: + * Jon A. Cruz + * + * Copyright (C) 2010 Jon A. Cruz + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifndef SEEN_DIALOG_DESKTOP_TRACKER +#define SEEN_DIALOG_DESKTOP_TRACKER + +#include +#include + +typedef struct _GtkWidget GtkWidget; +class SPDesktop; + +namespace Inkscape { + +class Application; + +namespace UI { +namespace Dialog { + +class DesktopTracker +{ +public: + DesktopTracker(); + virtual ~DesktopTracker(); + + void connect(GtkWidget *widget); + void disconnect(); + + SPDesktop *getDesktop() const; + + void setBase(SPDesktop *desktop); + SPDesktop *getBase() const; + + sigc::connection connectDesktopChanged( const sigc::slot & slot ); + +private: + static gboolean activateDesktopCB(Inkscape::Application *inkscape, SPDesktop *desktop, DesktopTracker *self ); + static bool hierarchyChangeCB(GtkWidget *widget, GtkWidget* prev, DesktopTracker *self); + + void handleHierarchyChange(); + void setDesktop(SPDesktop *desktop); + + SPDesktop *base; + SPDesktop *desktop; + GtkWidget *widget; + gulong hierID; + gulong inkID; + bool trackActive; + sigc::signal desktopChangedSig; +}; + +} // namespace Dialog +} // namespace UI +} // namespace Inkscape + +#endif // SEEN_DIALOG_DESKTOP_TRACKER +/* + 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:encoding=utf-8:textwidth=99 : diff --git a/src/ui/dialog/fill-and-stroke.cpp b/src/ui/dialog/fill-and-stroke.cpp index 6ee076a94..8c86e1ca4 100644 --- a/src/ui/dialog/fill-and-stroke.cpp +++ b/src/ui/dialog/fill-and-stroke.cpp @@ -43,11 +43,11 @@ FillAndStroke::FillAndStroke() _page_stroke_paint(1, 1, true, true), _page_stroke_style(1, 1, true, true), _composite_settings(SP_VERB_DIALOG_FILL_STROKE, "fillstroke", UI::Widget::SimpleFilterModifier::BLUR), - hierID(0), - trackActive(false), + deskTrack(), targetDesktop(0), fillWdgt(0), - strokeWdgt(0) + strokeWdgt(0), + desktopChangeConn() { Gtk::Box *contents = _getContents(); contents->set_spacing(0); @@ -68,59 +68,35 @@ FillAndStroke::FillAndStroke() _composite_settings.setSubject(&_subject); - // Use C/gobject callbacks to avoid gtkmm rewrap-during-destruct issues: - hierID = g_signal_connect( G_OBJECT(gobj()), "hierarchy-changed", G_CALLBACK(hierarchyChangeCB), this ); - - g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK( activateDesktopCB ), this ); + // Connect this up last + desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &FillAndStroke::setTargetDesktop) ); + deskTrack.connect(GTK_WIDGET(gobj())); } FillAndStroke::~FillAndStroke() { _composite_settings.setSubject(NULL); - if (hierID) { - g_signal_handler_disconnect(G_OBJECT(gobj()), hierID); - hierID = 0; - } -} -gboolean FillAndStroke::activateDesktopCB(Inkscape::Application */*inkscape*/, SPDesktop *desktop, FillAndStroke *self ) -{ - if (self && self->trackActive) { - self->setTargetDesktop(desktop); - } - return FALSE; -} - -bool FillAndStroke::hierarchyChangeCB(GtkWidget *widget, GtkWidget* /*prev*/, FillAndStroke *self) -{ - if (self) { - GtkWidget *ww = gtk_widget_get_ancestor(widget, SP_TYPE_VIEW_WIDGET); - bool newFlag = (ww == 0); - if (newFlag != self->trackActive) { - self->trackActive = newFlag; - if (self->trackActive) { - self->setTargetDesktop(SP_ACTIVE_DESKTOP); - } else { - self->setTargetDesktop(self->getDesktop()); - } - } - } - return false; + desktopChangeConn.disconnect(); + deskTrack.disconnect(); } void FillAndStroke::setDesktop(SPDesktop *desktop) { Panel::setDesktop(desktop); - setTargetDesktop(desktop); + deskTrack.setBase(desktop); } void FillAndStroke::setTargetDesktop(SPDesktop *desktop) { - if (fillWdgt) { - sp_fill_style_widget_set_desktop(fillWdgt, desktop); - } - if (strokeWdgt) { - sp_stroke_style_widget_set_desktop(strokeWdgt, desktop); + if (targetDesktop != desktop) { + targetDesktop = desktop; + if (fillWdgt) { + sp_fill_style_widget_set_desktop(fillWdgt, desktop); + } + if (strokeWdgt) { + sp_stroke_style_widget_set_desktop(strokeWdgt, desktop); + } } } diff --git a/src/ui/dialog/fill-and-stroke.h b/src/ui/dialog/fill-and-stroke.h index a5fe4906a..2d4e90d73 100644 --- a/src/ui/dialog/fill-and-stroke.h +++ b/src/ui/dialog/fill-and-stroke.h @@ -25,6 +25,7 @@ #include "ui/widget/panel.h" #include "ui/widget/notebook-page.h" #include "ui/widget/object-composite-settings.h" +#include "ui/dialog/desktop-tracker.h" namespace Inkscape { namespace UI { @@ -40,9 +41,6 @@ public: virtual void setDesktop(SPDesktop *desktop); - // temporary work-around until panel dialog itself tracks 'focus' properly. - virtual void setTargetDesktop(SPDesktop *desktop); - void selectionChanged(Inkscape::Application *inkscape, Inkscape::Selection *selection); @@ -71,14 +69,13 @@ private: FillAndStroke(FillAndStroke const &d); FillAndStroke& operator=(FillAndStroke const &d); - static gboolean activateDesktopCB(Inkscape::Application *inkscape, SPDesktop *desktop, FillAndStroke *self ); - static bool hierarchyChangeCB(GtkWidget *widget, GtkWidget* prev, FillAndStroke *self); + void setTargetDesktop(SPDesktop *desktop); - gulong hierID; - bool trackActive; + DesktopTracker deskTrack; SPDesktop *targetDesktop; Gtk::Widget *fillWdgt; Gtk::Widget *strokeWdgt; + sigc::connection desktopChangeConn; }; } // namespace Dialog diff --git a/src/ui/dialog/glyphs.cpp b/src/ui/dialog/glyphs.cpp index bc96b0575..c099b0718 100644 --- a/src/ui/dialog/glyphs.cpp +++ b/src/ui/dialog/glyphs.cpp @@ -32,7 +32,7 @@ namespace Inkscape { namespace UI { -namespace Dialogs { +namespace Dialog { GlyphsPanel &GlyphsPanel::getInstance() @@ -169,6 +169,8 @@ GlyphsPanel::GlyphsPanel() : scriptCombo(0), #endif // GLIB_CHECK_VERSION(2,14,0) fsel(0), + targetDesktop(0), + deskTrack(), iconActiveConn(), iconSelectConn(), scriptSelectConn() @@ -279,6 +281,10 @@ GlyphsPanel::GlyphsPanel() : show_all_children(); restorePanelPrefs(); + + // Connect this up last + desktopChangeConn = deskTrack.connectDesktopChanged( sigc::mem_fun(*this, &GlyphsPanel::setTargetDesktop) ); + deskTrack.connect(GTK_WIDGET(gobj())); } GlyphsPanel::~GlyphsPanel() @@ -286,8 +292,22 @@ GlyphsPanel::~GlyphsPanel() iconActiveConn.disconnect(); iconSelectConn.disconnect(); scriptSelectConn.disconnect(); + desktopChangeConn.disconnect(); +} + + +void GlyphsPanel::setDesktop(SPDesktop *desktop) +{ + Panel::setDesktop(desktop); + deskTrack.setBase(desktop); } +void GlyphsPanel::setTargetDesktop(SPDesktop *desktop) +{ + if (targetDesktop != desktop) { + targetDesktop = desktop; + } +} void GlyphsPanel::glyphActivated(Gtk::TreeModel::Path const & path) { diff --git a/src/ui/dialog/glyphs.h b/src/ui/dialog/glyphs.h index b4876f3c1..e41472e24 100644 --- a/src/ui/dialog/glyphs.h +++ b/src/ui/dialog/glyphs.h @@ -13,6 +13,7 @@ #include #include "ui/widget/panel.h" +#include "ui/dialog/desktop-tracker.h" namespace Gtk { @@ -32,7 +33,7 @@ namespace UI { class PreviewHolder; -namespace Dialogs { +namespace Dialog { class GlyphColumns; @@ -48,6 +49,8 @@ public: static GlyphsPanel& getInstance(); + virtual void setDesktop(SPDesktop *desktop); + protected: private: @@ -62,6 +65,7 @@ private: void glyphActivated(Gtk::TreeModel::Path const & path); void glyphSelectionChanged(); + void setTargetDesktop(SPDesktop *desktop); Glib::RefPtr store; @@ -72,9 +76,12 @@ private: Gtk::ComboBoxText *scriptCombo; #endif //GLIB_CHECK_VERSION(2,14,0) SPFontSelector *fsel; + SPDesktop *targetDesktop; + DesktopTracker deskTrack; sigc::connection iconActiveConn; sigc::connection iconSelectConn; sigc::connection scriptSelectConn; + sigc::connection desktopChangeConn; }; -- 2.30.2