planner r883 - in trunk: . src



Author: mvdpot
Date: Fri Feb 15 21:36:53 2008
New Revision: 883
URL: http://svn.gnome.org/viewvc/planner?rev=883&view=rev

Log:
2008-02-15  Maurice van der Pot  <griffon26 kfk4ever com>

	* src/eel-canvas-rect.c: (eel_canvas_rect_bounds):
	* src/planner-gantt-chart.c: (gantt_chart_map),
	(gantt_chart_size_allocate), (gantt_chart_reflow_idle),
	(planner_gantt_chart_reflow_now),
	(gantt_chart_project_start_changed),
	(planner_gantt_chart_set_model), (gantt_chart_get_visible_region),
	(gantt_chart_set_zoom):
	* src/planner-gantt-chart.h:
	* src/planner-gantt-row.c: (gantt_row_drag_item_to_pointer),
	(gantt_row_scroll_timeout_cb), (get_drag_spot), (gantt_row_event):
	Allow dragging of duration beyond the window size and show the percentage in
	the status bar when dragging progress.



Modified:
   trunk/ChangeLog
   trunk/src/eel-canvas-rect.c
   trunk/src/planner-gantt-chart.c
   trunk/src/planner-gantt-chart.h
   trunk/src/planner-gantt-row.c

Modified: trunk/src/eel-canvas-rect.c
==============================================================================
--- trunk/src/eel-canvas-rect.c	(original)
+++ trunk/src/eel-canvas-rect.c	Fri Feb 15 21:36:53 2008
@@ -636,17 +636,18 @@
 {
 	EelCanvasRect *rect;
 	EelCanvasRectDetails *details;
-	double hwidth;
+	gint cx, cy;
 
 	rect = EEL_CANVAS_RECT (item);
 	details = rect->details;
 
-	hwidth = (details->width_pixels / item->canvas->pixels_per_unit) / 2.0;
-	
-	*x1 = details->x1 - hwidth;
-	*y1 = details->y1 - hwidth;
-	*x2 = details->x2 + hwidth;
-	*y2 = details->y2 + hwidth;
+	gnome_canvas_w2c (item->canvas, details->x1, details->y1, &cx, &cy);
+	*x1 = cx;
+	*y1 = cy;
+
+	gnome_canvas_w2c (item->canvas, details->x2, details->y2, &cx, &cy);
+	*x2 = cx;
+	*y2 = cy;
 }
 
 static void

Modified: trunk/src/planner-gantt-chart.c
==============================================================================
--- trunk/src/planner-gantt-chart.c	(original)
+++ trunk/src/planner-gantt-chart.c	Fri Feb 15 21:36:53 2008
@@ -181,7 +181,6 @@
 static void        gantt_chart_build_tree               (PlannerGanttChart  *chart);
 static void        gantt_chart_reflow                   (PlannerGanttChart  *chart,
 							 gboolean            height_changed);
-static void        gantt_chart_reflow_now               (PlannerGanttChart  *chart);
 static TreeNode *  gantt_chart_insert_task              (PlannerGanttChart  *chart,
 							 GtkTreePath        *path,
 							 MrpTask            *task);
@@ -190,6 +189,11 @@
 							 TreeNode           *task,
 							 TreeNode           *predecessor,
 							 MrpRelationType     type);
+static void        gantt_chart_get_visible_region       (PlannerGanttChart *chart,
+							 gdouble            *x1,
+							 gdouble            *y1,
+							 gdouble            *x2,
+							 gdouble            *y2);
 static void        gantt_chart_set_scroll_region        (PlannerGanttChart  *chart,
 							 gdouble             x1,
 							 gdouble             y1,
@@ -572,7 +576,7 @@
 	}
 
 	chart->priv->height_changed = TRUE;
-	gantt_chart_reflow_now (chart);
+	planner_gantt_chart_reflow_now (chart);
 }
 
 static void
@@ -592,7 +596,7 @@
 	 * jumping around.
 	 */
 	if (GTK_WIDGET_MAPPED (chart)) {
-		gantt_chart_reflow_now (chart);
+		planner_gantt_chart_reflow_now (chart);
 	}
 }
 
@@ -963,6 +967,7 @@
 	PlannerGanttChartPriv *priv;
 	mrptime                t1, t2;
 	gdouble                x1, y1, x2, y2;
+	gdouble                vx1, vy1, vx2, vy2;
 	gdouble                width, height;
 	gdouble                bx1, bx2;
 	GtkAllocation          allocation;
@@ -1001,11 +1006,16 @@
 
 	/* Put some padding after the right-most coordinate. */
 	bx2 += PADDING;
