예제 #1
0
static void
preview(GEdgeControls *controls,
        GEdgeArgs *args)
{
    GwyDataField *mask, *dfield;
    GwyPixmapLayer *layer;

    dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(controls->mydata,
                                                             "/0/data"));

    /* Set up the mask */
    if (!gwy_container_gis_object_by_name(controls->mydata, "/0/mask", &mask)) {
        mask = create_mask_field(dfield);
        gwy_container_set_object_by_name(controls->mydata, "/0/mask", mask);
        g_object_unref(mask);

        layer = gwy_layer_mask_new();
        gwy_pixmap_layer_set_data_key(layer, "/0/mask");
        gwy_layer_mask_set_color_key(GWY_LAYER_MASK(layer), "/0/mask");
        gwy_data_view_set_alpha_layer(GWY_DATA_VIEW(controls->view), layer);
    }
    gwy_data_field_copy(dfield, mask, FALSE);
    gedge_process(dfield, mask, args);
    gwy_data_field_data_changed(mask);
}
예제 #2
0
static void
add_mask_layer(GwyDataView *view,
               const GwyRGBA *color)
{
    GwyContainer *data;
    GwyDataField *mfield, *dfield;
    GwyPixmapLayer *layer;

    data = gwy_data_view_get_data(view);
    if (!gwy_container_gis_object_by_name(data, "/0/mask", &mfield)) {
        gwy_container_gis_object_by_name(data, "/0/data", &dfield);
        mfield = create_mask_field(dfield);
        gwy_container_set_object_by_name(data, "/0/mask", mfield);
        g_object_unref(mfield);

        layer = gwy_layer_mask_new();
        gwy_pixmap_layer_set_data_key(layer, "/0/mask");
        gwy_layer_mask_set_color_key(GWY_LAYER_MASK(layer), "/0/mask");
        gwy_data_view_set_alpha_layer(view, layer);

        if (color)
            gwy_rgba_store_to_container(color, data, "/0/mask");
    }
}
예제 #3
0
static void
gfilter_dialog(GFilterArgs *args,
              GwyContainer *data,
              GwyDataField *dfield,
              GwyDataField *mfield,
              gint id,
              GQuark mquark)
{
    GtkWidget *dialog, *table, *vbox, *hbox, *scwin, *hbox2, *label;
    GtkTreeView *treeview;
    GtkTreeSelection *selection;
    GFilterControls controls;
    gint response, row, i;
    GwySIUnit *siunit;
    GwyPixmapLayer *layer;

    controls.args = args;
    controls.mask = mfield;
    controls.in_init = TRUE;
    controls.computed = FALSE;

    siunit = gwy_si_unit_new(NULL);
    for (i = 0; i < NQUANTITIES; i++) {
        controls.vf[i]
            = gwy_si_unit_get_format_with_digits(siunit,
                                                 GWY_SI_UNIT_FORMAT_VFMARKUP,
                                                 1.0, 4, NULL);
    }
    g_object_unref(siunit);

    dialog = gtk_dialog_new_with_buttons(_("Filter Grains"),
                                         NULL, 0, NULL);
    gtk_dialog_add_action_widget(GTK_DIALOG(dialog),
                                 gwy_stock_like_button_new(_("_Update"),
                                                           GTK_STOCK_EXECUTE),
                                 RESPONSE_PREVIEW);
    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);
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
    gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), RESPONSE_PREVIEW,
                                      !args->update);
    gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT);
    controls.dialog = dialog;

    hbox = gtk_hbox_new(FALSE, 2);

    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 4);

    vbox = gtk_vbox_new(FALSE, 4);
    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);

    controls.mydata = gwy_container_new();
    gwy_container_set_object_by_name(controls.mydata, "/0/data", dfield);
    mfield = gwy_data_field_duplicate(mfield);
    gwy_container_set_object_by_name(controls.mydata, "/0/mask", mfield);
    g_object_unref(mfield);
    gwy_app_sync_data_items(data, controls.mydata, id, 0, FALSE,
                            GWY_DATA_ITEM_PALETTE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            GWY_DATA_ITEM_RANGE,
                            GWY_DATA_ITEM_REAL_SQUARE,
                            0);
    controls.view = gwy_data_view_new(controls.mydata);
    layer = gwy_layer_basic_new();
    g_object_set(layer,
                 "data-key", "/0/data",
                 "gradient-key", "/0/base/palette",
                 "range-type-key", "/0/base/range-type",
                 "min-max-key", "/0/base",
                 NULL);
    gwy_data_view_set_data_prefix(GWY_DATA_VIEW(controls.view), "/0/data");
    gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer);
    layer = gwy_layer_mask_new();
    gwy_pixmap_layer_set_data_key(layer, "/0/mask");
    gwy_layer_mask_set_color_key(GWY_LAYER_MASK(layer), "/0/mask");
    gwy_data_view_set_alpha_layer(GWY_DATA_VIEW(controls.view), layer);
    gwy_set_data_preview_size(GWY_DATA_VIEW(controls.view), PREVIEW_SIZE);

    gtk_box_pack_start(GTK_BOX(vbox), controls.view, FALSE, FALSE, 0);

    controls.update = gtk_check_button_new_with_mnemonic(_("I_nstant updates"));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.update),
                                 args->update);
    gtk_box_pack_start(GTK_BOX(vbox), controls.update, FALSE, FALSE, 0);
    g_signal_connect_swapped(controls.update, "toggled",
                             G_CALLBACK(update_changed), &controls);

    hbox2 = gtk_hbox_new(FALSE, 6);
    gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 0);

    label = gtk_label_new_with_mnemonic(_("_Mask color:"));
    gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);

    controls.color_button = gwy_color_button_new();
    gwy_color_button_set_use_alpha(GWY_COLOR_BUTTON(controls.color_button),
                                   TRUE);
    load_mask_color(controls.color_button,
                    gwy_data_view_get_data(GWY_DATA_VIEW(controls.view)));
    gtk_label_set_mnemonic_widget(GTK_LABEL(label), controls.color_button);
    gtk_box_pack_start(GTK_BOX(hbox2), controls.color_button, FALSE, FALSE, 0);
    g_signal_connect(controls.color_button, "clicked",
                     G_CALLBACK(mask_color_changed), &controls);

    table = gtk_table_new(10, 4, 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_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 4);
    controls.table = table;
    row = 0;

    scwin = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scwin),
                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
    gtk_table_attach(GTK_TABLE(table), scwin, 0, 4, row, row+1,
                     GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);

    controls.values = gwy_grain_value_tree_view_new(FALSE,
                                                    "name", "symbol_markup",
                                                    NULL);
    treeview = GTK_TREE_VIEW(controls.values);
    gtk_widget_set_size_request(scwin, -1, 120);
    gtk_tree_view_set_headers_visible(treeview, FALSE);
    selection = gtk_tree_view_get_selection(treeview);
    gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
    gwy_grain_value_tree_view_set_same_units(treeview, args->units_equal);
    gwy_grain_value_tree_view_set_expanded_groups(treeview, args->expanded);
    gtk_container_add(GTK_CONTAINER(scwin), controls.values);
    row++;

    hbox2 = gtk_hbox_new(FALSE, 0);
    for (i = 0; i < NQUANTITIES; i++) {
        gchar buf[2];
        buf[0] = 'A' + i;
        buf[1] = '\0';
        controls.set_as[i] = gtk_button_new_with_label(buf);
        gtk_box_pack_start(GTK_BOX(hbox2), controls.set_as[i], FALSE, FALSE, 0);
        g_object_set_data(G_OBJECT(controls.set_as[i]),
                          "id", GUINT_TO_POINTER(i));
        g_signal_connect_swapped(controls.set_as[i], "clicked",
                                 G_CALLBACK(set_as_clicked), &controls);
    }
    gwy_table_attach_hscale(table, row++,
                            _("Set selected as:"), NULL,
                            GTK_OBJECT(hbox2), GWY_HSCALE_WIDGET_NO_EXPAND);

    controls.logical_op
        = gwy_enum_combo_box_newl(G_CALLBACK(logical_op_changed), &controls,
                                  args->logical,
                                  "A", GRAIN_LOGICAL_A,
                                  "A ∧ B", GRAIN_LOGICAL_A_AND_B,
                                  "A ∨ B", GRAIN_LOGICAL_A_OR_B,
                                  "A ∧ B ∧ C", GRAIN_LOGICAL_A_AND_B_AND_C,
                                  "A ∨ B ∨ C", GRAIN_LOGICAL_A_OR_B_OR_C,
                                  "(A ∧ B) ∨ C", GRAIN_LOGICAL_A_AND_B_OR_C,
                                  "(A ∨ B) ∧ C", GRAIN_LOGICAL_A_OR_B_AND_C,
                                  NULL);
    gwy_table_attach_hscale(table, row++,
                            _("Keep grains satisfying:"), NULL,
                            GTK_OBJECT(controls.logical_op),
                            GWY_HSCALE_WIDGET);

    for (i = 0; i < NQUANTITIES; i++) {
        gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8);

        controls.header[i] = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(controls.header[i]), 0.0, 0.5);
        gtk_table_attach(GTK_TABLE(table), controls.header[i],
                         0, 4, row, row+1, GTK_FILL, 0, 0, 0);
        row++;

        /* The values are set properly later. */
        controls.lower_label[i] = gtk_label_new(_("Lower threshold:"));
        gtk_misc_set_alignment(GTK_MISC(controls.lower_label[i]), 0.0, 0.5);
        gtk_table_attach(GTK_TABLE(table), controls.lower_label[i],
                         0, 1, row, row+1, GTK_FILL, 0, 0, 0);

        controls.lower[i] = gtk_adjustment_new(0.0, 0.0, 0.0,
                                               1.0, 10.0, 0.0);
        g_object_set_data(G_OBJECT(controls.lower[i]), "id",
                          GUINT_TO_POINTER(i));
        g_signal_connect_swapped(controls.lower[i], "value-changed",
                                 G_CALLBACK(threshold_changed), &controls);
        controls.lower_scale[i]
            = gtk_hscale_new(GTK_ADJUSTMENT(controls.lower[i]));
        gtk_scale_set_draw_value(GTK_SCALE(controls.lower_scale[i]), FALSE);
        gtk_widget_set_size_request(controls.lower_scale[i],
                                    GWY_HSCALE_WIDTH, -1);
        gtk_table_attach(GTK_TABLE(table), controls.lower_scale[i],
                         1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);

        controls.lower_entry[i] = gtk_entry_new();
        gtk_entry_set_width_chars(GTK_ENTRY(controls.lower_entry[i]), 8);
        gtk_table_attach(GTK_TABLE(table), controls.lower_entry[i],
                         2, 3, row, row+1, GTK_FILL, 0, 0, 0);
        gwy_widget_set_activate_on_unfocus(controls.lower_entry[i], TRUE);
        g_object_set_data(G_OBJECT(controls.lower_entry[i]), "id",
                          GUINT_TO_POINTER(i));
        g_signal_connect_swapped(controls.lower_entry[i], "activate",
                                 G_CALLBACK(threshold_activated), &controls);

        controls.lower_units[i] = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(controls.lower_units[i]), 0.0, 0.5);
        gtk_table_attach(GTK_TABLE(table), controls.lower_units[i],
                         3, 4, row, row+1, GTK_FILL, 0, 0, 0);
        row++;

        controls.upper_label[i] = gtk_label_new(_("Upper threshold:"));
        gtk_misc_set_alignment(GTK_MISC(controls.upper_label[i]), 0.0, 0.5);
        gtk_table_attach(GTK_TABLE(table), controls.upper_label[i],
                         0, 1, row, row+1, GTK_FILL, 0, 0, 0);

        controls.upper[i] = gtk_adjustment_new(0.0, 0.0, 0.0,
                                               1.0, 10.0, 0.0);
        g_object_set_data(G_OBJECT(controls.upper[i]), "id",
                          GUINT_TO_POINTER(i | IS_UPPER));
        g_signal_connect_swapped(controls.upper[i], "value-changed",
                                 G_CALLBACK(threshold_changed), &controls);
        controls.upper_scale[i]
            = gtk_hscale_new(GTK_ADJUSTMENT(controls.upper[i]));
        gtk_scale_set_draw_value(GTK_SCALE(controls.upper_scale[i]), FALSE);
        gtk_widget_set_size_request(controls.upper_scale[i],
                                    GWY_HSCALE_WIDTH, -1);
        gtk_table_attach(GTK_TABLE(table), controls.upper_scale[i],
                         1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);

        controls.upper_entry[i] = gtk_entry_new();
        gtk_entry_set_width_chars(GTK_ENTRY(controls.upper_entry[i]), 8);
        gtk_table_attach(GTK_TABLE(table), controls.upper_entry[i],
                         2, 3, row, row+1, GTK_FILL, 0, 0, 0);
        gwy_widget_set_activate_on_unfocus(controls.upper_entry[i], TRUE);
        g_object_set_data(G_OBJECT(controls.upper_entry[i]), "id",
                          GUINT_TO_POINTER(i | IS_UPPER));
        g_signal_connect_swapped(controls.upper_entry[i], "activate",
                                 G_CALLBACK(threshold_activated), &controls);

        controls.upper_units[i] = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(controls.upper_units[i]), 0.0, 0.5);
        gtk_table_attach(GTK_TABLE(table), controls.upper_units[i],
                         3, 4, row, row+1, GTK_FILL, 0, 0, 0);
        row++;
    }

    for (i = 0; i < NQUANTITIES; i++) {
        GwyInventory *inventory;
        GwyGrainValue *gvalue;

        inventory = gwy_grain_values();
        gvalue = gwy_inventory_get_item(inventory, args->ranges[i].quantity);
        set_up_quantity(&controls, gvalue, i);
    }
    logical_op_changed(GTK_COMBO_BOX(controls.logical_op), &controls);

    /* finished initializing, allow instant updates */
    controls.in_init = FALSE;
    gfilter_invalidate(&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:
            args->expanded = gwy_grain_value_tree_view_get_expanded_groups
                                             (GTK_TREE_VIEW(controls.values));
            for (i = 0; i < NQUANTITIES; i++)
                gwy_si_unit_value_format_free(controls.vf[i]);
            gtk_widget_destroy(dialog);
            case GTK_RESPONSE_NONE:
            g_object_unref(controls.mydata);
            gfilter_save_args(gwy_app_settings_get(), args);
            return;
            break;

            case GTK_RESPONSE_OK:
            break;

            case RESPONSE_PREVIEW:
            preview(&controls);
            break;

            default:
            g_assert_not_reached();
            break;
        }
    } while (response != GTK_RESPONSE_OK);

    for (i = 0; i < NQUANTITIES; i++)
        gwy_si_unit_value_format_free(controls.vf[i]);
    args->expanded = gwy_grain_value_tree_view_get_expanded_groups
                                             (GTK_TREE_VIEW(controls.values));
    gwy_app_sync_data_items(controls.mydata, data, 0, id, FALSE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            0);
    gtk_widget_destroy(dialog);

    gfilter_save_args(gwy_app_settings_get(), args);

    if (controls.computed) {
        mfield = gwy_container_get_object_by_name(controls.mydata, "/0/mask");
        gwy_app_undo_qcheckpointv(data, 1, &mquark);
        gwy_container_set_object(data, mquark, mfield);
        g_object_unref(controls.mydata);
    }
    else {
        g_object_unref(controls.mydata);
        run_noninteractive(args, data, controls.mask, mquark);
    }

    gwy_app_channel_log_add_proc(data, id, id);
}