Introduce LdDiagramConnection.
This commit is contained in:
parent
539f537846
commit
2744d84896
@ -114,6 +114,7 @@ set (liblogdiag_SOURCES
|
||||
liblogdiag/ld-diagram.c
|
||||
liblogdiag/ld-diagram-object.c
|
||||
liblogdiag/ld-diagram-symbol.c
|
||||
liblogdiag/ld-diagram-connection.c
|
||||
liblogdiag/ld-canvas.c
|
||||
liblogdiag/ld-library.c
|
||||
liblogdiag/ld-library-toolbar.c
|
||||
@ -130,6 +131,7 @@ set (liblogdiag_HEADERS
|
||||
liblogdiag/ld-diagram.h
|
||||
liblogdiag/ld-diagram-object.h
|
||||
liblogdiag/ld-diagram-symbol.h
|
||||
liblogdiag/ld-diagram-connection.h
|
||||
liblogdiag/ld-canvas.h
|
||||
liblogdiag/ld-library.h
|
||||
liblogdiag/ld-library-toolbar.h
|
||||
|
@ -50,5 +50,12 @@
|
||||
#endif
|
||||
#endif /* ! HAVE_SANE___RESTRICT */
|
||||
|
||||
/* We have to remove nodes first due to a bug in json-glib. */
|
||||
#define json_object_set_member(object, name, node) \
|
||||
G_STMT_START { \
|
||||
json_object_remove_member ((object), (name)); \
|
||||
json_object_set_member ((object), (name), (node)); \
|
||||
} G_STMT_END
|
||||
|
||||
#endif /* __CONFIG_H__ */
|
||||
|
||||
|
333
liblogdiag/ld-diagram-connection.c
Normal file
333
liblogdiag/ld-diagram-connection.c
Normal file
@ -0,0 +1,333 @@
|
||||
/*
|
||||
* ld-diagram-connection.c
|
||||
*
|
||||
* This file is a part of logdiag.
|
||||
* Copyright Přemysl Janouch 2011. All rights reserved.
|
||||
*
|
||||
* See the file LICENSE for licensing information.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "liblogdiag.h"
|
||||
#include "config.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION:ld-diagram-connection
|
||||
* @short_description: A connection object
|
||||
* @see_also: #LdDiagramObject
|
||||
*
|
||||
* #LdDiagramConnection is an implementation of #LdDiagramObject.
|
||||
*/
|
||||
|
||||
typedef struct _SetPointsActionData SetPointsActionData;
|
||||
|
||||
/*
|
||||
* SetPointsActionData:
|
||||
* @self: the object this action has happened on.
|
||||
* @old_node: the old node.
|
||||
* @new_node: the new node.
|
||||
*/
|
||||
struct _SetPointsActionData
|
||||
{
|
||||
LdDiagramConnection *self;
|
||||
JsonNode *old_node;
|
||||
JsonNode *new_node;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_POINTS
|
||||
};
|
||||
|
||||
static void ld_diagram_connection_get_property (GObject *object,
|
||||
guint property_id, GValue *value, GParamSpec *pspec);
|
||||
static void ld_diagram_connection_set_property (GObject *object,
|
||||
guint property_id, const GValue *value, GParamSpec *pspec);
|
||||
|
||||
static gboolean read_point_node (JsonNode *node, LdPoint *point);
|
||||
static gboolean read_double_node (JsonNode *node, gdouble *value);
|
||||
|
||||
static void on_set_points_undo (gpointer user_data);
|
||||
static void on_set_points_redo (gpointer user_data);
|
||||
static void on_set_points_destroy (gpointer user_data);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (LdDiagramConnection, ld_diagram_connection,
|
||||
LD_TYPE_DIAGRAM_OBJECT);
|
||||
|
||||
static void
|
||||
ld_diagram_connection_class_init (LdDiagramConnectionClass *klass)
|
||||
{
|
||||
GObjectClass *object_class;
|
||||
GParamSpec *pspec;
|
||||
|
||||
object_class = G_OBJECT_CLASS (klass);
|
||||
object_class->get_property = ld_diagram_connection_get_property;
|
||||
object_class->set_property = ld_diagram_connection_set_property;
|
||||
|
||||
/**
|
||||
* LdDiagramConnection:points:
|
||||
*
|
||||
* Points defining this connection.
|
||||
*/
|
||||
pspec = g_param_spec_boxed ("points", "Points",
|
||||
"Points defining this connection.",
|
||||
LD_TYPE_POINT_ARRAY, G_PARAM_READWRITE);
|
||||
g_object_class_install_property (object_class, PROP_POINTS, pspec);
|
||||
}
|
||||
|
||||
static void
|
||||
ld_diagram_connection_init (LdDiagramConnection *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
ld_diagram_connection_get_property (GObject *object, guint property_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
LdDiagramConnection *self;
|
||||
|
||||
self = LD_DIAGRAM_CONNECTION (object);
|
||||
switch (property_id)
|
||||
{
|
||||
LdPointArray *points;
|
||||
|
||||
case PROP_POINTS:
|
||||
points = ld_diagram_connection_get_points (self);
|
||||
g_value_set_boxed_take_ownership (value, points);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ld_diagram_connection_set_property (GObject *object, guint property_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
LdDiagramConnection *self;
|
||||
|
||||
self = LD_DIAGRAM_CONNECTION (object);
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_POINTS:
|
||||
ld_diagram_connection_set_points (self, g_value_get_boxed (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ld_diagram_connection_new:
|
||||
* @storage: a storage backend.
|
||||
*
|
||||
* Return value: a new #LdDiagramConnection object.
|
||||
*/
|
||||
LdDiagramConnection *
|
||||
ld_diagram_connection_new (JsonObject *storage)
|
||||
{
|
||||
LdDiagramConnection *self;
|
||||
|
||||
self = g_object_new (LD_TYPE_DIAGRAM_CONNECTION, "storage", storage, NULL);
|
||||
return self;
|
||||
}
|
||||
|
||||
#define WARN_NODE_TYPE(node, type) \
|
||||
G_STMT_START { \
|
||||
g_warning ("%s: unable to read a value of type `%s' from node" \
|
||||
" of type `%s'", G_STRLOC, g_type_name (type), \
|
||||
json_node_type_name (node)); \
|
||||
} G_STMT_END
|
||||
|
||||
/**
|
||||
* ld_diagram_connection_get_points:
|
||||
* @self: an #LdDiagramConnection object.
|
||||
*
|
||||
* Get points defining this connection. Coordinates of the points are relative
|
||||
* to the inherited #LdDiagramObject:x and #LdDiagramObject:y properties.
|
||||
*
|
||||
* Return value: (transfer full): a point array.
|
||||
*/
|
||||
LdPointArray *
|
||||
ld_diagram_connection_get_points (LdDiagramConnection *self)
|
||||
{
|
||||
LdPointArray *points;
|
||||
JsonObject *storage;
|
||||
JsonNode *node;
|
||||
JsonArray *array;
|
||||
GList *point_node_list, *iter;
|
||||
|
||||
g_return_val_if_fail (LD_IS_DIAGRAM_CONNECTION (self), NULL);
|
||||
|
||||
storage = ld_diagram_object_get_storage (LD_DIAGRAM_OBJECT (self));
|
||||
node = json_object_get_member (storage, "points");
|
||||
if (!node || json_node_is_null (node))
|
||||
return ld_point_array_new (0);
|
||||
if (!JSON_NODE_HOLDS_ARRAY (node))
|
||||
{
|
||||
WARN_NODE_TYPE (node, LD_TYPE_POINT_ARRAY);
|
||||
return ld_point_array_new (0);
|
||||
}
|
||||
|
||||
array = json_node_get_array (node);
|
||||
point_node_list = json_array_get_elements (array);
|
||||
points = ld_point_array_new (json_array_get_length (array));
|
||||
|
||||
points->num_points = 0;
|
||||
for (iter = point_node_list; iter; iter = g_list_next (iter))
|
||||
{
|
||||
if (read_point_node (iter->data, &points->points[points->num_points]))
|
||||
points->num_points++;
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
read_point_node (JsonNode *node, LdPoint *point)
|
||||
{
|
||||
JsonArray *array;
|
||||
JsonNode *x_node, *y_node;
|
||||
|
||||
g_return_val_if_fail (node != NULL, FALSE);
|
||||
g_return_val_if_fail (point != NULL, FALSE);
|
||||
|
||||
if (!JSON_NODE_HOLDS_ARRAY (node))
|
||||
{
|
||||
WARN_NODE_TYPE (node, LD_TYPE_POINT);
|
||||
return FALSE;
|
||||
}
|
||||
array = json_node_get_array (node);
|
||||
if (json_array_get_length (array) < 2)
|
||||
{
|
||||
g_warning ("%s: too few values for a point", G_STRLOC);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
x_node = json_array_get_element (array, 0);
|
||||
y_node = json_array_get_element (array, 1);
|
||||
|
||||
return read_double_node (x_node, &point->x)
|
||||
&& read_double_node (y_node, &point->y);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
read_double_node (JsonNode *node, gdouble *value)
|
||||
{
|
||||
GValue double_value, json_value;
|
||||
|
||||
g_return_val_if_fail (node != NULL, FALSE);
|
||||
g_return_val_if_fail (value != NULL, FALSE);
|
||||
|
||||
if (!JSON_NODE_HOLDS_VALUE (node) || !g_value_type_transformable
|
||||
(json_node_get_value_type (node), G_TYPE_DOUBLE))
|
||||
{
|
||||
WARN_NODE_TYPE (node, G_TYPE_DOUBLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset (&json_value, 0, sizeof (GValue));
|
||||
memset (&double_value, 0, sizeof (GValue));
|
||||
|
||||
json_node_get_value (node, &json_value);
|
||||
g_value_init (&double_value, G_TYPE_DOUBLE);
|
||||
g_value_transform (&json_value, &double_value);
|
||||
*value = g_value_get_double (&double_value);
|
||||
|
||||
g_value_unset (&json_value);
|
||||
g_value_unset (&double_value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ld_diagram_connection_set_points:
|
||||
* @self: an #LdDiagramConnection object.
|
||||
* @points: a point array.
|
||||
*
|
||||
* Set the points defining this connection.
|
||||
*/
|
||||
void
|
||||
ld_diagram_connection_set_points (LdDiagramConnection *self,
|
||||
const LdPointArray *points)
|
||||
{
|
||||
LdUndoAction *action;
|
||||
SetPointsActionData *action_data;
|
||||
JsonNode *node;
|
||||
JsonObject *storage;
|
||||
JsonArray *array, *point_array;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (LD_IS_DIAGRAM_CONNECTION (self));
|
||||
g_return_if_fail (points != NULL);
|
||||
|
||||
storage = ld_diagram_object_get_storage (LD_DIAGRAM_OBJECT (self));
|
||||
array = json_array_new ();
|
||||
for (i = 0; i < points->num_points; i++)
|
||||
{
|
||||
point_array = json_array_new ();
|
||||
json_array_add_double_element (point_array, points->points[i].x);
|
||||
json_array_add_double_element (point_array, points->points[i].y);
|
||||
json_array_add_array_element (array, point_array);
|
||||
}
|
||||
|
||||
action_data = g_slice_new (SetPointsActionData);
|
||||
action_data->self = g_object_ref (self);
|
||||
|
||||
node = json_object_get_member (storage, "points");
|
||||
action_data->old_node = node ? json_node_copy (node) : NULL;
|
||||
|
||||
node = json_node_new (JSON_NODE_ARRAY);
|
||||
json_node_set_array (node, array);
|
||||
action_data->new_node = json_node_copy (node);
|
||||
|
||||
json_object_set_member (storage, "points", node);
|
||||
|
||||
action = ld_undo_action_new (on_set_points_undo, on_set_points_redo,
|
||||
on_set_points_destroy, action_data);
|
||||
ld_diagram_object_changed (LD_DIAGRAM_OBJECT (self), action);
|
||||
g_object_unref (action);
|
||||
}
|
||||
|
||||
static void
|
||||
on_set_points_undo (gpointer user_data)
|
||||
{
|
||||
SetPointsActionData *data;
|
||||
JsonObject *storage;
|
||||
|
||||
data = user_data;
|
||||
storage = ld_diagram_object_get_storage (LD_DIAGRAM_OBJECT (data->self));
|
||||
|
||||
json_object_set_member (storage, "points", json_node_copy (data->old_node));
|
||||
}
|
||||
|
||||
static void
|
||||
on_set_points_redo (gpointer user_data)
|
||||
{
|
||||
SetPointsActionData *data;
|
||||
JsonObject *storage;
|
||||
|
||||
data = user_data;
|
||||
storage = ld_diagram_object_get_storage (LD_DIAGRAM_OBJECT (data->self));
|
||||
|
||||
json_object_set_member (storage, "points", json_node_copy (data->new_node));
|
||||
}
|
||||
|
||||
static void
|
||||
on_set_points_destroy (gpointer user_data)
|
||||
{
|
||||
SetPointsActionData *data;
|
||||
|
||||
data = user_data;
|
||||
g_object_unref (data->self);
|
||||
if (data->old_node)
|
||||
json_node_free (data->old_node);
|
||||
if (data->new_node)
|
||||
json_node_free (data->new_node);
|
||||
g_slice_free (SetPointsActionData, data);
|
||||
}
|
||||
|
64
liblogdiag/ld-diagram-connection.h
Normal file
64
liblogdiag/ld-diagram-connection.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* ld-diagram-connection.h
|
||||
*
|
||||
* This file is a part of logdiag.
|
||||
* Copyright Přemysl Janouch 2011. All rights reserved.
|
||||
*
|
||||
* See the file LICENSE for licensing information.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LD_DIAGRAM_CONNECTION_H__
|
||||
#define __LD_DIAGRAM_CONNECTION_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
||||
#define LD_TYPE_DIAGRAM_CONNECTION (ld_diagram_connection_get_type ())
|
||||
#define LD_DIAGRAM_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST \
|
||||
((obj), LD_TYPE_DIAGRAM_CONNECTION, LdDiagramConnection))
|
||||
#define LD_DIAGRAM_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST \
|
||||
((klass), LD_TYPE_DIAGRAM_CONNECTION, LdDiagramConnectionClass))
|
||||
#define LD_IS_DIAGRAM_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE \
|
||||
((obj), LD_TYPE_DIAGRAM_CONNECTION))
|
||||
#define LD_IS_DIAGRAM_CONNECTION_CLASS(klass) (G_TYPE_CHECK_INSTANCE_TYPE \
|
||||
((klass), LD_TYPE_DIAGRAM_CONNECTION))
|
||||
#define LD_DIAGRAM_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS \
|
||||
((obj), LD_DIAGRAM_CONNECTION, LdDiagramConnectionClass))
|
||||
|
||||
typedef struct _LdDiagramConnection LdDiagramConnection;
|
||||
typedef struct _LdDiagramConnectionPrivate LdDiagramConnectionPrivate;
|
||||
typedef struct _LdDiagramConnectionClass LdDiagramConnectionClass;
|
||||
|
||||
|
||||
/**
|
||||
* LdDiagramConnection:
|
||||
*/
|
||||
struct _LdDiagramConnection
|
||||
{
|
||||
/*< private >*/
|
||||
LdDiagramObject parent_instance;
|
||||
};
|
||||
|
||||
/**
|
||||
* LdDiagramConnectionClass:
|
||||
*/
|
||||
struct _LdDiagramConnectionClass
|
||||
{
|
||||
/*< private >*/
|
||||
LdDiagramObjectClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType ld_diagram_connection_get_type (void) G_GNUC_CONST;
|
||||
|
||||
LdDiagramConnection *ld_diagram_connection_new (JsonObject *storage);
|
||||
LdPointArray *ld_diagram_connection_get_points (LdDiagramConnection *self);
|
||||
void ld_diagram_connection_set_points (LdDiagramConnection *self,
|
||||
const LdPointArray *points);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* ! __LD_DIAGRAM_CONNECTION_H__ */
|
||||
|
@ -312,15 +312,6 @@ ld_diagram_object_get_data_default:
|
||||
g_object_set_property (G_OBJECT (self), name, data);
|
||||
}
|
||||
|
||||
/* We have to remove it first due to a bug in json-glib. */
|
||||
#define json_object_set_member(object, name, node) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
json_object_remove_member (object, name); \
|
||||
json_object_set_member (object, name, node); \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
/**
|
||||
* ld_diagram_object_set_data_for_param:
|
||||
* @self: an #LdDiagramObject object.
|
||||
|
@ -525,6 +525,8 @@ deserialize_object (JsonObject *object_storage)
|
||||
type = json_node_get_string (object_type_node);
|
||||
if (!g_strcmp0 ("symbol", type))
|
||||
return LD_DIAGRAM_OBJECT (ld_diagram_symbol_new (object_storage));
|
||||
if (!g_strcmp0 ("connection", type))
|
||||
return LD_DIAGRAM_OBJECT (ld_diagram_connection_new (object_storage));
|
||||
|
||||
deserialize_object_default:
|
||||
/* Anything we can't identify is just an indefinite object. */
|
||||
@ -576,6 +578,8 @@ get_object_class_string (GType type)
|
||||
{
|
||||
if (type == LD_TYPE_DIAGRAM_SYMBOL)
|
||||
return "symbol";
|
||||
if (type == LD_TYPE_DIAGRAM_CONNECTION)
|
||||
return "connection";
|
||||
if (type != LD_TYPE_DIAGRAM_OBJECT)
|
||||
/* We don't know our own type, that's just plain wrong. */
|
||||
g_warn_if_reached ();
|
||||
|
@ -110,14 +110,6 @@ void ld_diagram_select_all (LdDiagram *self);
|
||||
void ld_diagram_unselect (LdDiagram *self, LdDiagramObject *object);
|
||||
void ld_diagram_unselect_all (LdDiagram *self);
|
||||
|
||||
/*
|
||||
GList *ld_diagram_get_connections (LdDiagram *self);
|
||||
void ld_diagram_connection_add (LdDiagram *self,
|
||||
LdConnection *connection, gint pos);
|
||||
void ld_diagram_connection_remove (LdDiagram *self,
|
||||
LdConnection *connection);
|
||||
*/
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "ld-undo-action.h"
|
||||
#include "ld-diagram-object.h"
|
||||
#include "ld-diagram-symbol.h"
|
||||
#include "ld-diagram-connection.h"
|
||||
#include "ld-diagram.h"
|
||||
|
||||
#include "ld-canvas.h"
|
||||
|
Loading…
Reference in New Issue
Block a user