static gboolean restore_enabled(GtkTreeModel *model, G_GNUC_UNUSED GtkTreePath *path, GtkTreeIter *iter, gpointer user_data) { const gchar **names = (const gchar**)user_data; GwyGrainValue *gvalue; if (!names) { gtk_tree_store_set(GTK_TREE_STORE(model), iter, GWY_GRAIN_VALUE_STORE_COLUMN_ENABLED, FALSE, -1); return FALSE; } gtk_tree_model_get(model, iter, GWY_GRAIN_VALUE_STORE_COLUMN_ITEM, &gvalue, -1); if (gvalue) { const gchar *name = gwy_resource_get_name(GWY_RESOURCE(gvalue)); while (*names && !gwy_strequal(name, *names)) names++; gtk_tree_store_set(GTK_TREE_STORE(model), iter, GWY_GRAIN_VALUE_STORE_COLUMN_ENABLED, !!*names, -1); g_object_unref(gvalue); } return FALSE; }
static gboolean gather_enabled(GtkTreeModel *model, G_GNUC_UNUSED GtkTreePath *path, GtkTreeIter *iter, gpointer user_data) { GPtrArray *names = (GPtrArray*)user_data; GwyGrainValue *gvalue; gboolean enabled; gtk_tree_model_get(model, iter, GWY_GRAIN_VALUE_STORE_COLUMN_ITEM, &gvalue, GWY_GRAIN_VALUE_STORE_COLUMN_ENABLED, &enabled, -1); if (gvalue) { if (enabled) { const gchar *name = gwy_resource_get_name(GWY_RESOURCE(gvalue)); g_ptr_array_add(names, (gpointer)name); } g_object_unref(gvalue); } return FALSE; }
static void axis_quantity_changed(GrainCrossControls *controls) { GtkTreeSelection *selection; GwyGraphModel *gmodel; GwyGrainValue *gvalue; GtkTreeModel *model; GtkTreeIter iter; gboolean ok; ok = TRUE; selection = gtk_tree_view_get_selection(controls->abscissa); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, GWY_GRAIN_VALUE_STORE_COLUMN_ITEM, &gvalue, -1); controls->args->abscissa = gwy_resource_get_name(GWY_RESOURCE(gvalue)); } else ok = FALSE; selection = gtk_tree_view_get_selection(controls->ordinate); if (gtk_tree_selection_get_selected(selection, &model, &iter)) { gtk_tree_model_get(model, &iter, GWY_GRAIN_VALUE_STORE_COLUMN_ITEM, &gvalue, -1); controls->args->ordinate = gwy_resource_get_name(GWY_RESOURCE(gvalue)); } else ok = FALSE; gmodel = create_corr_graph(controls->args, controls->dfield); gwy_graph_set_model(GWY_GRAPH(controls->graph), gmodel); g_object_unref(gmodel); gtk_dialog_set_response_sensitive(controls->dialog, GTK_RESPONSE_OK, ok); update_target_graphs(controls); }
static gpointer gwy_gl_material_copy(gpointer item) { GwyGLMaterial *gl_material, *copy; g_return_val_if_fail(GWY_IS_GL_MATERIAL(item), NULL); gl_material = GWY_GL_MATERIAL(item); copy = gwy_gl_material_new(gwy_resource_get_name(GWY_RESOURCE(item)), &gl_material->ambient, &gl_material->diffuse, &gl_material->specular, &gl_material->emission, gl_material->shininess, FALSE); return copy; }
static GSList* construct_bases_radio(GwyGrainQuantity current, GCallback callback, gpointer cbdata) { enum { n = G_N_ELEMENTS(level_grains_bases) }; GwyEnum entries[n]; guint i; for (i = 0; i < n; i++) { GwyGrainQuantity q = level_grains_bases[i]; GwyGrainValue *value = gwy_grain_values_get_builtin_grain_value(q); entries[i].value = q; entries[i].name = gwy_resource_get_name(GWY_RESOURCE(value)); } return gwy_radio_buttons_create(entries, n, callback, cbdata, current); }
static void threshold_changed(GFilterControls *controls, GtkAdjustment *adj) { GFilterArgs *args = controls->args; GwyInventory *inventory; GwyGrainValue *gvalue; GtkEntry *entry; const gchar *name; gboolean is_upper; guint id, i, k; gdouble *v; gdouble value; gchar *s; if (controls->in_init) return; id = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(adj), "id")); is_upper = id & IS_UPPER; id &= ~IS_UPPER; k = gwy_adjustment_get_int(adj); inventory = gwy_grain_values(); gvalue = gwy_inventory_get_item(inventory, args->ranges[id].quantity); g_return_if_fail(gvalue); name = gwy_resource_get_name(GWY_RESOURCE(gvalue)); i = gwy_inventory_get_item_position(inventory, args->ranges[id].quantity); v = g_ptr_array_index(args->sortedvaluedata, i); value = v[k]; s = g_strdup_printf("%.*f", controls->vf[id]->precision, value/controls->vf[id]->magnitude); if (is_upper) entry = GTK_ENTRY(controls->upper_entry[id]); else entry = GTK_ENTRY(controls->lower_entry[id]); gtk_entry_set_text(entry, s); g_free(s); set_threshold_value(args, id, name, value, is_upper); gfilter_invalidate(controls); }
static void set_adjustment_to_grain_value(GFilterControls *controls, GwyGrainValue *gvalue, GtkAdjustment *adj, gdouble value) { GFilterArgs *args = controls->args; GwyInventory *inventory; const gchar *name; guint k, i; const gdouble *v; inventory = gwy_grain_values(); name = gwy_resource_get_name(GWY_RESOURCE(gvalue)); i = gwy_inventory_get_item_position(inventory, name); v = g_ptr_array_index(args->sortedvaluedata, i); k = bisect_lower(v, args->nuniqvalues[i], value); /* XXX: This is approximate, but maybe sufficient. */ gtk_adjustment_set_value(adj, k); }
static void gfilter_sanitize_args(GFilterArgs *args) { GwyInventory *inventory; guint i; inventory = gwy_grain_values(); args->logical = MIN(args->logical, GRAIN_LOGICAL_NTYPES); for (i = 0; i < NQUANTITIES; i++) { RangeRecord *rr = args->ranges + i; GwyGrainValue *gvalue; if ((gvalue = gwy_inventory_get_item(inventory, rr->quantity))) rr->quantity = gwy_resource_get_name(GWY_RESOURCE(gvalue)); else rr->quantity = gfilter_defaults.ranges[i].quantity; /* The actual range is restored later from range_history. */ } args->update = !!args->update; }
static void threshold_activated(GFilterControls *controls, GtkEntry *entry) { GFilterArgs *args = controls->args; GwyInventory *inventory; GwyGrainValue *gvalue; GtkAdjustment *adj; guint id; gboolean is_upper; const gchar *s, *name; gdouble value; if (controls->in_init) return; id = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(entry), "id")); is_upper = id & IS_UPPER; id &= ~IS_UPPER; inventory = gwy_grain_values(); gvalue = gwy_inventory_get_item(inventory, args->ranges[id].quantity); g_return_if_fail(gvalue); name = gwy_resource_get_name(GWY_RESOURCE(gvalue)); s = gtk_entry_get_text(entry); value = g_strtod(s, NULL) * controls->vf[id]->magnitude; if (is_upper) adj = GTK_ADJUSTMENT(controls->upper[id]); else adj = GTK_ADJUSTMENT(controls->lower[id]); controls->in_init = TRUE; set_adjustment_to_grain_value(controls, gvalue, adj, value); controls->in_init = FALSE; set_threshold_value(args, id, name, value, is_upper); gfilter_invalidate(controls); }
static void render_name(G_GNUC_UNUSED GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data) { GtkTreeView *treeview = (GtkTreeView*)user_data; PangoEllipsizeMode ellipsize; PangoWeight weight; GwyGrainValue *gvalue; GwyGrainValueGroup group; const gchar *name; GdkColor color; gtk_tree_model_get(model, iter, GWY_GRAIN_VALUE_STORE_COLUMN_ITEM, &gvalue, GWY_GRAIN_VALUE_STORE_COLUMN_GROUP, &group, -1); ellipsize = gvalue ? PANGO_ELLIPSIZE_END : PANGO_ELLIPSIZE_NONE; weight = gvalue ? PANGO_WEIGHT_NORMAL : PANGO_WEIGHT_BOLD; text_color(treeview, gvalue, &color); if (gvalue) { name = gwy_resource_get_name(GWY_RESOURCE(gvalue)); if (group != GWY_GRAIN_VALUE_GROUP_USER) name = gettext(name); g_object_unref(gvalue); } else name = gettext(gwy_grain_value_group_name(group)); g_object_set(renderer, "ellipsize", ellipsize, "weight", weight, "markup", name, "foreground-gdk", &color, NULL); }
static void set_up_quantity(GFilterControls *controls, GwyGrainValue *gvalue, guint id) { GFilterArgs *args = controls->args; GwyInventory *inventory; GwyDataField *dfield; RangeRecord *rr; const gchar *name; const gdouble *v; gchar *s, *t; gdouble vmin, vmax, lower = -G_MAXDOUBLE, upper = G_MAXDOUBLE; GwySIUnit *siunit, *siunitxy, *siunitz; gboolean was_in_init = controls->in_init; guint i, nuniq; controls->in_init = TRUE; name = gwy_resource_get_name(GWY_RESOURCE(gvalue)); args->ranges[id].quantity = name; /* TRANSLATORS: %c is replaced with quantity label A, B or C. */ s = g_strdup_printf(_("Condition %c: %s"), 'A' + id, name); t = g_strconcat("<b>", s, "</b>", NULL); gtk_label_set_markup(GTK_LABEL(controls->header[id]), t); g_free(t); g_free(s); rr = g_hash_table_lookup(args->ranges_history, (gpointer)name); if (rr) { lower = rr->lower; upper = rr->upper; } inventory = gwy_grain_values(); i = gwy_inventory_get_item_position(inventory, name); nuniq = args->nuniqvalues[i]; v = g_ptr_array_index(args->sortedvaluedata, i); vmin = v[0]; vmax = v[nuniq-1]; lower = CLAMP(lower, vmin, vmax); upper = CLAMP(upper, vmin, vmax); gtk_adjustment_set_upper(GTK_ADJUSTMENT(controls->lower[id]), nuniq-1); gtk_adjustment_set_upper(GTK_ADJUSTMENT(controls->upper[id]), nuniq-1); dfield = gwy_container_get_object_by_name(controls->mydata, "/0/data"); siunitxy = gwy_data_field_get_si_unit_xy(dfield); siunitz = gwy_data_field_get_si_unit_z(dfield); siunit = gwy_si_unit_power_multiply(siunitxy, gwy_grain_value_get_power_xy(gvalue), siunitz, gwy_grain_value_get_power_z(gvalue), NULL); gwy_si_unit_get_format_with_digits(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, MAX(fabs(vmin), fabs(vmax)), 4, controls->vf[id]); g_object_unref(siunit); /* Special-case the pixel area format. */ if (gwy_strequal(name, "Pixel area")) { controls->vf[id]->magnitude = 1.0; controls->vf[id]->precision = 0; gwy_si_unit_value_format_set_units(controls->vf[id], ""); } gtk_label_set_markup(GTK_LABEL(controls->lower_units[id]), controls->vf[id]->units); gtk_label_set_markup(GTK_LABEL(controls->upper_units[id]), controls->vf[id]->units); args->ranges[id].quantity = name; args->ranges[id].lower = lower; args->ranges[id].upper = upper; set_adjustment_to_grain_value(controls, gvalue, GTK_ADJUSTMENT(controls->lower[id]), lower); set_adjustment_to_grain_value(controls, gvalue, GTK_ADJUSTMENT(controls->upper[id]), upper); s = g_strdup_printf("%.*f", controls->vf[id]->precision, lower/controls->vf[id]->magnitude); gtk_entry_set_text(GTK_ENTRY(controls->lower_entry[id]), s); g_free(s); s = g_strdup_printf("%.*f", controls->vf[id]->precision, upper/controls->vf[id]->magnitude); gtk_entry_set_text(GTK_ENTRY(controls->upper_entry[id]), s); g_free(s); /* XXX: We might have modified the range by CLAMP(). Store the new one * right here? Pro: consistency. Con: the user did not do anything, * he just may be browsing. */ controls->in_init = was_in_init; gfilter_invalidate(controls); }
static void gfilter_load_args(GwyContainer *container, GFilterArgs *args) { GwyInventory *inventory; gchar *filename, *buffer; gsize size; guint i; inventory = gwy_grain_values(); *args = gfilter_defaults; gwy_container_gis_boolean_by_name(container, update_key, &args->update); gwy_container_gis_int32_by_name(container, expanded_key, &args->expanded); gwy_container_gis_enum_by_name(container, logical_key, &args->logical); for (i = 0; i < NQUANTITIES; i++) { RangeRecord *rr = args->ranges + i; gchar buf[sizeof(quantity_key) + 10]; g_snprintf(buf, sizeof(buf), "%s%u", quantity_key, i+1); gwy_container_gis_string_by_name(container, buf, (const guchar**)&rr->quantity); } args->ranges_history = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, range_record_free); filename = g_build_filename(gwy_get_user_dir(), "grain_filter", "ranges", NULL); if (g_file_get_contents(filename, &buffer, &size, NULL)) { gchar *p = buffer, *line; for (line = gwy_str_next_line(&p); line; line = gwy_str_next_line(&p)) { g_strstrip(line); if (*line) { GwyGrainValue *gvalue; RangeRecord *rr; gchar *s = line, *end; gdouble lower, upper; lower = g_ascii_strtod(s, &end); s = end; upper = g_ascii_strtod(s, &end); if (end == s) { g_warning("Invalid grain_filter range record: %s.", line); continue; } s = end; g_strstrip(s); if (!(gvalue = gwy_inventory_get_item(inventory, s))) { g_warning("Invalid grain_filter range record: %s.", line); continue; } rr = g_slice_new(RangeRecord); rr->lower = lower; rr->upper = upper; rr->quantity = gwy_resource_get_name(GWY_RESOURCE(gvalue)); g_hash_table_insert(args->ranges_history, (gpointer)rr->quantity, rr); } } g_free(buffer); } g_free(filename); gfilter_sanitize_args(args); }
static GwyGraphModel* create_corr_graph(GrainCrossArgs *args, GwyDataField *dfield) { GwyGraphCurveModel *cmodel; GwyGraphModel *gmodel; GwyGrainValue *gvalues[2]; gdouble *xdata, *ydata, *bothdata, *rdata[2]; GwySIUnit *siunitxy, *siunitz, *siunitx, *siunity; const gchar *title; gint i; gvalues[0] = gwy_grain_values_get_grain_value(args->abscissa); gvalues[1] = gwy_grain_values_get_grain_value(args->ordinate); bothdata = g_new(gdouble, 4*args->ngrains + 2); rdata[0] = xdata = bothdata + 2*args->ngrains; rdata[1] = ydata = bothdata + 3*args->ngrains + 1; gwy_grain_values_calculate(2, gvalues, rdata, dfield, args->ngrains, args->grains); for (i = 0; i < args->ngrains; i++) { bothdata[2*i + 0] = xdata[i+1]; bothdata[2*i + 1] = ydata[i+1]; } qsort(bothdata, args->ngrains, 2*sizeof(gdouble), compare_doubles); for (i = 0; i < args->ngrains; i++) { xdata[i] = bothdata[2*i + 0]; ydata[i] = bothdata[2*i + 1]; } gmodel = gwy_graph_model_new(); cmodel = gwy_graph_curve_model_new(); gwy_graph_model_add_curve(gmodel, cmodel); g_object_unref(cmodel); siunitxy = gwy_data_field_get_si_unit_xy(dfield); siunitz = gwy_data_field_get_si_unit_z(dfield); siunitx = gwy_si_unit_power_multiply (siunitxy, gwy_grain_value_get_power_xy(gvalues[0]), siunitz, gwy_grain_value_get_power_z(gvalues[0]), NULL); siunity = gwy_si_unit_power_multiply (siunitxy, gwy_grain_value_get_power_xy(gvalues[1]), siunitz, gwy_grain_value_get_power_z(gvalues[1]), NULL); /* FIXME */ title = gettext(gwy_resource_get_name(GWY_RESOURCE(gvalues[1]))); g_object_set (gmodel, "title", title, "axis-label-left", gwy_grain_value_get_symbol_markup(gvalues[1]), "axis-label-bottom", gwy_grain_value_get_symbol_markup(gvalues[0]), "si-unit-x", siunitx, "si-unit-y", siunity, NULL); g_object_unref(siunitx); g_object_unref(siunity); g_object_set(cmodel, "description", title, "mode", GWY_GRAPH_CURVE_POINTS, NULL); gwy_graph_curve_model_set_data(cmodel, xdata, ydata, args->ngrains); g_free(bothdata); return gmodel; }