Beispiel #1
0
PartItem *
part_item_canvas_new (Sheet *sheet, Part *part)
{
	PartItem *part_item;
	PartItemPriv *priv;
	GooCanvasItem *item;
	ItemData *item_data;

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

	item = g_object_new (TYPE_PART_ITEM, NULL);
	
	g_object_set (item, 
	              "parent", sheet->object_group, 
	              NULL);
	
	part_item = PART_ITEM (item);
	g_object_set (part_item, 
                  "data", part, 
                  NULL);
	priv = part_item->priv;
	
	priv->label_group = GOO_CANVAS_ITEM (goo_canvas_group_new (
	        GOO_CANVAS_ITEM (part_item),
	        "width", -1.0,
	        "height", -1.0,
	        NULL));
	g_object_unref (item);
	
	priv->node_group = GOO_CANVAS_ITEM (goo_canvas_group_new (
	        GOO_CANVAS_ITEM (part_item), 
	        NULL));

	g_object_set (GOO_CANVAS_ITEM (priv->node_group),
	              "visibility", GOO_CANVAS_ITEM_INVISIBLE, 
	              NULL);

	item_data = ITEM_DATA (part);
	item_data->rotated_handler_id = g_signal_connect_object (G_OBJECT (part), 
	                                "rotated",
	                                G_CALLBACK (part_rotated_callback),
	                                G_OBJECT (part_item), 0);
	item_data->flipped_handler_id = g_signal_connect_object (G_OBJECT (part), 
	                                "flipped",
	                                G_CALLBACK (part_flipped_callback),
	                                G_OBJECT (part_item), 0);
	item_data->moved_handler_id = g_signal_connect_object (G_OBJECT (part),
	                                "moved",
	                                G_CALLBACK (part_moved_callback),
	                                G_OBJECT (part_item), 0);
	item_data->changed_handler_id = g_signal_connect_object (G_OBJECT (part),
	                                "changed",
	                                G_CALLBACK (part_changed_callback),
	                                G_OBJECT (part_item), 0);

	return part_item;
}
Beispiel #2
0
/**
 * update the node lables of all parts in the current sheet
 */
void sheet_update_parts (Sheet *sheet)
{
	GList *list;

	g_return_if_fail (sheet != NULL);
	g_return_if_fail (IS_SHEET (sheet));

	for (list = sheet->priv->items; list; list = list->next) {
		if (IS_PART_ITEM (list->data))
			part_item_update_node_label (PART_ITEM (list->data));
	}
}
Beispiel #3
0
static void
part_item_finalize (GObject *object)
{
	PartItemPriv *priv;

	priv = PART_ITEM (object)->priv;

	g_slist_free (priv->label_nodes);
	g_slist_free (priv->label_items);
	g_free (priv);
	priv = NULL;
	G_OBJECT_CLASS (parent_class)->finalize (object);
}
Beispiel #4
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 #5
0
static gboolean
is_in_area (SheetItem *object, Coords *p1, Coords *p2)
{
	PartItem *item;
	Coords bbox_start, bbox_end;

	item = PART_ITEM (object);

	get_cached_bounds (item, &bbox_start, &bbox_end);

	if ((p1->x < bbox_start.x) &&
	    (p2->x > bbox_end.x)   &&
	    (p1->y < bbox_start.y) &&
	    (p2->y > bbox_end.y))  {
		return TRUE;
	}
	return FALSE;
}
Beispiel #6
0
static void
show_labels (SheetItem *sheet_item, gboolean show)
{
	PartItem *item;
	PartItemPriv *priv;

	g_return_if_fail (sheet_item != NULL);
	g_return_if_fail (IS_PART_ITEM (sheet_item));

	item = PART_ITEM (sheet_item);
	priv = item->priv;

	if (show)
		g_object_set (priv->label_group, 
				      "visibility", GOO_CANVAS_ITEM_VISIBLE, 
		              NULL);
	else
		g_object_set (priv->label_group, 
				      "visibility", GOO_CANVAS_ITEM_INVISIBLE, 
		              NULL);
}
Beispiel #7
0
/**
 * whenever the model changes, this one gets called to update the view representation
 * @attention this recalculates the matrix every time, this makes sure no errors stack up
 * @attention further reading on matrix manipulations
 * @attention http://www.cairographics.org/matrix_transform/
 * @param data the model item, a bare C struct derived from ItemData
 * @param sheet_item the view item, derived from goo_canvas_group/item
 */
