summaryrefslogtreecommitdiff
path: root/src/model/item-data.c
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2018-07-13 06:17:58 +0000
committerRuben Undheim <ruben.undheim@gmail.com>2018-07-13 06:17:58 +0000
commit9e0bd16a997e55d6b9c2e80734ea8e61794c7602 (patch)
treed73377e0368b0c730d5a14019b1eee53897505bf /src/model/item-data.c
parente1fffcb07ce0d8b0db9e0b4b5e1e0c1128197af5 (diff)
New upstream version 0.84.22
Diffstat (limited to 'src/model/item-data.c')
-rw-r--r--src/model/item-data.c403
1 files changed, 193 insertions, 210 deletions
diff --git a/src/model/item-data.c b/src/model/item-data.c
index 382a012..c9391d4 100644
--- a/src/model/item-data.c
+++ b/src/model/item-data.c
@@ -8,12 +8,14 @@
* Ricardo Markiewicz <rmarkie@fi.uba.ar>
* Andres de Barbara <adebarbara@fi.uba.ar>
* Marc Lorber <lorber.marc@wanadoo.fr>
+ * Bernhard Schuster <bernhard@ahoi.io>
*
- * Web page: https://github.com/marc-lorber/oregano
+ * Web page: https://ahoi.io/project/oregano
*
* Copyright (C) 1999-2001 Richard Hult
* Copyright (C) 2003,2006 Ricardo Markiewicz
* Copyright (C) 2009-2012 Marc Lorber
+ * Copyright (C) 2013 Bernhard Schuster
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -27,80 +29,87 @@
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
-#include "goocanvas.h"
+#include <glib.h>
+#include <goocanvas.h>
#include "item-data.h"
#include "node-store.h"
-#define NG_DEBUG(s) if (0) g_print ("%s\n", s)
+#include "debug.h"
static void item_data_class_init (ItemDataClass *klass);
static void item_data_init (ItemData *item_data);
-static void item_data_set_gproperty (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *spec);
-static void item_data_get_gproperty (GObject *object, guint prop_id,
- GValue *value, GParamSpec *spec);
+static void item_data_set_gproperty (GObject *object, guint prop_id, const GValue *value,
+ GParamSpec *spec);
+static void item_data_get_gproperty (GObject *object, guint prop_id, GValue *value,
+ GParamSpec *spec);
static void item_data_copy (ItemData *dest, ItemData *src);
-static gboolean emit_moved_signal_when_handler_connected (gpointer data);
-enum {
- ARG_0,
- ARG_STORE,
- ARG_POS
-};
+enum { ARG_0, ARG_STORE, ARG_POS };
enum {
MOVED,
ROTATED,
FLIPPED,
+ CHANGED, // used to notify the view to reset and recalc the transformation
HIGHLIGHT,
LAST_SIGNAL
};
-struct _ItemDataPriv {
+struct _ItemDataPriv
+{
NodeStore *store;
- SheetPos pos;
- // Bounding box.
+
+ // modificator matrices
+ cairo_matrix_t translate;
+ cairo_matrix_t rotate;
+ cairo_matrix_t flip;
+
+ // Bounding box
GooCanvasBounds bounds;
};
-// Structure defined to cover exchange between g_timeout_add and the
-// function in charge to emit the moved signal only once the handler
-// has been connected.
-typedef struct {
- ItemData *item_data;
- SheetPos delta;
-} SignalStruct;
+G_DEFINE_TYPE (ItemData, item_data, G_TYPE_OBJECT);
-G_DEFINE_TYPE (ItemData, item_data, G_TYPE_OBJECT)
+static guint item_data_signals[LAST_SIGNAL] = {0};
-static guint item_data_signals [LAST_SIGNAL] = { 0 };
+static void item_data_init (ItemData *item_data)
+{
+ ItemDataPriv *priv;
+
+ priv = g_slice_new0 (ItemDataPriv);
+
+ priv->bounds.x1 = priv->bounds.x2 = priv->bounds.y1 = priv->bounds.y2 = 0;
-static void
-item_data_dispose (GObject *object)
+ cairo_matrix_init_identity (&(priv->translate));
+ cairo_matrix_init_identity (&(priv->rotate));
+ cairo_matrix_init_identity (&(priv->flip));
+
+ item_data->priv = priv;
+}
+
+static void item_data_dispose (GObject *object)
{
+ ItemDataPriv *priv = ITEM_DATA (object)->priv;
// Remove the item from the sheet node store if there.
- if (ITEM_DATA (object)->priv->store) {
+ if (priv->store) {
item_data_unregister (ITEM_DATA (object));
}
-
+ g_slice_free (ItemDataPriv, priv);
G_OBJECT_CLASS (item_data_parent_class)->dispose (object);
}
-
-static void
-item_data_finalize (GObject *object)
+static void item_data_finalize (GObject *object)
{
g_return_if_fail (object != NULL);
G_OBJECT_CLASS (item_data_parent_class)->finalize (object);
}
-static void
-item_data_class_init (ItemDataClass *klass)
+static void item_data_class_init (ItemDataClass *klass)
{
GObjectClass *object_class;
@@ -108,63 +117,41 @@ item_data_class_init (ItemDataClass *klass)
object_class = G_OBJECT_CLASS (klass);
- // This assignment must be performed before the call
+ // This assignment must be performed before the call
// to g_object_class_install_property
object_class->set_property = item_data_set_gproperty;
object_class->get_property = item_data_get_gproperty;
- g_object_class_install_property (object_class, ARG_STORE,
- g_param_spec_pointer ("store", "ItemData::store",
- "the store data", G_PARAM_READWRITE));
+ g_object_class_install_property (
+ object_class, ARG_STORE,
+ g_param_spec_pointer ("store", "ItemData::store", "the store data", G_PARAM_READWRITE));
- g_object_class_install_property (object_class, ARG_POS,
- g_param_spec_pointer ("pos", "ItemData::pos",
- "the pos data", G_PARAM_READWRITE));
+ g_object_class_install_property (
+ object_class, ARG_POS,
+ g_param_spec_pointer ("pos", "ItemData::pos", "the pos data", G_PARAM_READWRITE));
object_class->dispose = item_data_dispose;
object_class->finalize = item_data_finalize;
- item_data_signals [MOVED] = g_signal_new ("moved",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (ItemDataClass, moved),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE,
- 1,
- G_TYPE_POINTER);
-
- item_data_signals [ROTATED] = g_signal_new ("rotated",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE,
- 1,
- G_TYPE_INT);
-
- item_data_signals [FLIPPED] = g_signal_new ("flipped",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE,
- 1,
- G_TYPE_INT);
-
- item_data_signals [HIGHLIGHT] = g_signal_new ("highlight",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_FIRST,
- 0,
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
+ item_data_signals[MOVED] =
+ g_signal_new ("moved", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (ItemDataClass, moved), NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
+
+ item_data_signals[ROTATED] =
+ g_signal_new ("rotated", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST, 0, NULL,
+ NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+
+ item_data_signals[FLIPPED] =
+ g_signal_new ("flipped", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST, 0, NULL,
+ NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+
+ item_data_signals[CHANGED] =
+ g_signal_new ("changed", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST, 0, NULL,
+ NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
+ item_data_signals[HIGHLIGHT] =
+ g_signal_new ("highlight", G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_FIRST, 0, NULL,
+ NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
// Methods.
klass->clone = NULL;
@@ -173,38 +160,27 @@ item_data_class_init (ItemDataClass *klass)
klass->flip = NULL;
klass->reg = NULL;
klass->unreg = NULL;
+ klass->changed = NULL;
// Signals.
klass->moved = NULL;
}
-static void
-item_data_init (ItemData *item_data)
-{
- ItemDataPriv *priv;
-
- priv = g_new0 (ItemDataPriv, 1);
-
- priv->pos.x = 0;
- priv->pos.y = 0;
- priv->bounds.x1 = priv->bounds.x2 = priv->bounds.y1 = priv->bounds.y2 = 0;
+////////////////////////////////////////////////////////////////////////////////
+// END BOILER PLATE
+////////////////////////////////////////////////////////////////////////////////
- item_data->priv = priv;
-}
-
-ItemData *
-item_data_new (void)
+ItemData *item_data_new (void)
{
ItemData *item_data;
- item_data = ITEM_DATA (g_object_new (item_data_get_type(), NULL));
+ item_data = ITEM_DATA (g_object_new (item_data_get_type (), NULL));
return item_data;
}
-static void
-item_data_set_gproperty (GObject *object, guint prop_id, const GValue *value,
- GParamSpec *spec)
+static void item_data_set_gproperty (GObject *object, guint prop_id, const GValue *value,
+ GParamSpec *spec)
{
ItemData *item_data = ITEM_DATA (object);
@@ -213,13 +189,12 @@ item_data_set_gproperty (GObject *object, guint prop_id, const GValue *value,
item_data->priv->store = g_value_get_pointer (value);
break;
default:
- break;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (item_data, prop_id, spec);
}
}
-static void
-item_data_get_gproperty (GObject *object, guint prop_id, GValue *value,
- GParamSpec *spec)
+static void item_data_get_gproperty (GObject *object, guint prop_id, GValue *value,
+ GParamSpec *spec)
{
ItemData *item_data = ITEM_DATA (object);
@@ -232,72 +207,48 @@ item_data_get_gproperty (GObject *object, guint prop_id, GValue *value,
}
}
-void
-item_data_get_pos (ItemData *item_data, SheetPos *pos)
+/**
+ * returns the top left corner of the item
+ */
+void item_data_get_pos (ItemData *item_data, Coords *pos)
{
g_return_if_fail (item_data != NULL);
g_return_if_fail (IS_ITEM_DATA (item_data));
g_return_if_fail (pos != NULL);
-
- *pos = item_data->priv->pos;
+ ItemDataPriv *priv;
+ priv = item_data->priv;
+ pos->x = priv->translate.x0;
+ pos->y = priv->translate.y0;
}
-void
-item_data_set_pos (ItemData *item_data, SheetPos *pos)
+void item_data_set_pos (ItemData *item_data, Coords *pos)
{
ItemDataPriv *priv;
- SheetPos delta;
- SignalStruct *signal_struct;
+ gboolean handler_connected;
- g_return_if_fail (pos != NULL);
- g_return_if_fail (item_data != NULL);
+ g_return_if_fail (pos);
+ g_return_if_fail (item_data);
g_return_if_fail (IS_ITEM_DATA (item_data));
- if (pos == NULL)
- return;
-
priv = item_data->priv;
- priv->pos.x = pos->x;
- priv->pos.y = pos->y;
-
- delta.x = pos->x;
- delta.y = pos->y;
-
- signal_struct = g_new0 (SignalStruct, 1);
- signal_struct->item_data = item_data;
- signal_struct->delta = delta;
- g_timeout_add (10,
- (gpointer) emit_moved_signal_when_handler_connected,
- (gpointer) signal_struct);
-}
-static gboolean
-emit_moved_signal_when_handler_connected (gpointer data)
-{
- gboolean handler_connected;
- SignalStruct *signal_struct = (SignalStruct *) data;
- SheetPos delta;
- ItemData *item_data;
+ cairo_matrix_init_translate (&(priv->translate), pos->x, pos->y);
- item_data = signal_struct->item_data;
- delta.x = signal_struct->delta.x;
- delta.y = signal_struct->delta.y;
-
- handler_connected = g_signal_handler_is_connected (G_OBJECT (item_data),
- item_data->moved_handler_id);
+ handler_connected =
+ g_signal_handler_is_connected (G_OBJECT (item_data), item_data->moved_handler_id);
if (handler_connected) {
- g_signal_emit_by_name (G_OBJECT (item_data),
- "moved", &delta);
+ g_signal_emit_by_name (G_OBJECT (item_data), "moved", pos);
+ }
+ handler_connected =
+ g_signal_handler_is_connected (G_OBJECT (item_data), item_data->changed_handler_id);
+ if (handler_connected) {
+ g_signal_emit_by_name (G_OBJECT (item_data), "changed");
}
-
- return !handler_connected;
}
-void
-item_data_move (ItemData *item_data, SheetPos *delta)
+void item_data_move (ItemData *item_data, const Coords *delta)
{
ItemDataPriv *priv;
- SignalStruct *signal_struct;
g_return_if_fail (item_data != NULL);
g_return_if_fail (IS_ITEM_DATA (item_data));
@@ -305,22 +256,17 @@ item_data_move (ItemData *item_data, SheetPos *delta)
if (delta == NULL)
return;
+ if (fabs (delta->x) < 1e-2 && fabs (delta->y) < 1e-2)
+ return;
+
priv = item_data->priv;
- priv->pos.x += delta->x;
- priv->pos.y += delta->y;
- delta->x = priv->pos.x;
- delta->y = priv->pos.y;
-
- signal_struct = g_new0 (SignalStruct, 1);
- signal_struct->item_data = item_data;
- signal_struct->delta = (* delta);
- g_timeout_add (10,
- (gpointer) emit_moved_signal_when_handler_connected,
- (gpointer) signal_struct);
+ cairo_matrix_translate (&(priv->translate), delta->x, delta->y);
+
+ g_signal_emit_by_name (G_OBJECT (item_data), "changed");
}
-gpointer // NodeStore *
-item_data_get_store (ItemData *item_data)
+// NodeStore *
+gpointer item_data_get_store (ItemData *item_data)
{
g_return_val_if_fail (item_data != NULL, NULL);
g_return_val_if_fail (IS_ITEM_DATA (item_data), NULL);
@@ -328,8 +274,7 @@ item_data_get_store (ItemData *item_data)
return item_data->priv->store;
}
-ItemData *
-item_data_clone (ItemData *src)
+ItemData *item_data_clone (ItemData *src)
{
ItemDataClass *id_class;
@@ -343,20 +288,20 @@ item_data_clone (ItemData *src)
return id_class->clone (src);
}
-static void
-item_data_copy (ItemData *dest, ItemData *src)
+static void item_data_copy (ItemData *dest, ItemData *src)
{
g_return_if_fail (dest != NULL);
g_return_if_fail (IS_ITEM_DATA (dest));
g_return_if_fail (src != NULL);
g_return_if_fail (IS_ITEM_DATA (src));
- dest->priv->pos = src->priv->pos;
+ dest->priv->translate = src->priv->translate;
+ dest->priv->rotate = src->priv->rotate;
+ dest->priv->flip = src->priv->flip;
dest->priv->store = NULL;
}
-void
-item_data_get_relative_bbox (ItemData *data, SheetPos *p1, SheetPos *p2)
+void item_data_get_relative_bbox (ItemData *data, Coords *p1, Coords *p2)
{
g_return_if_fail (data != NULL);
g_return_if_fail (IS_ITEM_DATA (data));
@@ -372,27 +317,28 @@ item_data_get_relative_bbox (ItemData *data, SheetPos *p1, SheetPos *p2)
}
}
-void
-item_data_get_absolute_bbox (ItemData *data, SheetPos *p1, SheetPos *p2)
+void item_data_get_absolute_bbox (ItemData *data, Coords *p1, Coords *p2)
{
g_return_if_fail (data != NULL);
g_return_if_fail (IS_ITEM_DATA (data));
+ ItemDataPriv *priv;
+
item_data_get_relative_bbox (data, p1, p2);
+ priv = data->priv;
if (p1) {
- p1->x += data->priv->pos.x;
- p1->y += data->priv->pos.y;
+ p1->x += priv->translate.x0;
+ p1->y += priv->translate.y0;
}
if (p2) {
- p2->x += data->priv->pos.x;
- p2->y += data->priv->pos.y;
+ p2->x += priv->translate.x0;
+ p2->y += priv->translate.y0;
}
}
-void
-item_data_set_relative_bbox (ItemData *data, SheetPos *p1, SheetPos *p2)
+void item_data_set_relative_bbox (ItemData *data, Coords *p1, Coords *p2)
{
g_return_if_fail (data != NULL);
g_return_if_fail (IS_ITEM_DATA (data));
@@ -408,20 +354,20 @@ item_data_set_relative_bbox (ItemData *data, SheetPos *p1, SheetPos *p2)
}
}
-void
-item_data_list_get_absolute_bbox (GList *item_data_list, SheetPos *p1,
- SheetPos *p2)
+void item_data_list_get_absolute_bbox (GList *item_data_list, Coords *p1, Coords *p2)
{
- GList *list;
- SheetPos b1, b2;
+ GList *iter;
+ Coords b1, b2;
if (item_data_list == NULL)
return;
item_data_get_absolute_bbox (item_data_list->data, p1, p2);
- for (list = item_data_list; list; list = list->next) {
- item_data_get_absolute_bbox (list->data, &b1, &b2);
+ for (iter = item_data_list; iter; iter = iter->next) {
+ if (G_UNLIKELY (iter->data == NULL))
+ continue;
+ item_data_get_absolute_bbox (iter->data, &b1, &b2);
if (p1) {
p1->x = MIN (p1->x, b1.x);
@@ -433,11 +379,9 @@ item_data_list_get_absolute_bbox (GList *item_data_list, SheetPos *p1,
p2->y = MAX (p2->y, b2.y);
}
}
- g_list_free_full (list, g_object_unref);
}
-void
-item_data_rotate (ItemData *data, int angle, SheetPos *center)
+void item_data_rotate (ItemData *data, int angle, Coords *center)
{
ItemDataClass *id_class;
@@ -450,8 +394,7 @@ item_data_rotate (ItemData *data, int angle, SheetPos *center)
}
}
-void
-item_data_flip (ItemData *data, gboolean horizontal, SheetPos *center)
+void item_data_flip (ItemData *data, IDFlip direction, Coords *center)
{
ItemDataClass *id_class;
@@ -460,12 +403,11 @@ item_data_flip (ItemData *data, gboolean horizontal, SheetPos *center)
id_class = ITEM_DATA_CLASS (G_OBJECT_GET_CLASS (data));
if (id_class->flip) {
- id_class->flip (data, horizontal, center);
+ id_class->flip (data, direction, center);
}
}
-void
-item_data_unregister (ItemData *data)
+void item_data_unregister (ItemData *data)
{
ItemDataClass *id_class;
@@ -478,23 +420,21 @@ item_data_unregister (ItemData *data)
}
}
-int
-item_data_register (ItemData *data)
+gboolean item_data_register (ItemData *data)
{
ItemDataClass *id_class;
- g_return_val_if_fail (data != NULL, -1);
- g_return_val_if_fail (IS_ITEM_DATA (data), -1);
+ g_return_val_if_fail (data != NULL, FALSE);
+ g_return_val_if_fail (IS_ITEM_DATA (data), FALSE);
id_class = ITEM_DATA_CLASS (G_OBJECT_GET_CLASS (data));
if (id_class->reg) {
return id_class->reg (data);
}
- return -1;
+ return FALSE;
}
-char *
-item_data_get_refdes_prefix (ItemData *data)
+char *item_data_get_refdes_prefix (ItemData *data)
{
ItemDataClass *id_class;
@@ -509,8 +449,7 @@ item_data_get_refdes_prefix (ItemData *data)
return NULL;
}
-void
-item_data_set_property (ItemData *data, char *property, char *value)
+void item_data_set_property (ItemData *data, char *property, char *value)
{
ItemDataClass *id_class;
@@ -524,8 +463,7 @@ item_data_set_property (ItemData *data, char *property, char *value)
}
}
-gboolean
-item_data_has_properties (ItemData *data)
+gboolean item_data_has_properties (ItemData *data)
{
ItemDataClass *id_class;
@@ -539,8 +477,7 @@ item_data_has_properties (ItemData *data)
return FALSE;
}
-void
-item_data_print (ItemData *data, cairo_t *cr, SchematicPrintContext *ctx)
+void item_data_print (ItemData *data, cairo_t *cr, SchematicPrintContext *ctx)
{
ItemDataClass *id_class;
@@ -553,3 +490,49 @@ item_data_print (ItemData *data, cairo_t *cr, SchematicPrintContext *ctx)
id_class->print (data, cr, ctx);
}
}
+
+/**
+ * \brief changed, forcefully emits a changed signal to recalculate the morph
+ *matrix
+ *
+ * @param data determines which item to refresh
+ *
+ * \note this function does _not_ request a redraw
+ */
+void item_data_changed (ItemData *data)
+{
+ ItemDataClass *id_class;
+
+ g_return_if_fail (data != NULL);
+ g_return_if_fail (IS_ITEM_DATA (data));
+
+ id_class = ITEM_DATA_CLASS (G_OBJECT_GET_CLASS (data));
+ if (id_class->changed == NULL)
+ return;
+
+ return id_class->changed (data);
+}
+
+/**
+ * @param data
+ * @returns [transfer-none] pointer to cairo matrix which only includes the
+ * translation
+ */
+cairo_matrix_t *item_data_get_translate (ItemData *data)
+{
+ g_return_val_if_fail (data != NULL, NULL);
+ g_return_val_if_fail (IS_ITEM_DATA (data), NULL);
+ return &(data->priv->translate);
+}
+
+/**
+ * @param data
+ * @returns [transfer-none] pointer to cairo matrix which only includes the
+ * rotation
+ */
+cairo_matrix_t *item_data_get_rotate (ItemData *data)
+{
+ g_return_val_if_fail (data != NULL, NULL);
+ g_return_val_if_fail (IS_ITEM_DATA (data), NULL);
+ return &(data->priv->rotate);
+}