Ejemplo n.º 1
0
ObjectChange *
polyconn_move_handle(PolyConn *poly, Handle *handle,
		     Point *to, ConnectionPoint *cp,
		     HandleMoveReason reason, ModifierKeys modifiers)
{
  int handle_nr;
  
  handle_nr = get_handle_nr(poly, handle);
  switch(handle->id) {
  case HANDLE_MOVE_STARTPOINT:
    poly->points[0] = *to;
    break;
  case HANDLE_MOVE_ENDPOINT:
    poly->points[poly->numpoints-1] = *to;
    break;
  case HANDLE_CORNER:
    poly->points[handle_nr] = *to;
    break;
  default:
    g_warning("Internal error in polyconn_move_handle.\n");
    break;
  }

  return NULL;
}
Ejemplo n.º 2
0
/*!
 * \brief Return the major handle for the control point with the handle closest to
 * a given point.
 * @param bezier A bezier connection
 * @param point A point
 * @return The major (middle) handle of the bezier control that has the
 * handle closest to point.
 * @bug Don't we really want the major handle that's actually closest to
 * the point?  This is used in connection with object menus and could cause
 * some unexpected selection of handles if a different segment has a control
 * point close to the major handle.
 */
Handle *
bezierconn_closest_major_handle (BezierConn *bezier, Point *point)
{
  Handle *closest = bezierconn_closest_handle(bezier, point);

  return bezier->object.handles[3*get_major_nr(get_handle_nr(bezier, closest))];
}
Ejemplo n.º 3
0
Handle *
beziershape_closest_major_handle(BezierShape *bezier, Point *point)
{
  Handle *closest = beziershape_closest_handle(bezier, point);
  int pos = get_major_nr(get_handle_nr(bezier, closest));

  if (pos == 0)
    pos = bezier->numpoints - 1;
  return bezier->object.handles[3*pos - 1];
}
Ejemplo n.º 4
0
ObjectChange *
beziershape_set_corner_type(BezierShape *bez, Handle *handle,
			    BezCornerType corner_type)
{
  Handle *mid_handle = NULL;
  Point old_left, old_right;
  int old_type;
  int handle_nr, comp_nr;

  handle_nr = get_handle_nr(bez, handle);

  switch (handle->id) {
  case HANDLE_BEZMAJOR:
    mid_handle = handle;
    break;
  case HANDLE_LEFTCTRL:
    handle_nr++;
    if (handle_nr == bez->object.num_handles) handle_nr = 0;
    mid_handle = bez->object.handles[handle_nr];
    break;
  case HANDLE_RIGHTCTRL:
    handle_nr--;
    if (handle_nr < 0) handle_nr = bez->object.num_handles - 1;
    mid_handle = bez->object.handles[handle_nr];
    break;
  default:
    g_assert_not_reached();
    break;
  }

  comp_nr = get_major_nr(handle_nr);

  old_type = bez->corner_types[comp_nr];
  old_left = bez->points[comp_nr].p2;
  if (comp_nr == bez->numpoints - 1)
    old_right = bez->points[1].p1;
  else
    old_right = bez->points[comp_nr+1].p1;

#if 0
  g_message("Setting corner type on segment %d to %s", comp_nr,
	    corner_type == BEZ_CORNER_SYMMETRIC ? "symmetric" :
	    corner_type == BEZ_CORNER_SMOOTH ? "smooth" : "cusp");
#endif
  bez->corner_types[comp_nr] = corner_type;
  if (comp_nr == 0)
    bez->corner_types[bez->numpoints-1] = corner_type;
  else if (comp_nr == bez->numpoints - 1)
    bez->corner_types[0] = corner_type;

  beziershape_straighten_corner(bez, comp_nr);

  return beziershape_create_corner_change(bez, mid_handle, &old_left,
					  &old_right, old_type, corner_type);
}
Ejemplo n.º 5
0
ObjectChange*
polyshape_move_handle(PolyShape *poly, Handle *handle,
		      Point *to, ConnectionPoint *cp,
		      HandleMoveReason reason, ModifierKeys modifiers)
{
  int handle_nr;
  
  handle_nr = get_handle_nr(poly, handle);
  poly->points[handle_nr] = *to;
  
  return NULL;
}
Ejemplo n.º 6
0
/** Change the corner type of a bezier line.
 * @param bezier The bezierconn that has the corner
 * @param handle The handle whose corner should be set.
 * @param corner_type What type of corner the handle should have.
 * @returns Undo information about the corner change.
 */
