Code

Purge use of SP_ACTIVE_* and encapsulate by moving 'active' desktop tracking out...
authorJon A. Cruz <jon@joncruz.org>
Mon, 29 Mar 2010 05:00:58 +0000 (22:00 -0700)
committerJon A. Cruz <jon@joncruz.org>
Mon, 29 Mar 2010 05:00:58 +0000 (22:00 -0700)
src/ui/dialog/fill-and-stroke.cpp
src/ui/dialog/fill-and-stroke.h
src/widgets/fill-n-stroke-factory.h
src/widgets/fill-style.cpp
src/widgets/fill-style.h
src/widgets/stroke-style.cpp
src/widgets/stroke-style.h

index fe63c6e24e6fd9f15e4e2ff172d019bca906e5cc..fae2e873ca947356c89b46290432fb20feb47af8 100644 (file)
@@ -6,8 +6,10 @@
 /* Authors:
  *   Bryce W. Harrington <bryce@bryceharrington.org>
  *   Gustav Broberg <broberg@kth.se>
+ *   Jon A. Cruz <jon@joncruz.org>
  *
  * Copyright (C) 2004--2007 Authors
+ * Copyright (C) 2010 Jon A. Cruz
  *
  * Released under GNU GPL.  Read the file 'COPYING' for more information.
  */
@@ -29,6 +31,8 @@
 #include "widgets/stroke-style.h"
 #include "xml/repr.h"
 
+#include "ui/view/view-widget.h"
+
 namespace Inkscape {
 namespace UI {
 namespace Dialog {
@@ -38,7 +42,12 @@ FillAndStroke::FillAndStroke()
       _page_fill(1, 1, true, true),
       _page_stroke_paint(1, 1, true, true),
       _page_stroke_style(1, 1, true, true),
-      _composite_settings(SP_VERB_DIALOG_FILL_STROKE, "fillstroke", SimpleFilterModifier::BLUR)
+      _composite_settings(SP_VERB_DIALOG_FILL_STROKE, "fillstroke", SimpleFilterModifier::BLUR),
+      hierID(0),
+      trackActive(false),
+      targetDesktop(0),
+      fillWdgt(0),
+      strokeWdgt(0)
 {
     Gtk::Box *contents = _getContents();
     contents->set_spacing(0);
@@ -58,25 +67,75 @@ FillAndStroke::FillAndStroke()
     show_all_children();
 
     _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 );
 }
 
 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;
+}
+
+void FillAndStroke::setDesktop(SPDesktop *desktop)
+{
+    Panel::setDesktop(desktop);
+    setTargetDesktop(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);
+    }
 }
 
 void
 FillAndStroke::_layoutPageFill()
 {
-    Gtk::Widget *fs = manage(Glib::wrap(sp_fill_style_widget_new()));
-    _page_fill.table().attach(*fs, 0, 1, 0, 1);
+    fillWdgt = manage(sp_fill_style_widget_new());
+    _page_fill.table().attach(*fillWdgt, 0, 1, 0, 1);
 }
 
 void
 FillAndStroke::_layoutPageStrokePaint()
 {
-    Gtk::Widget *ssp = manage(Glib::wrap(sp_stroke_style_paint_widget_new()));
-    _page_stroke_paint.table().attach(*ssp, 0, 1, 0, 1);
+    strokeWdgt = manage(sp_stroke_style_paint_widget_new());
+    _page_stroke_paint.table().attach(*strokeWdgt, 0, 1, 0, 1);
 }
 
 void
index 7dc892fea75e6d22a64ef069b1113197b917b847..f0d68ced8cbe84e459f98e8027492ea4cd04d812 100644 (file)
@@ -4,8 +4,10 @@
 /* Authors:
  *   Bryce W. Harrington <bryce@bryceharrington.org>
  *   Gustav Broberg <broberg@kth.se>
+ *   Jon A. Cruz <jon@joncruz.org>
  *
  * Copyright (C) 2004--2007 Authors
+ * Copyright (C) 2010 Jon A. Cruz
  *
  * Released under GNU GPL.  Read the file 'COPYING' for more information.
  */
@@ -37,6 +39,12 @@ public:
 
     static FillAndStroke &getInstance() { return *new FillAndStroke(); }
 
+
+    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);
 
@@ -54,7 +62,7 @@ protected:
     StyleSubject::Selection _subject;
     ObjectCompositeSettings _composite_settings;
 
-    Gtk::HBox &_createPageTabLabel(const Glib::ustring &label, 
+    Gtk::HBox &_createPageTabLabel(const Glib::ustring &label,
                                    const char *label_image);
 
     void _layoutPageFill();
@@ -64,6 +72,15 @@ protected:
 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);
