From b37248c6315ce652f83ce2ca885e296448d603fa Mon Sep 17 00:00:00 2001 From: buliabyak Date: Sat, 29 Apr 2006 05:58:40 +0000 Subject: [PATCH] enable the widget to listen to a repr to reflect its style --- src/ui/widget/style-swatch.cpp | 119 ++++++++++++++++++++++++++++++++- src/ui/widget/style-swatch.h | 15 ++++- 2 files changed, 132 insertions(+), 2 deletions(-) diff --git a/src/ui/widget/style-swatch.cpp b/src/ui/widget/style-swatch.cpp index 5d4623c19..023f91c55 100644 --- a/src/ui/widget/style-swatch.cpp +++ b/src/ui/widget/style-swatch.cpp @@ -23,21 +23,77 @@ #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); diff --git a/src/ui/widget/style-swatch.h b/src/ui/widget/style-swatch.h index d78b3d64e..a21d6202f 100644 --- a/src/ui/widget/style-swatch.h +++ b/src/ui/widget/style-swatch.h @@ -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]; -- 2.30.2