Bug 679387 - Add "select pixels with this color" from colormap

Add gimp_gegl_index_to_mask() and gimp_channel_select_by_index() and
around it actions, callbacks and GUI in the colormap dialog.
This commit is contained in:
Michael Natterer 2015-08-26 01:06:34 +02:00
parent 3ca15939ff
commit 37a3d423e9
10 changed files with 206 additions and 14 deletions

View File

@ -25,6 +25,7 @@
#include "actions-types.h"
#include "core/gimpcontext.h"
#include "core/gimpdrawable.h"
#include "core/gimpimage.h"
#include "core/gimpimage-colormap.h"
@ -66,6 +67,32 @@ static const GimpEnumActionEntry colormap_add_color_actions[] =
GIMP_HELP_INDEXED_PALETTE_ADD }
};
static const GimpEnumActionEntry colormap_to_selection_actions[] =
{
{ "colormap-selection-replace", GIMP_STOCK_SELECTION_REPLACE,
NC_("colormap-action", "_Select this Color"), NULL,
NC_("colormap-action", "Select all pixels with this color"),
GIMP_CHANNEL_OP_REPLACE, FALSE,
GIMP_HELP_INDEXED_PALETTE_SELECTION_REPLACE },
{ "colormap-selection-add", GIMP_STOCK_SELECTION_ADD,
NC_("colormap-action", "_Add to Selection"), NULL,
NC_("colormap-action", "Add all pixels with this color to the current selection"),
GIMP_CHANNEL_OP_ADD, FALSE,
GIMP_HELP_INDEXED_PALETTE_SELECTION_ADD },
{ "colormap-selection-subtract", GIMP_STOCK_SELECTION_SUBTRACT,
NC_("colormap-action", "_Subtract from Selection"), NULL,
NC_("colormap-action", "Subtract all pixels with this color from the current selection"),
GIMP_CHANNEL_OP_SUBTRACT, FALSE,
GIMP_HELP_INDEXED_PALETTE_SELECTION_SUBTRACT },
{ "colormap-selection-intersect", GIMP_STOCK_SELECTION_INTERSECT,
NC_("colormap-action", "_Intersect with Selection"), NULL,
NC_("colormap-action", "Intersect all pixels with this color with the current selection"),
GIMP_CHANNEL_OP_INTERSECT, FALSE,
GIMP_HELP_INDEXED_PALETTE_SELECTION_INTERSECT }
};
void
colormap_actions_setup (GimpActionGroup *group)
@ -78,23 +105,36 @@ colormap_actions_setup (GimpActionGroup *group)
colormap_add_color_actions,
G_N_ELEMENTS (colormap_add_color_actions),
G_CALLBACK (colormap_add_color_cmd_callback));
gimp_action_group_add_enum_actions (group, "colormap-action",
colormap_to_selection_actions,
G_N_ELEMENTS (colormap_to_selection_actions),
G_CALLBACK (colormap_to_selection_cmd_callback));
}
void
colormap_actions_update (GimpActionGroup *group,
gpointer data)
{
GimpImage *image = action_data_get_image (data);
GimpContext *context = action_data_get_context (data);
gboolean indexed = FALSE;
gint num_colors = 0;
GimpImage *image = action_data_get_image (data);
GimpContext *context = action_data_get_context (data);
gboolean indexed = FALSE;
gboolean drawable_indexed = FALSE;
gint num_colors = 0;
GimpRGB fg;
GimpRGB bg;
if (image)
{
indexed = (gimp_image_get_base_type (image) == GIMP_INDEXED);
num_colors = gimp_image_get_colormap_size (image);
indexed = (gimp_image_get_base_type (image) == GIMP_INDEXED);
if (indexed)
{
GimpDrawable *drawable = gimp_image_get_active_drawable (image);
num_colors = gimp_image_get_colormap_size (image);
drawable_indexed = gimp_drawable_is_indexed (drawable);
}
}
if (context)
@ -109,15 +149,25 @@ colormap_actions_update (GimpActionGroup *group,
gimp_action_group_set_action_color (group, action, color, FALSE);
SET_SENSITIVE ("colormap-edit-color",
image && indexed && num_colors > 0);
indexed && num_colors > 0);
SET_SENSITIVE ("colormap-add-color-from-fg",
image && indexed && num_colors < 256);
indexed && num_colors < 256);
SET_SENSITIVE ("colormap-add-color-from-bg",
image && indexed && num_colors < 256);
indexed && num_colors < 256);
SET_COLOR ("colormap-add-color-from-fg", context ? &fg : NULL);
SET_COLOR ("colormap-add-color-from-bg", context ? &bg : NULL);
SET_SENSITIVE ("colormap-selection-replace",
drawable_indexed && num_colors > 0);
SET_SENSITIVE ("colormap-selection-add",
drawable_indexed && num_colors > 0);
SET_SENSITIVE ("colormap-selection-subtract",
drawable_indexed && num_colors > 0);
SET_SENSITIVE ("colormap-selection-intersect",
drawable_indexed && num_colors > 0);
#undef SET_SENSITIVE
#undef SET_COLOR
}

