Ejemplo n.º 1
0
static ObjectChange*
message_move_handle(Message *message, Handle *handle,
		    Point *to, ConnectionPoint *cp,
		    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, cp, reason, modifiers);
    connection_adjust_for_autogap(&message->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(&message->text_pos, &p2);
  }

  message_update_data(message);

  return NULL;
}
Ejemplo n.º 2
0
static void
message_update_data(Message *message)
{
  Connection *conn = &message->connection;
  DiaObject *obj = &conn->object;
  Rectangle rect;
  
  if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
      connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
    connection_adjust_for_autogap(conn);
  }
  obj->position = conn->endpoints[0];

  message->text_handle.pos = message->text_pos;

  connection_update_handles(conn);
  connection_update_boundingbox(conn);

  message->text_width =
    dia_font_string_width(message->text, message->font, message->font_height);

  /* Add boundingbox for text: */
  rect.left = message->text_pos.x-message->text_width/2;
  rect.right = rect.left + message->text_width;
  rect.top = message->text_pos.y -
      dia_font_ascent(message->text, message->font, message->font_height);
  rect.bottom = rect.top + message->font_height;
  rectangle_union(&obj->bounding_box, &rect);
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
static void
constraint_update_data(Constraint *constraint)
{
  Connection *conn = &constraint->connection;
  DiaObject *obj = &conn->object;
  Rectangle rect;
  LineBBExtras *extra;

  if ((constraint->text) && (constraint->text[0] == '{')) {
    /* we might have a string loaded from an older dia. Clean it up. */
    g_free(constraint->brtext);
    constraint->brtext = constraint->text;
    constraint->text = bracketted_to_string(constraint->text,"{","}");
  } else if (!constraint->brtext) {
    constraint->brtext = string_to_bracketted(constraint->text, "{", "}");
  }
  
  if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
      connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
    connection_adjust_for_autogap(conn);
  }
  obj->position = conn->endpoints[0];

  constraint->text_width = dia_font_string_width(constraint->brtext, 
                                                 constraint->font, 
                                                 constraint->font_height);
  
  constraint->text_handle.pos = constraint->text_pos;

  connection_update_handles(conn);

  /* Boundingbox: */
  extra = &conn->extra_spacing;

  extra->start_long = 
    extra->start_trans = 
    extra->end_long = constraint->line_width/2.0;
  extra->end_trans = MAX(constraint->line_width,CONSTRAINT_ARROWLEN)/2.0;
  
  connection_update_boundingbox(conn);

  /* Add boundingbox for text: */
  rect.left = constraint->text_pos.x;
  rect.right = rect.left + constraint->text_width;
  rect.top = constraint->text_pos.y -
      dia_font_ascent(constraint->brtext,
                      constraint->font, constraint->font_height);
  rect.bottom = rect.top + constraint->font_height;
  rectangle_union(&obj->bounding_box, &rect);
}
Ejemplo n.º 5
0
Archivo: line.c Proyecto: mpuels/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);
  connection_adjust_for_autogap(&line->connection);

  line_update_data(line);

  return NULL;
}
Ejemplo n.º 6
0
static void
annotation_update_data(Annotation *annotation)
{
  Connection *conn = &annotation->connection;
  DiaObject *obj = &conn->object;
  Rectangle textrect;
  
  if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
      connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
    connection_adjust_for_autogap(conn);
  }
  obj->position = conn->endpoints[0];

  annotation->text_handle.pos = annotation->text->position;

  connection_update_handles(conn);

  connection_update_boundingbox(conn);
  text_calc_boundingbox(annotation->text,&textrect);
  rectangle_union(&obj->bounding_box, &textrect);
}
Ejemplo n.º 7
0
Archivo: flow.c Proyecto: brunetton/dia
static void
flow_update_data(Flow *flow)
{
  Connection *conn = &flow->connection;
  DiaObject *obj = &conn->object;
  Rectangle rect;
  Color* color = NULL;
  
  if (connpoint_is_autogap(flow->connection.endpoint_handles[0].connected_to) ||
      connpoint_is_autogap(flow->connection.endpoint_handles[1].connected_to)) {
    connection_adjust_for_autogap(conn);
  }
  obj->position = conn->endpoints[0];

  switch (flow->type) {
  case FLOW_ENERGY:
    color = &flow_color_energy ;
    break ;
  case FLOW_MATERIAL:
    color = &flow_color_material ;
    break ;
  case FLOW_SIGNAL:
    color = &flow_color_signal ;
    break ;
  }
  text_set_color( flow->text, color ) ;

  flow->text->position = flow->textpos;
  flow->text_handle.pos = flow->textpos;

  connection_update_handles(conn);

  /* Boundingbox: */
  connection_update_boundingbox(conn);

  /* Add boundingbox for text: */
  text_calc_boundingbox(flow->text, &rect) ;
  rectangle_union(&obj->bounding_box, &rect);
}
Ejemplo n.º 8
0
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);
    connection_adjust_for_autogap(&flow->connection);

    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;
}
Ejemplo n.º 9
0
static void
wanlink_update_data(WanLink *wanlink)
{
  Connection *conn = &wanlink->connection;
  DiaObject *obj = (DiaObject *) wanlink;
  Point v, vhat;
  Point *endpoints;
  real width, width_2;
  real len, angle;
  Point origin;
  int i;
  Matrix m;
  

  width = wanlink->width;
  width_2 = width / 2.0;
  
  if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
      connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
    connection_adjust_for_autogap(conn);
  }
  endpoints = &conn->endpoints[0]; 
  obj->position = endpoints[0];

  v = endpoints[1];
  point_sub(&v, &endpoints[0]);
  if ((fabs(v.x) == 0.0) && (fabs(v.y)==0.0)) {
    v.x += 0.01;
  }
  vhat = v;
  point_normalize(&vhat);

  connection_update_boundingbox(conn);

  /** compute the polygon **/
  origin = wanlink->connection.endpoints [0];
  len = point_len (&v);

  angle = atan2 (vhat.y, vhat.x) - M_PI_2;

    /* The case of the wanlink */
  wanlink->poly[0].x = (width * 0.50) - width_2;
  wanlink->poly[0].y = (len * 0.00);
  wanlink->poly[1].x = (width * 0.50) - width_2;
  wanlink->poly[1].y = (len * 0.45);
  wanlink->poly[2].x = (width * 0.94) - width_2;
  wanlink->poly[2].y = (len * 0.45);
  wanlink->poly[3].x = (width * 0.50) - width_2;
  wanlink->poly[3].y = (len * 1.00);
  wanlink->poly[4].x = (width * 0.50) - width_2;
  wanlink->poly[4].y = (len * 0.55);
  wanlink->poly[5].x = (width * 0.06) - width_2;
  wanlink->poly[5].y = (len * 0.55);
  
  /* rotate */
  _identity_matrix (m);
  _rotate_matrix (m, angle);

  obj->bounding_box.top = origin.y;
  obj->bounding_box.left = origin.x;
  obj->bounding_box.bottom = conn->endpoints[1].y;
  obj->bounding_box.right = conn->endpoints[1].x;
  for (i = 0; i <  WANLINK_POLY_LEN; i++) 
  {
      Point new_pt;
      
      _transform_point (m, &wanlink->poly[i], 
		        &new_pt);
      point_add (&new_pt, &origin);
      wanlink->poly[i] = new_pt;
  }
  /* calculate bounding box */
  {
    PolyBBExtras bbex = {0, 0, wanlink->width/2, 0, 0 };
    polyline_bbox (&wanlink->poly[0], WANLINK_POLY_LEN, &bbex, TRUE, &obj->bounding_box);
  }


  connection_update_handles(conn);
}
Ejemplo n.º 10
0
Archivo: line.c Proyecto: mpuels/dia
static void
line_update_data(Line *line)
{
  Connection *conn = &line->connection;
  DiaObject *obj = &conn->object;
  LineBBExtras *extra = &conn->extra_spacing;
  Point start, end;

  extra->start_trans =
  extra->end_trans   =
  extra->start_long  =
  extra->end_long    = (line->line_width / 2.0);

  if (connpoint_is_autogap(line->connection.endpoint_handles[0].connected_to) ||
      connpoint_is_autogap(line->connection.endpoint_handles[1].connected_to)) {
    connection_adjust_for_autogap(conn);
  }
  if (line->absolute_start_gap || line->absolute_end_gap ) {
    Point gap_endpoints[2];

    line_adjust_for_absolute_gap(line, gap_endpoints);
    line_bbox(&gap_endpoints[0],&gap_endpoints[1],
	      &conn->extra_spacing,&conn->object.bounding_box);
    start = gap_endpoints[0];
    end = gap_endpoints[1];
  } else {
    connection_update_boundingbox(conn);
    start = conn->endpoints[0];
    end = conn->endpoints[1];
  }
  if (line->start_arrow.type != ARROW_NONE) {
    Rectangle bbox;
    Point move_arrow, move_line;
    Point to = start;
    Point from = end;
    calculate_arrow_point(&line->start_arrow, &to, &from,
                          &move_arrow, &move_line, line->line_width);
    /* move them */
    point_sub(&to, &move_arrow);
    point_sub(&from, &move_line);

    arrow_bbox (&line->start_arrow, line->line_width, &to, &from, &bbox);
    rectangle_union (&obj->bounding_box, &bbox);
  }
  if (line->end_arrow.type != ARROW_NONE) {
    Rectangle bbox;
    Point move_arrow, move_line;
    Point to = end;
    Point from = start;
    calculate_arrow_point(&line->end_arrow, &to, &from,
                          &move_arrow, &move_line, line->line_width);
    /* move them */
    point_sub(&to, &move_arrow);
    point_sub(&from, &move_line);

    arrow_bbox (&line->end_arrow, line->line_width, &to, &from, &bbox);
    rectangle_union (&obj->bounding_box, &bbox);
  }

  obj->position = conn->endpoints[0];

  connpointline_update(line->cpl);
  connpointline_putonaline(line->cpl, &start, &end, DIR_ALL);
  
  connection_update_handles(conn);
}
Ejemplo n.º 11
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;
}