mirror of https://github.com/GNOME/gimp.git
app: quick on-canvas copy-paste multi-layer aware.
This commit is contained in:
parent
bb7f94ce3b
commit
a7c59277fb
|
@ -35,6 +35,7 @@
|
|||
#include "gimpdrawable-private.h"
|
||||
#include "gimperror.h"
|
||||
#include "gimpimage.h"
|
||||
#include "gimpimage-new.h"
|
||||
#include "gimpimage-undo.h"
|
||||
#include "gimpimage-undo-push.h"
|
||||
#include "gimplayer.h"
|
||||
|
@ -808,7 +809,7 @@ gimp_selection_extract (GimpSelection *selection,
|
|||
|
||||
GimpLayer *
|
||||
gimp_selection_float (GimpSelection *selection,
|
||||
GimpDrawable *drawable,
|
||||
GList *drawables,
|
||||
GimpContext *context,
|
||||
gboolean cut_image,
|
||||
gint off_x,
|
||||
|
@ -817,22 +818,41 @@ gimp_selection_float (GimpSelection *selection,
|
|||
{
|
||||
GimpImage *image;
|
||||
GimpLayer *layer;
|
||||
GimpPickable *pickable;
|
||||
GeglBuffer *buffer;
|
||||
GimpColorProfile *profile;
|
||||
GimpImage *temp_image = NULL;
|
||||
const Babl *format = NULL;
|
||||
GList *iter;
|
||||
gint x1, y1;
|
||||
gint x2, y2;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_SELECTION (selection), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE (drawable), NULL);
|
||||
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
for (iter = drawables; iter; iter = iter->next)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_DRAWABLE (iter->data), NULL);
|
||||
g_return_val_if_fail (gimp_item_is_attached (iter->data), NULL);
|
||||
|
||||
if (! format)
|
||||
format = gimp_drawable_get_format_with_alpha (iter->data);
|
||||
else
|
||||
g_return_val_if_fail (format == gimp_drawable_get_format_with_alpha (iter->data),
|
||||
NULL);
|
||||
}
|
||||
|
||||
image = gimp_item_get_image (GIMP_ITEM (selection));
|
||||
|
||||
/* Make sure there is a region to float... */
|
||||
if (! gimp_item_mask_bounds (GIMP_ITEM (drawable), &x1, &y1, &x2, &y2) ||
|
||||
(x1 == x2 || y1 == y2))
|
||||
for (iter = drawables; iter; iter = iter->next)
|
||||
{
|
||||
if (gimp_item_mask_bounds (iter->data, &x1, &y1, &x2, &y2) &&
|
||||
x1 != x2 && y1 != y2)
|
||||
break;
|
||||
}
|
||||
if (iter == NULL)
|
||||
{
|
||||
g_set_error_literal (error, GIMP_ERROR, GIMP_FAILED,
|
||||
_("Cannot float selection because the selected "
|
||||
|
@ -844,22 +864,31 @@ gimp_selection_float (GimpSelection *selection,
|
|||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_FS_FLOAT,
|
||||
C_("undo-type", "Float Selection"));
|
||||
|
||||
if (g_list_length (drawables) > 1)
|
||||
{
|
||||
temp_image = gimp_image_new_from_drawables (image->gimp, drawables, TRUE);
|
||||
pickable = GIMP_PICKABLE (temp_image);
|
||||
}
|
||||
else
|
||||
{
|
||||
pickable = GIMP_PICKABLE (drawables->data);
|
||||
}
|
||||
|
||||
/* Cut or copy the selected region */
|
||||
buffer = gimp_selection_extract (selection, GIMP_PICKABLE (drawable), context,
|
||||
buffer = gimp_selection_extract (selection, pickable, context,
|
||||
cut_image, FALSE, TRUE,
|
||||
&x1, &y1, NULL);
|
||||
|
||||
profile = gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (drawable));
|
||||
profile = gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (pickable));
|
||||
|
||||
/* Clear the selection */
|
||||
gimp_channel_clear (GIMP_CHANNEL (selection), NULL, TRUE);
|
||||
|
||||
/* Create a new layer from the buffer, using the drawable's type
|
||||
/* Create a new layer from the buffer, using the drawables' type
|
||||
* because it may be different from the image's type if we cut from
|
||||
* a channel or layer mask
|
||||
*/
|
||||
layer = gimp_layer_new_from_gegl_buffer (buffer, image,
|
||||
gimp_drawable_get_format_with_alpha (drawable),
|
||||
layer = gimp_layer_new_from_gegl_buffer (buffer, image, format,
|
||||
_("Floated Layer"),
|
||||
GIMP_OPACITY_OPAQUE,
|
||||
gimp_image_get_default_new_layer_mode (image),
|
||||
|
@ -872,7 +901,7 @@ gimp_selection_float (GimpSelection *selection,
|
|||
g_object_unref (buffer);
|
||||
|
||||
/* Add the floating layer to the image */
|
||||
floating_sel_attach (layer, drawable);
|
||||
floating_sel_attach (layer, drawables->data);
|
||||
|
||||
/* End an undo group */
|
||||
gimp_image_undo_group_end (image);
|
||||
|
@ -880,5 +909,8 @@ gimp_selection_float (GimpSelection *selection,
|
|||
/* invalidate the image's boundary variables */
|
||||
GIMP_CHANNEL (selection)->boundary_known = FALSE;
|
||||
|
||||
if (temp_image)
|
||||
g_object_unref (temp_image);
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ GeglBuffer * gimp_selection_extract (GimpSelection *selection,
|
|||
GError **error);
|
||||
|
||||
GimpLayer * gimp_selection_float (GimpSelection *selection,
|
||||
GimpDrawable *drawable,
|
||||
GList *drawables,
|
||||
GimpContext *context,
|
||||
gboolean cut_image,
|
||||
gint off_x,
|
||||
|
|
|
@ -595,7 +595,7 @@ gimp_edit_selection_tool_update_motion (GimpEditSelectionTool *edit_select,
|
|||
case GIMP_TRANSLATE_MODE_MASK_TO_LAYER:
|
||||
case GIMP_TRANSLATE_MODE_MASK_COPY_TO_LAYER:
|
||||
if (! gimp_selection_float (GIMP_SELECTION (gimp_image_get_mask (image)),
|
||||
GIMP_DRAWABLE (selected_items->data),
|
||||
selected_items,
|
||||
gimp_get_user_context (display->gimp),
|
||||
edit_select->edit_mode ==
|
||||
GIMP_TRANSLATE_MODE_MASK_TO_LAYER,
|
||||
|
|
|
@ -225,7 +225,7 @@ gimp_selection_tool_oper_update (GimpTool *tool,
|
|||
GimpSelectionTool *selection_tool = GIMP_SELECTION_TOOL (tool);
|
||||
GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
|
||||
GimpImage *image;
|
||||
GimpDrawable *drawable;
|
||||
GList *drawables;
|
||||
GimpLayer *layer;
|
||||
GimpLayer *floating_sel;
|
||||
GdkModifierType extend_mask;
|
||||
|
@ -235,7 +235,7 @@ gimp_selection_tool_oper_update (GimpTool *tool,
|
|||
gboolean move_floating_sel = FALSE;
|
||||
|
||||
image = gimp_display_get_image (display);
|
||||
drawable = gimp_image_get_active_drawable (image);
|
||||
drawables = gimp_image_get_selected_drawables (image);
|
||||
layer = gimp_image_pick_layer (image, coords->x, coords->y, NULL);
|
||||
floating_sel = gimp_image_get_floating_selection (image);
|
||||
|
||||
|
@ -244,19 +244,29 @@ gimp_selection_tool_oper_update (GimpTool *tool,
|
|||
|
||||
have_selection = gimp_selection_tool_have_selection (selection_tool, display);
|
||||
|
||||
if (drawable)
|
||||
if (drawables)
|
||||
{
|
||||
if (floating_sel)
|
||||
{
|
||||
if (layer == floating_sel)
|
||||
move_floating_sel = TRUE;
|
||||
}
|
||||
else if (have_selection &&
|
||||
gimp_item_mask_intersect (GIMP_ITEM (drawable),
|
||||
NULL, NULL, NULL, NULL))
|
||||
else if (have_selection)
|
||||
{
|
||||
move_layer = TRUE;
|
||||
GList *iter;
|
||||
|
||||
for (iter = drawables; iter; iter = iter->next)
|
||||
{
|
||||
if (gimp_item_mask_intersect (GIMP_ITEM (iter->data),
|
||||
NULL, NULL, NULL, NULL))
|
||||
{
|
||||
move_layer = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (drawables);
|
||||
}
|
||||
|
||||
selection_tool->function = SELECTION_SELECT;
|
||||
|
@ -509,9 +519,8 @@ gimp_selection_tool_check (GimpSelectionTool *sel_tool,
|
|||
GimpDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (sel_tool);
|
||||
GimpImage *image = gimp_display_get_image (display);
|
||||
GimpDrawable *drawable = gimp_image_get_active_drawable (image);
|
||||
GimpSelectionOptions *options = GIMP_SELECTION_TOOL_GET_OPTIONS (sel_tool);
|
||||
GimpImage *image = gimp_display_get_image (display);
|
||||
|
||||
switch (sel_tool->function)
|
||||
{
|
||||
|
@ -548,22 +557,34 @@ gimp_selection_tool_check (GimpSelectionTool *sel_tool,
|
|||
|
||||
case SELECTION_MOVE:
|
||||
case SELECTION_MOVE_COPY:
|
||||
if (gimp_viewable_get_children (GIMP_VIEWABLE (drawable)))
|
||||
{
|
||||
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
|
||||
_("Cannot modify the pixels of layer groups."));
|
||||
GList *drawables = gimp_image_get_selected_drawables (image);
|
||||
GList *iter;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else if (gimp_item_is_content_locked (GIMP_ITEM (drawable)))
|
||||
{
|
||||
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
|
||||
_("The active layer's pixels are locked."));
|
||||
for (iter = drawables; iter; iter = iter->next)
|
||||
{
|
||||
if (gimp_viewable_get_children (iter->data))
|
||||
{
|
||||
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
|
||||
_("Cannot modify the pixels of layer groups."));
|
||||
|
||||
if (error)
|
||||
gimp_tools_blink_lock_box (display->gimp, GIMP_ITEM (drawable));
|
||||
g_list_free (drawables);
|
||||
return FALSE;
|
||||
}
|
||||
else if (gimp_item_is_content_locked (iter->data))
|
||||
{
|
||||
g_set_error (error, GIMP_ERROR, GIMP_FAILED,
|
||||
_("The active layer's pixels are locked."));
|
||||
|
||||
return FALSE;
|
||||
if (error)
|
||||
gimp_tools_blink_lock_box (display->gimp, iter->data);
|
||||
|
||||
g_list_free (drawables);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free (drawables);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue