Commit 1217dc8d authored by Michael Natterer's avatar Michael Natterer 😴 Committed by Michael Natterer

Allow to initialize a new layer mask with any of the image's channels.

2006-05-14  Michael Natterer  <mitch@gimp.org>

	Allow to initialize a new layer mask with any of the image's
	channels. Fixes bug #310207.

	* libgimpbase/gimpbaseenums.h (enum GimpAddMaskType): added
	value GIMP_ADD_CHANNEL_MASK.

	* libgimpbase/gimpbaseenums.c
	* tools/pdbgen/enums.pl: regenerated.

	* app/core/gimplayer.[ch] (gimp_layer_create_mask): added
	GimpChannel* parameter. Hacked the GIMP_ADD_SELECTION_MASK code a
	bit so it can handle GIMP_ADD_CHANNEL_MASK too. Cleaned up the
	function a bit.

	* app/dialogs/layer-add-mask-dialog.[ch]: added a menu of the
	image's channels.

	* app/actions/layers-commands.c (layers_add_mask_response): pass
	the channel selected in the menu to gimp_layer_create_mask().

	* tools/pdbgen/pdb/layer.pdb (layer_create_mask): use the image's
	active channel when GIMP_ADD_CHANNEL_MASK is passed. Fail if there
	is no active channel.

	* app/pdb/layer_cmds.c: regenerated.
parent 0ee7569d
2006-05-14 Michael Natterer <mitch@gimp.org>
Allow to initialize a new layer mask with any of the image's
channels. Fixes bug #310207.
* libgimpbase/gimpbaseenums.h (enum GimpAddMaskType): added
value GIMP_ADD_CHANNEL_MASK.
* libgimpbase/gimpbaseenums.c
* tools/pdbgen/enums.pl: regenerated.
* app/core/gimplayer.[ch] (gimp_layer_create_mask): added
GimpChannel* parameter. Hacked the GIMP_ADD_SELECTION_MASK code a
bit so it can handle GIMP_ADD_CHANNEL_MASK too. Cleaned up the
function a bit.
* app/dialogs/layer-add-mask-dialog.[ch]: added a menu of the
image's channels.
* app/actions/layers-commands.c (layers_add_mask_response): pass
the channel selected in the menu to gimp_layer_create_mask().
* tools/pdbgen/pdb/layer.pdb (layer_create_mask): use the image's
active channel when GIMP_ADD_CHANNEL_MASK is passed. Fail if there
is no active channel.
* app/pdb/layer_cmds.c: regenerated.
2006-05-14 Michael Natterer <mitch@gimp.org>
* app/tools/gimptexttool.c (gimp_text_tool_set_layer): find a
......
......@@ -974,10 +974,17 @@ layers_add_mask_response (GtkWidget *widget,
{
if (response_id == GTK_RESPONSE_OK)
{
GimpLayer *layer = dialog->layer;
GimpLayer *layer = dialog->layer;
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
GimpLayerMask *mask;
if (dialog->add_mask_type == GIMP_ADD_CHANNEL_MASK &&
! dialog->channel)
{
g_message (_("Please select a channel first"));
return;
}
layer_add_mask_type = dialog->add_mask_type;
layer_mask_invert = dialog->invert;
......@@ -987,7 +994,8 @@ layers_add_mask_response (GtkWidget *widget,
if (! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
gimp_layer_add_alpha (layer);
mask = gimp_layer_create_mask (layer, layer_add_mask_type);
mask = gimp_layer_create_mask (layer, layer_add_mask_type,
dialog->channel);
if (layer_mask_invert)
gimp_channel_invert (GIMP_CHANNEL (mask), FALSE);
......
......@@ -1279,7 +1279,8 @@ gimp_layer_add_mask (GimpLayer *layer,
GimpLayerMask *
gimp_layer_create_mask (const GimpLayer *layer,
GimpAddMaskType add_mask_type)
GimpAddMaskType add_mask_type,
GimpChannel *channel)
{
GimpDrawable *drawable;
GimpItem *item;
......@@ -1291,10 +1292,12 @@ gimp_layer_create_mask (const GimpLayer *layer,
GimpRGB black = { 0.0, 0.0, 0.0, GIMP_OPACITY_OPAQUE };
g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
g_return_val_if_fail (add_mask_type != GIMP_ADD_CHANNEL_MASK ||
GIMP_IS_CHANNEL (channel), NULL);
drawable = GIMP_DRAWABLE (layer);
item = GIMP_ITEM (layer);
image = gimp_item_get_image (item);
image = gimp_item_get_image (item);
mask_name = g_strdup_printf (_("%s mask"),
gimp_object_get_name (GIMP_OBJECT (layer)));
......@@ -1320,7 +1323,7 @@ gimp_layer_create_mask (const GimpLayer *layer,
break;
}
pixel_region_init (&destPR, GIMP_DRAWABLE (mask)->tiles,
pixel_region_init (&destPR, gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)),
0, 0,
GIMP_ITEM (mask)->width,
GIMP_ITEM (mask)->height,
......@@ -1336,7 +1339,7 @@ gimp_layer_create_mask (const GimpLayer *layer,
case GIMP_ADD_ALPHA_TRANSFER_MASK:
if (gimp_drawable_has_alpha (drawable))
{
pixel_region_init (&srcPR, drawable->tiles,
pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
0, 0,
item->width, item->height,
FALSE);
......@@ -1349,14 +1352,14 @@ gimp_layer_create_mask (const GimpLayer *layer,
gint w, h;
guchar *alpha_ptr;
gimp_drawable_push_undo (GIMP_DRAWABLE (layer),
gimp_drawable_push_undo (drawable,
_("Transfer Alpha to Mask"),
0, 0,
item->width,
item->height,
NULL, FALSE);
pixel_region_init (&srcPR, drawable->tiles,
pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
0, 0,
item->width, item->height,
TRUE);
......@@ -1385,31 +1388,36 @@ gimp_layer_create_mask (const GimpLayer *layer,
break;
case GIMP_ADD_SELECTION_MASK:
case GIMP_ADD_CHANNEL_MASK:
{
GimpChannel *selection;
gboolean selection_empty;
gint copy_x, copy_y;
gint copy_width, copy_height;
gboolean channel_empty;
gint copy_x, copy_y;
gint copy_width, copy_height;
selection = gimp_image_get_mask (image);
selection_empty = gimp_channel_is_empty (selection);
if (add_mask_type == GIMP_ADD_SELECTION_MASK)
channel = GIMP_CHANNEL (gimp_image_get_mask (image));
channel_empty = gimp_channel_is_empty (channel);
gimp_rectangle_intersect (0, 0, image->width, image->height,
item->offset_x, item->offset_y,
item->width, item->height,
&copy_x, &copy_y, &copy_width, &copy_height);
if (copy_width < item->width || copy_height < item->height ||
selection_empty)
if (copy_width < item->width ||
copy_height < item->height ||
channel_empty)
gimp_channel_clear (GIMP_CHANNEL (mask), NULL, FALSE);
if ((copy_width || copy_height) && ! selection_empty)
if ((copy_width || copy_height) && ! channel_empty)
{
pixel_region_init (&srcPR, GIMP_DRAWABLE (selection)->tiles,
pixel_region_init (&srcPR,
gimp_drawable_get_tiles (GIMP_DRAWABLE (channel)),
copy_x, copy_y,
copy_width, copy_height,
FALSE);
pixel_region_init (&destPR, GIMP_DRAWABLE (mask)->tiles,
pixel_region_init (&destPR,
gimp_drawable_get_tiles (GIMP_DRAWABLE (mask)),
copy_x - item->offset_x, copy_y - item->offset_y,
copy_width, copy_height,
TRUE);
......@@ -1451,7 +1459,7 @@ gimp_layer_create_mask (const GimpLayer *layer,
}
else
{
pixel_region_init (&srcPR, drawable->tiles,
pixel_region_init (&srcPR, gimp_drawable_get_tiles (drawable),
0, 0,
item->width,
item->height,
......
......@@ -99,7 +99,8 @@ GimpLayer * gimp_layer_new_from_region (PixelRegion *region,
GimpLayerModeEffects mode);
GimpLayerMask * gimp_layer_create_mask (const GimpLayer *layer,
GimpAddMaskType mask_type);
GimpAddMaskType mask_type,
GimpChannel *channel);
GimpLayerMask * gimp_layer_add_mask (GimpLayer *layer,
GimpLayerMask *mask,
gboolean push_undo);
......
......@@ -24,16 +24,30 @@
#include "dialogs-types.h"
#include "core/gimpchannel.h"
#include "core/gimpcontainer.h"
#include "core/gimpimage.h"
#include "core/gimplayer.h"
#include "widgets/gimpcontainercombobox.h"
#include "widgets/gimpcontainerview.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpviewabledialog.h"
#include "widgets/gimpwidgets-utils.h"
#include "layer-add-mask-dialog.h"
#include "gimp-intl.h"
/* local function prototypes */
static gboolean layer_add_mask_dialog_channel_selected (GimpContainerView *view,
GimpViewable *viewable,
gpointer insert_data,
LayerAddMaskDialog *dialog);
/* public functions */
LayerAddMaskDialog *
......@@ -45,7 +59,9 @@ layer_add_mask_dialog_new (GimpLayer *layer,
LayerAddMaskDialog *dialog;
GtkWidget *vbox;
GtkWidget *frame;
GtkWidget *combo;
GtkWidget *button;
GimpChannel *channel;
g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
g_return_val_if_fail (GTK_IS_WIDGET (parent), NULL);
......@@ -97,6 +113,26 @@ layer_add_mask_dialog_new (GimpLayer *layer,
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
gtk_widget_show (frame);
combo = gimp_container_combo_box_new (GIMP_ITEM (layer)->image->channels,
NULL,
GIMP_VIEW_SIZE_SMALL, 1);
gimp_enum_radio_frame_add (GTK_FRAME (frame), combo, GIMP_ADD_CHANNEL_MASK);
gtk_widget_show (combo);
g_signal_connect (combo, "select-item",
G_CALLBACK (layer_add_mask_dialog_channel_selected),
dialog);
channel = gimp_image_get_active_channel (GIMP_ITEM (layer)->image);
if (! channel)
channel = GIMP_CHANNEL
(gimp_container_get_child_by_index (GIMP_ITEM (layer)->image->channels,
0));
gimp_container_view_select_item (GIMP_CONTAINER_VIEW (combo),
GIMP_VIEWABLE (channel));
button = gtk_check_button_new_with_mnemonic (_("In_vert mask"));
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), dialog->invert);
gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
......@@ -108,3 +144,17 @@ layer_add_mask_dialog_new (GimpLayer *layer,
return dialog;
}
/* private functions */
static gboolean
layer_add_mask_dialog_channel_selected (GimpContainerView *view,
GimpViewable *viewable,
gpointer insert_data,
LayerAddMaskDialog *dialog)
{
dialog->channel = GIMP_CHANNEL (viewable);
return TRUE;
}
......@@ -28,6 +28,7 @@ struct _LayerAddMaskDialog
GimpLayer *layer;
GimpAddMaskType add_mask_type;
GimpChannel *channel;
gboolean invert;
};
......
......@@ -355,10 +355,23 @@ layer_create_mask_invoker (GimpProcedure *procedure,
if (success)
{
mask = gimp_layer_create_mask (layer, (GimpAddMaskType) mask_type);
GimpChannel *channel = NULL;
if (! mask)
success = FALSE;
if (mask_type == GIMP_ADD_CHANNEL_MASK)
{
channel = gimp_image_get_active_channel (GIMP_ITEM (layer)->image);
if (! channel)
success = FALSE;
}
if (success)
{
mask = gimp_layer_create_mask (layer, mask_type, channel);
if (! mask)
success = FALSE;
}
}
return_vals = gimp_procedure_get_return_values (procedure, success);
......@@ -1172,7 +1185,7 @@ register_layer_procs (GimpPDB *pdb)
gimp_procedure_add_argument (procedure,
g_param_spec_enum ("mask-type",
"mask type",
"The type of mask: { GIMP_ADD_WHITE_MASK (0), GIMP_ADD_BLACK_MASK (1), GIMP_ADD_ALPHA_MASK (2), GIMP_ADD_ALPHA_TRANSFER_MASK (3), GIMP_ADD_SELECTION_MASK (4), GIMP_ADD_COPY_MASK (5) }",
"The type of mask: { GIMP_ADD_WHITE_MASK (0), GIMP_ADD_BLACK_MASK (1), GIMP_ADD_ALPHA_MASK (2), GIMP_ADD_ALPHA_TRANSFER_MASK (3), GIMP_ADD_SELECTION_MASK (4), GIMP_ADD_COPY_MASK (5), GIMP_ADD_CHANNEL_MASK (6) }",
GIMP_TYPE_ADD_MASK_TYPE,
GIMP_ADD_WHITE_MASK,
GIMP_PARAM_READWRITE));
......
......@@ -18,6 +18,7 @@ gimp_add_mask_type_get_type (void)
{ GIMP_ADD_ALPHA_TRANSFER_MASK, "GIMP_ADD_ALPHA_TRANSFER_MASK", "alpha-transfer-mask" },
{ GIMP_ADD_SELECTION_MASK, "GIMP_ADD_SELECTION_MASK", "selection-mask" },
{ GIMP_ADD_COPY_MASK, "GIMP_ADD_COPY_MASK", "copy-mask" },
{ GIMP_ADD_CHANNEL_MASK, "GIMP_ADD_CHANNEL_MASK", "channel-mask" },
{ 0, NULL, NULL }
};
......@@ -29,6 +30,7 @@ gimp_add_mask_type_get_type (void)
{ GIMP_ADD_ALPHA_TRANSFER_MASK, N_("_Transfer layer's alpha channel"), NULL },
{ GIMP_ADD_SELECTION_MASK, N_("_Selection"), NULL },
{ GIMP_ADD_COPY_MASK, N_("_Grayscale copy of layer"), NULL },
{ GIMP_ADD_CHANNEL_MASK, N_("C_hannel"), NULL },
{ 0, NULL, NULL }
};
......
......@@ -37,7 +37,8 @@ typedef enum
GIMP_ADD_ALPHA_MASK, /*< desc="Layer's _alpha channel" >*/
GIMP_ADD_ALPHA_TRANSFER_MASK, /*< desc="_Transfer layer's alpha channel" >*/
GIMP_ADD_SELECTION_MASK, /*< desc="_Selection" >*/
GIMP_ADD_COPY_MASK /*< desc="_Grayscale copy of layer" >*/
GIMP_ADD_COPY_MASK, /*< desc="_Grayscale copy of layer" >*/
GIMP_ADD_CHANNEL_MASK /*< desc="C_hannel" >*/
} GimpAddMaskType;
......
......@@ -135,10 +135,23 @@ HELP
%invoke = (
code => <<'CODE'
{
mask = gimp_layer_create_mask (layer, (GimpAddMaskType) mask_type);
GimpChannel *channel = NULL;
if (! mask)
success = FALSE;
if (mask_type == GIMP_ADD_CHANNEL_MASK)
{
channel = gimp_image_get_active_channel (GIMP_ITEM (layer)->image);
if (! channel)
success = FALSE;
}
if (success)
{
mask = gimp_layer_create_mask (layer, mask_type, channel);
if (! mask)
success = FALSE;
}
}
CODE
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment