示例#1
0
gboolean node_store_is_pin_at_pos (NodeStore *store, Coords pos)
{
	int num_pins;
	Coords part_pos;
	GList *p;
	Part *part;
	Pin *pins;
	int i;
	gdouble x, y;

	for (p = store->parts; p; p = p->next) {
		part = PART (p->data);

		num_pins = part_get_num_pins (part);

		item_data_get_pos (ITEM_DATA (part), &part_pos);

		pins = part_get_pins (part);
		for (i = 0; i < num_pins; i++) {
			x = part_pos.x + pins[i].offset.x;
			y = part_pos.y + pins[i].offset.y;

			if (fabs (x - pos.x) < NODE_EPSILON && fabs (y - pos.y) < NODE_EPSILON)
				return TRUE;
		}
	}
	return FALSE;
}
示例#2
0
int
node_store_is_pin_at_pos (NodeStore *store, SheetPos pos)
{
	int num_pins;
	SheetPos part_pos;
	GList *p;
	Part *part;
	Pin *pins;
	int i;
	gdouble x, y;

	for (p = store->parts; p; p = p->next) {
		part = PART (p->data);

		num_pins = part_get_num_pins (part);

		item_data_get_pos (ITEM_DATA (part), &part_pos);

		pins = part_get_pins (part);
		for (i = 0; i < num_pins; i++) {
			x = part_pos.x + pins[i].offset.x;
			y = part_pos.y + pins[i].offset.y;

			if ((x == pos.x) && (y == pos.y)) {
				return 1;
			}
		}
	}
	g_list_free_full (p, g_object_unref);
	return 0;
}
示例#3
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;
}
示例#4
0
int
node_store_add_part (NodeStore *self, Part *part)
{
	GSList *wire_list, *list;
	Node *node;
	SheetPos lookup_key;
	SheetPos part_pos;
	gdouble x, y;
	int i, num_pins;

	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (IS_NODE_STORE (self), FALSE);
	g_return_val_if_fail (part != NULL, FALSE);
	g_return_val_if_fail (IS_PART (part), FALSE);

	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;

		//Use the position of the pin as hash key.
		lookup_key.x = x;
		lookup_key.y = y;

		// Retrieve a node for this position.
		node = node_store_get_or_create_node (self, lookup_key);

		// Add all the wires that intersect this pin to the node store.
		wire_list = wires_at_pos (self, lookup_key);

		for (list = wire_list; list; list = list->next) {
			Wire *wire = list->data;

		    NG_DEBUG ("Add pin to wire.\n");

			node_add_wire (node, wire);
			wire_add_node (wire, node);
		}

		g_slist_free (wire_list);

		node_add_pin (node, &pins[i]);
	}

	g_object_set (G_OBJECT (part), "store", self, NULL);
	self->parts = g_list_prepend (self->parts, part);
	self->items = g_list_prepend (self->items, part);

	return TRUE;
}
示例#5
0
int
node_store_remove_part (NodeStore *self, Part *part)
{
	Node *node;
	SheetPos lookup_key;
	SheetPos pos;
	gdouble x, y;
	int i, num_pins;
	Pin *pins;

	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (IS_NODE_STORE (self), FALSE);
	g_return_val_if_fail (part != NULL, FALSE);
	g_return_val_if_fail (IS_PART (part), FALSE);

	self->parts = g_list_remove (self->parts, part);
	self->items = g_list_remove (self->items, part);

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

	pins = part_get_pins (part);
	for (i = 0; i < num_pins; i++) {
		x = pos.x + pins[i].offset.x;
		y = pos.y + pins[i].offset.y;

		// Use the position of the pin as lookup key.
		lookup_key.x = x;
		lookup_key.y = y;

		node = g_hash_table_lookup (self->nodes, &lookup_key);
		if (node) {
			if (!node_remove_pin (node, &pins[i])) {
				g_warning ("Couldn't remove pin.");
				return FALSE;
			}

			// If the node is empty after removing the pin,
			// remove the node as well.
			if (node_is_empty (node)) {
				g_hash_table_remove (self->nodes, &lookup_key);
				g_object_unref (G_OBJECT (node));
			}
		} 
		else {
			return FALSE;
		}
	}

	return TRUE;
}
示例#6
0
/**
 * register a part to the nodestore
 */