-		
+
 	width = MAX (width, bx2 - bx1);
 
 	x2 = x1 + width;
-	
+
+	gantt_chart_get_visible_region(chart, &vx1, &vy1, &vx2, &vy2);
+
+	x2 = MAX (x2, vx2);
+	y2 = MAX (y2, vy2);
+
 	gantt_chart_set_scroll_region (chart,
 				       x1,
 				       y1,
@@ -1025,8 +1035,8 @@
 	return FALSE;
 }
 
-static void
-gantt_chart_reflow_now (PlannerGanttChart *chart)
+void
+planner_gantt_chart_reflow_now (PlannerGanttChart *chart)
 {
 	if (!GTK_WIDGET_MAPPED (chart)) {
 		return;
@@ -1199,7 +1209,7 @@
 		      "project-start", t,
 		      NULL);
 	
-	gantt_chart_reflow_now (chart);
+	planner_gantt_chart_reflow_now (chart);
 }
 
 static void
@@ -1521,7 +1531,7 @@
 		 * start-up .
 		 */
 		priv->height_changed = TRUE;
-		gantt_chart_reflow_now (chart);
+		planner_gantt_chart_reflow_now (chart);
 	}
 	
 	g_object_notify (G_OBJECT (chart), "model");
@@ -1661,6 +1671,25 @@
 }
 
 static void
+gantt_chart_get_visible_region (PlannerGanttChart *chart,
+			       gdouble            *x1,
+			       gdouble            *y1,
+			       gdouble            *x2,
+			       gdouble            *y2)
+{
+	GnomeCanvas *canvas;
+	gint cx, cy;
+	
+	canvas = chart->priv->canvas;
+
+	gnome_canvas_get_scroll_offsets(canvas, &cx, &cy);
+	gnome_canvas_c2w(canvas, cx, cy, x1, y1);
+
+	*x2 = *x1 + GTK_WIDGET(canvas)->allocation.width;
+	*y2 = *y1 + GTK_WIDGET(canvas)->allocation.height;
+}
+
+static void
 gantt_chart_set_scroll_region (PlannerGanttChart *chart,
 			       gdouble            x1,
 			       gdouble            y1,
@@ -1750,7 +1779,7 @@
 			       "zoom", priv->zoom,
 			       NULL);
 
-	gantt_chart_reflow_now (chart);
+	planner_gantt_chart_reflow_now (chart);
 }
 
 static mrptime 

Modified: trunk/src/planner-gantt-chart.h
==============================================================================
--- trunk/src/planner-gantt-chart.h	(original)
+++ trunk/src/planner-gantt-chart.h	Fri Feb 15 21:36:53 2008
@@ -82,6 +82,7 @@
 						       const gchar       *message);
 void             planner_gantt_chart_resource_clicked (PlannerGanttChart *chart,
 						       MrpResource       *resource);
