A quick (partly working) hack: xy_flip



Hi,

I've been looking at using dia as a drawing tool for technical documents (We use the internal FrameMaker drawing commands at work, and it really sucks). However, like everyone else, I've been missing the "rotate" command.

I noticed however, that some objects have "flip horizontal" and "flip vertical" options. I've decided to hack these into a "flip xy" option that swaps the XY axes from the top-left corner of the object.

By combining this with the "flip horizontal" and "flip vertical" options already existing, the 90,270 degree rotations can be emulated (180 degree rotation can be done using "flip horizontal" and "flip vertical" alone).

The patch was doen only in objects/custom/custom_objects.c and is incomplete. when activated, the object is indeed xy flipped, but when its is being dragged, the object moves in a different direction than the 8 hanles bounding it. (If I move the mouse horizontally, the object moves vertically, and vice versa).

Since my total exposure to the dia source code was 1-2 hours, I haven't tried fixing that yet.

I don't know how hard it would be to fix the mouse drag operation. I know that the general rotation problem requires great infrastructure changes in dia, but I would hope someone who knows the dia codebase better than me could take this patch further and fix the remaining problems, or explain why this is hard. I'm even willing to live for the moment with not being able to rotate text at all, just graphics.

Udi

--- custom_object.c.orig        2004-08-16 09:56:15.000000000 +0200
+++ custom_object.c     2004-09-13 22:25:12.000000000 +0200
@@ -81,7 +81,7 @@
   LineStyle line_style;
   real dashlength;
 
-  gboolean flip_h, flip_v;
+  gboolean flip_h, flip_v, flip_xy;
 
   Text *text;
   TextAttributes attrs;
@@ -178,6 +178,8 @@
     N_("Flip horizontal"), NULL, NULL },
   { "flip_vertical", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE,
     N_("Flip vertical"), NULL, NULL },
+  { "flip_xy", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE,
+    N_("Flip xy"), NULL, NULL },
   PROP_DESC_END
 };
 
@@ -197,6 +199,8 @@
     N_("Flip horizontal"), NULL, NULL },
   { "flip_vertical", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE,
     N_("Flip vertical"), NULL, NULL },
+  { "flip_xy", PROP_TYPE_BOOL, PROP_FLAG_VISIBLE,
+    N_("Flip xy"), NULL, NULL },
   PROP_DESC_END
 };
 
@@ -210,6 +214,7 @@
     offsetof(Custom, line_style), offsetof(Custom, dashlength) },
   { "flip_horizontal", PROP_TYPE_BOOL, offsetof(Custom, flip_h) },
   { "flip_vertical", PROP_TYPE_BOOL, offsetof(Custom, flip_v) },
+  { "flip_xy", PROP_TYPE_BOOL, offsetof(Custom, flip_xy) },
   { NULL, 0, 0 }
 };
 
@@ -223,6 +228,7 @@
     offsetof(Custom, line_style), offsetof(Custom, dashlength) },
   { "flip_horizontal", PROP_TYPE_BOOL, offsetof(Custom, flip_h) },
   { "flip_vertical", PROP_TYPE_BOOL, offsetof(Custom, flip_v) },
+  { "flip_xy", PROP_TYPE_BOOL, offsetof(Custom, flip_xy) },
   {"text",PROP_TYPE_TEXT,offsetof(Custom,text)},
   {"text_font",PROP_TYPE_FONT,offsetof(Custom,attrs.font)},
   {"text_height",PROP_TYPE_REAL,offsetof(Custom,attrs.height)},