static void
part_changed_callback (ItemData *data, SheetItem *sheet_item)
{
	//TODO add static vars in order to skip the redraw if nothing changed
	//TODO may happen once in a while and the check is really cheap
	GSList *iter;
	GooCanvasAnchorType anchor;
	GooCanvasGroup *group;
	GooCanvasItem *canvas_item;
	PartItem *item;
	PartItemPriv *priv;
	Part *part;
	int index = 0;
	Coords pos;
	double scale_h, scale_v;


	// states
	int rotation;
	IDFlip flip;

	g_return_if_fail (sheet_item != NULL);
	g_return_if_fail (IS_PART_ITEM (sheet_item));

	item = PART_ITEM (sheet_item);
	group = GOO_CANVAS_GROUP (item);
	part = PART (data);

	priv = item->priv;

	// init the states

	flip = part_get_flip (part);
	rotation = part_get_rotation (part);

	DEGSANITY (rotation);

	scale_h = (flip & ID_FLIP_HORIZ) ? -1. : 1.;
	scale_v = (flip & ID_FLIP_VERT) ? -1. : 1.;


	item_data_get_pos (data, &pos);
	// Move the canvas item and invalidate the bbox cache.
	goo_canvas_item_set_simple_transform (GOO_CANVAS_ITEM (sheet_item),
	                                      pos.x,
	                                      pos.y,
	                                      1.0,
	                                      0.0);

	cairo_matrix_t morph, inv;
	cairo_status_t done;

	cairo_matrix_init_rotate (&morph, DEG2RAD (rotation));
	cairo_matrix_scale (&morph, scale_h, scale_v);

	inv = morph;
	done = cairo_matrix_invert (&inv);
	if (done != CAIRO_STATUS_SUCCESS) {
		g_warning ("Failed to invert matrix. This should never happen. Never!");
		return;
	}

	// rotate all items in the canvas group
	for (index = 0; index < group->items->len; index++) {
		canvas_item = GOO_CANVAS_ITEM (group->items->pdata[index]);
		goo_canvas_item_set_transform (GOO_CANVAS_ITEM (canvas_item), &morph);
	}

	// revert the rotation of all labels and change their anchor to not overlap too badly
	// this assures that the text is always horizontal and properly aligned
	anchor = angle_to_anchor (rotation);

	for (iter = priv->label_items; iter; iter = iter->next) {
		g_object_set (iter->data,
		              "anchor", anchor,
		              NULL);

		goo_canvas_item_set_transform (iter->data, &inv);

	}
	// same for label nodes
	for (iter = priv->label_nodes; iter; iter = iter->next) {
		g_object_set (iter->data,
		              "anchor", anchor, 
		              NULL);

		goo_canvas_item_set_transform (iter->data, &inv);
	}


	// Invalidate the bounding box cache.
	priv->cache_valid = FALSE;
}
Beispiel #8
0
static void
edit_properties (SheetItem *object)
{
	GSList *properties;
	PartItem *item;
	Part *part;
	char *internal, *msg;
	GtkBuilder *gui;
	GError *error = NULL;
	GtkGrid *prop_grid;
	GtkNotebook *notebook;
	gint response, y = 0;
	gboolean has_model;
	gchar *model_name = NULL;

	g_return_if_fail (object != NULL);
	g_return_if_fail (IS_PART_ITEM (object));

	item = PART_ITEM (object);
	part = PART (sheet_item_get_data (SHEET_ITEM (item)));

	internal = part_get_property (part, "internal");
	if (internal) {
		if (g_ascii_strcasecmp (internal, "ground") == 0) {
			g_free (internal);
			return;
		}
		if (g_ascii_strcasecmp (internal, "point") == 0) {
			edit_properties_point (item);
			return;
		}
	}

	g_free (internal);

	if ((gui = gtk_builder_new ()) == NULL) {
		oregano_error (_("Could not create part properties dialog."));
		return;
	} 
	else
		 gtk_builder_set_translation_domain (gui, NULL);


	if (gtk_builder_add_from_file (gui, OREGANO_UIDIR "/part-properties-dialog.ui", 
	    &error) <= 0) {
		msg = error->message;
		oregano_error_with_title (_("Could not create part properties dialog."), 
		                          msg);
		g_error_free (error);
		return;
	}

	prop_dialog = g_new0 (PartPropDialog, 1);

	prop_dialog->part_item = item;

	prop_dialog->dialog = GTK_DIALOG (gtk_builder_get_object (gui, 
	                      "part-properties-dialog"));

	prop_grid = GTK_GRID (gtk_builder_get_object (gui, "prop_grid"));
	notebook  = GTK_NOTEBOOK (gtk_builder_get_object (gui, "notebook"));

	g_signal_connect (prop_dialog->dialog, "destroy",
		G_CALLBACK (prop_dialog_destroy),  prop_dialog);

	prop_dialog->widgets = NULL;
	has_model = FALSE;

	for (properties = part_get_properties (part); properties;
		properties = properties->next) {
		Property *prop;
		
		prop = properties->data;

		if (prop->name) {
			GtkWidget *entry;
			GtkWidget *label;
			gchar *temp=NULL;
			
			if (!g_ascii_strcasecmp (prop->name, "internal"))
				continue;

			if (!g_ascii_strcasecmp (prop->name,  "model")) {
				has_model = TRUE;
				model_name = g_strdup (prop->value);
			}
			
			// Find the Refdes and replace by their real value
			temp = prop->name;
			if (!g_ascii_strcasecmp (temp,  "Refdes")) temp = _("Designation");
			if (!g_ascii_strcasecmp (temp,  "Template")) temp  = _("Template");
			if (!g_ascii_strcasecmp (temp,  "Res")) temp  = _("Resistor");
			if (!g_ascii_strcasecmp (temp,  "Cap")) temp  = _("Capacitor");
			if (!g_ascii_strcasecmp (temp,  "Ind")) temp  = _("Inductor");
			label = gtk_label_new (temp);

			entry = gtk_entry_new ();
			gtk_entry_set_text (GTK_ENTRY (entry),  prop->value);
			g_object_set_data (G_OBJECT (entry),  "user",  g_strdup (prop->name));

			gtk_grid_attach (prop_grid, label, 0,y, 1,1);
			
			gtk_grid_attach (prop_grid, entry, 1,y, 1,1);
			
			y++;
			gtk_widget_show (label);
			gtk_widget_show (entry);

			prop_dialog->widgets = g_list_prepend (prop_dialog->widgets, entry);
		}
	}

	if (!has_model) {
		gtk_notebook_remove_page (notebook, 1); 
	} 
	else {
		GtkTextBuffer *txtbuffer;
		GtkTextView *txtmodel;
		gchar *filename, *str;
		GError *read_error = NULL;

		txtmodel = GTK_TEXT_VIEW (gtk_builder_get_object (gui, "txtmodel"));
		txtbuffer = gtk_text_buffer_new (NULL);

		filename = g_strdup_printf ("%s/%s.model", OREGANO_MODELDIR, model_name);
		if (g_file_get_contents (filename, &str, NULL, &read_error)) {
			gtk_text_buffer_set_text (txtbuffer, str, -1);
			g_free (str);
		} 
		else {
			gtk_text_buffer_set_text (txtbuffer, read_error->message, -1);
			g_error_free (read_error);
		}

		g_free (filename);
		g_free (model_name);

		gtk_text_view_set_buffer (txtmodel, txtbuffer);
	}

	gtk_dialog_set_default_response (prop_dialog->dialog, 1);

	response = gtk_dialog_run (prop_dialog->dialog);

	prop_dialog_response (GTK_WIDGET (prop_dialog->dialog), response, prop_dialog);

	g_slist_free_full (properties, g_object_unref);
	gtk_widget_destroy (GTK_WIDGET (prop_dialog->dialog));
}