+void             planner_gantt_chart_reflow_now       (PlannerGanttChart *chart);
 
 void
 planner_gantt_chart_set_highlight_critical_tasks      (PlannerGanttChart  *chart,

Modified: trunk/src/planner-gantt-row.c
==============================================================================
--- trunk/src/planner-gantt-row.c	(original)
+++ trunk/src/planner-gantt-row.c	Fri Feb 15 21:36:53 2008
@@ -281,6 +281,17 @@
 static GdkBitmap            *break_stipple = NULL;
 static gchar                 break_stipple_pattern[] = { 0x03 };
 
+/* Data related to dragging items */
+static GnomeCanvasItem   *drag_item;
+static gdouble            drag_item_wx_min;
+static gdouble            drag_item_wx_max;
+static gdouble            drag_item_wy_min;
+static gdouble            drag_item_wy_max;
+static gdouble            drag_wx1, drag_wy1;
+static GnomeCanvasPoints *drag_points = NULL;
+static GnomeCanvasItem   *target_item;
+static GnomeCanvasItem   *old_target_item;
+
 GType
 planner_gantt_row_get_type (void)
 {
@@ -2282,45 +2293,197 @@
 	g_list_free (resources);
 }
 
-static gboolean
-gantt_row_scroll_timeout_cb (PlannerGanttRow *row)
+static gboolean 
+gantt_row_drag_item_to_pointer (PlannerGanttRow *row, gboolean scroll)
 {
-	GtkWidget *widget;
+	PlannerGanttChart *chart;
+	GnomeCanvas *canvas;
 	gint       width, height;
-	gint       x, y, dx = 0, dy = 0;
+	gint       x, y, item_cx, item_cy;
+	gint       cx, cy;
+	gdouble    wx2, wy2;
+	gint dx, dy;
+
+	gint         duration;
+	gint         work;
+	MrpProject  *project;
+	gchar       *message;
+
+	gint        percent_complete;
+
+	canvas = GNOME_CANVAS_ITEM (row)->canvas;
+	chart = g_object_get_data (G_OBJECT (GNOME_CANVAS_ITEM (row)->canvas), "chart");
 
-	widget = GTK_WIDGET (GNOME_CANVAS_ITEM (row)->canvas);
 	
 	/* Get the current mouse position so that we can decide if the pointer
 	 * is inside the viewport.
 	 */
-	gdk_window_get_pointer (widget->window, &x, &y, NULL);
+	gdk_window_get_pointer (GTK_WIDGET(canvas)->window, &x, &y, NULL);
+
+	gnome_canvas_get_scroll_offsets (canvas, &cx, &cy);
+
+	width = GTK_WIDGET(canvas)->allocation.width;
+	height = GTK_WIDGET(canvas)->allocation.height;
+
+	if(!scroll)
+	{
+		x = CLAMP(x, 0, width - 1);
+		y = CLAMP(y, 0, height - 1);
+	}
+
+	gnome_canvas_c2w (canvas, cx + x, cy + y, &wx2, &wy2);
+
+  	if(drag_item_wx_min != -1.0) wx2 = MAX(wx2, drag_item_wx_min);
+  	if(drag_item_wx_max != -1.0) wx2 = MIN(wx2, drag_item_wx_max);
+  	if(drag_item_wy_min != -1.0) wy2 = MAX(wy2, drag_item_wy_min);
+  	if(drag_item_wy_max != -1.0) wy2 = MIN(wy2, drag_item_wy_max);
+
+	switch(row->priv->state)
+	{
+	case STATE_DRAG_DURATION:
+
+		project = mrp_object_get_project (MRP_OBJECT (row->priv->task));
+
+		duration = MAX (0, (wx2 - row->priv->x_start) / row->priv->scale);
+
+		/* Snap to quarters. */
+		duration = floor (duration / SNAP + 0.5) * SNAP;
+
+		work = mrp_project_calculate_task_work (
+			project,
+			row->priv->task,
+			-1,
+			mrp_task_get_start (row->priv->task) + duration);
+
+		message = g_strdup_printf (_("Change work to %s"),
+					   planner_format_duration (project, work));
+		planner_gantt_chart_status_updated (chart, message);
+		g_free (message);
+
+		gnome_canvas_item_set (drag_item,
+				       "x2", wx2,
+				       NULL);
+		break;
+
+	case STATE_DRAG_COMPLETE:
+		percent_complete = floor ((CLAMP(wx2 - row->priv->x, 0, row->priv->width) * 100.0) / row->priv->width + 0.5);
+		message = g_strdup_printf (_("Change progress to %u%% complete"), percent_complete);
+		planner_gantt_chart_status_updated (chart, message);
+		g_free (message);
+
+		gnome_canvas_item_set (drag_item,
+				       "x2", wx2,
+				       NULL);
+		break;
+	case STATE_DRAG_LINK:
+		target_item = gnome_canvas_get_item_at (canvas, wx2, wy2);
+		
+		drag_points->coords[0] = drag_wx1;
+		drag_points->coords[1] = drag_wy1;
+		drag_points->coords[2] = wx2;
+		drag_points->coords[3] = wy2;
+	
+		gnome_canvas_item_set (drag_item,
+				       "points", drag_points,
+				       NULL);
+		
+		if (old_target_item && old_target_item != target_item) {
+			g_object_set (old_target_item,
+				      "highlight",
+				      FALSE,
+				      NULL);
+		}
+		
+		if (target_item && target_item != GNOME_CANVAS_ITEM(row)) {
+			const gchar *task_name, *target_name;
+			
+			g_object_set (target_item,
+				      "highlight",
+				      TRUE,
+				      NULL);
+
+			target_name = mrp_task_get_name (PLANNER_GANTT_ROW (target_item)->priv->task);
+			task_name = mrp_task_get_name (row->priv->task);
+			
+			if (target_name == NULL || target_name[0] == 0) {
+				target_name = _("No name");
+			}
+			if (task_name == NULL || task_name[0] == 0) {
+				task_name = _("No name");
+			}
+			
+			message = g_strdup_printf (_("Make task '%s' a predecessor of '%s'"),
+						   task_name,
+						   target_name);
+
+			planner_gantt_chart_status_updated (chart, message);
+
+			g_free (message);
+		}
+
+		if (target_item == NULL) {
+			planner_gantt_chart_status_updated (chart, NULL);
+		}
+		
+		old_target_item = target_item;
+		break;
+	default:
+		g_assert (FALSE);
+		break;
+	}
 
-	width = widget->allocation.width;
-	height = widget->allocation.height;
+	if(!scroll) return TRUE;
+
+	gnome_canvas_w2c (canvas, wx2, wy2, &item_cx, &item_cy);
 
 	if (x < 0) {
-		dx = x;
-	} else if (x >= widget->allocation.width) {
-		dx = x - widget->allocation.width + 1;
+		dx = MAX(x, (item_cx - cx) - width / 2);
+		dx = MIN(dx, 0);
+	} else if (x >= width) {
+		dx = MIN(x - width + 1, (item_cx - cx) - width/2);
+		dx = MAX(dx, 0);
 	} else {
 		dx = 0;
 	}
 
 	if (y < 0) {
 		dy = y;
-	} else if (y >= widget->allocation.height) {
-		dy = y - widget->allocation.height + 1;
+	} else if (y >= height) {
+		dy = y - height + 1;
 	} else {
 		dy = 0;
 	}
 	
-	gantt_row_canvas_scroll (widget, dx, dy);
-	
+	if(dx > 0)
+	{
+		planner_gantt_chart_reflow_now(chart);
+		gantt_row_canvas_scroll (GTK_WIDGET(canvas), dx, dy);
+	}
+	else if(dx < 0)
+	{
+		gantt_row_canvas_scroll (GTK_WIDGET(canvas), dx, dy);
+		planner_gantt_chart_reflow_now(chart);
+	}
+	else
+	{
+		if(dy != 0)
+		{
+			gantt_row_canvas_scroll (GTK_WIDGET(canvas), dx, dy);
+		}
+		planner_gantt_chart_reflow_now(chart);
+	}
+
 	return TRUE;
 }
 
-static DragSpot get_drag_spot(gdouble x, gdouble y, PlannerGanttRowPriv *priv)
+static gboolean
+gantt_row_scroll_timeout_cb (PlannerGanttRow *row)
+{
+	return gantt_row_drag_item_to_pointer(row, TRUE);
+}
+
+static DragSpot 
+get_drag_spot(gdouble x, gdouble y, PlannerGanttRowPriv *priv)
 {
 	gdouble x2 = priv->x + priv->width;
 	if( (y > priv->y + priv->bar_top) &&
@@ -2370,19 +2533,13 @@
 	PlannerGanttRowPriv      *priv;
 	PlannerGanttChart        *chart;
 	GtkWidget                *canvas_widget;
-	static gdouble            x1, y1;
 	gdouble                   wx1, wy1;
 	gdouble                   wx2, wy2;
-	static GnomeCanvasItem   *target_item;
-	static GnomeCanvasItem   *old_target_item;
-	static GnomeCanvasItem   *drag_item = NULL;
-	static GnomeCanvasPoints *drag_points = NULL;
 	MrpTask                  *task;
 	MrpTask                  *target_task;
 	GdkCursor                *cursor;
 	gboolean                  summary;
 	MrpTaskType               type;
-	gchar                    *message;
 	DragSpot                  drag_spot;
 	
 	row = PLANNER_GANTT_ROW (item);
@@ -2477,6 +2634,12 @@
 									   "width_pixels", 1,
 									   NULL);
 					gnome_canvas_item_hide (drag_item);
+
+					/* set limits */
+					drag_item_wx_min = wx1;
+					drag_item_wx_max = -1.0;
+					drag_item_wy_min = wy1;
+					drag_item_wy_max = wy2;
 				}
 
 				/* Start the autoscroll timeout. */
@@ -2513,6 +2676,12 @@
 									   "width_pixels", 1,
 									   NULL);
 					gnome_canvas_item_hide (drag_item);
