From aa9931f8be6eb313ee956d84477c99440e6fd7ad Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Tue, 9 Jan 2001 01:39:37 +0000 Subject: [PATCH] added a new simple widget which provides a color preview area capable of 2001-01-09 Sven Neumann * libgimp/gimpcolorarea.[ch]: added a new simple widget which provides a color preview area capable of DND. It will be used in the GimpColorButton and in the color_selectors. * libgimp/Makefile.am * libgimp/gimpui.h * libgimp/gimpuitypes.h: include the new files * libgimp/gimpcolor.[ch]: use proper names instead of abbreviations * app/asupsample.c * plug-ins/Lighting/lighting_preview.c * plug-ins/Lighting/lighting_shade.c * plug-ins/MapObject/mapobject_preview.c * plug-ins/MapObject/mapobject_shade.c * plug-ins/libgck/gck/gckcolor.c: changed accordingly --- ChangeLog | 19 ++ app/asupsample.c | 12 +- libgimp/Makefile.am | 3 +- libgimp/gimpcolor.c | 24 +- libgimp/gimpcolor.h | 70 ++--- libgimp/gimpcolorarea.c | 403 +++++++++++++++++++++++++ libgimp/gimpcolorarea.h | 63 ++++ libgimp/gimpui.h | 1 + libgimp/gimpuitypes.h | 1 + libgimpwidgets/gimpcolorarea.c | 403 +++++++++++++++++++++++++ libgimpwidgets/gimpcolorarea.h | 63 ++++ plug-ins/Lighting/lighting_preview.c | 8 +- plug-ins/Lighting/lighting_shade.c | 12 +- plug-ins/MapObject/mapobject_preview.c | 8 +- plug-ins/MapObject/mapobject_shade.c | 12 +- plug-ins/libgck/gck/gckcolor.c | 12 +- 16 files changed, 1034 insertions(+), 80 deletions(-) create mode 100644 libgimp/gimpcolorarea.c create mode 100644 libgimp/gimpcolorarea.h create mode 100644 libgimpwidgets/gimpcolorarea.c create mode 100644 libgimpwidgets/gimpcolorarea.h diff --git a/ChangeLog b/ChangeLog index f948714e00..1084b4c5e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2001-01-09 Sven Neumann + + * libgimp/gimpcolorarea.[ch]: added a new simple widget which + provides a color preview area capable of DND. It will be used + in the GimpColorButton and in the color_selectors. + + * libgimp/Makefile.am + * libgimp/gimpui.h + * libgimp/gimpuitypes.h: include the new files + + * libgimp/gimpcolor.[ch]: use proper names instead of abbreviations + + * app/asupsample.c + * plug-ins/Lighting/lighting_preview.c + * plug-ins/Lighting/lighting_shade.c + * plug-ins/MapObject/mapobject_preview.c + * plug-ins/MapObject/mapobject_shade.c + * plug-ins/libgck/gck/gckcolor.c: changed accordingly + 2001-01-09 Michael Natterer * app/color_notebook.[ch] diff --git a/app/asupsample.c b/app/asupsample.c index ba1004ca9f..ef98b51d76 100644 --- a/app/asupsample.c +++ b/app/asupsample.c @@ -335,12 +335,12 @@ render_sub_pixel (gint max_depth, { /* Check whether we have tu supersample */ - if ((gimp_rgba_dist (&c1, &c2) >= threshold) || - (gimp_rgba_dist (&c1, &c3) >= threshold) || - (gimp_rgba_dist (&c1, &c4) >= threshold) || - (gimp_rgba_dist (&c2, &c3) >= threshold) || - (gimp_rgba_dist (&c2, &c4) >= threshold) || - (gimp_rgba_dist (&c3, &c4) >= threshold)) { + if ((gimp_rgba_distance (&c1, &c2) >= threshold) || + (gimp_rgba_distance (&c1, &c3) >= threshold) || + (gimp_rgba_distance (&c1, &c4) >= threshold) || + (gimp_rgba_distance (&c2, &c3) >= threshold) || + (gimp_rgba_distance (&c2, &c4) >= threshold) || + (gimp_rgba_distance (&c3, &c4) >= threshold)) { /* Calc coordinates of center subsample */ x2 = (x1 + x3) / 2; diff --git a/libgimp/Makefile.am b/libgimp/Makefile.am index 85db987ee0..8a07372fd6 100644 --- a/libgimp/Makefile.am +++ b/libgimp/Makefile.am @@ -209,8 +209,8 @@ libgimpui_la_SOURCES = \ gimpgradientmenu.c \ gimppatternmenu.c \ gimpchainbutton.c \ + gimpcolorarea.c \ gimpcolorbutton.c \ - gimpcolorbutton.h \ gimpdialog.c \ gimpexport.c \ gimpfileselection.c \ @@ -230,6 +230,7 @@ gimpinclude_HEADERS = \ gimpchainbutton.h \ gimpchannel.h \ gimpcolor.h \ + gimpcolorarea.h \ gimpcolorbutton.h \ gimpcolordisplay.h \ gimpcolorselector.h \ diff --git a/libgimp/gimpcolor.c b/libgimp/gimpcolor.c index 5b07aadbdc..5cec9ab883 100644 --- a/libgimp/gimpcolor.c +++ b/libgimp/gimpcolor.c @@ -58,8 +58,8 @@ gimp_rgb_add (GimpRGB *rgb1, } void -gimp_rgb_sub (GimpRGB *rgb1, - const GimpRGB *rgb2) +gimp_rgb_subtract (GimpRGB *rgb1, + const GimpRGB *rgb2) { g_return_if_fail (rgb1 != NULL); g_return_if_fail (rgb2 != NULL); @@ -70,8 +70,8 @@ gimp_rgb_sub (GimpRGB *rgb1, } void -gimp_rgb_mul (GimpRGB *rgb, - gdouble factor) +gimp_rgb_multiply (GimpRGB *rgb, + gdouble factor) { g_return_if_fail (rgb != NULL); @@ -81,8 +81,8 @@ gimp_rgb_mul (GimpRGB *rgb, } gdouble -gimp_rgb_dist (const GimpRGB *rgb1, - const GimpRGB *rgb2) +gimp_rgb_distance (const GimpRGB *rgb1, + const GimpRGB *rgb2) { g_return_val_if_fail (rgb1 != NULL, 0.0); g_return_val_if_fail (rgb2 != NULL, 0.0); @@ -168,8 +168,8 @@ gimp_rgba_add (GimpRGB *rgba1, } void -gimp_rgba_sub (GimpRGB *rgba1, - const GimpRGB *rgba2) +gimp_rgba_subtract (GimpRGB *rgba1, + const GimpRGB *rgba2) { g_return_if_fail (rgba1 != NULL); g_return_if_fail (rgba2 != NULL); @@ -181,8 +181,8 @@ gimp_rgba_sub (GimpRGB *rgba1, } void -gimp_rgba_mul (GimpRGB *rgba, - gdouble factor) +gimp_rgba_multiply (GimpRGB *rgba, + gdouble factor) { g_return_if_fail (rgba != NULL); @@ -193,8 +193,8 @@ gimp_rgba_mul (GimpRGB *rgba, } gdouble -gimp_rgba_dist (const GimpRGB *rgba1, - const GimpRGB *rgba2) +gimp_rgba_distance (const GimpRGB *rgba1, + const GimpRGB *rgba2) { g_return_val_if_fail (rgba1 != NULL, 0.0); g_return_val_if_fail (rgba2 != NULL, 0.0); diff --git a/libgimp/gimpcolor.h b/libgimp/gimpcolor.h index 2759ed2314..051e57a219 100644 --- a/libgimp/gimpcolor.h +++ b/libgimp/gimpcolor.h @@ -37,45 +37,45 @@ struct _GimpRGB }; -void gimp_rgb_set (GimpRGB *rgb, - gdouble r, - gdouble g, - gdouble b); +void gimp_rgb_set (GimpRGB *rgb, + gdouble r, + gdouble g, + gdouble b); -void gimp_rgb_add (GimpRGB *rgb1, - const GimpRGB *rgb2); -void gimp_rgb_sub (GimpRGB *rgb1, - const GimpRGB *rgb2); -void gimp_rgb_mul (GimpRGB *rgb1, - gdouble factor); -gdouble gimp_rgb_dist (const GimpRGB *rgb1, - const GimpRGB *rgb2); -gdouble gimp_rgb_max (const GimpRGB *rgb); -gdouble gimp_rgb_min (const GimpRGB *rgb); -void gimp_rgb_clamp (GimpRGB *rgb); -void gimp_rgb_gamma (GimpRGB *rgb, - gdouble gamma); +void gimp_rgb_add (GimpRGB *rgb1, + const GimpRGB *rgb2); +void gimp_rgb_subtract (GimpRGB *rgb1, + const GimpRGB *rgb2); +void gimp_rgb_multiply (GimpRGB *rgb1, + gdouble factor); +gdouble gimp_rgb_distance (const GimpRGB *rgb1, + const GimpRGB *rgb2); +gdouble gimp_rgb_max (const GimpRGB *rgb); +gdouble gimp_rgb_min (const GimpRGB *rgb); +void gimp_rgb_clamp (GimpRGB *rgb); +void gimp_rgb_gamma (GimpRGB *rgb, + gdouble gamma); -void gimp_rgba_set (GimpRGB *rgba, - gdouble r, - gdouble g, - gdouble b, - gdouble a); +void gimp_rgba_set (GimpRGB *rgba, + gdouble r, + gdouble g, + gdouble b, + gdouble a); -void gimp_rgba_add (GimpRGB *rgba1, - const GimpRGB *rgba2); -void gimp_rgba_sub (GimpRGB *rgba1, - const GimpRGB *rgba2); -void gimp_rgba_mul (GimpRGB *rgba, - gdouble factor); -gdouble gimp_rgba_dist (const GimpRGB *rgba1, - const GimpRGB *rgba2); -gdouble gimp_rgba_max (const GimpRGB *rgba); -gdouble gimp_rgba_min (const GimpRGB *rgba); -void gimp_rgba_clamp (GimpRGB *rgba); -void gimp_rgba_gamma (GimpRGB *rgba, - gdouble gamma); +void gimp_rgba_add (GimpRGB *rgba1, + const GimpRGB *rgba2); +void gimp_rgba_subtract (GimpRGB *rgba1, + const GimpRGB *rgba2); +void gimp_rgba_multiply (GimpRGB *rgba, + gdouble factor); +gdouble gimp_rgba_distance (const GimpRGB *rgba1, + const GimpRGB *rgba2); +gdouble gimp_rgba_max (const GimpRGB *rgba); +gdouble gimp_rgba_min (const GimpRGB *rgba); +void gimp_rgba_clamp (GimpRGB *rgba); +void gimp_rgba_gamma (GimpRGB *rgba, + gdouble gamma); #ifdef __cplusplus diff --git a/libgimp/gimpcolorarea.c b/libgimp/gimpcolorarea.c new file mode 100644 index 0000000000..e63c6b031a --- /dev/null +++ b/libgimp/gimpcolorarea.c @@ -0,0 +1,403 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpcolorarea.c + * Copyright (C) 2001 Sven Neumann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "gimp.h" + +#include "gimpuitypes.h" + +#include "gimpcolorarea.h" +#include "gimplimits.h" + + +#define DRAG_PREVIEW_SIZE 32 +#define DRAG_ICON_OFFSET -8 + + +static const GtkTargetEntry targets[] = { { "application/x-color", 0 } }; + + +struct _GimpColorArea +{ + GtkPreview preview; + + gboolean alpha; + GimpRGB color; +}; + +enum +{ + COLOR_CHANGED, + LAST_SIGNAL +}; + +static guint gimp_color_area_signals[LAST_SIGNAL] = { 0 }; +static GtkWidgetClass *parent_class = NULL; + + +static void gimp_color_area_class_init (GimpColorAreaClass *class); +static void gimp_color_area_init (GimpColorArea *gca); +static void gimp_color_area_destroy (GtkObject *object); +static void gimp_color_area_paint (GimpColorArea *gca); + +static void gimp_color_area_drag_begin (GtkWidget *widget, + GdkDragContext *context); +static void gimp_color_area_drag_end (GtkWidget *widget, + GdkDragContext *context); +static void gimp_color_area_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time); +static void gimp_color_area_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time); + +GtkType +gimp_color_area_get_type (void) +{ + static guint gca_type = 0; + + if (!gca_type) + { + GtkTypeInfo gca_info = + { + "GimpColorArea", + sizeof (GimpColorArea), + sizeof (GimpColorAreaClass), + (GtkClassInitFunc) gimp_color_area_class_init, + (GtkObjectInitFunc) gimp_color_area_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL + }; + + gca_type = gtk_type_unique (gtk_preview_get_type (), &gca_info); + } + + return gca_type; +} + +static void +gimp_color_area_class_init (GimpColorAreaClass *class) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + + object_class = (GtkObjectClass*) class; + widget_class = (GtkWidgetClass*) class; + + parent_class = gtk_type_class (gtk_preview_get_type ()); + + gimp_color_area_signals[COLOR_CHANGED] = + gtk_signal_new ("color_changed", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (GimpColorAreaClass, + color_changed), + gtk_marshal_NONE__POINTER , + GTK_TYPE_NONE, + 1, GTK_TYPE_POINTER); + + gtk_object_class_add_signals (object_class, gimp_color_area_signals, + LAST_SIGNAL); + + class->color_changed = NULL; + + object_class->destroy = gimp_color_area_destroy; + + widget_class->drag_begin = gimp_color_area_drag_begin; + widget_class->drag_end = gimp_color_area_drag_end; + widget_class->drag_data_received = gimp_color_area_drag_data_received; + widget_class->drag_data_get = gimp_color_area_drag_data_get; +} + +static void +gimp_color_area_init (GimpColorArea *gca) +{ + gca->alpha = FALSE; +} + +static void +gimp_color_area_destroy (GtkObject *object) +{ + GimpColorArea *gca; + + g_return_if_fail (object != NULL); + g_return_if_fail (GIMP_IS_COLOR_AREA (object)); + + gca = GIMP_COLOR_AREA (object); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + GTK_OBJECT_CLASS (parent_class)->destroy (object); +} + +/** + * gimp_color_area_new: + * @color: An array of guchar holding the color (RGB or RGBA) + * @bpp: May be 3 for RGB or 4 for RGBA. + * + * Creates a new #GimpColorArea widget. + * + * This returns a preview area showing the color. It handles color + * DND. If the color changes, the "color_changed" signal is emitted. + * + * Returns: Pointer to the new #GimpColorArea widget. + **/ +GtkWidget * +gimp_color_area_new (GimpRGB *color, + gboolean alpha) +{ + GimpColorArea *gca; + + g_return_val_if_fail (color != NULL, NULL); + + gca = gtk_type_new (gimp_color_area_get_type ()); + + gca->color = *color; + + GTK_PREVIEW (gca)->type = GTK_PREVIEW_COLOR; + GTK_PREVIEW (gca)->bpp = 3; + GTK_PREVIEW (gca)->dither = GDK_RGB_DITHER_NORMAL; + GTK_PREVIEW (gca)->expand = TRUE; + + gtk_signal_connect_after (GTK_OBJECT (gca), "size_allocate", + GTK_SIGNAL_FUNC (gimp_color_area_paint), + NULL); + + gtk_drag_dest_set (GTK_WIDGET (gca), + GTK_DEST_DEFAULT_HIGHLIGHT | + GTK_DEST_DEFAULT_MOTION | + GTK_DEST_DEFAULT_DROP, + targets, 1, + GDK_ACTION_COPY); + gtk_drag_source_set (GTK_WIDGET (gca), + GDK_BUTTON2_MASK, + targets, 1, + GDK_ACTION_COPY | GDK_ACTION_MOVE); + + return GTK_WIDGET (gca); +} + +/** + * gimp_color_area_set_color: + * @gca: Pointer to a #GimpColorArea. + * @color: + * + **/ +void +gimp_color_area_set_color (GimpColorArea *gca, + GimpRGB *color) +{ + g_return_if_fail (gca != NULL); + g_return_if_fail (GIMP_IS_COLOR_AREA (gca)); + + g_return_if_fail (color != NULL); + + if (gimp_rgba_distance (&gca->color, color) > 0.000001) + { + gca->color = *color; + + gimp_color_area_paint (gca); + + gtk_signal_emit (GTK_OBJECT (gca), + gimp_color_area_signals[COLOR_CHANGED], + &gca->color); + } +} + +static void +gimp_color_area_paint (GimpColorArea *gca) +{ + gint x, y; + gdouble c0, c1; + guint width, height; + guchar *p0, *p1; + guchar *even, *odd; + + g_return_if_fail (gca != NULL); + g_return_if_fail (GIMP_IS_COLOR_AREA (gca)); + + if (! GTK_WIDGET_DRAWABLE (GTK_WIDGET (gca))) + return; + + gdk_window_get_size (GTK_WIDGET (gca)->window, &width, &height); + + if (!width || !height) + return; + + p0 = even = g_new (guchar, width * 3); + p1 = odd = g_new (guchar, width * 3); + + if (gca->alpha) + { + for (x = 0; x < width; x++) + { + if ((x / GIMP_CHECK_SIZE_SM) & 1) + { + c0 = GIMP_CHECK_LIGHT; + c1 = GIMP_CHECK_DARK; + } + else + { + c0 = GIMP_CHECK_DARK; + c1 = GIMP_CHECK_LIGHT; + } + + *p0++ = (c0 + (gca->color.r - c0) * gca->color.a) * 255.999; + *p1++ = (c1 + (gca->color.r - c1) * gca->color.a) * 255.999; + *p0++ = (c0 + (gca->color.g - c0) * gca->color.a) * 255.999; + *p1++ = (c1 + (gca->color.g - c1) * gca->color.a) * 255.999; + *p0++ = (c0 + (gca->color.b - c0) * gca->color.a) * 255.999; + *p1++ = (c1 + (gca->color.b - c1) * gca->color.a) * 255.999; + } + + for (y = 0; y < height; y++) + { + if ((y / GIMP_CHECK_SIZE_SM) & 1) + gtk_preview_draw_row (GTK_PREVIEW (gca), odd, 0, y, width); + else + gtk_preview_draw_row (GTK_PREVIEW (gca), even, 0, y, width); + } + } + else + { + for (x = 0; x < width; x++) + { + *p0++ = gca->color.r; + *p0++ = gca->color.g; + *p0++ = gca->color.b; + } + + for (y = 0; y < height; y++) + gtk_preview_draw_row (GTK_PREVIEW (gca), even, 0, y, width); + } + + g_free (even); + g_free (odd); + + gtk_widget_queue_draw (GTK_WIDGET (gca)); +} + +static void +gimp_color_area_drag_begin (GtkWidget *widget, + GdkDragContext *context) +{ + GimpColorArea *gca; + GtkWidget *window; + GdkColor bg; + + gca = GIMP_COLOR_AREA (widget); + + window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); + gtk_widget_set_usize (window, DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE); + gtk_widget_realize (window); + gtk_object_set_data_full (GTK_OBJECT (widget), + "gimp-color-button-drag-window", + window, + (GtkDestroyNotify) gtk_widget_destroy); + + bg.red = gca->color.r * 0xffff; + bg.green = gca->color.g * 0xffff; + bg.blue = gca->color.b * 0xffff; + + gdk_color_alloc (gtk_widget_get_colormap (window), &bg); + gdk_window_set_background (window->window, &bg); + + gtk_drag_set_icon_widget (context, window, DRAG_ICON_OFFSET, DRAG_ICON_OFFSET); +} + +static void +gimp_color_area_drag_end (GtkWidget *widget, + GdkDragContext *context) +{ + gtk_object_set_data (GTK_OBJECT (widget), + "gimp-color-area-drag-window", NULL); +} + +static void +gimp_color_area_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + GimpColorArea *gca; + GimpRGB color; + guint16 *vals; + + gca = GIMP_COLOR_AREA (widget); + + if (selection_data->length < 0) + return; + + if ((selection_data->format != 16) || + (selection_data->length != 8)) + { + g_warning ("Received invalid color data\n"); + return; + } + + vals = (guint16 *)selection_data->data; + + gimp_rgba_set (&color, + (gdouble) vals[0] / 0xffff, + (gdouble) vals[1] / 0xffff, + (gdouble) vals[2] / 0xffff, + (gdouble) vals[3] / 0xffff); + + gimp_color_area_set_color (gca, &color); +} + +static void +gimp_color_area_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + GimpColorArea *gca; + guint16 vals[4]; + + gca = GIMP_COLOR_AREA (widget); + + vals[0] = gca->color.r * 0xffff; + vals[1] = gca->color.g * 0xffff; + vals[2] = gca->color.b * 0xffff; + vals[3] = gca->color.a * 0xffff; + + gtk_selection_data_set (selection_data, + gdk_atom_intern ("application/x-color", FALSE), + 16, (guchar *)vals, 8); +} + + diff --git a/libgimp/gimpcolorarea.h b/libgimp/gimpcolorarea.h new file mode 100644 index 0000000000..449e4d1f53 --- /dev/null +++ b/libgimp/gimpcolorarea.h @@ -0,0 +1,63 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpcolorarea.h + * Copyright (C) 2001 Sven Neumann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* This provides a color preview area. The preview + * can handle transparency by showing the checkerboard and + * handles drag'n'drop. + */ + +#ifndef __GIMP_COLOR_AREA_H__ +#define __GIMP_COLOR_AREA_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GIMP_TYPE_COLOR_AREA (gimp_color_area_get_type ()) +#define GIMP_COLOR_AREA(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_COLOR_AREA, GimpColorArea)) +#define GIMP_COLOR_AREA_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_COLOR_AREA, GimpColorAreaClass)) +#define GIMP_IS_COLOR_AREA(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_COLOR_AREA)) +#define GIMP_IS_COLOR_AREA_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_COLOR_AREA)) + +typedef struct _GimpColorAreaClass GimpColorAreaClass; + +struct _GimpColorAreaClass +{ + GtkPreviewClass parent_class; + + void (* color_changed) (GimpColorArea *gca, + GimpRGB *color); +}; + + +GtkType gimp_color_area_get_type (void); +GtkWidget * gimp_color_area_new (GimpRGB *color, + gboolean alpha); +void gimp_color_area_update (GimpColorArea *gca); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GIMP_COLOR_AREA_H__ */ diff --git a/libgimp/gimpui.h b/libgimp/gimpui.h index 9a0334ceb3..9b7b700d0d 100644 --- a/libgimp/gimpui.h +++ b/libgimp/gimpui.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/libgimp/gimpuitypes.h b/libgimp/gimpuitypes.h index 5e7ddb169f..591dc82757 100644 --- a/libgimp/gimpuitypes.h +++ b/libgimp/gimpuitypes.h @@ -36,6 +36,7 @@ typedef enum GIMP_SIZE_ENTRY_UPDATE_RESOLUTION = 2 } GimpSizeEntryUpdatePolicy; +typedef struct _GimpColorArea GimpColorArea; typedef struct _GimpColorButton GimpColorButton; typedef struct _GimpPathEditor GimpPathEditor; typedef struct _GimpSizeEntry GimpSizeEntry; diff --git a/libgimpwidgets/gimpcolorarea.c b/libgimpwidgets/gimpcolorarea.c new file mode 100644 index 0000000000..e63c6b031a --- /dev/null +++ b/libgimpwidgets/gimpcolorarea.c @@ -0,0 +1,403 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpcolorarea.c + * Copyright (C) 2001 Sven Neumann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "gimp.h" + +#include "gimpuitypes.h" + +#include "gimpcolorarea.h" +#include "gimplimits.h" + + +#define DRAG_PREVIEW_SIZE 32 +#define DRAG_ICON_OFFSET -8 + + +static const GtkTargetEntry targets[] = { { "application/x-color", 0 } }; + + +struct _GimpColorArea +{ + GtkPreview preview; + + gboolean alpha; + GimpRGB color; +}; + +enum +{ + COLOR_CHANGED, + LAST_SIGNAL +}; + +static guint gimp_color_area_signals[LAST_SIGNAL] = { 0 }; +static GtkWidgetClass *parent_class = NULL; + + +static void gimp_color_area_class_init (GimpColorAreaClass *class); +static void gimp_color_area_init (GimpColorArea *gca); +static void gimp_color_area_destroy (GtkObject *object); +static void gimp_color_area_paint (GimpColorArea *gca); + +static void gimp_color_area_drag_begin (GtkWidget *widget, + GdkDragContext *context); +static void gimp_color_area_drag_end (GtkWidget *widget, + GdkDragContext *context); +static void gimp_color_area_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time); +static void gimp_color_area_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time); + +GtkType +gimp_color_area_get_type (void) +{ + static guint gca_type = 0; + + if (!gca_type) + { + GtkTypeInfo gca_info = + { + "GimpColorArea", + sizeof (GimpColorArea), + sizeof (GimpColorAreaClass), + (GtkClassInitFunc) gimp_color_area_class_init, + (GtkObjectInitFunc) gimp_color_area_init, + /* reserved_1 */ NULL, + /* reserved_2 */ NULL, + (GtkClassInitFunc) NULL + }; + + gca_type = gtk_type_unique (gtk_preview_get_type (), &gca_info); + } + + return gca_type; +} + +static void +gimp_color_area_class_init (GimpColorAreaClass *class) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + + object_class = (GtkObjectClass*) class; + widget_class = (GtkWidgetClass*) class; + + parent_class = gtk_type_class (gtk_preview_get_type ()); + + gimp_color_area_signals[COLOR_CHANGED] = + gtk_signal_new ("color_changed", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (GimpColorAreaClass, + color_changed), + gtk_marshal_NONE__POINTER , + GTK_TYPE_NONE, + 1, GTK_TYPE_POINTER); + + gtk_object_class_add_signals (object_class, gimp_color_area_signals, + LAST_SIGNAL); + + class->color_changed = NULL; + + object_class->destroy = gimp_color_area_destroy; + + widget_class->drag_begin = gimp_color_area_drag_begin; + widget_class->drag_end = gimp_color_area_drag_end; + widget_class->drag_data_received = gimp_color_area_drag_data_received; + widget_class->drag_data_get = gimp_color_area_drag_data_get; +} + +static void +gimp_color_area_init (GimpColorArea *gca) +{ + gca->alpha = FALSE; +} + +static void +gimp_color_area_destroy (GtkObject *object) +{ + GimpColorArea *gca; + + g_return_if_fail (object != NULL); + g_return_if_fail (GIMP_IS_COLOR_AREA (object)); + + gca = GIMP_COLOR_AREA (object); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + GTK_OBJECT_CLASS (parent_class)->destroy (object); +} + +/** + * gimp_color_area_new: + * @color: An array of guchar holding the color (RGB or RGBA) + * @bpp: May be 3 for RGB or 4 for RGBA. + * + * Creates a new #GimpColorArea widget. + * + * This returns a preview area showing the color. It handles color + * DND. If the color changes, the "color_changed" signal is emitted. + * + * Returns: Pointer to the new #GimpColorArea widget. + **/ +GtkWidget * +gimp_color_area_new (GimpRGB *color, + gboolean alpha) +{ + GimpColorArea *gca; + + g_return_val_if_fail (color != NULL, NULL); + + gca = gtk_type_new (gimp_color_area_get_type ()); + + gca->color = *color; + + GTK_PREVIEW (gca)->type = GTK_PREVIEW_COLOR; + GTK_PREVIEW (gca)->bpp = 3; + GTK_PREVIEW (gca)->dither = GDK_RGB_DITHER_NORMAL; + GTK_PREVIEW (gca)->expand = TRUE; + + gtk_signal_connect_after (GTK_OBJECT (gca), "size_allocate", + GTK_SIGNAL_FUNC (gimp_color_area_paint), + NULL); + + gtk_drag_dest_set (GTK_WIDGET (gca), + GTK_DEST_DEFAULT_HIGHLIGHT | + GTK_DEST_DEFAULT_MOTION | + GTK_DEST_DEFAULT_DROP, + targets, 1, + GDK_ACTION_COPY); + gtk_drag_source_set (GTK_WIDGET (gca), + GDK_BUTTON2_MASK, + targets, 1, + GDK_ACTION_COPY | GDK_ACTION_MOVE); + + return GTK_WIDGET (gca); +} + +/** + * gimp_color_area_set_color: + * @gca: Pointer to a #GimpColorArea. + * @color: + * + **/ +void +gimp_color_area_set_color (GimpColorArea *gca, + GimpRGB *color) +{ + g_return_if_fail (gca != NULL); + g_return_if_fail (GIMP_IS_COLOR_AREA (gca)); + + g_return_if_fail (color != NULL); + + if (gimp_rgba_distance (&gca->color, color) > 0.000001) + { + gca->color = *color; + + gimp_color_area_paint (gca); + + gtk_signal_emit (GTK_OBJECT (gca), + gimp_color_area_signals[COLOR_CHANGED], + &gca->color); + } +} + +static void +gimp_color_area_paint (GimpColorArea *gca) +{ + gint x, y; + gdouble c0, c1; + guint width, height; + guchar *p0, *p1; + guchar *even, *odd; + + g_return_if_fail (gca != NULL); + g_return_if_fail (GIMP_IS_COLOR_AREA (gca)); + + if (! GTK_WIDGET_DRAWABLE (GTK_WIDGET (gca))) + return; + + gdk_window_get_size (GTK_WIDGET (gca)->window, &width, &height); + + if (!width || !height) + return; + + p0 = even = g_new (guchar, width * 3); + p1 = odd = g_new (guchar, width * 3); + + if (gca->alpha) + { + for (x = 0; x < width; x++) + { + if ((x / GIMP_CHECK_SIZE_SM) & 1) + { + c0 = GIMP_CHECK_LIGHT; + c1 = GIMP_CHECK_DARK; + } + else + { + c0 = GIMP_CHECK_DARK; + c1 = GIMP_CHECK_LIGHT; + } + + *p0++ = (c0 + (gca->color.r - c0) * gca->color.a) * 255.999; + *p1++ = (c1 + (gca->color.r - c1) * gca->color.a) * 255.999; + *p0++ = (c0 + (gca->color.g - c0) * gca->color.a) * 255.999; + *p1++ = (c1 + (gca->color.g - c1) * gca->color.a) * 255.999; + *p0++ = (c0 + (gca->color.b - c0) * gca->color.a) * 255.999; + *p1++ = (c1 + (gca->color.b - c1) * gca->color.a) * 255.999; + } + + for (y = 0; y < height; y++) + { + if ((y / GIMP_CHECK_SIZE_SM) & 1) + gtk_preview_draw_row (GTK_PREVIEW (gca), odd, 0, y, width); + else + gtk_preview_draw_row (GTK_PREVIEW (gca), even, 0, y, width); + } + } + else + { + for (x = 0; x < width; x++) + { + *p0++ = gca->color.r; + *p0++ = gca->color.g; + *p0++ = gca->color.b; + } + + for (y = 0; y < height; y++) + gtk_preview_draw_row (GTK_PREVIEW (gca), even, 0, y, width); + } + + g_free (even); + g_free (odd); + + gtk_widget_queue_draw (GTK_WIDGET (gca)); +} + +static void +gimp_color_area_drag_begin (GtkWidget *widget, + GdkDragContext *context) +{ + GimpColorArea *gca; + GtkWidget *window; + GdkColor bg; + + gca = GIMP_COLOR_AREA (widget); + + window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE); + gtk_widget_set_usize (window, DRAG_PREVIEW_SIZE, DRAG_PREVIEW_SIZE); + gtk_widget_realize (window); + gtk_object_set_data_full (GTK_OBJECT (widget), + "gimp-color-button-drag-window", + window, + (GtkDestroyNotify) gtk_widget_destroy); + + bg.red = gca->color.r * 0xffff; + bg.green = gca->color.g * 0xffff; + bg.blue = gca->color.b * 0xffff; + + gdk_color_alloc (gtk_widget_get_colormap (window), &bg); + gdk_window_set_background (window->window, &bg); + + gtk_drag_set_icon_widget (context, window, DRAG_ICON_OFFSET, DRAG_ICON_OFFSET); +} + +static void +gimp_color_area_drag_end (GtkWidget *widget, + GdkDragContext *context) +{ + gtk_object_set_data (GTK_OBJECT (widget), + "gimp-color-area-drag-window", NULL); +} + +static void +gimp_color_area_drag_data_received (GtkWidget *widget, + GdkDragContext *context, + gint x, + gint y, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + GimpColorArea *gca; + GimpRGB color; + guint16 *vals; + + gca = GIMP_COLOR_AREA (widget); + + if (selection_data->length < 0) + return; + + if ((selection_data->format != 16) || + (selection_data->length != 8)) + { + g_warning ("Received invalid color data\n"); + return; + } + + vals = (guint16 *)selection_data->data; + + gimp_rgba_set (&color, + (gdouble) vals[0] / 0xffff, + (gdouble) vals[1] / 0xffff, + (gdouble) vals[2] / 0xffff, + (gdouble) vals[3] / 0xffff); + + gimp_color_area_set_color (gca, &color); +} + +static void +gimp_color_area_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + GimpColorArea *gca; + guint16 vals[4]; + + gca = GIMP_COLOR_AREA (widget); + + vals[0] = gca->color.r * 0xffff; + vals[1] = gca->color.g * 0xffff; + vals[2] = gca->color.b * 0xffff; + vals[3] = gca->color.a * 0xffff; + + gtk_selection_data_set (selection_data, + gdk_atom_intern ("application/x-color", FALSE), + 16, (guchar *)vals, 8); +} + + diff --git a/libgimpwidgets/gimpcolorarea.h b/libgimpwidgets/gimpcolorarea.h new file mode 100644 index 0000000000..449e4d1f53 --- /dev/null +++ b/libgimpwidgets/gimpcolorarea.h @@ -0,0 +1,63 @@ +/* LIBGIMP - The GIMP Library + * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball + * + * gimpcolorarea.h + * Copyright (C) 2001 Sven Neumann + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* This provides a color preview area. The preview + * can handle transparency by showing the checkerboard and + * handles drag'n'drop. + */ + +#ifndef __GIMP_COLOR_AREA_H__ +#define __GIMP_COLOR_AREA_H__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#define GIMP_TYPE_COLOR_AREA (gimp_color_area_get_type ()) +#define GIMP_COLOR_AREA(obj) (GTK_CHECK_CAST ((obj), GIMP_TYPE_COLOR_AREA, GimpColorArea)) +#define GIMP_COLOR_AREA_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GIMP_TYPE_COLOR_AREA, GimpColorAreaClass)) +#define GIMP_IS_COLOR_AREA(obj) (GTK_CHECK_TYPE ((obj), GIMP_TYPE_COLOR_AREA)) +#define GIMP_IS_COLOR_AREA_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_COLOR_AREA)) + +typedef struct _GimpColorAreaClass GimpColorAreaClass; + +struct _GimpColorAreaClass +{ + GtkPreviewClass parent_class; + + void (* color_changed) (GimpColorArea *gca, + GimpRGB *color); +}; + + +GtkType gimp_color_area_get_type (void); +GtkWidget * gimp_color_area_new (GimpRGB *color, + gboolean alpha); +void gimp_color_area_update (GimpColorArea *gca); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GIMP_COLOR_AREA_H__ */ diff --git a/plug-ins/Lighting/lighting_preview.c b/plug-ins/Lighting/lighting_preview.c index c779535bb9..5d7b557cfa 100644 --- a/plug-ins/Lighting/lighting_preview.c +++ b/plug-ins/Lighting/lighting_preview.c @@ -146,9 +146,9 @@ compute_preview (gint startx, } else { - gimp_rgb_mul (&color, color.a); + gimp_rgb_multiply (&color, color.a); temp = lightcheck; - gimp_rgb_mul (&temp, 1.0 - color.a); + gimp_rgb_multiply (&temp, 1.0 - color.a); gimp_rgb_add (&color, &temp); } } @@ -160,9 +160,9 @@ compute_preview (gint startx, } else { - gimp_rgb_mul (&color, color.a); + gimp_rgb_multiply (&color, color.a); temp = darkcheck; - gimp_rgb_mul (&temp, 1.0 - color.a); + gimp_rgb_multiply (&temp, 1.0 - color.a); gimp_rgb_add (&color, &temp); } } diff --git a/plug-ins/Lighting/lighting_shade.c b/plug-ins/Lighting/lighting_shade.c index e77078ae65..1735f0e34f 100644 --- a/plug-ins/Lighting/lighting_shade.c +++ b/plug-ins/Lighting/lighting_shade.c @@ -43,7 +43,7 @@ phong_shade (GimpVector3 *position, n = *normal; ambient_color = *diff_col; - gimp_rgb_mul (&ambient_color, mapvals.material.ambient_int); + gimp_rgb_multiply (&ambient_color, mapvals.material.ambient_int); /* Compute (N*L) term of Phong's equation */ /* ====================================== */ @@ -77,15 +77,15 @@ phong_shade (GimpVector3 *position, /* =================================================== */ diffuse_color = *diff_col; - gimp_rgb_mul (&diffuse_color, mapvals.material.diffuse_ref); - gimp_rgb_mul (&diffuse_color, nl); + gimp_rgb_multiply (&diffuse_color, mapvals.material.diffuse_ref); + gimp_rgb_multiply (&diffuse_color, nl); specular_color = *spec_col; - gimp_rgb_mul (&specular_color, mapvals.material.specular_ref); - gimp_rgb_mul (&specular_color, rv); + gimp_rgb_multiply (&specular_color, mapvals.material.specular_ref); + gimp_rgb_multiply (&specular_color, rv); gimp_rgb_add (&diffuse_color, &specular_color); - gimp_rgb_mul (&diffuse_color, mapvals.material.diffuse_int); + gimp_rgb_multiply (&diffuse_color, mapvals.material.diffuse_int); gimp_rgb_clamp (&diffuse_color); gimp_rgb_add (&ambient_color, &diffuse_color); diff --git a/plug-ins/MapObject/mapobject_preview.c b/plug-ins/MapObject/mapobject_preview.c index 15462afd6f..c4e5f9ca35 100644 --- a/plug-ins/MapObject/mapobject_preview.c +++ b/plug-ins/MapObject/mapobject_preview.c @@ -233,9 +233,9 @@ compute_preview (gint x, } else { - gimp_rgb_mul (&color, color.a); + gimp_rgb_multiply (&color, color.a); temp = lightcheck; - gimp_rgb_mul (&temp, 1.0 - color.a); + gimp_rgb_multiply (&temp, 1.0 - color.a); gimp_rgb_add (&color, &temp); } } @@ -247,9 +247,9 @@ compute_preview (gint x, } else { - gimp_rgb_mul (&color, color.a); + gimp_rgb_multiply (&color, color.a); temp = darkcheck; - gimp_rgb_mul (&temp, 1.0 - color.a); + gimp_rgb_multiply (&temp, 1.0 - color.a); gimp_rgb_add (&color, &temp); } } diff --git a/plug-ins/MapObject/mapobject_shade.c b/plug-ins/MapObject/mapobject_shade.c index cc2fd1501b..4608a28332 100644 --- a/plug-ins/MapObject/mapobject_shade.c +++ b/plug-ins/MapObject/mapobject_shade.c @@ -49,7 +49,7 @@ phong_shade (GimpVector3 *pos, N = *normal; ambientcolor = *diff_col; - gimp_rgb_mul (&ambientcolor, mapvals.material.ambient_int); + gimp_rgb_multiply (&ambientcolor, mapvals.material.ambient_int); /* Compute (N*L) term of Phong's equation */ /* ====================================== */ @@ -83,15 +83,15 @@ phong_shade (GimpVector3 *pos, /* =================================================== */ diffusecolor = *diff_col; - gimp_rgb_mul (&diffusecolor, mapvals.material.diffuse_ref); - gimp_rgb_mul (&diffusecolor, NL); + gimp_rgb_multiply (&diffusecolor, mapvals.material.diffuse_ref); + gimp_rgb_multiply (&diffusecolor, NL); specularcolor = *spec_col; - gimp_rgb_mul (&specularcolor, mapvals.material.specular_ref); - gimp_rgb_mul (&specularcolor, RV); + gimp_rgb_multiply (&specularcolor, mapvals.material.specular_ref); + gimp_rgb_multiply (&specularcolor, RV); gimp_rgb_add (&diffusecolor, &specularcolor); - gimp_rgb_mul (&diffusecolor, mapvals.material.diffuse_int); + gimp_rgb_multiply (&diffusecolor, mapvals.material.diffuse_int); gimp_rgb_clamp (&diffusecolor); gimp_rgb_add (&ambientcolor, &diffusecolor); diff --git a/plug-ins/libgck/gck/gckcolor.c b/plug-ins/libgck/gck/gckcolor.c index d42a5d906e..18fb230f41 100644 --- a/plug-ins/libgck/gck/gckcolor.c +++ b/plug-ins/libgck/gck/gckcolor.c @@ -1555,12 +1555,12 @@ gulong gck_render_sub_pixel(int max_depth, int depth, _GckSampleType ** block, /* Check whether we have to supersample */ /* ==================================== */ - if ((gimp_rgba_dist(&c[0], &c[1]) >= threshold) || - (gimp_rgba_dist(&c[0], &c[2]) >= threshold) || - (gimp_rgba_dist(&c[0], &c[3]) >= threshold) || - (gimp_rgba_dist(&c[1], &c[2]) >= threshold) || - (gimp_rgba_dist(&c[1], &c[3]) >= threshold) || - (gimp_rgba_dist(&c[2], &c[3]) >= threshold)) + if ((gimp_rgba_distance (&c[0], &c[1]) >= threshold) || + (gimp_rgba_distance (&c[0], &c[2]) >= threshold) || + (gimp_rgba_distance (&c[0], &c[3]) >= threshold) || + (gimp_rgba_distance (&c[1], &c[2]) >= threshold) || + (gimp_rgba_distance (&c[1], &c[3]) >= threshold) || + (gimp_rgba_distance (&c[2], &c[3]) >= threshold)) { /* Calc coordinates of center subsample */ /* ==================================== */