static void gwy_graph_data_update_headers(GwyGraphData *graph_data) { const GwyGraphDataCurve *curve; const gchar *xlabel, *ylabel; GtkTreeView *treeview; GtkTreeViewColumn *column; GtkWidget *table, *label; GwySIUnit *siunit; gchar *sx, *sy; GString *str; guint i; treeview = GTK_TREE_VIEW(graph_data); xlabel = gwy_graph_model_get_axis_label(graph_data->graph_model, GTK_POS_BOTTOM); ylabel = gwy_graph_model_get_axis_label(graph_data->graph_model, GTK_POS_LEFT); g_object_get(graph_data->graph_model, "si-unit-x", &siunit, NULL); sx = gwy_si_unit_get_string(siunit, GWY_SI_UNIT_FORMAT_MARKUP); g_object_unref(siunit); g_object_get(graph_data->graph_model, "si-unit-y", &siunit, NULL); sy = gwy_si_unit_get_string(siunit, GWY_SI_UNIT_FORMAT_MARKUP); g_object_unref(siunit); str = g_string_new(""); for (i = 0; i < graph_data->curves->len; i++) { curve = &g_array_index(graph_data->curves, GwyGraphDataCurve, i); column = gtk_tree_view_get_column(treeview, i); table = gtk_tree_view_column_get_widget(column); label = gwy_table_get_child_widget(table, 0, 0); gtk_label_set_markup(GTK_LABEL(label), curve->gcmodel->description->str); label = gwy_table_get_child_widget(table, 1, 0); g_string_assign(str, xlabel); if (sx && *sx) { g_string_append(str, " ["); g_string_append(str, sx); g_string_append(str, "]"); } gtk_label_set_markup(GTK_LABEL(label), str->str); label = gwy_table_get_child_widget(table, 1, 1); g_string_assign(str, ylabel); if (sy && *sy) { g_string_append(str, " ["); g_string_append(str, sy); g_string_append(str, "]"); } gtk_label_set_markup(GTK_LABEL(label), str->str); } g_string_free(str, TRUE); g_free(sx); g_free(sy); }
static gchar* asc_format_header(GwyContainer *data, GwyDataField *dfield, gboolean *zunit_is_nm) { static const gchar asc_header_template[] = "# File Format = ASCII\n" "# Created by Gwyddion %s\n" "# Original file: %s\n" "# x-pixels = %u\n" "# y-pixels = %u\n" "# x-length = %s\n" "# y-length = %s\n" "# x-offset = %s\n" "# y-offset = %s\n" "# Bit2nm = 1.0\n" "%s" "# Start of Data:\n"; GwySIUnit *zunit; gchar *header, *zunit_str, *zunit_line; gchar xreal_str[G_ASCII_DTOSTR_BUF_SIZE], yreal_str[G_ASCII_DTOSTR_BUF_SIZE], xoff_str[G_ASCII_DTOSTR_BUF_SIZE], yoff_str[G_ASCII_DTOSTR_BUF_SIZE]; const guchar *filename = "NONE"; gdouble xreal, yreal, xoff, yoff; /* XXX: Gwyddion can have lateral dimensions as whatever we want. But * who knows about the SPIP ASC format... */ xreal = gwy_data_field_get_xreal(dfield)/Nanometer; yreal = gwy_data_field_get_yreal(dfield)/Nanometer; xoff = gwy_data_field_get_xoffset(dfield)/Nanometer; yoff = gwy_data_field_get_yoffset(dfield)/Nanometer; zunit = gwy_data_field_get_si_unit_z(dfield); g_ascii_dtostr(xreal_str, G_ASCII_DTOSTR_BUF_SIZE, xreal); g_ascii_dtostr(yreal_str, G_ASCII_DTOSTR_BUF_SIZE, yreal); g_ascii_dtostr(xoff_str, G_ASCII_DTOSTR_BUF_SIZE, xoff); g_ascii_dtostr(yoff_str, G_ASCII_DTOSTR_BUF_SIZE, yoff); zunit_str = gwy_si_unit_get_string(zunit, GWY_SI_UNIT_FORMAT_PLAIN); if ((*zunit_is_nm = gwy_strequal(zunit_str, "m"))) zunit_line = g_strdup(""); else zunit_line = g_strdup_printf("# z-unit = %s\n", zunit_str); gwy_container_gis_string_by_name(data, "/filename", &filename); header = g_strdup_printf(asc_header_template, gwy_version_string(), filename, gwy_data_field_get_xres(dfield), gwy_data_field_get_yres(dfield), xreal_str, yreal_str, xoff_str, yoff_str, zunit_line); g_free(zunit_str); g_free(zunit_line); return header; }
static void gwy_app_file_chooser_describe_channel(GwyContainer *container, gint id, GString *str) { GwyDataField *dfield; GwySIUnit *siunit; GwySIValueFormat *vf; GQuark quark; gint xres, yres; gdouble xreal, yreal; gchar *s; g_string_truncate(str, 0); quark = gwy_app_get_data_key_for_id(id); dfield = GWY_DATA_FIELD(gwy_container_get_object(container, quark)); g_return_if_fail(GWY_IS_DATA_FIELD(dfield)); s = gwy_app_get_data_field_title(container, id); g_string_append(str, s); g_free(s); siunit = gwy_data_field_get_si_unit_z(dfield); s = gwy_si_unit_get_string(siunit, GWY_SI_UNIT_FORMAT_MARKUP); g_string_append_printf(str, " [%s]\n", s); g_free(s); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); g_string_append_printf(str, "%d×%d px\n", xres, yres); xreal = gwy_data_field_get_xreal(dfield); yreal = gwy_data_field_get_yreal(dfield); siunit = gwy_data_field_get_si_unit_xy(dfield); vf = gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, sqrt(xreal*yreal), NULL); g_string_append_printf(str, "%.*f×%.*f%s%s", vf->precision, xreal/vf->magnitude, vf->precision, yreal/vf->magnitude, (vf->units && *vf->units) ? " " : "", vf->units); gwy_si_unit_value_format_free(vf); }
static GByteArray* gwy_si_unit_serialize(GObject *obj, GByteArray *buffer) { GwySIUnit *si_unit; GByteArray *retval; g_return_val_if_fail(GWY_IS_SI_UNIT(obj), NULL); si_unit = GWY_SI_UNIT(obj); { gchar *unitstr = gwy_si_unit_get_string(si_unit, GWY_SI_UNIT_FORMAT_PLAIN); GwySerializeSpec spec[] = { { 's', "unitstr", &unitstr, NULL, }, }; gwy_debug("unitstr = <%s>", unitstr); retval = gwy_serialize_pack_object_struct(buffer, GWY_SI_UNIT_TYPE_NAME, G_N_ELEMENTS(spec), spec); g_free(unitstr); return retval; } }
static gboolean surffile_save(GwyContainer *data, const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { FILE *fh; gboolean ok = TRUE; SurfWriter surf; gfloat uintmax = 1073741824.0; gdouble zmaxreal; gdouble zminreal; gdouble xreal; gdouble yreal; gchar *dxunittmp; gchar *dyunittmp; gchar *dzunittmp; GwySIUnit *xysi; GwySIUnit *zsi; GwyContainer *current_data; int power = 0; int k = 0; GwyDataField *dfield; const gdouble *points; gint32 *integer_values; strncpy(surf.signature, "DIGITAL SURF", 12); surf.format = 0; surf.nobjects = 1; surf.version = 1; surf.type = 1; strncpy(surf.object_name, "SCRATCH", 30); strncpy(surf.operator_name, "csm", 30); surf.material_code = 0; surf.acquisition = 0; surf.range = 1; surf.special_points = 0; surf.absolute = 1; strncpy(surf.reserved, " ", 8); surf.pointsize = 32; surf.zmin = 0; surf.zmax = 1073741824.0; strncpy(surf.xaxis, "X", 16); strncpy(surf.yaxis, "Y", 16); strncpy(surf.zaxis, "Z", 16); surf.xunit_ratio = 1; surf.yunit_ratio = 1; surf.zunit_ratio = 1; surf.imprint = 1; surf.inversion = 0; surf.leveling = 0; strncpy(surf.obsolete, " ", 12); surf.seconds = 0; surf.minutes = 0; surf.hours = 0; surf.day = 5; surf.month = 1; surf.year = 2001; surf.dayof = 0; surf.measurement_duration = 1.0; strncpy(surf.obsolete2, " ", 10); surf.comment_size = 0; surf.private_size = 0; strncpy(surf.client_zone," ", 128); surf.XOffset = 0.0; surf.YOffset = 0.0; surf.ZOffset = 0.0; strncpy(surf.reservedzone, " ", 34); if (!(fh = gwy_fopen( filename, "wb"))) { err_OPEN_WRITE(error); return FALSE; } gwy_app_data_browser_get_current(GWY_APP_CONTAINER, ¤t_data, 0); if (!current_data) { err_NO_CHANNEL_EXPORT(error); return FALSE; } if (data != current_data) { return FALSE; } gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, 0); if (!dfield) { err_NO_CHANNEL_EXPORT(error); return FALSE; } /*header values*/ xysi = gwy_data_field_get_si_unit_xy(dfield); zsi = gwy_data_field_get_si_unit_z(dfield); dxunittmp = gwy_si_unit_get_string(xysi, GWY_SI_UNIT_FORMAT_PLAIN); dyunittmp = gwy_si_unit_get_string (xysi, GWY_SI_UNIT_FORMAT_PLAIN); dzunittmp = gwy_si_unit_get_string (zsi, GWY_SI_UNIT_FORMAT_PLAIN); strncpy(surf.dx_unit, dxunittmp, 16); strncpy(surf.dy_unit, dyunittmp, 16); strncpy(surf.dz_unit, dzunittmp, 16); g_free(dxunittmp); g_free(dyunittmp); g_free(dzunittmp); /*extrema*/ zmaxreal = gwy_data_field_get_max(dfield); zminreal = gwy_data_field_get_min(dfield); surf.xres = gwy_data_field_get_xres(dfield); surf.yres = gwy_data_field_get_yres(dfield); surf.nofpoints = surf.xres * surf.yres; xreal = gwy_data_field_get_xreal(dfield); yreal = gwy_data_field_get_yreal(dfield); /*units*/ power = 0; surf.dx = (gfloat)(xreal / surf.xres); get_unit(surf.dx_unit, &power, xreal); surf.dx *= pow10(power); strncpy(surf.xlength_unit, surf.dx_unit, 16); power = 0; surf.dy = (gfloat)(yreal / surf.yres); get_unit(surf.dy_unit, &power, yreal); surf.dy *= pow10(power); strncpy(surf.ylength_unit, surf.dy_unit, 16); power = 0; if (zmaxreal > zminreal) { get_unit(surf.dz_unit, &power, (zmaxreal - zminreal)); } strncpy(surf.zlength_unit, surf.dz_unit, 16); zmaxreal *= pow10(power); zminreal *= pow10(power); surf.dz = (zmaxreal - zminreal) / uintmax; surf.ZOffset = zminreal; /*convert data into integer32*/ integer_values = g_new(gint32, surf.nofpoints); points = gwy_data_field_get_data_const(dfield); if (zminreal != zmaxreal) { for (k = 0; k < surf.nofpoints; k++) { // * pow10( power ) to convert in the dz_unit integer_values[k] = floor(uintmax * (points[k] * pow10(power) - zminreal) / (zmaxreal - zminreal)); } } else { for (k = 0; k < surf.nofpoints; k++) { integer_values[k] = 0; } } /* byte order*/ surf.format = GINT16_TO_LE(surf.format); surf.nobjects = GUINT16_TO_LE(surf.nobjects); surf.version = GINT16_TO_LE(surf.version); surf.type = GINT16_TO_LE(surf.type); surf.material_code = GINT16_TO_LE(surf.material_code); surf.acquisition = GINT16_TO_LE(surf.acquisition); surf.range = GINT16_TO_LE(surf.range); surf.special_points = GINT16_TO_LE(surf.special_points); surf.absolute = GINT16_TO_LE(surf.absolute); surf.pointsize = GINT16_TO_LE(surf.pointsize); surf.zmin = GINT32_TO_LE(surf.zmin); surf.zmax = GINT32_TO_LE(surf.zmax); surf.xres = GINT32_TO_LE(surf.xres); surf.yres = GINT32_TO_LE(surf.yres); surf.nofpoints = GINT32_TO_LE(surf.nofpoints); surf.dx = GFLOAT_TO_LE(surf.dx); surf.dy = GFLOAT_TO_LE(surf.dy); surf.dz = GFLOAT_TO_LE(surf.dz); surf.xunit_ratio = GFLOAT_TO_LE(surf.xunit_ratio); surf.yunit_ratio = GFLOAT_TO_LE(surf.yunit_ratio); surf.zunit_ratio = GFLOAT_TO_LE(surf.zunit_ratio); surf.imprint = GINT16_TO_LE(surf.imprint); surf.inversion = GINT16_TO_LE(surf.inversion); surf.leveling = GINT16_TO_LE(surf.leveling); surf.seconds = GINT16_TO_LE(surf.seconds); surf.minutes = GINT16_TO_LE(surf.minutes); surf.hours = GINT16_TO_LE(surf.hours); surf.day = GINT16_TO_LE(surf.day); surf.month = GINT16_TO_LE(surf.month); surf.year = GINT16_TO_LE(surf.year); surf.dayof = GINT16_TO_LE(surf.dayof); surf.measurement_duration = GFLOAT_TO_LE(surf.measurement_duration); surf.comment_size = GINT16_TO_LE(surf.comment_size); surf.private_size = GINT16_TO_LE(surf.private_size); surf.XOffset = GFLOAT_TO_LE(surf.XOffset); surf.YOffset = GFLOAT_TO_LE(surf.YOffset); surf.ZOffset = GFLOAT_TO_LE(surf.ZOffset); for (k = 0; k < surf.nofpoints; k++) { integer_values[k] = GINT32_TO_LE(integer_values[k]); } //write // fwrite(&surf, sizeof( SurfWriter ), 1, fh) bad struct align if( fwrite(&surf.signature, sizeof(char), 12, fh) != 12 || fwrite(&surf.format, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.nobjects, sizeof(guint16), 1, fh) != 1 || fwrite(&surf.version, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.type, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.object_name, sizeof(char), 30, fh) != 30 || fwrite(&surf.operator_name, sizeof(char), 30, fh) != 30 || fwrite(&surf.material_code, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.acquisition, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.range, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.special_points, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.absolute, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.reserved, sizeof(char), 8, fh) != 8 || fwrite(&surf.pointsize, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.zmin, sizeof(gint32), 1, fh) != 1 || fwrite(&surf.zmax, sizeof(gint32), 1, fh) != 1 || fwrite(&surf.xres, sizeof(gint32), 1, fh) != 1 || fwrite(&surf.yres, sizeof(gint32), 1, fh) != 1 || fwrite(&surf.nofpoints, sizeof(gint32), 1, fh) != 1 || fwrite(&surf.dx, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.dy, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.dz, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.xaxis, sizeof(char), 16, fh) != 16 || fwrite(&surf.yaxis, sizeof(char), 16, fh) != 16 || fwrite(&surf.zaxis, sizeof(char), 16, fh) != 16 || fwrite(&surf.dx_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.dy_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.dz_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.xlength_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.ylength_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.zlength_unit, sizeof(char), 16, fh) != 16 || fwrite(&surf.xunit_ratio, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.yunit_ratio, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.zunit_ratio, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.imprint, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.inversion, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.leveling, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.obsolete, sizeof(char), 12, fh) != 12 || fwrite(&surf.seconds, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.minutes, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.hours, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.day, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.month, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.year, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.dayof, sizeof(gint16),1,fh) != 1 || fwrite(&surf.measurement_duration, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.obsolete2, sizeof(char), 10, fh) != 10 || fwrite(&surf.comment_size, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.private_size, sizeof(gint16), 1, fh) != 1 || fwrite(&surf.client_zone, sizeof(char), 128, fh) != 128 || fwrite(&surf.XOffset, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.YOffset, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.ZOffset, sizeof(gfloat), 1, fh) != 1 || fwrite(&surf.reservedzone, sizeof(char), 34, fh)!= 34 || fwrite(integer_values, sizeof(gint32), surf.nofpoints, fh) != surf.nofpoints ) { err_WRITE(error); ok = FALSE; g_unlink(filename); } g_free(integer_values); fclose( fh ); return ok; }
static GwySIUnit* get_physical_scale(GHashTable *hash, GHashTable *scannerlist, GHashTable *scanlist, gboolean has_version, gdouble *scale, GError **error) { GwySIUnit *siunit, *siunit2; NanoscopeValue *val, *sval; gchar *key; gint q; /* Very old style scales (files with Version field) */ if (!has_version) { if (!(val = g_hash_table_lookup(hash, "Z magnify image"))) { err_MISSING_FIELD(error, "Z magnify image"); return NULL; } /* TODO: Luminescence */ siunit = gwy_si_unit_new("m"); /* According to Markus, the units are 1/100 nm, but his scale * calculation is raw/655.36 [nm]. We have the factor 1/65536 applied * automatically, that gives 1e-7 [m]. Whatever. */ *scale = 1e-7 * val->hard_value; return siunit; } /* XXX: This is a damned heuristics. For some value types we try to guess * a different quantity scale to look up. */ if (!(val = g_hash_table_lookup(hash, "@2:Z scale"))) { if (!(val = g_hash_table_lookup(hash, "Z scale"))) { err_MISSING_FIELD(error, "Z scale"); return NULL; } /* Old style scales */ siunit = gwy_si_unit_new_parse(val->hard_value_units, &q); *scale = val->hard_value * pow10(q); if (val->hard_scale) *scale *= 65536.0/val->hard_scale; return siunit; } key = g_strdup_printf("@%s", val->soft_scale); if (!(sval = g_hash_table_lookup(scannerlist, key)) && (!scanlist || !(sval = g_hash_table_lookup(scanlist, key)))) { g_warning("`%s' not found", key); g_free(key); /* XXX */ *scale = val->hard_value; return gwy_si_unit_new(""); } *scale = val->hard_value*sval->hard_value; if (!sval->hard_value_units || !*sval->hard_value_units) { if (gwy_strequal(val->soft_scale, "Sens. Phase")) siunit = gwy_si_unit_new("deg"); else siunit = gwy_si_unit_new("V"); } else { siunit = gwy_si_unit_new_parse(sval->hard_value_units, &q); siunit2 = gwy_si_unit_new("V"); gwy_si_unit_multiply(siunit, siunit2, siunit); gwy_debug("Scale1 = %g V/LSB", val->hard_value); gwy_debug("Scale2 = %g %s", sval->hard_value, sval->hard_value_units); *scale *= pow10(q); gwy_debug("Total scale = %g %s/LSB", *scale, gwy_si_unit_get_string(siunit, GWY_SI_UNIT_FORMAT_PLAIN)); g_object_unref(siunit2); } g_free(key); return siunit; }
static gboolean gsf_export(GwyContainer *container, const gchar *filename, G_GNUC_UNUSED GwyRunType mode, GError **error) { static const gchar zeroes[4] = { 0, 0, 0, 0 }; GString *header = NULL; gfloat *dfl = NULL; guint i, xres, yres, padding; gint id; GwyDataField *dfield; const gdouble *d; gdouble v; gchar *s; GwySIUnit *unit, *emptyunit; FILE *fh; gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_ID, &id, 0); if (!dfield) { err_NO_CHANNEL_EXPORT(error); return FALSE; } if (!(fh = g_fopen(filename, "wb"))) { err_OPEN_WRITE(error); return FALSE; } xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); header = g_string_new(MAGIC); g_string_append_printf(header, "XRes = %u\n", xres); g_string_append_printf(header, "YRes = %u\n", yres); append_num(header, "XReal", gwy_data_field_get_xreal(dfield)); append_num(header, "YReal", gwy_data_field_get_yreal(dfield)); if ((v = gwy_data_field_get_xoffset(dfield))) append_num(header, "XOffset", v); if ((v = gwy_data_field_get_yoffset(dfield))) append_num(header, "YOffset", v); emptyunit = gwy_si_unit_new(NULL); unit = gwy_data_field_get_si_unit_xy(dfield); if (!gwy_si_unit_equal(unit, emptyunit)) { s = gwy_si_unit_get_string(unit, GWY_SI_UNIT_FORMAT_PLAIN); g_string_append_printf(header, "XYUnits = %s\n", s); g_free(s); } unit = gwy_data_field_get_si_unit_z(dfield); if (!gwy_si_unit_equal(unit, emptyunit)) { s = gwy_si_unit_get_string(unit, GWY_SI_UNIT_FORMAT_PLAIN); g_string_append_printf(header, "ZUnits = %s\n", s); g_free(s); } g_object_unref(emptyunit); s = gwy_app_get_data_field_title(container, id); g_string_append_printf(header, "Title = %s\n", s); g_free(s); if (fwrite(header->str, 1, header->len, fh) != header->len) { err_WRITE(error); goto fail; } padding = 4 - (header->len % 4); if (fwrite(zeroes, 1, padding, fh) != padding) { err_WRITE(error); goto fail; } g_string_free(header, TRUE); header = NULL; dfl = g_new(gfloat, xres*yres); d = gwy_data_field_get_data_const(dfield); for (i = 0; i < xres*yres; i++) { union { guchar pp[4]; float f; } z; z.f = d[i]; #if (G_BYTE_ORDER == G_BIG_ENDIAN) GWY_SWAP(guchar, z.pp[0], z.pp[3]); GWY_SWAP(guchar, z.pp[1], z.pp[2]); #endif dfl[i] = z.f; } if (fwrite(dfl, sizeof(gfloat), xres*yres, fh) != xres*yres) { err_WRITE(error); goto fail; } g_free(dfl); fclose(fh); return TRUE; fail: if (fh) fclose(fh); g_unlink(filename); if (header) g_string_free(header, TRUE); g_free(dfl); return FALSE; }
static gboolean tilt_dialog(TiltArgs *args, GwyDataField *dfield) { enum { RESPONSE_RESET = 1 }; GtkWidget *dialog, *spin, *table, *label; GwySIUnit *unit; gchar *unitstr; TiltControls controls; gboolean units_equal; gint row, response; unit = gwy_si_unit_new(NULL); units_equal = gwy_si_unit_equal(gwy_data_field_get_si_unit_z(dfield), gwy_data_field_get_si_unit_xy(dfield)); gwy_si_unit_divide(gwy_data_field_get_si_unit_z(dfield), gwy_data_field_get_si_unit_xy(dfield), unit); unitstr = gwy_si_unit_get_string(unit, GWY_SI_UNIT_FORMAT_VFMARKUP); g_object_unref(unit); dialog = gtk_dialog_new_with_buttons(_("Tilt"), NULL, 0, _("_Reset"), RESPONSE_RESET, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); controls.args = args; controls.in_update = TRUE; table = gtk_table_new(5 + (units_equal ? 1 : 0), 3, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 2); gtk_table_set_col_spacings(GTK_TABLE(table), 6); gtk_container_set_border_width(GTK_CONTAINER(table), 4); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), table); row = 0; /* Slopes */ label = gwy_label_new_header(_("Slopes")); gtk_table_attach(GTK_TABLE(table), label, 0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); row++; controls.dx = gtk_adjustment_new(args->dx, -100, 100, 1e-4, 1e-2, 0); spin = gwy_table_attach_hscale(table, row, _("_X:"), unitstr, controls.dx, GWY_HSCALE_NO_SCALE); gwy_widget_set_activate_on_unfocus(spin, TRUE); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 6); g_signal_connect(controls.dx, "value-changed", G_CALLBACK(tilt_dx_changed), &controls); row++; controls.dy = gtk_adjustment_new(args->dy, -100, 100, 1e-4, 1e-2, 0); spin = gwy_table_attach_hscale(table, row, _("_Y:"), unitstr, controls.dy, GWY_HSCALE_NO_SCALE); gwy_widget_set_activate_on_unfocus(spin, TRUE); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 6); g_signal_connect(controls.dy, "value-changed", G_CALLBACK(tilt_dy_changed), &controls); gtk_table_set_row_spacing(GTK_TABLE(table), row, 8); row++; /* Angles (adjustment values will be calculated later) */ label = gwy_label_new_header(_("Angles")); gtk_table_attach(GTK_TABLE(table), label, 0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); row++; if (units_equal) { controls.theta = gtk_adjustment_new(0, 0, 89.6, 1e-2, 1.0, 0); spin = gwy_table_attach_hscale(table, row, _("θ:"), _("deg"), controls.theta, GWY_HSCALE_NO_SCALE); gwy_widget_set_activate_on_unfocus(spin, TRUE); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 4); g_signal_connect_swapped(controls.theta, "value-changed", G_CALLBACK(tilt_angle_changed), &controls); row++; } else controls.theta = gtk_adjustment_new(0, 0, 90.0, 1e-2, 1.0, 0); controls.phi = gtk_adjustment_new(0, -180, 180, 1e-2, 1.0, 0); spin = gwy_table_attach_hscale(table, row, _("φ:"), _("deg"), controls.phi, GWY_HSCALE_NO_SCALE); gwy_widget_set_activate_on_unfocus(spin, TRUE); gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 4); g_signal_connect_swapped(controls.phi, "value-changed", G_CALLBACK(tilt_angle_changed), &controls); row++; controls.in_update = FALSE; tilt_deriv_to_angles(&controls); gtk_widget_show_all(dialog); do { response = gtk_dialog_run(GTK_DIALOG(dialog)); switch (response) { case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_DELETE_EVENT: gtk_widget_destroy(dialog); case GTK_RESPONSE_NONE: return FALSE; break; case GTK_RESPONSE_OK: break; case RESPONSE_RESET: dialog_reset(&controls); break; default: g_assert_not_reached(); break; } } while (response != GTK_RESPONSE_OK); gtk_widget_destroy(dialog); return TRUE; }