gboolean node_store_add_part (NodeStore *self, Part *part)
{
	NG_DEBUG ("-0-");
	g_return_val_if_fail (self, FALSE);
	g_return_val_if_fail (IS_NODE_STORE (self), FALSE);
	g_return_val_if_fail (part, FALSE);
	g_return_val_if_fail (IS_PART (part), FALSE);

	GSList *iter, *copy;
	Node *node;
	Coords pin_pos;
	Coords part_pos;
	int i, num_pins;
	Pin *pins;

	num_pins = part_get_num_pins (part);
	pins = part_get_pins (part);

	item_data_get_pos (ITEM_DATA (part), &part_pos);

	for (i = 0; i < num_pins; i++) {
		// Use the position of the pin as hash key.
		pin_pos.x = part_pos.x + pins[i].offset.x;
		pin_pos.y = part_pos.y + pins[i].offset.y;

		// Retrieve a node for this position.
		node = node_store_get_or_create_node (self, pin_pos);

		// Add all the wires that intersect this pin to the node store.
		copy = get_wires_at_pos (self, pin_pos);
		for (iter = copy; iter; iter = iter->next) {
			Wire *wire = copy->data;

			node_add_wire (node, wire);
			wire_add_node (wire, node);
		}

		g_slist_free (copy);

		node_add_pin (node, &pins[i]);
	}

	g_object_set (G_OBJECT (part), "store", self, NULL);
	self->parts = g_list_prepend (self->parts, part);
	self->items = g_list_prepend (self->items, part);

	return TRUE;
}
示例#7
0
/**
 * remove/unregister a part from the nodestore
 * this does _not_ free the part!
 */
gboolean node_store_remove_part (NodeStore *self, Part *part)
{
	Node *node;
	Coords pin_pos;
	Coords part_pos;
	int i, num_pins;
	Pin *pins;

	g_return_val_if_fail (self, FALSE);
	g_return_val_if_fail (IS_NODE_STORE (self), FALSE);
	g_return_val_if_fail (part, FALSE);
	g_return_val_if_fail (IS_PART (part), FALSE);

	self->parts = g_list_remove (self->parts, part);
	self->items = g_list_remove (self->items, part);

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

	pins = part_get_pins (part);
	for (i = 0; i < num_pins; i++) {
		pin_pos.x = part_pos.x + pins[i].offset.x;
		pin_pos.y = part_pos.y + pins[i].offset.y;

		node = g_hash_table_lookup (self->nodes, &pin_pos);
		if (node) {
			if (!node_remove_pin (node, &pins[i])) {
				g_warning ("Could not remove pin[%i] from node %p.", i, node);
				return FALSE;
			}

			// If the node is empty after removing the pin,
			// remove the node as well.
			if (node_is_empty (node)) {
				g_hash_table_remove (self->nodes, &pin_pos);
				g_object_unref (G_OBJECT (node));
			}
		} else {
			return FALSE;
		}
	}

	return TRUE;
}
示例#8
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);
		}
	}
}
示例#9
0
/**
 * add/register the wire to the nodestore
 *
 * @param store
 * @param wire
 * @returns TRUE if the wire was added or merged, else FALSE
 */