+
+    gulong hierID;
+    bool trackActive;
+    SPDesktop *targetDesktop;
+    Gtk::Widget *fillWdgt;
+    Gtk::Widget *strokeWdgt;
 };
 
 } // namespace Dialog
index 14cbd6a58392a7d8166e25ec3ed0531e0e073601..74339a07f76ee03b3ad13b126538e7d222db59cc 100644 (file)
 
 #include "fill-or-stroke.h"
 
-typedef struct _GtkWidget GtkWidget;
+namespace Gtk {
+class Widget;
+}
 
 namespace Inkscape {
 namespace Widgets {
 
-GtkWidget *createStyleWidget( FillOrStroke kind );
+Gtk::Widget *createStyleWidget( FillOrStroke kind );
 
 } // namespace Widgets
 } // namespace Inkscape
index 552668a885379fabe89b0ad393b61ec509b7a625..63def4c875449cc3cad416c2cf6e7eab872d3288 100644 (file)
@@ -24,6 +24,8 @@
 #include <gtkmm/box.h>
 #include <gtk/gtkvbox.h>
 
+#include "desktop.h"
+#include "selection.h"
 #include "desktop-handles.h"
 #include "desktop-style.h"
 #include "display/sp-canvas.h"
 /* Fill */
 
 
+Gtk::Widget *sp_fill_style_widget_new(void)
+{
+    return Inkscape::Widgets::createStyleWidget( FILL );
+}
+
+
+namespace Inkscape {
 
 class FillNStroke : public Gtk::VBox
 {
@@ -58,6 +67,8 @@ public:
 
     void setFillrule( SPPaintSelector::FillRule mode );
 
+    void setDesktop(SPDesktop *desktop);
+
 private:
     static void paintModeChangeCB(SPPaintSelector *psel, SPPaintSelector::Mode mode, FillNStroke *self);
     static void paintChangedCB(SPPaintSelector *psel, FillNStroke *self);
@@ -65,8 +76,7 @@ private:
 
     static void fillruleChangedCB( SPPaintSelector *psel, SPPaintSelector::FillRule mode, FillNStroke *self );
 
-    static void selectionModifiedCB(Inkscape::Application *inkscape, Inkscape::Selection *selection, guint flags, FillNStroke *self);
-    static void selectionChangedCB(Inkscape::Application *inkscape, void * data, FillNStroke *self);
+    void selectionModifiedCB(guint flags);
 
     void dragFromPaint();
     void updateFromPaint();
@@ -74,33 +84,47 @@ private:
     void performUpdate();
 
     FillOrStroke kind;
+    SPDesktop *desktop;
     SPPaintSelector *psel;
     bool update;
     bool local;
+    sigc::connection selectChangedConn;
+    sigc::connection subselChangedConn;
+    sigc::connection selectModifiedConn;
 };
 
+} // namespace Inkscape
 
-GtkWidget *sp_fill_style_widget_new(void)
+void sp_fill_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop)
 {
-    return Inkscape::Widgets::createStyleWidget( FILL );
+    Inkscape::FillNStroke *fs = dynamic_cast<Inkscape::FillNStroke*>(widget);
+    if (fs) {
+        fs->setDesktop(desktop);
+    }
 }
 
+namespace Inkscape {
+
 /**
  * Create the fill or stroke style widget, and hook up all the signals.
  */
-GtkWidget *Inkscape::Widgets::createStyleWidget( FillOrStroke kind )
+Gtk::Widget *Inkscape::Widgets::createStyleWidget( FillOrStroke kind )
 {
-    FillNStroke *filler = Gtk::manage(new FillNStroke(kind));
+    FillNStroke *filler = new FillNStroke(kind);
 
-    return GTK_WIDGET(filler->gobj());
+    return filler;
 }
 
 FillNStroke::FillNStroke( FillOrStroke kind ) :
     Gtk::VBox(),
     kind(kind),
+    desktop(0),
     psel(0),
     update(false),
-    local(false)
+    local(false),
+    selectChangedConn(),
+    subselChangedConn(),
+    selectModifiedConn()
 {
     // Add and connect up the paint selector widget:
     psel = sp_paint_selector_new(kind);
@@ -123,58 +147,50 @@ FillNStroke::FillNStroke( FillOrStroke kind ) :
                           this );
     }
 
