added enum GimpActiveColor which can be one of { FOREGROUND, BACKGROUND },

2004-05-27  Michael Natterer  <mitch@gimp.org>

	* app/widgets/widgets-enums.[ch]: added enum GimpActiveColor which
	can be one of { FOREGROUND, BACKGROUND },

	* app/widgets/Makefile.am
	* app/widgets/gimpfgbgeditor.[ch]: new widget implementing the
	FG/BG/Swap/Default color area known from the toolbox.

	* app/widgets/gimptoolbox-color-area.c: use the new widget.

	* app/widgets/gimpcoloreditor.[ch]: replaced the FG/BG buttons and
	the color area by a GimpFgBgEditor.
This commit is contained in:
Michael Natterer 2004-05-27 12:41:22 +00:00 committed by Michael Natterer
parent fe64a83dab
commit 855eedf396
10 changed files with 837 additions and 499 deletions

View File

@ -1,3 +1,17 @@
2004-05-27 Michael Natterer <mitch@gimp.org>
* app/widgets/widgets-enums.[ch]: added enum GimpActiveColor which
can be one of { FOREGROUND, BACKGROUND },
* app/widgets/Makefile.am
* app/widgets/gimpfgbgeditor.[ch]: new widget implementing the
FG/BG/Swap/Default color area known from the toolbox.
* app/widgets/gimptoolbox-color-area.c: use the new widget.
* app/widgets/gimpcoloreditor.[ch]: replaced the FG/BG buttons and
the color area by a GimpFgBgEditor.
2004-05-27 Michael Natterer <mitch@gimp.org>
* app/widgets/gimpdocumentview.c (gimp_document_view_new):

View File

@ -111,6 +111,8 @@ libappwidgets_a_sources = \
gimpenumwidgets.h \
gimperrorconsole.c \
gimperrorconsole.h \
gimpfgbgeditor.c \
gimpfgbgeditor.h \
gimpfiledialog.c \
gimpfiledialog.h \
gimpfontview.c \

View File

