예제 #1
0
double canvas_t::set_zoom(double zoom) {
  /* Limit a proposed zoom factor to sane ranges.
   * Specifically the map is allowed to be no smaller than the viewport. */

  canvas_goocanvas *gcanvas = static_cast<canvas_goocanvas *>(this);
  /* get size of visible area in pixels and convert to meters of intended */
  /* zoom by dividing by zoom (which is basically pix/m) */
  const GtkAllocation &dim = widget->allocation;

  double limit;
  int delta;

  if (dim.height < dim.width) {
    limit = dim.height;
    delta = gcanvas->bounds.max.y - gcanvas->bounds.min.y;
  } else {
    limit = dim.width;
    delta = gcanvas->bounds.max.x - gcanvas->bounds.min.x;
  }
  limit *= 0.95 / zoom;

  if (delta < limit) {
    zoom /= (delta / limit);

    printf("Can't zoom further out (%f)\n", zoom);
  }

  goo_canvas_set_scale(GOO_CANVAS(widget), zoom);

  return zoom;
}
예제 #2
0
파일: sheet.c 프로젝트: dionysos-sf/oregano
void
sheet_change_zoom (const Sheet *sheet, gdouble rate)
{
	gdouble scale;
	
	sheet->priv->zoom *= rate;
	scale = goo_canvas_get_scale (GOO_CANVAS (sheet));
	scale = scale * rate;
	goo_canvas_set_scale (GOO_CANVAS (sheet), scale);
}
예제 #3
0
파일: sheet.c 프로젝트: hriesz/oregano-old
/*
 * change the zoom by factor <rate>
 * zoom origin when zooming in is the cursor
 * zoom origin when zooming out is the center of the current viewport
 * sane <rate> values are in range of [0.5 .. 2]
 */
void
sheet_change_zoom (Sheet *sheet, gdouble rate)
{
	g_return_if_fail (sheet);
	g_return_if_fail (IS_SHEET (sheet));
//////////////////////////////////////////////7

	gdouble x, y;
	gdouble rx, ry;
	gdouble px, py;
	gdouble dx, dy;
	gdouble cx, cy;
	gdouble dcx, dcy;
	GtkAdjustment *hadj, *vadj;
	GooCanvas *canvas;

	canvas = GOO_CANVAS (sheet);

	// if we scroll out, just scroll to the center
	if (rate < 1.) {
		goo_canvas_set_scale (canvas, rate * goo_canvas_get_scale (canvas));
		return;
	}

	// top left corner in pixels
	if (sheet_get_adjustments (sheet, &hadj, &vadj)) {
		x = gtk_adjustment_get_value (hadj);
		y = gtk_adjustment_get_value (vadj);
	} else {
		x = y = 0.;
	}

	// get pointer position in pixels
	sheet_get_pointer_pixel (sheet, &px, &py);

	// get the page size in pixels
	dx = gtk_adjustment_get_page_size (hadj);
	dy = gtk_adjustment_get_page_size (vadj);
	// calculate the center of the widget in pixels
	cx = x + dx/2;
	cy = y + dy/2;
	
	// calculate the delta between the center and the pointer in pixels
	// this is required as the center is the zoom target
	dcx = px - cx;
	dcy = py - cy;

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

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

	//the center of the canvas is now our cursor position
	goo_canvas_scroll_to (canvas, x, 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
	rx = gtk_adjustment_get_value (hadj);
	ry = gtk_adjustment_get_value (vadj);
	goo_canvas_convert_from_pixels (canvas, &rx, &ry);
	//the correction term in goo coordinates, to be subtracted from the backscroll distance
	rx -= x;
	ry -= y;

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

	// top left corner in pixels after scaling
	if (sheet_get_adjustments (sheet, &hadj, &vadj)) {
		x = gtk_adjustment_get_value (hadj);
		y = gtk_adjustment_get_value (vadj);
	} else {
		x = y = 0.;
	}
	// not sure if the below part is required, could be zer0
	NG_DEBUG ("rx %lf\n", rx);
	NG_DEBUG ("ry %lf\n", ry);
	NG_DEBUG ("dcx %lf\n", dcx);
	NG_DEBUG ("dcy %lf\n", dcy);
	NG_DEBUG ("\n\n");
	// gtk_adjustment_get_page_size is constant
	x -= (dcx) / sheet->priv->zoom;
	y -= (dcy) / sheet->priv->zoom;
	goo_canvas_convert_from_pixels (canvas, &x, &y);

	goo_canvas_scroll_to (canvas, x-rx, y-ry);

	gtk_widget_queue_draw (GTK_WIDGET (canvas));
}
예제 #4
0
파일: sheet.c 프로젝트: hriesz/oregano-old
static void
sheet_set_zoom (const Sheet *sheet, double zoom)
{
	goo_canvas_set_scale (GOO_CANVAS (sheet), zoom);
	sheet->priv->zoom = zoom;
}
예제 #5
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));
}
예제 #6
0
static void
zoom_changed (GtkAdjustment *adj, GooCanvas *canvas)
{
  goo_canvas_set_scale (canvas, gtk_adjustment_get_value (adj));
}