-    // connect to the app instance to get selection notifications.
-    // TODO FIXME should really get connected to a Desktop instead.
-    Inkscape::Application *appInstance = INKSCAPE;
-    g_signal_connect( G_OBJECT(appInstance), "modify_selection",
-                      G_CALLBACK(selectionModifiedCB),
-                      this );
-
-    g_signal_connect( G_OBJECT(appInstance), "change_selection",
-                      G_CALLBACK(selectionChangedCB),
-                      this );
-
-    g_signal_connect( G_OBJECT(appInstance), "change_subselection",
-                      G_CALLBACK(selectionChangedCB),
-                      this );
-
-
     performUpdate();
 }
 
 FillNStroke::~FillNStroke()
 {
     psel = 0;
+    selectModifiedConn.disconnect();
+    subselChangedConn.disconnect();
+    selectChangedConn.disconnect();
 }
 
 /**
  * On signal modified, invokes an update of the fill or stroke style paint object.
  */
-void FillNStroke::selectionModifiedCB( Inkscape::Application * /*inkscape*/,
-                                       Inkscape::Selection */*selection*/,
-                                       guint flags,
-                                       FillNStroke *self )
+void FillNStroke::selectionModifiedCB( guint flags )
 {
-    if (self &&
-        (flags & ( SP_OBJECT_MODIFIED_FLAG |
+    if (flags & ( SP_OBJECT_MODIFIED_FLAG |
                    SP_OBJECT_PARENT_MODIFIED_FLAG |
-                   SP_OBJECT_STYLE_MODIFIED_FLAG) ) {
+                   SP_OBJECT_STYLE_MODIFIED_FLAG) ) {
 #ifdef SP_FS_VERBOSE
-        g_message("selectionModifiedCB(%p)", self);
+        g_message("selectionModifiedCB(%d) on %p", flags, this);
 #endif
-        self->performUpdate();
+        performUpdate();
     }
 }
 
-/**
- * On signal selection changed or subselection changed, invokes an update of the fill or stroke style paint object.
- */
-void FillNStroke::selectionChangedCB( Inkscape::Application * /*inkscape*/,
-                                      void * /*data*/,
-                                      FillNStroke *self )
+void FillNStroke::setDesktop(SPDesktop *desktop)
 {
-    if (self) {
-        self->performUpdate();
+    if (this->desktop != desktop) {
+        if (this->desktop) {
+            selectModifiedConn.disconnect();
+            subselChangedConn.disconnect();
+            selectChangedConn.disconnect();
+        }
+        this->desktop = desktop;
+        if (desktop && desktop->selection) {
+            selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &FillNStroke::performUpdate)));
+            subselChangedConn = desktop->connectToolSubselectionChanged(sigc::hide(sigc::mem_fun(*this, &FillNStroke::performUpdate)));
+
+            // Must check flags, so can't call performUpdate() directly.
+            selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &FillNStroke::selectionModifiedCB)));
+
+        }
+        performUpdate();
     }
 }
 