@@ -377,18 +383,30 @@
 static void
 transform_coord(Custom *custom, const Point *p1, Point *out)
 {
-  out->x = p1->x * custom->xscale + custom->xoffs;
-  out->y = p1->y * custom->yscale + custom->yoffs;
+  if (custom->flip_xy) {
+    out->x = p1->y * custom->yscale + custom->xoffs;
+    out->y = p1->x * custom->xscale + custom->yoffs;
+  } else {
+    out->x = p1->x * custom->xscale + custom->xoffs;
+    out->y = p1->y * custom->yscale + custom->yoffs;
+  }
 }
 
 static void
 transform_rect(Custom *custom, const Rectangle *r1, Rectangle *out)
 {
   real coord;
-  out->left   = r1->left   * custom->xscale + custom->xoffs;
-  out->right  = r1->right  * custom->xscale + custom->xoffs;
-  out->top    = r1->top    * custom->yscale + custom->yoffs;
-  out->bottom = r1->bottom * custom->yscale + custom->yoffs;
+  if (custom->flip_xy) {
+    out->left   = r1->top    * custom->yscale + custom->xoffs;
+    out->right  = r1->bottom * custom->yscale + custom->xoffs;
+    out->top    = r1->left   * custom->xscale + custom->yoffs;
+    out->bottom = r1->right  * custom->xscale + custom->yoffs;
+  } else {
+    out->left   = r1->left   * custom->xscale + custom->xoffs;
+    out->right  = r1->right  * custom->xscale + custom->xoffs;
+    out->top    = r1->top    * custom->yscale + custom->yoffs;
+    out->bottom = r1->bottom * custom->yscale + custom->yoffs;
+  }
 
   if (out->left > out->right) {
     coord = out->left;
@@ -829,6 +847,7 @@
   int i;
   GList *tmp;
   char *txs;
+  real tmpreal;
   
   /* save starting points */
   center = bottom_right = elem->corner;
@@ -935,6 +954,14 @@
     custom->yscale = -custom->yscale;
     custom->yoffs = elem->corner.y -custom->yscale * info->shape_bounds.bottom;
   }
+  if (custom->flip_xy) {
+    tmpreal = custom->yscale;
+    custom->xscale = custom->yscale;
+    custom->yscale = tmpreal;
+    tmpreal = custom->yoffs;
+    custom->yoffs = custom->xoffs;
+    custom->xoffs = tmpreal;
+  }
   
   /* reposition the text element to the new text bounding box ... */
   if (info->has_text) {
@@ -1227,6 +1254,7 @@
 
   custom->flip_h = FALSE;
   custom->flip_v = FALSE;
+  custom->flip_xy = FALSE;
   
   if (info->has_text) {
     attributes_get_default_font(&font, &font_height);
@@ -1318,6 +1346,7 @@
 
   newcustom->flip_h = custom->flip_h;
   newcustom->flip_v = custom->flip_v;
+  newcustom->flip_xy = custom->flip_xy;
 
   if (custom->info->has_text) {
     newcustom->text = text_copy(custom->text);
@@ -1362,7 +1391,7 @@
 struct CustomObjectChange {
   ObjectChange objchange;
 
-  enum { CHANGE_FLIPH, CHANGE_FLIPV} type;
+  enum { CHANGE_FLIPH, CHANGE_FLIPV, CHANGE_FLIPXY} type;
   gboolean old_val;
 };
 
@@ -1376,6 +1405,9 @@
   case CHANGE_FLIPV:
     custom->flip_v = !change->old_val;
     break;
+  case CHANGE_FLIPXY:
+    custom->flip_xy = !change->old_val;
+    break;
   }
 }
 static void
@@ -1388,6 +1420,9 @@
   case CHANGE_FLIPV:
     custom->flip_v = change->old_val;
     break;
+  case CHANGE_FLIPXY:
+    custom->flip_xy = change->old_val;
+    break;
   }
 }
 
@@ -1427,9 +1462,28 @@
   return &change->objchange;
 }
 
+static ObjectChange *
+custom_flip_xy_callback (DiaObject *obj, Point *clicked, gpointer data)
+{
+  Custom *custom = (Custom *)obj;
+  struct CustomObjectChange *change = g_new0(struct CustomObjectChange, 1);
+
+  change->objchange.apply = (ObjectChangeApplyFunc)custom_change_apply;
+  change->objchange.revert = (ObjectChangeRevertFunc)custom_change_revert;
+  change->objchange.free = NULL;
+  change->type = CHANGE_FLIPXY;
+  change->old_val = custom->flip_xy;
+
+  custom->flip_v = !custom->flip_xy;
+  custom_update_data(custom, ANCHOR_MIDDLE, ANCHOR_MIDDLE);
+
+  return &change->objchange;
+}
+
 static DiaMenuItem custom_menu_items[] = {
   { N_("Flip Horizontal"), custom_flip_h_callback, NULL, 1 },
   { N_("Flip Vertical"), custom_flip_v_callback, NULL, 1 },
+  { N_("Flip XY"), custom_flip_xy_callback, NULL, 1 },
 };
 
 static DiaMenu custom_menu = {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]