ObjectChange *
bezierconn_set_corner_type (BezierConn *bezier,
			    Handle *handle,
			    BezCornerType corner_type)
{
  Handle *mid_handle;
  Point old_left, old_right;
  int old_type;
  int handle_nr, comp_nr;

  handle_nr = get_handle_nr(bezier, handle);

  switch (handle->id) {
  case HANDLE_BEZMAJOR:
    mid_handle = handle;
    break;
  case HANDLE_LEFTCTRL:
    handle_nr++;
    mid_handle = bezier->object.handles[handle_nr];
    break;
  case HANDLE_RIGHTCTRL:
    handle_nr--;
    mid_handle = bezier->object.handles[handle_nr];
    break;
  default:
    g_warning("Internal error: Setting corner type of endpoint of bezier");
    return NULL;
  }

  comp_nr = get_major_nr(handle_nr);

  old_type = bezier->bezier.corner_types[comp_nr];
  old_left = bezier->bezier.points[comp_nr].p2;
  old_right = bezier->bezier.points[comp_nr+1].p1;

  bezier->bezier.corner_types[comp_nr] = corner_type;

  bezierconn_straighten_corner(bezier, comp_nr);

  return bezierconn_create_corner_change(bezier, mid_handle, &old_left, &old_right,
					 old_type, corner_type);
}
Ejemplo n.º 7
0
void
polyconn_move_handle(PolyConn *poly, Handle *handle,
		     Point *to, HandleMoveReason reason)
{
  int handle_nr;
  
  handle_nr = get_handle_nr(poly, handle);
  switch(handle->id) {
  case HANDLE_MOVE_STARTPOINT:
    poly->points[0] = *to;
    break;
  case HANDLE_MOVE_ENDPOINT:
    poly->points[poly->numpoints-1] = *to;
    break;
  case HANDLE_CORNER:
    poly->points[handle_nr] = *to;
    break;
  default:
    message_error("Internal error in polyconn_move_handle.\n");
    break;
  }
}
Ejemplo n.º 8
0
ObjectChange *
beziershape_move_handle(BezierShape *bezier, Handle *handle,
			Point *to, ConnectionPoint *cp,
			HandleMoveReason reason, ModifierKeys modifiers)
{
  int handle_nr, comp_nr, next_nr, prev_nr;
  Point delta, pt;
  
  delta = *to;
  point_sub(&delta, &handle->pos);

  handle_nr = get_handle_nr(bezier, handle);
  comp_nr = get_comp_nr(handle_nr);
  next_nr = comp_nr + 1;
  prev_nr = comp_nr - 1;
  if (comp_nr == bezier->numpoints - 1)
    next_nr = 1;
  if (comp_nr == 1)
    prev_nr = bezier->numpoints - 1;
  
  switch(handle->id) {
  case HANDLE_BEZMAJOR:
    if (comp_nr == bezier->numpoints - 1) {
      bezier->points[comp_nr].p3 = *to;
      bezier->points[0].p1 = bezier->points[0].p3 = *to;
      point_add(&bezier->points[comp_nr].p2, &delta);
      point_add(&bezier->points[1].p1, &delta);
    } else {
      bezier->points[comp_nr].p3 = *to;
      point_add(&bezier->points[comp_nr].p2, &delta);
      point_add(&bezier->points[comp_nr+1].p1, &delta);
    }
    break;
  case HANDLE_LEFTCTRL:
    bezier->points[comp_nr].p2 = *to;
    switch (bezier->corner_types[comp_nr]) {
    case BEZ_CORNER_SYMMETRIC:
      pt = bezier->points[comp_nr].p3;
      point_sub(&pt, &bezier->points[comp_nr].p2);
      point_add(&pt, &bezier->points[comp_nr].p3);
      bezier->points[next_nr].p1 = pt;
      break;
    case BEZ_CORNER_SMOOTH: {
      real len;

      pt = bezier->points[next_nr].p1;
      point_sub(&pt, &bezier->points[comp_nr].p3);
      len = point_len(&pt);

      pt = bezier->points[comp_nr].p3;
      point_sub(&pt, &bezier->points[comp_nr].p2);
      if (point_len(&pt) > 0)
	point_normalize(&pt);
      else {
	pt.x = 1.0; pt.y = 0.0;
      }
      point_scale(&pt, len);
      point_add(&pt, &bezier->points[comp_nr].p3);
      bezier->points[next_nr].p1 = pt;
      break;
    }
    case BEZ_CORNER_CUSP:
      /* no mirror point movement required */
      break;
    }
    break;
  case HANDLE_RIGHTCTRL:
    bezier->points[comp_nr].p1 = *to;
    switch (bezier->corner_types[prev_nr]) {
    case BEZ_CORNER_SYMMETRIC:
      pt = bezier->points[prev_nr].p3;
      point_sub(&pt, &bezier->points[comp_nr].p1);
      point_add(&pt, &bezier->points[prev_nr].p3);
      bezier->points[prev_nr].p2 = pt;
      break;
    case BEZ_CORNER_SMOOTH: {
      real len;

      pt = bezier->points[prev_nr].p2;
      point_sub(&pt, &bezier->points[prev_nr].p3);
      len = point_len(&pt);

      pt = bezier->points[prev_nr].p3;
      point_sub(&pt, &bezier->points[comp_nr].p1);
      if (point_len(&pt) > 0)
	point_normalize(&pt);
      else {
	pt.x = 1.0; pt.y = 0.0;
      }
      point_scale(&pt, len);
      point_add(&pt, &bezier->points[prev_nr].p3);
      bezier->points[prev_nr].p2 = pt;
      break;
    }
    case BEZ_CORNER_CUSP:
      /* no mirror point movement required */
      break;
    }
    break;
  default:
    message_error("Internal error in beziershape_move_handle.");
    break;
  }
  return NULL;
}
Ejemplo n.º 9
0
/*!
 * \brief Move one of the handles associated with the
 * @param bezier The object whose handle is being moved.
 * @param handle The handle being moved.
 * @param to The position it has been moved to (corrected for
 *   vertical/horizontal only movement).
 * @param cp If non-NULL, the connectionpoint found at this position.
 *   If @a cp is NULL, there may or may not be a connectionpoint.
 * @param reason ignored
 * @param modifiers ignored
 * @return NULL
 * \memberof BezierConn
 */