@@ -186,7 +202,7 @@ void FillNStroke::selectionChangedCB( Inkscape::Application * /*inkscape*/,
  */
 void FillNStroke::performUpdate()
 {
-    if ( update ) {
+    if ( update || !desktop ) {
         return;
     }
 
@@ -201,10 +217,10 @@ void FillNStroke::performUpdate()
     update = true;
 
     // create temporary style
-    SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT);
+    SPStyle *query = sp_style_new(desktop->doc());
 
     // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
-    int result = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE);
+    int result = sp_desktop_query_style(desktop, query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE);
 
     SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
     SPIScale24 &targOpacity = (kind == FILL) ? query->fill_opacity : query->stroke_opacity;
@@ -298,9 +314,7 @@ void FillNStroke::fillruleChangedCB( SPPaintSelector * /*psel*/,
 
 void FillNStroke::setFillrule( SPPaintSelector::FillRule mode )
 {
-    if (!update) {
-        SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-
+    if (!update && desktop) {
         SPCSSAttr *css = sp_repr_css_attr_new();
         sp_repr_css_set_property(css, "fill-rule", (mode == SPPaintSelector::FILLRULE_EVENODD) ? "evenodd":"nonzero");
 
@@ -309,7 +323,7 @@ void FillNStroke::setFillrule( SPPaintSelector::FillRule mode )
         sp_repr_css_attr_unref(css);
         css = 0;
 
-        sp_document_done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_FILL_STROKE,
+        sp_document_done(desktop->doc(), SP_VERB_DIALOG_FILL_STROKE,
                          _("Change fill rule"));
     }
 }
@@ -342,7 +356,7 @@ void FillNStroke::paintDraggedCB(SPPaintSelector * /*psel*/, FillNStroke *self)
  */
 void FillNStroke::dragFromPaint()
 {
-    if (!INKSCAPE || update) {
+    if (!desktop || update) {
         return;
     }
 
@@ -361,8 +375,8 @@ void FillNStroke::dragFromPaint()
         case SPPaintSelector::MODE_COLOR_RGB:
         case SPPaintSelector::MODE_COLOR_CMYK:
         {
-            psel->setFlatColor( SP_ACTIVE_DESKTOP, (kind == FILL) ? "fill" : "stroke", (kind == FILL) ? "fill-opacity" : "stroke-opacity" );
-            sp_document_maybe_done(sp_desktop_document(SP_ACTIVE_DESKTOP), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE,
+            psel->setFlatColor( desktop, (kind == FILL) ? "fill" : "stroke", (kind == FILL) ? "fill-opacity" : "stroke-opacity" );
+            sp_document_maybe_done(desktop->doc(), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE,
                                    (kind == FILL) ? _("Set fill color") : _("Set stroke color"));
             if (kind == FILL) {
                 local = true; // local change, do not update from selection
@@ -397,7 +411,6 @@ void FillNStroke::paintChangedCB( SPPaintSelector * /*psel*/, FillNStroke *self
 
 void FillNStroke::updateFromPaint()
 {
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
     if (!desktop) {
         return;
     }
@@ -484,7 +497,7 @@ void FillNStroke::updateFromPaint()
                 if (!vector) {
                     /* No vector in paint selector should mean that we just changed mode */
 
-                    SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT);
+                    SPStyle *query = sp_style_new(desktop->doc());
                     int result = objects_query_fillstroke(const_cast<GSList *>(items), query, kind == FILL);
                     SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
                     guint32 common_rgb = 0;
@@ -635,6 +648,7 @@ void FillNStroke::updateFromPaint()
     update = false;
 }
 
+} // namespace Inkscape
 
 /*
   Local Variables:
index ea97bd48671dd7b1fad3a1514a675fcda77577c2..ef19d7788b6f3569be6a775fdeb37723abc073a2 100644 (file)
 #ifndef SEEN_DIALOGS_SP_FILL_STYLE_H
 #define SEEN_DIALOGS_SP_FILL_STYLE_H
 
-typedef struct _GtkWidget GtkWidget;
+namespace Gtk {
+class Widget;
+}
 
-GtkWidget *sp_fill_style_widget_new(void);
+class SPDesktop;
+
+Gtk::Widget *sp_fill_style_widget_new(void);
+
+void sp_fill_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop);
 
 #endif // SEEN_DIALOGS_SP_FILL_STYLE_H
 
index d6a38f978c6b877264525365a8fbc8bed4c6d17e..f020b0c3a16cf278e7db229095b5a42f69c9f144 100644 (file)
@@ -56,6 +56,7 @@
 #include "xml/repr.h"
 
 #include "stroke-style.h"
+#include "fill-style.h" // to get sp_fill_style_widget_set_desktop
 #include "fill-n-stroke-factory.h"
 
 /** Marker selection option menus */
@@ -72,11 +73,17 @@ static void      ink_markers_menu_update(Gtk::Container* spw, SPMarkerLoc const
 
 static Inkscape::UI::Cache::SvgPreview svg_preview_cache;
 
-GtkWidget *sp_stroke_style_paint_widget_new(void)
+Gtk::Widget *sp_stroke_style_paint_widget_new(void)
 {
     return Inkscape::Widgets::createStyleWidget( STROKE );
 }
 
+void sp_stroke_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop)
+{
+    sp_fill_style_widget_set_desktop(widget, desktop);
+}
+
+
 
 /* Line */
 
index 9ed7e2a922754b09fd04a691bf4b670b40bb476d..72dc5449a7401cbed516df473b4898c8d95cf94a 100644 (file)
 #ifndef SEEN_DIALOGS_STROKE_STYLE_H
 #define SEEN_DIALOGS_STROKE_STYLE_H
 
-#include <gtkmm/container.h>
+namespace Gtk {
+class Widget;
+class Container;
+}
 
-typedef struct _GtkWidget GtkWidget;
-
-GtkWidget *sp_stroke_style_paint_widget_new(void);
+Gtk::Widget *sp_stroke_style_paint_widget_new(void);
 Gtk::Container *sp_stroke_style_line_widget_new(void);
 
+void sp_stroke_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop);
+
 #endif // SEEN_DIALOGS_STROKE_STYLE_H
 
 /*