Code

Split dynamic desktop tracking into common, shared code.
authorJon A. Cruz <jon@joncruz.org>
Sat, 3 Apr 2010 06:08:32 +0000 (23:08 -0700)
committerJon A. Cruz <jon@joncruz.org>
Sat, 3 Apr 2010 06:08:32 +0000 (23:08 -0700)
src/ui/dialog/Makefile_insert
src/ui/dialog/desktop-tracker.cpp [new file with mode: 0644]
src/ui/dialog/desktop-tracker.h [new file with mode: 0644]
src/ui/dialog/fill-and-stroke.cpp
src/ui/dialog/fill-and-stroke.h
src/ui/dialog/glyphs.cpp
src/ui/dialog/glyphs.h

index 7546bc1959074725481795be935950be9f9b92b1..da9be1e7c4d620b3a7b796d18fe9ddf4f44be0f0 100644 (file)
@@ -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 (file)
index 0000000..f527f1c
--- /dev/null
@@ -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 <glib-object.h>
+
+#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<void, SPDesktop*> & 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 (file)
index 0000000..7a5bc39
--- /dev/null
@@ -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 <sigc++/connection.h>
+#include <glib/gtypes.h>
+
+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<void, SPDesktop*> & 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<void, SPDesktop*> 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 :
index 6ee076a940a8710fc181fff3d26481c02b84511a..8c86e1ca46afeb6f025b1d35d11a061b5574ad7b 100644 (file)
@@ -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);
+        }
     }
 }
 
index a5fe4906a7d7135748b08bc06147bdb99afa7894..2d4e90d734f40d48b0c444ee8bacfd33aa8fa624 100644 (file)
@@ -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
index bc96b05754d0173cfe25d261bcade3d191d5a8c1..c099b071899d848c1fde3ef50f27f894de481af8 100644 (file)
@@ -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)
 {
index b4876f3c16366d5bd0f0d0b9d3b7a81f794a0a09..e41472e2448968be5958bcd0a5140c2c24618d7c 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <gtkmm/treemodel.h>
 #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<Gtk::ListStore> 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;
 };