mirror of
https://gitlab.gnome.org/GNOME/gimp
synced 2024-10-21 20:12:30 +00:00
f6858e21d1
* app/*.[ch]: Actually use the enum types GimpImageType, GimpImageBaseType, LayerModeEffects, PaintApplicationMode, BrushApplicationMode, GimpFillType and ConvertPaletteType, instead of just int or gint. Hopefully I catched most of the places where these should be used. Add an enum ConvolutionType, suffix the too general constants NORMAL, ABSOLUTE and NEGATIVE with _CONVOL. Use NORMAL_MODE instead of NORMAL in some places (this was what was intended). Fix some minor gccisms. * app/apptypes.h: New file. This file contains the above enumeration types, and some opaque struct typedefs. It was necessary to collect these in one header that doesn't include other headers, because when we started using the above mentioned types in the headers, all hell broke loose because of the spaghetti-like cross-inclusion mess between headers. (An example: Header A includes header B, which includes header C which includes A. B uses a type defined in A. This is not defined, because A hasn't defined it yet at the point where it includes B, and A included from B of course is skipped as we already are reading A.)
665 lines
20 KiB
C
665 lines
20 KiB
C
/* The GIMP -- an image manipulation program
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 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 "appenv.h"
|
|
#include "actionarea.h"
|
|
#include "color_picker.h"
|
|
#include "draw_core.h"
|
|
#include "drawable.h"
|
|
#include "gdisplay.h"
|
|
#include "cursorutil.h"
|
|
#include "info_dialog.h"
|
|
#include "palette.h"
|
|
#include "tool_options_ui.h"
|
|
#include "tools.h"
|
|
#include "gimprc.h"
|
|
|
|
#include "libgimp/gimpintl.h"
|
|
|
|
/* maximum information buffer size */
|
|
#define MAX_INFO_BUF 8
|
|
|
|
/* the color picker structures */
|
|
|
|
typedef struct _ColorPickerOptions ColorPickerOptions;
|
|
struct _ColorPickerOptions
|
|
{
|
|
ToolOptions tool_options;
|
|
|
|
gint sample_merged;
|
|
gint sample_merged_d;
|
|
GtkWidget *sample_merged_w;
|
|
|
|
gint sample_average;
|
|
gint sample_average_d;
|
|
GtkWidget *sample_average_w;
|
|
|
|
gdouble average_radius;
|
|
gdouble average_radius_d;
|
|
GtkObject *average_radius_w;
|
|
};
|
|
|
|
typedef struct _ColorPickerTool ColorPickerTool;
|
|
struct _ColorPickerTool
|
|
{
|
|
DrawCore *core; /* Core select object */
|
|
|
|
gint centerx; /* starting x coord */
|
|
gint centery; /* starting y coord */
|
|
};
|
|
|
|
/* the color picker tool options */
|
|
static ColorPickerOptions * color_picker_options = NULL;
|
|
|
|
/* the color value */
|
|
gint col_value[5] = { 0, 0, 0, 0, 0 };
|
|
|
|
/* the color picker dialog */
|
|
static gint update_type;
|
|
static GimpImageType sample_type;
|
|
static InfoDialog * color_picker_info = NULL;
|
|
static gchar red_buf [MAX_INFO_BUF];
|
|
static gchar green_buf [MAX_INFO_BUF];
|
|
static gchar blue_buf [MAX_INFO_BUF];
|
|
static gchar alpha_buf [MAX_INFO_BUF];
|
|
static gchar index_buf [MAX_INFO_BUF];
|
|
static gchar gray_buf [MAX_INFO_BUF];
|
|
static gchar hex_buf [MAX_INFO_BUF];
|
|
|
|
|
|
/* local function prototypes */
|
|
|
|
static void color_picker_button_press (Tool *, GdkEventButton *, gpointer);
|
|
static void color_picker_button_release (Tool *, GdkEventButton *, gpointer);
|
|
static void color_picker_motion (Tool *, GdkEventMotion *, gpointer);
|
|
static void color_picker_cursor_update (Tool *, GdkEventMotion *, gpointer);
|
|
static void color_picker_control (Tool *, ToolAction, gpointer);
|
|
|
|
static void color_picker_info_window_close_callback (GtkWidget *, gpointer);
|
|
static void color_picker_info_update (Tool *, gboolean);
|
|
|
|
|
|
/* functions */
|
|
|
|
static void
|
|
color_picker_options_reset (void)
|
|
{
|
|
ColorPickerOptions *options = color_picker_options;
|
|
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->sample_merged_w),
|
|
options->sample_merged_d);
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->sample_average_w),
|
|
options->sample_average_d);
|
|
gtk_adjustment_set_value (GTK_ADJUSTMENT (options->average_radius_w),
|
|
options->average_radius_d);
|
|
}
|
|
|
|
static ColorPickerOptions *
|
|
color_picker_options_new (void)
|
|
{
|
|
ColorPickerOptions *options;
|
|
|
|
GtkWidget *vbox;
|
|
GtkWidget *abox;
|
|
GtkWidget *table;
|
|
GtkWidget *label;
|
|
GtkWidget *scale;
|
|
|
|
/* the new color picker tool options structure */
|
|
options = g_new (ColorPickerOptions, 1);
|
|
tool_options_init ((ToolOptions *) options,
|
|
_("Color Picker Options"),
|
|
color_picker_options_reset);
|
|
options->sample_merged = options->sample_merged_d = FALSE;
|
|
options->sample_average = options->sample_average_d = FALSE;
|
|
options->average_radius = options->average_radius_d = 1.0;
|
|
|
|
/* the main vbox */
|
|
vbox = options->tool_options.main_vbox;
|
|
|
|
/* the sample merged toggle button */
|
|
options->sample_merged_w =
|
|
gtk_check_button_new_with_label (_("Sample Merged"));
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->sample_merged_w),
|
|
options->sample_merged_d);
|
|
gtk_box_pack_start (GTK_BOX (vbox), options->sample_merged_w, FALSE, FALSE, 0);
|
|
gtk_signal_connect (GTK_OBJECT (options->sample_merged_w), "toggled",
|
|
(GtkSignalFunc) tool_options_toggle_update,
|
|
&options->sample_merged);
|
|
gtk_widget_show (options->sample_merged_w);
|
|
|
|
/* the sample average options */
|
|
table = gtk_table_new (2, 2, FALSE);
|
|
gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
|
|
gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
|
|
|
|
options->sample_average_w =
|
|
gtk_check_button_new_with_label (_("Sample Average"));
|
|
gtk_table_attach (GTK_TABLE (table), options->sample_average_w, 0, 1, 0, 1,
|
|
GTK_SHRINK | GTK_FILL, GTK_SHRINK, 0, 0);
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (options->sample_average_w),
|
|
options->sample_average_d);
|
|
gtk_signal_connect (GTK_OBJECT (options->sample_average_w), "toggled",
|
|
(GtkSignalFunc) tool_options_toggle_update,
|
|
&options->sample_average);
|
|
gtk_widget_show (options->sample_average_w);
|
|
|
|
label = gtk_label_new (_("Radius:"));
|
|
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
|
|
gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
|
|
GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
|
|
gtk_widget_show (label);
|
|
|
|
/* the feather radius scale */
|
|
abox = gtk_alignment_new (0.5, 1.0, 1.0, 0.0);
|
|
gtk_table_attach (GTK_TABLE (table), abox, 1, 2, 0, 2,
|
|
GTK_EXPAND | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
|
|
gtk_widget_show (abox);
|
|
|
|
options->average_radius_w =
|
|
gtk_adjustment_new (options->average_radius_d, 1.0, 15.0, 2.0, 2.0, 0.0);
|
|
scale = gtk_hscale_new (GTK_ADJUSTMENT (options->average_radius_w));
|
|
gtk_scale_set_digits (GTK_SCALE (scale), 0);
|
|
gtk_container_add (GTK_CONTAINER (abox), scale);
|
|
gtk_widget_set_sensitive (scale, options->sample_average_d);
|
|
gtk_object_set_data (GTK_OBJECT (options->sample_average_w), "set_sensitive",
|
|
scale);
|
|
gtk_widget_set_sensitive (label, options->sample_average_d);
|
|
gtk_object_set_data (GTK_OBJECT (scale), "set_sensitive",
|
|
label);
|
|
gtk_scale_set_value_pos (GTK_SCALE (scale), GTK_POS_TOP);
|
|
gtk_range_set_update_policy (GTK_RANGE (scale), GTK_UPDATE_DELAYED);
|
|
gtk_signal_connect (GTK_OBJECT (options->average_radius_w), "value_changed",
|
|
(GtkSignalFunc) tool_options_double_adjustment_update,
|
|
&options->average_radius);
|
|
gtk_widget_show (scale);
|
|
gtk_widget_show (table);
|
|
|
|
return options;
|
|
}
|
|
|
|
static void
|
|
color_picker_button_press (Tool *tool,
|
|
GdkEventButton *bevent,
|
|
gpointer gdisp_ptr)
|
|
{
|
|
GDisplay * gdisp;
|
|
ColorPickerTool *cp_tool;
|
|
gint x, y;
|
|
|
|
static ActionAreaItem action_items[] =
|
|
{
|
|
{ N_("Close"), color_picker_info_window_close_callback, NULL, NULL },
|
|
};
|
|
|
|
gdisp = (GDisplay *) gdisp_ptr;
|
|
cp_tool = (ColorPickerTool *) tool->private;
|
|
|
|
/* Make the tool active and set it's gdisplay & drawable */
|
|
tool->gdisp_ptr = gdisp;
|
|
tool->drawable = gimage_active_drawable (gdisp->gimage);
|
|
tool->state = ACTIVE;
|
|
|
|
/* create the info dialog if it doesn't exist */
|
|
if (! color_picker_info)
|
|
{
|
|
color_picker_info = info_dialog_new (_("Color Picker"));
|
|
|
|
/* if the gdisplay is for a color image, the dialog must have RGB */
|
|
switch (drawable_type (tool->drawable))
|
|
{
|
|
case RGB_GIMAGE: case RGBA_GIMAGE:
|
|
info_dialog_add_label (color_picker_info, _("Red:"), red_buf);
|
|
info_dialog_add_label (color_picker_info, _("Green:"), green_buf);
|
|
info_dialog_add_label (color_picker_info, _("Blue:"), blue_buf);
|
|
info_dialog_add_label (color_picker_info, _("Alpha:"), alpha_buf);
|
|
info_dialog_add_label (color_picker_info, _("Hex Triplet:"), hex_buf);
|
|
break;
|
|
|
|
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
|
|
info_dialog_add_label (color_picker_info, _("Index:"), index_buf);
|
|
info_dialog_add_label (color_picker_info, _("Alpha:"), alpha_buf);
|
|
info_dialog_add_label (color_picker_info, _("Red:"), red_buf);
|
|
info_dialog_add_label (color_picker_info, _("Green:"), green_buf);
|
|
info_dialog_add_label (color_picker_info, _("Blue:"), blue_buf);
|
|
info_dialog_add_label (color_picker_info, _("Hex Triplet"), hex_buf);
|
|
break;
|
|
|
|
case GRAY_GIMAGE: case GRAYA_GIMAGE:
|
|
info_dialog_add_label (color_picker_info, _("Intensity:"), gray_buf);
|
|
info_dialog_add_label (color_picker_info, _("Alpha:"), alpha_buf);
|
|
info_dialog_add_label (color_picker_info, _("Hex Triplet:"), hex_buf);
|
|
break;
|
|
|
|
default :
|
|
break;
|
|
}
|
|
|
|
/* create the action area */
|
|
action_items[0].user_data = color_picker_info;
|
|
build_action_area (GTK_DIALOG (color_picker_info->shell),
|
|
action_items, 1, 0);
|
|
}
|
|
|
|
/* Keep the coordinates of the target */
|
|
gdisplay_untransform_coords (gdisp, bevent->x, bevent->y,
|
|
&cp_tool->centerx, &cp_tool->centery, FALSE, 1);
|
|
|
|
gdk_pointer_grab (gdisp->canvas->window, FALSE,
|
|
(GDK_POINTER_MOTION_HINT_MASK |
|
|
GDK_BUTTON1_MOTION_MASK |
|
|
GDK_BUTTON_RELEASE_MASK),
|
|
NULL, NULL, bevent->time);
|
|
|
|
/* First, transform the coordinates to gimp image space */
|
|
gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y,
|
|
FALSE, FALSE);
|
|
|
|
/* if the shift key is down, create a new color.
|
|
* otherwise, modify the current color.
|
|
*/
|
|
if (bevent->state & GDK_SHIFT_MASK)
|
|
{
|
|
color_picker_info_update (tool,
|
|
pick_color (gdisp->gimage, tool->drawable, x, y,
|
|
color_picker_options->sample_merged,
|
|
color_picker_options->sample_average,
|
|
color_picker_options->average_radius,
|
|
COLOR_NEW));
|
|
update_type = COLOR_UPDATE_NEW;
|
|
}
|
|
else
|
|
{
|
|
color_picker_info_update (tool,
|
|
pick_color (gdisp->gimage, tool->drawable, x, y,
|
|
color_picker_options->sample_merged,
|
|
color_picker_options->sample_average,
|
|
color_picker_options->average_radius,
|
|
COLOR_UPDATE));
|
|
update_type = COLOR_UPDATE;
|
|
}
|
|
|
|
/* Start drawing the colorpicker tool */
|
|
draw_core_start (cp_tool->core, gdisp->canvas->window, tool);
|
|
}
|
|
|
|
static void
|
|
color_picker_button_release (Tool *tool,
|
|
GdkEventButton *bevent,
|
|
gpointer gdisp_ptr)
|
|
{
|
|
GDisplay *gdisp;
|
|
ColorPickerTool *cp_tool;
|
|
gint x, y;
|
|
|
|
gdk_pointer_ungrab (bevent->time);
|
|
gdk_flush ();
|
|
gdisp = (GDisplay *) gdisp_ptr;
|
|
cp_tool = (ColorPickerTool *) tool->private;
|
|
|
|
/* First, transform the coordinates to gimp image space */
|
|
gdisplay_untransform_coords (gdisp, bevent->x, bevent->y, &x, &y,
|
|
FALSE, FALSE);
|
|
|
|
color_picker_info_update (tool,
|
|
pick_color (gdisp->gimage, tool->drawable, x, y,
|
|
color_picker_options->sample_merged,
|
|
color_picker_options->sample_average,
|
|
color_picker_options->average_radius,
|
|
update_type));
|
|
|
|
draw_core_stop (cp_tool->core, tool);
|
|
tool->state = INACTIVE;
|
|
}
|
|
|
|
static void
|
|
color_picker_motion (Tool *tool,
|
|
GdkEventMotion *mevent,
|
|
gpointer gdisp_ptr)
|
|
{
|
|
GDisplay *gdisp;
|
|
ColorPickerTool *cp_tool;
|
|
int x, y;
|
|
|
|
gdisp = (GDisplay *) gdisp_ptr;
|
|
cp_tool = (ColorPickerTool *) tool->private;
|
|
|
|
/* undraw the current tool */
|
|
draw_core_pause (cp_tool->core, tool);
|
|
|
|
/* First, transform the coordinates to gimp image space */
|
|
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y,
|
|
FALSE, FALSE);
|
|
|
|
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y,
|
|
&cp_tool->centerx, &cp_tool->centery,
|
|
FALSE, TRUE);
|
|
|
|
color_picker_info_update (tool,
|
|
pick_color (gdisp->gimage, tool->drawable, x, y,
|
|
color_picker_options->sample_merged,
|
|
color_picker_options->sample_average,
|
|
color_picker_options->average_radius,
|
|
update_type));
|
|
|
|
/* redraw the current tool */
|
|
draw_core_resume (cp_tool->core, tool);
|
|
}
|
|
|
|
static void
|
|
color_picker_cursor_update (Tool *tool,
|
|
GdkEventMotion *mevent,
|
|
gpointer gdisp_ptr)
|
|
{
|
|
GDisplay *gdisp;
|
|
int x, y;
|
|
|
|
gdisp = (GDisplay *) gdisp_ptr;
|
|
|
|
gdisplay_untransform_coords (gdisp, mevent->x, mevent->y, &x, &y,
|
|
FALSE, FALSE);
|
|
|
|
if (gimage_pick_correlate_layer (gdisp->gimage, x, y))
|
|
gdisplay_install_tool_cursor (gdisp, GIMP_COLOR_PICKER_CURSOR);
|
|
else
|
|
gdisplay_install_tool_cursor (gdisp, GDK_TOP_LEFT_ARROW);
|
|
}
|
|
|
|
static void
|
|
color_picker_control (Tool *tool,
|
|
ToolAction action,
|
|
gpointer gdisp_ptr)
|
|
{
|
|
ColorPickerTool * cp_tool;
|
|
|
|
cp_tool = (ColorPickerTool *) tool->private;
|
|
|
|
switch (action)
|
|
{
|
|
case PAUSE :
|
|
draw_core_pause (cp_tool->core, tool);
|
|
break;
|
|
|
|
case RESUME :
|
|
draw_core_resume (cp_tool->core, tool);
|
|
break;
|
|
|
|
case HALT :
|
|
draw_core_stop (cp_tool->core, tool);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
typedef guchar * (*GetColorFunc) (GtkObject *, int, int);
|
|
|
|
gboolean
|
|
pick_color (GimpImage *gimage,
|
|
GimpDrawable *drawable,
|
|
gint x,
|
|
gint y,
|
|
gboolean sample_merged,
|
|
gboolean sample_average,
|
|
gdouble average_radius,
|
|
gint final)
|
|
{
|
|
guchar *color;
|
|
gint offx, offy;
|
|
gint has_alpha;
|
|
gint is_indexed;
|
|
GetColorFunc get_color_func;
|
|
GtkObject *get_color_obj;
|
|
|
|
if (!drawable && !sample_merged)
|
|
return FALSE;
|
|
|
|
if (!sample_merged)
|
|
{
|
|
drawable_offsets (drawable, &offx, &offy);
|
|
x -= offx;
|
|
y -= offy;
|
|
|
|
sample_type = gimp_drawable_type (drawable);
|
|
is_indexed = gimp_drawable_indexed (drawable);
|
|
|
|
get_color_func = (GetColorFunc) gimp_drawable_get_color_at;
|
|
get_color_obj = GTK_OBJECT (drawable);
|
|
}
|
|
else
|
|
{
|
|
sample_type = gimp_image_composite_type (gimage);
|
|
is_indexed = FALSE;
|
|
|
|
get_color_func = (GetColorFunc) gimp_image_get_color_at;
|
|
get_color_obj = GTK_OBJECT (gimage);
|
|
}
|
|
|
|
has_alpha = TYPE_HAS_ALPHA (sample_type);
|
|
|
|
if (!(color = (*get_color_func) (get_color_obj, x, y)))
|
|
return FALSE;
|
|
|
|
if (sample_average)
|
|
{
|
|
gint i, j;
|
|
gint count = 0;
|
|
gint color_avg[4] = { 0, 0, 0, 0 };
|
|
guchar *tmp_color;
|
|
gint radius = (gint) average_radius;
|
|
|
|
for (i = x - radius; i <= x + radius; i++)
|
|
for (j = y - radius; j <= y + radius; j++)
|
|
if ((tmp_color = (*get_color_func) (get_color_obj, i, j)))
|
|
{
|
|
count++;
|
|
|
|
color_avg[RED_PIX] += tmp_color[RED_PIX];
|
|
color_avg[GREEN_PIX] += tmp_color[GREEN_PIX];
|
|
color_avg[BLUE_PIX] += tmp_color[BLUE_PIX];
|
|
if (has_alpha)
|
|
color_avg[ALPHA_PIX] += tmp_color[3];
|
|
|
|
g_free(tmp_color);
|
|
}
|
|
|
|
color[RED_PIX] = (guchar) (color_avg[RED_PIX] / count);
|
|
color[GREEN_PIX] = (guchar) (color_avg[GREEN_PIX] / count);
|
|
color[BLUE_PIX] = (guchar) (color_avg[BLUE_PIX] / count);
|
|
if (has_alpha)
|
|
color[ALPHA_PIX] = (guchar) (color_avg[3] / count);
|
|
|
|
is_indexed = FALSE;
|
|
}
|
|
|
|
col_value[RED_PIX] = color[RED_PIX];
|
|
col_value[GREEN_PIX] = color[GREEN_PIX];
|
|
col_value[BLUE_PIX] = color[BLUE_PIX];
|
|
if (has_alpha)
|
|
col_value[ALPHA_PIX] = color[3];
|
|
if (is_indexed)
|
|
col_value[4] = color[4];
|
|
|
|
palette_set_active_color (col_value [RED_PIX], col_value [GREEN_PIX],
|
|
col_value [BLUE_PIX], final);
|
|
g_free (color);
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
colorpicker_draw (Tool *tool)
|
|
{
|
|
GDisplay * gdisp;
|
|
ColorPickerTool * cp_tool;
|
|
gint tx, ty;
|
|
gint radiusx, radiusy;
|
|
gint cx, cy;
|
|
|
|
if(!color_picker_options->sample_average)
|
|
return;
|
|
|
|
gdisp = (GDisplay *) tool->gdisp_ptr;
|
|
cp_tool = (ColorPickerTool *) tool->private;
|
|
|
|
gdisplay_transform_coords (gdisp, cp_tool->centerx, cp_tool->centery,
|
|
&tx, &ty, TRUE);
|
|
|
|
radiusx = SCALEX (gdisp, color_picker_options->average_radius);
|
|
radiusy = SCALEY (gdisp, color_picker_options->average_radius);
|
|
cx = SCALEX (gdisp, 1);
|
|
cy = SCALEY (gdisp, 1);
|
|
|
|
/* Draw the circle around the collecting area */
|
|
gdk_draw_rectangle (cp_tool->core->win, cp_tool->core->gc, 0,
|
|
tx - radiusx,
|
|
ty - radiusy,
|
|
2 * radiusx + cx, 2 * radiusy + cy);
|
|
|
|
if(radiusx > 1 && radiusy > 1)
|
|
{
|
|
gdk_draw_rectangle (cp_tool->core->win, cp_tool->core->gc, 0,
|
|
tx - radiusx + 2,
|
|
ty - radiusy + 2,
|
|
2 * radiusx + cx - 4, 2 * radiusy + cy - 4);
|
|
}
|
|
}
|
|
|
|
static void
|
|
color_picker_info_update (Tool *tool,
|
|
gboolean valid)
|
|
{
|
|
if (!valid)
|
|
{
|
|
g_snprintf (red_buf, MAX_INFO_BUF, _("N/A"));
|
|
g_snprintf (green_buf, MAX_INFO_BUF, _("N/A"));
|
|
g_snprintf (blue_buf, MAX_INFO_BUF, _("N/A"));
|
|
g_snprintf (alpha_buf, MAX_INFO_BUF, _("N/A"));
|
|
g_snprintf (index_buf, MAX_INFO_BUF, _("N/A"));
|
|
g_snprintf (gray_buf, MAX_INFO_BUF, _("N/A"));
|
|
g_snprintf (hex_buf, MAX_INFO_BUF, _("N/A"));
|
|
}
|
|
else
|
|
{
|
|
switch (sample_type)
|
|
{
|
|
case RGB_GIMAGE: case RGBA_GIMAGE:
|
|
g_snprintf (red_buf, MAX_INFO_BUF, "%d", col_value [RED_PIX]);
|
|
g_snprintf (green_buf, MAX_INFO_BUF, "%d", col_value [GREEN_PIX]);
|
|
g_snprintf (blue_buf, MAX_INFO_BUF, "%d", col_value [BLUE_PIX]);
|
|
if (sample_type == RGBA_GIMAGE)
|
|
g_snprintf (alpha_buf, MAX_INFO_BUF, "%d", col_value [ALPHA_PIX]);
|
|
else
|
|
g_snprintf (alpha_buf, MAX_INFO_BUF, _("N/A"));
|
|
g_snprintf (hex_buf, MAX_INFO_BUF, "#%.2x%.2x%.2x",
|
|
col_value [RED_PIX],
|
|
col_value [GREEN_PIX],
|
|
col_value [BLUE_PIX]);
|
|
break;
|
|
|
|
case INDEXED_GIMAGE: case INDEXEDA_GIMAGE:
|
|
g_snprintf (index_buf, MAX_INFO_BUF, "%d", col_value [4]);
|
|
if (sample_type == INDEXEDA_GIMAGE)
|
|
g_snprintf (alpha_buf, MAX_INFO_BUF, "%d", col_value [ALPHA_PIX]);
|
|
else
|
|
g_snprintf (alpha_buf, MAX_INFO_BUF, _("N/A"));
|
|
g_snprintf (red_buf, MAX_INFO_BUF, "%d", col_value [RED_PIX]);
|
|
g_snprintf (green_buf, MAX_INFO_BUF, "%d", col_value [GREEN_PIX]);
|
|
g_snprintf (blue_buf, MAX_INFO_BUF, "%d", col_value [BLUE_PIX]);
|
|
g_snprintf (hex_buf, MAX_INFO_BUF, "#%.2x%.2x%.2x",
|
|
col_value [RED_PIX],
|
|
col_value [GREEN_PIX],
|
|
col_value [BLUE_PIX]);
|
|
break;
|
|
|
|
case GRAY_GIMAGE: case GRAYA_GIMAGE:
|
|
g_snprintf (gray_buf, MAX_INFO_BUF, "%d", col_value [GRAY_PIX]);
|
|
if (sample_type == GRAYA_GIMAGE)
|
|
g_snprintf (alpha_buf, MAX_INFO_BUF, "%d", col_value [ALPHA_PIX]);
|
|
else
|
|
g_snprintf (alpha_buf, MAX_INFO_BUF, _("N/A"));
|
|
g_snprintf (hex_buf, MAX_INFO_BUF, "#%.2x%.2x%.2x",
|
|
col_value [GRAY_PIX],
|
|
col_value [GRAY_PIX],
|
|
col_value [GRAY_PIX]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
info_dialog_update (color_picker_info);
|
|
info_dialog_popup (color_picker_info);
|
|
}
|
|
|
|
static void
|
|
color_picker_info_window_close_callback (GtkWidget *widget,
|
|
gpointer client_data)
|
|
{
|
|
info_dialog_popdown ((InfoDialog *) client_data);
|
|
}
|
|
|
|
Tool *
|
|
tools_new_color_picker ()
|
|
{
|
|
Tool * tool;
|
|
ColorPickerTool * private;
|
|
|
|
/* The tool options */
|
|
if (! color_picker_options)
|
|
{
|
|
color_picker_options = color_picker_options_new ();
|
|
tools_register (COLOR_PICKER, (ToolOptions *) color_picker_options);
|
|
}
|
|
|
|
tool = tools_new_tool (COLOR_PICKER);
|
|
private = g_new (ColorPickerTool, 1);
|
|
|
|
private->core = draw_core_new (colorpicker_draw);
|
|
|
|
tool->preserve = FALSE; /* Don't preserve on drawable change */
|
|
|
|
tool->private = (void *) private;
|
|
|
|
tool->button_press_func = color_picker_button_press;
|
|
tool->button_release_func = color_picker_button_release;
|
|
tool->motion_func = color_picker_motion;
|
|
tool->cursor_update_func = color_picker_cursor_update;
|
|
tool->control_func = color_picker_control;
|
|
|
|
return tool;
|
|
}
|
|
|
|
void
|
|
tools_free_color_picker (Tool *tool)
|
|
{
|
|
ColorPickerTool * cp_tool;
|
|
|
|
cp_tool = (ColorPickerTool *) tool->private;
|
|
|
|
if (tool->state == ACTIVE)
|
|
draw_core_stop (cp_tool->core, tool);
|
|
|
|
draw_core_free (cp_tool->core);
|
|
|
|
if (color_picker_info)
|
|
{
|
|
info_dialog_free (color_picker_info);
|
|
color_picker_info = NULL;
|
|
}
|
|
|
|
g_free (cp_tool);
|
|
}
|