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.
This commit is contained in:
parent
5ccabad6ce
commit
baed5ee4bd
|
@ -240,6 +240,7 @@ static void queue_object_draw (LdCanvas *self, LdDiagramObject *object);
|
||||||
|
|
||||||
/* Symbol terminals. */
|
/* Symbol terminals. */
|
||||||
static void check_terminals (LdCanvas *self, const LdPoint *point);
|
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 hide_terminals (LdCanvas *self);
|
||||||
static void queue_terminal_draw (LdCanvas *self, LdPoint *terminal);
|
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,
|
static gboolean get_symbol_area (LdCanvas *self,
|
||||||
LdDiagramSymbol *symbol, LdRectangle *rect);
|
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,
|
static LdSymbol *resolve_symbol (LdCanvas *self,
|
||||||
LdDiagramSymbol *diagram_symbol);
|
LdDiagramSymbol *diagram_symbol);
|
||||||
|
|
||||||
|
@ -1162,12 +1165,12 @@ check_terminals (LdCanvas *self, const LdPoint *point)
|
||||||
objects = (GList *) ld_diagram_get_objects (self->priv->diagram);
|
objects = (GList *) ld_diagram_get_objects (self->priv->diagram);
|
||||||
for (iter = objects; iter; iter = g_list_next (iter))
|
for (iter = objects; iter; iter = g_list_next (iter))
|
||||||
{
|
{
|
||||||
LdDiagramObject *diagram_object;
|
|
||||||
gdouble object_x, object_y;
|
gdouble object_x, object_y;
|
||||||
LdDiagramSymbol *diagram_symbol;
|
LdDiagramSymbol *diagram_symbol;
|
||||||
LdSymbol *symbol;
|
LdSymbol *symbol;
|
||||||
const LdPointArray *terminals;
|
const LdPointArray *terminals;
|
||||||
guint i;
|
guint i;
|
||||||
|
gint rotation;
|
||||||
|
|
||||||
if (!LD_IS_DIAGRAM_SYMBOL (iter->data))
|
if (!LD_IS_DIAGRAM_SYMBOL (iter->data))
|
||||||
continue;
|
continue;
|
||||||
|
@ -1177,17 +1180,17 @@ check_terminals (LdCanvas *self, const LdPoint *point)
|
||||||
if (!symbol)
|
if (!symbol)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
diagram_object = LD_DIAGRAM_OBJECT (iter->data);
|
g_object_get (diagram_symbol, "x", &object_x, "y", &object_y,
|
||||||
g_object_get (diagram_object, "x", &object_x, "y", &object_y, NULL);
|
"rotation", &rotation, NULL);
|
||||||
|
|
||||||
terminals = ld_symbol_get_terminals (symbol);
|
terminals = ld_symbol_get_terminals (symbol);
|
||||||
|
|
||||||
for (i = 0; i < terminals->length; i++)
|
for (i = 0; i < terminals->length; i++)
|
||||||
{
|
{
|
||||||
LdPoint cur_term, widget_coords;
|
LdPoint cur_term, widget_coords;
|
||||||
gdouble distance;
|
gdouble distance;
|
||||||
|
|
||||||
cur_term = terminals->points[i];
|
cur_term = terminals->points[i];
|
||||||
|
rotate_terminal (&cur_term, rotation);
|
||||||
cur_term.x += object_x;
|
cur_term.x += object_x;
|
||||||
cur_term.y += object_y;
|
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
|
static void
|
||||||
hide_terminals (LdCanvas *self)
|
hide_terminals (LdCanvas *self)
|
||||||
{
|
{
|
||||||
|
@ -1276,8 +1303,10 @@ get_symbol_area (LdCanvas *self, LdDiagramSymbol *symbol, LdRectangle *rect)
|
||||||
LdRectangle area;
|
LdRectangle area;
|
||||||
gdouble x1, x2;
|
gdouble x1, x2;
|
||||||
gdouble y1, y2;
|
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);
|
library_symbol = resolve_symbol (self, symbol);
|
||||||
if (library_symbol)
|
if (library_symbol)
|
||||||
|
@ -1285,7 +1314,8 @@ get_symbol_area (LdCanvas *self, LdDiagramSymbol *symbol, LdRectangle *rect)
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* TODO: Rotate the rectangle for other orientations. */
|
rotate_symbol_area (&area, rotation);
|
||||||
|
|
||||||
ld_canvas_diagram_to_widget_coords (self,
|
ld_canvas_diagram_to_widget_coords (self,
|
||||||
object_x + area.x,
|
object_x + area.x,
|
||||||
object_y + area.y,
|
object_y + area.y,
|
||||||
|
@ -1307,6 +1337,68 @@ get_symbol_area (LdCanvas *self, LdDiagramSymbol *symbol, LdRectangle *rect)
|
||||||
return TRUE;
|
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 *
|
static LdSymbol *
|
||||||
resolve_symbol (LdCanvas *self, LdDiagramSymbol *diagram_symbol)
|
resolve_symbol (LdCanvas *self, LdDiagramSymbol *diagram_symbol)
|
||||||
{
|
{
|
||||||
|
@ -1846,11 +1938,6 @@ on_button_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
||||||
AddObjectData *data;
|
AddObjectData *data;
|
||||||
LdDiagramObject *object;
|
LdDiagramObject *object;
|
||||||
|
|
||||||
if (event->button != 1)
|
|
||||||
return FALSE;
|
|
||||||
if (!gtk_widget_has_focus (widget))
|
|
||||||
gtk_widget_grab_focus (widget);
|
|
||||||
|
|
||||||
point.x = event->x;
|
point.x = event->x;
|
||||||
point.y = event->y;
|
point.y = event->y;
|
||||||
|
|
||||||
|
@ -1858,6 +1945,19 @@ on_button_press (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
|
||||||
if (!self->priv->diagram)
|
if (!self->priv->diagram)
|
||||||
return FALSE;
|
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;
|
self->priv->drag_operation = OPER_0;
|
||||||
switch (self->priv->operation)
|
switch (self->priv->operation)
|
||||||
{
|
{
|
||||||
|
@ -2151,6 +2251,7 @@ draw_symbol (LdDiagramSymbol *diagram_symbol, DrawData *data)
|
||||||
LdSymbol *symbol;
|
LdSymbol *symbol;
|
||||||
LdRectangle clip_rect;
|
LdRectangle clip_rect;
|
||||||
gdouble x, y;
|
gdouble x, y;
|
||||||
|
gint rotation;
|
||||||
|
|
||||||
symbol = resolve_symbol (data->self, diagram_symbol);
|
symbol = resolve_symbol (data->self, diagram_symbol);
|
||||||
|
|
||||||
|
@ -2175,12 +2276,25 @@ draw_symbol (LdDiagramSymbol *diagram_symbol, DrawData *data)
|
||||||
clip_rect.width, clip_rect.height);
|
clip_rect.width, clip_rect.height);
|
||||||
cairo_clip (data->cr);
|
cairo_clip (data->cr);
|
||||||
|
|
||||||
/* TODO: Rotate the space for other orientations. */
|
g_object_get (diagram_symbol, "x", &x, "y", &y,
|
||||||
g_object_get (diagram_symbol, "x", &x, "y", &y, NULL);
|
"rotation", &rotation, NULL);
|
||||||
ld_canvas_diagram_to_widget_coords (data->self, x, y, &x, &y);
|
ld_canvas_diagram_to_widget_coords (data->self, x, y, &x, &y);
|
||||||
cairo_translate (data->cr, x, y);
|
cairo_translate (data->cr, x, y);
|
||||||
cairo_scale (data->cr, data->scale, data->scale);
|
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);
|
ld_symbol_draw (symbol, data->cr);
|
||||||
cairo_restore (data->cr);
|
cairo_restore (data->cr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,8 +87,6 @@ void ld_canvas_zoom_out (LdCanvas *self);
|
||||||
|
|
||||||
void ld_canvas_add_object_begin (LdCanvas *self, LdDiagramObject *object);
|
void ld_canvas_add_object_begin (LdCanvas *self, LdDiagramObject *object);
|
||||||
|
|
||||||
/* TODO: The rest of the interface. */
|
|
||||||
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
PROP_CLASS
|
PROP_CLASS,
|
||||||
|
PROP_ROTATION
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ld_diagram_symbol_get_property (GObject *object, guint property_id,
|
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.",
|
"The class of this symbol.",
|
||||||
"", G_PARAM_READWRITE);
|
"", G_PARAM_READWRITE);
|
||||||
g_object_class_install_property (object_class, PROP_CLASS, pspec);
|
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
|
static void
|
||||||
|
@ -70,6 +81,7 @@ ld_diagram_symbol_get_property (GObject *object, guint property_id,
|
||||||
switch (property_id)
|
switch (property_id)
|
||||||
{
|
{
|
||||||
case PROP_CLASS:
|
case PROP_CLASS:
|
||||||
|
case PROP_ROTATION:
|
||||||
ld_diagram_object_get_data_for_param (self, value, pspec);
|
ld_diagram_object_get_data_for_param (self, value, pspec);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -87,6 +99,7 @@ ld_diagram_symbol_set_property (GObject *object, guint property_id,
|
||||||
switch (property_id)
|
switch (property_id)
|
||||||
{
|
{
|
||||||
case PROP_CLASS:
|
case PROP_CLASS:
|
||||||
|
case PROP_ROTATION:
|
||||||
ld_diagram_object_set_data_for_param (self, value, pspec);
|
ld_diagram_object_set_data_for_param (self, value, pspec);
|
||||||
break;
|
break;
|
||||||
default:
|
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_return_if_fail (LD_IS_DIAGRAM_SYMBOL (self));
|
||||||
g_object_set (self, "class", klass, NULL);
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
GType ld_diagram_symbol_get_type (void) G_GNUC_CONST;
|
||||||
|
|
||||||
LdDiagramSymbol *ld_diagram_symbol_new (JsonObject *storage);
|
LdDiagramSymbol *ld_diagram_symbol_new (JsonObject *storage);
|
||||||
gchar *ld_diagram_symbol_get_class (LdDiagramSymbol *self);
|
gchar *ld_diagram_symbol_get_class (LdDiagramSymbol *self);
|
||||||
void ld_diagram_symbol_set_class (LdDiagramSymbol *self, const gchar *klass);
|
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
|
G_END_DECLS
|
||||||
|
|
Loading…
Reference in New Issue