dia r4237 - in trunk: . app



Author: hans
Date: Fri Jan 30 20:14:36 2009
New Revision: 4237
URL: http://svn.gnome.org/viewvc/dia?rev=4237&view=rev

Log:
2009-01-30  Hans Breuer  <hans breuer org>

	* app/object_ops.[ch] : implement object_list_nudge() ...
	* app/disp_callbacks.c : ... use it to move selected objects by 
	keyboard keys (arrow/shift-arrow for small/bigger step), bug #137433
	(The viewable area can still be moved as before if nothing is selected)
	Make PageUp, Ctrl-PageUp, PageDown, Ctrl-PageDown scroll selected
	view by one page up/left/down/right, bug #94015
	Home/End to align the top-left/bottom-right corner of the diagram with
	the viewable area



Modified:
   trunk/ChangeLog
   trunk/app/disp_callbacks.c
   trunk/app/object_ops.c
   trunk/app/object_ops.h

Modified: trunk/app/disp_callbacks.c
==============================================================================
--- trunk/app/disp_callbacks.c	(original)
+++ trunk/app/disp_callbacks.c	Fri Jan 30 20:14:36 2009
@@ -432,6 +432,54 @@
   }
 }
 
+static void
+_scroll_page (DDisplay *ddisp, Direction dir)
+{
+  Point delta = {0, 0};
+
+  switch (dir) {
+  case DIR_LEFT :
+    delta.x = ddisp->diagram->data->paper.width * ddisp->diagram->data->paper.scaling;
+    break;
+  case DIR_RIGHT :
+    delta.x = -ddisp->diagram->data->paper.width * ddisp->diagram->data->paper.scaling;
+    break;
+  case DIR_UP :
+    delta.y = -ddisp->diagram->data->paper.height * ddisp->diagram->data->paper.scaling;
+    break;
+  case DIR_DOWN :
+    delta.y = ddisp->diagram->data->paper.height * ddisp->diagram->data->paper.scaling;
+    break;
+  }
+  ddisplay_scroll(ddisp, &delta);
+  ddisplay_flush(ddisp);
+}
+
+static void
+_scroll_step (DDisplay *ddisp, guint keyval)
+{
+  switch (keyval) {
+  case GDK_Up :
+    ddisplay_scroll_up(ddisp);
+    ddisplay_flush(ddisp);
+    break;
+  case GDK_Down:
+    ddisplay_scroll_down(ddisp);
+    ddisplay_flush(ddisp);
+    break;
+  case GDK_Left:
+    ddisplay_scroll_left(ddisp);
+    ddisplay_flush(ddisp);
+    break;
+  case GDK_Right:
+    ddisplay_scroll_right(ddisp);
+    ddisplay_flush(ddisp);
+    break;
+  default :
+    g_assert_not_reached  ();
+  }
+}
+
 /** Main input handler for a diagram canvas.
  */
 gint