ObjectChange*
bezierconn_move_handle (BezierConn *bezier,
			Handle *handle,
			Point *to,
			ConnectionPoint *cp,
			HandleMoveReason reason,
			ModifierKeys modifiers)
{
  int handle_nr, comp_nr;
  Point delta, pt;
  
  delta = *to;
  point_sub(&delta, &handle->pos);

  handle_nr = get_handle_nr(bezier, handle);
  comp_nr = get_comp_nr(handle_nr);
  switch(handle->id) {
  case HANDLE_MOVE_STARTPOINT:
    bezier->bezier.points[0].p1 = *to;
    /* shift adjacent point */
    point_add(&bezier->bezier.points[1].p1, &delta);
    break;
  case HANDLE_MOVE_ENDPOINT:
    bezier->bezier.points[bezier->bezier.num_points-1].p3 = *to;
    /* shift adjacent point */
    point_add(&bezier->bezier.points[bezier->bezier.num_points-1].p2, &delta);
    break;
  case HANDLE_BEZMAJOR:
    bezier->bezier.points[comp_nr].p3 = *to;
    /* shift adjacent point */
    point_add(&bezier->bezier.points[comp_nr].p2, &delta);
    point_add(&bezier->bezier.points[comp_nr+1].p1, &delta);
    break;
  case HANDLE_LEFTCTRL:
    bezier->bezier.points[comp_nr].p2 = *to;
    if (comp_nr < bezier->bezier.num_points - 1) {
      switch (bezier->bezier.corner_types[comp_nr]) {
      case BEZ_CORNER_SYMMETRIC:
	pt = bezier->bezier.points[comp_nr].p3;
	point_sub(&pt, &bezier->bezier.points[comp_nr].p2);
	point_add(&pt, &bezier->bezier.points[comp_nr].p3);
	bezier->bezier.points[comp_nr+1].p1 = pt;
	break;
      case BEZ_CORNER_SMOOTH: {
	real len;
	pt = bezier->bezier.points[comp_nr+1].p1;
	point_sub(&pt, &bezier->bezier.points[comp_nr].p3);
	len = point_len(&pt);
	pt = bezier->bezier.points[comp_nr].p2;
	point_sub(&pt, &bezier->bezier.points[comp_nr].p3);
	if (point_len(&pt) > 0)
	  point_normalize(&pt);
	else { pt.x = 1.0; pt.y = 0.0; }
	point_scale(&pt, -len);
	point_add(&pt, &bezier->bezier.points[comp_nr].p3);
	bezier->bezier.points[comp_nr+1].p1 = pt;
	break;
      }	
      case BEZ_CORNER_CUSP:
	/* Do nothing to the other guy */
	break;
      }
    }
    break;
  case HANDLE_RIGHTCTRL:
    bezier->bezier.points[comp_nr].p1 = *to;
    if (comp_nr > 1) {
      switch (bezier->bezier.corner_types[comp_nr-1]) {
      case BEZ_CORNER_SYMMETRIC:
	pt = bezier->bezier.points[comp_nr - 1].p3;
	point_sub(&pt, &bezier->bezier.points[comp_nr].p1);
	point_add(&pt, &bezier->bezier.points[comp_nr - 1].p3);
	bezier->bezier.points[comp_nr-1].p2 = pt;
	break;
      case BEZ_CORNER_SMOOTH: {
	real len;
	pt = bezier->bezier.points[comp_nr-1].p2;
	point_sub(&pt, &bezier->bezier.points[comp_nr-1].p3);
	len = point_len(&pt);
	pt = bezier->bezier.points[comp_nr].p1;
	point_sub(&pt, &bezier->bezier.points[comp_nr-1].p3);
	if (point_len(&pt) > 0)
	  point_normalize(&pt);
	else { pt.x = 1.0; pt.y = 0.0; }
	point_scale(&pt, -len);
	point_add(&pt, &bezier->bezier.points[comp_nr-1].p3);
	bezier->bezier.points[comp_nr-1].p2 = pt;
	break;
      }	
      case BEZ_CORNER_CUSP:
	/* Do nothing to the other guy */
	break;
      }
    }
    break;
  default:
    g_warning("Internal error in bezierconn_move_handle.\n");
    break;
  }
  return NULL;
}