// 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; }
/* * remove the currently selected items from the sheet * (especially their goocanvas representators) */ void sheet_delete_selection (Sheet *sheet) { GList *copy, *iter; g_return_if_fail (sheet != NULL); g_return_if_fail (IS_SHEET (sheet)); if (sheet->state != SHEET_STATE_NONE) return; copy = g_list_copy (sheet->priv->selected_objects); for (iter = copy; iter; iter = iter->next) { sheet_remove_item_in_sheet (SHEET_ITEM (iter->data), sheet); goo_canvas_item_remove (GOO_CANVAS_ITEM (iter->data)); } g_list_free (copy); // we need to it like this as <sheet_remove_item_in_sheet> // requires selected_objects, items, floating_objects // to be not NULL! g_list_free (sheet->priv->selected_objects); sheet->priv->selected_objects = NULL; }
static void update_canvas_labels (PartItem *item) { PartItemPriv *priv; Part *part; GSList *labels, *label_items; GooCanvasItem *canvas_item; g_return_if_fail (item != NULL); g_return_if_fail (IS_PART_ITEM (item)); priv = item->priv; part = PART (sheet_item_get_data (SHEET_ITEM (item))); label_items = priv->label_items; // Put the label of each item for (labels = part_get_labels (part); labels; labels = labels->next, label_items = label_items->next) { char *text; PartLabel *label = (PartLabel*) labels->data; g_assert (label_items != NULL); canvas_item = label_items->data; text = part_property_expand_macros (part, label->text); g_object_set (canvas_item, "text", text, NULL); g_free (text); } }
gboolean rubberband_finish (Sheet *sheet, GdkEvent *event) { RubberbandInfo *rubberband_info; rubberband_info = sheet->priv->rubberband_info; #if 1 GList *iter = NULL; if (sheet->priv->preserve_selection_items) { for (iter = sheet->priv->preserve_selection_items; iter; iter = iter->next) sheet_item_set_preserve_selection (SHEET_ITEM (iter->data), FALSE); g_list_free (sheet->priv->preserve_selection_items); sheet->priv->preserve_selection_items = NULL; } #endif sheet_pointer_ungrab (sheet, event); g_object_set (rubberband_info->rectangle, "visibility", GOO_CANVAS_ITEM_INVISIBLE, NULL); rubberband_info->state = RUBBERBAND_START; return TRUE; }
// Retrieves the bounding box. We use a caching scheme for this // since it's too expensive to calculate it every time we need it. inline static void get_cached_bounds (TextboxItem *item, Coords *p1, Coords *p2) { PangoFontDescription *font; Coords pos; TextboxItemPriv *priv; priv = item->priv; if (!priv->cache_valid) { Coords start_pos, end_pos; font = pango_font_description_from_string (TEXTBOX_FONT); item_data_get_pos (sheet_item_get_data (SHEET_ITEM (item)), &pos); start_pos.x = pos.x; start_pos.y = pos.y - 5; // - font->ascent; end_pos.x = pos.x + 5; // + rbearing; end_pos.y = pos.y + 5; // + font->descent; priv->bbox_start = start_pos; priv->bbox_end = end_pos; priv->cache_valid = TRUE; pango_font_description_free (font); } memcpy (p1, &priv->bbox_start, sizeof(Coords)); memcpy (p2, &priv->bbox_end, sizeof(Coords)); }
void clipboard_add_object (GObject *item) { ItemDataClass *id_class; ItemData *item_data, *clone; ClipboardData *cb_data; g_return_if_fail (item != NULL); item_data = sheet_item_get_data (SHEET_ITEM (item)); g_return_if_fail (item_data != NULL); id_class = ITEM_DATA_CLASS (G_OBJECT_GET_CLASS (item_data)); if (id_class->clone == NULL) return; // Duplicate the data for the object and add to the clipboard. clone = id_class->clone (item_data); cb_data = g_new0 (ClipboardData, 1); cb_data->item_data = clone; cb_data->item_class = SHEET_ITEM_CLASS (G_OBJECT_GET_CLASS (item)); oregano.clipboard = g_slist_prepend (oregano.clipboard, cb_data); }
static void sheet_item_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *spec) { SheetItem *sheet_item; sheet_item = SHEET_ITEM (object); switch (prop_id) { case ARG_X: g_value_set_double (value, sheet_item->x); break; case ARG_Y: g_value_set_double (value, sheet_item->y); break; case ARG_WIDTH: g_value_set_double (value, sheet_item->width); break; case ARG_HEIGHT: g_value_set_double (value, sheet_item->height); break; case ARG_DATA: g_value_set_pointer (value, sheet_item->priv->data); break; case ARG_SHEET: g_value_set_pointer (value, sheet_item_get_sheet (sheet_item)); break; case ARG_ACTION_GROUP: g_value_set_pointer (value, sheet_item->priv->action_group); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (sheet_item, prop_id, spec); break; } }
void part_item_signal_connect_floating (PartItem *item) { Sheet *sheet; sheet = sheet_item_get_sheet (SHEET_ITEM (item)); sheet->state = SHEET_STATE_FLOAT_START; g_signal_connect (G_OBJECT (item), "double_clicked", G_CALLBACK (edit_properties), item); }
// Go through the properties and commit the changes. void edit_dialog_ok (TextboxItem *item) { const gchar *value; Textbox *textbox; g_return_if_fail (item != NULL); g_return_if_fail (IS_TEXTBOX_ITEM (item)); textbox = TEXTBOX (sheet_item_get_data (SHEET_ITEM (item))); value = gtk_entry_get_text (GTK_ENTRY (prop_dialog->entry)); textbox_set_text (textbox, value); }
/** * select all items on the sheet */ void sheet_select_all (Sheet *sheet, gboolean select) { GList *list; g_return_if_fail (sheet != NULL); g_return_if_fail (IS_SHEET (sheet)); for (list = sheet->priv->items; list; list = list->next) sheet_item_select (SHEET_ITEM (list->data), select); if (!select) sheet_release_selected_objects (sheet); }
void sheet_show_node_labels (Sheet *sheet, gboolean show) { g_return_if_fail (sheet != NULL); g_return_if_fail (IS_SHEET (sheet)); GList *item = NULL; for (item = sheet->priv->items; item; item = item->next) { if (IS_PART_ITEM (item->data)) if (part_get_num_pins (PART (sheet_item_get_data (SHEET_ITEM (item->data)))) == 1) part_item_show_node_labels (PART_ITEM (item->data), show); } }
/** * save the selection * @attention not stackable */ GList *sheet_preserve_selection (Sheet *sheet) { g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (IS_SHEET (sheet), FALSE); GList *list = NULL; for (list = sheet->priv->selected_objects; list; list = list->next) { sheet_item_set_preserve_selection (SHEET_ITEM (list->data), TRUE); } // Return the list so that we can remove the preserve_selection // flags later. return sheet->priv->selected_objects; }
static void textbox_item_init (TextboxItem *item) { TextboxItemPriv *priv; priv = g_new0 (TextboxItemPriv, 1); item->priv = priv; priv->highlight = FALSE; priv->cache_valid = FALSE; sheet_item_add_menu (SHEET_ITEM (item), textbox_item_context_menu, action_entries, G_N_ELEMENTS (action_entries)); }
static int unhighlight_wire (WireItem *item) { char *color; WireItemPriv *priv = item->priv; color = sheet_item_get_selected (SHEET_ITEM (item)) ? SELECTED_COLOR : NORMAL_COLOR; g_object_set (priv->line, "stroke-color", color, NULL); g_object_unref (G_OBJECT (item)); return FALSE; }
static void part_item_init (PartItem *item) { PartItemPriv *priv; priv = g_new0 (PartItemPriv, 1); priv->cache_valid = FALSE; item->priv = priv; sheet_item_add_menu (SHEET_ITEM (item), part_item_context_menu, action_entries, G_N_ELEMENTS (action_entries)); }
static void sheet_item_finalize (GObject *object) { GooCanvasItemSimple *simple = (GooCanvasItemSimple *)object; SheetItem *sheet_item; sheet_item = SHEET_ITEM (object); if (simple->simple_data) { g_free (sheet_item->priv); sheet_item->priv = NULL; } // FIXME check if we need // goo_canvas_sheet_item_unregister (sheet, item); G_OBJECT_CLASS (sheet_item_parent_class)->finalize (object); }
static int unhighlight_wire (WireItem *item) { char *color; WireItemPriv *priv = item->priv; color = sheet_item_get_selected (SHEET_ITEM (item)) ? SELECTED_COLOR : NORMAL_COLOR; gnome_canvas_item_set (GNOME_CANVAS_ITEM (priv->line), "fill_color", color, NULL); g_object_unref (G_OBJECT (item)); return FALSE; }
void wire_item_signal_connect_placed (WireItem *wire_item, Sheet *sheet) { ItemData *item; item = sheet_item_get_data (SHEET_ITEM (wire_item)); g_signal_connect (wire_item, "button-press-event", G_CALLBACK (wire_item_event), sheet); g_signal_connect (wire_item, "button-release-event", G_CALLBACK (wire_item_event), sheet); g_signal_connect (wire_item, "motion-notify-event", G_CALLBACK (wire_item_event), sheet); g_signal_connect (wire_item, "mouse_over", G_CALLBACK (mouse_over_wire_callback), sheet); g_signal_connect (item, "highlight", G_CALLBACK (highlight_wire_callback), wire_item); }
static void sheet_item_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *spec) { GooCanvasItemSimple *simple = (GooCanvasItemSimple*) object; SheetItem *sheet_item; Coords pos; sheet_item = SHEET_ITEM (object); switch (prop_id) { case ARG_X: sheet_item->x = g_value_get_double (value); break; case ARG_Y: sheet_item->y = g_value_get_double (value); break; case ARG_WIDTH: sheet_item->width = g_value_get_double (value); break; case ARG_HEIGHT: sheet_item->height = g_value_get_double (value); break; case ARG_DATA: if (sheet_item->priv->data) { g_warning (_("Cannot set SheetItem after creation.")); break; } sheet_item->priv->data = g_value_get_pointer (value); item_data_get_pos (sheet_item->priv->data, &pos); sheet_item->x = pos.x; sheet_item->y = pos.y; break; case ARG_ACTION_GROUP: sheet_item->priv->action_group = g_value_get_pointer (value); gtk_ui_manager_insert_action_group (sheet_item->priv->ui_manager, sheet_item->priv->action_group, 0); break; default: break; } goo_canvas_item_simple_changed (simple, TRUE); }
void part_item_update_node_label (PartItem *item) { PartItemPriv *priv; Part *part; GSList *labels; GooCanvasItem *canvas_item; Pin *pins; gint num_pins; g_return_if_fail (item != NULL); g_return_if_fail (IS_PART_ITEM (item)); priv = item->priv; part = PART (sheet_item_get_data (SHEET_ITEM (item))); g_return_if_fail (IS_PART (part) ); // Put the label of each node num_pins = part_get_num_pins (part); if (num_pins == 1) { pins = part_get_pins (part); labels = priv->label_nodes; for (labels = priv->label_nodes; labels; labels=labels->next) { char *txt; txt = g_strdup_printf ("V(%d)", pins[0].node_nr); canvas_item = labels->data; if (pins[0].node_nr != 0) g_object_set (canvas_item, "text", txt, "fill_color", LABEL_COLOR, "font", "Sans 8", NULL); else g_object_set (canvas_item, "text", "", NULL); g_free (txt); } } }
gboolean rubberband_start (Sheet *sheet, GdkEvent *event) { GList *list; double x, y; RubberbandInfo *rubberband_info; g_assert (event->type == GDK_BUTTON_PRESS); x = event->button.x; y = event->button.y; goo_canvas_convert_from_pixels (GOO_CANVAS (sheet), &x, &y); rubberband_info = sheet->priv->rubberband_info; rubberband_info->start.x = x; rubberband_info->start.y = y; rubberband_info->end.x = x; rubberband_info->end.y = y; rubberband_info->state = RUBBERBAND_ACTIVE; //FIXME TODO recheck g_assert (rubberband_info->rectangle!=NULL); g_object_set (rubberband_info->rectangle, "x", x, "y", y, "width", 0., "height", 0., "visibility", GOO_CANVAS_ITEM_VISIBLE, NULL); #if 1 // Mark all the selected objects to preserve their selected state // if SHIFT is pressed while rubberbanding. if (event->button.state & GDK_SHIFT_MASK) { for (list = sheet->priv->selected_objects; list; list = list->next) sheet_item_set_preserve_selection (SHEET_ITEM (list->data), TRUE); sheet->priv->preserve_selection_items = g_list_copy (sheet->priv->selected_objects); } #endif sheet_pointer_grab (sheet, event); return TRUE; }
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); }
void wire_item_signal_connect_placed (WireItem *wire, SchematicView *sv) { g_signal_connect ( G_OBJECT (wire), "event", G_CALLBACK(wire_item_event), sv); g_signal_connect ( G_OBJECT (wire), "mouse_over", G_CALLBACK(mouse_over_wire_cb), sv); g_signal_connect ( G_OBJECT (sheet_item_get_data (SHEET_ITEM (wire))), "highlight", G_CALLBACK(highlight_wire_cb), wire); }
void sheet_stop_rubberband (Sheet *sheet, GdkEventButton *event) { GList *list = NULL; sheet->priv->rubberband->state = RUBBER_NO; if (sheet->priv->preserve_selection_items != NULL) { for (list = sheet->priv->preserve_selection_items; list; list = list->next) sheet_item_set_preserve_selection (SHEET_ITEM (list->data), FALSE); g_list_free (sheet->priv->preserve_selection_items); sheet->priv->preserve_selection_items = NULL; } goo_canvas_pointer_ungrab (GOO_CANVAS (sheet), GOO_CANVAS_ITEM (sheet->grid), event->time); goo_canvas_item_remove (GOO_CANVAS_ITEM (sheet->priv->rubberband->rectangle)); //g_list_free_full (list, g_object_unref); //FIXME }
void sheet_delete_selection (Sheet *sheet) { GList *list, *copy; g_return_if_fail (sheet != NULL); g_return_if_fail (IS_SHEET (sheet)); if (sheet->state != SHEET_STATE_NONE) return; copy = g_list_copy (sheet->priv->selected_objects); for (list = copy; list; list = list->next) { sheet_remove_item_in_sheet (SHEET_ITEM (list->data), sheet); goo_canvas_item_remove (GOO_CANVAS_ITEM (list->data)); } g_list_free (sheet->priv->selected_objects); sheet->priv->selected_objects = NULL; g_list_free (copy); }
static void prop_dialog_response (GtkWidget *dialog, gint response, PartPropDialog *prop_dialog) { GSList *props; GList *widget; Property *prop; PartItem *item; Part *part; gchar *prop_name; const gchar *prop_value; GtkWidget *w; item = prop_dialog->part_item; part = PART (sheet_item_get_data (SHEET_ITEM (item))); for (widget = prop_dialog->widgets; widget; widget = widget->next) { w = widget->data; prop_name = g_object_get_data (G_OBJECT (w), "user"); prop_value = gtk_entry_get_text (GTK_ENTRY (w)); for (props = part_get_properties (part); props; props = props->next) { prop = props->data; if (g_ascii_strcasecmp (prop->name, prop_name) == 0) { if (prop->value) g_free (prop->value); prop->value = g_strdup (prop_value); } } g_free (prop_name); } g_slist_free_full (props, g_object_unref); update_canvas_labels (item); }
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); }
// Event handler for a "floating" group of objects. int sheet_item_floating_event (Sheet *sheet, const GdkEvent *event) { SheetPriv *priv; GList *list; static Coords pos; static int keep = 0; // Remember the last position of the mouse cursor. static double last_x, last_y; // Mouse cursor position in window coordinates, snapped to the grid spacing. double snapped_x, snapped_y; // Move the selected item(s) by this movement. double dx, dy; g_return_val_if_fail (sheet != NULL, FALSE); g_return_val_if_fail (IS_SHEET (sheet), FALSE); g_return_val_if_fail (sheet->priv->floating_objects != NULL, FALSE); priv = sheet->priv; switch (event->type) { case GDK_BUTTON_RELEASE: g_signal_stop_emission_by_name (sheet, "event"); break; case GDK_BUTTON_PRESS: if (sheet->state != SHEET_STATE_FLOAT) return TRUE; switch (event->button.button) { case 2: case 4: case 5: return FALSE; case 1: // do not free the floating items, but use them like a stamp keep = event->button.state & GDK_CONTROL_MASK; // Continue adding if CTRL is pressed if (!keep) { sheet->state = SHEET_STATE_NONE; g_signal_stop_emission_by_name (sheet, "event"); if (g_signal_handler_is_connected (sheet, sheet->priv->float_handler_id)) g_signal_handler_disconnect (sheet, sheet->priv->float_handler_id); sheet->priv->float_handler_id = 0; } // Get pointer position in canvas coordinates sheet_get_pointer (sheet, &pos.x, &pos.y); for (list = priv->floating_objects; list; list = list->next) { SheetItem *floating_item; ItemData *floating_data; // Create a real item. floating_item = list->data; if (!keep) { floating_data = sheet_item_get_data (floating_item); g_object_set (floating_item, "visibility", GOO_CANVAS_ITEM_INVISIBLE, NULL); } else { floating_data = item_data_clone (sheet_item_get_data (floating_item)); } g_object_ref (G_OBJECT (floating_data)); item_data_set_pos (floating_data, &pos); schematic_add_item (schematic_view_get_schematic_from_sheet (sheet), floating_data); if (!keep) g_object_unref (G_OBJECT (floating_item)); } if (keep) { g_object_set (G_OBJECT (sheet->priv->floating_group), "x", pos.x, "y", pos.y, NULL); } else { g_list_free (sheet->priv->floating_objects); sheet->priv->floating_objects = NULL; } pos.x = 0.0; pos.y = 0.0; break; case 3: // Cancel the "float-placement" for button-3 clicks. g_signal_stop_emission_by_name (sheet, "event"); sheet_item_cancel_floating (sheet); break; } break; case GDK_2BUTTON_PRESS: case GDK_3BUTTON_PRESS: g_signal_stop_emission_by_name (sheet, "event"); return TRUE; case GDK_MOTION_NOTIFY: if (sheet->state != SHEET_STATE_FLOAT && sheet->state != SHEET_STATE_FLOAT_START) return FALSE; g_signal_stop_emission_by_name (sheet, "event"); if (sheet->state == SHEET_STATE_FLOAT_START) { sheet->state = SHEET_STATE_FLOAT; // Reparent the selected objects so that we can move them // efficiently. for (list = priv->floating_objects; list; list = list->next) { sheet_item_reparent (SHEET_ITEM (list->data), priv->floating_group); // Set the floating item visible g_object_set (G_OBJECT (list->data), "visibility", GOO_CANVAS_ITEM_VISIBLE, NULL); } last_x = 0.0; last_y = 0.0; } // Get pointer position independantly of the zoom sheet_get_pointer (sheet, &snapped_x, &snapped_y); // Calculate which amount to move the selected objects by. dx = snapped_x - last_x; dy = snapped_y - last_y; last_x = snapped_x; last_y = snapped_y; for (list = priv->floating_objects; list; list = list->next) { goo_canvas_item_translate (GOO_CANVAS_ITEM (list->data), dx, dy); } g_list_free_full (list, g_object_unref); break; case GDK_KEY_PRESS: switch (event->key.keyval) { case GDK_KEY_r: case GDK_KEY_R: sheet_rotate_ghosts (sheet); { gdouble x, y; GooCanvasBounds bounds; sheet_get_pointer (sheet, &x, &y); // Center the objects around the mouse pointer. goo_canvas_item_get_bounds ( GOO_CANVAS_ITEM (priv->floating_group), &bounds); snapped_x = x - (bounds.x1 + bounds.x2) / 2; snapped_y = y - (bounds.y1 + bounds.y2) / 2; snap_to_grid (sheet->grid, &snapped_x, &snapped_y); goo_canvas_item_translate ( GOO_CANVAS_ITEM (priv->floating_group), snapped_x, snapped_y); last_x = snapped_x; last_y = snapped_y; } break; default: return FALSE; } default: return FALSE; } 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); }
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); }