Пример #1
0
gboolean
rubberband_update (Sheet *sheet, GdkEvent *event)
{
	GList *iter;
	Coords cur, cmin, cmax;
	double dx, dy; // TODO maybe keep track of subpixel changes, make em global/part of the rubberband_info struct and reset on finish
	double width, height,
	       width_ng, height_ng;
	RubberbandInfo *rubberband_info;

	rubberband_info = sheet->priv->rubberband_info;

	g_assert (event->type == GDK_MOTION_NOTIFY);
	cur.x = event->motion.x;
	cur.y = event->motion.y;
	goo_canvas_convert_from_pixels (GOO_CANVAS (sheet), &cur.x, &cur.y);

	width  = fabs(rubberband_info->end.x - rubberband_info->start.x);
	height = fabs(rubberband_info->end.y - rubberband_info->start.y);

	width_ng  = fabs(cur.x - rubberband_info->start.x);
	height_ng = fabs(cur.y - rubberband_info->start.y);

	dx = fabs (width_ng - width);
	dy = fabs (height_ng - height);
	NG_DEBUG ("motion :: dx=%lf, dy=%lf :: x=%lf, y=%lf :: w_ng=%lf, h_ng=%lf", dx, dy, cur.x, cur.y, width_ng, height_ng);

	// TODO FIXME scroll window if needed (use http://developer.gnome.org/goocanvas/stable/GooCanvas.html#goo-canvas-scroll-to)

	if (dx > 0.1 || dy > 0.1) { //a 0.1 change in pixel coords would be the least visible, silently ignore everything else
		rubberband_info->end.x = cur.x;
		rubberband_info->end.y = cur.y;
		cmin.x = MIN(rubberband_info->start.x, rubberband_info->end.x);
		cmin.y = MIN(rubberband_info->start.y, rubberband_info->end.y);
		cmax.x = cmin.x + width_ng;
		cmax.y = cmin.y + height_ng;
#if 1
		for (iter = sheet->priv->items; iter; iter = iter->next) {
			sheet_item_select_in_area (iter->data,
			                           &cmin,
			                           &cmax);
		}
#endif

		g_object_set (GOO_CANVAS_ITEM (rubberband_info->rectangle),
		              "x", cmin.x,
		              "y", cmin.y,
		              "width", width_ng, 
		              "height", height_ng,
		              "visibility", GOO_CANVAS_ITEM_VISIBLE,
		              NULL);
		goo_canvas_item_raise (GOO_CANVAS_ITEM (rubberband_info->rectangle), NULL);
	}
	return TRUE;
}
Пример #2
0
int    
sheet_motion_rubberband (Sheet *sheet, GdkEventMotion *event)
{
	static double width_old = 0, height_old = 0;
	double x, y;
	double height, width;
	
	double dx, dy;
	GList *list = NULL;
	SheetPos p1, p2;

    // Obtains the current pointer position and modifier state.
    // The position is given in coordinates relative to window.
	sheet_get_pointer (sheet, &x, &y);

	if (x < sheet->priv->rubberband->start_x) {
		width = sheet->priv->rubberband->start_x - x;
	}
	else {
		double tmp = x;
		x = sheet->priv->rubberband->start_x;
		width = tmp - sheet->priv->rubberband->start_x;
	}

	if (y < sheet->priv->rubberband->start_y) {
		height = sheet->priv->rubberband->start_y - y;
	}
	else {
		double tmp = y;
		y = sheet->priv->rubberband->start_y;
		height = tmp - sheet->priv->rubberband->start_y;
	}

	p1.x = x;
	p1.y = y;
	p2.x = x + width;
	p2.y = y + height;

	// Scroll the sheet if needed.
	// Need FIX
	/*{
		int width, height;
		int dx = 0, dy = 0;
		GtkAllocation allocation;
		
		sheet_get_pointer (sheet, &x, &y);

		gtk_widget_get_allocation (GTK_WIDGET (sheet), &allocation);
		width = allocation.width;
		height = allocation.height;

		if (_x < 0)
			dx = -1;
		else if (_x > width)
			dx = 1;

		if (_y < 0)
			dy = -1;
		else if (_y > height)
			dy = 1;

		if (!(_x > 0 && _x < width && _y > 0 && _y < height))
			sheet_scroll (sheet, dx * 5, dy * 5);
	}*/

	// Modify the rubberband rectangle if needed
	dx = fabs (width - width_old);
	dy = fabs (height - height_old);
	if (dx > 1.0 || dy > 1.0) {
		// Save old state
		width_old = width;
		height_old = height;

		for (list = sheet->priv->items; list; list = list->next) {
			sheet_item_select_in_area (list->data, &p1, &p2);
		}

		g_object_set (sheet->priv->rubberband->rectangle,
		              "x", (double) x, 
		              "y", (double) y,
		              "width", width, 
		              "height", height,
		              NULL);

		//g_list_free_full (list, g_object_unref); //FIXME
	}
	return TRUE;
}