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); } }
static void part_item_set_property (GObject *object, guint propety_id, const GValue *value, GParamSpec *pspec) { g_return_if_fail (object != NULL); g_return_if_fail (IS_PART_ITEM(object)); switch (propety_id) { default: g_warning ("PartItem: Invalid argument.\n"); } }
/** * 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)); } }
static void part_item_get_property (GObject *object, guint propety_id, GValue *value, GParamSpec *pspec) { g_return_if_fail (object != NULL); g_return_if_fail (IS_PART_ITEM (object)); switch (propety_id) { default: pspec->value_type = G_TYPE_INVALID; break; } }
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); } }
static void part_item_set_label_items (PartItem *item, GSList *item_list) { PartItemPriv *priv; g_return_if_fail (item != NULL); g_return_if_fail (IS_PART_ITEM (item)); priv = item->priv; if (priv->label_items) g_slist_free (priv->label_items); priv->label_items = item_list; }
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); } } }
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); }
static void create_canvas_labels (PartItem *item, Part *part) { GooCanvasItem *canvas_item; GSList *list, *item_list; GooCanvasGroup *group; 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)); group = GOO_CANVAS_GROUP (item->priv->label_group); item_list = NULL; for (list = part_get_labels (part); list; list = list->next) { PartLabel *label = list->data; char *text; text = part_property_expand_macros (part, label->text); canvas_item = goo_canvas_text_new (GOO_CANVAS_ITEM (group), text, (double) label->pos.x, (double) label->pos.y, 0, GOO_CANVAS_ANCHOR_SOUTH_WEST, "fill_color", LABEL_COLOR, "font", "Sans 8", NULL); item_list = g_slist_prepend (item_list, canvas_item); g_free (text); } g_slist_free_full (list, g_object_unref); item_list = g_slist_reverse (item_list); part_item_set_label_items (item, item_list); }
/** * 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; }
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)); }
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; }