Exemplo n.º 1
0
static void
implements_move_handle(Implements *implements, Handle *handle,
		 Point *to, HandleMoveReason reason, ModifierKeys modifiers)
{
  Point v1, v2;
  
  assert(implements!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  if (handle->id == HANDLE_MOVE_TEXT) {
    implements->text_pos = *to;
  } else if (handle->id == HANDLE_CIRCLE_SIZE) {
    v1 = implements->connection.endpoints[0];
    point_sub(&v1, &implements->connection.endpoints[1]);
    point_normalize(&v1);
    v2 = *to;
    point_sub(&v2, &implements->connection.endpoints[1]);
    implements->circle_diameter = point_dot(&v1, &v2);
    if (implements->circle_diameter<0.03)
      implements->circle_diameter = 0.03;
  } else {
    v1 = implements->connection.endpoints[1];
    connection_move_handle(&implements->connection, handle->id, to, reason);
    point_sub(&v1, &implements->connection.endpoints[1]);
    point_sub(&implements->text_pos, &v1);
  }

  implements_update_data(implements);
}
Exemplo n.º 2
0
static ObjectChange*
mbr_move_handle(Mbr *mbr, Handle *handle,
		 Point *to, ConnectionPoint *cp,
		 HandleMoveReason reason, ModifierKeys modifiers)
{
  Point p1, p2;
  Point *endpoints;

  assert(mbr!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  if (handle->id == HANDLE_MOVE_MID_POINT) {
    mbr->pm = *to;
  } else  {
    endpoints = &mbr->connection.endpoints[0];
    p1.x = 0.5*(endpoints[0].x + endpoints[1].x);
    p1.y = 0.5*(endpoints[0].y + endpoints[1].y);
    connection_move_handle(&mbr->connection, handle->id, to, cp, reason, modifiers);
    p2.x = 0.5*(endpoints[0].x + endpoints[1].x);
    p2.y = 0.5*(endpoints[0].y + endpoints[1].y);
    point_sub(&p2, &p1);
    point_add(&mbr->pm, &p2);
  }

  mbr_update_data(mbr);
  return NULL;
}
Exemplo n.º 3
0
static void
message_move_handle(Message *message, Handle *handle,
		 Point *to, HandleMoveReason reason, ModifierKeys modifiers)
{
  Point p1, p2;
  Point *endpoints;
  
  assert(message!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  if (handle->id == HANDLE_MOVE_TEXT) {
    message->text_pos = *to;
  } else  {
    endpoints = &message->connection.endpoints[0]; 
    p1.x = 0.5*(endpoints[0].x + endpoints[1].x);
    p1.y = 0.5*(endpoints[0].y + endpoints[1].y);
    connection_move_handle(&message->connection, handle->id, to, reason);
    p2.x = 0.5*(endpoints[0].x + endpoints[1].x);
    p2.y = 0.5*(endpoints[0].y + endpoints[1].y);
    point_sub(&p2, &p1);
    point_add(&message->text_pos, &p2);
  }

  message_update_data(message);
}
Exemplo n.º 4
0
static void
arc_move_handle(Arc *arc, Handle *handle,
		Point *to, HandleMoveReason reason, ModifierKeys modifiers)
{
  assert(arc!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  if (handle->id == HANDLE_MIDDLE) {
    Point a,b;
    real tmp;

    b = *to;
    point_sub(&b, &arc->connection.endpoints[0]);
   
    a = arc->connection.endpoints[1];
    point_sub(&a, &arc->connection.endpoints[0]);

    tmp = point_dot(&a,&b);
    arc->curve_distance =
      sqrt(fabs(point_dot(&b,&b) - tmp*tmp/point_dot(&a,&a)));
    
    if (a.x*b.y - a.y*b.x < 0) 
      arc->curve_distance = -arc->curve_distance;

  } else {
    connection_move_handle(&arc->connection, handle->id, to, reason);
  }

  arc_update_data(arc);
}
Exemplo n.º 5
0
static ObjectChange*
constraint_move_handle(Constraint *constraint, Handle *handle,
		       Point *to, ConnectionPoint *cp,
		       HandleMoveReason reason, ModifierKeys modifiers)
{
  Point p1, p2;
  Point *endpoints;
  
  assert(constraint!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  if (handle->id == HANDLE_MOVE_TEXT) {
    constraint->text_pos = *to;
  } else  {
    endpoints = &constraint->connection.endpoints[0]; 
    p1.x = 0.5*(endpoints[0].x + endpoints[1].x);
    p1.y = 0.5*(endpoints[0].y + endpoints[1].y);
    connection_move_handle(&constraint->connection, handle->id, to, cp, 
			   reason, modifiers);
    connection_adjust_for_autogap(&constraint->connection);
    p2.x = 0.5*(endpoints[0].x + endpoints[1].x);
    p2.y = 0.5*(endpoints[0].y + endpoints[1].y);
    point_sub(&p2, &p1);
    point_add(&constraint->text_pos, &p2);
  }

  constraint_update_data(constraint);

  return NULL;
}
Exemplo n.º 6
0
static ObjectChange* 
measure_move_handle (Measure *measure,
                     Handle *handle,
		     Point *to, ConnectionPoint *cp,
		     HandleMoveReason reason, ModifierKeys modifiers)
{
  connection_move_handle(&measure->connection, handle->id, to, cp, reason, modifiers);
  measure_update_data(measure);
  return NULL;
}
Exemplo n.º 7
0
static void
line_move_handle(Line *line, Handle *handle,
		 Point *to, HandleMoveReason reason, ModifierKeys modifiers)
{
  assert(line!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  connection_move_handle(&line->connection, handle->id, to, reason);

  line_update_data(line);
}
Exemplo n.º 8
0
static ObjectChange*
wanlink_move_handle(WanLink *wanlink, Handle *handle,
		    Point *to, ConnectionPoint *cp,
		    HandleMoveReason reason, ModifierKeys modifiers)
{
  connection_move_handle(&wanlink->connection, handle->id, to, cp,
			 reason, modifiers);
  connection_adjust_for_autogap(&wanlink->connection);

  wanlink_update_data(wanlink);

  return NULL;
}
Exemplo n.º 9
0
static ObjectChange*
annotation_move_handle(Annotation *annotation, Handle *handle,
		       Point *to, ConnectionPoint *cp,
		       HandleMoveReason reason, ModifierKeys modifiers)
{
  Point p1, p2;
  Point *endpoints;
  Connection *conn = (Connection *)annotation;

  g_assert(annotation!=NULL);
  g_assert(handle!=NULL);
  g_assert(to!=NULL);

  if (handle->id == HANDLE_MOVE_TEXT) {
    annotation->text->position = *to;
  } else  {
    endpoints = &(conn->endpoints[0]); 
    if (handle->id == HANDLE_MOVE_STARTPOINT) {
      p1 = endpoints[0];
      connection_move_handle(conn, handle->id, to, cp, reason, modifiers);
      p2 = endpoints[0];
      point_sub(&p2, &p1);
      point_add(&annotation->text->position, &p2);
      point_add(&p2,&(endpoints[1]));
      connection_move_handle(conn, HANDLE_MOVE_ENDPOINT, &p2, NULL, reason, 0);
    } else {      
      p1 = endpoints[1];
      connection_move_handle(conn, handle->id, to, cp, reason, modifiers);
      p2 = endpoints[1];
      point_sub(&p2, &p1);
      point_add(&annotation->text->position, &p2);
    }
  }
  annotation_update_data(annotation);

  return NULL;
}
Exemplo n.º 10
0
Arquivo: line.c Projeto: brunetton/dia
static ObjectChange*
line_move_handle(Line *line, Handle *handle,
		 Point *to, ConnectionPoint *cp,
		 HandleMoveReason reason, ModifierKeys modifiers)
{
  assert(line!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  connection_move_handle(&line->connection, handle->id, to, cp, reason, modifiers);

  line_update_data(line);

  return NULL;
}
Exemplo n.º 11
0
Arquivo: flow.c Projeto: brunetton/dia
static ObjectChange*
flow_move_handle(Flow *flow, Handle *handle,
		 Point *to, ConnectionPoint *cp,
		 HandleMoveReason reason, ModifierKeys modifiers)
{
  Point p1, p2;
  Point *endpoints;
  
  assert(flow!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  if (handle->id == HANDLE_MOVE_TEXT) {
    flow->textpos = *to;
  } else  {
    real dest_length ;
    real orig_length2 ;
    real along_mag, norm_mag ;
    Point along ;

    endpoints = &flow->connection.endpoints[0]; 
    p1 = flow->textpos ;
    point_sub( &p1, &endpoints[0] ) ;

    p2 = endpoints[1] ;
    point_sub( &p2, &endpoints[0] ) ;
    orig_length2= point_dot( &p2, &p2 ) ;
    along = p2 ;
    if ( orig_length2 > 1e-5 ) {
      along_mag = point_dot( &p2, &p1 )/sqrt(orig_length2) ;
      along_mag *= along_mag ;
      norm_mag = point_dot( &p1, &p1 ) ;
      norm_mag = (real)sqrt( (double)( norm_mag - along_mag ) ) ;
      along_mag = (real)sqrt( along_mag/orig_length2 ) ;
      if ( p1.x*p2.y - p1.y*p2.x > 0.0 )
	norm_mag = -norm_mag ;
    } else {
      along_mag = 0.5 ;
      norm_mag = (real)sqrt( (double) point_dot( &p1, &p1 ) ) ;
    }

    connection_move_handle(&flow->connection, handle->id, to, cp, 
			   reason, modifiers);

    p2 = endpoints[1] ;
    point_sub( &p2, &endpoints[0] ) ;
    flow->textpos = endpoints[0] ;
    along = p2 ;
    p2.x = -along.y ;
    p2.y = along.x ;
    dest_length = point_dot( &p2, &p2 ) ;
    if ( dest_length > 1e-5 ) {
      point_normalize( &p2 ) ;
    } else {
      p2.x = 0.0 ; p2.y = -1.0 ; 
    }
    point_scale( &p2, norm_mag ) ;
    point_scale( &along, along_mag ) ;
    point_add( &flow->textpos, &p2 ) ;
    point_add( &flow->textpos, &along ) ;
  }

  flow_update_data(flow);

  return NULL;
}
Exemplo n.º 12
0
static ObjectChange*
bus_move_handle(Bus *bus, Handle *handle,
		Point *to, ConnectionPoint *cp,
		HandleMoveReason reason, ModifierKeys modifiers)
{
  Connection *conn = &bus->connection;
  Point *endpoints;
  static real *parallel=NULL;
  static real *perp=NULL;
  static int max_num=0;
  Point vhat, vhatperp;
  Point u;
  real vlen, vlen2;
  real len_scale;
  int i;

  if (bus->num_handles>max_num) {
    if (parallel!=NULL) {
      g_free(parallel);
      g_free(perp);
    }
    parallel = g_malloc(sizeof(real)*bus->num_handles);
    perp = g_malloc(sizeof(real)*bus->num_handles);
    max_num = bus->num_handles;
  }

  if (handle->id == HANDLE_BUS) {
    handle->pos = *to;
  } else {
    endpoints = &conn->endpoints[0];
    vhat = endpoints[1];
    point_sub(&vhat, &endpoints[0]);
    if ((fabs(vhat.x) == 0.0) && (fabs(vhat.y)==0.0)) {
      vhat.x += 0.01;
    }
    vlen = sqrt(point_dot(&vhat, &vhat));
    point_scale(&vhat, 1.0/vlen);
    
    vhatperp.x = -vhat.y;
    vhatperp.y =  vhat.x;
    for (i=0;i<bus->num_handles;i++) {
      u = bus->handles[i]->pos;
      point_sub(&u, &endpoints[0]);
      parallel[i] = point_dot(&vhat, &u);
      perp[i] = point_dot(&vhatperp, &u);
    }
    
    connection_move_handle(&bus->connection, handle->id, to, cp, 
			   reason, modifiers);

    vhat = endpoints[1];
    point_sub(&vhat, &endpoints[0]);
    if ((fabs(vhat.x) == 0.0) && (fabs(vhat.y)==0.0)) {
      vhat.x += 0.01;
    }
    vlen2 = sqrt(point_dot(&vhat, &vhat));
    len_scale = vlen2 / vlen;
    point_normalize(&vhat);
    vhatperp.x = -vhat.y;
    vhatperp.y =  vhat.x;
    for (i=0;i<bus->num_handles;i++) {
      if (bus->handles[i]->connected_to == NULL) {
	u = vhat;
	point_scale(&u, parallel[i]*len_scale);
	point_add(&u, &endpoints[0]);
	bus->parallel_points[i] = u;
	u = vhatperp;
	point_scale(&u, perp[i]);
	point_add(&u, &bus->parallel_points[i]);
	bus->handles[i]->pos = u;
	}
    }
  }

  bus_update_data(bus);

  return NULL;
}
Exemplo n.º 13
0
/*!
 * Moving handles of a lifeline
 *
 * - the top handle is usually connected to an object, when moved connected
 * the whole lifeline is moved horizontally (but may not any longer vertically).
 * - the top box handle is used to move the whole box vertically.
 * - the bottom box handle should maybe resize the box without changing the 
 *   connection point distance, i.e. adding/removing some (maybe limited
 *   by connected points)
 * - the bottom handle just move itself, not beyond the lower box handle
 */
static ObjectChange*
lifeline_move_handle(Lifeline *lifeline, Handle *handle,
		     Point *to, ConnectionPoint *cp,
		     HandleMoveReason reason, ModifierKeys modifiers)
{
  real s, dy;
  Connection *conn;

  assert(lifeline!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  conn = &lifeline->connection;
  if (handle->id == HANDLE_BOXBOT) {
    /* distance between upper handle and boxtop must not be smaller than zero */
    dy = to->y - conn->endpoints[0].y;
    if (dy > lifeline_rect_size(lifeline)) {
      real dist = dy - lifeline->rbot;
      real di;
      
      modf (dist, &di);
      /* the integer part gives the number of points to add or remove */
      if (fabs (di) > 0) {
        int ni = (int)di;

	if (lifeline_point_above_mid (lifeline, to) ? 
	      lifeline->northeast->num_connections + ni > 0 :
	      lifeline->southeast->num_connections + ni > 0)
	  return lifeline_create_change (lifeline, ni > 0 ? LIFELINE_CHANGE_ADD : LIFELINE_CHANGE_DEL, to);
	else
	  return NULL;
      }
    }
  } else if (handle->id == HANDLE_BOXMID) {
    /* the box can not move over the top - same logic, but old movement behavior as above */
    real dist = (to->y - handle->pos.y); /* the potential movement */
    if (dist > 0 ||
        -dist < lifeline->rtop) {
      lifeline->rbot += dist;
      lifeline->rtop = lifeline->rbot - lifeline_rect_size(lifeline);
    }
  } else if (handle->id == HANDLE_BOXTOP) {
    /* Distance between upper handle and boxtop must not be smaller than zero,
     * Same for boxbot and lower handle */
    dy = to->y - conn->endpoints[0].y;
    if (dy > 0 && 
      dy + lifeline_rect_size(lifeline) < conn->endpoints[1].y) {
      lifeline->rtop = dy;
    }
  } else {
    /* move horizontally only if startpoint is moved */
    if (handle->id==HANDLE_MOVE_STARTPOINT) {
      conn->endpoints[0].x = conn->endpoints[1].x = to->x;
    } else {
      to->x = conn->endpoints[0].x;
    }
    /* If connected don't change size */
    dy = (reason==HANDLE_MOVE_CONNECTED) ? 
	  conn->endpoints[1].y - conn->endpoints[0].y : lifeline->rbot;
    connection_move_handle(conn, handle->id, to, cp, reason, modifiers);
    s = conn->endpoints[1].y - conn->endpoints[0].y;
    if (handle->id==HANDLE_MOVE_ENDPOINT && s < dy && 
        s > lifeline->rtop + LIFELINE_BOXMINHEIGHT)
      lifeline->rbot = s;
    else if (reason==HANDLE_MOVE_CONNECTED || s < dy)
      conn->endpoints[1].y = conn->endpoints[0].y + dy;
  }

  lifeline_update_data(lifeline);

  return NULL;
}
Exemplo n.º 14
0
Arquivo: bus.c Projeto: GNOME/dia
static ObjectChange*
bus_move_handle(Bus *bus, Handle *handle,
		Point *to, ConnectionPoint *cp,
		HandleMoveReason reason, ModifierKeys modifiers)
{
  Connection *conn = &bus->connection;
  Point *endpoints;
  real *parallel=NULL;
  real *perp=NULL;
  Point vhat, vhatperp;
  Point u;
  real vlen, vlen2;
  real len_scale;
  int i;
  const int num_handles = bus->num_handles; /* const to help scan-build */

  /* code copied to Misc/tree.c */
  parallel = (real *)g_alloca (num_handles * sizeof(real));
  perp = (real *)g_alloca (num_handles * sizeof(real));

  if (handle->id == HANDLE_BUS) {
    handle->pos = *to;
  } else {
    endpoints = &conn->endpoints[0];
    vhat = endpoints[1];
    point_sub(&vhat, &endpoints[0]);
    if ((fabs(vhat.x) == 0.0) && (fabs(vhat.y)==0.0)) {
      vhat.x += 0.01;
    }
    vlen = sqrt(point_dot(&vhat, &vhat));
    point_scale(&vhat, 1.0/vlen);

    vhatperp.x = -vhat.y;
    vhatperp.y =  vhat.x;
    for (i=0;i<num_handles;i++) {
      u = bus->handles[i]->pos;
      point_sub(&u, &endpoints[0]);
      parallel[i] = point_dot(&vhat, &u);
      perp[i] = point_dot(&vhatperp, &u);
    }

    connection_move_handle(&bus->connection, handle->id, to, cp,
			   reason, modifiers);

    vhat = endpoints[1];
    point_sub(&vhat, &endpoints[0]);
    if ((fabs(vhat.x) == 0.0) && (fabs(vhat.y)==0.0)) {
      vhat.x += 0.01;
    }
    vlen2 = sqrt(point_dot(&vhat, &vhat));
    len_scale = vlen2 / vlen;
    point_normalize(&vhat);
    vhatperp.x = -vhat.y;
    vhatperp.y =  vhat.x;
    for (i=0;i<num_handles;i++) {
      if (bus->handles[i]->connected_to == NULL) {
	u = vhat;
	point_scale(&u, parallel[i]*len_scale);
	point_add(&u, &endpoints[0]);
	bus->parallel_points[i] = u;
	u = vhatperp;
	point_scale(&u, perp[i]);
	point_add(&u, &bus->parallel_points[i]);
	bus->handles[i]->pos = u;
	}
    }
  }

  bus_update_data(bus);

  return NULL;
}
Exemplo n.º 15
0
static ObjectChange*
arc_move_handle(Arc *arc, Handle *handle,
                Point *to, ConnectionPoint *cp,
                HandleMoveReason reason, ModifierKeys modifiers)
{
    assert(arc!=NULL);
    assert(handle!=NULL);
    assert(to!=NULL);
    /* A minimum distance between our three points needs to be maintained
     * Otherwise our math will get unstable with unpredictable results. */
    {
        const Point *p1, *p2;

        if (handle->id == HANDLE_MIDDLE) {
            p1 = &arc->connection.endpoints[0];
            p2 = &arc->connection.endpoints[1];
        } else if (handle->id == HANDLE_CENTER) {
            p1 = &arc->connection.endpoints[0];
            p2 = &arc->connection.endpoints[1];
            /* special movement, let the center point snap to grid */
        } else {
            p1 = &arc->middle_handle.pos;
            p2 = &arc->connection.endpoints[(handle == (&arc->connection.endpoint_handles[0])) ? 1 : 0];
        }
        if (   (distance_point_point (to, p1) < 0.01)
                || (distance_point_point (to, p2) < 0.01))
            return NULL;
    }

    if (handle->id == HANDLE_MIDDLE) {
        TRACE(printf("curve_dist: %.2f \n",arc->curve_distance));
        arc->curve_distance = arc_compute_curve_distance(arc, &arc->connection.endpoints[0], &arc->connection.endpoints[1], to);
        TRACE(printf("curve_dist: %.2f \n",arc->curve_distance));
    } else if (handle->id == HANDLE_CENTER) {
        /* We can move the handle only on the line through center and middle
        * Intersecting chord theorem says a*a=b*c
        *   with a = dist(p1,p2)/2
        *        b = curve_distance
        *        c = 2*radius-b or c = r + d
        *   with Pythagoras r^2 = d^2 + a^2
        *        d = sqrt(r^2-a^2)
        */
        Point p0 = arc->connection.endpoints[0];
        Point p1 = arc->connection.endpoints[1];
        Point p2 = { (p0.x + p1.x) / 2.0, (p0.y + p1.y) / 2.0 };
        real a = distance_point_point (&p0, &p1)/2.0;
        real r = (  distance_point_point (&p0, to) + distance_point_point (&p1, to)) / 2.0;
        real d = sqrt(r*r-a*a);
        real cd;
        /* If the new point lies between midpoint and the chords center the angles is >180,
         * so c is smaller than r */
        if (point_projection_is_between (to, &arc->middle_handle.pos, &p2))
            d = -d;
        cd  = a*a / (r+d);
        /* the sign of curve_distance, i.e. if the arc angle is clockwise, does not change */
        arc->curve_distance = (arc->curve_distance > 0) ? cd : -cd;
    } else {
        Point best;
        TRACE(printf("Modifiers: %d \n",modifiers));
        if (modifiers & MODIFIER_SHIFT)
            /* if(arc->end_arrow.type == ARROW_NONE)*/
        {
            TRACE(printf("SHIFT USED, to at %.2f %.2f  ",to->x,to->y));
            if (arc_find_radial(arc, to, &best)) {
                /* needs to move two handles at the same time
                 * compute pos of middle handle */
                Point midpoint;
                int ok;
                if (handle == (&arc->connection.endpoint_handles[0]))
                    ok = arc_compute_midpoint(arc, &best , &arc->connection.endpoints[1], &midpoint);
                else
                    ok = arc_compute_midpoint(arc,  &arc->connection.endpoints[0], &best , &midpoint);
                if (!ok)
                    return NULL;
                connection_move_handle(&arc->connection, handle->id, &best, cp, reason, modifiers);
                connection_adjust_for_autogap(&arc->connection);
                /* recompute curve distance equiv. move middle handle */
                arc->curve_distance = arc_compute_curve_distance(arc, &arc->connection.endpoints[0], &arc->connection.endpoints[1], &midpoint);
                TRACE(printf("curve_dist: %.2f \n",arc->curve_distance));
            }
            else {
                TRACE(printf("NO best\n"));
            }
        } else {
            connection_move_handle(&arc->connection, handle->id, to, cp, reason, modifiers);
            connection_adjust_for_autogap(&arc->connection);
        }
    }

    arc_update_data(arc);

    return NULL;
}