Esempio n. 1
0
static gboolean
i7_goo_canvas_item_get_onscreen_coordinates(GooCanvasItem *item, GooCanvas *canvas, gint *x, gint *y)
{
	GooCanvasBounds bounds;
	GtkAllocation allocation;
	gdouble canvas_x, canvas_y;
	gdouble top, bottom, left, right, item_x, item_y;

	/* Find out the size and coordinates of the current viewport */
	goo_canvas_get_bounds(canvas, &canvas_x, &canvas_y, NULL, NULL);
	GtkWidget *scrolled_window = gtk_widget_get_parent(GTK_WIDGET(canvas));
	g_assert(GTK_IS_SCROLLED_WINDOW(scrolled_window));
	GtkAdjustment *adj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(scrolled_window));
	left = canvas_x + gtk_adjustment_get_value(adj);
	right = left + gtk_adjustment_get_page_size(adj);
	adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window));
	top = canvas_y + gtk_adjustment_get_value(adj);
	bottom = top + gtk_adjustment_get_page_size(adj);

	/* Make sure item is currently displayed */
	goo_canvas_item_get_bounds(item, &bounds);
	if(bounds.x1 > right || bounds.x2 < left || bounds.y1 > bottom || bounds.y2 < top) {
		g_warning("Node not onscreen in canvas");
		return FALSE;
	}

	/* Find out the onscreen coordinates of the canvas viewport */
	gtk_widget_get_allocation(GTK_WIDGET(canvas), &allocation);

	if(x) {
		item_x = bounds.x1;
		*x = (gint)(item_x - left) + allocation.x;
	}
	if(y) {
		item_y = bounds.y1;
		*y = (gint)(item_y - top) + allocation.y;
	}
	return TRUE;
}
Esempio n. 2
0
/**
 * change the zoom by factor
 *
 * zoom origin when zooming in is the cursor
 * zoom origin when zooming out is the center of the current viewport
 *
 * @param sheet
 * @param factor values should be in the range of [0.5 .. 2]
 */
void
sheet_change_zoom (Sheet *sheet, gdouble factor)
{
	g_return_if_fail (sheet);
	g_return_if_fail (IS_SHEET (sheet));

	Coords adju, r, pointer, delta, center, pagesize;
	GtkAdjustment *hadj = NULL, *vadj = NULL;
	GooCanvas *canvas;
	gboolean b = FALSE;

	canvas = GOO_CANVAS (sheet);

	// if we scroll out, just use the center as focus
	// mouse curser centered scroll out "feels" awkward
	if (factor < 1.) {
		goo_canvas_set_scale (canvas, factor * goo_canvas_get_scale (canvas));
		return;
	}

	// get pointer position in pixels
	// just skip the correction if we can not get the pointer
	if (!sheet_get_pointer_pixel (sheet, &pointer.x, &pointer.y)) {
		goo_canvas_set_scale (canvas, factor * goo_canvas_get_scale (canvas));
		g_warning ("Failed to get cursor position.");
		return;
	}

	// top left corner in pixels
	b = sheet_get_adjustments (sheet, &hadj, &vadj);
	if (b) {
		adju.x = gtk_adjustment_get_value (hadj);
		adju.y = gtk_adjustment_get_value (vadj);
		// get the page size in pixels
		pagesize.x = gtk_adjustment_get_page_size (hadj);
		pagesize.y = gtk_adjustment_get_page_size (vadj);
	} else {
		//FIXME untested codepath, check for variable space conversion
		//FIXME Pixel vs GooUnits
		gdouble left, right, top, bottom;
		goo_canvas_get_bounds (canvas, &left, &top, &right, &bottom);
		pagesize.x = bottom - top;
		pagesize.y = right - left;
		adju.x = adju.y = 0.;
	}

	// calculate the center of the widget in pixels
	center.x = adju.x + pagesize.x/2.;
	center.y = adju.y + pagesize.y/2.;

	// calculate the delta between the center and the pointer in pixels
	// this is required as the center is the zoom target
	delta.x = pointer.x - center.x;
	delta.y = pointer.y - center.y;

	// increase the top left position in pixels by our calculated delta
	adju.x += delta.x;
	adju.y += delta.y;

	//convert to canvas coords
	goo_canvas_convert_from_pixels (canvas, &adju.x, &adju.y);

	//the center of the canvas is now our cursor position
	goo_canvas_scroll_to (canvas, adju.x, adju.y);

	//calculate a correction term
	//for the case that we can not scroll the pane far enough to
	//compensate the whole off-due-to-wrong-center-error

	if (b) {
		r.x = gtk_adjustment_get_value (hadj);
		r.y = gtk_adjustment_get_value (vadj);
		goo_canvas_convert_from_pixels (canvas, &r.x, &r.y);
		//the correction term in goo coordinates, to be subtracted from the backscroll distance
		r.x -= adju.x;
		r.y -= adju.y;
	} else {
		r.x = r.y = 0.;
	}

	// no the center is our cursor position and we can safely call scale
	goo_canvas_set_scale (canvas, factor * goo_canvas_get_scale (canvas));

	// top left corner in pixels after scaling
	if (b) {
		adju.x = gtk_adjustment_get_value (hadj);
		adju.y = gtk_adjustment_get_value (vadj);
	} else {
		adju.x = adju.y = 0.;
	}

	// gtk_adjustment_get_page_size is constant before and after scale
	adju.x -= (delta.x) / sheet->priv->zoom;
	adju.y -= (delta.y) / sheet->priv->zoom;
	goo_canvas_convert_from_pixels (canvas, &adju.x, &adju.y);

	goo_canvas_scroll_to (canvas, adju.x-r.x, adju.y-r.y);

	gtk_widget_queue_draw (GTK_WIDGET (canvas));
}