gboolean node_store_add_wire (NodeStore *store, Wire *wire)
{
	GList *list;
	Node *node;
	int i = 0;

	g_return_val_if_fail (store, FALSE);
	g_return_val_if_fail (IS_NODE_STORE (store), FALSE);
	g_return_val_if_fail (wire, FALSE);
	g_return_val_if_fail (IS_WIRE (wire), FALSE);

	// Check for intersection with other wires.
	for (list = store->wires; list; list = list->next) {
		g_assert (list->data != NULL);
		g_assert (IS_WIRE (list->data));

		Coords where = {-77.77, -77.77};
		Wire *other = list->data;
		if (do_wires_intersect (wire, other, &where)) {
			if (is_t_crossing (wire, other, &where) || is_t_crossing (other, wire, &where)) {

				node = node_store_get_or_create_node (store, where);

				node_add_wire (node, wire);
				node_add_wire (node, other);

				wire_add_node (wire, node);
				wire_add_node (other, node);

				NG_DEBUG ("Add wire %p to wire %p @ %lf,%lf.\n", wire, other, where.x, where.y);
			} else {
				// magic node removal if a x crossing is overlapped with another wire
				node = node_store_get_node (store, where);
				NG_DEBUG ("Nuke that node [ %p ] at coords inbetween", node);
				if (node) {
					Coords c[4];
					wire_get_start_and_end_pos (other, c + 0, c + 1);
					wire_get_start_and_end_pos (wire, c + 2, c + 3);
					if (!coords_equal (&where, c + 0) && !coords_equal (&where, c + 1) &&
					    !coords_equal (&where, c + 2) && !coords_equal (&where, c + 3)) {

						wire_remove_node (wire, node);
						wire_remove_node (other, node);
						node_remove_wire (node, wire);
						node_remove_wire (node, other);
					}
				}
			}
		}
	}

	// Check for overlapping with other wires.
	do {
		for (list = store->wires; list; list = list->next) {
			g_assert (list->data != NULL);
			g_assert (IS_WIRE (list->data));
			Wire *other = list->data;
			Coords so, eo;
			const gboolean overlap = do_wires_overlap (wire, other, &so, &eo);
			NG_DEBUG ("overlap [ %p] and [ %p ] -- %s", wire, other,
			          overlap == TRUE ? "YES" : "NO");
			if (overlap) {
				Node *sn = node_store_get_node (store, eo);
				Node *en = node_store_get_node (store, so);
#if 1
				wire = vulcanize_wire (store, wire, other, &so, &eo);
				node_store_remove_wire (store, g_object_ref (other)); // equiv
				                                                      // wire_unregister
				                                                      // XXX FIXME this
				                                                      // modifies the list
				                                                      // we iterate over!
				// delay this until idle, so all handlers like adding view
				// representation are completed so existing wire-items can be deleted
				// properly
				// this is not fancy nor nice but seems to work fairly nicly
				g_idle_add (delayed_wire_delete, other);
				break;
				NG_DEBUG ("overlapping of %p with %p ", wire, other);
#else
				if (!sn && !en) {
					wire = vulcanize_wire (store, wire, other, &so, &eo);
				} else if (!sn) {
					NG_DEBUG ("do_something(TM) : %p sn==NULL ", other);
				} else if (!en) {
					NG_DEBUG ("do_something(TM) : %p en==NULL ", other);
				} else {
					NG_DEBUG ("do_something(TM) : %p else ", other);
				}
#endif
			} else {
				NG_DEBUG ("not of %p with %p ", wire, other);
			}
		}
	} while (list);

	// Check for intersection with parts (pins).
	for (list = store->parts; list; list = list->next) {
		g_assert (list->data != NULL);
		g_assert (IS_PART (list->data));

		Coords part_pos;
		gint num_pins = -1;
		Part *part = list->data;

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

		// Go through all the parts and see which of their
		// pins that intersect the wire.
		for (i = 0; i < num_pins; i++) {
			Pin *pins;
			Coords lookup_pos;

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

			// If there is a wire at this pin's position,
			// add it to the return list.
			if (is_point_on_wire (wire, &lookup_pos)) {
				Node *node;
				node = node_store_get_node (store, lookup_pos);

				if (node != NULL) {
					// Add the wire to the node (pin) that it intersected.
					node_add_wire (node, wire);
					wire_add_node (wire, node);
					NG_DEBUG ("Add wire %p to pin (node) %p.\n", wire, node);
				} else {
					g_warning ("Bug: Found no node at pin at (%g %g).\n", lookup_pos.x,
					           lookup_pos.y);
				}
			}
		}
	}

	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;
}
示例#10
0
static void
create_canvas_label_nodes (PartItem *item, Part *part)
{
	GooCanvasItem *canvas_item;
	GSList *item_list;
	GooCanvasItem *group;
	Pin *pins;
	int num_pins, i;
	Coords p1, p2;
	GooCanvasAnchorType anchor;
	
	g_return_if_fail (item != NULL);
	g_return_if_fail (IS_PART_ITEM (item));
	g_return_if_fail (part != NULL);
	g_return_if_fail (IS_PART (part));

	num_pins = part_get_num_pins (part);
	pins = part_get_pins (part);
	group = item->priv->node_group;
	item_list = NULL;

	get_cached_bounds (item, &p1, &p2);

	switch (part_get_rotation (part)) {
		case 0:
			anchor = GOO_CANVAS_ANCHOR_SOUTH_WEST;
		break;
		case 90:
			anchor = GOO_CANVAS_ANCHOR_NORTH_WEST;
		break;
		case 180:
			anchor = GOO_CANVAS_ANCHOR_NORTH_EAST;
		break;
		case 270:
			anchor = GOO_CANVAS_ANCHOR_SOUTH_EAST;
		break;
		default:
			anchor = GOO_CANVAS_ANCHOR_SOUTH_WEST;
	}

	for (i = 0; i < num_pins; i++) {
		int x, y;
		char *text;
		x = pins[i].offset.x;
		y = pins[i].offset.y;

		text = g_strdup_printf ("%d", pins[i].node_nr);
		canvas_item = goo_canvas_text_new (GOO_CANVAS_ITEM (group),
		                text,
		                (double) x,
		                (double) y,
		                0,
		                anchor,
		                "fill_color", "black",
		                "font", "Sans 8",
		                NULL);
		// Shift slightly the label for a Voltmeter
		if (i == 0) goo_canvas_item_translate (canvas_item, -15.0, -10.0);

		item_list = g_slist_prepend (item_list, canvas_item);
		g_free (text);
	}
	item_list = g_slist_reverse (item_list);
	item->priv->label_nodes = item_list;
}