Ejemplo n.º 1
0
int
node_store_is_wire_at_pos (NodeStore *store, SheetPos pos)
{
	GList *list;
	Wire *wire;
	SheetPos wire_pos, wire_length;
	double x1, y1, x2, y2;

	g_return_val_if_fail (store != NULL, FALSE);
	g_return_val_if_fail (IS_NODE_STORE (store), FALSE);

	for (list = store->wires; list; list = list->next) {
		wire = list->data;

		wire_get_pos_and_length (wire, &wire_pos, &wire_length);
		x1 = wire_pos.x;
		y1 = wire_pos.y;
		x2 = x1 + wire_length.x;
		y2 = y1 + wire_length.y;

		if (is_wire_at_pos (x1, y1, x2, y2, pos))
			return TRUE;
	}
	g_list_free_full (list, g_object_unref);

	return FALSE;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
static void
wire_changed_callback (Wire *wire, WireItem *item)
{
	SheetPos start_pos, length;
	GnomeCanvasPoints *points;

	wire_get_pos_and_length (wire, &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->priv->resize1),
		"x1", -RESIZER_SIZE,
		"y1", -RESIZER_SIZE,
		"x2", RESIZER_SIZE,
		"y2", RESIZER_SIZE,
		NULL);

	gnome_canvas_item_set (GNOME_CANVAS_ITEM (item->priv->resize2),
		"x1", length.x-RESIZER_SIZE,
		"y1", length.y-RESIZER_SIZE,
		"x2", length.x+RESIZER_SIZE,
		"y2", length.y+RESIZER_SIZE,
		NULL);
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
static void
wire_changed_callback (Wire *wire, WireItem *item)
{
	SheetPos start_pos, length;
	GooCanvasPoints *points;
	
	wire_get_pos_and_length (wire, &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->priv->resize1,
	              "x", -RESIZER_SIZE, 
	              "y", -RESIZER_SIZE,
	              "width", 2 * RESIZER_SIZE, 
	              "height", 2 * RESIZER_SIZE, 
	              NULL);

	g_object_set (item->priv->resize2,
	              "x", length.x-RESIZER_SIZE, 
	              "y", length.y-RESIZER_SIZE,
	              "width", 2 * RESIZER_SIZE, 
	              "height", 2 * RESIZER_SIZE, 
	              NULL);

	goo_canvas_item_request_update (GOO_CANVAS_ITEM (item->priv->line));
}
Ejemplo n.º 6
0
static GSList *
wire_intersect_parts (NodeStore *store, Wire *wire)
{
	GList *list;
	GSList *ip_list;
	Node *node;
	SheetPos lookup_pos;
	SheetPos part_pos, wire_pos, wire_length;
	Part *part;
	double x, y, wire_x1, wire_y1, wire_x2, wire_y2;
	int i, num_pins;

	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);

	ip_list = NULL;

	wire_get_pos_and_length (wire, &wire_pos, &wire_length);

	wire_x1 = wire_pos.x;
	wire_x2 = wire_pos.x + wire_length.x;
	wire_y1 = wire_pos.y;
	wire_y2 = wire_pos.y + wire_length.y;

	// Go through all the parts and see which of their
	// pins that intersect the wire.
	for (list = store->parts; list; list = list->next) {
		part = list->data;

		num_pins = part_get_num_pins (part);
		item_data_get_pos (ITEM_DATA (part), &part_pos);

		for (i = 0; i < num_pins; i++) {
			Pin *pins;

			pins = part_get_pins (part);
			x = part_pos.x + pins[i].offset.x;
			y = part_pos.y + pins[i].offset.y;

			lookup_pos.x = x;
			lookup_pos.y = y;

			// If there is a wire at this pin's position,
			// add it to the return list.
			if (is_wire_at_pos (wire_x1, wire_y1, wire_x2, wire_y2, lookup_pos)) {
				node = node_store_get_node (store, lookup_pos);

				if (node != NULL)
					ip_list = g_slist_prepend (ip_list, node);
			}
		}
	}
	g_list_free_full (list, g_object_unref);

	return ip_list;
}
Ejemplo n.º 7
0
static void
wire_changed_callback (Wire *wire, WireItem *item)
{
	Coords start_pos, length;
	GooCanvasPoints *points;

	g_return_if_fail (wire != NULL);
	g_return_if_fail (IS_ITEM_DATA (wire));
	g_return_if_fail (item != NULL);
	g_return_if_fail (IS_WIRE_ITEM (item));


	wire_get_pos_and_length (wire, &start_pos, &length);

	Sheet *sheet = SHEET (goo_canvas_item_get_canvas (GOO_CANVAS_ITEM (item)));
	if (G_UNLIKELY(!sheet)) {
		g_warning ("Failed to determine the Sheet the item is glued to. This should never happen. Ever!");
	} else {
		item_data_snap (ITEM_DATA (wire), sheet->grid);
	}

	// Move the canvas item and invalidate the bbox cache.
	goo_canvas_item_set_simple_transform (GOO_CANVAS_ITEM (item),
	                                      start_pos.x,
	                                      start_pos.y,
	                                      1.0,
	                                      0.0);
	item->priv->cache_valid = FALSE;

	points = goo_canvas_points_new (2);
	points->coords[0] = 0;
	points->coords[1] = 0;
	points->coords[2] = length.x;
	points->coords[3] = length.y;

	// this does handle cleanup of previous points internally
	g_object_set (item->priv->line,
	              "points", points,
	              NULL);
	goo_canvas_points_unref (points);

	g_object_set (item->priv->resize1,
	              "x", -RESIZER_SIZE,
	              "y", -RESIZER_SIZE,
	              "width", 2 * RESIZER_SIZE,
	              "height", 2 * RESIZER_SIZE,
	              NULL);

	g_object_set (item->priv->resize2,
	              "x", length.x-RESIZER_SIZE,
	              "y", length.y-RESIZER_SIZE,
	              "width", 2 * RESIZER_SIZE,
	              "height", 2 * RESIZER_SIZE,
	              NULL);

	goo_canvas_item_request_update (GOO_CANVAS_ITEM (item->priv->line));
}
Ejemplo n.º 8
0
void wire_update_bbox (Wire *wire)
{
    Coords b1, b2, pos, length;

    wire_get_pos_and_length (wire, &pos, &length);

    b1.x = b1.y = 0.0;
    b2 = length;

    item_data_set_relative_bbox (ITEM_DATA (wire), &b1, &b2);
}
Ejemplo n.º 9
0
int
node_store_remove_wire (NodeStore *store, Wire *wire)
{
	GSList *list;
	SheetPos lookup_key, 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);

	if (item_data_get_store (ITEM_DATA (wire)) == NULL) {
		g_warning ("Trying to remove non-stored wire.");
		return FALSE;
	}

	wire_get_pos_and_length (wire, &pos, &length);

	store->wires = g_list_remove (store->wires, wire);
	store->items = g_list_remove (store->items, wire);

	// If the nodes that this wire passes through will be
	// empty when the wire is removed, remove the node as well.

	// We must work on a copy of the nodes list, since it
	// changes as we remove nodes.
	list = g_slist_copy (wire_get_nodes (wire));

	for (; list; list = list->next) {
		Node *node = list->data;

		lookup_key = node->key;

		node_remove_wire (node, wire);

		wire_remove_node (wire, node);

		if (node_is_empty (node))
			g_hash_table_remove (store->nodes, &lookup_key);
	}

	g_slist_free (list);

	return TRUE;
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
static GSList *
wires_intersect (NodeStore *store, double x1, double y1, double x2, double y2)
{
	GList *list;
	GSList *ip_list;
	Wire *wire;
	SheetPos pos, wire_pos, wire_length;
	double wire_x1, wire_y1, wire_x2, wire_y2;

	g_return_val_if_fail (store != NULL, FALSE);
	g_return_val_if_fail (IS_NODE_STORE (store), FALSE);

	// Search through all the wires. Is there a better way?
	ip_list = NULL;
	for (list = store->wires; list; list = list->next) {
		wire = list->data;

		wire_get_pos_and_length (wire, &wire_pos, &wire_length);
		wire_x1 = wire_pos.x;
		wire_y1 = wire_pos.y;
		wire_x2 = wire_x1 + wire_length.x;
		wire_y2 = wire_y1 + wire_length.y;

		if (do_wires_intersect (x1, y1, x2, y2, wire_x1, wire_y1,
								wire_x2, wire_y2, &pos)) {
			IntersectionPoint *ip;

			ip = g_new0 (IntersectionPoint, 1);

			ip->wire = wire;
			ip->pos = pos;
			ip_list = g_slist_prepend (ip_list, ip);
		}
	}
	g_list_free_full (list, g_object_unref);

	return ip_list;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
gboolean
node_needs_dot (Node *node)
{
	Wire *wire1, *wire2;
	Coords start_pos1, length1, end_pos1;
	Coords start_pos2, length2, end_pos2;

	NG_DEBUG ("\nnode: %p --- pins: %i --- wires: %i", node, node->pin_count, node->wire_count);

	// always display a black dot if a part hits a wire
	if (node->pin_count >= 1 && node->wire_count >= 1) {
		NG_DEBUG ("  TRUE (pins>=1 && wires>=1)");
		return TRUE;
	// FIXME this can create sparse knots, because of overlaying wires o===xxxx===o
	// TODO can be fixed by optimizing away/fuzing duplicate/overlaying wires
	} else if ((node->pin_count + node->wire_count) > 2) {
		NG_DEBUG ("  TRUE (pins+wires>2)");
		return TRUE;
	} else if (node->wire_count == 2) {
		// Check that we don't have two wire endpoints.
		wire1 = node->wires->data;
		wire2 = node->wires->next->data;

		wire_get_pos_and_length (wire1, &start_pos1, &length1);
		wire_get_pos_and_length (wire2, &start_pos2, &length2);

		end_pos1.x = start_pos1.x + length1.x;
		end_pos1.y = start_pos1.y + length1.y;
		end_pos2.x = start_pos2.x + length2.x;
		end_pos2.y = start_pos2.y + length2.y;

		if (!(SEP (start_pos1, start_pos2) ||
			  SEP (start_pos1, end_pos2)   ||
			  SEP (end_pos1, end_pos2)     ||
			  SEP (end_pos1, start_pos2))) {

			// The dot is only needed when the end/start-point of
			// one of the wires in on the other wire.
			if (ON_THE_WIRE (start_pos1, start_pos2, end_pos2) ||
			    ON_THE_WIRE (  end_pos1, start_pos2, end_pos2) ||
			    ON_THE_WIRE (start_pos2, start_pos1, end_pos1) ||
			    ON_THE_WIRE (  end_pos2, start_pos1, end_pos1)
			) {
				NG_DEBUG ("  TRUE (wires>2 && endpoint on wire)");
				return TRUE;
			} else {
				NG_DEBUG ("  FALSE (wires>2 && crossing)");
				return FALSE;
			}
		}
		return FALSE;
	} else if (node->pin_count == 1 && node->wire_count == 1) {
		// TODO this is most likely obsolete and is never entered
		// Check if we have one wire with a pin in the 'middle'.
		wire1 = node->wires->data;
		wire_get_pos_and_length (wire1, &start_pos1, &length1);
		end_pos1.x = start_pos1.x + length1.x;
		end_pos1.y = start_pos1.y + length1.y;

		if (!SEP (node->key, start_pos1) && !SEP (node->key, end_pos1)) {
			NG_DEBUG ("  FALSE (pins==1 && wires==1) pin in the middle of a wire");
			return TRUE;
		}
	}
	NG_DEBUG (" FALSE (else)");
	return FALSE;
}
Ejemplo n.º 14
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);
}
Ejemplo n.º 15
0
WireItem *
wire_item_new (Sheet *sheet, Wire *wire)
{
	GooCanvasItem *item;
	WireItem *wire_item;
	GooCanvasPoints *points;
	WireItemPriv *priv;
	SheetPos start_pos, length;

	g_return_val_if_fail (sheet != NULL, NULL);
	g_return_val_if_fail (IS_SHEET (sheet), NULL);

	wire_get_pos_and_length (wire, &start_pos, &length);

	item = g_object_new (TYPE_WIRE_ITEM, NULL);
	
	g_object_set (item, 
	              "parent", sheet->object_group, 
	              NULL);
	
	wire_item = WIRE_ITEM (item);
	g_object_set (wire_item, 
	              "data", wire,
	              NULL);

	priv = wire_item->priv;
	
	priv->resize1 = GOO_CANVAS_RECT (goo_canvas_rect_new (
	           	GOO_CANVAS_ITEM (wire_item),
			   	-RESIZER_SIZE, 
	            -RESIZER_SIZE, 
	            2 * RESIZER_SIZE, 
	            2 * RESIZER_SIZE,
	    		"stroke-color", "blue",
	            "fill-color", "green",
	    		"line-width", 1.0,
	    		NULL));
	g_object_set (priv->resize1, 
				  "visibility", GOO_CANVAS_ITEM_INVISIBLE, 
	              NULL);

	priv->resize2 = GOO_CANVAS_RECT (goo_canvas_rect_new (
				GOO_CANVAS_ITEM (wire_item),
				length.x - RESIZER_SIZE, 
	     		length.y - RESIZER_SIZE, 
	            2 * RESIZER_SIZE,
	    		2 * RESIZER_SIZE,
	    		"stroke-color", "blue",
	            "fill-color", "green",
	    		"line-width", 1.0, 
	    		NULL));
	g_object_set (priv->resize2, 
				  "visibility", GOO_CANVAS_ITEM_INVISIBLE, 
	              NULL);

	points = goo_canvas_points_new (2);                                 
	points->coords[0] = 0;
	points->coords[1] = 0;
	points->coords[2] = length.x;
	points->coords[3] = length.y;

	priv->line = GOO_CANVAS_POLYLINE (goo_canvas_polyline_new (
	    GOO_CANVAS_ITEM (wire_item), 
		FALSE, 0, 
	    "points", points, 
	    "stroke-color", "blue", 
	    "line-width", 1.0, 
	    NULL));
	
	goo_canvas_points_unref (points);

	ITEM_DATA (wire)->rotated_handler_id = 
		g_signal_connect_data (wire, "rotated",
		G_CALLBACK (wire_rotated_callback), G_OBJECT (wire_item), NULL, 0);
	
	g_signal_connect_data (wire, "flipped",
		G_CALLBACK (wire_flipped_callback), G_OBJECT (wire_item), NULL, 0);
	
	ITEM_DATA (wire)->moved_handler_id = 
		g_signal_connect_object (wire, "moved",
		G_CALLBACK (wire_moved_callback),  G_OBJECT (wire_item), 0);

	g_signal_connect (wire, "changed", 
		G_CALLBACK (wire_changed_callback), wire_item);

	g_signal_connect (wire, "delete", 
	    G_CALLBACK (wire_delete_callback), wire_item);
	                                   
	wire_update_bbox (wire);

	return wire_item;
}
Ejemplo n.º 16
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);
}
Ejemplo n.º 17
0
WireItem *wire_item_new (Sheet *sheet, Wire *wire)
{
	GooCanvasItem *item;
	WireItem *wire_item;
	ItemData *item_data;
	GooCanvasPoints *points;
	WireItemPriv *priv;
	Coords start_pos, length;

	g_return_val_if_fail (sheet != NULL, NULL);
	g_return_val_if_fail (IS_SHEET (sheet), NULL);

	wire_get_pos_and_length (wire, &start_pos, &length);

	item = g_object_new (TYPE_WIRE_ITEM, NULL);

	g_object_set (item, "parent", sheet->object_group, NULL);

	wire_item = WIRE_ITEM (item);
	g_object_set (wire_item, "data", wire, NULL);

	priv = wire_item->priv;

	const int random_color_count = 9;
	const char *random_color[] = {"blue",   "red",  "green" /*, "yellow"*/, "orange",    "brown",
	                              "purple", "pink", "lightblue",            "lightgreen"};

	priv->resize1 = GOO_CANVAS_RECT (
	    goo_canvas_rect_new (GOO_CANVAS_ITEM (wire_item), -RESIZER_SIZE, -RESIZER_SIZE,
	                         2 * RESIZER_SIZE, 2 * RESIZER_SIZE, "stroke-color",
	                         oregano_options_debug_wires ()
	                             ? random_color[g_random_int_range (0, random_color_count - 1)]
	                             : "blue",
	                         "fill-color", "green", "line-width", 1.0, NULL));
	g_object_set (priv->resize1, "visibility", GOO_CANVAS_ITEM_INVISIBLE, NULL);

	priv->resize2 = GOO_CANVAS_RECT (goo_canvas_rect_new (
	    GOO_CANVAS_ITEM (wire_item), length.x - RESIZER_SIZE, length.y - RESIZER_SIZE,
	    2 * RESIZER_SIZE, 2 * RESIZER_SIZE, "stroke-color",
	    oregano_options_debug_wires ()
	        ? random_color[g_random_int_range (0, random_color_count - 1)]
	        : "blue",
	    "fill-color", "green", "line-width", 1.0, NULL));
	g_object_set (priv->resize2, "visibility", GOO_CANVAS_ITEM_INVISIBLE, NULL);

	points = goo_canvas_points_new (2);
	points->coords[0] = 0;
	points->coords[1] = 0;
	points->coords[2] = length.x;
	points->coords[3] = length.y;

	priv->line = GOO_CANVAS_POLYLINE (goo_canvas_polyline_new (
	    GOO_CANVAS_ITEM (wire_item), FALSE, 0, "points", points, "stroke-color",
	    oregano_options_debug_wires ()
	        ? random_color[g_random_int_range (0, random_color_count - 1)]
	        : "blue",
	    "line-width", 1.0, "start-arrow", oregano_options_debug_wires () ? TRUE : FALSE,
	    "end-arrow", oregano_options_debug_wires () ? TRUE : FALSE, NULL));

	goo_canvas_points_unref (points);

	item_data = ITEM_DATA (wire);
	item_data->rotated_handler_id = g_signal_connect_object (
	    G_OBJECT (wire), "rotated", G_CALLBACK (wire_rotated_callback), G_OBJECT (wire_item), 0);
	item_data->flipped_handler_id = g_signal_connect_object (
	    G_OBJECT (wire), "flipped", G_CALLBACK (wire_flipped_callback), G_OBJECT (wire_item), 0);
	item_data->moved_handler_id = g_signal_connect_object (
	    G_OBJECT (wire), "moved", G_CALLBACK (wire_moved_callback), G_OBJECT (wire_item), 0);
	item_data->changed_handler_id = g_signal_connect_object (
	    G_OBJECT (wire), "changed", G_CALLBACK (wire_changed_callback), G_OBJECT (wire_item), 0);

	g_signal_connect (wire, "delete", G_CALLBACK (wire_delete_callback), wire_item);

	wire_update_bbox (wire);

	return wire_item;
}
Ejemplo n.º 18
0
WireItem *
wire_item_new (Sheet *sheet, Wire *wire)
{
	WireItem *item;
	GnomeCanvasPoints *points;
	WireItemPriv *priv;
	SheetPos start_pos, length;

	g_return_val_if_fail (sheet != NULL, NULL);
	g_return_val_if_fail (IS_SHEET (sheet), NULL);

	//g_object_ref (G_OBJECT(wire));
	/* XXX Ver si hay equivalente gtk_object_sink (GTK_OBJECT (wire)); */

	wire_get_pos_and_length (wire, &start_pos, &length);

	/*
	 * Because of the GnomeCanvasGroup inheritance, a small hack is needed
	 * here. The group starts at the startpoint of the wire, and the line
	 * goes from (0,0) to (length.x, length.y).
	 */
	item = WIRE_ITEM (gnome_canvas_item_new (
		sheet->object_group,
		wire_item_get_type (),
		"data", wire,
		"x", (double) start_pos.x,
		"y", (double) start_pos.y,
		NULL));

	priv = item->priv;

	priv->resize1 = GNOME_CANVAS_RECT (gnome_canvas_item_new (
		GNOME_CANVAS_GROUP (item),
		gnome_canvas_rect_get_type (),
		"x1", -RESIZER_SIZE,
		"y1", -RESIZER_SIZE,
		"x2", RESIZER_SIZE,
		"y2", RESIZER_SIZE,
		"fill_color", "red",
		"fill_color_rgba", 0x3cb37180,
		"outline_color", "blue",
		"width_pixels", 1,
		NULL));

	priv->resize2 = GNOME_CANVAS_RECT (gnome_canvas_item_new (
		GNOME_CANVAS_GROUP (item),
		gnome_canvas_rect_get_type (),
		"x1", length.x-RESIZER_SIZE,
		"y1", length.y-RESIZER_SIZE,
		"x2", length.x+RESIZER_SIZE,
		"y2", length.y+RESIZER_SIZE,
		"fill_color", "red",
		"fill_color_rgba", 0x3cb37180,
		"outline_color", "blue",
		"width_pixels", 1,
		NULL));
	gnome_canvas_item_hide (GNOME_CANVAS_ITEM (priv->resize1));
	gnome_canvas_item_hide (GNOME_CANVAS_ITEM (priv->resize2));

	points = gnome_canvas_points_new (2);
	points->coords[0] = 0;
	points->coords[1] = 0;
	points->coords[2] = length.x;
	points->coords[3] = length.y;

	priv->line = GNOME_CANVAS_LINE (gnome_canvas_item_new (
		GNOME_CANVAS_GROUP (item),
		gnome_canvas_line_get_type (),
		"points", points,
		"fill_color", "blue",
		"width_pixels", 1,
		NULL));

	gnome_canvas_points_free (points);

	g_signal_connect_object(G_OBJECT(wire),	"rotated",
		G_CALLBACK(wire_rotated_callback), G_OBJECT(item), 0);
	g_signal_connect_object(G_OBJECT(wire), "flipped",
		G_CALLBACK(wire_flipped_callback), G_OBJECT(item), 0);
	g_signal_connect_object(G_OBJECT(wire), "moved",
		G_CALLBACK(wire_moved_callback),  G_OBJECT(item), 0);

	g_signal_connect (G_OBJECT (wire), "changed", G_CALLBACK (wire_changed_callback), item);
	g_signal_connect (G_OBJECT (wire), "delete", G_CALLBACK (wire_delete_callback), item);
	wire_update_bbox (wire);

	return item;
}
Ejemplo n.º 19
0
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;
}