Beispiel #1
0
// 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;
}
Beispiel #2
0
/*
 * 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;
}
Beispiel #3
0
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);
	}
}
Beispiel #4
0
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;
}
Beispiel #5
0
// 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));
}
Beispiel #6
0
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);
}
Beispiel #7
0
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;
	}
}
Beispiel #8
0
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);
}
Beispiel #9
0
// 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);
}
Beispiel #10
0
/**
 * 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);
}
Beispiel #11
0
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);
	}
}
Beispiel #12
0
/**
 * 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;
}
Beispiel #13
0
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));
}
Beispiel #14
0
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;
}
Beispiel #15
0
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));
}
Beispiel #16
0
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);
}
Beispiel #17
0
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;
}
Beispiel #18
0
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);
}
Beispiel #19
0
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);
}
Beispiel #20
0
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);
		}
	}
}
Beispiel #21
0
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;
}
Beispiel #22
0
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);
}
Beispiel #23
0
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);
}
Beispiel #24
0
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
}
Beispiel #25
0
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);
}
Beispiel #26
0
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);
}
Beispiel #27
0
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);
}
Beispiel #28
0
// 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;
}
Beispiel #29
0
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);
}
Beispiel #30
0
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);
}