summaryrefslogtreecommitdiffstats
path: root/plug-ins/gimpressionist/orientmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'plug-ins/gimpressionist/orientmap.c')
-rw-r--r--plug-ins/gimpressionist/orientmap.c717
1 files changed, 717 insertions, 0 deletions
diff --git a/plug-ins/gimpressionist/orientmap.c b/plug-ins/gimpressionist/orientmap.c
new file mode 100644
index 0000000..1b8b765
--- /dev/null
+++ b/plug-ins/gimpressionist/orientmap.c
@@ -0,0 +1,717 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * 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 <gtk/gtk.h>
+
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+
+#include "gimpressionist.h"
+#include "ppmtool.h"
+#include "infile.h"
+
+#include "preview.h"
+
+#include "orientmap.h"
+
+#include "libgimp/stdplugins-intl.h"
+
+#define NUMVECTYPES 4
+
+static GtkWidget *orient_map_window;
+
+static GtkWidget *vector_preview;
+static GtkWidget *orient_map_preview_prev;
+static GtkWidget *prev_button;
+static GtkWidget *next_button;
+static GtkWidget *add_button;
+static GtkWidget *kill_button;
+static GtkAdjustment *vector_preview_brightness_adjust = NULL;
+
+static GtkAdjustment *angle_adjust = NULL;
+static GtkAdjustment *strength_adjust = NULL;
+static GtkAdjustment *orient_map_str_exp_adjust = NULL;
+static GtkAdjustment *angle_offset_adjust = NULL;
+static GtkWidget *vector_types[NUMVECTYPES];
+static GtkWidget *orient_voronoi = NULL;
+
+#define OMWIDTH 150
+#define OMHEIGHT 150
+
+static vector_t vector[MAXORIENTVECT];
+static gint num_vectors = 0;
+static gint vector_type;
+
+static ppm_t update_om_preview_nbuffer = {0, 0, NULL};
+
+static gint selectedvector = 0;
+static ppm_t update_vector_preview_backup = {0, 0, NULL};
+static ppm_t update_vector_preview_buffer = {0, 0, NULL};
+
+static gboolean adjignore = FALSE;
+
+double get_direction (double x, double y, int from)
+{
+ gint i;
+ gint n;
+ gint voronoi;
+ gdouble sum, dx, dy, dst;
+ vector_t *vec;
+ gdouble angoff, strexp;
+ gint first = 0, last;
+
+ if (from == 0)
+ {
+ n = num_vectors;
+ vec = vector;
+ angoff = gtk_adjustment_get_value (angle_offset_adjust);
+ strexp = gtk_adjustment_get_value (orient_map_str_exp_adjust);
+ voronoi = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (orient_voronoi));
+ }
+ else
+ {
+ n = pcvals.num_orient_vectors;
+ vec = pcvals.orient_vectors;
+ angoff = pcvals.orient_angle_offset;
+ strexp = pcvals.orient_strength_exponent;
+ voronoi = pcvals.orient_voronoi;
+ }
+
+ if (voronoi)
+ {
+ gdouble bestdist = -1.0;
+
+ for (i = 0; i < n; i++)
+ {
+ dst = dist (x,y,vec[i].x,vec[i].y);
+
+ if ((bestdist < 0.0) || (dst < bestdist))
+ {
+ bestdist = dst;
+ first = i;
+ }
+ }
+ last = first+1;
+ }
+ else
+ {
+ first = 0;
+ last = n;
+ }
+
+ dx = dy = 0.0;
+ sum = 0.0;
+ for (i = first; i < last; i++)
+ {
+ gdouble s = vec[i].str;
+ gdouble tx = 0.0, ty = 0.0;
+
+ if (vec[i].type == 0)
+ {
+ tx = vec[i].dx;
+ ty = vec[i].dy;
+ }
+ else if (vec[i].type == 1)
+ {
+ gdouble a = atan2 (vec[i].dy, vec[i].dx);
+
+ a -= atan2 (y-vec[i].y, x-vec[i].x);
+ tx = sin (a + G_PI_2);
+ ty = cos (a + G_PI_2);
+ }
+ else if (vec[i].type == 2)
+ {
+ gdouble a = atan2 (vec[i].dy, vec[i].dx);
+
+ a += atan2 (y-vec[i].y, x-vec[i].x);
+ tx = sin (a + G_PI_2);
+ ty = cos (a + G_PI_2);
+ }
+ else if (vec[i].type == 3)
+ {
+ gdouble a = atan2 (vec[i].dy, vec[i].dx);
+
+ a -= atan2 (y-vec[i].y, x-vec[i].x)*2;
+ tx = sin (a + G_PI_2);
+ ty = cos (a + G_PI_2);
+ }
+
+ dst = dist (x,y,vec[i].x,vec[i].y);
+ dst = pow (dst, strexp);
+
+ if (dst < 0.0001)
+ dst = 0.0001;
+ s = s / dst;
+
+ dx += tx * s;
+ dy += ty * s;
+ sum += s;
+ }
+ dx = dx / sum;
+ dy = dy / sum;
+
+ return 90 - (gimp_rad_to_deg (atan2 (dy, dx)) + angoff);
+}
+
+static void
+update_orient_map_preview_prev (void)
+{
+ int x, y;
+ guchar black[3] = {0, 0, 0};
+ guchar gray[3] = {120, 120, 120};
+ guchar white[3] = {255, 255, 255};
+
+ if (!PPM_IS_INITED (&update_om_preview_nbuffer))
+ ppm_new (&update_om_preview_nbuffer,OMWIDTH,OMHEIGHT);
+
+ fill (&update_om_preview_nbuffer, black);
+
+ for (y = 6; y < OMHEIGHT-4; y += 10)
+ for (x = 6; x < OMWIDTH-4; x += 10)
+ {
+ double dir =
+ gimp_deg_to_rad (get_direction (x / (double)OMWIDTH,
+ y / (double)OMHEIGHT,0));
+ double xo = sin (dir) * 4.0;
+ double yo = cos (dir) * 4.0;
+ ppm_drawline (&update_om_preview_nbuffer,
+ x - xo, y - yo, x + xo, y + yo,
+ gray);
+ ppm_put_rgb (&update_om_preview_nbuffer,
+ x - xo, y - yo,
+ white);
+ }
+
+ gimp_preview_area_draw (GIMP_PREVIEW_AREA (orient_map_preview_prev),
+ 0, 0, OMWIDTH, OMHEIGHT,
+ GIMP_RGB_IMAGE,
+ (guchar *)update_om_preview_nbuffer.col,
+ OMWIDTH * 3);
+
+ gtk_widget_queue_draw (orient_map_preview_prev);
+
+ gtk_widget_set_sensitive (prev_button, (num_vectors > 1));
+ gtk_widget_set_sensitive (next_button, (num_vectors > 1));
+ gtk_widget_set_sensitive (add_button, (num_vectors < MAXORIENTVECT));
+ gtk_widget_set_sensitive (kill_button, (num_vectors > 1));
+}
+
+static void
+update_vector_prev (void)
+{
+ static gint ok = 0;
+ gint i, x, y;
+ gdouble dir, xo, yo;
+ gdouble val;
+ static gdouble last_val = 0.0;
+ guchar gray[3] = {120, 120, 120};
+ guchar red[3] = {255, 0, 0};
+ guchar white[3] = {255, 255, 255};
+
+ if (vector_preview_brightness_adjust)
+ val = 1.0 - gtk_adjustment_get_value (vector_preview_brightness_adjust) / 100.0;
+ else
+ val = 0.5;
+
+ if (!ok || (val != last_val))
+ {
+ infile_copy_to_ppm (&update_vector_preview_backup);
+ ppm_apply_brightness (&update_vector_preview_backup, val, 1,1,1);
+
+ if ((update_vector_preview_backup.width != OMWIDTH) ||
+ (update_vector_preview_backup.height != OMHEIGHT))
+ resize_fast (&update_vector_preview_backup, OMWIDTH, OMHEIGHT);
+ ok = 1;
+ }
+ ppm_copy (&update_vector_preview_backup, &update_vector_preview_buffer);
+
+ for (i = 0; i < num_vectors; i++)
+ {
+ gdouble s;
+
+ x = vector[i].x * OMWIDTH;
+ y = vector[i].y * OMHEIGHT;
+ dir = gimp_deg_to_rad (vector[i].dir);
+ s = gimp_deg_to_rad (vector[i].str);
+ xo = sin (dir) * (6.0+100*s);
+ yo = cos (dir) * (6.0+100*s);
+
+ if (i == selectedvector)
+ {
+ ppm_drawline (&update_vector_preview_buffer,
+ x - xo, y - yo, x + xo, y + yo, red);
+ }
+ else
+ {
+ ppm_drawline (&update_vector_preview_buffer,
+ x - xo, y - yo, x + xo, y + yo, gray);
+ }
+ ppm_put_rgb (&update_vector_preview_buffer, x - xo, y - yo, white);
+ }
+
+ gimp_preview_area_draw (GIMP_PREVIEW_AREA (vector_preview),
+ 0, 0, OMWIDTH, OMHEIGHT,
+ GIMP_RGB_IMAGE,
+ (guchar *)update_vector_preview_buffer.col,
+ OMWIDTH * 3);
+}
+
+void
+orientation_map_free_resources (void)
+{
+ ppm_kill (&update_om_preview_nbuffer);
+ ppm_kill (&update_vector_preview_backup);
+ ppm_kill (&update_vector_preview_buffer);
+}
+
+static void
+update_slides (void)
+{
+ gint type;
+
+ adjignore = TRUE;
+ gtk_adjustment_set_value (angle_adjust, vector[selectedvector].dir);
+ gtk_adjustment_set_value (strength_adjust, vector[selectedvector].str);
+ type = vector[selectedvector].type;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (vector_types[type]), TRUE);
+ adjignore = FALSE;
+}
+
+static void
+prev_click_callback (GtkWidget *w, gpointer data)
+{
+ selectedvector--;
+ if (selectedvector < 0)
+ selectedvector = num_vectors-1;
+ update_slides ();
+ update_vector_prev ();
+}
+
+static void
+next_click_callback (GtkWidget *w, gpointer data)
+{
+ selectedvector++;
+ if (selectedvector == num_vectors) selectedvector = 0;
+ update_slides ();
+ update_vector_prev ();
+}
+
+static void
+add_new_vector (gdouble x, gdouble y)
+{
+ vector[num_vectors].x = x;
+ vector[num_vectors].y = y;
+ vector[num_vectors].dir = 0.0;
+ vector[num_vectors].dx = sin (gimp_deg_to_rad (0.0));
+ vector[num_vectors].dy = cos (gimp_deg_to_rad (0.0));
+ vector[num_vectors].str = 1.0;
+ vector[num_vectors].type = 0;
+ selectedvector = num_vectors;
+ num_vectors++;
+}
+
+static void
+add_click_callback (GtkWidget *w, gpointer data)
+{
+ add_new_vector (0.5, 0.5);
+ update_slides ();
+ update_vector_prev ();
+ update_orient_map_preview_prev ();
+}
+
+static void
+delete_click_callback (GtkWidget *w, gpointer data)
+{
+ int i;
+
+ for (i = selectedvector; i < num_vectors-1; i++)
+ vector[i] = vector[i + 1];
+
+ num_vectors--;
+
+ if (selectedvector >= num_vectors) selectedvector = 0;
+ update_slides ();
+ update_vector_prev ();
+ update_orient_map_preview_prev ();
+}
+
+static void
+map_click_callback (GtkWidget *w, GdkEventButton *event)
+{
+ if (event->button == 1)
+ {
+ vector[selectedvector].x = event->x / (double)OMWIDTH;
+ vector[selectedvector].y = event->y / (double)OMHEIGHT;
+ }
+ else if (event->button == 2)
+ {
+ if (num_vectors + 1 == MAXORIENTVECT)
+ return;
+ add_new_vector (event->x / (double)OMWIDTH,
+ event->y / (double)OMHEIGHT);
+ update_slides ();
+
+ }
+ else if (event->button == 3)
+ {
+ gdouble d;
+
+ d = atan2 (OMWIDTH * vector[selectedvector].x - event->x,
+ OMHEIGHT * vector[selectedvector].y - event->y);
+ vector[selectedvector].dir = gimp_rad_to_deg (d);
+ vector[selectedvector].dx = sin (d);
+ vector[selectedvector].dy = cos (d);
+ update_slides ();
+ }
+ update_vector_prev ();
+ update_orient_map_preview_prev ();
+}
+
+static void
+angle_adjust_move_callback (GtkWidget *w, gpointer data)
+{
+ if (adjignore)
+ return;
+ vector[selectedvector].dir = gtk_adjustment_get_value (angle_adjust);
+ vector[selectedvector].dx =
+ sin (gimp_deg_to_rad (vector[selectedvector].dir));
+ vector[selectedvector].dy =
+ cos (gimp_deg_to_rad (vector[selectedvector].dir));
+ update_vector_prev ();
+ update_orient_map_preview_prev ();
+}
+
+static void
+strength_adjust_move_callback (GtkWidget *w, gpointer data)
+{
+ if (adjignore)
+ return;
+ vector[selectedvector].str = gtk_adjustment_get_value (strength_adjust);
+ update_vector_prev ();
+ update_orient_map_preview_prev ();
+}
+
+static void
+strength_exponent_adjust_move_callback (GtkWidget *w, gpointer data)
+{
+ if (adjignore)
+ return;
+ update_vector_prev ();
+ update_orient_map_preview_prev ();
+}
+
+static void
+angle_offset_adjust_move_callback (GtkWidget *w, gpointer data)
+{
+ if (adjignore)
+ return;
+ update_vector_prev ();
+ update_orient_map_preview_prev ();
+}
+
+static void
+vector_type_click_callback (GtkWidget *w, gpointer data)
+{
+ if (adjignore)
+ return;
+
+ gimp_radio_button_update (w, data);
+ vector[selectedvector].type = vector_type;
+ update_vector_prev ();
+ update_orient_map_preview_prev ();
+}
+
+static void
+orient_map_response (GtkWidget *widget,
+ gint response_id,
+ gpointer data)
+{
+ switch (response_id)
+ {
+ case GTK_RESPONSE_APPLY:
+ case GTK_RESPONSE_OK:
+ {
+ gint i;
+
+ for (i = 0; i < num_vectors; i++)
+ pcvals.orient_vectors[i] = vector[i];
+
+ pcvals.num_orient_vectors = num_vectors;
+ pcvals.orient_strength_exponent = gtk_adjustment_get_value (orient_map_str_exp_adjust);
+ pcvals.orient_angle_offset = gtk_adjustment_get_value (angle_offset_adjust);
+ pcvals.orient_voronoi = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (orient_voronoi));
+ }
+ };
+
+ if (response_id != GTK_RESPONSE_APPLY)
+ gtk_widget_hide (widget);
+}
+
+static void
+init_vectors (void)
+{
+ if (pcvals.num_orient_vectors)
+ {
+ gint i;
+
+ num_vectors = pcvals.num_orient_vectors;
+ for (i = 0; i < num_vectors; i++)
+ vector[i] = pcvals.orient_vectors[i];
+ }
+ else
+ {/* Shouldn't happen */
+ num_vectors = 0;
+ add_new_vector (0.5, 0.5);
+ }
+ if (selectedvector >= num_vectors)
+ selectedvector = num_vectors-1;
+}
+
+void
+update_orientmap_dialog (void)
+{
+ if (!orient_map_window) return;
+
+ init_vectors ();
+
+ gtk_adjustment_set_value (orient_map_str_exp_adjust,
+ pcvals.orient_strength_exponent);
+ gtk_adjustment_set_value (angle_offset_adjust,
+ pcvals.orient_angle_offset);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (orient_voronoi),
+ pcvals.orient_voronoi);
+
+ update_vector_prev ();
+ update_orient_map_preview_prev ();
+}
+
+void
+create_orientmap_dialog (GtkWidget *parent)
+{
+ GtkWidget *tmpw, *tmpw2;
+ GtkWidget *table1, *table2;
+ GtkWidget *frame;
+ GtkWidget *ebox, *hbox, *vbox;
+
+ init_vectors ();
+
+ if (orient_map_window)
+ {
+ update_vector_prev ();
+ update_orient_map_preview_prev ();
+ gtk_widget_show (orient_map_window);
+ return;
+ }
+
+ orient_map_window =
+ gimp_dialog_new (_("Orientation Map Editor"), PLUG_IN_ROLE,
+ gtk_widget_get_toplevel (parent), 0,
+ gimp_standard_help_func, PLUG_IN_PROC,
+
+ _("_Apply"), GTK_RESPONSE_APPLY,
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ _("_OK"), GTK_RESPONSE_OK,
+
+ NULL);
+
+ gtk_dialog_set_alternative_button_order (GTK_DIALOG (orient_map_window),
+ GTK_RESPONSE_OK,
+ GTK_RESPONSE_APPLY,
+ GTK_RESPONSE_CANCEL,
+ -1);
+
+ g_signal_connect (orient_map_window, "response",
+ G_CALLBACK (orient_map_response),
+ orient_map_window);
+ g_signal_connect (orient_map_window, "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &orient_map_window);
+
+ table1 = gtk_table_new (2, 5, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (table1), 6);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (orient_map_window))),
+ table1, TRUE, TRUE, 0);
+ gtk_widget_show (table1);
+
+ frame = gtk_frame_new (_("Vectors"));
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 2);
+ gtk_table_attach (GTK_TABLE (table1), frame, 0, 1, 0, 1,
+ GTK_EXPAND, GTK_EXPAND, 0, 0);
+ gtk_widget_show (frame);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+ gtk_widget_show (hbox);
+
+ ebox = gtk_event_box_new ();
+ gimp_help_set_help_data (ebox,
+ _("The vector-field. "
+ "Left-click to move selected vector, "
+ "Right-click to point it towards mouse, "
+ "Middle-click to add a new vector."), NULL);
+ gtk_box_pack_start (GTK_BOX (hbox), ebox, FALSE, FALSE, 0);
+
+ tmpw = vector_preview = gimp_preview_area_new ();
+ gtk_widget_set_size_request (tmpw, OMWIDTH, OMHEIGHT);
+ gtk_container_add (GTK_CONTAINER (ebox), tmpw);
+ gtk_widget_show (tmpw);
+ gtk_widget_add_events (ebox, GDK_BUTTON_PRESS_MASK);
+ g_signal_connect (ebox, "button-press-event",
+ G_CALLBACK (map_click_callback), NULL);
+ gtk_widget_show (ebox);
+
+ vector_preview_brightness_adjust = (GtkAdjustment *)
+ gtk_adjustment_new (50.0, 0.0, 100.0, 1.0, 1.0, 1.0);
+ tmpw = gtk_scale_new (GTK_ORIENTATION_VERTICAL,
+ vector_preview_brightness_adjust);
+ gtk_scale_set_draw_value (GTK_SCALE (tmpw), FALSE);
+ gtk_box_pack_start (GTK_BOX (hbox), tmpw, FALSE, FALSE,0);
+ gtk_widget_show (tmpw);
+ g_signal_connect (vector_preview_brightness_adjust, "value-changed",
+ G_CALLBACK (update_vector_prev), NULL);
+ gimp_help_set_help_data (tmpw, _("Adjust the preview's brightness"), NULL);
+
+ tmpw2 = tmpw = gtk_frame_new (_("Preview"));
+ gtk_container_set_border_width (GTK_CONTAINER (tmpw), 2);
+ gtk_table_attach (GTK_TABLE (table1), tmpw, 1,2, 0,1,
+ GTK_EXPAND, GTK_EXPAND, 0, 0);
+ gtk_widget_show (tmpw);
+
+ tmpw = orient_map_preview_prev = gimp_preview_area_new ();
+ gtk_widget_set_size_request (tmpw, OMWIDTH, OMHEIGHT);
+ gtk_container_add (GTK_CONTAINER (tmpw2), tmpw);
+ gtk_widget_show (tmpw);
+
+ hbox = tmpw = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
+ gtk_container_set_border_width (GTK_CONTAINER (tmpw), 2);
+ gtk_table_attach_defaults (GTK_TABLE (table1), tmpw, 0,1, 1,2);
+ gtk_widget_show (tmpw);
+
+ prev_button = tmpw = gtk_button_new_with_mnemonic ("_<<");
+ gtk_box_pack_start (GTK_BOX (hbox), tmpw, FALSE, TRUE, 0);
+ gtk_widget_show (tmpw);
+ g_signal_connect (tmpw, "clicked", G_CALLBACK (prev_click_callback), NULL);
+ gimp_help_set_help_data (tmpw, _("Select previous vector"), NULL);
+
+ next_button = tmpw = gtk_button_new_with_mnemonic ("_>>");
+ gtk_box_pack_start (GTK_BOX (hbox),tmpw,FALSE,TRUE,0);
+ gtk_widget_show (tmpw);
+ g_signal_connect (tmpw, "clicked", G_CALLBACK (next_click_callback), NULL);
+ gimp_help_set_help_data (tmpw, _("Select next vector"), NULL);
+
+ add_button = tmpw = gtk_button_new_with_mnemonic ( _("A_dd"));
+ gtk_box_pack_start (GTK_BOX (hbox), tmpw, FALSE, TRUE, 0);
+ gtk_widget_show (tmpw);
+ g_signal_connect (tmpw, "clicked", G_CALLBACK (add_click_callback), NULL);
+ gimp_help_set_help_data (tmpw, _("Add new vector"), NULL);
+
+ kill_button = tmpw = gtk_button_new_with_mnemonic ( _("_Kill"));
+ gtk_box_pack_start (GTK_BOX (hbox), tmpw, FALSE, TRUE, 0);
+ gtk_widget_show (tmpw);
+ g_signal_connect (tmpw, "clicked", G_CALLBACK (delete_click_callback), NULL);
+ gimp_help_set_help_data (tmpw, _("Delete selected vector"), NULL);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ gtk_box_set_spacing (GTK_BOX (hbox), 12);
+ gtk_table_attach_defaults (GTK_TABLE (table1), hbox, 0, 2, 2, 3);
+ gtk_widget_show (hbox);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+ gtk_widget_show (vbox);
+
+ frame = gimp_int_radio_group_new (TRUE, _("Type"),
+ G_CALLBACK (vector_type_click_callback),
+ &vector_type, 0,
+
+ _("_Normal"), 0, &vector_types[0],
+ _("Vorte_x"), 1, &vector_types[1],
+ _("Vortex_2"), 2, &vector_types[2],
+ _("Vortex_3"), 3, &vector_types[3],
+
+ NULL);
+ gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, 0);
+ gtk_widget_show (frame);
+
+ orient_voronoi = tmpw = gtk_check_button_new_with_mnemonic ( _("_Voronoi"));
+ gtk_box_pack_start (GTK_BOX (vbox), tmpw, TRUE, TRUE, 0);
+ gtk_widget_show (tmpw);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tmpw),
+ pcvals.orient_voronoi);
+ g_signal_connect (tmpw, "clicked",
+ G_CALLBACK (angle_offset_adjust_move_callback), NULL);
+ gimp_help_set_help_data (tmpw,
+ _("Voronoi-mode makes only the vector closest to the given point have any influence"),
+ NULL);
+
+ table2 = gtk_table_new (4, 3, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table2), 4);
+ gtk_box_pack_start (GTK_BOX (hbox), table2, TRUE, TRUE, 0);
+ gtk_widget_show (table2);
+
+ angle_adjust = (GtkAdjustment *)
+ gimp_scale_entry_new (GTK_TABLE (table2), 0, 0,
+ _("A_ngle:"),
+ 150, 6, 0.0,
+ 0.0, 360.0, 1.0, 10.0, 1,
+ TRUE, 0, 0,
+ _("Change the angle of the selected vector"),
+ NULL);
+ g_signal_connect (angle_adjust, "value-changed",
+ G_CALLBACK (angle_adjust_move_callback), NULL);
+
+ angle_offset_adjust = (GtkAdjustment *)
+ gimp_scale_entry_new (GTK_TABLE (table2), 0, 1,
+ _("Ang_le offset:"),
+ 150, 6, 0.0,
+ 0.0, 360.0, 1.0, 10.0, 1,
+ TRUE, 0, 0,
+ _("Offset all vectors with a given angle"),
+ NULL);
+ g_signal_connect (angle_offset_adjust, "value-changed",
+ G_CALLBACK (angle_offset_adjust_move_callback), NULL);
+
+ strength_adjust = (GtkAdjustment *)
+ gimp_scale_entry_new (GTK_TABLE (table2), 0, 2,
+ _("_Strength:"),
+ 150, 6, 1.0,
+ 0.1, 5.0, 0.1, 1.0, 1,
+ TRUE, 0, 0,
+ _("Change the strength of the selected vector"),
+ NULL);
+ g_signal_connect (strength_adjust, "value-changed",
+ G_CALLBACK (strength_adjust_move_callback), NULL);
+
+ orient_map_str_exp_adjust = (GtkAdjustment *)
+ gimp_scale_entry_new (GTK_TABLE (table2), 0, 3,
+ _("S_trength exp.:"),
+ 150, 6, 1.0,
+ 0.1, 10.9, 0.1, 1.0, 1,
+ TRUE, 0, 0,
+ _("Change the exponent of the strength"),
+ NULL);
+ g_signal_connect (orient_map_str_exp_adjust, "value-changed",
+ G_CALLBACK (strength_exponent_adjust_move_callback), NULL);
+
+ gtk_widget_show (orient_map_window);
+
+ update_vector_prev ();
+ update_orient_map_preview_prev ();
+}