Creating a new SPObject

From Inkscape Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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;
    }
}