@ -35,6 +35,7 @@
#include "gimpcoloreditor.h"
#include "gimpdocked.h"
#include "gimpfgbgeditor.h"
#include "gimpsessioninfo.h"
#include "gimp-intl.h"
@ -66,11 +67,10 @@ static void gimp_color_editor_color_changed (GimpColorSelector *selector,
const GimpRGB *rgb,
const GimpHSV *hsv,
GimpColorEditor *editor);
static void gimp_color_editor_area_changed (GimpColorArea *color_area,
GimpColorEditor *editor);
static void gimp_color_editor_tab_toggled (GtkWidget *widget,
GimpColorEditor *editor);
static void gimp_color_editor_fg_bg_toggled (GtkWidget *widget,
static void gimp_color_editor_fg_bg_notify (GtkWidget *widget,
GParamSpec *pspec,
GimpColorEditor *editor);
static void gimp_color_editor_color_picked (GtkWidget *widget,
const GimpRGB *rgb,
@ -120,11 +120,8 @@ gimp_color_editor_get_type (void)
static void
gimp_color_editor_class_init (GimpColorEditorClass* klass)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = GTK_OBJECT_CLASS (klass);
widget_class = GTK_WIDGET_CLASS (klass);
GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
@ -231,71 +228,15 @@ gimp_color_editor_init (GimpColorEditor *editor)
editor);
}
/* FG/BG toggles */
{
GtkWidget *hbox;
GtkWidget *vbox;
GtkWidget *frame;
gint i;
/* FG/BG editor */
editor->fg_bg = gimp_fg_bg_editor_new (NULL);
gtk_widget_set_size_request (editor->fg_bg, -1, 48);
gtk_box_pack_start (GTK_BOX (editor), editor->fg_bg, FALSE, FALSE, 0);
gtk_widget_show (editor->fg_bg);
static const gchar *labels[] =
{
N_("FG"), N_("BG")
};
static const gchar *tips[] =
{
N_("Edit Foreground Color"), N_("Edit Background Color")
};
hbox = gtk_hbox_new (FALSE, button_spacing);
gtk_box_pack_start (GTK_BOX (editor), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
vbox = gtk_vbox_new (FALSE, button_spacing);
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
gtk_widget_show (vbox);
group = NULL;
for (i = 0; i < G_N_ELEMENTS (labels); i++)
{
GtkWidget *button;
button = gtk_radio_button_new_with_mnemonic (group,
gettext (labels[i]));
group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
gimp_help_set_help_data (button, gettext (tips[i]), NULL);
g_object_set_data (G_OBJECT (button), "edit_bg",
GINT_TO_POINTER (i == 1));
if ((i == 1) == editor->edit_bg)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
g_signal_connect (button, "toggled",
G_CALLBACK (gimp_color_editor_fg_bg_toggled),
g_signal_connect (editor->fg_bg, "notify::active-color",
G_CALLBACK (gimp_color_editor_fg_bg_notify),
editor);
}
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
gtk_box_pack_end (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
gtk_widget_show (frame);
editor->color_area = gimp_color_area_new (&rgb, GIMP_COLOR_AREA_FLAT,
GDK_BUTTON1_MASK |
GDK_BUTTON2_MASK);
gtk_container_add (GTK_CONTAINER (frame), editor->color_area);
gtk_widget_show (editor->color_area);
g_signal_connect (editor->color_area, "color_changed",
G_CALLBACK (gimp_color_editor_area_changed),
editor);
}
}
static void
@ -413,6 +354,8 @@ gimp_color_editor_set_context (GimpDocked *docked,
gimp_color_editor_fg_changed (editor->context, &rgb, editor);
}
}
gimp_fg_bg_editor_set_context (GIMP_FG_BG_EDITOR (editor->fg_bg), context);
}
static void
@ -474,20 +417,13 @@ gimp_color_editor_fg_changed (GimpContext *context,
g_signal_handlers_block_by_func (editor->notebook,
gimp_color_editor_color_changed,
editor);
g_signal_handlers_block_by_func (editor->color_area,
gimp_color_editor_area_changed,
editor);
gimp_color_selector_set_color (GIMP_COLOR_SELECTOR (editor->notebook),
rgb, &hsv);
gimp_color_area_set_color (GIMP_COLOR_AREA (editor->color_area), rgb);
g_signal_handlers_unblock_by_func (editor->notebook,
gimp_color_editor_color_changed,
editor);
g_signal_handlers_unblock_by_func (editor->color_area,
gimp_color_editor_area_changed,
editor);
}
}
@ -505,20 +441,13 @@ gimp_color_editor_bg_changed (GimpContext *context,
g_signal_handlers_block_by_func (editor->notebook,
gimp_color_editor_color_changed,
editor);
g_signal_handlers_block_by_func (editor->color_area,
gimp_color_editor_area_changed,
editor);
gimp_color_selector_set_color (GIMP_COLOR_SELECTOR (editor->notebook),
rgb, &hsv);
gimp_color_area_set_color (GIMP_COLOR_AREA (editor->color_area), rgb);
g_signal_handlers_unblock_by_func (editor->notebook,
gimp_color_editor_color_changed,
editor);
g_signal_handlers_unblock_by_func (editor->color_area,
gimp_color_editor_area_changed,
editor);
}
}
@ -555,30 +484,6 @@ gimp_color_editor_color_changed (GimpColorSelector *selector,
editor);
}
}
g_signal_handlers_block_by_func (editor->color_area,
gimp_color_editor_area_changed,
editor);
gimp_color_area_set_color (GIMP_COLOR_AREA (editor->color_area), rgb);
g_signal_handlers_unblock_by_func (editor->color_area,
gimp_color_editor_area_changed,
editor);
}
static void
gimp_color_editor_area_changed (GimpColorArea *color_area,
GimpColorEditor *editor)
{
GimpRGB rgb;
GimpHSV hsv;
gimp_color_area_get_color (color_area, &rgb);
gimp_rgb_to_hsv (&rgb, &hsv);
gimp_color_selector_set_color (GIMP_COLOR_SELECTOR (editor->notebook),
&rgb, &hsv);
}
static void
@ -607,15 +512,14 @@ gimp_color_editor_tab_toggled (GtkWidget *widget,
}
static void
gimp_color_editor_fg_bg_toggled (GtkWidget *widget,
gimp_color_editor_fg_bg_notify (GtkWidget *widget,
GParamSpec *pspec,
GimpColorEditor *editor)
{
if (GTK_TOGGLE_BUTTON (widget)->active)
{
gboolean edit_bg;
edit_bg = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget),
"edit_bg"));
edit_bg = (GIMP_FG_BG_EDITOR (widget)->active_color ==
GIMP_ACTIVE_COLOR_BACKGROUND);
if (edit_bg != editor->edit_bg)
{
@ -637,7 +541,6 @@ gimp_color_editor_fg_bg_toggled (GtkWidget *widget,
}
}
}
}
}
static void
@ -645,5 +548,11 @@ gimp_color_editor_color_picked (GtkWidget *widget,
const GimpRGB *rgb,
GimpColorEditor *editor)
{
gimp_color_area_set_color (GIMP_COLOR_AREA (editor->color_area), rgb);
if (editor->context)
{
if (editor->edit_bg)
gimp_context_set_background (editor->context, rgb);
else
gimp_context_set_foreground (editor->context, rgb);
}
}

View File

@ -45,7 +45,7 @@ struct _GimpColorEditor
GtkWidget *hbox;
GtkWidget *notebook;
GtkWidget *color_area;
GtkWidget *fg_bg;
};
struct _GimpColorEditorClass

View File

