static void zoom_in_changed(EntropyControls *controls, GtkToggleButton *check) { GwyGraphModel *gmodel = gwy_graph_get_model(GWY_GRAPH(controls->graph)); GwyGraphCurveModel *gcmodel; const gdouble *xdata, *ydata; gdouble S; guint ndata, i; g_object_set(gmodel, "x-min-set", FALSE, "x-max-set", FALSE, "y-min-set", FALSE, "y-max-set", FALSE, NULL); if (!(controls->args->zoom_in = gtk_toggle_button_get_active(check)) || (gwy_graph_model_get_n_curves(gmodel) < 2)) { return; } gcmodel = gwy_graph_model_get_curve(gmodel, 1); ydata = gwy_graph_curve_model_get_ydata(gcmodel); S = ydata[0]; gcmodel = gwy_graph_model_get_curve(gmodel, 0); ndata = gwy_graph_curve_model_get_ndata(gcmodel); if (ndata < 5) return; xdata = gwy_graph_curve_model_get_xdata(gcmodel); ydata = gwy_graph_curve_model_get_ydata(gcmodel); for (i = 1; i+1 < ndata; i++) { if (ydata[i] > S - G_LN2) { g_object_set(gmodel, "x-min", xdata[i-1], "x-min-set", TRUE, "y-min", ydata[i-1], "y-min-set", TRUE, NULL); break; } } for (i = ndata-2; i; i--) { if (ydata[i] < S + G_LN2) { g_object_set(gmodel, "x-max", xdata[i+1], "x-max-set", TRUE, "y-max", ydata[i+1], "y-max-set", TRUE, NULL); break; } } }
/* FIXME: It seems to overestimate the height a bit, it's visible on labels * with many curves. It also seems to strangely underestimate the width * for curve descriptions under certain length. */ static void gwy_graph_label_calculate_size(GwyGraphLabel *label) { gint i, nc; PangoLayout *layout; PangoRectangle rect; GwyGraphCurveModel *curvemodel; GwyGraphModel *model; label->reqheight = 0; label->reqwidth = 0; model = GWY_GRAPH_MODEL(label->graph_model); nc = gwy_graph_model_get_n_curves(model); for (i = 0; i < nc; i++) { curvemodel = gwy_graph_model_get_curve(model, i); layout = gtk_widget_create_pango_layout(GTK_WIDGET(label), NULL); pango_layout_set_font_description(layout, label->font_desc); pango_layout_set_markup(layout, curvemodel->description->str, curvemodel->description->len); pango_layout_get_pixel_extents(layout, NULL, &rect); if (label->reqwidth < rect.width) label->reqwidth = rect.width + 30 + model->label_frame_thickness; label->reqheight += rect.height + 5 + model->label_frame_thickness; g_object_unref(layout); } if (label->reqwidth == 0) label->reqwidth = 30; if (label->reqheight == 0) label->reqheight = 30; }
static void prof_execute(ProfControls *controls, GwyContainer *data) { GwyGraphCurveModel *gcmodel; GwyGraphModel *gmodel; ProfArgs *args = controls->args; gchar *s; gint i, n; n = gwy_selection_get_data(controls->selection, NULL); g_return_if_fail(n); g_object_set(controls->gmodel, "label-visible", TRUE, NULL); if (!args->separate) { gwy_app_add_graph_or_curves(controls->gmodel, data, &args->target_graph, 1); return; } for (i = 0; i < n; i++) { gmodel = gwy_graph_model_new_alike(controls->gmodel); gcmodel = gwy_graph_model_get_curve(controls->gmodel, i); gcmodel = gwy_graph_curve_model_duplicate(gcmodel); gwy_graph_model_add_curve(gmodel, gcmodel); g_object_unref(gcmodel); g_object_get(gcmodel, "description", &s, NULL); g_object_set(gmodel, "title", s, NULL); g_free(s); gwy_app_data_browser_add_graph_model(gmodel, data, TRUE); g_object_unref(gmodel); } }
static void filter(GwyGraph *graph) { GwyContainer *data; GwyGraphCurveModel *cmodel, *cmodelnew; GwyGraphModel *model; const gdouble *xdata, *ydata; gdouble *newydata; gint i, ncurves, ndata; GQuark quark; gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &data, GWY_APP_GRAPH_MODEL_KEY, &quark, 0); gwy_app_undo_qcheckpointv(data, 1, &quark); model = gwy_graph_get_model(graph); ncurves = gwy_graph_model_get_n_curves(model); for (i = 0; i < ncurves; i++) { cmodel = gwy_graph_model_get_curve(model, i); cmodelnew = gwy_graph_curve_model_new_alike(cmodel); xdata = gwy_graph_curve_model_get_xdata(cmodel); ydata = gwy_graph_curve_model_get_ydata(cmodel); ndata = gwy_graph_curve_model_get_ndata(cmodel); newydata = g_new(gdouble, ndata); filter_do(ydata, newydata, ndata); gwy_graph_curve_model_set_data(cmodelnew, xdata, newydata, ndata); g_free(newydata); gwy_graph_model_remove_curve(gwy_graph_get_model(graph), i); gwy_graph_model_add_curve(model, cmodelnew); g_object_unref(cmodelnew); } }
static void prof_update_curve(ProfControls *controls, gint i) { GwyGraphCurveModel *gcmodel; gdouble xy[4], h; gint xl0, yl0, xl1, yl1; gint n, lineres; gchar *desc; g_return_if_fail(gwy_selection_get_object(controls->selection, i, xy)); /* The ω=0 pixel is always at res/2, for even dimensions it means it is * shifted half-a-pixel to the right from the precise centre. */ xl0 = gwy_data_field_get_xres(controls->psdffield)/2; yl0 = gwy_data_field_get_yres(controls->psdffield)/2; xl1 = floor(gwy_data_field_rtoj(controls->psdffield, xy[0])); yl1 = floor(gwy_data_field_rtoi(controls->psdffield, xy[1])); xy[0] += gwy_data_field_get_xoffset(controls->psdffield); xy[1] += gwy_data_field_get_yoffset(controls->psdffield); h = hypot(controls->hx*xy[0], controls->hy*xy[1])/hypot(xy[0], xy[1]); if (!controls->args->fixres) { lineres = GWY_ROUND(hypot(abs(xl0 - xl1) + 1, abs(yl0 - yl1) + 1)); lineres = MAX(lineres, MIN_RESOLUTION); } else lineres = controls->args->resolution; gwy_data_field_get_profile(controls->psdffield, controls->line, xl0, yl0, xl1, yl1, lineres, 1, controls->args->interpolation); gwy_data_line_multiply(controls->line, h); n = gwy_graph_model_get_n_curves(controls->gmodel); if (i < n) { gcmodel = gwy_graph_model_get_curve(controls->gmodel, i); } else { gcmodel = gwy_graph_curve_model_new(); g_object_set(gcmodel, "mode", GWY_GRAPH_CURVE_LINE, "color", gwy_graph_get_preset_color(i), NULL); gwy_graph_model_add_curve(controls->gmodel, gcmodel); g_object_unref(gcmodel); } gwy_graph_curve_model_set_data_from_dataline(gcmodel, controls->line, 0, 0); desc = g_strdup_printf(_("PSDF %.0f°"), 180.0/G_PI*atan2(-xy[1], xy[0])); g_object_set(gcmodel, "description", desc, NULL); g_free(desc); }
static void fit_plot_curve(FitArgs *args) { GwyGraphCurveModel *cmodel; gdouble *xd, *yd; gboolean initial, ok; /* XXX: ignored */ gint i, n; gdouble *param; if (!args->is_fitted && !args->is_estimated) return; initial = !args->is_fitted; n = gwy_nlfit_preset_get_nparams(args->fitfunc); param = g_newa(gdouble, n); for (i = 0; i < n; i++) { FitParamArg *arg; arg = &g_array_index(args->param, FitParamArg, i); param[i] = initial ? arg->init : arg->value; } n = gwy_data_line_get_res(args->xdata); g_return_if_fail(n == gwy_data_line_get_res(args->ydata)); xd = gwy_data_line_get_data(args->xdata); yd = gwy_data_line_get_data(args->ydata); for (i = 0; i < n; i++) yd[i] = gwy_nlfit_preset_get_value(args->fitfunc, xd[i], param, &ok); if (gwy_graph_model_get_n_curves(args->graph_model) == 2) cmodel = gwy_graph_model_get_curve(args->graph_model, 1); else { cmodel = gwy_graph_curve_model_new(); g_object_set(cmodel, "mode", GWY_GRAPH_CURVE_LINE, "color", &args->fitcolor, NULL); gwy_graph_model_add_curve(args->graph_model, cmodel); g_object_unref(cmodel); } g_object_set(cmodel, "description", initial ? gwy_sgettext("Estimate") : gwy_sgettext("Fit"), NULL); gwy_graph_curve_model_set_data(cmodel, xd, yd, n); }
/** * gwy_graph_label_export_vector: * @label: A graph label. * @x: x position of the graph label * @y: y position of the graph label * @width: width of the graph label * @height: hieght of the graph label * @fontsize: fontsize of the label * * Creates PostScript representation of a graph label. * * Returns: A fragment of PostScript code representing the the graph label * as a newly allocated #GString. **/ GString* gwy_graph_label_export_vector(GwyGraphLabel *label, gint x, gint y, gint width, gint height, gint fontsize) { gint i, nc; GwyGraphCurveModel *curvemodel; GwyGraphModel *model; GString *out; gint xpos, ypos; GwyRGBA *color; gint pointsize; gint linesize; gchar *description; out = g_string_new("%%Label\n"); g_string_append_printf(out, "/Times-Roman findfont\n"); g_string_append_printf(out, "%d scalefont\n setfont\n", fontsize); model = GWY_GRAPH_MODEL(label->graph_model); g_string_append_printf(out, "/box {\n" "newpath\n" "%d setlinewidth\n" "%d %d M\n" "%d %d L\n" "%d %d L\n" "%d %d L\n" "closepath\n" "} def\n", model->label_frame_thickness, x, y, x + width, y, x + width, y + height, x, y + height); g_string_append_printf(out, "gsave\n"); g_string_append_printf(out, "box\n"); g_string_append_printf(out, "gsave\n"); g_string_append_printf(out, "stroke\n"); g_string_append_printf(out, "grestore\n"); g_string_append_printf(out, "clip\n"); g_string_append_printf(out, "1 setgray\n"); g_string_append_printf(out, "fill\n"); xpos = 5; ypos = height - fontsize; nc = gwy_graph_model_get_n_curves(model); for (i = 0; i < nc; i++) { curvemodel = gwy_graph_model_get_curve(model, i); g_object_get(curvemodel, "point-size", &pointsize, "line-width", &linesize, "color", &color, "description", &description, NULL); g_string_append_printf(out, "/hpt %d def\n", pointsize); g_string_append_printf(out, "/vpt %d def\n", pointsize); g_string_append_printf(out, "/hpt2 hpt 2 mul def\n"); g_string_append_printf(out, "/vpt2 vpt 2 mul def\n"); g_string_append_printf(out, "%d setlinewidth\n", linesize); g_string_append_printf(out, "%f %f %f setrgbcolor\n", color->r, color->g, color->b); g_string_append_printf(out, "%d %d M\n", x + xpos, y + ypos); g_string_append_printf(out, "%d %d L\n", x + xpos + 20, y + ypos); g_string_append_printf(out, "%d %d R\n", 5, -(gint)(fontsize/4)); g_string_append_printf(out, "(%s) show\n", description); g_string_append_printf(out, "stroke\n"); ypos -= fontsize + 5; g_free(description); gwy_rgba_free(color); } g_string_append_printf(out, "grestore\n"); return out; }
/** * gwy_graph_label_draw_on_drawable: * @label: graph label * @drawable: the #GdkDrawable * @gc: Graphics context. * It is modified by this function unpredictably. * @layout: pango layout * @x: x position where label is to be drawn * @y: y position where label is to be drawn * @width: width of the label * @height: hieght of the label * * draws a graph label on a drawable **/ void gwy_graph_label_draw_on_drawable(GwyGraphLabel *label, GdkDrawable *drawable, GdkGC *gc, PangoLayout *layout, gint x, gint y, gint width, gint height) { gint ypos, winheight, winwidth, winx, winy, frame_off; gint i, nc; GwyGraphCurveModel *curvemodel; GwyGraphModel *model; PangoRectangle rect; GdkColor fg = { 0, 0, 0, 0 }; GdkColor color = { 0, 65535, 65535, 65535 }; if (!label->graph_model) return; model = GWY_GRAPH_MODEL(label->graph_model); pango_layout_set_font_description(layout, label->font_desc); frame_off = model->label_frame_thickness/2; ypos = 5 + frame_off; gdk_gc_set_rgb_fg_color(gc, &color); gdk_draw_rectangle(drawable, gc, TRUE, x, y, width, height); gdk_gc_set_rgb_fg_color(gc, &fg); winx = x; winy = y; winwidth = width; winheight = height; nc = gwy_graph_model_get_n_curves(model); for (i = 0; i < nc; i++) { curvemodel = gwy_graph_model_get_curve(model, i); pango_layout_set_markup(layout, curvemodel->description->str, curvemodel->description->len); pango_layout_get_pixel_extents(layout, NULL, &rect); if (model->label_reverse) gdk_draw_layout(drawable, gc, winx + winwidth - rect.width - 25 - frame_off, winy + ypos, layout); else gdk_draw_layout(drawable, gc, winx + 25 + frame_off, winy + ypos, layout); g_array_index(label->samplepos, gint, i) = ypos; if (curvemodel->mode == GWY_GRAPH_CURVE_LINE || curvemodel->mode == GWY_GRAPH_CURVE_LINE_POINTS) { if (model->label_reverse) gwy_graph_draw_line(drawable, gc, winx + winwidth - 20 - frame_off, winy + ypos + rect.height/2, winx + winwidth - 5, winy + ypos + rect.height/2, curvemodel->line_style, curvemodel->line_width, &(curvemodel->color)); else gwy_graph_draw_line(drawable, gc, winx + 5 + frame_off, winy + ypos + rect.height/2, winx + 20 + frame_off, winy + ypos + rect.height/2, curvemodel->line_style, curvemodel->line_width, &(curvemodel->color)); } if (curvemodel->mode == GWY_GRAPH_CURVE_POINTS || curvemodel->mode == GWY_GRAPH_CURVE_LINE_POINTS) { if (model->label_reverse) gwy_graph_draw_point(drawable, gc, winx + winwidth - 13 - frame_off, winy + ypos + rect.height/2, curvemodel->point_type, curvemodel->point_size, &(curvemodel->color)); else gwy_graph_draw_point(drawable, gc, winx + 12 + frame_off, winy + ypos + rect.height/2, curvemodel->point_type, curvemodel->point_size, &(curvemodel->color)); } gdk_gc_set_rgb_fg_color(gc, &fg); ypos += rect.height + 5; } if (model->label_frame_thickness > 0) { gdk_gc_set_line_attributes(gc, model->label_frame_thickness, GDK_LINE_SOLID, GDK_CAP_ROUND, GDK_JOIN_MITER); gdk_draw_line(drawable, gc, winx + model->label_frame_thickness/2, winy + model->label_frame_thickness/2, winx + winwidth - model->label_frame_thickness/2 - 1, winy + model->label_frame_thickness/2); gdk_draw_line(drawable, gc, winx + model->label_frame_thickness/2, winy + winheight - model->label_frame_thickness/2 - 1, winx + winwidth - model->label_frame_thickness/2 - 1, winy + winheight - model->label_frame_thickness/2 - 1); gdk_draw_line(drawable, gc, winx + model->label_frame_thickness/2, winy + model->label_frame_thickness/2, winx + model->label_frame_thickness/2, winy + winheight - model->label_frame_thickness/2 - 1); gdk_draw_line(drawable, gc, winx + winwidth - model->label_frame_thickness/2 - 1, winy + model->label_frame_thickness/2, winx + winwidth - model->label_frame_thickness/2 - 1, winy + winheight - model->label_frame_thickness/2 - 1); } }
static void fit_dialog(FitArgs *args) { GtkWidget *label, *dialog, *hbox, *hbox2, *table, *align, *expander, *scroll; GtkTable *table2; GwyGraphModel *gmodel; GwyGraphCurveModel *cmodel; GwyGraphArea *area; GwySelection *selection; GwySIUnit *siunit; FitControls controls; gint response, row; GString *report; gdouble xmin, xmax; controls.args = args; controls.in_update = TRUE; controls.param = g_array_new(FALSE, TRUE, sizeof(FitParamControl)); gmodel = gwy_graph_get_model(GWY_GRAPH(args->parent_graph)); gwy_graph_model_get_x_range(gmodel, &xmin, &xmax); g_object_get(gmodel, "si-unit-x", &siunit, NULL); args->abscissa_vf = gwy_si_unit_get_format_with_digits(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP, MAX(fabs(xmin), fabs(xmax)), 4, NULL); g_object_unref(siunit); dialog = gtk_dialog_new_with_buttons(_("Fit FD Curve"), NULL, 0, NULL); controls.dialog = dialog; gtk_dialog_add_action_widget(GTK_DIALOG(dialog), gwy_stock_like_button_new(gwy_sgettext("verb|_Fit"), GTK_STOCK_EXECUTE), RESPONSE_FIT); gtk_dialog_add_button(GTK_DIALOG(dialog), gwy_sgettext("verb|_Estimate"), RESPONSE_ESTIMATE); gtk_dialog_add_button(GTK_DIALOG(dialog), _("_Plot Inits"), RESPONSE_PLOT); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_SAVE, RESPONSE_SAVE); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL); gtk_dialog_add_button(GTK_DIALOG(dialog), GTK_STOCK_OK, GTK_RESPONSE_OK); gwy_help_add_to_graph_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT); gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); hbox = gtk_hbox_new(FALSE, 2); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 0); /* Graph */ args->graph_model = gwy_graph_model_new_alike(gmodel); controls.graph = gwy_graph_new(args->graph_model); g_object_unref(args->graph_model); gtk_widget_set_size_request(controls.graph, 400, 300); gwy_graph_enable_user_input(GWY_GRAPH(controls.graph), FALSE); gtk_box_pack_start(GTK_BOX(hbox), controls.graph, TRUE, TRUE, 0); gwy_graph_set_status(GWY_GRAPH(controls.graph), GWY_GRAPH_STATUS_XSEL); area = GWY_GRAPH_AREA(gwy_graph_get_area(GWY_GRAPH(controls.graph))); selection = gwy_graph_area_get_selection(area, GWY_GRAPH_STATUS_XSEL); gwy_selection_set_max_objects(selection, 1); g_signal_connect(selection, "changed", G_CALLBACK(graph_selected), &controls); gwy_graph_model_add_curve(controls.args->graph_model, gwy_graph_model_get_curve(gmodel, args->curve)); args->fitfunc = NULL; /* Controls */ align = gtk_alignment_new(0.0, 0.0, 0.0, 0.0); gtk_box_pack_start(GTK_BOX(hbox), align, FALSE, FALSE, 0); g_signal_connect(align, "size-request", G_CALLBACK(grow_width), NULL); table = gtk_table_new(7, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE(table), 2); gtk_table_set_col_spacings(GTK_TABLE(table), 6); gtk_box_pack_start(GTK_BOX(hbox), table, FALSE, FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(table), 4); row = 0; /* Curve to fit */ label = gtk_label_new_with_mnemonic(_("_Graph curve:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 0, 0); controls.curve = curve_selector_new(gmodel, G_CALLBACK(curve_changed), &controls, args->curve); gtk_label_set_mnemonic_widget(GTK_LABEL(label), controls.curve); gtk_table_attach(GTK_TABLE(table), controls.curve, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); row++; /* Fitted function */ label = gtk_label_new_with_mnemonic(_("F_unction:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 0, 0); controls.function = function_selector_new(G_CALLBACK(function_changed), &controls, args->function_type); gtk_label_set_mnemonic_widget(GTK_LABEL(label), controls.function); gtk_table_attach(GTK_TABLE(table), controls.function, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); row++; controls.formula = gtk_label_new("f(x) ="); gtk_misc_set_alignment(GTK_MISC(controls.formula), 0.0, 0.5); gtk_label_set_selectable(GTK_LABEL(controls.formula), TRUE); scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), controls.formula); gtk_table_attach(GTK_TABLE(table), scroll, 0, 2, row, row+1, GTK_FILL, 0, 0, 8); row++; /* Parameters sought */ controls.param_table = gtk_table_new(1, 10, FALSE); table2 = GTK_TABLE(controls.param_table); gtk_table_set_row_spacing(table2, 0, 2); gtk_table_set_col_spacings(table2, 2); gtk_table_set_col_spacing(table2, 0, 6); gtk_table_set_col_spacing(table2, 4, 6); gtk_table_set_col_spacing(table2, 5, 6); gtk_table_set_col_spacing(table2, 7, 6); gtk_table_set_col_spacing(table2, 8, 6); gtk_table_attach(GTK_TABLE(table), GTK_WIDGET(table2), 0, 2, row, row+1, GTK_FILL, 0, 0, 0); gtk_table_set_row_spacing(GTK_TABLE(table), row, 8); row++; gtk_table_attach(table2, gwy_label_new_header(_("Fix")), 0, 1, 0, 1, GTK_FILL, 0, 0, 0); gtk_table_attach(table2, gwy_label_new_header(_("Parameter")), 1, 5, 0, 1, GTK_FILL, 0, 0, 0); gtk_table_attach(table2, gwy_label_new_header(_("Error")), 6, 8, 0, 1, GTK_FILL, 0, 0, 0); gtk_table_attach(table2, gwy_label_new_header(_("Initial")), 9, 10, 0, 1, GTK_FILL, 0, 0, 0); /* Make space for 4 parameters */ #if 0 for (i = 0; i < 4; i++) fit_param_row_create(&controls, i, table2, i+1); #endif /* Chi^2 */ label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), _("χ<sup>2</sup> result:")); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_FILL, 0, 0, 0); controls.chisq = gtk_label_new(NULL); gtk_misc_set_alignment(GTK_MISC(controls.chisq), 0.0, 0.5); gtk_table_attach(GTK_TABLE(table), controls.chisq, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); gtk_table_set_row_spacing(GTK_TABLE(table), row, 8); row++; /* Correlation matrix */ expander = gtk_expander_new(NULL); gtk_expander_set_label_widget(GTK_EXPANDER(expander), gwy_label_new_header(_("Correlation Matrix"))); gtk_table_attach(GTK_TABLE(table), expander, 0, 2, row, row+1, GTK_FILL, 0, 0, 0); gtk_table_set_row_spacing(GTK_TABLE(table), row, 8); row++; align = gtk_alignment_new(0.0, 0.5, 0.0, 0.0); gtk_container_add(GTK_CONTAINER(expander), align); row++; controls.covar = g_array_new(FALSE, TRUE, sizeof(GtkWidget*)); controls.covar_table = gtk_table_new(1, 1, TRUE); table2 = GTK_TABLE(controls.covar_table); gtk_table_set_col_spacings(table2, 6); gtk_table_set_row_spacings(table2, 2); gtk_container_add(GTK_CONTAINER(align), GTK_WIDGET(table2)); /* Fit area */ hbox2 = gtk_hbox_new(FALSE, 6); gtk_table_attach(GTK_TABLE(table), hbox2, 0, 2, row, row+1, GTK_FILL, 0, 0, 0); row++; label = gtk_label_new(_("Range:")); gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); controls.from = gtk_entry_new(); g_object_set_data(G_OBJECT(controls.from), "id", (gpointer)"from"); gtk_entry_set_width_chars(GTK_ENTRY(controls.from), 8); gtk_box_pack_start(GTK_BOX(hbox2), controls.from, FALSE, FALSE, 0); g_signal_connect(controls.from, "activate", G_CALLBACK(range_changed), &controls); gwy_widget_set_activate_on_unfocus(controls.from, TRUE); label = gtk_label_new(gwy_sgettext("range|to")); gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); controls.to = gtk_entry_new(); g_object_set_data(G_OBJECT(controls.to), "id", (gpointer)"to"); gtk_entry_set_width_chars(GTK_ENTRY(controls.to), 8); gtk_box_pack_start(GTK_BOX(hbox2), controls.to, FALSE, FALSE, 0); g_signal_connect(controls.to, "activate", G_CALLBACK(range_changed), &controls); gwy_widget_set_activate_on_unfocus(controls.to, TRUE); label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), args->abscissa_vf->units); gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); /* Auto-update */ hbox2 = gtk_hbox_new(FALSE, 6); gtk_table_attach(GTK_TABLE(table), hbox2, 0, 2, row, row+1, GTK_FILL, 0, 0, 0); row++; label = gtk_label_new(_("Instant:")); gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0); controls.auto_estimate = gtk_check_button_new_with_mnemonic(_("e_stimate")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.auto_estimate), args->auto_estimate); gtk_box_pack_start(GTK_BOX(hbox2), controls.auto_estimate, FALSE, FALSE, 0); g_signal_connect(controls.auto_estimate, "toggled", G_CALLBACK(auto_estimate_changed), &controls); controls.auto_plot = gtk_check_button_new_with_mnemonic(_("p_lot")); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.auto_plot), args->auto_plot); gtk_box_pack_start(GTK_BOX(hbox2), controls.auto_plot, FALSE, FALSE, 0); g_signal_connect(controls.auto_plot, "toggled", G_CALLBACK(auto_plot_changed), &controls); function_changed(GTK_COMBO_BOX(controls.function), &controls); graph_selected(selection, -1, &controls); controls.in_update = FALSE; gtk_widget_show_all(dialog); do { response = gtk_dialog_run(GTK_DIALOG(dialog)); fit_fetch_entry(&controls); switch (response) { case GTK_RESPONSE_CANCEL: case GTK_RESPONSE_DELETE_EVENT: gtk_widget_destroy(dialog); fit_controls_free(&controls); return; break; case GTK_RESPONSE_OK: if (args->is_estimated) { cmodel = gwy_graph_model_get_curve(args->graph_model, 1); gwy_graph_model_add_curve(gmodel, cmodel); } gtk_widget_destroy(dialog); break; case RESPONSE_SAVE: report = create_fit_report(args); gwy_save_auxiliary_data(_("Save Fit Report"), GTK_WINDOW(dialog), -1, report->str); g_string_free(report, TRUE); break; case RESPONSE_ESTIMATE: fit_estimate(&controls); break; case RESPONSE_PLOT: fit_set_state(&controls, FALSE, TRUE); fit_plot_curve(args); break; case RESPONSE_FIT: fit_do(&controls); break; default: g_assert_not_reached(); break; } } while (response != GTK_RESPONSE_OK); fit_controls_free(&controls); }
static gboolean curvature_plot_graph(GwyDataField *dfield, const Intersection *i1, const Intersection *i2, GwyGraphModel *gmodel) { GwyGraphCurveModel *gcmodel; GwyDataLine *dline; gint xres, yres; guint i; if (!gwy_graph_model_get_n_curves(gmodel)) { GwySIUnit *siunitxy, *siunitz; gchar *s; siunitxy = gwy_si_unit_duplicate(gwy_data_field_get_si_unit_xy(dfield)); siunitz = gwy_si_unit_duplicate(gwy_data_field_get_si_unit_z(dfield)); g_object_set(gmodel, "title", _("Curvature Sections"), "si-unit-x", siunitxy, "si-unit-y", siunitz, NULL); g_object_unref(siunitxy); g_object_unref(siunitz); for (i = 0; i < 2; i++) { gcmodel = gwy_graph_curve_model_new(); s = g_strdup_printf(_("Profile %d"), (gint)i+1); g_object_set(gcmodel, "description", s, "mode", GWY_GRAPH_CURVE_LINE, "color", gwy_graph_get_preset_color(i), NULL); g_free(s); gwy_graph_model_add_curve(gmodel, gcmodel); g_object_unref(gcmodel); } } else { g_assert(gwy_graph_model_get_n_curves(gmodel) == 2); } dline = gwy_data_line_new(1, 1.0, FALSE); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); for (i = 0; i < 2; i++) { gint col1 = gwy_data_field_rtoj(dfield, i1[i].x); gint row1 = gwy_data_field_rtoi(dfield, i1[i].y); gint col2 = gwy_data_field_rtoj(dfield, i2[i].x); gint row2 = gwy_data_field_rtoi(dfield, i2[i].y); gwy_data_field_get_profile(dfield, dline, CLAMP(col1, 0, xres-1), CLAMP(row1, 0, yres-1), CLAMP(col2, 0, xres-1), CLAMP(row2, 0, yres-1), -1, 1, GWY_INTERPOLATION_BILINEAR); gwy_data_line_set_offset(dline, i1[i].t/(i2[i].t - i1[i].t) * gwy_data_line_get_real(dline)); gcmodel = gwy_graph_model_get_curve(gmodel, i); gwy_graph_curve_model_set_data_from_dataline(gcmodel, dline, 0, 0); } g_object_unref(dline); return TRUE; }
static void gwy_graph_data_update_ncurves(GwyGraphData *graph_data) { GwyGraphDataCurve *curve; GtkTreeView *treeview; GtkTreeViewColumn *column; GtkWidget *table, *label; guint i, ncolumns, ncurves = 0; ncolumns = graph_data->curves->len; gwy_debug("old ncurves: %d", ncolumns); /* Reconnect all signals just to be sure. * GraphModel is a bit cagey when changes in its curves are regarded */ for (i = 0; i < graph_data->curves->len; i++) { curve = &g_array_index(graph_data->curves, GwyGraphDataCurve, i); gwy_signal_handler_disconnect(curve->gcmodel, curve->changed_id); gwy_object_unref(curve->gcmodel); } g_array_set_size(graph_data->curves, 0); if (graph_data->graph_model) { GwyGraphDataCurve newcurve; ncurves = gwy_graph_model_get_n_curves(graph_data->graph_model); for (i = 0; i < ncurves; i++) { newcurve.gcmodel = gwy_graph_model_get_curve(graph_data->graph_model, i); g_object_ref(newcurve.gcmodel); newcurve.changed_id = g_signal_connect_swapped (newcurve.gcmodel, "data-changed", G_CALLBACK(gwy_graph_data_update_nrows), graph_data); g_array_append_val(graph_data->curves, newcurve); } } gwy_debug("ncurves: %d", ncurves); /* Update the number of columns. */ treeview = GTK_TREE_VIEW(graph_data); while (ncolumns > ncurves) { ncolumns--; gwy_debug("removing column %d", ncolumns); column = gtk_tree_view_get_column(treeview, ncolumns); gtk_tree_view_remove_column(treeview, column); } while (ncolumns < ncurves) { GtkRequisition req; GtkWidget *align; gwy_debug("adding column %d", ncolumns); column = gtk_tree_view_column_new(); g_object_set_qdata(G_OBJECT(column), quark_id, GINT_TO_POINTER(ncolumns)); gwy_graph_data_pack_renderer(graph_data, column, 0); gwy_graph_data_pack_renderer(graph_data, column, 1); table = gtk_table_new(2, 2, TRUE); label = gtk_label_new(NULL); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 2, 0, 1); label = gtk_label_new(NULL); gtk_label_set_width_chars(GTK_LABEL(label), COL_WIDTH); gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2); label = gtk_label_new(NULL); gtk_label_set_width_chars(GTK_LABEL(label), COL_WIDTH); gtk_table_attach_defaults(GTK_TABLE(table), label, 1, 2, 1, 2); gtk_widget_show_all(table); gtk_tree_view_column_set_widget(column, table); gtk_widget_size_request(table, &req); g_object_set(column, "sizing", GTK_TREE_VIEW_COLUMN_FIXED, "fixed-width", req.width, NULL); gtk_tree_view_append_column(treeview, column); align = gtk_widget_get_parent(table); /* XXX: The alignment is Gtk+'s private widget. */ if (align && GTK_IS_ALIGNMENT(align)) { g_signal_connect(align, "notify::xscale", G_CALLBACK(fix_xscale), NULL); fix_xscale(align); } ncolumns++; } if (graph_data->graph_model) gwy_graph_data_update_headers(graph_data); if (graph_data->store) gwy_graph_data_update_nrows(graph_data); }