void ddisplay_set_origo(DDisplay *ddisp, coord x, coord y) { Rectangle *extents = &ddisp->diagram->data->extents; Rectangle *visible = &ddisp->visible; int width, height; g_return_if_fail (ddisp->renderer != NULL); /* updaterar origo+visible+rulers */ ddisp->origo.x = x; ddisp->origo.y = y; if (ddisp->zoom_factor<DDISPLAY_MIN_ZOOM) ddisp->zoom_factor = DDISPLAY_MIN_ZOOM; if (ddisp->zoom_factor > DDISPLAY_MAX_ZOOM) ddisp->zoom_factor = DDISPLAY_MAX_ZOOM; width = dia_renderer_get_width_pixels (ddisp->renderer); height = dia_renderer_get_height_pixels (ddisp->renderer); visible->left = ddisp->origo.x; visible->top = ddisp->origo.y; visible->right = ddisp->origo.x + ddisplay_untransform_length(ddisp, width); visible->bottom = ddisp->origo.y + ddisplay_untransform_length(ddisp, height); ddisplay_update_rulers (ddisp, extents, visible); }
/** Scroll display to where point x,y (window coords) is visible */ gboolean ddisplay_autoscroll(DDisplay *ddisp, int x, int y) { guint16 width, height; Point scroll; if (! ddisp->autoscroll) return FALSE; scroll.x = scroll.y = 0; width = GTK_WIDGET(ddisp->canvas)->allocation.width; height = GTK_WIDGET(ddisp->canvas)->allocation.height; if (x < 0) { scroll.x = x; } else if ( x > width) { scroll.x = x - width; } if (y < 0) { scroll.y = y; } else if (y > height) { scroll.y = y - height; } if ((scroll.x != 0) || (scroll.y != 0)) { gboolean scrolled; scroll.x = ddisplay_untransform_length(ddisp, scroll.x); scroll.y = ddisplay_untransform_length(ddisp, scroll.y); scrolled = ddisplay_scroll(ddisp, &scroll); if (scrolled) { ddisplay_flush(ddisp); return TRUE; } } return FALSE; }
void ddisplay_add_update_pixels(DDisplay *ddisp, Point *point, int pixel_width, int pixel_height) { Rectangle rect; real size_x, size_y; size_x = ddisplay_untransform_length(ddisp, pixel_width+1); size_y = ddisplay_untransform_length(ddisp, pixel_height+1); rect.left = point->x - size_x/2.0; rect.top = point->y - size_y/2.0; rect.right = point->x + size_x/2.0; rect.bottom = point->y + size_y/2.0; ddisplay_add_update(ddisp, &rect); }
/** Marks a rectangle for update, with a pixel border around it. */ void ddisplay_add_update_with_border(DDisplay *ddisp, const Rectangle *rect, int pixel_border) { Rectangle r; real size = ddisplay_untransform_length(ddisp, pixel_border+1); r.left = rect->left-size; r.top = rect->top-size; r.right = rect->right+size; r.bottom = rect->bottom+size; ddisplay_add_update(ddisp, &r); }
void pagebreak_draw(DDisplay *ddisp, Rectangle *update) { DiaRenderer *renderer = ddisp->renderer; DiaInteractiveRendererInterface *irenderer; int width = dia_renderer_get_width_pixels(ddisp->renderer); int height = dia_renderer_get_height_pixels(ddisp->renderer); irenderer = DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer); if (prefs.pagebreak.visible) { Diagram *dia = ddisp->diagram; real origx = 0, origy = 0, pos; real pwidth = dia->data->paper.width; real pheight = dia->data->paper.height; int x,y; DIA_RENDERER_GET_CLASS(renderer)->set_linewidth(renderer, 0.0); if (prefs.pagebreak.solid) DIA_RENDERER_GET_CLASS(renderer)->set_linestyle(renderer, LINESTYLE_SOLID, 0.0); else DIA_RENDERER_GET_CLASS(renderer)->set_linestyle(renderer, LINESTYLE_DOTTED, ddisplay_untransform_length(ddisp, 31)); if (dia->data->paper.fitto) { origx = dia->data->extents.left; origy = dia->data->extents.top; } /* vertical lines ... */ pos = origx + ceil((update->left - origx) / pwidth) * pwidth; while (pos <= update->right) { ddisplay_transform_coords(ddisp, pos,0,&x,&y); irenderer->draw_pixel_line(renderer, x, 0, x, height, &dia->pagebreak_color); pos += pwidth; } /* Horizontal lines: */ pos = origy + ceil((update->top - origy) / pheight) * pheight; while (pos <= update->bottom) { ddisplay_transform_coords(ddisp, 0,pos,&x,&y); irenderer->draw_pixel_line(renderer, 0, y, width, y, &dia->pagebreak_color); pos += pheight; } } }
static void grid_draw_horizontal_lines(DDisplay *ddisp, Rectangle *update, real length) { int x, y; real pos; int height, width; guint major_lines = ddisp->diagram->grid.major_lines; DiaRenderer *renderer = ddisp->renderer; DiaInteractiveRendererInterface *irenderer; int major_count = 0; irenderer = DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer); pos = ceil( update->top / length ) * length; ddisplay_transform_coords(ddisp, update->left, pos, &x, &y); ddisplay_transform_coords(ddisp, update->right, update->bottom, &width, &height); /* Explanatory note from Lawrence Withers ([email protected]): Think about it in terms of the maths and the modulo arithmetic; we have a number P such that P < 0, and we want to find a number Q such that Q >= 0, but (P % major_count) == (Q % major_count). To do this, we say Q = P - (P * major_count), which is guaranteed to give a correct answer if major_count > 0 (since the addition of anf multiple of major_count won't alter the modulo). */ if (major_lines) { major_count = ROUND (pos/length); if(major_count < 0) major_count -= major_lines * major_count; major_count %= major_lines; } while (y < height) { if (major_lines) { if (major_count == 0) DIA_RENDERER_GET_CLASS(renderer)->set_linestyle(renderer, LINESTYLE_SOLID, 0.0); else DIA_RENDERER_GET_CLASS(renderer)->set_linestyle(renderer, LINESTYLE_DOTTED, ddisplay_untransform_length(ddisp, 31)); major_count = (major_count+1)%major_lines; } irenderer->draw_pixel_line(renderer, x, y, width, y, &ddisp->diagram->grid.colour); pos += length; ddisplay_transform_coords(ddisp, update->left, pos, &x, &y); } }
/** Calculate the width (in cm) of the gap between grid lines in dynamic * grid mode. */ static void calculate_dynamic_grid(DDisplay *ddisp, real *width_x, real *width_y) { real zoom = ddisplay_untransform_length(ddisp, 1.0); real ret, tmp; /* Twiddle zoom to make change-over appropriate */ zoom *= 5; ret = pow(10, ceil(log10(zoom))); /* dont' make it too small or huge (this is in pixels) */ tmp = ddisplay_transform_length(ddisp, ret); if (tmp < 10.0) ret *= 2.0; else if (tmp > 35.0) ret /= 2.0; *width_x = ret; *width_y = ret; }
static void grid_draw_vertical_lines(DDisplay *ddisp, Rectangle *update, real length) { int x = 0, y = 0; real pos; int height, width; guint major_lines = ddisp->diagram->grid.major_lines; DiaRenderer *renderer = ddisp->renderer; DiaInteractiveRendererInterface *irenderer; int major_count = 0; irenderer = DIA_GET_INTERACTIVE_RENDERER_INTERFACE (renderer); pos = ceil( update->left / length ) * length; ddisplay_transform_coords(ddisp, update->right, update->bottom, &width, &height); if (major_lines) { major_count = ROUND (pos/length); if(major_count < 0) major_count -= major_lines * major_count; major_count %= major_lines; } while (x < width) { ddisplay_transform_coords(ddisp, pos, update->top, &x, &y); if (major_lines) { if (major_count == 0) DIA_RENDERER_GET_CLASS(renderer)->set_linestyle(renderer, LINESTYLE_SOLID, 0.0); else DIA_RENDERER_GET_CLASS(renderer)->set_linestyle(renderer, LINESTYLE_DOTTED, ddisplay_untransform_length(ddisp, 31)); major_count = (major_count+1)%major_lines; } irenderer->draw_pixel_line(renderer, x, y, x, height, &ddisp->diagram->grid.colour); pos += length; } }
static DiaObject * click_select_object(DDisplay *ddisp, Point *clickedpoint, GdkEventButton *event) { Diagram *diagram; real click_distance; DiaObject *obj; diagram = ddisp->diagram; /* Find the closest object to select it: */ click_distance = ddisplay_untransform_length(ddisp, 3.0); obj = diagram_find_clicked_object(diagram, clickedpoint, click_distance); if (obj!=NULL) { /* Selected an object. */ GList *already; /*printf("Selected object!\n");*/ already = g_list_find(diagram->data->selected, obj); if (already == NULL) { /* Not already selected */ /*printf("Not already selected\n");*/ if (!(event->state & GDK_SHIFT_MASK)) { /* Not Multi-select => remove current selection */ diagram_remove_all_selected(diagram, TRUE); } diagram_select(diagram, obj); /* To be removed once text edit mode is stable. By then, * we don't want to automatically edit selected objects. textedit_activate_object(ddisp, obj, clickedpoint); */ ddisplay_do_update_menu_sensitivity(ddisp); object_add_updates_list(diagram->data->selected, diagram); diagram_flush(diagram); return obj; } else { /* Clicked on already selected. */ /*printf("Already selected\n");*/ /* To be removed once text edit mode is stable. By then, * we don't want to automatically edit selected objects. textedit_activate_object(ddisp, obj, clickedpoint); */ object_add_updates_list(diagram->data->selected, diagram); diagram_flush(diagram); if (event->state & GDK_SHIFT_MASK) { /* Multi-select */ /* Remove the selected selected */ ddisplay_do_update_menu_sensitivity(ddisp); diagram_unselect_object(diagram, (DiaObject *)already->data); diagram_flush(ddisp->diagram); } else { return obj; } } } /* Else part moved to allow union/intersection select */ return NULL; }
static void create_object_button_press(CreateObjectTool *tool, GdkEventButton *event, DDisplay *ddisp) { Point clickedpoint, origpoint; Handle *handle1; Handle *handle2; DiaObject *obj; real click_distance; ddisplay_untransform_coords(ddisp, (int)event->x, (int)event->y, &clickedpoint.x, &clickedpoint.y); origpoint = clickedpoint; snap_to_grid(ddisp, &clickedpoint.x, &clickedpoint.y); click_distance = ddisplay_untransform_length(ddisp, 3.0); obj = dia_object_default_create (tool->objtype, &clickedpoint, tool->user_data, &handle1, &handle2); tool->obj = obj; /* ensure that tool->obj is initialised in case we return early. */ if (!obj) { tool->moving = FALSE; tool->handle = NULL; message_error(_("'%s' creation failed"), tool->objtype ? tool->objtype->name : "NULL"); return; } diagram_add_object(ddisp->diagram, obj); /* Try a connect */ if (handle1 != NULL && handle1->connect_type != HANDLE_NONCONNECTABLE) { ConnectionPoint *connectionpoint; connectionpoint = object_find_connectpoint_display(ddisp, &origpoint, obj, TRUE); if (connectionpoint != NULL) { (obj->ops->move)(obj, &origpoint); } } if (!(event->state & GDK_SHIFT_MASK)) { /* Not Multi-select => remove current selection */ diagram_remove_all_selected(ddisp->diagram, TRUE); } diagram_select(ddisp->diagram, obj); /* Connect first handle if possible: */ if ((handle1!= NULL) && (handle1->connect_type != HANDLE_NONCONNECTABLE)) { object_connect_display(ddisp, obj, handle1, TRUE); } object_add_updates(obj, ddisp->diagram); ddisplay_do_update_menu_sensitivity(ddisp); diagram_flush(ddisp->diagram); if (handle2 != NULL) { tool->handle = handle2; tool->moving = TRUE; tool->last_to = handle2->pos; gdk_pointer_grab (gtk_widget_get_window(ddisp->canvas), FALSE, GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_RELEASE_MASK, NULL, NULL, event->time); ddisplay_set_all_cursor(get_cursor(CURSOR_SCROLL)); } else { diagram_update_extents(ddisp->diagram); tool->moving = FALSE; } }