diff options
Diffstat (limited to 'app/propgui/gimppropgui-convolution-matrix.c')
-rw-r--r-- | app/propgui/gimppropgui-convolution-matrix.c | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/app/propgui/gimppropgui-convolution-matrix.c b/app/propgui/gimppropgui-convolution-matrix.c new file mode 100644 index 0000000..7a5635e --- /dev/null +++ b/app/propgui/gimppropgui-convolution-matrix.c @@ -0,0 +1,309 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis + * + * gimppropgui-convolution-matrix.c + * Copyright (C) 2002-2014 Michael Natterer <mitch@gimp.org> + * Sven Neumann <sven@gimp.org> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <gegl.h> +#include <gtk/gtk.h> + +#include "libgimpwidgets/gimpwidgets.h" + +#include "propgui-types.h" + +#include "core/gimpcontext.h" + +#include "gimppropgui.h" +#include "gimppropgui-convolution-matrix.h" +#include "gimppropgui-generic.h" + +#include "gimp-intl.h" + + +static const gchar * +convolution_matrix_prop_name (gint x, + gint y) +{ + static const gchar * const prop_names[5][5] = { + {"a1", "a2", "a3", "a4", "a5"}, + {"b1", "b2", "b3", "b4", "b5"}, + {"c1", "c2", "c3", "c4", "c5"}, + {"d1", "d2", "d3", "d4", "d5"}, + {"e1", "e2", "e3", "e4", "e5"}}; + + return prop_names[x][y]; +} + +static void +convolution_matrix_rotate_flip (GtkWidget *button, + GObject *config) +{ + gint rotate = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), + "convolution-matrix-rotate")); + gint flip = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), + "convolution-matrix-flip")); + gint x, y; + + while (rotate--) + { + for (y = 0; y < 2; y++) + { + for (x = y; x < 4 - y; x++) + { + gint i; + gdouble temp; + + g_object_get (config, + convolution_matrix_prop_name (x, y), &temp, + NULL); + + for (i = 0; i < 4; i++) + { + gint next_x, next_y; + gdouble val; + + next_x = 4 - y; + next_y = x; + + if (i < 3) + { + g_object_get (config, + convolution_matrix_prop_name (next_x, next_y), &val, + NULL); + } + else + { + val = temp; + } + + g_object_set (config, + convolution_matrix_prop_name (x, y), val, + NULL); + + x = next_x; + y = next_y; + } + } + } + } + + while (flip--) + { + for (y = 0; y < 5; y++) + { + for (x = 0; x < 2; x++) + { + gdouble val1, val2; + + g_object_get (config, + convolution_matrix_prop_name (x, y), &val1, + NULL); + g_object_get (config, + convolution_matrix_prop_name (4 - x, y), &val2, + NULL); + + g_object_set (config, + convolution_matrix_prop_name (x, y), val2, + NULL); + g_object_set (config, + convolution_matrix_prop_name (4 - x, y), val1, + NULL); + } + } + } +} + +GtkWidget * +_gimp_prop_gui_new_convolution_matrix (GObject *config, + GParamSpec **param_specs, + guint n_param_specs, + GeglRectangle *area, + GimpContext *context, + GimpCreatePickerFunc create_picker_func, + GimpCreateControllerFunc create_controller_func, + gpointer creator) +{ + GtkWidget *main_vbox; + GtkWidget *vbox; + GtkWidget *table; + GtkWidget *hbox; + GtkWidget *scale; + GtkWidget *vbox2; + const gchar *label; + gint x, y; + + g_return_val_if_fail (G_IS_OBJECT (config), NULL); + g_return_val_if_fail (param_specs != NULL, NULL); + g_return_val_if_fail (n_param_specs > 0, NULL); + g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); + + main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8); + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0); + gtk_widget_show (vbox); + + /* matrix */ + + table = gtk_table_new (5, 5, TRUE); + gtk_table_set_row_spacings (GTK_TABLE (table), 2); + gtk_table_set_col_spacings (GTK_TABLE (table), 4); + gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); + gtk_widget_show (table); + + for (y = 0; y < 5; y++) + { + for (x = 0; x < 5; x++) + { + GtkWidget *spin; + + spin = gimp_prop_spin_button_new (config, + convolution_matrix_prop_name (x, y), + 1.0, 10.0, 2); + gtk_entry_set_width_chars (GTK_ENTRY (spin), 8); + gtk_table_attach (GTK_TABLE (table), spin, + x, x + 1, y, y + 1, + GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, + 0, 0); + gtk_widget_show (spin); + } + } + + /* rotate / flip buttons */ + { + typedef struct + { + const gchar *tooltip; + const gchar *icon_name; + gint rotate; + gint flip; + } ButtonInfo; + + gint i; + const ButtonInfo buttons[] = { + { + .tooltip = _("Rotate matrix 90° counter-clockwise"), + .icon_name = GIMP_ICON_OBJECT_ROTATE_270, + .rotate = 1, + .flip = 0 + }, + { + .tooltip = _("Rotate matrix 90° clockwise"), + .icon_name = GIMP_ICON_OBJECT_ROTATE_90, + .rotate = 3, + .flip = 0 + }, + { + .tooltip = _("Flip matrix horizontally"), + .icon_name = GIMP_ICON_OBJECT_FLIP_HORIZONTAL, + .rotate = 0, + .flip = 1 + }, + { + .tooltip = _("Flip matrix vertically"), + .icon_name = GIMP_ICON_OBJECT_FLIP_VERTICAL, + .rotate = 2, + .flip = 1 + }}; + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + for (i = 0; i < G_N_ELEMENTS (buttons); i++) + { + const ButtonInfo *info = &buttons[i]; + GtkWidget *button; + GtkWidget *image; + + button = gtk_button_new (); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); + gtk_widget_set_tooltip_text (button, info->tooltip); + gtk_widget_set_can_focus (button, FALSE); + gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); + gtk_widget_show (button); + + image = gtk_image_new_from_icon_name (info->icon_name, + GTK_ICON_SIZE_BUTTON); + gtk_container_add (GTK_CONTAINER (button), image); + gtk_widget_show (image); + + g_object_set_data (G_OBJECT (button), + "convolution-matrix-rotate", + GINT_TO_POINTER (info->rotate)); + g_object_set_data (G_OBJECT (button), + "convolution-matrix-flip", + GINT_TO_POINTER (info->flip)); + + g_signal_connect (button, "clicked", + G_CALLBACK (convolution_matrix_rotate_flip), + config); + } + } + + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + gtk_box_pack_start (GTK_BOX (main_vbox), vbox, FALSE, FALSE, 0); + gtk_widget_show (vbox); + + /* divisor / offset spin scales */ + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); + gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + scale = gimp_prop_widget_new (config, "divisor", + area, context, NULL, NULL, NULL, &label); + gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0); + gtk_widget_show (scale); + + scale = gimp_prop_widget_new (config, "offset", + area, context, NULL, NULL, NULL, &label); + gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0); + gtk_widget_show (scale); + + /* rest of the properties */ + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); + gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + vbox2 = _gimp_prop_gui_new_generic (config, + param_specs + 27, 4, + area, context, + create_picker_func, + create_controller_func, + creator); + gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0); + gtk_widget_show (vbox2); + + vbox2 = _gimp_prop_gui_new_generic (config, + param_specs + 31, + n_param_specs - 31, + area, context, + create_picker_func, + create_controller_func, + creator); + gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0); + gtk_widget_show (vbox2); + + return main_vbox; +} |