View File

@ -25,6 +25,7 @@
#include "actions-types.h"
#include "core/gimpchannel-select.h"
#include "core/gimpcontext.h"
#include "core/gimpimage.h"
#include "core/gimpimage-colormap.h"
@ -133,6 +134,27 @@ colormap_add_color_cmd_callback (GtkAction *action,
}
}
void
colormap_to_selection_cmd_callback (GtkAction *action,
gint value,
gpointer data)
{
GimpColormapEditor *editor;
GimpImage *image;
GimpChannelOps op;
return_if_no_image (image, data);
editor = GIMP_COLORMAP_EDITOR (data);
op = (GimpChannelOps) value;
gimp_channel_select_by_index (gimp_image_get_mask (image),
gimp_image_get_active_drawable (image),
editor->col_index,
op,
FALSE, 0.0, 0.0);
}
/* private functions */

View File

@ -19,11 +19,14 @@
#define __COLORMAP_COMMANDS_H__
void colormap_edit_color_cmd_callback (GtkAction *action,
gpointer data);
void colormap_add_color_cmd_callback (GtkAction *action,
gint value,
gpointer data);
void colormap_edit_color_cmd_callback (GtkAction *action,
gpointer data);
void colormap_add_color_cmd_callback (GtkAction *action,
gint value,
gpointer data);
void colormap_to_selection_cmd_callback (GtkAction *action,
gint value,
gpointer data);
#endif /* __COLORMAP_COMMANDS_H__ */

View File

@ -29,6 +29,7 @@
#include "core-types.h"
#include "gegl/gimp-gegl-apply-operation.h"
#include "gegl/gimp-gegl-loops.h"
#include "gegl/gimp-gegl-mask-combine.h"
#include "gimpchannel.h"
@ -579,3 +580,42 @@ gimp_channel_select_by_color (GimpChannel *channel,
feather_radius_y);
g_object_unref (add_on);
}
void
gimp_channel_select_by_index (GimpChannel *channel,
GimpDrawable *drawable,
gint index,
GimpChannelOps op,
gboolean feather,
gdouble feather_radius_x,
gdouble feather_radius_y)
{
GeglBuffer *add_on;
gint add_on_x = 0;
gint add_on_y = 0;
g_return_if_fail (GIMP_IS_CHANNEL (channel));
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (channel)));
g_return_if_fail (GIMP_IS_DRAWABLE (drawable));
g_return_if_fail (gimp_drawable_is_indexed (drawable));
add_on = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
gimp_item_get_width (GIMP_ITEM (drawable)),
gimp_item_get_height (GIMP_ITEM (drawable))),
babl_format ("Y float"));
gimp_gegl_index_to_mask (gimp_drawable_get_buffer (drawable), NULL,
gimp_drawable_get_format_without_alpha (drawable),
add_on, NULL,
index);
gimp_item_get_offset (GIMP_ITEM (drawable), &add_on_x, &add_on_y);
gimp_channel_select_buffer (channel, C_("undo-type", "Select by Indexed Color"),
add_on, add_on_x, add_on_y,
op,
feather,
feather_radius_x,
feather_radius_y);
g_object_unref (add_on);
}

View File

@ -147,6 +147,13 @@ void gimp_channel_select_by_color (GimpChannel *channel,
gboolean feather,
gdouble feather_radius_x,
gdouble feather_radius_y);
void gimp_channel_select_by_index (GimpChannel *channel,
GimpDrawable *drawable,
gint index,
GimpChannelOps op,
gboolean feather,
gdouble feather_radius_x,
gdouble feather_radius_y);
#endif /* __GIMP_CHANNEL_SELECT_H__ */

View File

