void object_draw_connectionpoints(DiaObject *obj, DDisplay *ddisp) { int i; static Color midpoint_color = { 1.0, 0.0, 0.0, 1.0 }; DiaRenderer *renderer = ddisp->renderer; DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (ddisp->renderer); DiaInteractiveRendererInterface *irenderer = DIA_GET_INTERACTIVE_RENDERER_INTERFACE (ddisp->renderer); /* this does not change for any of the points */ renderer_ops->set_linewidth (renderer, 0.0); renderer_ops->set_linestyle (renderer, LINESTYLE_SOLID); /* optimization to only draw the connection points at all if the size * of the object (bounding box) is bigger than the summed size of the * connection points - or some variation thereof ;) */ if (dia_object_get_num_connections(obj) > 1) { const Rectangle *bbox = dia_object_get_bounding_box (obj); real w = ddisplay_transform_length (ddisp, bbox->right - bbox->left); real h = ddisplay_transform_length (ddisp, bbox->bottom - bbox->top); int n = dia_object_get_num_connections(obj); /* just comparing the sizes is still drawing more CPs than useful - try 50% */ if (w * h < n * CONNECTIONPOINT_SIZE * CONNECTIONPOINT_SIZE * 2) { if (ddisp->mainpoint_magnetism) return; /* just draw the main point */ for (i = 0; i < n; ++i) { if (obj->connections[i]->flags & CP_FLAG_ANYPLACE) connectionpoint_draw(obj->connections[i], ddisp, renderer, irenderer, &midpoint_color); } return; } } for (i=0;i<dia_object_get_num_connections(obj);i++) { if ((obj->connections[i]->flags & CP_FLAG_ANYPLACE) == 0) connectionpoint_draw(obj->connections[i], ddisp, renderer, irenderer, &connectionpoint_color); else if (!ddisp->mainpoint_magnetism) /* draw the "whole object"/center connpoints, but only when we don't * have snap-to-grid */ connectionpoint_draw(obj->connections[i], ddisp, renderer, irenderer, &midpoint_color); } }
/* Updates all objects connected to the 'obj' object. Calls this function recursively for objects modified. If update_nonmoved is TRUE, also objects that have not moved since last time is updated. This is not propagated in the recursion. */ void diagram_update_connections_object(Diagram *dia, DiaObject *obj, int update_nonmoved) { int i,j; ConnectionPoint *cp; GList *list; DiaObject *connected_obj; Handle *handle; for (i=0;i<dia_object_get_num_connections(obj);i++) { cp = obj->connections[i]; if ((update_nonmoved) || (distance_point_point_manhattan(&cp->pos, &cp->last_pos) > CHANGED_TRESHOLD)) { cp->last_pos = cp->pos; list = cp->connected; while (list!=NULL) { connected_obj = (DiaObject *) list->data; object_add_updates(connected_obj, dia); handle = NULL; for (j=0;j<connected_obj->num_handles;j++) { if (connected_obj->handles[j]->connected_to == cp) { handle = connected_obj->handles[j]; connected_obj->ops->move_handle(connected_obj, handle, &cp->pos, cp, HANDLE_MOVE_CONNECTED,0); } } object_add_updates(connected_obj, dia); diagram_update_connections_object(dia, connected_obj, FALSE); list = g_list_next(list); } } } if (obj->children) { GList *child; for (child = obj->children; child != NULL; child = child->next) { DiaObject *child_obj = (DiaObject *)child->data; diagram_update_connections_object(dia, child_obj, update_nonmoved); } } }
/** Find a connectionpoint sufficiently close to the given point. * * @param ddisp The display to search * @param pos A position in the display, typically mouse position * @param notthis If not null, an object to ignore (typically the object * connecting) * @param snap_to_objects Whether snapping to objects should be in effect * in this call (anded to the display-wide setting). */ ConnectionPoint * object_find_connectpoint_display(DDisplay *ddisp, Point *pos, DiaObject *notthis, gboolean snap_to_objects) { real distance; ConnectionPoint *connectionpoint; GList *avoid = NULL; DiaObject *obj_here; distance = diagram_find_closest_connectionpoint(ddisp->diagram, &connectionpoint, pos, notthis); distance = ddisplay_transform_length(ddisp, distance); if (distance < OBJECT_CONNECT_DISTANCE) { return connectionpoint; } if (ddisp->mainpoint_magnetism && snap_to_objects) { DiaObject *parent; /* Try to find an all-object CP. */ /* Don't pick a parent, though */ avoid = g_list_prepend(avoid, notthis); for (parent = notthis->parent; parent != NULL; parent = parent->parent) { avoid = g_list_prepend(avoid, parent); } obj_here = diagram_find_clicked_object_except(ddisp->diagram, pos, 0.00001, avoid); if (obj_here != NULL) { int i; for (i = 0; i < dia_object_get_num_connections(obj_here); ++i) { if (obj_here->connections[i]->flags & CP_FLAG_ANYPLACE) { g_list_free(avoid); return obj_here->connections[i]; } } } } return NULL; }
void object_add_updates(DiaObject *obj, Diagram *dia) { int i; /* Bounding box */ if (data_object_get_highlight(dia->data,obj) != DIA_HIGHLIGHT_NONE) { diagram_add_update_with_border(dia, dia_object_get_enclosing_box (obj), 5); } else { diagram_add_update(dia, dia_object_get_enclosing_box (obj)); } /* Handles */ for (i=0; i<obj->num_handles; i++) { handle_add_update(obj->handles[i], dia); } /* Connection points */ for (i=0; i<dia_object_get_num_connections(obj); ++i) { connectionpoint_add_update(obj->connections[i], dia); } }