Code

Add two files that were forgotten in last commit
authorjohanengelen <johanengelen@users.sourceforge.net>
Fri, 28 Mar 2008 19:31:06 +0000 (19:31 +0000)
committerjohanengelen <johanengelen@users.sourceforge.net>
Fri, 28 Mar 2008 19:31:06 +0000 (19:31 +0000)
src/sp-lpe-item.cpp [new file with mode: 0644]
src/sp-lpe-item.h [new file with mode: 0644]

diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp
new file mode 100644 (file)
index 0000000..373d641
--- /dev/null
@@ -0,0 +1,451 @@
+#define __SP_LPE_ITEM_CPP__\r
+\r
+/** \file\r
+ * Base class for live path effect items\r
+ */\r
+/*\r
+ * Authors:\r
+ *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>\r
+ *   Bastien Bouclet <bgkweb@gmail.com>\r
+ *\r
+ * Copyright (C) 2008 authors\r
+ *\r
+ * Released under GNU GPL, read the file 'COPYING' for more information\r
+ */\r
+\r
+#ifdef HAVE_CONFIG_H\r
+# include "config.h"\r
+#endif\r
+\r
+#include "live_effects/effect.h"\r
+#include "live_effects/lpeobject.h"\r
+#include "live_effects/lpeobject-reference.h"\r
+\r
+#include "sp-path.h"\r
+#include "sp-item-group.h"\r
+#include "macros.h"\r
+#include "attributes.h"\r
+#include "sp-lpe-item.h"\r
+#include "xml/repr.h"\r
+#include "uri.h"\r
+\r
+/* LPEItem base class */\r
+\r
+static void sp_lpe_item_class_init(SPLPEItemClass *klass);\r
+static void sp_lpe_item_init(SPLPEItem *lpe_item);\r
+static void sp_lpe_item_finalize(GObject *object);\r
+\r
+static void sp_lpe_item_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);\r
+static void sp_lpe_item_release(SPObject *object);\r
+static void sp_lpe_item_set(SPObject *object, unsigned int key, gchar const *value);\r
+static void sp_lpe_item_update(SPObject *object, SPCtx *ctx, guint flags);\r
+static void sp_lpe_item_modified (SPObject *object, unsigned int flags);\r
+static Inkscape::XML::Node *sp_lpe_item_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);\r
+\r
+static void sp_lpe_item_child_added (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * ref);\r
+static void sp_lpe_item_remove_child (SPObject * object, Inkscape::XML::Node * child);\r
+\r
+static void lpeobject_ref_changed(SPObject *old_ref, SPObject *ref, SPLPEItem *lpeitem);\r
+static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem);\r
+\r
+static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem);\r
+static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem);\r
+\r
+static SPItemClass *parent_class;\r
+\r
+GType\r
+sp_lpe_item_get_type()\r
+{\r
+    static GType lpe_item_type = 0;\r
+\r
+    if (!lpe_item_type) {\r
+        GTypeInfo lpe_item_info = {\r
+            sizeof(SPLPEItemClass),\r
+            NULL, NULL,\r
+            (GClassInitFunc) sp_lpe_item_class_init,\r
+            NULL, NULL,\r
+            sizeof(SPLPEItem),\r
+            16,\r
+            (GInstanceInitFunc) sp_lpe_item_init,\r
+            NULL,    /* value_table */\r
+        };\r
+        lpe_item_type = g_type_register_static(SP_TYPE_ITEM, "SPLPEItem", &lpe_item_info, (GTypeFlags)0);\r
+    }\r
+    return lpe_item_type;\r
+}\r
+\r
+static void\r
+sp_lpe_item_class_init(SPLPEItemClass *klass)\r
+{    \r
+    GObjectClass *gobject_class;\r
+    SPObjectClass *sp_object_class;\r
+\r
+    gobject_class = (GObjectClass *) klass;\r
+    sp_object_class = (SPObjectClass *) klass;\r
+    parent_class = (SPItemClass *)g_type_class_peek_parent (klass);\r
+\r
+    gobject_class->finalize = sp_lpe_item_finalize;\r
+\r
+    sp_object_class->build = sp_lpe_item_build;\r
+    sp_object_class->release = sp_lpe_item_release;\r
+    sp_object_class->set = sp_lpe_item_set;\r
+    sp_object_class->update = sp_lpe_item_update;\r
+    sp_object_class->modified = sp_lpe_item_modified;\r
+    sp_object_class->write = sp_lpe_item_write;\r
+    sp_object_class->child_added = sp_lpe_item_child_added;\r
+    sp_object_class->remove_child = sp_lpe_item_remove_child;\r
+    \r
+    klass->update_patheffect = NULL;\r
+}\r
+\r
+static void\r
+sp_lpe_item_init(SPLPEItem *lpeitem)\r
+{\r
+    lpeitem->path_effect_ref  = new Inkscape::LivePathEffect::LPEObjectReference(SP_OBJECT(lpeitem));\r
+    new (&lpeitem->lpe_modified_connection) sigc::connection();\r
+}\r
+\r
+static void\r
+sp_lpe_item_finalize(GObject *object)\r
+{\r
+    if (((GObjectClass *) (parent_class))->finalize) {\r
+        (* ((GObjectClass *) (parent_class))->finalize)(object);\r
+    }\r
+}\r
+\r
+/**\r
+ * Reads the Inkscape::XML::Node, and initializes SPLPEItem variables.  For this to get called,\r
+ * our name must be associated with a repr via "sp_object_type_register".  Best done through\r
+ * sp-object-repr.cpp's repr_name_entries array.\r
+ */\r
+static void\r
+sp_lpe_item_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)\r
+{\r
+    SP_LPE_ITEM(object)->path_effect_ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(lpeobject_ref_changed), SP_LPE_ITEM(object)));\r
+\r
+    sp_object_read_attr(object, "inkscape:path-effect");\r
+    \r
+    if (((SPObjectClass *) parent_class)->build) {\r
+        ((SPObjectClass *) parent_class)->build(object, document, repr);\r
+    }\r
+}\r
+\r
+/**\r
+ * Drops any allocated memory.\r
+ */\r
+static void\r
+sp_lpe_item_release(SPObject *object)\r
+{\r
+    SPLPEItem *lpeitem;\r
+    lpeitem = (SPLPEItem *) object;\r
+\r
+    lpeitem->path_effect_ref->detach();\r
+\r
+    lpeitem->lpe_modified_connection.disconnect();\r
+    lpeitem->lpe_modified_connection.~connection();\r
+\r
+    if (((SPObjectClass *) parent_class)->release)\r
+        ((SPObjectClass *) parent_class)->release(object);\r
+}\r
+\r
+/**\r
+ * Sets a specific value in the SPLPEItem.\r
+ */\r
+static void\r
+sp_lpe_item_set(SPObject *object, unsigned int key, gchar const *value)\r
+{\r
+    SPLPEItem *lpeitem = (SPLPEItem *) object;\r
+\r
+    switch (key) {\r
+        case SP_ATTR_INKSCAPE_PATH_EFFECT:\r
+            if ( value && lpeitem->path_effect_ref->lpeobject_href \r
+                    && ( strcmp(value, lpeitem->path_effect_ref->lpeobject_href) == 0 ) ) {\r
+                /* No change, do nothing. */\r
+            } else {\r
+                if (value) {\r
+                    // Now do the attaching, which emits the changed signal.\r
+                    try {\r
+                        lpeitem->path_effect_ref->link((gchar*)value);\r
+                    } catch (Inkscape::BadURIException &e) {\r
+                        g_warning("%s", e.what());\r
+                        lpeitem->path_effect_ref->detach();\r
+                    }\r
+                } else {\r
+                    // Detach, which emits the changed signal.\r
+                    lpeitem->path_effect_ref->detach();\r
+                }\r
+            }\r
+            break;\r
+        default:\r
+            if (((SPObjectClass *) parent_class)->set) {\r
+                ((SPObjectClass *) parent_class)->set(object, key, value);\r
+            }\r
+            break;\r
+    }\r
+}\r
+\r
+/**\r
+ * Receives update notifications.\r
+ */\r
+static void\r
+sp_lpe_item_update(SPObject *object, SPCtx *ctx, guint flags)\r
+{\r
+    if (((SPObjectClass *) parent_class)->update) {\r
+        ((SPObjectClass *) parent_class)->update(object, ctx, flags);\r
+    }\r
+}\r
+\r
+/**\r
+ * Sets modified flag for all sub-item views.\r
+ */\r
+static void\r
+sp_lpe_item_modified (SPObject *object, unsigned int flags)\r
+{\r
+       if (((SPObjectClass *) (parent_class))->modified) {\r
+         (* ((SPObjectClass *) (parent_class))->modified) (object, flags);\r
+       }\r
+}\r
+\r
+/**\r
+ * Writes its settings to an incoming repr object, if any.\r
+ */\r
+static Inkscape::XML::Node *\r
+sp_lpe_item_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)\r
+{\r
+    SPLPEItem *lpeitem = (SPLPEItem *) object;\r
+\r
+    if ( sp_lpe_item_has_path_effect(lpeitem) ) {\r
+        repr->setAttribute("inkscape:path-effect", lpeitem->path_effect_ref->lpeobject_href);\r
+    } else {\r
+        repr->setAttribute("inkscape:path-effect", NULL);\r
+    }\r
+\r
+    if (((SPObjectClass *)(parent_class))->write) {\r
+        ((SPObjectClass *)(parent_class))->write(object, repr, flags);\r
+    }\r
+\r
+    return repr;\r
+}\r
+\r
+\r
+LivePathEffectObject *\r
+sp_lpe_item_get_livepatheffectobject(SPLPEItem *lpeitem) {\r
+    if (!lpeitem) return NULL;\r
+\r
+    if (sp_lpe_item_has_path_effect(lpeitem)) {\r
+        return lpeitem->path_effect_ref->lpeobject;\r
+    } else {\r
+        return NULL;\r
+    }\r
+}\r
+\r
+Inkscape::LivePathEffect::Effect *\r
+sp_lpe_item_get_livepatheffect(SPLPEItem *lpeitem) {\r
+    if (!lpeitem) return NULL;\r
+\r
+    LivePathEffectObject * lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);\r
+    if (lpeobj)\r
+        return lpeobj->lpe;\r
+    else\r
+        return NULL;\r
+}\r
+\r
+void sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve) {\r
+    if (!lpeitem) return;\r
+    if (!curve) return;\r
+\r
+    if (sp_lpe_item_has_path_effect(lpeitem)) {\r
+        LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);\r
+        lpeobj->lpe->doEffect(curve);\r
+    }\r
+    \r
+    SPObject *parent = lpeitem->parent;\r
+    if (parent && SP_IS_LPE_ITEM(parent))\r
+        sp_lpe_item_perform_path_effect(SP_LPE_ITEM(parent), curve);\r
+}\r
+\r
+/**\r
+ * Calls any registered handlers for the update_patheffect action\r
+ */\r
+void\r
+sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool write)\r
+{\r
+#ifdef SHAPE_VERBOSE\r
+    g_message("sp_lpe_item_update_patheffect: %p\n", lpeitem);\r
+#endif\r
+    g_return_if_fail (lpeitem != NULL);\r
+    g_return_if_fail (SP_IS_LPE_ITEM (lpeitem));\r
+\r
+    if (sp_lpe_item_has_path_effect(lpeitem)) {\r
+        LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);\r
+        lpeobj->lpe->doBeforeEffect(lpeitem);\r
+    }\r
+\r
+    if (SP_LPE_ITEM_CLASS (G_OBJECT_GET_CLASS (lpeitem))->update_patheffect) {\r
+        SP_LPE_ITEM_CLASS (G_OBJECT_GET_CLASS (lpeitem))->update_patheffect (lpeitem, write);\r
+    }\r
+}\r
+\r
+/**\r
+ * Gets called when (re)attached to another lpeobject.\r
+ */\r
+static void\r
+lpeobject_ref_changed(SPObject *old_ref, SPObject *ref, SPLPEItem *lpeitem)\r
+{\r
+    if (old_ref) {\r
+        sp_signal_disconnect_by_data(old_ref, lpeitem);\r
+    }\r
+    if ( IS_LIVEPATHEFFECT(ref) && ref != lpeitem )\r
+    {\r
+        lpeitem->lpe_modified_connection.disconnect();\r
+        lpeitem->lpe_modified_connection = ref->connectModified(sigc::bind(sigc::ptr_fun(&lpeobject_ref_modified), lpeitem));\r
+        lpeobject_ref_modified(ref, 0, lpeitem);\r
+    }\r
+}\r
+\r
+/**\r
+ * Gets called when lpeobject repr contents change: i.e. parameter change.\r
+ */\r
+static void\r
+lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPLPEItem *lpeitem)\r
+{\r
+    sp_lpe_item_update_patheffect (lpeitem, true);\r
+}\r
+\r
+static void\r
+sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem)\r
+{\r
+    if (SP_IS_GROUP(lpeitem)) {\r
+        GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem));\r
+        for ( GSList const *iter = item_list; iter; iter = iter->next ) {\r
+            SPObject *subitem = static_cast<SPObject *>(iter->data);\r
+            if (SP_IS_LPE_ITEM(subitem)) {\r
+                sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(subitem));\r
+            }\r
+        }\r
+    }\r
+    else if (SP_IS_PATH(lpeitem)) {\r
+        Inkscape::XML::Node *pathrepr = SP_OBJECT_REPR(lpeitem);\r
+        if ( !pathrepr->attribute("inkscape:original-d") ) {\r
+            pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d"));\r
+        }\r
+    }\r
+}\r
+\r
+static void\r
+sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem)\r
+{\r
+    if (SP_IS_GROUP(lpeitem)) {\r
+        GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem));\r
+        for ( GSList const *iter = item_list; iter; iter = iter->next ) {\r
+            SPObject *subitem = static_cast<SPObject *>(iter->data);\r
+            if (SP_IS_LPE_ITEM(subitem)) {\r
+                sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem));\r
+            }\r
+        }\r
+    }\r
+    else if (SP_IS_PATH(lpeitem)) {\r
+        Inkscape::XML::Node *repr = SP_OBJECT_REPR(lpeitem);\r
+        if (!sp_lpe_item_has_path_effect_recursive(lpeitem) \r
+                && repr->attribute("inkscape:original-d")) {\r
+            repr->setAttribute("d", repr->attribute("inkscape:original-d"));\r
+            repr->setAttribute("inkscape:original-d", NULL);\r
+        }\r
+        else {\r
+            sp_lpe_item_update_patheffect(lpeitem, true);\r
+        }\r
+    }\r
+}\r
+\r
+void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, gchar *value)\r
+{\r
+    if (!value) {\r
+        sp_lpe_item_remove_path_effect(lpeitem, false);\r
+    } else {\r
+        SP_OBJECT_REPR(lpeitem)->setAttribute("inkscape:path-effect", value);\r
+        \r
+        // make sure there is an original-d for paths!!!\r
+        sp_lpe_item_create_original_path_recursive(lpeitem);\r
+    }\r
+}\r
+\r
+void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * new_lpeobj)\r
+{\r
+    const gchar * repr_id = SP_OBJECT_REPR(new_lpeobj)->attribute("id");\r
+    gchar *hrefstr = g_strdup_printf("#%s", repr_id);\r
+    sp_lpe_item_set_path_effect(lpeitem, hrefstr);\r
+    g_free(hrefstr);\r
+}\r
+\r
+void sp_lpe_item_remove_path_effect(SPLPEItem *lpeitem, bool keep_paths)\r
+{\r
+    Inkscape::XML::Node *repr = SP_OBJECT_REPR(lpeitem);\r
+    repr->setAttribute("inkscape:path-effect", NULL);\r
+    \r
+    if (!keep_paths) {\r
+        sp_lpe_item_cleanup_original_path_recursive(lpeitem);\r
+    }\r
+}\r
+\r
+bool sp_lpe_item_has_path_effect(SPLPEItem *lpeitem)\r
+{\r
+    return lpeitem->path_effect_ref && lpeitem->path_effect_ref->lpeobject;\r
+}\r
+\r
+bool sp_lpe_item_has_path_effect_recursive(SPLPEItem *lpeitem)\r
+{\r
+    SPObject *parent = lpeitem->parent;\r
+    if (parent && SP_IS_LPE_ITEM(parent)) {\r
+        return sp_lpe_item_has_path_effect(lpeitem) || sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(parent));\r
+    }\r
+    else {\r
+        return sp_lpe_item_has_path_effect(lpeitem);\r
+    }\r
+}\r
+\r
+void sp_lpe_item_edit_next_param_oncanvas(SPLPEItem *lpeitem, SPDesktop *dt)\r
+{\r
+    LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);\r
+    if (lpeobj && lpeobj->lpe) {\r
+        lpeobj->lpe->editNextParamOncanvas(SP_ITEM(lpeitem), dt);\r
+    }\r
+}\r
+\r
+static void\r
+sp_lpe_item_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)\r
+{\r
+    if (((SPObjectClass *) (parent_class))->child_added)\r
+        (* ((SPObjectClass *) (parent_class))->child_added) (object, child, ref);\r
+        \r
+    if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) {\r
+        SPObject *ochild = sp_object_get_child_by_repr(object, child);\r
+        if ( ochild && SP_IS_LPE_ITEM(ochild) ) {\r
+            sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(ochild));\r
+        }\r
+    }\r
+}\r
+\r
+static void\r
+sp_lpe_item_remove_child (SPObject * object, Inkscape::XML::Node * child)\r
+{\r
+    if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) {\r
+        SPObject *ochild = sp_object_get_child_by_repr(object, child);\r
+        if ( ochild && SP_IS_LPE_ITEM(ochild) ) {\r
+            sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(ochild));\r
+        }\r
+    }\r
+\r
+    if (((SPObjectClass *) (parent_class))->remove_child)\r
+        (* ((SPObjectClass *) (parent_class))->remove_child) (object, child);\r
+}\r
+\r
+/*\r
+  Local Variables:\r
+  mode:c++\r
+  c-file-style:"stroustrup"\r
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+  indent-tabs-mode:nil\r
+  fill-column:99\r
+  End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r
diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h
new file mode 100644 (file)
index 0000000..a818eeb
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef SP_LPE_ITEM_H_SEEN\r
+#define SP_LPE_ITEM_H_SEEN\r
+\r
+/** \file\r
+ * Base class for live path effect items\r
+ */\r
+/*\r
+ * Authors:\r
+ *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>\r
+ *   Bastien Bouclet <bgkweb@gmail.com>\r
+ *\r
+ * Copyright (C) 2008 authors\r
+ *\r
+ * Released under GNU GPL, read the file 'COPYING' for more information\r
+ */\r
+\r
+#include "sp-item.h"\r
+#include "display/curve.h"\r
+\r
+#define SP_TYPE_LPE_ITEM (sp_lpe_item_get_type())\r
+#define SP_LPE_ITEM(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_LPE_ITEM, SPLPEItem))\r
+#define SP_LPE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_LPE_ITEM, SPLPEItemClass))\r
+#define SP_IS_LPE_ITEM(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_LPE_ITEM))\r
+#define SP_IS_LPE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_LPE_ITEM))\r
+\r
+struct LivePathEffectObject;\r
+namespace Inkscape{ \r
+namespace LivePathEffect{\r
+    class LPEObjectReference;\r
+    class Effect;\r
+};\r
+};\r
+\r
+struct SPLPEItem : public SPItem {\r
+    Inkscape::LivePathEffect::LPEObjectReference *path_effect_ref;\r
+    sigc::connection lpe_modified_connection;\r
+};\r
+\r
+struct SPLPEItemClass {\r
+    SPItemClass parent_class;\r
+\r
+    void (* update_patheffect) (SPLPEItem *lpeitem, bool write);\r
+};\r
+\r
+GType sp_lpe_item_get_type();\r
+\r
+LivePathEffectObject * sp_lpe_item_get_livepatheffectobject(SPLPEItem *lpeitem);\r
+Inkscape::LivePathEffect::Effect * sp_lpe_item_get_livepatheffect(SPLPEItem *lpeitem);\r
+void sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool write);\r
+void sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve);\r
+void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, gchar *value);\r
+void sp_lpe_item_set_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * new_lpeobj);\r
+void sp_lpe_item_remove_path_effect(SPLPEItem *lpeitem, bool keep_paths);\r
+bool sp_lpe_item_has_path_effect(SPLPEItem *lpeitem);\r
+bool sp_lpe_item_has_path_effect_recursive(SPLPEItem *lpeitem);\r
+void sp_lpe_item_edit_next_param_oncanvas(SPLPEItem *lpeitem, SPDesktop *dt);\r
+\r
+#endif /* !SP_LPE_ITEM_H_SEEN */\r
+\r
+/*\r
+  Local Variables:\r
+  mode:c++\r
+  c-file-style:"stroustrup"\r
+  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+  indent-tabs-mode:nil\r
+  fill-column:99\r
+  End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :\r