Code

enable the widget to listen to a repr to reflect its style
authorbuliabyak <buliabyak@users.sourceforge.net>
Sat, 29 Apr 2006 05:58:40 +0000 (05:58 +0000)
committerbuliabyak <buliabyak@users.sourceforge.net>
Sat, 29 Apr 2006 05:58:40 +0000 (05:58 +0000)
src/ui/widget/style-swatch.cpp
src/ui/widget/style-swatch.h

index 5d4623c194972ca60225b341651352cdd5426afd..023f91c55bef63350f2436a40dc35a1fc2a337f3 100644 (file)
 #include "sp-radial-gradient-fns.h"
 #include "sp-pattern.h"
 #include "xml/repr.h"
+#include "xml/node-event-vector.h"
 #include "widgets/widget-sizes.h"
 #include "helper/units.h"
+#include "inkscape.h"
 
 enum {
     SS_FILL,
     SS_STROKE
 };
 
+static void style_swatch_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
+                                       gchar const *old_value, gchar const *new_value,
+                                       bool is_interactive, gpointer data)
+{
+    Inkscape::UI::Widget::StyleSwatch *ss = (Inkscape::UI::Widget::StyleSwatch *) data;
+
+    if (!strcmp (name, "style")) { // FIXME: watching only for the style attr, no CSS attrs
+        SPCSSAttr *css = sp_repr_css_attr_inherited(repr, "style");
+        ss->setStyle (css);
+    }
+}
+
+
+static Inkscape::XML::NodeEventVector style_swatch_repr_events =
+{
+    NULL, /* child_added */
+    NULL, /* child_removed */
+    style_swatch_attr_changed,
+    NULL, /* content_changed */
+    NULL  /* order_changed */
+};
+
+
+static void style_swatch_tool_attr_changed(Inkscape::XML::Node *repr, gchar const *name,
+                                       gchar const *old_value, gchar const *new_value,
+                                       bool is_interactive, gpointer data)
+{
+    Inkscape::UI::Widget::StyleSwatch *ss = (Inkscape::UI::Widget::StyleSwatch *) data;
+
+    if (!strcmp (name, "usecurrent")) { // FIXME: watching only for the style attr, no CSS attrs
+        if (!strcmp (new_value, "1")) {
+            ss->setWatched (inkscape_get_repr(INKSCAPE, "desktop"));
+        } else {
+            ss->setWatched (inkscape_get_repr(INKSCAPE, ss->_tool_path));
+        }
+        // UGLY HACK: we have to reconnect to the watched tool repr again, retrieving it from the stored
+        // tool_path, because the actual repr keeps shifting with each change, no idea why
+        ss->setWatchedTool(ss->_tool_path, false); 
+    }
+}
+
+static Inkscape::XML::NodeEventVector style_swatch_tool_repr_events =
+{
+    NULL, /* child_added */
+    NULL, /* child_removed */
+    style_swatch_tool_attr_changed,
+    NULL, /* content_changed */
+    NULL  /* order_changed */
+};
 
 namespace Inkscape {
 namespace UI {
 namespace Widget {
 
 StyleSwatch::StyleSwatch(SPCSSAttr *css)
-    : _css (NULL),
+    : 
+      _tool_path(NULL),
+      _css (NULL),
+
+      _watched(NULL),
+      _watched_tool(NULL),
 
       _table(2, 6),
 
@@ -97,13 +153,74 @@ StyleSwatch::~StyleSwatch()
     for (int i = SS_FILL; i <= SS_STROKE; i++) {
         delete _color_preview[i];
     }
+
+    if (_watched) {
+        sp_repr_remove_listener_by_data(_watched, this);
+        Inkscape::GC::release(_watched);
+        _watched = NULL;
+    }
+
+    if (_watched_tool) {
+        std::cout << " =============remove\n";
+        sp_repr_remove_listener_by_data(_watched_tool, this);
+        Inkscape::GC::release(_watched_tool);
+        _watched_tool = NULL;
+        _tool_path = NULL;
+    }
+}
+
+void
+StyleSwatch::setWatched(Inkscape::XML::Node *watched)
+{
+    if (_watched) {
+        sp_repr_remove_listener_by_data(_watched, this);
+        Inkscape::GC::release(_watched);
+        _watched = NULL;
+    }
+
+    if (watched) {
+        _watched = watched;
+        Inkscape::GC::anchor(_watched);
+        sp_repr_add_listener(_watched, &style_swatch_repr_events, this);
+        sp_repr_synthesize_events(_watched, &style_swatch_repr_events, this);
+    }
+}
+
+void
+StyleSwatch::setWatchedTool(const char *path, bool synthesize)
+{
+    if (_watched_tool) {
+        sp_repr_remove_listener_by_data(_watched_tool, this);
+        Inkscape::GC::release(_watched_tool);
+        _watched_tool = NULL;
+        _tool_path = NULL;
+    }
+
+    if (path) {
+        _tool_path = (char *) path;
+        Inkscape::XML::Node *watched_tool = inkscape_get_repr(INKSCAPE, path);
+        if (watched_tool) {
+            _watched_tool = watched_tool;
+            Inkscape::GC::anchor(_watched_tool);
+            sp_repr_add_listener(_watched_tool, &style_swatch_tool_repr_events, this);
+            if (synthesize) {
+                sp_repr_synthesize_events(_watched_tool, &style_swatch_tool_repr_events, this);
+            }
+        }
+    }
+
 }
 
+
 void
 StyleSwatch::setStyle(SPCSSAttr *css)
 {
     if (_css) 
         sp_repr_css_attr_unref (_css);
+
+    if (!css)
+        return;
+
     _css = sp_repr_css_attr_new();
     sp_repr_css_merge(_css, css);
 
index d78b3d64eda16c66c450716fea73460852c39383..a21d6202fab46a1ad9fdb3cf86eafd420cb4240d 100644 (file)
@@ -28,6 +28,12 @@ class SPUnit;
 class SPStyle;
 class SPCSSAttr;
 
+namespace Inkscape {
+namespace XML {
+class Node;
+}
+}
+
 namespace Inkscape {
 namespace UI {
 namespace Widget {
@@ -35,7 +41,6 @@ namespace Widget {
 class StyleSwatch : public Gtk::HBox
 {
 public:
-    StyleSwatch (SPStyle *style);
     StyleSwatch (SPCSSAttr *attr);
 
     ~StyleSwatch();
@@ -44,9 +49,17 @@ public:
     void setStyle(SPCSSAttr *attr);
     SPCSSAttr *getStyle();
 
+    void setWatched (Inkscape::XML::Node *watched);
+    void setWatchedTool (const char *path, bool synthesize);
+
+    char *_tool_path;
+
 protected:
     SPCSSAttr *_css;
 
+    Inkscape::XML::Node *_watched;
+    Inkscape::XML::Node *_watched_tool;
+
     Gtk::Table _table;
 
     Gtk::Label _label[2];