+
+					/* set limits */
+					drag_item_wx_min = wx1;
+					drag_item_wx_max = priv->x + priv->width;
+					drag_item_wy_min = wy1;
+					drag_item_wy_max = wy2;
 				}
 
 				/* Start the autoscroll timeout. */
@@ -2539,6 +2708,12 @@
 								   NULL);
 				gnome_canvas_item_hide (drag_item);
 
+				/* set limits */
+				gnome_canvas_get_scroll_region(item->canvas, &drag_item_wx_min, 
+									     &drag_item_wy_min,
+									     &drag_item_wx_max,
+									     &drag_item_wy_max);
+
 				old_target_item = NULL;
 
 				/* Start the autoscroll timeout. */
@@ -2581,8 +2756,8 @@
 						NULL,
 						event->button.time);
 
-			x1 = event->button.x;
-			y1 = event->button.y;
+			drag_wx1 = event->button.x;
+			drag_wy1 = event->button.y;
 
 			return TRUE;
 
@@ -2612,7 +2787,7 @@
 			gint x, y;
 
 			gdk_window_get_pointer (event->motion.window, &x, &y, NULL);
-			gnome_canvas_c2w (item->canvas, x, y, &event->motion.x, &event->motion.y);
+			gnome_canvas_window_to_world(item->canvas, x, y, &event->motion.x, &event->motion.y);
 		}
 
 		if (!(priv->state & STATE_DRAG_ANY)) {
@@ -2656,121 +2831,11 @@
 			}
 			return TRUE;
 		}
