static void wire_rotated_callback (ItemData *data, int angle, SheetItem *sheet_item) { WireItem *wire_item; GooCanvasPoints *points; Coords start_pos, length; g_return_if_fail (sheet_item != NULL); g_return_if_fail (IS_WIRE_ITEM (sheet_item)); wire_item = WIRE_ITEM (sheet_item); wire_get_pos_and_length (WIRE (data), &start_pos, &length); points = goo_canvas_points_new (2); points->coords[0] = 0; points->coords[1] = 0; points->coords[2] = length.x; points->coords[3] = length.y; g_object_set (wire_item->priv->line, "points", points, NULL); goo_canvas_points_unref (points); g_object_set (wire_item, "x", start_pos.x, "y", start_pos.y, NULL); g_object_set (wire_item->priv->resize2, "x", length.x - RESIZER_SIZE, "y", length.y - RESIZER_SIZE, NULL); // Invalidate the bounding box cache. wire_item->priv->cache_valid = FALSE; }
static void wire_flipped_callback (ItemData *data, IDFlip direction, SheetItem *sheet_item) { GooCanvasPoints *points; WireItem *item; WireItemPriv *priv; Coords start_pos, length; g_return_if_fail (sheet_item != NULL); g_return_if_fail (IS_WIRE_ITEM (sheet_item)); item = WIRE_ITEM (sheet_item); priv = item->priv; wire_get_pos_and_length (WIRE (data), &start_pos, &length); points = goo_canvas_points_new (2); points->coords[0] = 0; points->coords[1] = 0; points->coords[2] = length.x; points->coords[3] = length.y; g_object_set (item->priv->line, "points", points, NULL); goo_canvas_points_unref (points); g_object_set (item, "x", start_pos.x, "y", start_pos.y, NULL); // Invalidate the bounding box cache. priv->cache_valid = FALSE; }
// Create a SheetItem from an ItemData object. This is a bit ugly. // It could be beautified by having a method that creates the item. // E.g. sheet_item->new_from_data (data); SheetItem * sheet_item_factory_create_sheet_item (Sheet *sheet, ItemData *data) { SheetItem *item; g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (IS_ITEM_DATA (data), NULL); g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (IS_SHEET (sheet), NULL); item = NULL; // Pick the right model. if (IS_PART (data)) { NG_DEBUG ("sheet_item_factory_create_sheet_item part\n\n"); item = SHEET_ITEM (part_item_new (sheet, PART (data))); } else if (IS_WIRE (data)) { NG_DEBUG ("sheet_item_factory_create_sheet_item wire\n\n"); item = SHEET_ITEM (wire_item_new (sheet, WIRE (data))); } else if (IS_TEXTBOX (data)) { NG_DEBUG ("sheet_item_factory_create_sheet_item text\n\n"); item = SHEET_ITEM (textbox_item_new (sheet, TEXTBOX (data))); } else g_warning ("Unknown Item type."); return item; }
static gboolean wire_register (ItemData *data) { NodeStore *store; g_return_val_if_fail (IS_WIRE (data), FALSE); store = item_data_get_store (data); return node_store_add_wire (store, WIRE (data)); }
static void wire_unregister (ItemData *data) { NodeStore *store; g_return_if_fail (IS_WIRE (data)); store = item_data_get_store (data); node_store_remove_wire (store, WIRE (data)); }
static void wire_copy (ItemData *dest, ItemData *src) { Wire *dest_wire, *src_wire; g_return_if_fail (dest != NULL); g_return_if_fail (IS_WIRE (dest)); g_return_if_fail (src != NULL); g_return_if_fail (IS_WIRE (src)); if (parent_class->copy != NULL) parent_class->copy (dest, src); dest_wire = WIRE (dest); src_wire = WIRE (src); dest_wire->priv->nodes = NULL; dest_wire->priv->length = src_wire->priv->length; }
static void wire_finalize (GObject *object) { Wire *wire = WIRE (object); WirePriv *priv = wire->priv; if (priv) { g_slist_free (priv->nodes); g_free (priv); wire->priv = NULL; } G_OBJECT_CLASS (parent_class)->finalize (object); }
static void wire_rotated_callback (ItemData *data, int angle, SheetItem *sheet_item) { WireItem *wire_item; GnomeCanvasPoints *points; SheetPos start_pos, length; g_return_if_fail (sheet_item != NULL); g_return_if_fail (IS_WIRE_ITEM (sheet_item)); wire_item = WIRE_ITEM (sheet_item); wire_get_pos_and_length (WIRE (data), &start_pos, &length); points = gnome_canvas_points_new (2); points->coords[0] = 0; points->coords[1] = 0; points->coords[2] = length.x; points->coords[3] = length.y; gnome_canvas_item_set (GNOME_CANVAS_ITEM (wire_item->priv->line), "points", points, NULL); gnome_canvas_points_unref (points); gnome_canvas_item_set (GNOME_CANVAS_ITEM (wire_item), "x", start_pos.x, "y", start_pos.y, NULL); gnome_canvas_item_set ( GNOME_CANVAS_ITEM (wire_item-> priv->resize2), "x1", length.x-RESIZER_SIZE, "y1", length.y-RESIZER_SIZE, "x2", length.x+RESIZER_SIZE, "y2", length.y+RESIZER_SIZE, NULL ); /* * Invalidate the bounding box cache. */ wire_item->priv->cache_valid = FALSE; }
static void wire_print (ItemData *data, cairo_t *cr, SchematicPrintContext *ctx) { Coords start_pos, end_pos; Wire *wire; g_return_if_fail (data != NULL); g_return_if_fail (IS_WIRE (data)); wire = WIRE (data); wire_get_start_pos (wire, &start_pos); wire_get_end_pos (wire, &end_pos); cairo_save (cr); gdk_cairo_set_source_rgba (cr, &ctx->colors.wires); cairo_move_to (cr, start_pos.x, start_pos.y); cairo_line_to (cr, end_pos.x, end_pos.y); cairo_stroke (cr); cairo_restore (cr); }
static void mouse_over_wire_callback (WireItem *item, Sheet *sheet) { GList *iter; Wire *wire; NodeStore *store; if (sheet->state != SHEET_STATE_NONE) return; store = schematic_get_store (schematic_view_get_schematic_from_sheet (sheet)); node_store_node_foreach (store, (GHFunc *)node_foreach_reset, NULL); for (iter = store->wires; iter; iter = iter->next) { wire = iter->data; wire_set_visited (wire, FALSE); } wire = WIRE (sheet_item_get_data (SHEET_ITEM (item))); wire_traverse (wire); }
static void wire_flipped_callback (ItemData *data, gboolean horizontal, SheetItem *sheet_item) { GnomeCanvasPoints *points; WireItem *item; WireItemPriv *priv; SheetPos start_pos, length; g_return_if_fail (sheet_item != NULL); g_return_if_fail (IS_WIRE_ITEM (sheet_item)); item = WIRE_ITEM (sheet_item); priv = item->priv; wire_get_pos_and_length (WIRE (data), &start_pos, &length); points = gnome_canvas_points_new (2); points->coords[0] = 0; points->coords[1] = 0; points->coords[2] = length.x; points->coords[3] = length.y; gnome_canvas_item_set (GNOME_CANVAS_ITEM (item->priv->line), "points", points, NULL); gnome_canvas_points_unref (points); gnome_canvas_item_set (GNOME_CANVAS_ITEM (item), "x", start_pos.x, "y", start_pos.y, NULL); /* * Invalidate the bounding box cache. */ priv->cache_valid = FALSE; }
static void mouse_over_wire_cb (WireItem *item, SchematicView *sv) { GList *wires; Wire *wire; NodeStore *store; Sheet *sheet; sheet = schematic_view_get_sheet (sv); if (sheet->state != SHEET_STATE_NONE) return; store = schematic_get_store (schematic_view_get_schematic (sv)); node_store_node_foreach (store, (GHFunc *) node_foreach_reset, NULL); for (wires = store->wires; wires; wires = wires->next) { wire = wires->data; wire_set_visited (wire, FALSE); } wire = WIRE (sheet_item_get_data (SHEET_ITEM (item))); wire_traverse (wire); }
static void wire_rotate (ItemData *data, int angle, Coords *center_pos) { cairo_matrix_t affine; double x, y; Wire *wire; WirePriv *priv; Coords b1, b2; Coords wire_center_before, wire_center_after, delta; Coords delta_cp_before, delta_cp_after; g_return_if_fail (data != NULL); g_return_if_fail (IS_WIRE (data)); if (angle == 0) return; wire = WIRE (data); item_data_get_absolute_bbox (ITEM_DATA (wire), &b1, &b2); wire_center_before = coords_average (&b1, &b2); priv = wire->priv; if (priv->direction == WIRE_DIR_VERT) { priv->direction = WIRE_DIR_HORIZ; } else if (priv->direction == WIRE_DIR_HORIZ) { priv->direction = WIRE_DIR_VERT; } cairo_matrix_init_rotate (&affine, (double)angle * M_PI / 180.0); // Rotate the wire's end point. x = priv->length.x; y = priv->length.y; cairo_matrix_transform_point (&affine, &x, &y); if (fabs (x) < 1e-2) x = 0.0; if (fabs (y) < 1e-2) y = 0.0; priv->length.x = x; priv->length.y = y; if (center_pos) { delta_cp_before = coords_sub (&wire_center_before, center_pos); delta_cp_after = delta_cp_before; cairo_matrix_transform_point (&affine, &delta_cp_after.x, &delta_cp_after.y); } // Update bounding box. wire_update_bbox (wire); item_data_get_absolute_bbox (ITEM_DATA (wire), &b1, &b2); wire_center_after = coords_average (&b1, &b2); delta = coords_sub (&wire_center_before, &wire_center_after); if (center_pos) { Coords diff = coords_sub (&delta_cp_after, &delta_cp_before); coords_add (&delta, &diff); } item_data_move (ITEM_DATA (wire), &delta); // item_data_snap (ITEM_DATA (wire), NULL); //FIXME XXX // Let the views (canvas items) know about the rotation. g_signal_emit_by_name (G_OBJECT (wire), "rotated", angle); // legacy g_signal_emit_by_name (G_OBJECT (wire), "changed"); }
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); }
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); }
gboolean delayed_wire_delete (gpointer user_data) { wire_delete (WIRE (user_data)); g_object_unref (G_OBJECT (WIRE (user_data))); return G_SOURCE_REMOVE; }
Wire *wire_new () { return WIRE (g_object_new (TYPE_WIRE, NULL)); }