@@ -725,22 +773,51 @@
           return_val = TRUE;
           
           switch(kevent->keyval) {
+	      case GDK_Home :
+	        /* match upper left corner of the diagram with it's view */
+		ddisplay_set_origo(ddisp, ddisp->diagram->data->extents.left, ddisp->diagram->data->extents.top);
+		ddisplay_update_scrollbars(ddisp);
+		ddisplay_add_update_all(ddisp);
+	        break;
+	      case GDK_End :
+	        /* match lower right corner of the diagram with it's view */
+		visible = &ddisp->visible;
+		ddisplay_set_origo(ddisp, 
+		                   ddisp->diagram->data->extents.right - (visible->right - visible->left), 
+				   ddisp->diagram->data->extents.bottom - (visible->bottom - visible->top));
+		ddisplay_update_scrollbars(ddisp);
+		ddisplay_add_update_all(ddisp);
+	        break;
+	      case GDK_Page_Up :
+	        _scroll_page (ddisp, !(state & GDK_CONTROL_MASK) ? DIR_UP : DIR_LEFT);
+	        break;
+	      case GDK_Page_Down :
+	        _scroll_page (ddisp, !(state & GDK_CONTROL_MASK) ? DIR_DOWN : DIR_RIGHT);
+	        break;
               case GDK_Up:
-                ddisplay_scroll_up(ddisp);
-                ddisplay_flush(ddisp);
-                break;
               case GDK_Down:
-                ddisplay_scroll_down(ddisp);
-                ddisplay_flush(ddisp);
-                break;
               case GDK_Left:
-                ddisplay_scroll_left(ddisp);
-                ddisplay_flush(ddisp);
-                break;
               case GDK_Right:
-                ddisplay_scroll_right(ddisp);
-                ddisplay_flush(ddisp);
-                break;
+	        if (g_list_length (ddisp->diagram->data->selected) > 0) {
+		  Diagram *dia = ddisp->diagram;
+		  GList *objects = dia->data->selected;
+		  Direction dir = GDK_Up == kevent->keyval ? DIR_UP :
+				  GDK_Down == kevent->keyval ? DIR_DOWN :
+				  GDK_Right == kevent->keyval ? DIR_RIGHT : DIR_LEFT;
+		  object_add_updates_list(objects, dia);
+		  object_list_nudge(objects, dia, dir, 
+				    /* step one pixel or more with <ctrl> */
+				    ddisplay_untransform_length (ddisp, (state & GDK_SHIFT_MASK) ? 10 : 1));
+		  diagram_update_connections_selection(dia);
+		  object_add_updates_list(objects, dia);
+		  diagram_modified(dia);
+		  diagram_flush(dia);     
+
+		  undo_set_transactionpoint(dia->undo);
+		} else {
+		  _scroll_step (ddisp, kevent->keyval);
+		}
+		break;
               case GDK_KP_Add:
               case GDK_plus:
                 visible = &ddisp->visible;

Modified: trunk/app/object_ops.c
==============================================================================
--- trunk/app/object_ops.c	(original)
+++ trunk/app/object_ops.c	Fri Jan 30 20:14:36 2009
@@ -463,3 +463,50 @@
   if (sort_alloc)
     g_list_free(objects);
 }
+
+/** Move the list in the given direction.
+ *
+ * @param objects The objects to move
+ * @param dia The diagram owning the objects
+ * @param dir The direction to move to
+ * @param step The step-width to move
+ */
+void
+object_list_nudge(GList *objects, Diagram *dia, Direction dir, real step)
+{
+  Point *orig_pos;
+  Point *dest_pos;
+  guint nobjs, i;
+  real inc_x, inc_y;
+  GList *list;
+  DiaObject *obj;
+
+  if (!objects)
+    return;
+  g_return_if_fail (step > 0);
+
+  nobjs = g_list_length (objects);
+  g_return_if_fail (nobjs > 0);
+
+  dest_pos = g_new(Point, nobjs);
+  orig_pos = g_new(Point, nobjs);
+
+  inc_x = DIR_RIGHT == dir ? step : (DIR_LEFT == dir ? -step : 0);
+  inc_y = DIR_DOWN == dir ? step : (DIR_UP == dir ? -step : 0);
+
+  /* remeber original positions and calculate destination */
+  i = 0;
+  list = objects;
+  while (list != NULL) {
+    obj = (DiaObject *) list->data;
+    
+    orig_pos[i] = obj->position;
+    dest_pos[i].x = orig_pos[i].x + inc_x;
+    dest_pos[i].y = orig_pos[i].y + inc_y;
+
+    obj->ops->move(obj, &dest_pos[i]);
+    ++i;
+    list = g_list_next(list);
+  }
+  undo_move_objects(dia, orig_pos, dest_pos, g_list_copy(objects)); 
+}

Modified: trunk/app/object_ops.h
==============================================================================
--- trunk/app/object_ops.h	(original)
+++ trunk/app/object_ops.h	Fri Jan 30 20:14:36 2009
@@ -46,5 +46,15 @@
 Point object_list_corner(GList *list);
 void object_list_align_h(GList *objects, Diagram *dia, int align);
 void object_list_align_v(GList *objects, Diagram *dia, int align);
+
+typedef enum {
+  DIR_UP = 1,
+  DIR_DOWN,
+  DIR_LEFT,
+  DIR_RIGHT
+} Direction;
+
+void object_list_nudge(GList *objects, Diagram *dia, Direction dir, real step);
+
 #endif /* OBJECT_OPS_H */
 



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