diff --git a/src/knotholder.cpp b/src/knotholder.cpp
index 70a234260f34bb5f87bfb8217d2182eb4a7570cc..a24bb16259d0bcf2b70d7459e0f9436e67448810 100644 (file)
--- a/src/knotholder.cpp
+++ b/src/knotholder.cpp
#include "knot.h"
#include "knotholder.h"
#include "knot-holder-entity.h"
+#include "rect-context.h"
+#include "sp-rect.h"
+#include "arc-context.h"
+#include "sp-ellipse.h"
+#include "star-context.h"
+#include "sp-star.h"
+#include "spiral-context.h"
+#include "sp-spiral.h"
+#include "sp-offset.h"
+#include "box3d.h"
+
#include <libnr/nr-matrix-div.h>
+#include <glibmm/i18n.h>
class SPDesktop;
static void knot_clicked_handler (SPKnot *knot, guint state, gpointer data);
static void knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, gpointer data);
static void knot_ungrabbed_handler (SPKnot *knot, unsigned int state, SPKnotHolder *kh);
+static void sp_knot_holder_class_init(SPKnotHolderClass *klass);
+
+void sp_knot_holder_dispose(GObject *object);
#ifdef KNOT_HOLDER_DEBUG
}
#endif
+static GObjectClass *parent_class;
+
+/**
+ * Registers SPKnotHolder class and returns its type number.
+ */
+GType sp_knot_holder_get_type()
+{
+ static GType type = 0;
+ if (!type) {
+ GTypeInfo info = {
+ sizeof(SPKnotHolderClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) sp_knot_holder_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (SPKnotHolder),
+ 16, /* n_preallocs */
+ NULL,
+ NULL
+ };
+ type = g_type_register_static (G_TYPE_OBJECT, "SPKnotHolder", &info, (GTypeFlags) 0);
+ }
+ return type;
+}
+
+/**
+ * SPKnotHolder vtable initialization.
+ */
+static void sp_knot_holder_class_init(SPKnotHolderClass *klass){
+ parent_class = (GObjectClass*) g_type_class_peek_parent(klass);
+ klass->dispose = sp_knot_holder_dispose;
+}
+
SPKnotHolder *sp_knot_holder_new(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler)
{
Inkscape::XML::Node *repr = SP_OBJECT(item)->repr;
g_return_val_if_fail(item != NULL, NULL);
g_return_val_if_fail(SP_IS_ITEM(item), NULL);
- SPKnotHolder *knot_holder = g_new(SPKnotHolder, 1);
+ SPKnotHolder *knot_holder = (SPKnotHolder*)g_object_new (SP_TYPE_KNOT_HOLDER, 0);
knot_holder->desktop = desktop;
knot_holder->item = item;
g_object_ref(G_OBJECT(item));
@@ -62,22 +111,25 @@ SPKnotHolder *sp_knot_holder_new(SPDesktop *desktop, SPItem *item, SPKnotHolderR
return knot_holder;
}
-void sp_knot_holder_destroy(SPKnotHolder *kh)
-{
- if (kh) {
- g_object_unref(G_OBJECT(kh->item));
- while (kh->entity) {
- SPKnotHolderEntity *e = (SPKnotHolderEntity *) kh->entity->data;
- /* unref should call destroy */
- g_object_unref(G_OBJECT(e->knot));
- g_free(e);
- kh->entity = g_slist_remove(kh->entity, e);
- }
-
- g_free(kh);
+void sp_knot_holder_dispose(GObject *object) {
+ SPKnotHolder *kh = G_TYPE_CHECK_INSTANCE_CAST((object), SP_TYPE_KNOT_HOLDER, SPKnotHolder);
+
+ g_object_unref(G_OBJECT(kh->item));
+ while (kh->entity) {
+ SPKnotHolderEntity *e = (SPKnotHolderEntity *) kh->entity->data;
+ g_signal_handler_disconnect(e->knot, e->_click_handler_id);
+ g_signal_handler_disconnect(e->knot, e->_ungrab_handler_id);
+ /* unref should call destroy */
+ g_object_unref(e->knot);
+ g_free(e);
+ kh->entity = g_slist_remove(kh->entity, e);
}
}
+void sp_knot_holder_destroy(SPKnotHolder *kh) {
+ g_object_unref(kh);
+ }
+
void sp_knot_holder_add(
SPKnotHolder *knot_holder,
SPKnotHolderSetFunc knot_set,
NR::Point dp = e->knot_get(item) * sp_item_i2d_affine(item);
sp_knot_set_position(e->knot, &dp, SP_KNOT_STATE_NORMAL);
- e->handler_id = g_signal_connect(G_OBJECT(e->knot), "moved", G_CALLBACK(knot_moved_handler), knot_holder);
- g_signal_connect(G_OBJECT(e->knot), "clicked", G_CALLBACK(knot_clicked_handler), knot_holder);
- g_signal_connect(G_OBJECT(e->knot), "ungrabbed", G_CALLBACK(knot_ungrabbed_handler), knot_holder);
+ e->handler_id = g_signal_connect(e->knot, "moved", G_CALLBACK(knot_moved_handler), knot_holder);
+ e->_click_handler_id = g_signal_connect(e->knot, "clicked", G_CALLBACK(knot_clicked_handler), knot_holder);
+ e->_ungrab_handler_id = g_signal_connect(e->knot, "ungrabbed", G_CALLBACK(knot_ungrabbed_handler), knot_holder);
#ifdef KNOT_HOLDER_DEBUG
g_signal_connect(ob, "destroy", sp_knot_holder_debug, "SPKnotHolder::knot");
static void knotholder_update_knots(SPKnotHolder *knot_holder, SPItem *item)
{
NR::Matrix const i2d(sp_item_i2d_affine(item));
-
+
for (GSList *el = knot_holder->entity; el; el = el->next) {
SPKnotHolderEntity *e = (SPKnotHolderEntity *) el->data;
- GObject *kob = G_OBJECT(e->knot);
-
+ GObject *kob = e->knot;
+
NR::Point dp( e->knot_get(item) * i2d );
g_signal_handler_block(kob, e->handler_id);
sp_knot_set_position(e->knot, &dp, SP_KNOT_STATE_NORMAL);
SPKnotHolder *knot_holder = (SPKnotHolder *) data;
SPItem *item = SP_ITEM (knot_holder->item);
+ g_object_ref(knot_holder);
for (GSList *el = knot_holder->entity; el; el = el->next) {
SPKnotHolderEntity *e = (SPKnotHolderEntity *) el->data;
if (e->knot == knot) {
}
knotholder_update_knots(knot_holder, item);
+ g_object_unref(knot_holder);
+
+ unsigned int object_verb = SP_VERB_NONE;
+
+ if (SP_IS_RECT(item))
+ object_verb = SP_VERB_CONTEXT_RECT;
+ else if (SP_IS_3DBOX(item))
+ object_verb = SP_VERB_CONTEXT_3DBOX;
+ else if (SP_IS_GENERICELLIPSE(item))
+ object_verb = SP_VERB_CONTEXT_ARC;
+ else if (SP_IS_STAR(item))
+ object_verb = SP_VERB_CONTEXT_STAR;
+ else if (SP_IS_SPIRAL(item))
+ object_verb = SP_VERB_CONTEXT_SPIRAL;
+ else if (SP_IS_OFFSET(item)) {
+ if (SP_OFFSET(item)->sourceHref)
+ object_verb = SP_VERB_SELECTION_LINKED_OFFSET;
+ else
+ object_verb = SP_VERB_SELECTION_DYNAMIC_OFFSET;
+ }
// for drag, this is done by ungrabbed_handler, but for click we must do it here
- sp_document_done(SP_OBJECT_DOCUMENT(knot_holder->item));
+ sp_document_done(SP_OBJECT_DOCUMENT(knot_holder->item), object_verb,
+ _("Change handle"));
}
static void knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, gpointer data)
@@ -188,8 +262,8 @@ static void knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, gp
SPKnotHolder *knot_holder = (SPKnotHolder *) data;
SPItem *item = SP_ITEM (knot_holder->item);
// this was a local change and the knotholder does not need to be recreated:
- knot_holder->local_change = TRUE;
-
+ knot_holder->local_change = TRUE;
+
for (GSList *el = knot_holder->entity; el; el = el->next) {
SPKnotHolderEntity *e = (SPKnotHolderEntity *) el->data;
if (e->knot == knot) {
@@ -213,7 +287,28 @@ static void knot_ungrabbed_handler(SPKnot *knot, unsigned int state, SPKnotHolde
} else {
SPObject *object = (SPObject *) kh->item;
object->updateRepr(object->repr, SP_OBJECT_WRITE_EXT);
- sp_document_done(SP_OBJECT_DOCUMENT (object));
+
+ unsigned int object_verb = SP_VERB_NONE;
+
+ if (SP_IS_RECT(object))
+ object_verb = SP_VERB_CONTEXT_RECT;
+ else if (SP_IS_3DBOX(object))
+ object_verb = SP_VERB_CONTEXT_3DBOX;
+ else if (SP_IS_GENERICELLIPSE(object))
+ object_verb = SP_VERB_CONTEXT_ARC;
+ else if (SP_IS_STAR(object))
+ object_verb = SP_VERB_CONTEXT_STAR;
+ else if (SP_IS_SPIRAL(object))
+ object_verb = SP_VERB_CONTEXT_SPIRAL;
+ else if (SP_IS_OFFSET(object)) {
+ if (SP_OFFSET(object)->sourceHref)
+ object_verb = SP_VERB_SELECTION_LINKED_OFFSET;
+ else
+ object_verb = SP_VERB_SELECTION_DYNAMIC_OFFSET;
+ }
+
+ sp_document_done(SP_OBJECT_DOCUMENT (object), object_verb,
+ _("Move handle"));
}
}