Creating a new SPObject

From Inkscape Wiki
Jump to: navigation, search

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