void test_nodestore () { gint i; NodeStore *store; Part *part; Wire *wire; Node *node; Coords p_pos = {111.,22.}; Coords n_pos = {111.,33.}; Coords w_pos = {111.,7.}; Coords w_len = {0.,88.}; store = node_store_new (); part = part_new (); wire = wire_new (); // add one Pin with a offset that is on the wire when rotation N*Pi times Pin *pin = g_new (Pin, 1); pin->offset.x = n_pos.x - p_pos.x; pin->offset.y = n_pos.y - p_pos.y; GSList *list = NULL; list = g_slist_prepend (list, pin); part_set_pins (part, list); g_slist_free (list); item_data_set_pos (ITEM_DATA (part), &p_pos); item_data_set_pos (ITEM_DATA (wire), &w_pos); wire_set_length (wire, &w_len); node_store_add_part (store, part); node_store_add_wire (store, wire); { for (i=0; i<11; i++) item_data_rotate (ITEM_DATA (part), 90, NULL); item_data_set_pos (ITEM_DATA (part), &w_len); for (i=0; i<4; i++) item_data_rotate (ITEM_DATA (part), 90, NULL); item_data_set_pos (ITEM_DATA (part), &n_pos); for (i=0; i<7; i++) item_data_rotate (ITEM_DATA (part), -90, NULL); item_data_set_pos (ITEM_DATA (part), &p_pos); } g_assert (node_store_is_wire_at_pos (store, n_pos)); g_assert (node_store_is_pin_at_pos (store, n_pos)); node = node_store_get_node (store, n_pos); g_assert (!node_is_empty (node)); g_assert (node_needs_dot (node)); node_store_remove_part (store, part); node_store_remove_wire (store, wire); g_object_unref (store); }
gboolean wire_item_event (WireItem *wire_item, GooCanvasItem *sheet_target_item, GdkEvent *event, Sheet *sheet) { SheetPos start_pos, length; Wire *wire; GooCanvas *canvas; static double last_x, last_y; double dx, dy, zoom; // The selected group's bounding box in window resp. canvas coordinates. double snapped_x, snapped_y; SheetPos pos; canvas = GOO_CANVAS (sheet); g_object_get (G_OBJECT (wire_item), "data", &wire, NULL); wire_get_pos_and_length (WIRE (wire), &start_pos, &length); sheet_get_zoom (sheet, &zoom); switch (event->type) { case GDK_BUTTON_PRESS: switch (event->button.button) { case 1: { double x, y; g_signal_stop_emission_by_name (wire_item, "button_press_event"); sheet_get_pointer (sheet, &x, &y); x = x - start_pos.x; y = y - start_pos.y; if ((x > -RESIZER_SIZE) && (x < RESIZER_SIZE) && (y > -RESIZER_SIZE) && (y < RESIZER_SIZE)) { gtk_widget_grab_focus (GTK_WIDGET (sheet)); sheet->state = SHEET_STATE_DRAG_START; wire_item->priv->resize_state = WIRE_RESIZER_1; sheet_get_pointer (sheet, &x, &y); last_x = x; last_y = y; item_data_unregister (ITEM_DATA (wire)); return TRUE; } if ((x > (length.x-RESIZER_SIZE)) && (x < (length.x+RESIZER_SIZE)) && (y > (length.y-RESIZER_SIZE)) && (y < (length.y+RESIZER_SIZE))) { gtk_widget_grab_focus (GTK_WIDGET (sheet)); sheet->state = SHEET_STATE_DRAG_START; wire_item->priv->resize_state = WIRE_RESIZER_2; sheet_get_pointer (sheet, &x, &y); last_x = x; last_y = y; item_data_unregister (ITEM_DATA (wire)); return TRUE; } } break; } break; case GDK_MOTION_NOTIFY: if (sheet->state != SHEET_STATE_DRAG && sheet->state != SHEET_STATE_DRAG_START) break; if (wire_item->priv->resize_state == WIRE_RESIZER_NONE) break; if (sheet->state == SHEET_STATE_DRAG_START || sheet->state == SHEET_STATE_DRAG) { g_signal_stop_emission_by_name (wire_item, "motion-notify-event"); sheet->state = SHEET_STATE_DRAG; sheet_get_pointer (sheet, &snapped_x, &snapped_y); dx = snapped_x - last_x; dy = snapped_y - last_y; last_x = snapped_x; last_y = snapped_y; wire_get_pos_and_length (wire, &pos, &length); if (wire_item->priv->resize_state == WIRE_RESIZER_1) { switch (wire->priv->direction) { case WIRE_DIR_VERT: /* Vertical Wire */ pos.y = last_y; length.y -= dy; break; case WIRE_DIR_HORIZ: /* Horizontal Wire */ pos.x = last_x; length.x -= dx; break; default: pos.y = last_y; length.y -= dy; pos.x = last_x; length.x -= dx; } } else { switch (wire->priv->direction) { case WIRE_DIR_VERT: /* Vertical Wire */ length.y += dy; break; case WIRE_DIR_HORIZ: /* Horizontal Wire */ length.x += dx; break; default: length.y += dy; length.x += dx; } } snap_to_grid (sheet->grid, &length.x, &length.y); item_data_set_pos (sheet_item_get_data (SHEET_ITEM (wire_item)), &pos); wire_set_length (wire, &length); return TRUE; } break; case GDK_BUTTON_RELEASE: switch (event->button.button) { case 1: if (sheet->state != SHEET_STATE_DRAG && sheet->state != SHEET_STATE_DRAG_START) { break; } if (wire_item->priv->resize_state == WIRE_RESIZER_NONE) { break; } g_signal_stop_emission_by_name (wire_item, "button-release-event"); goo_canvas_pointer_ungrab (canvas, GOO_CANVAS_ITEM (wire_item), event->button.time); wire_item->priv->resize_state = WIRE_RESIZER_NONE; sheet->state = SHEET_STATE_NONE; item_data_register (ITEM_DATA (wire)); return TRUE; } break; default: return sheet_item_event (GOO_CANVAS_ITEM (wire_item), GOO_CANVAS_ITEM (wire_item), event, sheet); } return sheet_item_event (GOO_CANVAS_ITEM (wire_item), GOO_CANVAS_ITEM (wire_item), event, sheet); }
int node_store_add_wire (NodeStore *store, Wire *wire) { gdouble x1, y1, x2, y2; GSList *ip_list, *list; IntersectionPoint *ipoint; Node *node; SheetPos pos, length; g_return_val_if_fail (store != NULL, FALSE); g_return_val_if_fail (IS_NODE_STORE (store), FALSE); g_return_val_if_fail (wire != NULL, FALSE); g_return_val_if_fail (IS_WIRE (wire), FALSE); wire_get_pos_and_length (wire, &pos, &length); x1 = pos.x; y1 = pos.y; x2 = x1 + length.x; y2 = y1 + length.y; // Check for intersection with other wires. ip_list = wires_intersect (store, x1, y1, x2, y2); for (list = ip_list; list; list = list->next) { ipoint = list->data; if (IS_EQ (x1, x2) && ((ipoint->pos.y == y1) || (ipoint->pos.y == y2))) { SheetPos w_pos, w_length; gboolean can_join; GSList *nodes; wire_get_pos_and_length (ipoint->wire, &w_pos, &w_length); gdouble _x1, _x2, _y1, _y2; _x1 = w_pos.x; _y1 = w_pos.y; _x2 = _x1 + w_length.x; _y2 = _y1 + w_length.y; can_join = TRUE; nodes = wire_get_nodes (wire); for (; nodes; nodes = nodes->next) { SheetPos p1; Node *node = (Node *)nodes->data; p1.x = _x1; p1.y = _y1; if ((fabs (node->key.x - p1.x) < 1e-3) && (fabs (node->key.y - p1.y) < 1e-3)){ can_join = FALSE; break; } p1.x = _x2; p1.y = _y2; if ((fabs (node->key.x - p1.x) < 1e-3) && (fabs (node->key.y - p1.y) < 1e-3)){ can_join = FALSE; break; } } if (IS_EQ(_x1, _x2) && can_join) { if (w_pos.x < pos.x) pos.x = w_pos.x; if (w_pos.y < pos.y) pos.y = w_pos.y; length.x += w_length.x; length.y += w_length.y; // Update the new size and pos of the wire item_data_unregister (ITEM_DATA (ipoint->wire)); wire_set_length (ipoint->wire, &length); item_data_set_pos (ITEM_DATA (ipoint->wire), &pos); wire_update_bbox (ipoint->wire); item_data_register (ITEM_DATA (ipoint->wire)); // Done!, return -1 so wire is deleted return -1; } } else if (IS_EQ (y1, y2) && ((ipoint->pos.x == x1) || (ipoint->pos.x == x2))) { SheetPos w_pos, w_length; gboolean can_join; GSList *nodes; wire_get_pos_and_length (ipoint->wire, &w_pos, &w_length); gdouble _x1, _x2, _y1, _y2; _x1 = w_pos.x; _y1 = w_pos.y; _x2 = _x1 + w_length.x; _y2 = _y1 + w_length.y; can_join = TRUE; nodes = wire_get_nodes (wire); for (; nodes; nodes = nodes->next) { SheetPos p; Node *node = (Node *)nodes->data; p.x = _x1; p.y = _y1; if ((fabs (node->key.x - p.x) < 1e-3) && (fabs (node->key.y - p.y) < 1e-3)){ can_join = FALSE; break; } p.x = _x2; p.y = _y2; if ((fabs (node->key.x - p.x) < 1e-3) && (fabs (node->key.y - p.y) < 1e-3)){ can_join = FALSE; break; } } if (IS_EQ(_y1, _y2) && can_join) { if (w_pos.x < pos.x) pos.x = w_pos.x; if (w_pos.y < pos.y) pos.y = w_pos.y; length.x += w_length.x; length.y += w_length.y; // Update the new size and pos of the wire item_data_unregister (ITEM_DATA (ipoint->wire)); wire_set_length (ipoint->wire, &length); item_data_set_pos (ITEM_DATA (ipoint->wire), &pos); wire_update_bbox (ipoint->wire); item_data_register (ITEM_DATA (ipoint->wire)); // Done!, return -1 so wire si deleted return -1; } } node = node_store_get_or_create_node (store, ipoint->pos); // Add the wire, and also the wire that is intersected. node_add_wire (node, wire); node_add_wire (node, ipoint->wire); wire_add_node (wire, node); wire_add_node (ipoint->wire, node); NG_DEBUG ("Add wire to wire.\n"); g_free (ipoint); } g_slist_free (ip_list); // Check for intersection with parts (pins). ip_list = wire_intersect_parts (store, wire); for (list = ip_list; list; list = list->next) { node = list->data; // Add the wire to the node (pin) that it intersected. node_add_wire (node, wire); wire_add_node (wire, node); NG_DEBUG ("Add wire to pin.\n"); } g_slist_free (ip_list); g_object_set (G_OBJECT (wire), "store", store, NULL); store->wires = g_list_prepend (store->wires, wire); store->items = g_list_prepend (store->items, wire); return TRUE; }
static int wire_item_event (WireItem *wire_item, const GdkEvent *event, SchematicView *sv) { SheetPos start_pos, length; Wire *wire; Sheet *sheet; GnomeCanvas *canvas; static double last_x, last_y; double dx, dy, zoom; /* The selected group's bounding box in window resp. canvas coordinates. */ double x1, y1, x2, y2; static double bb_x1, bb_y1, bb_x2, bb_y2; int cx1, cy1, cx2, cy2; double snapped_x, snapped_y; int sheet_width, sheet_height; SheetPos pos; sheet = schematic_view_get_sheet (sv); canvas = GNOME_CANVAS (sheet); g_object_get (G_OBJECT (wire_item), "data", &wire, NULL); wire_get_pos_and_length (WIRE (wire), &start_pos, &length); sheet_get_zoom (sheet, &zoom); switch (event->type) { case GDK_BUTTON_PRESS: switch (event->button.button) { case 1: { g_signal_stop_emission_by_name (G_OBJECT (sheet), "event"); double x, y; x = event->button.x - start_pos.x; y = event->button.y - start_pos.y; if ((x > -RESIZER_SIZE) && (x < RESIZER_SIZE) && (y > -RESIZER_SIZE) && (y < RESIZER_SIZE)) { gtk_widget_grab_focus (GTK_WIDGET (sheet)); sheet->state = SHEET_STATE_DRAG_START; wire_item->priv->resize_state = WIRE_RESIZER_1; last_x = event->button.x; last_y = event->button.y; item_data_unregister (ITEM_DATA (wire)); return TRUE; } if ((x > (length.x-RESIZER_SIZE)) && (x < (length.x+RESIZER_SIZE)) && (y > (length.y-RESIZER_SIZE)) && (y < (length.y+RESIZER_SIZE))) { gtk_widget_grab_focus (GTK_WIDGET (sheet)); sheet->state = SHEET_STATE_DRAG_START; wire_item->priv->resize_state = WIRE_RESIZER_2; last_x = event->button.x; last_y = event->button.y; item_data_unregister (ITEM_DATA (wire)); return TRUE; } } break; } break; case GDK_MOTION_NOTIFY: if (sheet->state != SHEET_STATE_DRAG && sheet->state != SHEET_STATE_DRAG_START) break; if (wire_item->priv->resize_state == WIRE_RESIZER_NONE) break; if (sheet->state == SHEET_STATE_DRAG_START || sheet->state == SHEET_STATE_DRAG) { sheet->state = SHEET_STATE_DRAG; snapped_x = event->motion.x; snapped_y = event->motion.y; snap_to_grid (sheet->grid, &snapped_x, &snapped_y); dx = snapped_x - last_x; dy = snapped_y - last_y; last_x = snapped_x; last_y = snapped_y; wire_get_pos_and_length (wire, &pos, &length); if (wire_item->priv->resize_state == WIRE_RESIZER_1) { switch (wire->priv->direction) { case WIRE_DIR_VERT: /* Vertical Wire */ pos.y = last_y; length.y -= dy; break; case WIRE_DIR_HORIZ: /* Horizontal Wire */ pos.x = last_x; length.x -= dx; break; default: pos.y = last_y; length.y -= dy; pos.x = last_x; length.x -= dx; } } else { switch (wire->priv->direction) { case WIRE_DIR_VERT: /* Vertical Wire */ length.y += dy; break; case WIRE_DIR_HORIZ: /* Horizontal Wire */ length.x += dx; break; default: length.y += dy; length.x += dx; } } snap_to_grid (sheet->grid, &length.x, &length.y); item_data_set_pos (sheet_item_get_data (SHEET_ITEM (wire_item)), &pos); wire_set_length (wire, &length); return TRUE; } break; case GDK_BUTTON_RELEASE: switch (event->button.button) { case 1: if (sheet->state != SHEET_STATE_DRAG && sheet->state != SHEET_STATE_DRAG_START) break; if (wire_item->priv->resize_state == WIRE_RESIZER_NONE) break; g_signal_stop_emission_by_name (G_OBJECT (wire_item), "event"); //gtk_timeout_remove (priv->scroll_timeout_id); // Esto no esta bien. sheet->state = SHEET_STATE_NONE; gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (wire_item), event->button.time); wire_item->priv->resize_state = WIRE_RESIZER_NONE; sheet->state = SHEET_STATE_NONE; item_data_register (ITEM_DATA (wire)); return TRUE; } break; default: return sheet_item_event (SHEET_ITEM (wire_item), event, sv); } return sheet_item_event (SHEET_ITEM (wire_item), event, sv); }