1997-11-25 06:05:25 +08:00
|
|
|
/* The GIMP -- an image manipulation program
|
|
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
|
|
*
|
|
|
|
* Gradient editor module copyight (C) 1996-1997 Federico Mena Quintero
|
|
|
|
* federico@nuclecu.unam.mx
|
|
|
|
*
|
|
|
|
* 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 2 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 PURIGHTE. 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, write to the Free Software
|
1998-04-13 13:44:11 +08:00
|
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
1997-11-25 06:05:25 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* Special thanks to:
|
|
|
|
*
|
|
|
|
* Luis Albarran (luis4@mindspring.com) - Nice UI suggestions
|
|
|
|
*
|
|
|
|
* Miguel de Icaza (miguel@nuclecu.unam.mx) - Pop-up menu suggestion
|
|
|
|
*
|
|
|
|
* Marcelo Malheiros (malheiro@dca.fee.unicamp.br) - many, many
|
|
|
|
* suggestions, nice gradient files
|
|
|
|
*
|
|
|
|
* Adam Moss (adam@uunet.pipex.com) - idea for the hint bar
|
|
|
|
*
|
|
|
|
* Everyone on #gimp - many suggestions
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* TODO:
|
|
|
|
*
|
|
|
|
* - Fix memory leaks: grad_free_gradient_editor() and any others
|
|
|
|
* which I may have missed.
|
|
|
|
*
|
|
|
|
* - Add all of Marcelo's neat suggestions:
|
|
|
|
* - Hue rotate, saturation, brightness, contrast.
|
|
|
|
*
|
|
|
|
* - Better handling of bogus gradient files and inconsistent
|
|
|
|
* segments. Do not loop indefinitely in seg_get_segment_at() if
|
|
|
|
* there is a missing segment between two others.
|
|
|
|
*/
|
2000-12-17 05:37:03 +08:00
|
|
|
|
1999-02-21 07:20:54 +08:00
|
|
|
#include "config.h"
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2002-01-30 22:54:27 +08:00
|
|
|
#ifdef __GNUC__
|
|
|
|
#warning GTK_DISABLE_DEPRECATED
|
|
|
|
#endif
|
|
|
|
#undef GTK_DISABLE_DEPRECATED
|
|
|
|
|
2000-12-17 05:37:03 +08:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
2001-01-24 02:49:44 +08:00
|
|
|
#include "libgimpcolor/gimpcolor.h"
|
2001-01-24 07:56:18 +08:00
|
|
|
#include "libgimpmath/gimpmath.h"
|
2001-05-22 04:30:16 +08:00
|
|
|
#include "libgimpbase/gimpbase.h"
|
2001-01-25 06:36:18 +08:00
|
|
|
#include "libgimpwidgets/gimpwidgets.h"
|
2001-01-24 02:49:44 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
#include "widgets-types.h"
|
2000-12-17 05:37:03 +08:00
|
|
|
|
2001-07-05 03:31:35 +08:00
|
|
|
#include "core/gimp.h"
|
2001-05-09 10:32:03 +08:00
|
|
|
#include "core/gimpcontainer.h"
|
|
|
|
#include "core/gimpcontext.h"
|
|
|
|
#include "core/gimpdatafactory.h"
|
|
|
|
#include "core/gimpgradient.h"
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
#include "gimpdnd.h"
|
|
|
|
#include "gimpgradienteditor.h"
|
|
|
|
#include "gimpitemfactory.h"
|
1998-11-23 22:47:09 +08:00
|
|
|
|
2000-04-28 01:27:28 +08:00
|
|
|
#include "libgimp/gimpintl.h"
|
|
|
|
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
#define EPSILON 1e-10
|
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
#define GRAD_SCROLLBAR_STEP_SIZE 0.05
|
|
|
|
#define GRAD_SCROLLBAR_PAGE_SIZE 0.75
|
|
|
|
|
1999-11-14 18:50:19 +08:00
|
|
|
#define GRAD_PREVIEW_WIDTH 600
|
|
|
|
#define GRAD_PREVIEW_HEIGHT 64
|
|
|
|
#define GRAD_CONTROL_HEIGHT 10
|
1999-10-28 23:05:49 +08:00
|
|
|
|
|
|
|
#define GRAD_MOVE_TIME 150 /* ms between mouse click and detection of movement in gradient control */
|
|
|
|
|
2001-02-13 08:12:15 +08:00
|
|
|
|
|
|
|
#define GRAD_PREVIEW_EVENT_MASK (GDK_EXPOSURE_MASK | \
|
|
|
|
GDK_LEAVE_NOTIFY_MASK | \
|
|
|
|
GDK_POINTER_MOTION_MASK | \
|
1999-11-14 18:50:19 +08:00
|
|
|
GDK_POINTER_MOTION_HINT_MASK | \
|
2001-02-13 08:12:15 +08:00
|
|
|
GDK_BUTTON_PRESS_MASK | \
|
1999-11-14 18:50:19 +08:00
|
|
|
GDK_BUTTON_RELEASE_MASK)
|
|
|
|
|
2001-02-13 08:12:15 +08:00
|
|
|
#define GRAD_CONTROL_EVENT_MASK (GDK_EXPOSURE_MASK | \
|
|
|
|
GDK_LEAVE_NOTIFY_MASK | \
|
|
|
|
GDK_POINTER_MOTION_MASK | \
|
1999-11-14 18:50:19 +08:00
|
|
|
GDK_POINTER_MOTION_HINT_MASK | \
|
2001-02-13 08:12:15 +08:00
|
|
|
GDK_BUTTON_PRESS_MASK | \
|
|
|
|
GDK_BUTTON_RELEASE_MASK | \
|
1999-10-28 23:05:49 +08:00
|
|
|
GDK_BUTTON1_MOTION_MASK)
|
|
|
|
|
2001-02-13 08:12:15 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
/* local function prototypes */
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
static void gimp_gradient_editor_class_init (GimpGradientEditorClass *klass);
|
|
|
|
static void gimp_gradient_editor_init (GimpGradientEditor *editor);
|
|
|
|
|
|
|
|
static void gimp_gradient_editor_set_data (GimpDataEditor *editor,
|
|
|
|
GimpData *data);
|
|
|
|
|
|
|
|
static void gradient_editor_drop_gradient (GtkWidget *widget,
|
|
|
|
GimpViewable *viewable,
|
|
|
|
gpointer data);
|
|
|
|
static void gradient_editor_scrollbar_update (GtkAdjustment *adj,
|
|
|
|
GimpGradientEditor *editor);
|
|
|
|
static void gradient_editor_zoom_all_callback (GtkWidget *widget,
|
|
|
|
GimpGradientEditor *editor);
|
|
|
|
static void gradient_editor_zoom_out_callback (GtkWidget *widget,
|
|
|
|
GimpGradientEditor *editor);
|
|
|
|
static void gradient_editor_zoom_in_callback (GtkWidget *widget,
|
|
|
|
GimpGradientEditor *editor);
|
|
|
|
static void gradient_editor_instant_update_update (GtkWidget *widget,
|
|
|
|
GimpGradientEditor *editor);
|
|
|
|
|
|
|
|
static void gradient_editor_set_hint (GimpGradientEditor *editor,
|
|
|
|
const gchar *str1,
|
|
|
|
const gchar *str2,
|
|
|
|
const gchar *str3);
|
2001-02-13 08:12:15 +08:00
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Gradient preview functions */
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
static gint preview_events (GtkWidget *widget,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpGradientEditor *editor);
|
|
|
|
static void preview_set_hint (GimpGradientEditor *editor,
|
|
|
|
gint x);
|
|
|
|
|
|
|
|
static void preview_set_foreground (GimpGradientEditor *editor,
|
|
|
|
gint x);
|
|
|
|
static void preview_set_background (GimpGradientEditor *editor,
|
|
|
|
gint x);
|
|
|
|
|
|
|
|
static void preview_update (GimpGradientEditor *editor,
|
|
|
|
gboolean recalculate);
|
|
|
|
static void preview_fill_image (GimpGradientEditor *editor,
|
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
gdouble left,
|
|
|
|
gdouble right);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Gradient control functions */
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
static gint control_events (GtkWidget *widget,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpGradientEditor *editor);
|
|
|
|
static void control_do_hint (GimpGradientEditor *editor,
|
|
|
|
gint x,
|
|
|
|
gint y);
|
|
|
|
static void control_button_press (GimpGradientEditor *editor,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
guint button,
|
|
|
|
guint state);
|
|
|
|
static gboolean control_point_in_handle (GimpGradientEditor *editor,
|
|
|
|
GimpGradient *gradient,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
GimpGradientSegment *seg,
|
2001-11-27 23:44:02 +08:00
|
|
|
GradientEditorDragMode handle);
|
2002-03-08 08:27:45 +08:00
|
|
|
static void control_select_single_segment (GimpGradientEditor *editor,
|
|
|
|
GimpGradientSegment *seg);
|
|
|
|
static void control_extend_selection (GimpGradientEditor *editor,
|
|
|
|
GimpGradientSegment *seg,
|
|
|
|
gdouble pos);
|
|
|
|
static void control_motion (GimpGradientEditor *editor,
|
|
|
|
GimpGradient *gradient,
|
|
|
|
gint x);
|
2000-12-20 05:49:46 +08:00
|
|
|
|
2001-02-18 05:20:10 +08:00
|
|
|
static void control_compress_left (GimpGradientSegment *range_l,
|
|
|
|
GimpGradientSegment *range_r,
|
|
|
|
GimpGradientSegment *drag_seg,
|
|
|
|
gdouble pos);
|
|
|
|
static void control_compress_range (GimpGradientSegment *range_l,
|
|
|
|
GimpGradientSegment *range_r,
|
|
|
|
gdouble new_l,
|
|
|
|
gdouble new_r);
|
2000-12-20 05:49:46 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
static double control_move (GimpGradientEditor *editor,
|
2001-02-18 05:20:10 +08:00
|
|
|
GimpGradientSegment *range_l,
|
|
|
|
GimpGradientSegment *range_r,
|
|
|
|
gdouble delta);
|
1999-07-24 23:37:03 +08:00
|
|
|
|
|
|
|
/* Control update/redraw functions */
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
static void control_update (GimpGradientEditor *editor,
|
|
|
|
GimpGradient *gradient,
|
|
|
|
gboolean recalculate);
|
|
|
|
static void control_draw (GimpGradientEditor *editor,
|
|
|
|
GimpGradient *gradient,
|
|
|
|
GdkPixmap *pixmap,
|
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
gdouble left,
|
|
|
|
gdouble right);
|
|
|
|
static void control_draw_normal_handle (GimpGradientEditor *editor,
|
|
|
|
GdkPixmap *pixmap,
|
|
|
|
gdouble pos,
|
|
|
|
gint height);
|
|
|
|
static void control_draw_middle_handle (GimpGradientEditor *editor,
|
|
|
|
GdkPixmap *pixmap,
|
|
|
|
gdouble pos,
|
|
|
|
gint height);
|
|
|
|
static void control_draw_handle (GdkPixmap *pixmap,
|
|
|
|
GdkGC *border_gc,
|
|
|
|
GdkGC *fill_gc,
|
|
|
|
gint xpos,
|
|
|
|
gint height);
|
|
|
|
|
|
|
|
static gint control_calc_p_pos (GimpGradientEditor *editor,
|
|
|
|
gdouble pos);
|
|
|
|
static gdouble control_calc_g_pos (GimpGradientEditor *editor,
|
|
|
|
gint pos);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/* Segment functions */
|
|
|
|
|
2001-02-11 09:39:24 +08:00
|
|
|
static void seg_get_closest_handle (GimpGradient *grad,
|
|
|
|
gdouble pos,
|
|
|
|
GimpGradientSegment **seg,
|
2001-11-27 23:44:02 +08:00
|
|
|
GradientEditorDragMode *handle);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-12-21 19:56:58 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
static GimpDataEditorClass *parent_class = NULL;
|
2001-02-14 09:42:12 +08:00
|
|
|
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
GType
|
|
|
|
gimp_gradient_editor_get_type (void)
|
|
|
|
{
|
|
|
|
static GType type = 0;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
if (! type)
|
|
|
|
{
|
|
|
|
static const GTypeInfo info =
|
|
|
|
{
|
|
|
|
sizeof (GimpGradientEditorClass),
|
|
|
|
NULL, /* base_init */
|
|
|
|
NULL, /* base_finalize */
|
|
|
|
(GClassInitFunc) gimp_gradient_editor_class_init,
|
|
|
|
NULL, /* class_finalize */
|
|
|
|
NULL, /* class_data */
|
|
|
|
sizeof (GimpGradientEditor),
|
|
|
|
0, /* n_preallocs */
|
|
|
|
(GInstanceInitFunc) gimp_gradient_editor_init,
|
|
|
|
};
|
|
|
|
|
|
|
|
type = g_type_register_static (GIMP_TYPE_DATA_EDITOR,
|
|
|
|
"GimpGradientEditor",
|
|
|
|
&info, 0);
|
|
|
|
}
|
1999-09-28 01:58:10 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
return type;
|
|
|
|
}
|
1999-09-28 01:58:10 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
static void
|
|
|
|
gimp_gradient_editor_class_init (GimpGradientEditorClass *klass)
|
|
|
|
{
|
|
|
|
GimpDataEditorClass *editor_class;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
editor_class = GIMP_DATA_EDITOR_CLASS (klass);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
parent_class = g_type_class_peek_parent (klass);
|
2001-02-19 08:05:03 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
editor_class->set_data = gimp_gradient_editor_set_data;
|
|
|
|
}
|
1999-11-03 17:58:46 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
static void
|
|
|
|
gimp_gradient_editor_init (GimpGradientEditor *editor)
|
|
|
|
{
|
|
|
|
GtkWidget *frame;
|
|
|
|
GtkWidget *vbox;
|
|
|
|
GtkWidget *hbox;
|
|
|
|
GtkWidget *button;
|
2001-02-13 08:12:15 +08:00
|
|
|
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
/* Frame for gradient preview and gradient control */
|
|
|
|
frame = gtk_frame_new (NULL);
|
|
|
|
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
2002-03-08 08:27:45 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (editor), frame, TRUE, TRUE, 0);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
gtk_widget_show (frame);
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
vbox = gtk_vbox_new (FALSE, 0);
|
|
|
|
gtk_container_add (GTK_CONTAINER (frame), vbox);
|
|
|
|
gtk_widget_show (vbox);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
|
|
|
|
/* Gradient preview */
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->preview_rows[0] = NULL;
|
|
|
|
editor->preview_rows[1] = NULL;
|
|
|
|
editor->preview_last_x = 0;
|
|
|
|
editor->preview_button_down = FALSE;
|
|
|
|
|
|
|
|
editor->preview = gtk_preview_new (GTK_PREVIEW_COLOR);
|
|
|
|
gtk_preview_set_dither (GTK_PREVIEW (editor->preview), GDK_RGB_DITHER_MAX);
|
|
|
|
gtk_preview_size (GTK_PREVIEW (editor->preview),
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
GRAD_PREVIEW_WIDTH, GRAD_PREVIEW_HEIGHT);
|
1999-07-24 23:37:03 +08:00
|
|
|
|
|
|
|
/* Enable auto-resizing of the preview but ensure a minimal size */
|
2001-12-29 21:26:29 +08:00
|
|
|
gtk_widget_set_size_request (editor->preview,
|
|
|
|
GRAD_PREVIEW_WIDTH, GRAD_PREVIEW_HEIGHT);
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_preview_set_expand (GTK_PREVIEW (editor->preview), TRUE);
|
1999-07-24 23:37:03 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_widget_set_events (editor->preview, GRAD_PREVIEW_EVENT_MASK);
|
2001-08-15 00:33:28 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
g_signal_connect (G_OBJECT (editor->preview), "event",
|
2001-08-15 00:33:28 +08:00
|
|
|
G_CALLBACK (preview_events),
|
2001-11-27 23:44:02 +08:00
|
|
|
editor);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
gimp_gtk_drag_dest_set_by_type (editor->preview,
|
2001-02-13 08:12:15 +08:00
|
|
|
GTK_DEST_DEFAULT_ALL,
|
|
|
|
GIMP_TYPE_GRADIENT,
|
|
|
|
GDK_ACTION_COPY);
|
2001-11-27 23:44:02 +08:00
|
|
|
gimp_dnd_viewable_dest_set (GTK_WIDGET (editor->preview),
|
2001-02-13 08:12:15 +08:00
|
|
|
GIMP_TYPE_GRADIENT,
|
|
|
|
gradient_editor_drop_gradient,
|
2001-11-27 23:44:02 +08:00
|
|
|
editor);
|
1999-10-28 23:05:49 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), editor->preview, TRUE, TRUE, 0);
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_widget_show (editor->preview);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
|
|
|
|
/* Gradient control */
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_pixmap = NULL;
|
|
|
|
editor->control_drag_segment = NULL;
|
|
|
|
editor->control_sel_l = NULL;
|
|
|
|
editor->control_sel_r = NULL;
|
|
|
|
editor->control_drag_mode = GRAD_DRAG_NONE;
|
|
|
|
editor->control_click_time = 0;
|
|
|
|
editor->control_compress = FALSE;
|
|
|
|
editor->control_last_x = 0;
|
|
|
|
editor->control_last_gx = 0.0;
|
|
|
|
editor->control_orig_pos = 0.0;
|
|
|
|
|
|
|
|
editor->control = gtk_drawing_area_new ();
|
2001-12-29 21:26:29 +08:00
|
|
|
gtk_widget_set_size_request (editor->control,
|
|
|
|
GRAD_PREVIEW_WIDTH, GRAD_CONTROL_HEIGHT);
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_widget_set_events (editor->control, GRAD_CONTROL_EVENT_MASK);
|
2002-03-08 08:27:45 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (vbox), editor->control, FALSE, FALSE, 0);
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_widget_show (editor->control);
|
new ui for the "Layer Offset" dialog.
1999-07-22 Michael Natterer <mitschel@cs.tu-berlin.de>
* app/channel_ops.[ch]: new ui for the "Layer Offset" dialog.
* app/channels_dialog.c
* app/layers_dialog.c: major code cleanup: Folded some callbacks
into common ones, "widget" instead of "w", indentation, ...
* app/commands.c
* app/interface.[ch]
* app/global_edit.c: the query boxes must be shown by the caller
now. There's no need to split up the string for the message box
manually as the Gtk 1.2 label widget handles newlines corectly.
Added the "edge_lock" toggle to the "Shrink Selection" dialog.
Nicer spacings for the query and message boxes.
* app/ink.c: tried to grab the pointer in the blob preview but
failed. Left the code there as a reminder (commented out).
* app/menus.c: reordered <Image>/Select.
I was bored and grep-ed the sources for ancient or deprecated stuff:
* app/about_dialog.[ch]
* app/actionarea.[ch]
* app/app_procs.c
* app/brush_edit.c
* app/brush_select.c
* app/color_select.c
* app/convert.c
* app/devices.c
* app/gdisplay.c
* app/gdisplay_ops.c
* app/histogram_tool.[ch]
* app/info_window.c
* app/install.c
* app/ops_buttons.c
* app/palette.c
* app/palette_select.c
* app/paths_dialog.c
* app/pattern_select.c
* app/resize.c
* app/scale_toolc.c
* app/text_tool.c:
s/container_border_width/container_set_border_width/g,
s/sprintf/g_snprintf/g, replaced some constant string lengths with
strlen(x).
* app/bezier_select.c
* app/blend.c
* app/boundary.c
* app/errors.[ch]
* app/free_select.c
* app/gimpbrushlist.c
* app/gimprc.c
* app/iscissors.c
* app/main.c
* app/patterns.[ch]
* app/text_tool.c: namespace fanaticism: prefixed all gimp error
functions with "gimp_" and formated the messages more uniformly.
* app/gradient.c
* app/gradient_select.c: same stuff as above for the ui
code. There are still some sub-dialogs which need cleanup.
Did some cleanup in most of these files: prototypes, removed tons
of #include's, i18n fixes, s/w/widget/ as above, indentation, ...
1999-07-23 00:21:10 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
g_signal_connect (G_OBJECT (editor->control), "event",
|
2001-08-15 00:33:28 +08:00
|
|
|
G_CALLBACK (control_events),
|
2001-11-27 23:44:02 +08:00
|
|
|
editor);
|
2001-08-15 00:33:28 +08:00
|
|
|
|
2001-02-19 08:05:03 +08:00
|
|
|
/* Scrollbar */
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->zoom_factor = 1;
|
|
|
|
|
|
|
|
editor->scroll_data = gtk_adjustment_new (0.0, 0.0, 1.0,
|
2002-03-08 08:27:45 +08:00
|
|
|
GRAD_SCROLLBAR_STEP_SIZE,
|
|
|
|
GRAD_SCROLLBAR_PAGE_SIZE,
|
2001-11-27 23:44:02 +08:00
|
|
|
1.0);
|
|
|
|
|
|
|
|
g_signal_connect (G_OBJECT (editor->scroll_data), "value_changed",
|
|
|
|
G_CALLBACK (gradient_editor_scrollbar_update),
|
|
|
|
editor);
|
|
|
|
g_signal_connect (G_OBJECT (editor->scroll_data), "changed",
|
|
|
|
G_CALLBACK (gradient_editor_scrollbar_update),
|
|
|
|
editor);
|
|
|
|
|
|
|
|
editor->scrollbar = gtk_hscrollbar_new (GTK_ADJUSTMENT (editor->scroll_data));
|
|
|
|
gtk_range_set_update_policy (GTK_RANGE (editor->scrollbar),
|
2001-02-19 08:05:03 +08:00
|
|
|
GTK_UPDATE_CONTINUOUS);
|
2002-03-08 08:27:45 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (editor), editor->scrollbar, FALSE, FALSE, 0);
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_widget_show (editor->scrollbar);
|
2001-02-19 08:05:03 +08:00
|
|
|
|
2001-08-10 00:39:08 +08:00
|
|
|
/* Horizontal box for zoom controls and instant update toggle */
|
2001-02-19 08:05:03 +08:00
|
|
|
hbox = gtk_hbox_new (FALSE, 4);
|
2002-03-08 08:27:45 +08:00
|
|
|
gtk_box_pack_start (GTK_BOX (editor), hbox, FALSE, FALSE, 0);
|
2001-02-19 08:05:03 +08:00
|
|
|
gtk_widget_show (hbox);
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
/* +, - and Zoom Fit buttons */
|
|
|
|
gimp_editor_add_button (GIMP_EDITOR (editor),
|
|
|
|
GTK_STOCK_ZOOM_FIT,
|
|
|
|
_("Zoom All"), NULL,
|
|
|
|
G_CALLBACK (gradient_editor_zoom_all_callback),
|
|
|
|
NULL,
|
|
|
|
editor);
|
|
|
|
|
|
|
|
gimp_editor_add_button (GIMP_EDITOR (editor),
|
|
|
|
GTK_STOCK_ZOOM_IN,
|
|
|
|
_("Zoom In"), NULL,
|
|
|
|
G_CALLBACK (gradient_editor_zoom_in_callback),
|
|
|
|
NULL,
|
|
|
|
editor);
|
|
|
|
|
|
|
|
gimp_editor_add_button (GIMP_EDITOR (editor),
|
|
|
|
GTK_STOCK_ZOOM_OUT,
|
|
|
|
_("Zoom Out"), NULL,
|
|
|
|
G_CALLBACK (gradient_editor_zoom_out_callback),
|
|
|
|
NULL,
|
|
|
|
editor);
|
2001-02-19 08:05:03 +08:00
|
|
|
|
|
|
|
/* Instant update toggle */
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->instant_update = TRUE;
|
2001-02-19 08:05:03 +08:00
|
|
|
|
|
|
|
button = gtk_check_button_new_with_label (_("Instant update"));
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
|
|
|
|
gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (button);
|
|
|
|
|
2001-08-15 00:33:28 +08:00
|
|
|
g_signal_connect (G_OBJECT (button), "toggled",
|
2001-11-27 23:44:02 +08:00
|
|
|
G_CALLBACK (gradient_editor_instant_update_update),
|
|
|
|
editor);
|
2001-02-19 08:05:03 +08:00
|
|
|
|
|
|
|
/* Hint bar */
|
2002-03-08 08:27:45 +08:00
|
|
|
editor->hint_label1 = gtk_label_new ("");
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (editor->hint_label1), 0.0, 0.5);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), editor->hint_label1, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (editor->hint_label1);
|
2001-02-19 08:05:03 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
editor->hint_label2 = gtk_label_new ("");
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (editor->hint_label2), 0.0, 0.5);
|
|
|
|
gtk_box_pack_start (GTK_BOX (editor), editor->hint_label2, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (editor->hint_label2);
|
|
|
|
|
|
|
|
editor->hint_label3 = gtk_label_new ("");
|
|
|
|
gtk_misc_set_alignment (GTK_MISC (editor->hint_label3), 0.0, 0.5);
|
|
|
|
gtk_box_pack_start (GTK_BOX (editor), editor->hint_label3, FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show (editor->hint_label3);
|
1999-07-23 04:42:59 +08:00
|
|
|
|
|
|
|
/* Initialize other data */
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->left_saved_segments = NULL;
|
|
|
|
editor->left_saved_dirty = FALSE;
|
|
|
|
|
|
|
|
editor->right_saved_segments = NULL;
|
|
|
|
editor->right_saved_dirty = FALSE;
|
|
|
|
|
|
|
|
editor->saved_colors[0].r = 0.0; /* Black */
|
|
|
|
editor->saved_colors[0].g = 0.0;
|
|
|
|
editor->saved_colors[0].b = 0.0;
|
2002-03-04 01:38:12 +08:00
|
|
|
editor->saved_colors[0].a = GIMP_OPACITY_OPAQUE;
|
2001-11-27 23:44:02 +08:00
|
|
|
|
|
|
|
editor->saved_colors[1].r = 0.5; /* 50% Gray */
|
|
|
|
editor->saved_colors[1].g = 0.5;
|
|
|
|
editor->saved_colors[1].b = 0.5;
|
2002-03-04 01:38:12 +08:00
|
|
|
editor->saved_colors[1].a = GIMP_OPACITY_OPAQUE;
|
2001-11-27 23:44:02 +08:00
|
|
|
|
|
|
|
editor->saved_colors[2].r = 1.0; /* White */
|
|
|
|
editor->saved_colors[2].g = 1.0;
|
|
|
|
editor->saved_colors[2].b = 1.0;
|
2002-03-04 01:38:12 +08:00
|
|
|
editor->saved_colors[2].a = GIMP_OPACITY_OPAQUE;
|
2001-11-27 23:44:02 +08:00
|
|
|
|
|
|
|
editor->saved_colors[3].r = 0.0; /* Clear */
|
|
|
|
editor->saved_colors[3].g = 0.0;
|
|
|
|
editor->saved_colors[3].b = 0.0;
|
2002-03-04 01:38:12 +08:00
|
|
|
editor->saved_colors[3].a = GIMP_OPACITY_TRANSPARENT;
|
2001-11-27 23:44:02 +08:00
|
|
|
|
|
|
|
editor->saved_colors[4].r = 1.0; /* Red */
|
|
|
|
editor->saved_colors[4].g = 0.0;
|
|
|
|
editor->saved_colors[4].b = 0.0;
|
2002-03-04 01:38:12 +08:00
|
|
|
editor->saved_colors[4].a = GIMP_OPACITY_OPAQUE;
|
2001-11-27 23:44:02 +08:00
|
|
|
|
|
|
|
editor->saved_colors[5].r = 1.0; /* Yellow */
|
|
|
|
editor->saved_colors[5].g = 1.0;
|
|
|
|
editor->saved_colors[5].b = 0.0;
|
2002-03-04 01:38:12 +08:00
|
|
|
editor->saved_colors[5].a = GIMP_OPACITY_OPAQUE;
|
2001-11-27 23:44:02 +08:00
|
|
|
|
|
|
|
editor->saved_colors[6].r = 0.0; /* Green */
|
|
|
|
editor->saved_colors[6].g = 1.0;
|
|
|
|
editor->saved_colors[6].b = 0.0;
|
2002-03-04 01:38:12 +08:00
|
|
|
editor->saved_colors[6].a = GIMP_OPACITY_OPAQUE;
|
2001-11-27 23:44:02 +08:00
|
|
|
|
|
|
|
editor->saved_colors[7].r = 0.0; /* Cyan */
|
|
|
|
editor->saved_colors[7].g = 1.0;
|
|
|
|
editor->saved_colors[7].b = 1.0;
|
2002-03-04 01:38:12 +08:00
|
|
|
editor->saved_colors[7].a = GIMP_OPACITY_OPAQUE;
|
2001-11-27 23:44:02 +08:00
|
|
|
|
|
|
|
editor->saved_colors[8].r = 0.0; /* Blue */
|
|
|
|
editor->saved_colors[8].g = 0.0;
|
|
|
|
editor->saved_colors[8].b = 1.0;
|
2002-03-04 01:38:12 +08:00
|
|
|
editor->saved_colors[8].a = GIMP_OPACITY_OPAQUE;
|
2001-11-27 23:44:02 +08:00
|
|
|
|
|
|
|
editor->saved_colors[9].r = 1.0; /* Magenta */
|
|
|
|
editor->saved_colors[9].g = 0.0;
|
|
|
|
editor->saved_colors[9].b = 1.0;
|
2002-03-04 01:38:12 +08:00
|
|
|
editor->saved_colors[9].a = GIMP_OPACITY_OPAQUE;
|
1999-10-28 23:05:49 +08:00
|
|
|
}
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
static void
|
|
|
|
gimp_gradient_editor_set_data (GimpDataEditor *editor,
|
|
|
|
GimpData *data)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2002-03-08 08:27:45 +08:00
|
|
|
GimpGradientEditor *gradient_editor;
|
2001-02-13 08:12:15 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor = GIMP_GRADIENT_EDITOR (editor);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
GIMP_DATA_EDITOR_CLASS (parent_class)->set_data (editor, data);
|
|
|
|
|
|
|
|
gimp_gradient_editor_update (gradient_editor,
|
|
|
|
GRAD_UPDATE_PREVIEW | GRAD_RESET_CONTROL);
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-30 18:50:36 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
/* public functions */
|
1999-09-30 18:50:36 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
GimpDataEditor *
|
|
|
|
gimp_gradient_editor_new (Gimp *gimp)
|
|
|
|
{
|
|
|
|
GimpGradientEditor *editor;
|
1999-09-30 18:50:36 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
editor = g_object_new (GIMP_TYPE_GRADIENT_EDITOR, NULL);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_data_editor_construct (GIMP_DATA_EDITOR (editor),
|
|
|
|
gimp,
|
|
|
|
GIMP_TYPE_GRADIENT);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
return GIMP_DATA_EDITOR (editor);
|
2001-11-27 23:44:02 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
void
|
|
|
|
gimp_gradient_editor_update (GimpGradientEditor *editor,
|
|
|
|
GradientEditorUpdateMask flags)
|
1998-10-13 07:31:08 +08:00
|
|
|
{
|
2002-03-08 08:27:45 +08:00
|
|
|
if (GIMP_DATA_EDITOR (editor)->data)
|
|
|
|
{
|
|
|
|
GimpGradient *gradient;
|
1998-10-13 07:31:08 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data);
|
1998-10-13 07:31:08 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
if (flags & GRAD_UPDATE_GRADIENT)
|
|
|
|
preview_update (editor, TRUE);
|
2001-02-18 05:20:10 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
if (flags & GRAD_UPDATE_PREVIEW)
|
|
|
|
preview_update (editor, TRUE);
|
2001-02-11 09:39:24 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
if (flags & GRAD_UPDATE_CONTROL)
|
|
|
|
control_update (editor, gradient, FALSE);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
if (flags & GRAD_RESET_CONTROL)
|
|
|
|
control_update (editor, gradient, TRUE);
|
|
|
|
}
|
1999-07-23 04:42:59 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
|
|
|
|
/* private functions */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2001-11-27 23:44:02 +08:00
|
|
|
gradient_editor_drop_gradient (GtkWidget *widget,
|
|
|
|
GimpViewable *viewable,
|
|
|
|
gpointer data)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_data_editor_set_data (GIMP_DATA_EDITOR (data), GIMP_DATA (viewable));
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_scrollbar_update (GtkAdjustment *adjustment,
|
|
|
|
GimpGradientEditor *editor)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2002-03-08 08:27:45 +08:00
|
|
|
gchar *str1;
|
|
|
|
gchar *str2;
|
|
|
|
|
|
|
|
str1 = g_strdup_printf (_("Zoom factor: %d:1"),
|
|
|
|
editor->zoom_factor);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
str2 = g_strdup_printf (_("Displaying [%0.6f, %0.6f]"),
|
|
|
|
adjustment->value,
|
|
|
|
adjustment->value + adjustment->page_size);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_set_hint (editor, str1, str2, "");
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
g_free (str1);
|
|
|
|
g_free (str2);
|
|
|
|
|
|
|
|
gimp_gradient_editor_update (editor,
|
|
|
|
GRAD_UPDATE_PREVIEW | GRAD_UPDATE_CONTROL);
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_zoom_all_callback (GtkWidget *widget,
|
|
|
|
GimpGradientEditor *editor)
|
1999-07-24 23:37:03 +08:00
|
|
|
{
|
|
|
|
GtkAdjustment *adjustment;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
adjustment = GTK_ADJUSTMENT (editor->scroll_data);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->zoom_factor = 1;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
adjustment->value = 0.0;
|
|
|
|
adjustment->page_size = 1.0;
|
|
|
|
adjustment->step_increment = GRAD_SCROLLBAR_STEP_SIZE;
|
|
|
|
adjustment->page_increment = GRAD_SCROLLBAR_PAGE_SIZE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_adjustment_changed (GTK_ADJUSTMENT (editor->scroll_data));
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_zoom_out_callback (GtkWidget *widget,
|
|
|
|
GimpGradientEditor *editor)
|
1999-07-24 23:37:03 +08:00
|
|
|
{
|
|
|
|
GtkAdjustment *adjustment;
|
2000-12-20 05:49:46 +08:00
|
|
|
gdouble old_value;
|
|
|
|
gdouble value;
|
|
|
|
gdouble old_page_size;
|
|
|
|
gdouble page_size;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->zoom_factor <= 1)
|
1999-07-24 23:37:03 +08:00
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
adjustment = GTK_ADJUSTMENT (editor->scroll_data);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
old_value = adjustment->value;
|
|
|
|
old_page_size = adjustment->page_size;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->zoom_factor--;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
page_size = 1.0 / editor->zoom_factor;
|
1999-07-24 23:37:03 +08:00
|
|
|
value = old_value - (page_size - old_page_size) / 2.0;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
if (value < 0.0)
|
|
|
|
value = 0.0;
|
|
|
|
else if ((value + page_size) > 1.0)
|
|
|
|
value = 1.0 - page_size;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-30 18:50:36 +08:00
|
|
|
adjustment->value = value;
|
|
|
|
adjustment->page_size = page_size;
|
1999-07-24 23:37:03 +08:00
|
|
|
adjustment->step_increment = page_size * GRAD_SCROLLBAR_STEP_SIZE;
|
|
|
|
adjustment->page_increment = page_size * GRAD_SCROLLBAR_PAGE_SIZE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_adjustment_changed (GTK_ADJUSTMENT (editor->scroll_data));
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_zoom_in_callback (GtkWidget *widget,
|
|
|
|
GimpGradientEditor *editor)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-07-24 23:37:03 +08:00
|
|
|
GtkAdjustment *adjustment;
|
2000-12-20 05:49:46 +08:00
|
|
|
gdouble old_value;
|
|
|
|
gdouble old_page_size;
|
|
|
|
gdouble page_size;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
adjustment = GTK_ADJUSTMENT (editor->scroll_data);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
old_value = adjustment->value;
|
|
|
|
old_page_size = adjustment->page_size;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->zoom_factor++;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
page_size = 1.0 / editor->zoom_factor;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
adjustment->value = old_value + (old_page_size - page_size) / 2.0;
|
|
|
|
adjustment->page_size = page_size;
|
|
|
|
adjustment->step_increment = page_size * GRAD_SCROLLBAR_STEP_SIZE;
|
|
|
|
adjustment->page_increment = page_size * GRAD_SCROLLBAR_PAGE_SIZE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_adjustment_changed (GTK_ADJUSTMENT (editor->scroll_data));
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_instant_update_update (GtkWidget *widget,
|
|
|
|
GimpGradientEditor *editor)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-07-24 23:37:03 +08:00
|
|
|
if (GTK_TOGGLE_BUTTON (widget)->active)
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->instant_update = TRUE;
|
|
|
|
gtk_range_set_update_policy (GTK_RANGE (editor->scrollbar),
|
1999-07-24 23:37:03 +08:00
|
|
|
GTK_UPDATE_CONTINUOUS);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->instant_update = FALSE;
|
|
|
|
gtk_range_set_update_policy (GTK_RANGE (editor->scrollbar),
|
1999-07-24 23:37:03 +08:00
|
|
|
GTK_UPDATE_DELAYED);
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_set_hint (GimpGradientEditor *editor,
|
|
|
|
const gchar *str1,
|
|
|
|
const gchar *str2,
|
|
|
|
const gchar *str3)
|
2001-11-27 23:44:02 +08:00
|
|
|
{
|
2002-03-08 08:27:45 +08:00
|
|
|
gtk_label_set_text (GTK_LABEL (editor->hint_label1), str1);
|
|
|
|
gtk_label_set_text (GTK_LABEL (editor->hint_label2), str2);
|
|
|
|
gtk_label_set_text (GTK_LABEL (editor->hint_label3), str3);
|
2001-11-27 23:44:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1997-11-25 06:05:25 +08:00
|
|
|
/***** Gradient preview functions *****/
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
static gboolean
|
|
|
|
preview_events (GtkWidget *widget,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpGradientEditor *editor)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-07-24 23:37:03 +08:00
|
|
|
gint x, y;
|
|
|
|
GdkEventButton *bevent;
|
|
|
|
GdkEventMotion *mevent;
|
2001-08-10 00:39:08 +08:00
|
|
|
GdkEventScroll *sevent;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
if (! GIMP_DATA_EDITOR (editor)->data)
|
|
|
|
return TRUE;
|
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case GDK_EXPOSE:
|
2001-11-27 23:44:02 +08:00
|
|
|
preview_update (editor, FALSE);
|
2001-08-10 00:39:08 +08:00
|
|
|
return FALSE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
case GDK_LEAVE_NOTIFY:
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_set_hint (editor, "", "", "");
|
1999-07-24 23:37:03 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
case GDK_MOTION_NOTIFY:
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_widget_get_pointer (editor->preview, &x, &y);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
mevent = (GdkEventMotion *) event;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (x != editor->preview_last_x)
|
1999-07-24 23:37:03 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->preview_last_x = x;
|
1999-07-24 23:37:03 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->preview_button_down)
|
1999-07-24 23:37:03 +08:00
|
|
|
{
|
|
|
|
if (mevent->state & GDK_CONTROL_MASK)
|
2001-11-27 23:44:02 +08:00
|
|
|
preview_set_background (editor, x);
|
1999-07-24 23:37:03 +08:00
|
|
|
else
|
2001-11-27 23:44:02 +08:00
|
|
|
preview_set_foreground (editor, x);
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
|
|
|
else
|
2000-12-20 05:49:46 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
preview_set_hint (editor, x);
|
2000-12-20 05:49:46 +08:00
|
|
|
}
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
|
|
|
break;
|
1999-07-23 04:42:59 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
case GDK_BUTTON_PRESS:
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_widget_get_pointer (editor->preview, &x, &y);
|
1999-07-23 04:42:59 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
bevent = (GdkEventButton *) event;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
switch (bevent->button)
|
|
|
|
{
|
|
|
|
case 1:
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->preview_last_x = x;
|
|
|
|
editor->preview_button_down = TRUE;
|
1999-07-24 23:37:03 +08:00
|
|
|
if (bevent->state & GDK_CONTROL_MASK)
|
2001-11-27 23:44:02 +08:00
|
|
|
preview_set_background (editor, x);
|
1999-07-24 23:37:03 +08:00
|
|
|
else
|
2001-11-27 23:44:02 +08:00
|
|
|
preview_set_foreground (editor, x);
|
1999-07-24 23:37:03 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
2001-11-30 22:41:56 +08:00
|
|
|
{
|
2002-01-26 02:34:33 +08:00
|
|
|
GimpItemFactory *factory;
|
2001-11-30 22:41:56 +08:00
|
|
|
|
2002-01-26 02:34:33 +08:00
|
|
|
factory = gimp_item_factory_from_path ("<GradientEditor>");
|
2001-11-30 22:41:56 +08:00
|
|
|
|
|
|
|
gimp_item_factory_popup_with_data (factory, editor, NULL);
|
|
|
|
}
|
1999-07-24 23:37:03 +08:00
|
|
|
break;
|
|
|
|
|
2001-08-10 00:39:08 +08:00
|
|
|
default:
|
1999-07-25 00:27:47 +08:00
|
|
|
break;
|
2001-08-10 00:39:08 +08:00
|
|
|
}
|
|
|
|
break;
|
1999-07-25 00:27:47 +08:00
|
|
|
|
2001-08-10 00:39:08 +08:00
|
|
|
case GDK_SCROLL:
|
|
|
|
sevent = (GdkEventScroll *) event;
|
|
|
|
|
|
|
|
if (sevent->state & GDK_SHIFT_MASK)
|
|
|
|
{
|
|
|
|
if (sevent->direction == GDK_SCROLL_UP)
|
2001-11-27 23:44:02 +08:00
|
|
|
gradient_editor_zoom_in_callback (NULL, editor);
|
2001-08-10 00:39:08 +08:00
|
|
|
else
|
2001-11-27 23:44:02 +08:00
|
|
|
gradient_editor_zoom_out_callback (NULL, editor);
|
2001-08-10 00:39:08 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
GtkAdjustment *adj = GTK_ADJUSTMENT (editor->scroll_data);
|
2001-08-10 00:39:08 +08:00
|
|
|
|
|
|
|
gfloat new_value = adj->value + ((sevent->direction == GDK_SCROLL_UP) ?
|
|
|
|
-adj->page_increment / 2 :
|
|
|
|
adj->page_increment / 2);
|
|
|
|
|
|
|
|
new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
|
|
|
|
|
|
|
|
gtk_adjustment_set_value (adj, new_value);
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
|
|
|
break;
|
1999-07-23 04:42:59 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
case GDK_BUTTON_RELEASE:
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->preview_button_down)
|
1999-07-24 23:37:03 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_widget_get_pointer (editor->preview, &x, &y);
|
1999-07-23 04:42:59 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
bevent = (GdkEventButton *) event;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->preview_last_x = x;
|
|
|
|
editor->preview_button_down = FALSE;
|
1999-07-24 23:37:03 +08:00
|
|
|
if (bevent->state & GDK_CONTROL_MASK)
|
2001-11-27 23:44:02 +08:00
|
|
|
preview_set_background (editor, x);
|
1999-07-24 23:37:03 +08:00
|
|
|
else
|
2001-11-27 23:44:02 +08:00
|
|
|
preview_set_foreground (editor, x);
|
1999-07-24 23:37:03 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-08-10 00:39:08 +08:00
|
|
|
return TRUE;
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
preview_set_hint (GimpGradientEditor *editor,
|
|
|
|
gint x)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2002-03-08 08:27:45 +08:00
|
|
|
GimpDataEditor *data_editor;
|
|
|
|
gdouble xpos;
|
|
|
|
GimpRGB rgb;
|
|
|
|
GimpHSV hsv;
|
|
|
|
gchar *str1;
|
|
|
|
gchar *str2;
|
|
|
|
gchar *str3;
|
|
|
|
|
|
|
|
data_editor = GIMP_DATA_EDITOR (editor);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
xpos = control_calc_g_pos (editor, x);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_get_color_at (GIMP_GRADIENT (data_editor->data),
|
2001-11-27 23:44:02 +08:00
|
|
|
xpos, &rgb);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-01-21 00:28:05 +08:00
|
|
|
gimp_rgb_to_hsv (&rgb, &hsv);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
str1 = g_strdup_printf (_("Position: %0.6f"), xpos);
|
|
|
|
|
|
|
|
str2 = g_strdup_printf (_("RGB (%0.3f, %0.3f, %0.3f) Opacity: %0.3f"),
|
|
|
|
rgb.r, rgb.g, rgb.b, rgb.a);
|
|
|
|
|
|
|
|
str3 = g_strdup_printf (_("HSV (%0.3f, %0.3f, %0.3f)"),
|
|
|
|
hsv.h * 360.0, hsv.s, hsv.v);
|
|
|
|
|
|
|
|
gradient_editor_set_hint (editor, str1, str2, str3);
|
|
|
|
|
|
|
|
g_free (str1);
|
|
|
|
g_free (str2);
|
|
|
|
g_free (str3);
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
preview_set_foreground (GimpGradientEditor *editor,
|
|
|
|
gint x)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2002-03-08 08:27:45 +08:00
|
|
|
GimpGradient *gradient;
|
|
|
|
GimpContext *user_context;
|
|
|
|
GimpRGB color;
|
|
|
|
gdouble xpos;
|
|
|
|
gchar *str2;
|
|
|
|
gchar *str3;
|
|
|
|
|
|
|
|
gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data);
|
|
|
|
|
|
|
|
user_context = gimp_get_user_context (GIMP_DATA_EDITOR (editor)->gimp);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
xpos = control_calc_g_pos (editor, x);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_get_color_at (gradient, xpos, &color);
|
|
|
|
|
|
|
|
gimp_context_set_foreground (user_context, &color);
|
2001-11-27 23:44:02 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
str2 = g_strdup_printf (_("RGB (%d, %d, %d)"),
|
|
|
|
(gint) (color.r * 255.0),
|
|
|
|
(gint) (color.g * 255.0),
|
|
|
|
(gint) (color.b * 255.0));
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
str3 = g_strdup_printf (_("(%0.3f, %0.3f, %0.3f)"),
|
|
|
|
color.r, color.g, color.b);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_set_hint (editor, _("Foreground color set to:"), str2, str3);
|
|
|
|
|
|
|
|
g_free (str2);
|
|
|
|
g_free (str3);
|
1999-07-23 04:42:59 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-23 04:42:59 +08:00
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
preview_set_background (GimpGradientEditor *editor,
|
|
|
|
gint x)
|
1999-07-23 04:42:59 +08:00
|
|
|
{
|
2002-03-08 08:27:45 +08:00
|
|
|
GimpGradient *gradient;
|
|
|
|
GimpContext *user_context;
|
|
|
|
GimpRGB color;
|
|
|
|
gdouble xpos;
|
|
|
|
gchar *str2;
|
|
|
|
gchar *str3;
|
|
|
|
|
|
|
|
gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data);
|
|
|
|
|
|
|
|
user_context = gimp_get_user_context (GIMP_DATA_EDITOR (editor)->gimp);
|
1999-07-23 04:42:59 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
xpos = control_calc_g_pos (editor, x);
|
2002-03-08 08:27:45 +08:00
|
|
|
|
|
|
|
gimp_gradient_get_color_at (gradient, xpos, &color);
|
|
|
|
|
|
|
|
gimp_context_set_background (user_context, &color);
|
|
|
|
|
|
|
|
str2 = g_strdup_printf (_("RGB (%d, %d, %d)"),
|
|
|
|
(gint) (color.r * 255.0),
|
|
|
|
(gint) (color.g * 255.0),
|
|
|
|
(gint) (color.b * 255.0));
|
|
|
|
|
|
|
|
str3 = g_strdup_printf (_("(%0.3f, %0.3f, %0.3f)"),
|
|
|
|
color.r, color.g, color.b);
|
|
|
|
|
|
|
|
gradient_editor_set_hint (editor, _("Background color set to:"), str2, str3);
|
|
|
|
|
|
|
|
g_free (str2);
|
|
|
|
g_free (str3);
|
1999-07-23 04:42:59 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/*****/
|
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
preview_update (GimpGradientEditor *editor,
|
|
|
|
gboolean recalculate)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-12-20 05:49:46 +08:00
|
|
|
glong rowsiz;
|
1999-07-24 23:37:03 +08:00
|
|
|
GtkAdjustment *adjustment;
|
2000-12-21 19:56:58 +08:00
|
|
|
guint16 width;
|
|
|
|
guint16 height;
|
1998-01-31 09:49:25 +08:00
|
|
|
|
2000-12-21 19:56:58 +08:00
|
|
|
static guint16 last_width = 0;
|
|
|
|
static guint16 last_height = 0;
|
1998-01-31 09:49:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (! GTK_WIDGET_DRAWABLE (editor->preview))
|
1999-07-24 23:37:03 +08:00
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
/* See whether we have to re-create the preview widget
|
|
|
|
* (note that the preview automatically follows the size of it's container)
|
|
|
|
*/
|
2001-11-27 23:44:02 +08:00
|
|
|
width = editor->preview->allocation.width;
|
|
|
|
height = editor->preview->allocation.height;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (! editor->preview_rows[0] ||
|
|
|
|
! editor->preview_rows[1] ||
|
2000-12-20 05:49:46 +08:00
|
|
|
(width != last_width) ||
|
1999-07-24 23:37:03 +08:00
|
|
|
(height != last_height))
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->preview_rows[0])
|
|
|
|
g_free (editor->preview_rows[0]);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->preview_rows[1])
|
|
|
|
g_free (editor->preview_rows[1]);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
rowsiz = width * 3 * sizeof (guchar);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->preview_rows[0] = g_malloc (rowsiz);
|
|
|
|
editor->preview_rows[1] = g_malloc (rowsiz);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
recalculate = TRUE; /* Force recalculation */
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
last_width = width;
|
|
|
|
last_height = height;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
/* Have to redraw? */
|
|
|
|
if (recalculate)
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
adjustment = GTK_ADJUSTMENT (editor->scroll_data);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
preview_fill_image (editor,
|
2001-02-18 05:20:10 +08:00
|
|
|
width, height,
|
2000-12-21 19:56:58 +08:00
|
|
|
adjustment->value,
|
|
|
|
adjustment->value + adjustment->page_size);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-12-29 21:26:29 +08:00
|
|
|
gtk_widget_queue_draw (editor->preview);
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
preview_fill_image (GimpGradientEditor *editor,
|
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
gdouble left,
|
|
|
|
gdouble right)
|
1999-09-28 01:58:10 +08:00
|
|
|
{
|
2001-02-13 08:12:15 +08:00
|
|
|
GimpGradient *gradient;
|
|
|
|
guchar *p0, *p1;
|
|
|
|
gint x, y;
|
|
|
|
gdouble dx, cur_x;
|
|
|
|
GimpRGB color;
|
|
|
|
gdouble c0, c1;
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data);
|
1999-09-28 01:58:10 +08:00
|
|
|
|
|
|
|
dx = (right - left) / (width - 1);
|
|
|
|
cur_x = left;
|
2001-11-27 23:44:02 +08:00
|
|
|
p0 = editor->preview_rows[0];
|
|
|
|
p1 = editor->preview_rows[1];
|
1999-09-28 01:58:10 +08:00
|
|
|
|
|
|
|
/* Create lines to fill the image */
|
|
|
|
for (x = 0; x < width; x++)
|
|
|
|
{
|
2001-02-13 08:12:15 +08:00
|
|
|
gimp_gradient_get_color_at (gradient, cur_x, &color);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-10-28 23:05:49 +08:00
|
|
|
if ((x / GIMP_CHECK_SIZE) & 1)
|
1999-09-28 01:58:10 +08:00
|
|
|
{
|
1999-10-28 23:05:49 +08:00
|
|
|
c0 = GIMP_CHECK_LIGHT;
|
|
|
|
c1 = GIMP_CHECK_DARK;
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-10-28 23:05:49 +08:00
|
|
|
c0 = GIMP_CHECK_DARK;
|
|
|
|
c1 = GIMP_CHECK_LIGHT;
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-01-21 00:28:05 +08:00
|
|
|
*p0++ = (c0 + (color.r - c0) * color.a) * 255.0;
|
|
|
|
*p0++ = (c0 + (color.g - c0) * color.a) * 255.0;
|
|
|
|
*p0++ = (c0 + (color.b - c0) * color.a) * 255.0;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-01-21 00:28:05 +08:00
|
|
|
*p1++ = (c1 + (color.r - c1) * color.a) * 255.0;
|
|
|
|
*p1++ = (c1 + (color.g - c1) * color.a) * 255.0;
|
|
|
|
*p1++ = (c1 + (color.b - c1) * color.a) * 255.0;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
cur_x += dx;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Fill image */
|
|
|
|
for (y = 0; y < height; y++)
|
2000-12-20 05:49:46 +08:00
|
|
|
{
|
|
|
|
if ((y / GIMP_CHECK_SIZE) & 1)
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (editor->preview),
|
|
|
|
editor->preview_rows[1], 0, y, width);
|
2000-12-20 05:49:46 +08:00
|
|
|
else
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_preview_draw_row (GTK_PREVIEW (editor->preview),
|
|
|
|
editor->preview_rows[0], 0, y, width);
|
2000-12-20 05:49:46 +08:00
|
|
|
}
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/***** Gradient control functions *****/
|
|
|
|
|
|
|
|
/* *** WARNING *** WARNING *** WARNING ***
|
|
|
|
*
|
|
|
|
* All the event-handling code for the gradient control widget is
|
|
|
|
* extremely hairy. You are not expected to understand it. If you
|
|
|
|
* find bugs, mail me unless you are very brave and you want to fix
|
|
|
|
* them yourself ;-)
|
|
|
|
*/
|
|
|
|
|
|
|
|
static gint
|
2002-03-08 08:27:45 +08:00
|
|
|
control_events (GtkWidget *widget,
|
|
|
|
GdkEvent *event,
|
|
|
|
GimpGradientEditor *editor)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-02-13 08:12:15 +08:00
|
|
|
GimpGradient *gradient;
|
|
|
|
GdkEventButton *bevent;
|
2001-02-11 03:35:29 +08:00
|
|
|
GimpGradientSegment *seg;
|
2001-02-13 08:12:15 +08:00
|
|
|
gint x, y;
|
|
|
|
guint32 time;
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
if (! GIMP_DATA_EDITOR (editor)->data)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
switch (event->type)
|
|
|
|
{
|
|
|
|
case GDK_EXPOSE:
|
2001-11-27 23:44:02 +08:00
|
|
|
control_update (editor, gradient, FALSE);
|
1999-07-24 23:37:03 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
case GDK_LEAVE_NOTIFY:
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_set_hint (editor, "", "", "");
|
1999-07-24 23:37:03 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
case GDK_BUTTON_PRESS:
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->control_drag_mode == GRAD_DRAG_NONE)
|
1999-07-24 23:37:03 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_widget_get_pointer (editor->control, &x, &y);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
bevent = (GdkEventButton *) event;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_last_x = x;
|
|
|
|
editor->control_click_time = bevent->time;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
control_button_press (editor,
|
2001-02-18 05:20:10 +08:00
|
|
|
x, y, bevent->button, bevent->state);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->control_drag_mode != GRAD_DRAG_NONE)
|
1999-07-24 23:37:03 +08:00
|
|
|
gtk_grab_add (widget);
|
|
|
|
}
|
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
case GDK_BUTTON_RELEASE:
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_set_hint (editor, "", "", "");
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->control_drag_mode != GRAD_DRAG_NONE)
|
1999-07-24 23:37:03 +08:00
|
|
|
{
|
|
|
|
gtk_grab_remove (widget);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_widget_get_pointer (editor->control, &x, &y);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
time = ((GdkEventButton *) event)->time;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if ((time - editor->control_click_time) >= GRAD_MOVE_TIME)
|
2000-12-20 05:49:46 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
if (! editor->instant_update)
|
2001-02-19 08:05:03 +08:00
|
|
|
gimp_data_dirty (GIMP_DATA (gradient));
|
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
/* Possible move */
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_editor_update (editor, GRAD_UPDATE_GRADIENT);
|
2000-12-20 05:49:46 +08:00
|
|
|
}
|
2001-11-27 23:44:02 +08:00
|
|
|
else if ((editor->control_drag_mode == GRAD_DRAG_MIDDLE) ||
|
|
|
|
(editor->control_drag_mode == GRAD_DRAG_ALL))
|
2000-12-20 05:49:46 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
seg = editor->control_drag_segment;
|
2000-12-20 05:49:46 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if ((editor->control_drag_mode == GRAD_DRAG_ALL) &&
|
|
|
|
editor->control_compress)
|
|
|
|
control_extend_selection (editor, seg,
|
|
|
|
control_calc_g_pos (editor,
|
2001-02-18 05:20:10 +08:00
|
|
|
x));
|
2000-12-20 05:49:46 +08:00
|
|
|
else
|
2001-11-27 23:44:02 +08:00
|
|
|
control_select_single_segment (editor, seg);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_editor_update (editor, GRAD_UPDATE_CONTROL);
|
2000-12-20 05:49:46 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_drag_mode = GRAD_DRAG_NONE;
|
|
|
|
editor->control_compress = FALSE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
control_do_hint (editor, x, y);
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
case GDK_MOTION_NOTIFY:
|
2001-11-27 23:44:02 +08:00
|
|
|
gtk_widget_get_pointer (editor->control, &x, &y);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (x != editor->control_last_x)
|
1999-07-24 23:37:03 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_last_x = x;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->control_drag_mode != GRAD_DRAG_NONE)
|
1999-07-24 23:37:03 +08:00
|
|
|
{
|
|
|
|
time = ((GdkEventButton *) event)->time;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if ((time - editor->control_click_time) >= GRAD_MOVE_TIME)
|
|
|
|
control_motion (editor, gradient, x);
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_editor_update (editor, GRAD_UPDATE_CONTROL);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
control_do_hint (editor, x, y);
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
return TRUE;
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
control_do_hint (GimpGradientEditor *editor,
|
|
|
|
gint x,
|
|
|
|
gint y)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
GimpGradient *gradient;
|
|
|
|
GimpGradientSegment *seg;
|
|
|
|
GradientEditorDragMode handle;
|
|
|
|
gboolean in_handle;
|
|
|
|
double pos;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data);
|
2001-02-13 08:12:15 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
pos = control_calc_g_pos (editor, x);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if ((pos < 0.0) || (pos > 1.0))
|
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-02-13 08:12:15 +08:00
|
|
|
seg_get_closest_handle (gradient, pos, &seg, &handle);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
in_handle = control_point_in_handle (editor, gradient,
|
2001-02-18 05:20:10 +08:00
|
|
|
x, y, seg, handle);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (in_handle)
|
|
|
|
{
|
|
|
|
switch (handle)
|
|
|
|
{
|
|
|
|
case GRAD_DRAG_LEFT:
|
|
|
|
if (seg != NULL)
|
|
|
|
{
|
|
|
|
if (seg->prev != NULL)
|
2001-11-27 23:44:02 +08:00
|
|
|
gradient_editor_set_hint (editor,
|
2002-03-08 08:27:45 +08:00
|
|
|
"",
|
|
|
|
_("Drag: move"),
|
|
|
|
_("<Shift>+Drag: move & compress"));
|
1999-09-28 01:58:10 +08:00
|
|
|
else
|
2001-11-27 23:44:02 +08:00
|
|
|
gradient_editor_set_hint (editor,
|
2002-03-08 08:27:45 +08:00
|
|
|
"",
|
|
|
|
_("Click: select"),
|
|
|
|
_("<Shift>+Click: extend selection"));
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
|
|
|
else
|
2000-12-20 05:49:46 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
gradient_editor_set_hint (editor,
|
2002-03-08 08:27:45 +08:00
|
|
|
"",
|
|
|
|
_("Click: select"),
|
|
|
|
_("<Shift>+Click: extend selection"));
|
2000-12-20 05:49:46 +08:00
|
|
|
}
|
1999-09-28 01:58:10 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
case GRAD_DRAG_MIDDLE:
|
2001-11-27 23:44:02 +08:00
|
|
|
gradient_editor_set_hint (editor,
|
2002-03-08 08:27:45 +08:00
|
|
|
"",
|
|
|
|
_("Click: select Drag: move"),
|
|
|
|
_("<Shift>+Click: extend selection"));
|
1999-09-28 01:58:10 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
default:
|
2001-11-27 23:44:02 +08:00
|
|
|
g_warning ("%s: in_handle is true, but received handle type %d.",
|
|
|
|
G_STRLOC, in_handle);
|
1999-09-28 01:58:10 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2001-11-27 23:44:02 +08:00
|
|
|
{
|
|
|
|
gradient_editor_set_hint (editor,
|
2002-03-08 08:27:45 +08:00
|
|
|
_("Click: select Drag: move"),
|
|
|
|
_("<Shift>+Click: extend selection"),
|
|
|
|
_("<Shift>+Drag: move & compress"));
|
2001-11-27 23:44:02 +08:00
|
|
|
}
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
control_button_press (GimpGradientEditor *editor,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
guint button,
|
|
|
|
guint state)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
GimpGradient *gradient;
|
|
|
|
GimpGradientSegment *seg;
|
|
|
|
GradientEditorDragMode handle;
|
|
|
|
double xpos;
|
|
|
|
gboolean in_handle;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient = GIMP_GRADIENT (GIMP_DATA_EDITOR (editor)->data);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
switch (button)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
case 3:
|
2001-11-30 22:41:56 +08:00
|
|
|
{
|
2002-01-26 02:34:33 +08:00
|
|
|
GimpItemFactory *factory;
|
2001-11-30 22:41:56 +08:00
|
|
|
|
2002-01-26 02:34:33 +08:00
|
|
|
factory = gimp_item_factory_from_path ("<GradientEditor>");
|
2001-11-30 22:41:56 +08:00
|
|
|
|
|
|
|
gimp_item_factory_popup_with_data (factory, editor, NULL);
|
|
|
|
}
|
1999-07-25 00:27:47 +08:00
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
/* wheelmouse support */
|
|
|
|
case 4:
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
GtkAdjustment *adj = GTK_ADJUSTMENT (editor->scroll_data);
|
2000-12-21 19:56:58 +08:00
|
|
|
gfloat new_value = adj->value - adj->page_increment / 2;
|
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
|
|
|
|
gtk_adjustment_set_value (adj, new_value);
|
|
|
|
}
|
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
case 5:
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
GtkAdjustment *adj = GTK_ADJUSTMENT (editor->scroll_data);
|
2000-12-21 19:56:58 +08:00
|
|
|
gfloat new_value = adj->value + adj->page_increment / 2;
|
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
new_value = CLAMP (new_value, adj->lower, adj->upper - adj->page_size);
|
|
|
|
gtk_adjustment_set_value (adj, new_value);
|
|
|
|
}
|
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
/* Find the closest handle */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
xpos = control_calc_g_pos (editor, x);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-02-13 08:12:15 +08:00
|
|
|
seg_get_closest_handle (gradient, xpos, &seg, &handle);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
in_handle = control_point_in_handle (editor, gradient,
|
2001-02-18 05:20:10 +08:00
|
|
|
x, y, seg, handle);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
/* Now see what we have */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
if (in_handle)
|
|
|
|
{
|
|
|
|
switch (handle)
|
|
|
|
{
|
|
|
|
case GRAD_DRAG_LEFT:
|
|
|
|
if (seg != NULL)
|
|
|
|
{
|
|
|
|
/* Left handle of some segment */
|
|
|
|
if (state & GDK_SHIFT_MASK)
|
|
|
|
{
|
|
|
|
if (seg->prev != NULL)
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_drag_mode = GRAD_DRAG_LEFT;
|
|
|
|
editor->control_drag_segment = seg;
|
|
|
|
editor->control_compress = TRUE;
|
1999-07-25 00:27:47 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
control_extend_selection (editor, seg, xpos);
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_editor_update (editor, GRAD_UPDATE_CONTROL);
|
1999-07-25 00:27:47 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (seg->prev != NULL)
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_drag_mode = GRAD_DRAG_LEFT;
|
|
|
|
editor->control_drag_segment = seg;
|
1999-07-25 00:27:47 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
control_select_single_segment (editor, seg);
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_editor_update (editor, GRAD_UPDATE_CONTROL);
|
1999-07-25 00:27:47 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else /* seg == NULL */
|
|
|
|
{
|
|
|
|
/* Right handle of last segment */
|
2001-02-13 08:12:15 +08:00
|
|
|
seg = gimp_gradient_segment_get_last (gradient->segments);
|
1999-07-25 00:27:47 +08:00
|
|
|
|
|
|
|
if (state & GDK_SHIFT_MASK)
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
control_extend_selection (editor, seg, xpos);
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_editor_update (editor, GRAD_UPDATE_CONTROL);
|
1999-07-25 00:27:47 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
control_select_single_segment (editor, seg);
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_editor_update (editor, GRAD_UPDATE_CONTROL);
|
1999-07-25 00:27:47 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
return;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
case GRAD_DRAG_MIDDLE:
|
|
|
|
if (state & GDK_SHIFT_MASK)
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
control_extend_selection (editor, seg, xpos);
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_editor_update (editor, GRAD_UPDATE_CONTROL);
|
1999-07-25 00:27:47 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_drag_mode = GRAD_DRAG_MIDDLE;
|
|
|
|
editor->control_drag_segment = seg;
|
1999-07-25 00:27:47 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
default:
|
2001-11-27 23:44:02 +08:00
|
|
|
g_warning ("%s: in_handle is true, but received handle type %d.",
|
|
|
|
G_STRLOC, in_handle);
|
1999-07-25 00:27:47 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else /* !in_handle */
|
|
|
|
{
|
2001-02-13 08:12:15 +08:00
|
|
|
seg = gimp_gradient_get_segment_at (gradient, xpos);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_drag_mode = GRAD_DRAG_ALL;
|
|
|
|
editor->control_drag_segment = seg;
|
|
|
|
editor->control_last_gx = xpos;
|
|
|
|
editor->control_orig_pos = xpos;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
if (state & GDK_SHIFT_MASK)
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_compress = TRUE;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-25 00:27:47 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
static gboolean
|
2002-03-08 08:27:45 +08:00
|
|
|
control_point_in_handle (GimpGradientEditor *editor,
|
2001-11-27 23:44:02 +08:00
|
|
|
GimpGradient *gradient,
|
|
|
|
gint x,
|
|
|
|
gint y,
|
|
|
|
GimpGradientSegment *seg,
|
|
|
|
GradientEditorDragMode handle)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-09-28 01:58:10 +08:00
|
|
|
gint handle_pos;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
switch (handle)
|
|
|
|
{
|
|
|
|
case GRAD_DRAG_LEFT:
|
|
|
|
if (seg)
|
2000-12-20 05:49:46 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
handle_pos = control_calc_p_pos (editor, seg->left);
|
2000-12-20 05:49:46 +08:00
|
|
|
}
|
1999-09-28 01:58:10 +08:00
|
|
|
else
|
|
|
|
{
|
2001-02-13 08:12:15 +08:00
|
|
|
seg = gimp_gradient_segment_get_last (gradient->segments);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
handle_pos = control_calc_p_pos (editor, seg->right);
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
case GRAD_DRAG_MIDDLE:
|
2001-11-27 23:44:02 +08:00
|
|
|
handle_pos = control_calc_p_pos (editor, seg->middle);
|
1999-09-28 01:58:10 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
default:
|
2001-11-27 23:44:02 +08:00
|
|
|
g_warning ("%s: Cannot handle drag mode %d.", G_STRLOC, handle);
|
1999-09-28 01:58:10 +08:00
|
|
|
return FALSE;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
y /= 2;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if ((x >= (handle_pos - y)) && (x <= (handle_pos + y)))
|
|
|
|
return TRUE;
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/*****/
|
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
control_select_single_segment (GimpGradientEditor *editor,
|
2001-02-18 05:20:10 +08:00
|
|
|
GimpGradientSegment *seg)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_sel_l = seg;
|
|
|
|
editor->control_sel_r = seg;
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
control_extend_selection (GimpGradientEditor *editor,
|
2001-02-18 05:20:10 +08:00
|
|
|
GimpGradientSegment *seg,
|
|
|
|
gdouble pos)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
if (fabs (pos - editor->control_sel_l->left) <
|
|
|
|
fabs (pos - editor->control_sel_r->right))
|
|
|
|
editor->control_sel_l = seg;
|
1999-09-28 01:58:10 +08:00
|
|
|
else
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_sel_r = seg;
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/*****/
|
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
control_motion (GimpGradientEditor *editor,
|
|
|
|
GimpGradient *gradient,
|
|
|
|
gint x)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-02-11 03:35:29 +08:00
|
|
|
GimpGradientSegment *seg;
|
2002-03-08 08:27:45 +08:00
|
|
|
gdouble pos;
|
|
|
|
gdouble delta;
|
|
|
|
gchar *str = NULL;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
seg = editor->control_drag_segment;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
switch (editor->control_drag_mode)
|
1999-09-28 01:58:10 +08:00
|
|
|
{
|
|
|
|
case GRAD_DRAG_LEFT:
|
2001-11-27 23:44:02 +08:00
|
|
|
pos = control_calc_g_pos (editor, x);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (! editor->control_compress)
|
2000-01-26 07:06:12 +08:00
|
|
|
seg->prev->right = seg->left = CLAMP (pos,
|
|
|
|
seg->prev->middle + EPSILON,
|
|
|
|
seg->middle - EPSILON);
|
1999-09-28 01:58:10 +08:00
|
|
|
else
|
2001-11-27 23:44:02 +08:00
|
|
|
control_compress_left (editor->control_sel_l,
|
|
|
|
editor->control_sel_r,
|
1999-09-28 01:58:10 +08:00
|
|
|
seg, pos);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-10 05:31:01 +08:00
|
|
|
str = g_strdup_printf (_("Handle position: %0.6f"), seg->left);
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_set_hint (editor, str, "", "");
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
case GRAD_DRAG_MIDDLE:
|
2001-11-27 23:44:02 +08:00
|
|
|
pos = control_calc_g_pos (editor, x);
|
2000-01-26 07:06:12 +08:00
|
|
|
seg->middle = CLAMP (pos, seg->left + EPSILON, seg->right - EPSILON);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-10 05:31:01 +08:00
|
|
|
str = g_strdup_printf (_("Handle position: %0.6f"), seg->middle);
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_set_hint (editor, str, "", "");
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
case GRAD_DRAG_ALL:
|
2001-11-27 23:44:02 +08:00
|
|
|
pos = control_calc_g_pos (editor, x);
|
|
|
|
delta = pos - editor->control_last_gx;
|
|
|
|
|
|
|
|
if ((seg->left >= editor->control_sel_l->left) &&
|
|
|
|
(seg->right <= editor->control_sel_r->right))
|
|
|
|
delta = control_move (editor,
|
|
|
|
editor->control_sel_l,
|
|
|
|
editor->control_sel_r, delta);
|
1999-09-28 01:58:10 +08:00
|
|
|
else
|
2001-11-27 23:44:02 +08:00
|
|
|
delta = control_move (editor, seg, seg, delta);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_last_gx += delta;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-10 05:31:01 +08:00
|
|
|
str = g_strdup_printf (_("Distance: %0.6f"),
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_last_gx -
|
|
|
|
editor->control_orig_pos);
|
2002-03-08 08:27:45 +08:00
|
|
|
gradient_editor_set_hint (editor, str, "", "");
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
default:
|
2001-11-27 23:44:02 +08:00
|
|
|
g_warning ("%s: Attempting to move bogus handle %d.",
|
|
|
|
G_STRLOC, editor->control_drag_mode);
|
1999-09-28 01:58:10 +08:00
|
|
|
break;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-10 05:31:01 +08:00
|
|
|
if (str)
|
|
|
|
g_free (str);
|
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->instant_update)
|
2001-02-19 08:05:03 +08:00
|
|
|
{
|
|
|
|
gimp_data_dirty (GIMP_DATA (gradient));
|
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_editor_update (editor,
|
|
|
|
GRAD_UPDATE_GRADIENT | GRAD_UPDATE_CONTROL);
|
2001-02-19 08:05:03 +08:00
|
|
|
}
|
1999-09-28 01:58:10 +08:00
|
|
|
else
|
2001-02-19 08:05:03 +08:00
|
|
|
{
|
2002-03-08 08:27:45 +08:00
|
|
|
gimp_gradient_editor_update (editor, GRAD_UPDATE_CONTROL);
|
2001-02-19 08:05:03 +08:00
|
|
|
}
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2001-02-11 03:35:29 +08:00
|
|
|
control_compress_left (GimpGradientSegment *range_l,
|
|
|
|
GimpGradientSegment *range_r,
|
|
|
|
GimpGradientSegment *drag_seg,
|
2001-02-18 05:20:10 +08:00
|
|
|
gdouble pos)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-02-11 03:35:29 +08:00
|
|
|
GimpGradientSegment *seg;
|
2001-02-13 08:12:15 +08:00
|
|
|
gdouble lbound, rbound;
|
|
|
|
gint k;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Check what we have to compress */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (!((drag_seg->left >= range_l->left) &&
|
|
|
|
((drag_seg->right <= range_r->right) || (drag_seg == range_r->next))))
|
|
|
|
{
|
|
|
|
/* We are compressing a segment outside the selection */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
range_l = range_r = drag_seg;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Calculate left bound for dragged hadle */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (drag_seg == range_l)
|
|
|
|
lbound = range_l->prev->left + 2.0 * EPSILON;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Count number of segments to the left of the dragged handle */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
seg = drag_seg;
|
|
|
|
k = 0;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
while (seg != range_l)
|
|
|
|
{
|
|
|
|
k++;
|
|
|
|
seg = seg->prev;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* 2*k handles have to fit */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
lbound = range_l->left + 2.0 * k * EPSILON;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Calculate right bound for dragged handle */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (drag_seg == range_r->next)
|
|
|
|
rbound = range_r->next->right - 2.0 * EPSILON;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Count number of segments to the right of the dragged handle */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
seg = drag_seg;
|
|
|
|
k = 1;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
while (seg != range_r)
|
|
|
|
{
|
|
|
|
k++;
|
|
|
|
seg = seg->next;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* 2*k handles have to fit */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
rbound = range_r->right - 2.0 * k * EPSILON;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Calculate position */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-01-26 07:06:12 +08:00
|
|
|
pos = CLAMP (pos, lbound, rbound);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Compress segments to the left of the handle */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (drag_seg == range_l)
|
|
|
|
control_compress_range (range_l->prev, range_l->prev,
|
|
|
|
range_l->prev->left, pos);
|
|
|
|
else
|
|
|
|
control_compress_range (range_l, drag_seg->prev, range_l->left, pos);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Compress segments to the right of the handle */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (drag_seg != range_r->next)
|
|
|
|
control_compress_range (drag_seg, range_r, pos, range_r->right);
|
|
|
|
else
|
|
|
|
control_compress_range (drag_seg, drag_seg, pos, drag_seg->right);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2001-02-11 03:35:29 +08:00
|
|
|
control_compress_range (GimpGradientSegment *range_l,
|
|
|
|
GimpGradientSegment *range_r,
|
2002-03-08 08:27:45 +08:00
|
|
|
gdouble new_l,
|
|
|
|
gdouble new_r)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-12-20 05:49:46 +08:00
|
|
|
gdouble orig_l, orig_r;
|
|
|
|
gdouble scale;
|
2001-02-11 03:35:29 +08:00
|
|
|
GimpGradientSegment *seg, *aseg;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
orig_l = range_l->left;
|
|
|
|
orig_r = range_r->right;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
scale = (new_r - new_l) / (orig_r - orig_l);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
seg = range_l;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
do
|
|
|
|
{
|
|
|
|
seg->left = new_l + (seg->left - orig_l) * scale;
|
|
|
|
seg->middle = new_l + (seg->middle - orig_l) * scale;
|
|
|
|
seg->right = new_l + (seg->right - orig_l) * scale;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Next */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
aseg = seg;
|
|
|
|
seg = seg->next;
|
2000-12-20 05:49:46 +08:00
|
|
|
}
|
|
|
|
while (aseg != range_r);
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/*****/
|
|
|
|
|
2000-12-20 05:49:46 +08:00
|
|
|
static gdouble
|
2002-03-08 08:27:45 +08:00
|
|
|
control_move (GimpGradientEditor *editor,
|
2001-02-18 05:20:10 +08:00
|
|
|
GimpGradientSegment *range_l,
|
2001-02-11 03:35:29 +08:00
|
|
|
GimpGradientSegment *range_r,
|
2001-11-27 23:44:02 +08:00
|
|
|
gdouble delta)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-02-18 05:20:10 +08:00
|
|
|
gdouble lbound, rbound;
|
|
|
|
gint is_first, is_last;
|
2001-02-11 03:35:29 +08:00
|
|
|
GimpGradientSegment *seg, *aseg;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* First or last segments in gradient? */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
is_first = (range_l->prev == NULL);
|
|
|
|
is_last = (range_r->next == NULL);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Calculate drag bounds */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (! editor->control_compress)
|
1999-09-28 01:58:10 +08:00
|
|
|
{
|
|
|
|
if (!is_first)
|
|
|
|
lbound = range_l->prev->middle + EPSILON;
|
|
|
|
else
|
|
|
|
lbound = range_l->left + EPSILON;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (!is_last)
|
|
|
|
rbound = range_r->next->middle - EPSILON;
|
|
|
|
else
|
|
|
|
rbound = range_r->right - EPSILON;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!is_first)
|
|
|
|
lbound = range_l->prev->left + 2.0 * EPSILON;
|
|
|
|
else
|
|
|
|
lbound = range_l->left + EPSILON;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (!is_last)
|
|
|
|
rbound = range_r->next->right - 2.0 * EPSILON;
|
|
|
|
else
|
|
|
|
rbound = range_r->right - EPSILON;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Fix the delta if necessary */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (delta < 0.0)
|
|
|
|
{
|
|
|
|
if (!is_first)
|
|
|
|
{
|
|
|
|
if (range_l->left + delta < lbound)
|
|
|
|
delta = lbound - range_l->left;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (range_l->middle + delta < lbound)
|
|
|
|
delta = lbound - range_l->middle;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!is_last)
|
|
|
|
{
|
|
|
|
if (range_r->right + delta > rbound)
|
|
|
|
delta = rbound - range_r->right;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (range_r->middle + delta > rbound)
|
|
|
|
delta = rbound - range_r->middle;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Move all the segments inside the range */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
seg = range_l;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
do
|
|
|
|
{
|
|
|
|
if (!((seg == range_l) && is_first))
|
|
|
|
seg->left += delta;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
seg->middle += delta;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (!((seg == range_r) && is_last))
|
|
|
|
seg->right += delta;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Next */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
aseg = seg;
|
|
|
|
seg = seg->next;
|
|
|
|
}
|
|
|
|
while (aseg != range_r);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Fix the segments that surround the range */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (!is_first)
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
if (! editor->control_compress)
|
1999-09-28 01:58:10 +08:00
|
|
|
range_l->prev->right = range_l->left;
|
|
|
|
else
|
|
|
|
control_compress_range (range_l->prev, range_l->prev,
|
|
|
|
range_l->prev->left, range_l->left);
|
|
|
|
}
|
2000-12-20 05:49:46 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (!is_last)
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
if (! editor->control_compress)
|
1999-09-28 01:58:10 +08:00
|
|
|
range_r->next->left = range_r->right;
|
|
|
|
else
|
|
|
|
control_compress_range (range_r->next, range_r->next,
|
|
|
|
range_r->right, range_r->next->right);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
return delta;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/*****/
|
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
control_update (GimpGradientEditor *editor,
|
|
|
|
GimpGradient *gradient,
|
|
|
|
gboolean recalculate)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-07-24 23:37:03 +08:00
|
|
|
GtkAdjustment *adjustment;
|
2000-12-20 05:49:46 +08:00
|
|
|
gint cwidth, cheight;
|
2002-03-08 08:27:45 +08:00
|
|
|
gint pwidth = 0;
|
|
|
|
gint pheight = 0;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (! GTK_WIDGET_DRAWABLE (editor->control))
|
1999-07-24 23:37:03 +08:00
|
|
|
return;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
/* See whether we have to re-create the control pixmap
|
|
|
|
* depending on the preview's width
|
|
|
|
*/
|
2001-11-27 23:44:02 +08:00
|
|
|
cwidth = editor->preview->allocation.width;
|
1999-07-24 23:37:03 +08:00
|
|
|
cheight = GRAD_CONTROL_HEIGHT;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->control_pixmap)
|
|
|
|
gdk_drawable_get_size (editor->control_pixmap, &pwidth, &pheight);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2002-03-08 08:27:45 +08:00
|
|
|
if (! editor->control_pixmap || (cwidth != pwidth) || (cheight != pheight))
|
1999-07-24 23:37:03 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
if (editor->control_pixmap)
|
2001-12-02 23:43:00 +08:00
|
|
|
g_object_unref (editor->control_pixmap);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_pixmap =
|
|
|
|
gdk_pixmap_new (editor->control->window, cwidth, cheight, -1);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
recalculate = TRUE;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
/* Have to reset the selection? */
|
|
|
|
if (recalculate)
|
2001-11-27 23:44:02 +08:00
|
|
|
control_select_single_segment (editor, gradient->segments);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-07-24 23:37:03 +08:00
|
|
|
/* Redraw pixmap */
|
2001-11-27 23:44:02 +08:00
|
|
|
adjustment = GTK_ADJUSTMENT (editor->scroll_data);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
control_draw (editor,
|
2001-02-18 05:20:10 +08:00
|
|
|
gradient,
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control_pixmap,
|
1999-07-24 23:37:03 +08:00
|
|
|
cwidth, cheight,
|
|
|
|
adjustment->value,
|
|
|
|
adjustment->value + adjustment->page_size);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
gdk_draw_drawable (editor->control->window,
|
|
|
|
editor->control->style->black_gc,
|
|
|
|
editor->control_pixmap,
|
2001-08-31 22:01:47 +08:00
|
|
|
0, 0, 0, 0,
|
|
|
|
cwidth, cheight);
|
1999-07-24 23:37:03 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
control_draw (GimpGradientEditor *editor,
|
|
|
|
GimpGradient *gradient,
|
|
|
|
GdkPixmap *pixmap,
|
|
|
|
gint width,
|
|
|
|
gint height,
|
|
|
|
gdouble left,
|
|
|
|
gdouble right)
|
1999-09-28 01:58:10 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
gint sel_l, sel_r;
|
|
|
|
gdouble g_pos;
|
|
|
|
GimpGradientSegment *seg;
|
|
|
|
GradientEditorDragMode handle;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Clear the pixmap */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
gdk_draw_rectangle (pixmap, editor->control->style->bg_gc[GTK_STATE_NORMAL],
|
1999-09-28 01:58:10 +08:00
|
|
|
TRUE, 0, 0, width, height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Draw selection */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
sel_l = control_calc_p_pos (editor,
|
|
|
|
editor->control_sel_l->left);
|
|
|
|
sel_r = control_calc_p_pos (editor,
|
|
|
|
editor->control_sel_r->right);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
gdk_draw_rectangle (pixmap,
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control->style->dark_gc[GTK_STATE_NORMAL],
|
1999-09-28 01:58:10 +08:00
|
|
|
TRUE, sel_l, 0, sel_r - sel_l + 1, height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Draw handles */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-02-13 08:12:15 +08:00
|
|
|
seg = gradient->segments;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
while (seg)
|
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
control_draw_normal_handle (editor, pixmap, seg->left, height);
|
|
|
|
control_draw_middle_handle (editor, pixmap, seg->middle, height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Draw right handle only if this is the last segment */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (seg->next == NULL)
|
2001-11-27 23:44:02 +08:00
|
|
|
control_draw_normal_handle (editor, pixmap, seg->right, height);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Next! */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
seg = seg->next;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Draw the handle which is closest to the mouse position */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
g_pos = control_calc_g_pos (editor, editor->control_last_x);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-02-13 08:12:15 +08:00
|
|
|
seg_get_closest_handle (gradient, CLAMP (g_pos, 0.0, 1.0), &seg, &handle);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
switch (handle)
|
|
|
|
{
|
|
|
|
case GRAD_DRAG_LEFT:
|
|
|
|
if (seg)
|
2000-12-20 05:49:46 +08:00
|
|
|
{
|
2001-11-27 23:44:02 +08:00
|
|
|
control_draw_normal_handle (editor, pixmap,
|
2001-02-18 05:20:10 +08:00
|
|
|
seg->left, height);
|
2000-12-20 05:49:46 +08:00
|
|
|
}
|
1999-09-28 01:58:10 +08:00
|
|
|
else
|
|
|
|
{
|
2001-02-13 08:12:15 +08:00
|
|
|
seg = gimp_gradient_segment_get_last (gradient->segments);
|
2000-12-20 05:49:46 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
control_draw_normal_handle (editor, pixmap,
|
2001-02-18 05:20:10 +08:00
|
|
|
seg->right, height);
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
case GRAD_DRAG_MIDDLE:
|
2001-11-27 23:44:02 +08:00
|
|
|
control_draw_middle_handle (editor, pixmap, seg->middle, height);
|
1999-09-28 01:58:10 +08:00
|
|
|
break;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
control_draw_normal_handle (GimpGradientEditor *editor,
|
|
|
|
GdkPixmap *pixmap,
|
|
|
|
gdouble pos,
|
|
|
|
gint height)
|
1999-09-28 01:58:10 +08:00
|
|
|
{
|
|
|
|
control_draw_handle (pixmap,
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control->style->black_gc,
|
|
|
|
editor->control->style->black_gc,
|
|
|
|
control_calc_p_pos (editor, pos), height);
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
2002-03-08 08:27:45 +08:00
|
|
|
control_draw_middle_handle (GimpGradientEditor *editor,
|
|
|
|
GdkPixmap *pixmap,
|
|
|
|
gdouble pos,
|
|
|
|
gint height)
|
1999-09-28 01:58:10 +08:00
|
|
|
{
|
|
|
|
control_draw_handle (pixmap,
|
2001-11-27 23:44:02 +08:00
|
|
|
editor->control->style->black_gc,
|
|
|
|
editor->control->style->bg_gc[GTK_STATE_PRELIGHT],
|
|
|
|
control_calc_p_pos (editor, pos), height);
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
static void
|
1999-09-28 01:58:10 +08:00
|
|
|
control_draw_handle (GdkPixmap *pixmap,
|
|
|
|
GdkGC *border_gc,
|
|
|
|
GdkGC *fill_gc,
|
2000-12-20 05:49:46 +08:00
|
|
|
gint xpos,
|
|
|
|
gint height)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-12-20 05:49:46 +08:00
|
|
|
gint y;
|
|
|
|
gint left, right, bottom;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
gdk_draw_line (pixmap, fill_gc, xpos - y / 2, y, xpos + y / 2, y);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
bottom = height - 1;
|
|
|
|
left = xpos - bottom / 2;
|
|
|
|
right = xpos + bottom / 2;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
gdk_draw_line (pixmap, border_gc, xpos, 0, left, bottom);
|
|
|
|
gdk_draw_line (pixmap, border_gc, xpos, 0, right, bottom);
|
|
|
|
gdk_draw_line (pixmap, border_gc, left, bottom, right, bottom);
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/*****/
|
|
|
|
|
2000-12-20 05:49:46 +08:00
|
|
|
static gint
|
2002-03-08 08:27:45 +08:00
|
|
|
control_calc_p_pos (GimpGradientEditor *editor,
|
|
|
|
gdouble pos)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
1999-09-28 01:58:10 +08:00
|
|
|
gint pwidth, pheight;
|
|
|
|
GtkAdjustment *adjustment;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Calculate the position (in widget's coordinates) of the
|
|
|
|
* requested point from the gradient. Rounding is done to
|
|
|
|
* minimize mismatches between the rendered gradient preview
|
|
|
|
* and the gradient control's handles.
|
|
|
|
*/
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
adjustment = GTK_ADJUSTMENT (editor->scroll_data);
|
|
|
|
gdk_drawable_get_size (editor->control_pixmap, &pwidth, &pheight);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-12-20 05:49:46 +08:00
|
|
|
return RINT ((pwidth - 1) * (pos - adjustment->value) / adjustment->page_size);
|
1999-09-28 01:58:10 +08:00
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2000-12-20 05:49:46 +08:00
|
|
|
static gdouble
|
2002-03-08 08:27:45 +08:00
|
|
|
control_calc_g_pos (GimpGradientEditor *editor,
|
|
|
|
gint pos)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2000-12-20 05:49:46 +08:00
|
|
|
gint pwidth, pheight;
|
1999-09-28 01:58:10 +08:00
|
|
|
GtkAdjustment *adjustment;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
/* Calculate the gradient position that corresponds to widget's coordinates */
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-11-27 23:44:02 +08:00
|
|
|
adjustment = GTK_ADJUSTMENT (editor->scroll_data);
|
|
|
|
gdk_drawable_get_size (editor->control_pixmap, &pwidth, &pheight);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
return adjustment->page_size * pos / (pwidth - 1) + adjustment->value;
|
|
|
|
}
|
1997-11-25 06:05:25 +08:00
|
|
|
|
|
|
|
/***** Segment functions *****/
|
|
|
|
|
|
|
|
static void
|
2001-11-27 23:44:02 +08:00
|
|
|
seg_get_closest_handle (GimpGradient *grad,
|
|
|
|
gdouble pos,
|
|
|
|
GimpGradientSegment **seg,
|
|
|
|
GradientEditorDragMode *handle)
|
1997-11-25 06:05:25 +08:00
|
|
|
{
|
2001-02-13 08:12:15 +08:00
|
|
|
gdouble l_delta, m_delta, r_delta;
|
1997-11-25 06:05:25 +08:00
|
|
|
|
2001-02-11 03:35:29 +08:00
|
|
|
*seg = gimp_gradient_get_segment_at (grad, pos);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
m_delta = fabs (pos - (*seg)->middle);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (pos < (*seg)->middle)
|
|
|
|
{
|
|
|
|
l_delta = fabs (pos - (*seg)->left);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (l_delta < m_delta)
|
|
|
|
*handle = GRAD_DRAG_LEFT;
|
|
|
|
else
|
|
|
|
*handle = GRAD_DRAG_MIDDLE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
r_delta = fabs (pos - (*seg)->right);
|
1997-11-25 06:05:25 +08:00
|
|
|
|
1999-09-28 01:58:10 +08:00
|
|
|
if (m_delta < r_delta)
|
|
|
|
{
|
|
|
|
*handle = GRAD_DRAG_MIDDLE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*seg = (*seg)->next;
|
|
|
|
*handle = GRAD_DRAG_LEFT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|