@ -624,6 +624,43 @@ gimp_gegl_replace (GeglBuffer *top_buffer,
}
}
void
gimp_gegl_index_to_mask (GeglBuffer *indexed_buffer,
const GeglRectangle *indexed_rect,
const Babl *indexed_format,
GeglBuffer *mask_buffer,
const GeglRectangle *mask_rect,
gint index)
{
GeglBufferIterator *iter;
iter = gegl_buffer_iterator_new (indexed_buffer, indexed_rect, 0,
indexed_format,
GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
gegl_buffer_iterator_add (iter, mask_buffer, mask_rect, 0,
babl_format ("Y float"),
GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
while (gegl_buffer_iterator_next (iter))
{
const guchar *indexed = iter->data[0];
gfloat *mask = iter->data[1];
gint count = iter->length;
while (count--)
{
if (*indexed == index)
*mask = 1.0;
else
*mask = 0.0;
indexed++;
mask++;
}
}
}
static gboolean
gimp_color_profile_can_gegl_copy (GimpColorProfile *src_profile,
GimpColorProfile *dest_profile)

View File

@ -81,6 +81,13 @@ void gimp_gegl_replace (GeglBuffer *top_buffer,
gdouble opacity,
const gboolean *affect);
void gimp_gegl_index_to_mask (GeglBuffer *indexed_buffer,
const GeglRectangle *indexed_rect,
const Babl *indexed_format,
GeglBuffer *mask_buffer,
const GeglRectangle *mask_rect,
gint index);
void gimp_gegl_convert_color_profile (GeglBuffer *src_buffer,
const GeglRectangle *src_rect,
GimpColorProfile *src_profile,

View File

@ -222,9 +222,16 @@ static void
gimp_colormap_editor_constructed (GObject *object)
{
GimpColormapEditor *editor = GIMP_COLORMAP_EDITOR (object);
GdkModifierType extend_mask;
GdkModifierType modify_mask;
G_OBJECT_CLASS (parent_class)->constructed (object);
extend_mask = gtk_widget_get_modifier_mask (GTK_WIDGET (object),
GDK_MODIFIER_INTENT_EXTEND_SELECTION);
modify_mask = gtk_widget_get_modifier_mask (GTK_WIDGET (object),
GDK_MODIFIER_INTENT_MODIFY_SELECTION);
gimp_editor_add_action_button (GIMP_EDITOR (editor), "colormap",
"colormap-edit-color",
NULL);
@ -234,6 +241,16 @@ gimp_colormap_editor_constructed (GObject *object)
"colormap-add-color-from-bg",
gimp_get_toggle_behavior_mask (),
NULL);
gimp_editor_add_action_button (GIMP_EDITOR (editor), "colormap",
"colormap-selection-replace",
"colormap-selection-add",
extend_mask,
"colormap-selection-subtract",
modify_mask,
"colormap-selection-intersect",
extend_mask | modify_mask,
NULL);
}
static void

View File

@ -504,6 +504,10 @@
#define GIMP_HELP_INDEXED_PALETTE_DIALOG "gimp-indexed-palette-dialog"
#define GIMP_HELP_INDEXED_PALETTE_EDIT "gimp-indexed-palette-edit"
#define GIMP_HELP_INDEXED_PALETTE_ADD "gimp-indexed-palette-add"
#define GIMP_HELP_INDEXED_PALETTE_SELECTION_REPLACE "gimp-indexed-palette-selection-replace"
#define GIMP_HELP_INDEXED_PALETTE_SELECTION_ADD "gimp-indexed-palette-selection-add"
#define GIMP_HELP_INDEXED_PALETTE_SELECTION_SUBTRACT "gimp-indexed-palette-selection-subtract"
#define GIMP_HELP_INDEXED_PALETTE_SELECTION_INTERSECT "gimp-indexed-palette-selection-intersect"
#define GIMP_HELP_POINTER_INFO_DIALOG "gimp-pointer-info-dialog"
#define GIMP_HELP_POINTER_INFO_SAMPLE_MERGED "gimp-pointer-info-sample-merged"

View File

@ -7,5 +7,10 @@
<menuitem action="colormap-add-color-from-fg" />
<menuitem action="colormap-add-color-from-bg" />
<separator />
<menuitem action="colormap-selection-replace" />
<menuitem action="colormap-selection-add" />
<menuitem action="colormap-selection-subtract" />
<menuitem action="colormap-selection-intersect" />
<separator />
</popup>
</ui>