static void arc_set_props(Arc *arc, GPtrArray *props) { object_set_props_from_offsets(&arc->connection.object, arc_offsets, props); arc_update_data(arc); }
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); }
static DiaObject * arc_create(Point *startpoint, void *user_data, Handle **handle1, Handle **handle2) { Arc *arc; OrthConn *orth; DiaObject *obj; arc = g_malloc0(sizeof(Arc)); orth = &arc->orth; obj = &orth->object; obj->type = &grafcet_arc_type; obj->ops = &arc_ops; orthconn_init(orth, startpoint); arc->uparrow = TRUE; arc_update_data(arc); *handle1 = orth->handles[0]; *handle2 = orth->handles[orth->numhandles-1]; return &arc->orth.object; }
static ObjectChange * arc_delete_segment_callback(DiaObject *obj, Point *clicked, gpointer data) { ObjectChange *change; change = orthconn_delete_segment((OrthConn *)obj, clicked); arc_update_data((Arc *)obj); return change; }
static ObjectChange* arc_move(Arc *arc, Point *to) { ObjectChange *change; change = orthconn_move(&arc->orth, to); arc_update_data(arc); return change; }
static ObjectChange* arc_move_handle(Arc *arc, Handle *handle, Point *to, ConnectionPoint *cp, HandleMoveReason reason, ModifierKeys modifiers) { ObjectChange *change; change = orthconn_move_handle(&arc->orth, handle, to, cp, reason, modifiers); arc_update_data(arc); return change; }
static void arc_move(Arc *arc, Point *to) { Point start_to_end; Point *endpoints = &arc->connection.endpoints[0]; start_to_end = endpoints[1]; point_sub(&start_to_end, &endpoints[0]); endpoints[1] = endpoints[0] = *to; point_add(&endpoints[1], &start_to_end); arc_update_data(arc); }
static void arc_set_state(Arc *arc, ArcState *state) { arc->line_width = state->line_width; arc->arc_color = state->arc_color; arc->curve_distance = state->curve_distance; arc->line_style = state->line_style; arc->dashlength = state->dashlength; arc->start_arrow = state->start_arrow; arc->end_arrow = state->end_arrow; g_free(state); arc_update_data(arc); }
static Object * arc_create(Point *startpoint, void *user_data, Handle **handle1, Handle **handle2) { Arc *arc; Connection *conn; Object *obj; Point defaultlen = { 1.0, 1.0 }; /*arc_init_defaults();*/ arc = g_malloc(sizeof(Arc)); arc->line_width = attributes_get_default_linewidth(); arc->curve_distance = 1.0; arc->arc_color = attributes_get_foreground(); attributes_get_default_line_style(&arc->line_style, &arc->dashlength); arc->start_arrow = attributes_get_default_start_arrow(); arc->end_arrow = attributes_get_default_end_arrow(); conn = &arc->connection; conn->endpoints[0] = *startpoint; conn->endpoints[1] = *startpoint; point_add(&conn->endpoints[1], &defaultlen); obj = (Object *) arc; obj->type = &arc_type;; obj->ops = &arc_ops; connection_init(conn, 3, 0); obj->handles[2] = &arc->middle_handle; arc->middle_handle.id = HANDLE_MIDDLE; arc->middle_handle.type = HANDLE_MINOR_CONTROL; arc->middle_handle.connect_type = HANDLE_NONCONNECTABLE; arc->middle_handle.connected_to = NULL; arc_update_data(arc); *handle1 = obj->handles[0]; *handle2 = obj->handles[1]; return (Object *)arc; }
static ObjectChange * arc_apply_properties(Arc *arc) { ObjectState *old_state; old_state = (ObjectState *)arc_get_state(arc); arc->line_width = gtk_spin_button_get_value_as_float(arc_properties_dialog->line_width); dia_color_selector_get_color(arc_properties_dialog->color, &arc->arc_color); dia_line_style_selector_get_linestyle(arc_properties_dialog->line_style, &arc->line_style, &arc->dashlength); arc->start_arrow = dia_arrow_selector_get_arrow(arc_properties_dialog->start_arrow); arc->end_arrow = dia_arrow_selector_get_arrow(arc_properties_dialog->end_arrow); arc_update_data(arc); return new_object_state_change((Object *)arc, old_state, (GetStateFunc)arc_get_state, (SetStateFunc)arc_set_state); }
static DiaObject * arc_create(Point *startpoint, void *user_data, Handle **handle1, Handle **handle2) { Arc *arc; Connection *conn; DiaObject *obj; Point defaultlen = { 1.0, 1.0 }; arc = g_malloc0(sizeof(Arc)); arc->line_width = attributes_get_default_linewidth(); arc->curve_distance = 1.0; arc->arc_color = attributes_get_foreground(); attributes_get_default_line_style(&arc->line_style, &arc->dashlength); arc->line_caps = LINECAPS_BUTT; arc->start_arrow = attributes_get_default_start_arrow(); arc->end_arrow = attributes_get_default_end_arrow(); conn = &arc->connection; conn->endpoints[0] = *startpoint; conn->endpoints[1] = *startpoint; point_add(&conn->endpoints[1], &defaultlen); obj = &conn->object; obj->type = &arc_type;; obj->ops = &arc_ops; connection_init(conn, 4, 0); _arc_setup_handles (arc); arc_update_data(arc); *handle1 = obj->handles[0]; *handle2 = obj->handles[1]; return &arc->connection.object; }
static DiaObject * arc_copy(Arc *arc) { Arc *newarc; Connection *conn, *newconn; DiaObject *newobj; conn = &arc->connection; newarc = g_malloc0(sizeof(Arc)); newconn = &newarc->connection; newobj = &newconn->object; connection_copy(conn, newconn); newarc->arc_color = arc->arc_color; newarc->curve_distance = arc->curve_distance; newarc->line_width = arc->line_width; newarc->line_style = arc->line_style; newarc->line_caps = arc->line_caps; newarc->dashlength = arc->dashlength; newarc->start_arrow = arc->start_arrow; newarc->end_arrow = arc->end_arrow; newarc->radius = arc->radius; newarc->center = arc->center; newarc->angle1 = arc->angle1; newarc->angle2 = arc->angle2; newobj->handles[2] = &newarc->middle_handle; newarc->middle_handle = arc->middle_handle; newobj->handles[3] = &newarc->center_handle; newarc->center_handle = arc->center_handle; arc_update_data(arc); return &newarc->connection.object; }
static Object * arc_load(ObjectNode obj_node, int version, const char *filename) { Arc *arc; Connection *conn; Object *obj; AttributeNode attr; arc = g_malloc(sizeof(Arc)); conn = &arc->connection; obj = (Object *) arc; obj->type = &arc_type;; obj->ops = &arc_ops; connection_load(conn, obj_node); arc->arc_color = color_black; attr = object_find_attribute(obj_node, "arc_color"); if (attr != NULL) data_color(attribute_first_data(attr), &arc->arc_color); arc->curve_distance = 0.1; attr = object_find_attribute(obj_node, "curve_distance"); if (attr != NULL) arc->curve_distance = data_real(attribute_first_data(attr)); arc->line_width = 0.1; attr = object_find_attribute(obj_node, "line_width"); if (attr != NULL) arc->line_width = data_real(attribute_first_data(attr)); arc->line_style = LINESTYLE_SOLID; attr = object_find_attribute(obj_node, "line_style"); if (attr != NULL) arc->line_style = data_enum(attribute_first_data(attr)); arc->dashlength = DEFAULT_LINESTYLE_DASHLEN; attr = object_find_attribute(obj_node, "dashlength"); if (attr != NULL) arc->dashlength = data_real(attribute_first_data(attr)); arc->start_arrow.type = ARROW_NONE; arc->start_arrow.length = 0.8; arc->start_arrow.width = 0.8; attr = object_find_attribute(obj_node, "start_arrow"); if (attr != NULL) arc->start_arrow.type = data_enum(attribute_first_data(attr)); attr = object_find_attribute(obj_node, "start_arrow_length"); if (attr != NULL) arc->start_arrow.length = data_real(attribute_first_data(attr)); attr = object_find_attribute(obj_node, "start_arrow_width"); if (attr != NULL) arc->start_arrow.width = data_real(attribute_first_data(attr)); arc->end_arrow.type = ARROW_NONE; arc->end_arrow.length = 0.8; arc->end_arrow.width = 0.8; attr = object_find_attribute(obj_node, "end_arrow"); if (attr != NULL) arc->end_arrow.type = data_enum(attribute_first_data(attr)); attr = object_find_attribute(obj_node, "end_arrow_length"); if (attr != NULL) arc->end_arrow.length = data_real(attribute_first_data(attr)); attr = object_find_attribute(obj_node, "end_arrow_width"); if (attr != NULL) arc->end_arrow.width = data_real(attribute_first_data(attr)); connection_init(conn, 3, 0); obj->handles[2] = &arc->middle_handle; arc->middle_handle.id = HANDLE_MIDDLE; arc->middle_handle.type = HANDLE_MINOR_CONTROL; arc->middle_handle.connect_type = HANDLE_NONCONNECTABLE; arc->middle_handle.connected_to = NULL; arc_update_data(arc); return (Object *)arc; }
static DiaObject * arc_load(ObjectNode obj_node, int version,DiaContext *ctx) { Arc *arc; Connection *conn; DiaObject *obj; AttributeNode attr; arc = g_malloc0(sizeof(Arc)); conn = &arc->connection; obj = &conn->object; obj->type = &arc_type; obj->ops = &arc_ops; connection_load(conn, obj_node, ctx); arc->arc_color = color_black; attr = object_find_attribute(obj_node, "arc_color"); if (attr != NULL) data_color(attribute_first_data(attr), &arc->arc_color, ctx); arc->curve_distance = 0.1; attr = object_find_attribute(obj_node, "curve_distance"); if (attr != NULL) arc->curve_distance = data_real(attribute_first_data(attr), ctx); arc->line_width = 0.1; attr = object_find_attribute(obj_node, PROP_STDNAME_LINE_WIDTH); if (attr != NULL) arc->line_width = data_real(attribute_first_data(attr), ctx); arc->line_style = LINESTYLE_SOLID; attr = object_find_attribute(obj_node, "line_style"); if (attr != NULL) arc->line_style = data_enum(attribute_first_data(attr), ctx); arc->dashlength = DEFAULT_LINESTYLE_DASHLEN; attr = object_find_attribute(obj_node, "dashlength"); if (attr != NULL) arc->dashlength = data_real(attribute_first_data(attr), ctx); arc->line_caps = LINECAPS_BUTT; attr = object_find_attribute(obj_node, "line_caps"); if (attr != NULL) arc->line_caps = data_enum(attribute_first_data(attr), ctx); load_arrow(obj_node, &arc->start_arrow, "start_arrow", "start_arrow_length", "start_arrow_width", ctx); load_arrow(obj_node, &arc->end_arrow, "end_arrow", "end_arrow_length", "end_arrow_width", ctx); connection_init(conn, 4, 0); _arc_setup_handles (arc); /* older versions did not prohibit everything reduced to a single point * and afterwards failed on all the calculations producing nan. */ if (distance_point_point (&arc->connection.endpoints[0], &arc->connection.endpoints[1]) < 0.02) { arc->curve_distance = 0.0; arc->connection.endpoints[0].x -= 0.01; arc->connection.endpoints[1].x += 0.01; arc_update_handles (arc); } arc_update_data(arc); return &arc->connection.object; }
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; }