-		else if (priv->state == STATE_DRAG_LINK) {
-			target_item = gnome_canvas_get_item_at (item->canvas,
-								event->motion.x,
-								event->motion.y);
-			
-			gnome_canvas_item_raise_to_top (drag_item);
-			gnome_canvas_item_show (drag_item);
-			
-			drag_points->coords[0] = x1;
-			drag_points->coords[1] = y1;
-			drag_points->coords[2] = event->motion.x;
-			drag_points->coords[3] = event->motion.y;
-		
-			gnome_canvas_item_set (drag_item,
-					       "points", drag_points,
-					       NULL);
-			
-			chart = g_object_get_data (G_OBJECT (item->canvas),
-						   "chart");
-			
-			if (old_target_item && old_target_item != target_item) {
-				g_object_set (old_target_item,
-					      "highlight",
-					      FALSE,
-					      NULL);
-			}
-			
-			if (target_item && target_item != item) {
-				const gchar *task_name, *target_name;
-				
-				g_object_set (target_item,
-					      "highlight",
-					      TRUE,
-					      NULL);
-
-				target_name = mrp_task_get_name (PLANNER_GANTT_ROW (target_item)->priv->task);
-				task_name = mrp_task_get_name (priv->task);
-				
-				if (target_name == NULL || target_name[0] == 0) {
-					target_name = _("No name");
-				}
-				if (task_name == NULL || task_name[0] == 0) {
-					task_name = _("No name");
-				}
-				
-				message = g_strdup_printf (_("Make task '%s' a predecessor of '%s'"),
-							   task_name,
-							   target_name);
-
-				planner_gantt_chart_status_updated (chart, message);
-
-				g_free (message);
-			}
-
-			if (target_item == NULL) {
-				planner_gantt_chart_status_updated (chart, NULL);
-			}
-			
-			old_target_item = target_item;
-		}
-		else if (priv->state == STATE_DRAG_COMPLETE) {
-			chart = g_object_get_data (G_OBJECT (item->canvas), "chart");
-
-			wx2 = MIN(event->motion.x, priv->x + priv->width);
-			wy2 = priv->y + priv->bar_bot - 4;
-			
-			gnome_canvas_item_i2w (item, &wx2, &wy2);
-
-			gnome_canvas_item_set (drag_item,
-					       "x2", wx2,
-					       "y2", wy2,
-					       NULL);
-			
-			gnome_canvas_item_raise_to_top (drag_item);
-			gnome_canvas_item_show (drag_item);
-
-			planner_gantt_chart_status_updated (chart, NULL);
-		}
-		else if (priv->state == STATE_DRAG_DURATION) {
-			gint         duration;
-			gint         work;
-			MrpProject  *project;
-
-			project = mrp_object_get_project (MRP_OBJECT (priv->task));
-
-			wx2 = event->motion.x;
-			wy2 = priv->y + priv->bar_bot;
-			
-			gnome_canvas_item_i2w (item, &wx2, &wy2);
-
-			gnome_canvas_item_set (drag_item,
-					       "x2", wx2,
-					       "y2", wy2,
-					       NULL);
-			
+		else {
 			gnome_canvas_item_raise_to_top (drag_item);
 			gnome_canvas_item_show (drag_item);
 
-			chart = g_object_get_data (G_OBJECT (item->canvas), "chart");
-
-			duration = MAX (0, (event->motion.x - priv->x_start) / priv->scale);
-
-			/* Snap to quarters. */
-			duration = floor (duration / SNAP + 0.5) * SNAP;
-
-			work = mrp_project_calculate_task_work (
-				project,
-				priv->task,
-				-1,
-				mrp_task_get_start (priv->task) + duration);
-
-			message = g_strdup_printf (_("Change work to %s"),
-						   planner_format_duration (project, work));
-			planner_gantt_chart_status_updated (chart, message);
-			g_free (message);
+			gantt_row_drag_item_to_pointer (row, FALSE);
 		}
 			
 		break;



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