@ -0,0 +1,632 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpfgbgeditor.c
* Copyright (C) 2004 Michael Natterer <mitch@gimp.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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 PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <string.h>
#include <gtk/gtk.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
#include "core/gimpcontext.h"
#include "core/gimpmarshal.h"
#include "gimpdnd.h"
#include "gimpfgbgeditor.h"
enum
{
PROP_0,
PROP_CONTEXT,
PROP_ACTIVE_COLOR
};
enum
{
COLOR_CLICKED,
LAST_SIGNAL
};
typedef enum
{
INVALID_AREA,
FORE_AREA,
BACK_AREA,
SWAP_AREA,
DEFAULT_AREA
} FgBgTarget;
static void gimp_fg_bg_editor_class_init (GimpFgBgEditorClass *klass);
static void gimp_fg_bg_editor_init (GimpFgBgEditor *editor);
static void gimp_fg_bg_editor_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_fg_bg_editor_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void gimp_fg_bg_editor_destroy (GtkObject *object);
static gboolean gimp_fg_bg_editor_expose (GtkWidget *widget,
GdkEventExpose *eevent);
static gboolean gimp_fg_bg_editor_button_press (GtkWidget *widget,
GdkEventButton *bevent);
static gboolean gimp_fg_bg_editor_button_release (GtkWidget *widget,
GdkEventButton *bevent);
static void gimp_fg_bg_editor_context_changed (GimpContext *context,
const GimpRGB *color,
GimpFgBgEditor *editor);
static void gimp_fg_bg_editor_drag_color (GtkWidget *widget,
GimpRGB *color,
gpointer data);
static void gimp_fg_bg_editor_drop_color (GtkWidget *widget,
const GimpRGB *color,
gpointer data);
static guint editor_signals[LAST_SIGNAL] = { 0 };
static GtkDrawingAreaClass *parent_class = NULL;
GType
gimp_fg_bg_editor_get_type (void)
{
static GType type = 0;
if (! type)
{
static const GTypeInfo info =
{
sizeof (GimpFgBgEditorClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gimp_fg_bg_editor_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GimpFgBgEditor),
0, /* n_preallocs */
(GInstanceInitFunc) gimp_fg_bg_editor_init,
};
type = g_type_register_static (GTK_TYPE_DRAWING_AREA,
"GimpFgBgEditor",
&info, 0);
}
return type;
}
static void
gimp_fg_bg_editor_class_init (GimpFgBgEditorClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
editor_signals[COLOR_CLICKED] =
g_signal_new ("color-clicked",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpFgBgEditorClass, color_clicked),
NULL, NULL,
gimp_marshal_VOID__ENUM,
G_TYPE_NONE, 1,
GIMP_TYPE_ACTIVE_COLOR);
object_class->set_property = gimp_fg_bg_editor_set_property;
object_class->get_property = gimp_fg_bg_editor_get_property;
gtk_object_class->destroy = gimp_fg_bg_editor_destroy;
widget_class->expose_event = gimp_fg_bg_editor_expose;
widget_class->button_press_event = gimp_fg_bg_editor_button_press;
widget_class->button_release_event = gimp_fg_bg_editor_button_release;
g_object_class_install_property (object_class, PROP_CONTEXT,
g_param_spec_object ("context",
NULL, NULL,
GIMP_TYPE_CONTEXT,
G_PARAM_READWRITE));
g_object_class_install_property (object_class, PROP_ACTIVE_COLOR,
g_param_spec_enum ("active-color",
NULL, NULL,
GIMP_TYPE_ACTIVE_COLOR,
GIMP_ACTIVE_COLOR_FOREGROUND,
G_PARAM_READWRITE));
}
static void
gimp_fg_bg_editor_init (GimpFgBgEditor *editor)
{
editor->context = NULL;
editor->active_color = GIMP_ACTIVE_COLOR_FOREGROUND;
gtk_widget_add_events (GTK_WIDGET (editor),
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK);
gimp_dnd_color_source_add (GTK_WIDGET (editor),
gimp_fg_bg_editor_drag_color, NULL);
gimp_dnd_color_dest_add (GTK_WIDGET (editor),
gimp_fg_bg_editor_drop_color, NULL);
}
static void
gimp_fg_bg_editor_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (object);
switch (property_id)
{
case PROP_CONTEXT:
gimp_fg_bg_editor_set_context (editor, g_value_get_object (value));
break;
case PROP_ACTIVE_COLOR:
gimp_fg_bg_editor_set_active (editor, g_value_get_enum (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_fg_bg_editor_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (object);
switch (property_id)
{
case PROP_CONTEXT:
g_value_set_object (value, editor->context);
break;
case PROP_ACTIVE_COLOR:
g_value_set_enum (value, editor->active_color);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_fg_bg_editor_destroy (GtkObject *object)
{
GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (object);
if (editor->context)
gimp_fg_bg_editor_set_context (editor, NULL);
if (editor->render_buf)
{
g_free (editor->render_buf);
editor->render_buf = NULL;
editor->render_buf_size = 0;
}
if (editor->default_icon)
{
g_object_unref (editor->default_icon);
editor->default_icon = NULL;
}
if (editor->swap_icon)
{
g_object_unref (editor->swap_icon);
editor->swap_icon = NULL;
}
GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
static void
gimp_fg_bg_editor_draw_rect (GimpFgBgEditor *editor,
GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
const GimpRGB *color)
{
gint rowstride;
guchar r, g, b;
gint xx, yy;
guchar *bp;
gimp_rgb_get_uchar (color, &r, &g, &b);
rowstride = 3 * ((width + 3) & -4);
if (! editor->render_buf || editor->render_buf_size < height * rowstride)
{
editor->render_buf_size = rowstride * height;
g_free (editor->render_buf);
editor->render_buf = g_malloc (editor->render_buf_size);
}
bp = editor->render_buf;
for (xx = 0; xx < width; xx++)
{
*bp++ = r;
*bp++ = g;
*bp++ = b;
}
bp = editor->render_buf;
for (yy = 1; yy < height; yy++)
{
bp += rowstride;
memcpy (bp, editor->render_buf, rowstride);
}
gdk_draw_rgb_image (drawable, gc, x, y, width, height,
GDK_RGB_DITHER_MAX,
editor->render_buf,
rowstride);
}
static gboolean
gimp_fg_bg_editor_expose (GtkWidget *widget,
GdkEventExpose *eevent)
{
GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (widget);
gint width, height;
gint default_w, default_h;
gint swap_w, swap_h;
gint rect_w, rect_h;
GimpRGB color;
if (! GTK_WIDGET_DRAWABLE (widget))
return FALSE;
width = widget->allocation.width;
height = widget->allocation.height;
/* draw the default colors pixbuf */
if (! editor->default_icon)
editor->default_icon = gtk_widget_render_icon (widget,
GIMP_STOCK_DEFAULT_COLORS,
GTK_ICON_SIZE_MENU, NULL);
default_w = gdk_pixbuf_get_width (editor->default_icon);
default_h = gdk_pixbuf_get_height (editor->default_icon);
gdk_draw_pixbuf (widget->window, NULL, editor->default_icon,
0, 0, 0, height - default_h, default_w, default_h,
GDK_RGB_DITHER_NORMAL, 0, 0);
/* draw the swap colors pixbuf */
if (! editor->swap_icon)
editor->swap_icon = gtk_widget_render_icon (widget,
GIMP_STOCK_SWAP_COLORS,
GTK_ICON_SIZE_MENU, NULL);
swap_w = gdk_pixbuf_get_width (editor->swap_icon);
swap_h = gdk_pixbuf_get_height (editor->swap_icon);
gdk_draw_pixbuf (widget->window, NULL, editor->swap_icon,
0, 0, width - swap_w, 0, swap_w, swap_h,
GDK_RGB_DITHER_NORMAL, 0, 0);
rect_h = height - MAX (default_h, swap_h) - 2;
rect_w = width - MAX (default_w, swap_w) - 4;
if (rect_h > (height * 3 / 4))
rect_w = MAX (rect_w - (rect_h - ((height * 3 / 4))),
width * 2 / 3);
editor->rect_width = rect_w;
editor->rect_height = rect_h;
/* draw the background area */
if (editor->context)
{
gimp_context_get_background (editor->context, &color);
gimp_fg_bg_editor_draw_rect (editor,
widget->window,
widget->style->fg_gc[0],
(width - rect_w),
(height - rect_h),
rect_w, rect_h,
&color);
}
gtk_paint_shadow (widget->style, widget->window, GTK_STATE_NORMAL,
editor->active_color == GIMP_ACTIVE_COLOR_FOREGROUND ?
GTK_SHADOW_OUT : GTK_SHADOW_IN,
NULL, widget, NULL,
(width - rect_w),
(height - rect_h),
rect_w, rect_h);
/* draw the foreground area */
if (editor->context)
{
gimp_context_get_foreground (editor->context, &color);
gimp_fg_bg_editor_draw_rect (editor,
widget->window,
widget->style->fg_gc[0],
0, 0,
rect_w, rect_h,
&color);
}
gtk_paint_shadow (widget->style, widget->window, GTK_STATE_NORMAL,
editor->active_color == GIMP_ACTIVE_COLOR_BACKGROUND ?
GTK_SHADOW_OUT : GTK_SHADOW_IN,
NULL, widget, NULL,
0, 0,
rect_w, rect_h);
return TRUE;
}
static FgBgTarget
gimp_fg_bg_editor_target (GimpFgBgEditor *editor,
gint x,
gint y)
{
gint width = GTK_WIDGET (editor)->allocation.width;
gint height = GTK_WIDGET (editor)->allocation.height;
gint rect_w = editor->rect_width;
gint rect_h = editor->rect_height;
if (x > 0 && x < rect_w && y > 0 && y < rect_h)
return FORE_AREA;
else if (x > (width - rect_w) && x < width &&
y > (height - rect_h) && y < height)
return BACK_AREA;
else if (x > 0 && x < (width - rect_w) &&
y > rect_h && y < height)
return DEFAULT_AREA;
else if (x > rect_w && x < width &&
y > 0 && y < (height - rect_h))
return SWAP_AREA;
return INVALID_AREA;
}
static gboolean
gimp_fg_bg_editor_button_press (GtkWidget *widget,
GdkEventButton *bevent)
{
GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (widget);
if (bevent->button == 1 && bevent->type == GDK_BUTTON_PRESS)
{
FgBgTarget target = gimp_fg_bg_editor_target (editor,
bevent->x, bevent->y);
editor->click_target = INVALID_AREA;
switch (target)
{
case FORE_AREA:
if (editor->active_color != GIMP_ACTIVE_COLOR_FOREGROUND)
gimp_fg_bg_editor_set_active (editor,
GIMP_ACTIVE_COLOR_FOREGROUND);
else
editor->click_target = FORE_AREA;
break;
case BACK_AREA:
if (editor->active_color != GIMP_ACTIVE_COLOR_BACKGROUND)
gimp_fg_bg_editor_set_active (editor,
GIMP_ACTIVE_COLOR_BACKGROUND);
else
editor->click_target = BACK_AREA;
break;
case SWAP_AREA:
if (editor->context)
gimp_context_swap_colors (editor->context);
break;
case DEFAULT_AREA:
if (editor->context)
gimp_context_set_default_colors (editor->context);
break;
default:
break;
}
}
return FALSE;
}
static gboolean
gimp_fg_bg_editor_button_release (GtkWidget *widget,
GdkEventButton *bevent)
{
GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (widget);
if (bevent->button == 1)
{
FgBgTarget target = gimp_fg_bg_editor_target (editor,
bevent->x, bevent->y);
if (target == editor->click_target)
{
switch (target)
{
case FORE_AREA:
g_signal_emit (editor, editor_signals[COLOR_CLICKED], 0,
GIMP_ACTIVE_COLOR_FOREGROUND);
break;
case BACK_AREA:
g_signal_emit (editor, editor_signals[COLOR_CLICKED], 0,
GIMP_ACTIVE_COLOR_BACKGROUND);
break;
default:
break;
}
}
editor->click_target = INVALID_AREA;
}
return FALSE;
}
/* public functions */
GtkWidget *
gimp_fg_bg_editor_new (GimpContext *context)
{
g_return_val_if_fail (context == NULL || GIMP_IS_CONTEXT (context), NULL);
return g_object_new (GIMP_TYPE_FG_BG_EDITOR,
"context", context,
NULL);
}
void
gimp_fg_bg_editor_set_context (GimpFgBgEditor *editor,
GimpContext *context)
{
g_return_if_fail (GIMP_IS_FG_BG_EDITOR (editor));
g_return_if_fail (context == NULL || GIMP_IS_CONTEXT (context));
if (context == editor->context)
return;
if (editor->context)
{
g_signal_handlers_disconnect_by_func (editor->context,
gimp_fg_bg_editor_context_changed,
editor);
g_object_unref (editor->context);
editor->context = NULL;
}
editor->context = context;
if (context)
{
g_object_ref (context);
g_signal_connect (context, "foreground_changed",
G_CALLBACK (gimp_fg_bg_editor_context_changed),
editor);
g_signal_connect (context, "background_changed",
G_CALLBACK (gimp_fg_bg_editor_context_changed),
editor);
}
g_object_notify (G_OBJECT (editor), "context");
}
void
gimp_fg_bg_editor_set_active (GimpFgBgEditor *editor,
GimpActiveColor active)
{
g_return_if_fail (GIMP_IS_FG_BG_EDITOR (editor));
editor->active_color = active;
gtk_widget_queue_draw (GTK_WIDGET (editor));
g_object_notify (G_OBJECT (editor), "active-color");
}
/* private functions */
static void
gimp_fg_bg_editor_context_changed (GimpContext *context,
const GimpRGB *color,
GimpFgBgEditor *editor)
{
gtk_widget_queue_draw (GTK_WIDGET (editor));
}
static void
gimp_fg_bg_editor_drag_color (GtkWidget *widget,
GimpRGB *color,
gpointer data)
{
GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (widget);
if (editor->context)
{
switch (editor->active_color)
{
case GIMP_ACTIVE_COLOR_FOREGROUND:
gimp_context_get_foreground (editor->context, color);
break;
case GIMP_ACTIVE_COLOR_BACKGROUND:
gimp_context_get_background (editor->context, color);
break;
}
}
}
static void
gimp_fg_bg_editor_drop_color (GtkWidget *widget,
const GimpRGB *color,
gpointer data)
{
GimpFgBgEditor *editor = GIMP_FG_BG_EDITOR (widget);
if (editor->context)
{
switch (editor->active_color)
{
case GIMP_ACTIVE_COLOR_FOREGROUND:
gimp_context_set_foreground (editor->context, color);
break;
case GIMP_ACTIVE_COLOR_BACKGROUND:
gimp_context_set_background (editor->context, color);
break;
}
}
}

View File

@ -0,0 +1,78 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpfgbgeditor.h
* Copyright (C) 2004 Michael Natterer <mitch@gimp.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 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 PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __GIMP_FG_BG_EDITOR_H__
#define __GIMP_FG_BG_EDITOR_H__
#include <gtk/gtkdrawingarea.h>
#define GIMP_TYPE_FG_BG_EDITOR (gimp_fg_bg_editor_get_type ())
#define GIMP_FG_BG_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_FG_BG_EDITOR, GimpFgBgEditor))
#define GIMP_FG_BG_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_FG_BG_EDITOR, GimpFgBgEditorClass))
#define GIMP_IS_FG_BG_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_FG_BG_EDITOR))
#define GIMP_IS_FG_BG_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_FG_BG_EDITOR))
#define GIMP_FG_BG_EDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_FG_BG_EDITOR, GimpFgBgEditorClass))
typedef struct _GimpFgBgEditorClass GimpFgBgEditorClass;
struct _GimpFgBgEditor
{
GtkDrawingArea parent_instance;
GimpContext *context;
GimpActiveColor active_color;
guchar *render_buf;
gint render_buf_size;
GdkPixbuf *default_icon;
GdkPixbuf *swap_icon;
gint rect_width;
gint rect_height;
gint click_target;
};
struct _GimpFgBgEditorClass
{
GtkDrawingAreaClass parent_class;
/* signals */
void (* color_clicked) (GimpFgBgEditor *editor,
GimpActiveColor color);
};
GType gimp_fg_bg_editor_get_type (void) G_GNUC_CONST;
GtkWidget * gimp_fg_bg_editor_new (GimpContext *context);
void gimp_fg_bg_editor_set_context (GimpFgBgEditor *editor,
GimpContext *context);
void gimp_fg_bg_editor_set_active (GimpFgBgEditor *editor,
GimpActiveColor active);
#endif /* __GIMP_FG_BG_EDITOR_H__ */

View File

@ -18,11 +18,8 @@
#include "config.h"
#include <string.h> /* memcpy */
#include <gtk/gtk.h>
#include "libgimpcolor/gimpcolor.h"
#include "libgimpwidgets/gimpwidgets.h"
#include "widgets-types.h"
@ -36,7 +33,7 @@
#include "core/gimpcontext.h"
#include "gimpdialogfactory.h"
#include "gimpdnd.h"
#include "gimpfgbgeditor.h"
#include "gimptoolbox.h"
#include "gimptoolbox-color-area.h"
@ -45,58 +42,23 @@
#include "gimp-intl.h"
typedef enum
{
FORE_AREA,
BACK_AREA,
SWAP_AREA,
DEFAULT_AREA,
INVALID_AREA
} ColorAreaTarget;
#define FOREGROUND 0
#define BACKGROUND 1
/* local function prototypes */
static ColorAreaTarget color_area_target (gint x,
gint y);
static gboolean color_area_expose_event (GtkWidget *widget,
GdkEventExpose *eevent,
static void color_area_color_clicked (GimpFgBgEditor *editor,
GimpActiveColor active_color,
GimpContext *context);
static void color_area_draw_rect (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
const GimpRGB *color);
static void color_area_select_callback (ColorNotebook *color_notebook,
const GimpRGB *color,
ColorNotebookState state,
gpointer data);
static void color_area_edit (GimpContext *context,
GtkWidget *widget);
static void color_area_drop_color (GtkWidget *widget,
const GimpRGB *color,
gpointer data);
static void color_area_drag_color (GtkWidget *widget,
GimpRGB *color,
gpointer data);
static gboolean color_area_events (GtkWidget *widget,
GdkEvent *event,
gpointer data);
/* Static variables */
/* local variables */
static GtkWidget *color_area = NULL;
static ColorNotebook *color_notebook = NULL;
static gboolean color_notebook_active = FALSE;
static gint active_color = FOREGROUND;
static gint edit_color;
static GimpActiveColor edit_color;
static GimpRGB revert_fg;
static GimpRGB revert_bg;
@ -114,31 +76,15 @@ gimp_toolbox_color_area_create (GimpToolbox *toolbox,
context = GIMP_DOCK (toolbox)->context;
color_area = gtk_drawing_area_new ();
color_area = gimp_fg_bg_editor_new (context);
gtk_widget_set_size_request (color_area, width, height);
gtk_widget_set_events (color_area,
GDK_EXPOSURE_MASK |
GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
gtk_widget_add_events (color_area,
GDK_ENTER_NOTIFY_MASK |
GDK_LEAVE_NOTIFY_MASK);
g_signal_connect (color_area, "event",
G_CALLBACK (color_area_events),
g_signal_connect (color_area, "color-clicked",
G_CALLBACK (color_area_color_clicked),
context);
g_signal_connect (color_area, "expose_event",
G_CALLBACK (color_area_expose_event),
context);
gimp_dnd_color_source_add (color_area, color_area_drag_color, context);
gimp_dnd_color_dest_add (color_area, color_area_drop_color, context);
g_signal_connect_swapped (context, "foreground_changed",
G_CALLBACK (gtk_widget_queue_draw),
color_area);
g_signal_connect_swapped (context, "background_changed",
G_CALLBACK (gtk_widget_queue_draw),
color_area);
return color_area;
}
@ -146,162 +92,6 @@ gimp_toolbox_color_area_create (GimpToolbox *toolbox,
/* private functions */
static ColorAreaTarget
color_area_target (gint x,
gint y)
{
gint rect_w, rect_h;
gint width, height;
width = color_area->allocation.width;
height = color_area->allocation.height;
rect_w = (width * 2) / 3;
rect_h = (height * 2) / 3;
/* foreground active */
if (x > 0 && x < rect_w && y > 0 && y < rect_h)
return FORE_AREA;
else if (x > (width - rect_w) && x < width &&
y > (height - rect_h) && y < height)
return BACK_AREA;
else if (x > 0 && x < (width - rect_w) &&
y > rect_h && y < height)
return DEFAULT_AREA;
else if (x > rect_w && x < width &&
y > 0 && y < (height - rect_h))
return SWAP_AREA;
else
return -1;
}
static gboolean
color_area_expose_event (GtkWidget *widget,
GdkEventExpose *eevent,
GimpContext *context)
{
gint rect_w, rect_h;
gint width, height;
gint w, h;
GimpRGB color;
GdkPixbuf *pixbuf;
if (!GTK_WIDGET_DRAWABLE (color_area))
return FALSE;
width = color_area->allocation.width;
height = color_area->allocation.height;
rect_w = (width * 2) / 3;
rect_h = (height * 2) / 3;
/* draw the background area */
gimp_context_get_background (context, &color);
color_area_draw_rect (color_area->window, color_area->style->fg_gc[0],
(width - rect_w), (height - rect_h), rect_w, rect_h,
&color);
gtk_paint_shadow (color_area->style, color_area->window, GTK_STATE_NORMAL,
active_color == FOREGROUND ? GTK_SHADOW_OUT : GTK_SHADOW_IN,
NULL, color_area, NULL,
(width - rect_w), (height - rect_h),
rect_w, rect_h);
/* draw the foreground area */
gimp_context_get_foreground (context, &color);
color_area_draw_rect (color_area->window, color_area->style->fg_gc[0],
0, 0, rect_w, rect_h,
&color);
gtk_paint_shadow (color_area->style, color_area->window, GTK_STATE_NORMAL,
active_color == BACKGROUND ? GTK_SHADOW_OUT : GTK_SHADOW_IN,
NULL, color_area, NULL,
0, 0,
rect_w, rect_h);
/* draw the default colors pixbuf */
pixbuf = gtk_widget_render_icon (color_area, GIMP_STOCK_DEFAULT_COLORS,
GTK_ICON_SIZE_MENU, NULL);
w = gdk_pixbuf_get_width (pixbuf);
h = gdk_pixbuf_get_height (pixbuf);
gdk_draw_pixbuf (color_area->window, NULL, pixbuf,
0, 0, 0, height - h, w, h,
GDK_RGB_DITHER_MAX, 0, 0);
g_object_unref (pixbuf);
/* draw the swap colors pixbuf */
pixbuf = gtk_widget_render_icon (color_area, GIMP_STOCK_SWAP_COLORS,
GTK_ICON_SIZE_MENU, NULL);
w = gdk_pixbuf_get_width (pixbuf);
h = gdk_pixbuf_get_height (pixbuf);
gdk_draw_pixbuf (color_area->window, NULL, pixbuf,
0, 0, width - w, 0, w, h,
GDK_RGB_DITHER_MAX, 0, 0);
g_object_unref (pixbuf);
return TRUE;
}
static void
color_area_draw_rect (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
const GimpRGB *color)
{
static guchar *color_area_rgb_buf = NULL;
static gint color_area_rgb_buf_size;
gint rowstride;
guchar r, g, b;
gint xx, yy;
guchar *bp;
gimp_rgb_get_uchar (color, &r, &g, &b);
rowstride = 3 * ((width + 3) & -4);
if (!color_area_rgb_buf || color_area_rgb_buf_size < height * rowstride)
{
color_area_rgb_buf_size = rowstride * height;
g_free (color_area_rgb_buf);
color_area_rgb_buf = g_malloc (color_area_rgb_buf_size);
}
bp = color_area_rgb_buf;
for (xx = 0; xx < width; xx++)
{
*bp++ = r;
*bp++ = g;
*bp++ = b;
}
bp = color_area_rgb_buf;
#ifdef DISPLAY_FILTERS
for (list = color_area_gdisp->cd_list; list; list = g_list_next (list))
{
ColorDisplayNode *node = (ColorDisplayNode *) list->data;
node->cd_convert (node->cd_ID, bp, width, 1, 3, rowstride);
}
#endif /* DISPLAY_FILTERS */
for (yy = 1; yy < height; yy++)
{
bp += rowstride;
memcpy (bp, color_area_rgb_buf, rowstride);
}
gdk_draw_rgb_image (drawable, gc, x, y, width, height,
GDK_RGB_DITHER_MAX,
color_area_rgb_buf,
rowstride);
}
static void
color_area_select_callback (ColorNotebook *color_notebook,
const GimpRGB *color,
@ -320,7 +110,7 @@ color_area_select_callback (ColorNotebook *color_notebook,
/* Fallthrough */
case COLOR_NOTEBOOK_UPDATE:
if (edit_color == FOREGROUND)
if (edit_color == GIMP_ACTIVE_COLOR_FOREGROUND)
gimp_context_set_foreground (context, color);
else
gimp_context_set_background (context, color);
@ -337,8 +127,9 @@ color_area_select_callback (ColorNotebook *color_notebook,
}
static void
color_area_edit (GimpContext *context,
GtkWidget *widget)
color_area_color_clicked (GimpFgBgEditor *editor,
GimpActiveColor active_color,
GimpContext *context)
{
GimpRGB color;
const gchar *title;
@ -349,18 +140,19 @@ color_area_edit (GimpContext *context,
gimp_context_get_background (context, &revert_bg);
}
if (active_color == FOREGROUND)
if (active_color == GIMP_ACTIVE_COLOR_FOREGROUND)
{
gimp_context_get_foreground (context, &color);
title = _("Change Foreground Color");
}
else
{
gimp_context_get_background (context, &color);
title = _("Change Background Color");
}
edit_color = active_color;
if (active_color == FOREGROUND)
title = _("Change Foreground Color");
else
title = _("Change Background Color");
if (! color_notebook)
{
GimpDialogFactory *toplevel_factory;
@ -368,7 +160,7 @@ color_area_edit (GimpContext *context,
toplevel_factory = gimp_dialog_factory_from_name ("toplevel");
color_notebook = color_notebook_new (NULL, title, NULL, NULL,
widget,
GTK_WIDGET (editor),
toplevel_factory,
"gimp-toolbox-color-dialog",
(const GimpRGB *) &color,
@ -385,123 +177,3 @@ color_area_edit (GimpContext *context,
color_notebook_active = TRUE;
}
}
static gint
color_area_events (GtkWidget *widget,
GdkEvent *event,
gpointer data)
{
GimpContext *context;
GdkEventButton *bevent;
ColorAreaTarget target;
static ColorAreaTarget press_target = INVALID_AREA;
context = GIMP_CONTEXT (data);
switch (event->type)
{
case GDK_BUTTON_PRESS:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
target = color_area_target (bevent->x, bevent->y);
press_target = INVALID_AREA;
switch (target)
{
case FORE_AREA:
case BACK_AREA:
if (target != active_color)
{
active_color = target;
gtk_widget_queue_draw (widget);
}
else
{
press_target = target;
}
break;
case SWAP_AREA:
gimp_context_swap_colors (context);
break;
case DEFAULT_AREA:
gimp_context_set_default_colors (context);
break;
default:
break;
}
}
break;
case GDK_BUTTON_RELEASE:
bevent = (GdkEventButton *) event;
if (bevent->button == 1)
{
target = color_area_target (bevent->x, bevent->y);
if (target == press_target)
{
switch (target)
{
case FORE_AREA:
case BACK_AREA:
color_area_edit (context, widget);
break;
default:
break;
}
}
press_target = INVALID_AREA;
}
break;
case GDK_LEAVE_NOTIFY:
press_target = INVALID_AREA;
break;
default:
break;
}
return FALSE;
}
static void
color_area_drag_color (GtkWidget *widget,
GimpRGB *color,
gpointer data)
{
GimpContext *context = GIMP_CONTEXT (data);
if (active_color == FOREGROUND)
gimp_context_get_foreground (context, color);
else
gimp_context_get_background (context, color);
}
static void
color_area_drop_color (GtkWidget *widget,
const GimpRGB *color,
gpointer data)
{
GimpContext *context = GIMP_CONTEXT (data);
if (color_notebook_active && active_color == edit_color)
{
color_notebook_set_color (color_notebook, color);
}
else
{
if (active_color == FOREGROUND)
gimp_context_set_foreground (context, color);
else
gimp_context_set_background (context, color);
}
}

View File

@ -8,6 +8,25 @@
/* enumerations from "./widgets-enums.h" */
static const GEnumValue gimp_active_color_enum_values[] =
{
{ GIMP_ACTIVE_COLOR_FOREGROUND, N_("Foreground"), "foreground" },
{ GIMP_ACTIVE_COLOR_BACKGROUND, N_("Background"), "background" },
{ 0, NULL, NULL }
};
GType
gimp_active_color_get_type (void)
{
static GType enum_type = 0;
if (!enum_type)
enum_type = g_enum_register_static ("GimpActiveColor", gimp_active_color_enum_values);
return enum_type;
}
static const GEnumValue gimp_aspect_type_enum_values[] =
{
{ GIMP_ASPECT_SQUARE, "GIMP_ASPECT_SQUARE", "square" },

View File

@ -24,6 +24,17 @@
* these enums that are registered with the type system
*/
#define GIMP_TYPE_ACTIVE_COLOR (gimp_active_color_get_type ())
GType gimp_active_color_get_type (void) G_GNUC_CONST;
typedef enum
{
GIMP_ACTIVE_COLOR_FOREGROUND, /*< desc="Foreground" >*/
GIMP_ACTIVE_COLOR_BACKGROUND /*< desc="Background" >*/
} GimpActiveColor;
#define GIMP_TYPE_ASPECT_TYPE (gimp_aspect_type_get_type ())
GType gimp_aspect_type_get_type (void) G_GNUC_CONST;

View File

@ -127,6 +127,7 @@ typedef struct _GimpColorDisplayEditor GimpColorDisplayEditor;
typedef struct _GimpColorFrame GimpColorFrame;
typedef struct _GimpColorPanel GimpColorPanel;
typedef struct _GimpDashEditor GimpDashEditor;
typedef struct _GimpFgBgEditor GimpFgBgEditor;
typedef struct _GimpGridEditor GimpGridEditor;
typedef struct _GimpHistogramBox GimpHistogramBox;
typedef struct _GimpHistogramView GimpHistogramView;