mirror of https://github.com/GNOME/gimp.git
app: the Device Status dockable now shows context-sensitive colors.
I moved the function to select a valid contextual RGBA format as a core API gimp_context_get_rgba_format(). This same API is now used in context actions, as well as in the GimpDeviceStatus widget. The latter now shows per-device fg/bg colors relatively to the active image's format. The tooltip will also display contextual information (i.e. either the image's name whose space is used, or sRGB). Of course, this all updates when switching images by connecting to the image-changed signal.
This commit is contained in:
parent
cd09634dc2
commit
7de118051f
|
@ -30,8 +30,6 @@
|
|||
|
||||
#include "operations/layer-modes/gimp-layer-modes.h"
|
||||
|
||||
#include "gegl/gimp-babl.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpbrushgenerated.h"
|
||||
#include "core/gimpcontext.h"
|
||||
|
@ -81,9 +79,6 @@ static gboolean context_set_color_index (gint index,
|
|||
static GimpPaletteEditor * context_get_palette_editor (void);
|
||||
static GimpColormapEditor * context_get_colormap_editor (void);
|
||||
|
||||
static const Babl * context_get_rgb_format (GimpContext *context,
|
||||
GeglColor *color);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
|
@ -151,7 +146,7 @@ context_foreground_red_cmd_callback (GimpAction *action,
|
|||
select_type = (GimpActionSelectType) g_variant_get_int32 (value);
|
||||
|
||||
color = gegl_color_duplicate (gimp_context_get_foreground (context));
|
||||
format = context_get_rgb_format (context, color);
|
||||
format = gimp_context_get_rgba_format (context, color, "double", NULL);
|
||||
|
||||
gegl_color_get_pixel (color, format, pixel);
|
||||
/* TODO: if value was already out-of-gamut, say we want to decrease it
|
||||
|
@ -183,7 +178,7 @@ context_foreground_green_cmd_callback (GimpAction *action,
|
|||
select_type = (GimpActionSelectType) g_variant_get_int32 (value);
|
||||
|
||||
color = gegl_color_duplicate (gimp_context_get_foreground (context));
|
||||
format = context_get_rgb_format (context, color);
|
||||
format = gimp_context_get_rgba_format (context, color, "double", NULL);
|
||||
|
||||
gegl_color_get_pixel (color, format, pixel);
|
||||
pixel[1] = action_select_value (select_type,
|
||||
|
@ -210,7 +205,7 @@ context_foreground_blue_cmd_callback (GimpAction *action,
|
|||
select_type = (GimpActionSelectType) g_variant_get_int32 (value);
|
||||
|
||||
color = gegl_color_duplicate (gimp_context_get_foreground (context));
|
||||
format = context_get_rgb_format (context, color);
|
||||
format = gimp_context_get_rgba_format (context, color, "double", NULL);
|
||||
|
||||
gegl_color_get_pixel (color, format, pixel);
|
||||
pixel[2] = action_select_value (select_type,
|
||||
|
@ -237,7 +232,7 @@ context_background_red_cmd_callback (GimpAction *action,
|
|||
select_type = (GimpActionSelectType) g_variant_get_int32 (value);
|
||||
|
||||
color = gegl_color_duplicate (gimp_context_get_background (context));
|
||||
format = context_get_rgb_format (context, color);
|
||||
format = gimp_context_get_rgba_format (context, color, "double", NULL);
|
||||
|
||||
gegl_color_get_pixel (color, format, pixel);
|
||||
pixel[0] = action_select_value (select_type,
|
||||
|
@ -264,7 +259,7 @@ context_background_green_cmd_callback (GimpAction *action,
|
|||
select_type = (GimpActionSelectType) g_variant_get_int32 (value);
|
||||
|
||||
color = gegl_color_duplicate (gimp_context_get_background (context));
|
||||
format = context_get_rgb_format (context, color);
|
||||
format = gimp_context_get_rgba_format (context, color, "double", NULL);
|
||||
|
||||
gegl_color_get_pixel (color, format, pixel);
|
||||
pixel[1] = action_select_value (select_type,
|
||||
|
@ -291,7 +286,7 @@ context_background_blue_cmd_callback (GimpAction *action,
|
|||
select_type = (GimpActionSelectType) g_variant_get_int32 (value);
|
||||
|
||||
color = gegl_color_duplicate (gimp_context_get_background (context));
|
||||
format = context_get_rgb_format (context, color);
|
||||
format = gimp_context_get_rgba_format (context, color, "double", NULL);
|
||||
|
||||
gegl_color_get_pixel (color, format, pixel);
|
||||
pixel[2] = action_select_value (select_type,
|
||||
|
@ -1096,86 +1091,3 @@ context_get_colormap_editor (void)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* The logic for the format to use in RGB color actions is as following:
|
||||
* - The space we navigate through is the active image's space.
|
||||
* - Increasing/decreasing follows the image TRC (in particular, if the image is
|
||||
* linear or perceptual, we care about chromaticities yet don't follow the
|
||||
* space TRC).
|
||||
* - If there is no active image or if its space is non-sRGB, we use the context
|
||||
* color's space.
|
||||
* - We discard non-RGB spaces and fallback to sRGB.
|
||||
*/
|
||||
static const Babl *
|
||||
context_get_rgb_format (GimpContext *context,
|
||||
GeglColor *color)
|
||||
{
|
||||
GimpImage *image = NULL;
|
||||
const Babl *format = NULL;
|
||||
const Babl *space = NULL;
|
||||
GimpTRCType trc = GIMP_TRC_NON_LINEAR;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
||||
|
||||
image = gimp_context_get_image (context);
|
||||
if (image)
|
||||
{
|
||||
format = gimp_image_get_layer_format (image, FALSE);
|
||||
space = babl_format_get_space (format);
|
||||
}
|
||||
|
||||
if (space == NULL ||
|
||||
#if BABL_MINOR_VERSION > 1 || (BABL_MINOR_VERSION == 1 && BABL_MICRO_VERSION >= 107)
|
||||
! babl_space_is_rgb (space) ||
|
||||
#else
|
||||
babl_space_is_cmyk (space) ||
|
||||
babl_space_is_gray (space) ||
|
||||
#endif
|
||||
FALSE)
|
||||
{
|
||||
format = gegl_color_get_format (color);
|
||||
space = babl_format_get_space (format);
|
||||
}
|
||||
|
||||
#if BABL_MINOR_VERSION > 1 || (BABL_MINOR_VERSION == 1 && BABL_MICRO_VERSION >= 107)
|
||||
if (! babl_space_is_rgb (space))
|
||||
#else
|
||||
if (babl_space_is_cmyk (space) || babl_space_is_gray (space))
|
||||
#endif
|
||||
{
|
||||
format = NULL;
|
||||
space = NULL;
|
||||
}
|
||||
|
||||
if (format != NULL)
|
||||
{
|
||||
if (image != NULL)
|
||||
{
|
||||
GimpPrecision precision;
|
||||
|
||||
precision = gimp_image_get_precision (image);
|
||||
trc = gimp_babl_trc (precision);
|
||||
}
|
||||
else
|
||||
{
|
||||
trc = gimp_babl_format_get_trc (format);
|
||||
}
|
||||
}
|
||||
|
||||
switch (trc)
|
||||
{
|
||||
case GIMP_TRC_LINEAR:
|
||||
format = babl_format_with_space ("RGBA double", space);
|
||||
break;
|
||||
case GIMP_TRC_NON_LINEAR:
|
||||
format = babl_format_with_space ("R'G'B'A double", space);
|
||||
break;
|
||||
case GIMP_TRC_PERCEPTUAL:
|
||||
format = babl_format_with_space ("R~G~B~A double", space);
|
||||
break;
|
||||
default:
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include "config/gimpcoreconfig.h"
|
||||
|
||||
#include "gegl/gimp-babl.h"
|
||||
|
||||
#include "gimp.h"
|
||||
#include "gimp-memsize.h"
|
||||
#include "gimpbrush.h"
|
||||
|
@ -1913,6 +1915,111 @@ gimp_context_image_changed (GimpContext *context)
|
|||
context->image);
|
||||
}
|
||||
|
||||
/* This is a utility function to share, across the program, some common logic of
|
||||
* "which format to use when you are not sure and you need to give generic color
|
||||
* information" in RGBA.
|
||||
* @babl_type must be a valid babl type name such as "u8", "double", "float".
|
||||
* If @space_image is not NULL, it will be used to return the GimpImage
|
||||
* associated to the returned format (if the returned format is indeed using the
|
||||
* image's space).
|
||||
*
|
||||
* The logic for the format to use in RGB color actions is as follows:
|
||||
* - The space we navigate through is the active image's space.
|
||||
* - Increasing/decreasing follows the image TRC (in particular, if the image is
|
||||
* linear or perceptual, we care about chromaticities yet don't follow the
|
||||
* space TRC).
|
||||
* - If there is no active image or if its space is non-sRGB, we use the context
|
||||
* color's space (if set).
|
||||
* - We discard non-RGB spaces and fallback to sRGB.
|
||||
*/
|
||||
const Babl *
|
||||
gimp_context_get_rgba_format (GimpContext *context,
|
||||
GeglColor *color,
|
||||
const gchar *babl_type,
|
||||
GimpImage **space_image)
|
||||
{
|
||||
GimpImage *image = NULL;
|
||||
const Babl *format = NULL;
|
||||
const Babl *space = NULL;
|
||||
gchar *format_name;
|
||||
GimpTRCType trc = GIMP_TRC_NON_LINEAR;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
||||
g_return_val_if_fail (babl_type != NULL , NULL);
|
||||
g_return_val_if_fail (space_image == NULL || *space_image == NULL, NULL);
|
||||
|
||||
image = gimp_context_get_image (context);
|
||||
if (image)
|
||||
{
|
||||
format = gimp_image_get_layer_format (image, FALSE);
|
||||
space = babl_format_get_space (format);
|
||||
if (space_image)
|
||||
*space_image = image;
|
||||
}
|
||||
|
||||
if (color != NULL &&
|
||||
(space == NULL ||
|
||||
#if BABL_MINOR_VERSION > 1 || (BABL_MINOR_VERSION == 1 && BABL_MICRO_VERSION >= 107)
|
||||
! babl_space_is_rgb (space) ||
|
||||
#else
|
||||
babl_space_is_cmyk (space) ||
|
||||
babl_space_is_gray (space) ||
|
||||
#endif
|
||||
FALSE))
|
||||
{
|
||||
format = gegl_color_get_format (color);
|
||||
space = babl_format_get_space (format);
|
||||
if (space_image)
|
||||
*space_image = NULL;
|
||||
}
|
||||
|
||||
#if BABL_MINOR_VERSION > 1 || (BABL_MINOR_VERSION == 1 && BABL_MICRO_VERSION >= 107)
|
||||
if (! babl_space_is_rgb (space))
|
||||
#else
|
||||
if (babl_space_is_cmyk (space) || babl_space_is_gray (space))
|
||||
#endif
|
||||
{
|
||||
format = NULL;
|
||||
space = NULL;
|
||||
if (space_image)
|
||||
*space_image = NULL;
|
||||
}
|
||||
|
||||
if (format != NULL)
|
||||
{
|
||||
if (image != NULL)
|
||||
{
|
||||
GimpPrecision precision;
|
||||
|
||||
precision = gimp_image_get_precision (image);
|
||||
trc = gimp_babl_trc (precision);
|
||||
}
|
||||
else
|
||||
{
|
||||
trc = gimp_babl_format_get_trc (format);
|
||||
}
|
||||
}
|
||||
|
||||
switch (trc)
|
||||
{
|
||||
case GIMP_TRC_LINEAR:
|
||||
format_name = g_strdup_printf ("RGBA %s", babl_type);
|
||||
break;
|
||||
case GIMP_TRC_NON_LINEAR:
|
||||
format_name = g_strdup_printf ("R'G'B'A %s", babl_type);
|
||||
break;
|
||||
case GIMP_TRC_PERCEPTUAL:
|
||||
format_name = g_strdup_printf ("R~G~B~A %s", babl_type);
|
||||
break;
|
||||
default:
|
||||
g_return_val_if_reached (NULL);
|
||||
}
|
||||
format = babl_format_with_space (format_name, space);
|
||||
g_free (format_name);
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_context_image_disconnect (GimpImage *image,
|
||||
GimpContext *context)
|
||||
|
|
|
@ -224,6 +224,12 @@ void gimp_context_set_image (GimpContext *context,
|
|||
void gimp_context_image_changed (GimpContext *context);
|
||||
|
||||
|
||||
const Babl * gimp_context_get_rgba_format (GimpContext *context,
|
||||
GeglColor *color,
|
||||
const gchar *babl_type,
|
||||
GimpImage **space_image);
|
||||
|
||||
|
||||
/* display */
|
||||
GimpDisplay * gimp_context_get_display (GimpContext *context);
|
||||
void gimp_context_set_display (GimpContext *context,
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "core/gimpcontext.h"
|
||||
#include "core/gimpdatafactory.h"
|
||||
#include "core/gimpgradient.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimplist.h"
|
||||
#include "core/gimppattern.h"
|
||||
#include "core/gimptoolinfo.h"
|
||||
|
@ -106,6 +107,9 @@ static void gimp_device_status_notify_device (GimpDeviceManager *manager,
|
|||
static void gimp_device_status_config_notify (GimpGuiConfig *config,
|
||||
const GParamSpec *pspec,
|
||||
GimpDeviceStatus *status);
|
||||
static void gimp_device_status_image_changed (GimpContext *user_context,
|
||||
GimpImage *image,
|
||||
GimpDeviceStatus *status);
|
||||
static void gimp_device_status_notify_info (GimpDeviceInfo *device_info,
|
||||
const GParamSpec *pspec,
|
||||
GimpDeviceStatusEntry *entry);
|
||||
|
@ -115,6 +119,10 @@ static void gimp_device_status_view_clicked (GtkWidget *widget,
|
|||
GdkModifierType state,
|
||||
const gchar *identifier);
|
||||
|
||||
static void
|
||||
gimp_device_status_set_color_help_data (GimpDeviceStatusEntry *entry,
|
||||
GimpContext *user_context);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpDeviceStatus, gimp_device_status, GIMP_TYPE_EDITOR)
|
||||
|
||||
|
@ -191,6 +199,10 @@ gimp_device_status_constructed (GObject *object)
|
|||
|
||||
gimp_device_status_config_notify (GIMP_GUI_CONFIG (status->gimp->config),
|
||||
NULL, status);
|
||||
|
||||
g_signal_connect_object (gimp_get_user_context (status->gimp), "image-changed",
|
||||
G_CALLBACK (gimp_device_status_image_changed),
|
||||
status, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -492,6 +504,21 @@ gimp_device_status_config_notify (GimpGuiConfig *config,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_device_status_image_changed (GimpContext *user_context,
|
||||
GimpImage *image,
|
||||
GimpDeviceStatus *status)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
for (list = status->devices; list; list = list->next)
|
||||
{
|
||||
GimpDeviceStatusEntry *entry = list->data;
|
||||
|
||||
gimp_device_status_set_color_help_data (entry, user_context);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_prop_visible (GtkWidget *widget,
|
||||
GtkWidget *widget_none,
|
||||
|
@ -550,22 +577,8 @@ gimp_device_status_notify_info (GimpDeviceInfo *device_info,
|
|||
}
|
||||
|
||||
if (! strcmp (pspec->name, "tool-options"))
|
||||
{
|
||||
GeglColor *color;
|
||||
guchar rgb[3];
|
||||
gchar buf[64];
|
||||
|
||||
color = gimp_context_get_foreground (entry->context);
|
||||
/* TODO: which space to use exactly to provide more useful info? */
|
||||
gegl_color_get_pixel (color, babl_format_with_space ("R'G'B' u8", NULL), rgb);
|
||||
g_snprintf (buf, sizeof (buf), _("Foreground: %d, %d, %d"), rgb[0], rgb[1], rgb[2]);
|
||||
gimp_help_set_help_data (entry->foreground, buf, NULL);
|
||||
|
||||
color = gimp_context_get_background (entry->context);
|
||||
gegl_color_get_pixel (color, babl_format_with_space ("R'G'B' u8", NULL), rgb);
|
||||
g_snprintf (buf, sizeof (buf), _("Background: %d, %d, %d"), rgb[0], rgb[1], rgb[2]);
|
||||
gimp_help_set_help_data (entry->background, buf, NULL);
|
||||
}
|
||||
gimp_device_status_set_color_help_data (entry,
|
||||
gimp_get_user_context (entry->context->gimp));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -593,3 +606,42 @@ gimp_device_status_view_clicked (GtkWidget *widget,
|
|||
gimp_widget_get_monitor (widget),
|
||||
identifier);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_device_status_set_color_help_data (GimpDeviceStatusEntry *entry,
|
||||
GimpContext *user_context)
|
||||
{
|
||||
const Babl *format;
|
||||
GimpImage *image = NULL;
|
||||
GeglColor *color;
|
||||
guchar rgb[4];
|
||||
gchar *buf;
|
||||
|
||||
/* Note: we don't set the GeglColor on purpose. Whatever is the specific
|
||||
* color space is too disconnected to this GUI usage and showing info in
|
||||
* this space would only be confusing.
|
||||
*/
|
||||
format = gimp_context_get_rgba_format (user_context, NULL, "u8", &image);
|
||||
|
||||
color = gimp_context_get_foreground (entry->context);
|
||||
gegl_color_get_pixel (color, format, rgb);
|
||||
if (image != NULL)
|
||||
buf = g_strdup_printf (_("Foreground: %d, %d, %d (in color space of \"%s\")"),
|
||||
rgb[0], rgb[1], rgb[2],
|
||||
gimp_image_get_display_name (image));
|
||||
else
|
||||
buf = g_strdup_printf (_("Foreground: %d, %d, %d (in sRGB)"), rgb[0], rgb[1], rgb[2]);
|
||||
gimp_help_set_help_data (entry->foreground, buf, NULL);
|
||||
g_free (buf);
|
||||
|
||||
color = gimp_context_get_background (entry->context);
|
||||
gegl_color_get_pixel (color, format, rgb);
|
||||
if (image != NULL)
|
||||
buf = g_strdup_printf (_("Background: %d, %d, %d (in color space of \"%s\")"),
|
||||
rgb[0], rgb[1], rgb[2],
|
||||
gimp_image_get_display_name (image));
|
||||
else
|
||||
buf = g_strdup_printf (_("Background: %d, %d, %d (in sRGB)"), rgb[0], rgb[1], rgb[2]);
|
||||
gimp_help_set_help_data (entry->background, buf, NULL);
|
||||
g_free (buf);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue