From baed5ee4bd2dd04e49df650b07278a8ceb900cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Mon, 14 Feb 2011 10:14:28 +0100 Subject: 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. --- liblogdiag/ld-canvas.c | 140 +++++++++++++++++++++++++++++++++++++---- liblogdiag/ld-canvas.h | 2 - liblogdiag/ld-diagram-symbol.c | 45 ++++++++++++- liblogdiag/ld-diagram-symbol.h | 10 +++ 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; @@ -1213,6 +1216,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) { @@ -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 -- cgit v1.2.3