void diagram_update_extents(Diagram *dia) { gfloat cur_scale = dia->data->paper.scaling; /* anropar update_scrollbars() */ if (data_update_extents(dia->data)) { /* Update scrollbars because extents were changed: */ GSList *l; DDisplay *ddisp; l = dia->displays; while (l!=NULL) { ddisp = (DDisplay *) l->data; ddisplay_update_scrollbars(ddisp); l = g_slist_next(l); } if (cur_scale != dia->data->paper.scaling) { diagram_add_update_all(dia); diagram_flush(dia); } } }
/* When using the mouse wheel button to zoom in and out, it is more intuitive to maintain the drawing zoom center-point based on the cursor position. This can help orientation and prevent the drawing from "jumping" around while zooming in and out. */ void ddisplay_zoom_centered(DDisplay *ddisp, Point *point, real magnify) { Rectangle *visible; real width, height; /* cursor position ratios */ real rx,ry; if ((ddisp->zoom_factor <= DDISPLAY_MIN_ZOOM) && (magnify<=1.0)) return; if ((ddisp->zoom_factor >= DDISPLAY_MAX_ZOOM) && (magnify>=1.0)) return; visible = &ddisp->visible; /* calculate cursor position ratios */ rx = (point->x-visible->left)/(visible->right - visible->left); ry = (point->y-visible->top)/(visible->bottom - visible->top); width = (visible->right - visible->left)/magnify; height = (visible->bottom - visible->top)/magnify; ddisp->zoom_factor *= magnify; /* set new origin based on the calculated ratios before zooming */ ddisplay_set_origo(ddisp, point->x-(width*rx),point->y-(height*ry)); ddisplay_update_scrollbars(ddisp); ddisplay_add_update_all(ddisp); ddisplay_flush(ddisp); update_zoom_status (ddisp); }
static void scroll_motion(ScrollTool *tool, GdkEventMotion *event, DDisplay *ddisp) { Point to; Point delta; /* set the cursor appropriately, and change use_hand if needed */ if (!tool->scrolling) { /* try to minimise the number of cursor type changes */ if ((event->state & GDK_SHIFT_MASK) != 0) { if (!tool->use_hand) { tool->use_hand = TRUE; if (!open_hand_cursor) open_hand_cursor = create_cursor(ddisp->canvas->window, hand_open_data_bits, hand_open_data_width, hand_open_data_height, hand_open_mask_bits, hand_open_data_width/2, hand_open_data_height/2); ddisplay_set_all_cursor(open_hand_cursor); } } else if (tool->use_hand) { tool->use_hand = FALSE; ddisplay_set_all_cursor(scroll_cursor); } return; } ddisplay_untransform_coords(ddisp, event->x, event->y, &to.x, &to.y); if (tool->use_hand) { delta = tool->last_pos; point_sub(&delta, &to); tool->last_pos = to; point_add(&tool->last_pos, &delta); /* we use this so you can scroll past the edge of the image */ point_add(&delta, &ddisp->origo); ddisplay_set_origo(ddisp, delta.x, delta.y); ddisplay_update_scrollbars(ddisp); ddisplay_add_update_all(ddisp); } else { delta = to; point_sub(&delta, &tool->last_pos); point_scale(&delta, 0.5); ddisplay_scroll(ddisp, &delta); tool->last_pos = to; } ddisplay_flush(ddisp); }
void ddisplay_show_all (DDisplay *ddisp) { Diagram *dia; real magnify_x, magnify_y; int width, height; Point middle; g_return_if_fail (ddisp != NULL); dia = ddisp->diagram; width = dia_renderer_get_width_pixels (ddisp->renderer); height = dia_renderer_get_height_pixels (ddisp->renderer); /* if there is something selected show that instead of all exisiting objects */ if (dia->data->selected) { GList *list = dia->data->selected; Rectangle extents = *dia_object_get_enclosing_box ((DiaObject*)list->data); list = g_list_next(list); while (list) { DiaObject *obj = (DiaObject *)list->data; rectangle_union(&extents, dia_object_get_enclosing_box (obj)); list = g_list_next(list); } magnify_x = (real)width / (extents.right - extents.left) / ddisp->zoom_factor; magnify_y = (real)height / (extents.bottom - extents.top) / ddisp->zoom_factor; middle.x = extents.left + (extents.right - extents.left) / 2.0; middle.y = extents.top + (extents.bottom - extents.top) / 2.0; } else { magnify_x = (real)width / (dia->data->extents.right - dia->data->extents.left) / ddisp->zoom_factor; magnify_y = (real)height / (dia->data->extents.bottom - dia->data->extents.top) / ddisp->zoom_factor; middle.x = dia->data->extents.left + (dia->data->extents.right - dia->data->extents.left) / 2.0; middle.y = dia->data->extents.top + (dia->data->extents.bottom - dia->data->extents.top) / 2.0; } ddisplay_zoom (ddisp, &middle, ((magnify_x<magnify_y)?magnify_x:magnify_y)/1.05); ddisplay_update_scrollbars(ddisp); ddisplay_add_update_all(ddisp); ddisplay_flush(ddisp); }
/*! * Called when the widget's window "size, position or stacking" * changes. Needs GDK_STRUCTURE_MASK set. */ static gboolean canvas_configure_event (GtkWidget *widget, GdkEventConfigure *cevent, DDisplay *ddisp) { gboolean new_size = FALSE; int width, height; g_return_val_if_fail (widget == ddisp->canvas, FALSE); if (ddisp->renderer) { width = dia_renderer_get_width_pixels (ddisp->renderer); height = dia_renderer_get_height_pixels (ddisp->renderer); } else { /* We can continue even without a renderer here because * ddisplay_resize_canvas () does the setup for us. */ width = height = 0; } /* Only do this when size is really changing */ if (width != cevent->width || height != cevent->height) { g_print ("Canvas size change...\n"); ddisplay_resize_canvas (ddisp, cevent->width, cevent->height); ddisplay_update_scrollbars(ddisp); /* on resize stop further propagation - does not help */ new_size = TRUE; } /* If the UI is not integrated, resizing should set the resized * window as active. With integrated UI, there is only one window. */ if (is_integrated_ui () == 0) display_set_active(ddisp); /* continue propagation with FALSE */ return new_size; }
/** Scroll the display by delta (diagram coords) */ gboolean ddisplay_scroll(DDisplay *ddisp, Point *delta) { Rectangle *visible = &ddisp->visible; real width = visible->right - visible->left; real height = visible->bottom - visible->top; Rectangle extents = ddisp->diagram->data->extents; real ex_width = extents.right - extents.left; real ex_height = extents.bottom - extents.top; Point new_origo = ddisp->origo; point_add(&new_origo, delta); rectangle_union(&extents, visible); if (new_origo.x < extents.left - ex_width) new_origo.x = extents.left - ex_width; if (new_origo.x+width > extents.right + ex_width) new_origo.x = extents.right - width + ex_width; if (new_origo.y < extents.top - ex_height) new_origo.y = extents.top - ex_height; if (new_origo.y+height > extents.bottom + ex_height) new_origo.y = extents.bottom - height + ex_height; if ( (new_origo.x != ddisp->origo.x) || (new_origo.y != ddisp->origo.y) ) { ddisplay_set_origo(ddisp, new_origo.x, new_origo.y); ddisplay_update_scrollbars(ddisp); ddisplay_add_update_all(ddisp); return TRUE; } return FALSE; }
void ddisplay_zoom(DDisplay *ddisp, Point *point, real magnify) { Rectangle *visible; real width, height, old_zoom; visible = &ddisp->visible; if ((ddisp->zoom_factor <= DDISPLAY_MIN_ZOOM) && (magnify<=1.0)) return; if ((ddisp->zoom_factor >= DDISPLAY_MAX_ZOOM) && (magnify>=1.0)) return; old_zoom = ddisp->zoom_factor; ddisp->zoom_factor = old_zoom * magnify; /* clip once more */ if (ddisp->zoom_factor < DDISPLAY_MIN_ZOOM) ddisp->zoom_factor = DDISPLAY_MIN_ZOOM; else if (ddisp->zoom_factor > DDISPLAY_MAX_ZOOM) ddisp->zoom_factor = DDISPLAY_MAX_ZOOM; /* the real one used - after clipping */ magnify = ddisp->zoom_factor / old_zoom; width = (visible->right - visible->left)/magnify; height = (visible->bottom - visible->top)/magnify; ddisplay_set_origo(ddisp, point->x - width/2.0, point->y - height/2.0); ddisplay_update_scrollbars(ddisp); ddisplay_add_update_all(ddisp); ddisplay_flush(ddisp); update_zoom_status (ddisp); }