aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2011-02-14 10:14:28 +0100
committerPřemysl Janouch <p.janouch@gmail.com>2011-02-14 10:14:28 +0100
commitbaed5ee4bd2dd04e49df650b07278a8ceb900cab (patch)
treebabffd783963aa569fe27ed086fb21779d8280df
parent5ccabad6ce7fbceda23ce0fb650d1c2ffd4337a4 (diff)
downloadlogdiag-baed5ee4bd2dd04e49df650b07278a8ceb900cab.tar.gz
logdiag-baed5ee4bd2dd04e49df650b07278a8ceb900cab.tar.xz
logdiag-baed5ee4bd2dd04e49df650b07278a8ceb900cab.zip
Allow rotation of symbols.
Bind this action to the right mouse button. Due to limitations of json-glib, we can't store rotation as an enum.
-rw-r--r--liblogdiag/ld-canvas.c140
-rw-r--r--liblogdiag/ld-canvas.h2
-rw-r--r--liblogdiag/ld-diagram-symbol.c45
-rw-r--r--liblogdiag/ld-diagram-symbol.h10
4 files changed, 181 insertions, 16 deletions
diff --git a/liblogdiag/ld-canvas.c b/liblogdiag/ld-canvas.c
index 9342973..a180167 100644
--- a/liblogdiag/ld-canvas.c
+++ b/liblogdiag/ld-canvas.c
@@ -240,6 +240,7 @@ static void queue_object_draw (LdCanvas *self, LdDiagramObject *object);
/* Symbol terminals. */
static void check_terminals (LdCanvas *self, const LdPoint *point);
+static void rotate_terminal (LdPoint *terminal, gint symbol_rotation);
static void hide_terminals (LdCanvas *self);
static void queue_terminal_draw (LdCanvas *self, LdPoint *terminal);
@@ -251,6 +252,8 @@ static gboolean get_symbol_clip_area (LdCanvas *self,
static gboolean get_symbol_area (LdCanvas *self,
LdDiagramSymbol *symbol, LdRectangle *rect);
+static void rotate_symbol_area (LdRectangle *area, gint rotation);
+static void rotate_symbol (LdCanvas *self, LdDiagramSymbol *symbol);
static LdSymbol *resolve_symbol (LdCanvas *self,
LdDiagramSymbol *diagram_symbol);
@@ -1162,12 +1165,12 @@ check_terminals (LdCanvas *self, const LdPoint *point)
objects = (GList *) ld_diagram_get_objects (self->priv->diagram);
for (iter = objects; iter; iter = g_list_next (iter))
{
- LdDiagramObject *diagram_object;
gdouble object_x, object_y;
LdDiagramSymbol *diagram_symbol;
LdSymbol *symbol;
const LdPointArray *terminals;
guint i;
+ gint rotation;
if (!LD_IS_DIAGRAM_SYMBOL (iter->data))
continue;
@@ -1177,17 +1180,17 @@ check_terminals (LdCanvas *self, const LdPoint *point)
if (!symbol)
continue;
- diagram_object = LD_DIAGRAM_OBJECT (iter->data);
- g_object_get (diagram_object, "x", &object_x, "y", &object_y, NULL);
+ g_object_get (diagram_symbol, "x", &object_x, "y", &object_y,
+ "rotation", &rotation, NULL);
terminals = ld_symbol_get_terminals (symbol);
-
for (i = 0; i < terminals->length; i++)
{
LdPoint cur_term, widget_coords;
gdouble distance;
cur_term = terminals->points[i];
+ rotate_terminal (&cur_term, rotation);
cur_term.x += object_x;
cur_term.y += object_y;
@@ -1214,6 +1217,30 @@ check_terminals (LdCanvas *self, const LdPoint *point)
}
static void
+rotate_terminal (LdPoint *terminal, gint symbol_rotation)
+{
+ gdouble temp;
+
+ switch (symbol_rotation)
+ {
+ case LD_DIAGRAM_SYMBOL_ROTATION_90:
+ temp = terminal->y;
+ terminal->y = terminal->x;
+ terminal->x = -temp;
+ break;
+ case LD_DIAGRAM_SYMBOL_ROTATION_180:
+ terminal->y = -terminal->y;
+ terminal->x = -terminal->x;
+ break;
+ case LD_DIAGRAM_SYMBOL_ROTATION_270:
+ temp = terminal->x;
+ terminal->x = terminal->y;
+ terminal->y = -temp;
+ break;
+ }
+}
+
+static void
hide_terminals (LdCanvas *self)
{
if (self->priv->terminal_hovered)
@@ -1276,8 +1303,10 @@ get_symbol_area (LdCanvas *self, LdDiagramSymbol *symbol, LdRectangle *rect)
LdRectangle area;
gdouble x1, x2;
gdouble y1, y2;
+ gint rotation;
- g_object_get (symbol, "x", &object_x, "y", &object_y, NULL);
+ g_object_get (symbol, "x", &object_x, "y", &object_y,
+ "rotation", &rotation, NULL);
library_symbol = resolve_symbol (self, symbol);
if (library_symbol)
@@ -1285,7 +1314,8 @@ get_symbol_area (LdCanvas *self, LdDiagramSymbol *symbol, LdRectangle *rect)
else
return FALSE;
- /* TODO: Rotate the rectangle for other orientations. */
+ rotate_symbol_area (&area, rotation);
+
ld_canvas_diagram_to_widget_coords (self,
object_x + area.x,
object_y + area.y,
@@ -1307,6 +1337,68 @@ get_symbol_area (LdCanvas *self, LdDiagramSymbol *symbol, LdRectangle *rect)
return TRUE;
}
+static void
+rotate_symbol_area (LdRectangle *area, gint rotation)
+{
+ gdouble temp;
+
+ switch (rotation)
+ {
+ case LD_DIAGRAM_SYMBOL_ROTATION_90:
+ temp = area->y;
+ area->y = area->x;
+ area->x = -(temp + area->height);
+ break;
+ case LD_DIAGRAM_SYMBOL_ROTATION_180:
+ area->y = -(area->y + area->height);
+ area->x = -(area->x + area->width);
+ break;
+ case LD_DIAGRAM_SYMBOL_ROTATION_270:
+ temp = area->x;
+ area->x = area->y;
+ area->y = -(temp + area->width);
+ break;
+ }
+
+ switch (rotation)
+ {
+ case LD_DIAGRAM_SYMBOL_ROTATION_90:
+ case LD_DIAGRAM_SYMBOL_ROTATION_270:
+ temp = area->width;
+ area->width = area->height;
+ area->height = temp;
+ break;
+ }
+}
+
+static void
+rotate_symbol (LdCanvas *self, LdDiagramSymbol *symbol)
+{
+ gint rotation;
+
+ g_object_get (symbol, "rotation", &rotation, NULL);
+ queue_object_draw (self, LD_DIAGRAM_OBJECT (symbol));
+
+ switch (rotation)
+ {
+ case LD_DIAGRAM_SYMBOL_ROTATION_0:
+ rotation = LD_DIAGRAM_SYMBOL_ROTATION_90;
+ break;
+ case LD_DIAGRAM_SYMBOL_ROTATION_90:
+ rotation = LD_DIAGRAM_SYMBOL_ROTATION_180;
+ break;
+ case LD_DIAGRAM_SYMBOL_ROTATION_180:
+ rotation = LD_DIAGRAM_SYMBOL_ROTATION_270;
+ break;
+ case LD_DIAGRAM_SYMBOL_ROTATION_270:
+ rotation = LD_DIAGRAM_SYMBOL_ROTATION_0;
+ break;
+ }
+
+ g_object_set (symbol, "rotation", rotation, NULL);
+ queue_object_draw (self, LD_DIAGRAM_OBJECT (symbol));
+}
+
static LdSymbol *
resolve_symbol (LdCanvas *self, LdDiagramSymbol *diagram_symbol)
{
@@ -1846,11 +1938,6 @@ on_button_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
AddObjectData *data;
LdDiagramObject *object;
- if (event->button != 1)
- return FALSE;
- if (!gtk_widget_has_focus (widget))
- gtk_widget_grab_focus (widget);
-
point.x = event->x;
point.y = event->y;
@@ -1858,6 +1945,19 @@ on_button_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
if (!self->priv->diagram)
return FALSE;
+ if (event->button == 3 && self->priv->operation == OPER_0)
+ {
+ object = get_object_at_point (self, &point);
+ if (object && LD_IS_DIAGRAM_SYMBOL (object))
+ rotate_symbol (self, LD_DIAGRAM_SYMBOL (object));
+ return FALSE;
+ }
+
+ if (event->button != 1)
+ return FALSE;
+ if (!gtk_widget_has_focus (widget))
+ gtk_widget_grab_focus (widget);
+
self->priv->drag_operation = OPER_0;
switch (self->priv->operation)
{
@@ -2151,6 +2251,7 @@ draw_symbol (LdDiagramSymbol *diagram_symbol, DrawData *data)
LdSymbol *symbol;
LdRectangle clip_rect;
gdouble x, y;
+ gint rotation;
symbol = resolve_symbol (data->self, diagram_symbol);
@@ -2175,12 +2276,25 @@ draw_symbol (LdDiagramSymbol *diagram_symbol, DrawData *data)
clip_rect.width, clip_rect.height);
cairo_clip (data->cr);
- /* TODO: Rotate the space for other orientations. */
- g_object_get (diagram_symbol, "x", &x, "y", &y, NULL);
+ g_object_get (diagram_symbol, "x", &x, "y", &y,
+ "rotation", &rotation, NULL);
ld_canvas_diagram_to_widget_coords (data->self, x, y, &x, &y);
cairo_translate (data->cr, x, y);
cairo_scale (data->cr, data->scale, data->scale);
+ switch (rotation)
+ {
+ case LD_DIAGRAM_SYMBOL_ROTATION_90:
+ cairo_rotate (data->cr, G_PI * 0.5);
+ break;
+ case LD_DIAGRAM_SYMBOL_ROTATION_180:
+ cairo_rotate (data->cr, G_PI);
+ break;
+ case LD_DIAGRAM_SYMBOL_ROTATION_270:
+ cairo_rotate (data->cr, G_PI * 1.5);
+ break;
+ }
+
ld_symbol_draw (symbol, data->cr);
cairo_restore (data->cr);
}
diff --git a/liblogdiag/ld-canvas.h b/liblogdiag/ld-canvas.h
index 9e2d105..3091a34 100644
--- a/liblogdiag/ld-canvas.h
+++ b/liblogdiag/ld-canvas.h
@@ -87,8 +87,6 @@ void ld_canvas_zoom_out (LdCanvas *self);
void ld_canvas_add_object_begin (LdCanvas *self, LdDiagramObject *object);
-/* TODO: The rest of the interface. */
-
G_END_DECLS
diff --git a/liblogdiag/ld-diagram-symbol.c b/liblogdiag/ld-diagram-symbol.c
index 8307ef4..01c0172 100644
--- a/liblogdiag/ld-diagram-symbol.c
+++ b/liblogdiag/ld-diagram-symbol.c
@@ -23,7 +23,8 @@
enum
{
PROP_0,
- PROP_CLASS
+ PROP_CLASS,
+ PROP_ROTATION
};
static void ld_diagram_symbol_get_property (GObject *object, guint property_id,
@@ -53,6 +54,16 @@ ld_diagram_symbol_class_init (LdDiagramSymbolClass *klass)
"The class of this symbol.",
"", G_PARAM_READWRITE);
g_object_class_install_property (object_class, PROP_CLASS, pspec);
+
+/**
+ * LdDiagramSymbol:rotation:
+ *
+ * Rotation of this symbol.
+ */
+ pspec = g_param_spec_int ("rotation", "Rotation",
+ "Rotation of this symbol.",
+ 0, 3, 0, G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_ROTATION, pspec);
}
static void
@@ -70,6 +81,7 @@ ld_diagram_symbol_get_property (GObject *object, guint property_id,
switch (property_id)
{
case PROP_CLASS:
+ case PROP_ROTATION:
ld_diagram_object_get_data_for_param (self, value, pspec);
break;
default:
@@ -87,6 +99,7 @@ ld_diagram_symbol_set_property (GObject *object, guint property_id,
switch (property_id)
{
case PROP_CLASS:
+ case PROP_ROTATION:
ld_diagram_object_set_data_for_param (self, value, pspec);
break;
default:
@@ -139,3 +152,33 @@ ld_diagram_symbol_set_class (LdDiagramSymbol *self, const gchar *klass)
g_return_if_fail (LD_IS_DIAGRAM_SYMBOL (self));
g_object_set (self, "class", klass, NULL);
}
+
+/**
+ * ld_diagram_symbol_get_rotation:
+ * @self: an #LdDiagramSymbol object.
+ *
+ * Return value: rotation of the symbol.
+ */
+gint
+ld_diagram_symbol_get_rotation (LdDiagramSymbol *self)
+{
+ gint rotation;
+
+ g_return_val_if_fail (LD_IS_DIAGRAM_SYMBOL (self), 0);
+ g_object_get (self, "rotation", &rotation, NULL);
+ return rotation;
+}
+
+/**
+ * ld_diagram_symbol_set_rotation:
+ * @self: an #LdDiagramSymbol object.
+ * @rotation: the rotation.
+ *
+ * Set rotation of the symbol.
+ */
+void
+ld_diagram_symbol_set_rotation (LdDiagramSymbol *self, gint rotation)
+{
+ g_return_if_fail (LD_IS_DIAGRAM_SYMBOL (self));
+ g_object_set (self, "rotation", rotation, NULL);
+}
diff --git a/liblogdiag/ld-diagram-symbol.h b/liblogdiag/ld-diagram-symbol.h
index d96c0f0..d7dfce2 100644
--- a/liblogdiag/ld-diagram-symbol.h
+++ b/liblogdiag/ld-diagram-symbol.h
@@ -50,11 +50,21 @@ struct _LdDiagramSymbolClass
};
+enum
+{
+ LD_DIAGRAM_SYMBOL_ROTATION_0,
+ LD_DIAGRAM_SYMBOL_ROTATION_90,
+ LD_DIAGRAM_SYMBOL_ROTATION_180,
+ LD_DIAGRAM_SYMBOL_ROTATION_270
+};
+
GType ld_diagram_symbol_get_type (void) G_GNUC_CONST;
LdDiagramSymbol *ld_diagram_symbol_new (JsonObject *storage);
gchar *ld_diagram_symbol_get_class (LdDiagramSymbol *self);
void ld_diagram_symbol_set_class (LdDiagramSymbol *self, const gchar *klass);
+gint ld_diagram_symbol_get_rotation (LdDiagramSymbol *self);
+void ld_diagram_symbol_set_rotation (LdDiagramSymbol *self, gint rotation);
G_END_DECLS