I was looking through the TODO file for dia and ran across the following: * If you hold down shift while moving the handle of an 'Element', scale while keeping same proportions.
So, I thought I'd try my hand at it. It only works for boxes right now, but shouldn't be too difficult to make it work for the other basic objects. Here's the patch for v0.88.1 (I'm not working with the CVS version at this point.) diff -pr dia-0.88.1/app/modify_tool.c dia-0.88.1.modified/app/modify_tool.c *** dia-0.88.1/app/modify_tool.c Sun Mar 25 20:05:16 2001 --- dia-0.88.1.modified/app/modify_tool.c Wed May 1 15:59:39 2002 *************** modify_motion(ModifyTool *tool, GdkEvent *** 280,285 **** --- 280,286 ---- Point now, delta, full_delta; gboolean auto_scroll, vertical = FALSE; ConnectionPoint *connectionpoint; + ModifierKeys modifier = MODIFIER_NONE; if (tool->state==STATE_NONE) return; /* Fast path... */ *************** modify_motion(ModifyTool *tool, GdkEvent *** 383,390 **** } object_add_updates(tool->object, ddisp->diagram); tool->object->ops->move_handle(tool->object, tool->handle, &to, ! HANDLE_MOVE_USER,0); object_add_updates(tool->object, ddisp->diagram); diagram_update_connections_selection(ddisp->diagram); --- 384,392 ---- } object_add_updates(tool->object, ddisp->diagram); + if (event->state & GDK_SHIFT_MASK) modifier = MODIFIER_SHIFT; tool->object->ops->move_handle(tool->object, tool->handle, &to, ! HANDLE_MOVE_USER,modifier); object_add_updates(tool->object, ddisp->diagram); diagram_update_connections_selection(ddisp->diagram); *************** modify_button_release(ModifyTool *tool, *** 433,438 **** --- 435,441 ---- GList *list; int i; Object *obj; + ModifierKeys modifier = MODIFIER_NONE; switch (tool->state) { case STATE_MOVE_OBJECT: *************** modify_button_release(ModifyTool *tool, *** 473,481 **** /* Final move: */ object_add_updates(tool->object, ddisp->diagram); tool->object->ops->move_handle(tool->object, tool->handle, &tool->last_to, ! HANDLE_MOVE_USER_FINAL,0); object_add_updates(tool->object, ddisp->diagram); /* Connect if possible: */ --- 476,485 ---- /* Final move: */ object_add_updates(tool->object, ddisp->diagram); + if (event->state & GDK_SHIFT_MASK) modifier = MODIFIER_SHIFT; tool->object->ops->move_handle(tool->object, tool->handle, &tool->last_to, ! HANDLE_MOVE_USER_FINAL,modifier); object_add_updates(tool->object, ddisp->diagram); /* Connect if possible: */ diff -pr dia-0.88.1/lib/element.c dia-0.88.1.modified/lib/element.c *** dia-0.88.1/lib/element.c Sun Mar 25 20:05:17 2001 --- dia-0.88.1.modified/lib/element.c Wed May 1 16:04:20 2002 *************** element_move_handle(Element *elem, Handl *** 150,155 **** --- 150,159 ---- default: message_error("Error, called element_move_handle() with wrong handle-id\n"); } + + if (elem->width != 0 && elem->height != 0) { + elem->aspectRatio = elem->width / elem->height; + } } void *************** element_copy(Element *from, Element *to) *** 280,285 **** --- 284,290 ---- to->corner = from->corner; to->width = from->width; to->height = from->height; + to->aspectRatio = from->aspectRatio; for (i=0;i<8;i++) { to->resize_handles[i] = from->resize_handles[i]; *************** void element_load(Element *elem, ObjectN *** 330,333 **** --- 335,343 ---- if (attr != NULL) elem->height = data_real( attribute_first_data(attr)); + if (elem->height != 0.0) { + elem->aspectRatio = elem->width / elem->height; + } else { + elem->aspectRatio = 0.0; + } } diff -pr dia-0.88.1/lib/element.h dia-0.88.1.modified/lib/element.h *** dia-0.88.1/lib/element.h Fri Feb 23 09:45:43 2001 --- dia-0.88.1.modified/lib/element.h Wed May 1 16:00:20 2002 *************** struct _Element { *** 41,46 **** --- 41,48 ---- real width; real height; + real aspectRatio; + ElementBBExtras extra_spacing; }; diff -pr dia-0.88.1/objects/standard/box.c dia-0.88.1.modified/objects/standard/box.c *** dia-0.88.1/objects/standard/box.c Mon Apr 30 20:56:01 2001 --- dia-0.88.1.modified/objects/standard/box.c Wed May 1 16:05:54 2002 *************** box_move_handle(Box *box, Handle *handle *** 308,314 **** assert(handle!=NULL); assert(to!=NULL); ! element_move_handle(&box->element, handle->id, to, reason); box_update_data(box); } --- 308,318 ---- assert(handle!=NULL); assert(to!=NULL); ! if (modifiers == MODIFIER_SHIFT) { ! element_move_handle_aspect(&box->element, handle->id, to, (real) box->element.aspectRatio); ! } else { ! element_move_handle(&box->element, handle->id, to, reason); ! } box_update_data(box); } *************** box_create(Point *startpoint, *** 511,516 **** --- 515,521 ---- elem->corner = *startpoint; elem->width = DEFAULT_WIDTH; elem->height = DEFAULT_WIDTH; + elem->aspectRatio = elem->width / elem->height; box->border_width = attributes_get_default_linewidth(); box->border_color = attributes_get_foreground(); I don't know that this is the best way to do this, but it does work. The basic idea is in addition to the width and height, keep a copy of the aspect ratio of an element in the element object. Then, when resizing, if the shift key is pressed, call the element_move_handle_aspect function rather than element_move_handle. The element_move_handle function updates the aspect ratio when it's finished while element_move_handle_aspect does not, since it should be the same. That's about it. Just have to make sure that the aspect ratio is calculated anytime the height or width changes. The only real trouble comes when the height or width is 0. This is a little tricky and I used some ugly hacks to make it work. Oh, I have to keep track of the ratio in the element (I guess you could keep it in the box, but then it can't be used in other objects) because if an object ever gets a width or height of zero, you don't want to recalculate the ratio. Also, if you calculate the ratio everytime the move_handle method gets called, if the width goes to zero, the aspect ratio does as well, and then weird things start happening (I had what looked like 5 unconnected handles stuck to the side of the window.) -- Titus Anderson _______________________________________________ Dia-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/dia-list