[gimp] app: Fuzzy Select tool multi-layer aware.



commit 6093399d7b9e0927d1443d43b0c45c58a84077b3
Author: Jehan <jehan girinstud io>
Date:   Sat Aug 1 19:56:07 2020 +0200

    app: Fuzzy Select tool multi-layer aware.
    
    When several layers are selected, and using the Fuzzy select tool
    without sample merged (with sample merged, nothing changes, it just uses
    the whole image), the selection will be based off a composited render of
    the image with only selected layers.
    
    This is equivalent to only making selected layers visible, running fuzzy
    select with sample merged, then making other layers visible again.

 app/tools/gimpfuzzyselecttool.c  | 45 ++++++++++++++++++++++++++++++----------
 app/tools/gimpregionselecttool.c | 25 +++++++++++++++-------
 2 files changed, 51 insertions(+), 19 deletions(-)
---
diff --git a/app/tools/gimpfuzzyselecttool.c b/app/tools/gimpfuzzyselecttool.c
index 785804a27b..d48d77fbb6 100644
--- a/app/tools/gimpfuzzyselecttool.c
+++ b/app/tools/gimpfuzzyselecttool.c
@@ -28,7 +28,10 @@
 
 #include "tools-types.h"
 
+#include "core/gimp.h"
+#include "core/gimpcontainer.h"
 #include "core/gimpimage.h"
+#include "core/gimpimage-new.h"
 #include "core/gimpitem.h"
 #include "core/gimppickable.h"
 #include "core/gimppickable-contiguous-region.h"
@@ -95,12 +98,14 @@ static GeglBuffer *
 gimp_fuzzy_select_tool_get_mask (GimpRegionSelectTool *region_select,
                                  GimpDisplay          *display)
 {
-  GimpTool                *tool        = GIMP_TOOL (region_select);
-  GimpSelectionOptions    *sel_options = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
-  GimpRegionSelectOptions *options     = GIMP_REGION_SELECT_TOOL_GET_OPTIONS (tool);
-  GimpImage               *image       = gimp_display_get_image (display);
-  GimpDrawable            *drawable    = gimp_image_get_active_drawable (image);
+  GimpTool                *tool         = GIMP_TOOL (region_select);
+  GimpSelectionOptions    *sel_options  = GIMP_SELECTION_TOOL_GET_OPTIONS (tool);
+  GimpRegionSelectOptions *options      = GIMP_REGION_SELECT_TOOL_GET_OPTIONS (tool);
+  GimpImage               *image        = gimp_display_get_image (display);
+  GimpImage               *select_image = NULL;
+  GList                   *drawables    = gimp_image_get_selected_drawables (image);
   GimpPickable            *pickable;
+  GeglBuffer              *mask;
   gint                     x, y;
 
   x = region_select->x;
@@ -108,25 +113,43 @@ gimp_fuzzy_select_tool_get_mask (GimpRegionSelectTool *region_select,
 
   if (! options->sample_merged)
     {
-      gint off_x, off_y;
+      if (g_list_length (drawables) == 1)
+        {
+          gint off_x, off_y;
 
-      gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
+          gimp_item_get_offset (drawables->data, &off_x, &off_y);
 
-      x -= off_x;
-      y -= off_y;
+          x -= off_x;
+          y -= off_y;
 
-      pickable = GIMP_PICKABLE (drawable);
+          pickable = GIMP_PICKABLE (drawables->data);
+        }
+      else
+        {
+          select_image = gimp_image_new_from_drawables (image->gimp, drawables, FALSE);
+          gimp_container_remove (image->gimp->images, GIMP_OBJECT (select_image));
+
+          pickable = GIMP_PICKABLE (select_image);
+          gimp_pickable_flush (pickable);
+        }
     }
   else
     {
       pickable = GIMP_PICKABLE (image);
     }
 
-  return gimp_pickable_contiguous_region_by_seed (pickable,
+  g_list_free (drawables);
+
+  mask = gimp_pickable_contiguous_region_by_seed (pickable,
                                                   sel_options->antialias,
                                                   options->threshold / 255.0,
                                                   options->select_transparent,
                                                   options->select_criterion,
                                                   options->diagonal_neighbors,
                                                   x, y);
+
+  if (select_image)
+    g_object_unref (select_image);
+
+  return mask;
 }
diff --git a/app/tools/gimpregionselecttool.c b/app/tools/gimpregionselecttool.c
index fe08533d5c..31278fc9ec 100644
--- a/app/tools/gimpregionselecttool.c
+++ b/app/tools/gimpregionselecttool.c
@@ -205,9 +205,12 @@ gimp_region_select_tool_button_release (GimpTool              *tool,
 
           if (! options->sample_merged)
             {
-              GimpDrawable *drawable = gimp_image_get_active_drawable (image);
+              GList *drawables = gimp_image_get_selected_drawables (image);
 
-              gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
+              if (g_list_length (drawables) == 1)
+                gimp_item_get_offset (drawables->data, &off_x, &off_y);
+
+              g_list_free (drawables);
             }
 
           gimp_channel_select_buffer (gimp_image_get_mask (image),
@@ -323,10 +326,13 @@ gimp_region_select_tool_draw (GimpDrawTool *draw_tool)
 
           if (! options->sample_merged)
             {
-              GimpImage    *image    = gimp_display_get_image (draw_tool->display);
-              GimpDrawable *drawable = gimp_image_get_active_drawable (image);
+              GimpImage *image     = gimp_display_get_image (draw_tool->display);
+              GList     *drawables = gimp_image_get_selected_drawables (image);
+
+              if (g_list_length (drawables) == 1)
+                gimp_item_get_offset (drawables->data, &off_x, &off_y);
 
-              gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
+              g_list_free (drawables);
             }
 
           gimp_draw_tool_add_boundary (draw_tool,
@@ -367,10 +373,13 @@ gimp_region_select_tool_get_mask (GimpRegionSelectTool *region_sel,
 
           if (! options->sample_merged)
             {
-              GimpImage    *image    = gimp_display_get_image (display);
-              GimpDrawable *drawable = gimp_image_get_active_drawable (image);
+              GimpImage *image     = gimp_display_get_image (display);
+              GList     *drawables = gimp_image_get_selected_drawables (image);
+
+              if (g_list_length (drawables) == 1)
+                gimp_item_get_offset (drawables->data, &off_x, &off_y);
 
-              gimp_item_get_offset (GIMP_ITEM (drawable), &off_x, &off_y);
+              g_list_free (drawables);
             }
 
           gimp_display_shell_set_mask (shell, region_sel->region_mask,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]