Difference between revisions of "Creating a new SPObject"
Jump to navigation
Jump to search
m (moved AddSPObject to Creating a new SPObject: kill wikiwords) |
(add changes for c++ified SPObject) |
||
Line 1: | Line 1: | ||
− | + | Create two new files in your source tree, sp-customobject.cpp and sp-customobject.h. | |
− | + | sp-customobject.h | |
+ | #ifndef SP_CUSTOMOBJECT_H_SEEN | ||
+ | #define SP_CUSTOMOBJECT_H_SEEN | ||
+ | |||
+ | /** \file | ||
+ | * Your custom object implementation | ||
+ | * | ||
+ | * Authors: | ||
+ | * You | ||
+ | * | ||
+ | * Copyright (C) You 2??? | ||
+ | * Released under GNU GPL, read the file 'COPYING' for more information | ||
+ | */ | ||
+ | |||
+ | #include "sp-object.h" | ||
+ | |||
+ | /* Skeleton base class */ | ||
+ | |||
+ | #define SP_CUSTOM_OBJECT(o) (dynamic_cast<SPCustomObject*>(o)) | ||
+ | #define SP_IS_CUSTOM_OBJECT(o) (dynamic_cast<SPCustomObject*>(o) != NULL) | ||
+ | |||
+ | class SPCustomObject : public SPObject { | ||
+ | public: | ||
+ | SPCustomObject() {} | ||
+ | virtual ~SPCustomObject() {} | ||
+ | |||
+ | // to do anything useful with your new object, you need to override the following methods: | ||
+ | virtual void build(SPDocument * doc, Inkscape::XML::Node *repr); | ||
+ | virtual void set(unsigned key, const gchar* value); | ||
+ | virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); | ||
+ | }; | ||
+ | |||
+ | |||
+ | #endif /* !SP_CUSTOMOBJECT_H_SEEN */ | ||
− | |||
− | + | Add this code into your .cpp file, which will register your SP object with the XML tree: | |
+ | namespace { | ||
+ | SPObject* createCustomObject() { | ||
+ | return new SPCustomObject(); | ||
+ | } | ||
+ | bool customObjectsRegistered = SPFactory::instance().registerObject("name_in_svg", createCustomObject); | ||
+ | } | ||
+ | (If your SPObject doesn't have a useful XML representation, you can skip this call.) | ||
+ | |||
+ | When you override build, set, or write, you need to include a call to the base class method: | ||
+ | |||
+ | void | ||
+ | SPCustomObject::build(SPDocument* doc, Inkscape::XML::Node* repr) { | ||
+ | // read in attributes from repr | ||
+ | readAttr( "inkscape:not-an-attribute" ); // this propogates up to SPObject, which calls the virtual set() method, finally calling back here | ||
+ | SPObject::build(doc, repr); | ||
+ | |||
+ | // maybe do some more stuff here | ||
+ | } | ||
+ | |||
+ | Inkscape::XML::Node* | ||
+ | SPCustomObject::write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags) { | ||
+ | // write our attributes to XML | ||
+ | |||
+ | // the repr doesn't exist, we need to create it | ||
+ | if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { | ||
+ | repr = doc->createElement("name_in_svg"); | ||
+ | } | ||
+ | |||
+ | if (flags & SP_OBJECT_WRITE_EXT) { | ||
+ | // write Inkscape-only objects here, not copied to plain SVG dump. | ||
+ | repr->setAttribute("inkscape:not-an-attribute"); | ||
+ | } | ||
+ | SPObject::write(doc, repr, flags); | ||
+ | // and possibly do anything else here | ||
+ | return repr; | ||
+ | } | ||
+ | |||
+ | void | ||
+ | SPCustomObject::set(unsigned int key, gchar const* value) { | ||
+ | // set an object from its value | ||
+ | switch (key) { | ||
+ | case SP_ATTR_INKSCAPE_CUSTOM: | ||
+ | if ((value && *value) && !strcmp(value, "true")) { | ||
+ | val = true; | ||
+ | } | ||
+ | break; | ||
+ | default: | ||
+ | SPObject::set(key, value); | ||
+ | break; | ||
+ | } | ||
+ | } |
Latest revision as of 20:40, 14 May 2014
Create two new files in your source tree, sp-customobject.cpp and sp-customobject.h.
sp-customobject.h
#ifndef SP_CUSTOMOBJECT_H_SEEN #define SP_CUSTOMOBJECT_H_SEEN /** \file * Your custom object implementation * * Authors: * You * * Copyright (C) You 2??? * Released under GNU GPL, read the file 'COPYING' for more information */ #include "sp-object.h" /* Skeleton base class */ #define SP_CUSTOM_OBJECT(o) (dynamic_cast<SPCustomObject*>(o)) #define SP_IS_CUSTOM_OBJECT(o) (dynamic_cast<SPCustomObject*>(o) != NULL) class SPCustomObject : public SPObject { public: SPCustomObject() {} virtual ~SPCustomObject() {} // to do anything useful with your new object, you need to override the following methods: virtual void build(SPDocument * doc, Inkscape::XML::Node *repr); virtual void set(unsigned key, const gchar* value); virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); }; #endif /* !SP_CUSTOMOBJECT_H_SEEN */
Add this code into your .cpp file, which will register your SP object with the XML tree:
namespace { SPObject* createCustomObject() { return new SPCustomObject(); } bool customObjectsRegistered = SPFactory::instance().registerObject("name_in_svg", createCustomObject); }
(If your SPObject doesn't have a useful XML representation, you can skip this call.)
When you override build, set, or write, you need to include a call to the base class method:
void SPCustomObject::build(SPDocument* doc, Inkscape::XML::Node* repr) { // read in attributes from repr readAttr( "inkscape:not-an-attribute" ); // this propogates up to SPObject, which calls the virtual set() method, finally calling back here SPObject::build(doc, repr); // maybe do some more stuff here }
Inkscape::XML::Node* SPCustomObject::write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags) { // write our attributes to XML // the repr doesn't exist, we need to create it if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { repr = doc->createElement("name_in_svg"); } if (flags & SP_OBJECT_WRITE_EXT) { // write Inkscape-only objects here, not copied to plain SVG dump. repr->setAttribute("inkscape:not-an-attribute"); } SPObject::write(doc, repr, flags); // and possibly do anything else here return repr; }
void SPCustomObject::set(unsigned int key, gchar const* value) { // set an object from its value switch (key) { case SP_ATTR_INKSCAPE_CUSTOM: if ((value && *value) && !strcmp(value, "true")) { val = true; } break; default: SPObject::set(key, value); break; } }