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);
  }
}
Exemple #2
0
/* 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);
    }    
  }
}
Exemple #3
0
/** 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;
}
Exemple #4
0
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);
    }

}