[gimp/gimp-2-10] app: alt-click to pick a layer will loop through candidate layers.



commit e0be9bdef2e312a52443d0a6a56355045c2934c4
Author: Jehan <jehan girinstud io>
Date:   Sat Dec 15 23:34:07 2018 +0100

    app: alt-click to pick a layer will loop through candidate layers.
    
    If you click on a zone filled in several visible layers, you don't
    necessarily want the top layer. You may want one below. With this
    change, as long as you hold alt, you will loop through all candidate
    layers from top to bottom (then looping back top when reaching the
    bottom).
    In a first alt-click, you will always end up to the top candidate.
    
    (cherry picked from commit 90e9eb3fcaaaf1b5482c88605532aa719635504b)

 app/core/gimpimage-pick-item.c | 46 +++++++++++++++++++++++++++++++++---------
 app/core/gimpimage-pick-item.h |  3 ++-
 app/pdb/image-cmds.c           |  2 +-
 app/tools/gimpmovetool.c       |  6 ++++--
 app/tools/gimppainttool.c      | 18 +++++++++++++----
 app/tools/gimppainttool.h      |  1 +
 app/tools/gimpselectiontool.c  |  2 +-
 pdb/groups/image.pdb           |  2 +-
 8 files changed, 60 insertions(+), 20 deletions(-)
---
diff --git a/app/core/gimpimage-pick-item.c b/app/core/gimpimage-pick-item.c
index db196bcdd9..bdfa75bc89 100644
--- a/app/core/gimpimage-pick-item.c
+++ b/app/core/gimpimage-pick-item.c
@@ -41,29 +41,55 @@
 GimpLayer *
 gimp_image_pick_layer (GimpImage *image,
                        gint       x,
-                       gint       y)
+                       gint       y,
+                       GimpLayer *previously_picked)
 {
   GList *all_layers;
   GList *list;
+  gint   off_x, off_y;
+  gint   tries = 1;
 
   g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
 
   all_layers = gimp_image_get_layer_list (image);
 
-  for (list = all_layers; list; list = g_list_next (list))
+  if (previously_picked)
     {
-      GimpLayer *layer = list->data;
-      gint       off_x, off_y;
-
-      gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y);
+      gimp_item_get_offset (GIMP_ITEM (previously_picked), &off_x, &off_y);
+      if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (previously_picked),
+                                        x - off_x, y - off_y) <= 0.25)
+        previously_picked = NULL;
+      else
+        tries++;
+    }
 
-      if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (layer),
-                                        x - off_x, y - off_y) > 0.25)
+  while (tries)
+    {
+      for (list = all_layers; list; list = g_list_next (list))
         {
-          g_list_free (all_layers);
+          GimpLayer *layer = list->data;
+
+          if (previously_picked)
+            {
+              /* Take the first layer with a pixel at given coordinates
+               * after the previously picked one.
+               */
+              if (layer == previously_picked)
+                previously_picked = NULL;
+              continue;
+            }
 
-          return layer;
+          gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y);
+
+          if (gimp_pickable_get_opacity_at (GIMP_PICKABLE (layer),
+                                            x - off_x, y - off_y) > 0.25)
+            {
+              g_list_free (all_layers);
+
+              return layer;
+            }
         }
+      tries--;
     }
 
   g_list_free (all_layers);
diff --git a/app/core/gimpimage-pick-item.h b/app/core/gimpimage-pick-item.h
index e0c62bf488..bf0d322a84 100644
--- a/app/core/gimpimage-pick-item.h
+++ b/app/core/gimpimage-pick-item.h
@@ -21,7 +21,8 @@
 
 GimpLayer       * gimp_image_pick_layer           (GimpImage *image,
                                                    gint       x,
-                                                   gint       y);
+                                                   gint       y,
+                                                   GimpLayer *previously_picked);
 GimpLayer       * gimp_image_pick_layer_by_bounds (GimpImage *image,
                                                    gint       x,
                                                    gint       y);
diff --git a/app/pdb/image-cmds.c b/app/pdb/image-cmds.c
index 24a67bcae7..6a79e1fa1c 100644
--- a/app/pdb/image-cmds.c
+++ b/app/pdb/image-cmds.c
@@ -776,7 +776,7 @@ image_pick_correlate_layer_invoker (GimpProcedure         *procedure,
 
   if (success)
     {
-      layer = gimp_image_pick_layer (image, x, y);
+      layer = gimp_image_pick_layer (image, x, y, NULL);
     }
 
   return_vals = gimp_procedure_get_return_values (procedure, success,
diff --git a/app/tools/gimpmovetool.c b/app/tools/gimpmovetool.c
index afd2666c8b..2d881f5367 100644
--- a/app/tools/gimpmovetool.c
+++ b/app/tools/gimpmovetool.c
@@ -219,7 +219,8 @@ gimp_move_tool_button_press (GimpTool            *tool,
             }
           else if ((layer = gimp_image_pick_layer (image,
                                                    coords->x,
-                                                   coords->y)))
+                                                   coords->y,
+                                                   NULL)))
             {
               if (gimp_image_get_floating_selection (image) &&
                   ! gimp_layer_is_floating_sel (layer))
@@ -582,7 +583,8 @@ gimp_move_tool_cursor_update (GimpTool         *tool,
           modifier    = GIMP_CURSOR_MODIFIER_MOVE;
         }
       else if ((layer = gimp_image_pick_layer (image,
-                                               coords->x, coords->y)))
+                                               coords->x, coords->y,
+                                               NULL)))
         {
           /*  if there is a floating selection, and this aint it...  */
           if (gimp_image_get_floating_selection (image) &&
diff --git a/app/tools/gimppainttool.c b/app/tools/gimppainttool.c
index c208e3ae98..968cc0c90c 100644
--- a/app/tools/gimppainttool.c
+++ b/app/tools/gimppainttool.c
@@ -273,9 +273,17 @@ gimp_paint_tool_button_press (GimpTool            *tool,
 
       layer = gimp_image_pick_layer (image,
                                      (gint) coords->x,
-                                     (gint) coords->y);
-      if (layer && layer != gimp_image_get_active_layer (image))
-        gimp_image_set_active_layer (image, layer);
+                                     (gint) coords->y,
+                                     paint_tool->picked_layer);
+      if (layer)
+        {
+          if (layer != gimp_image_get_active_layer (image))
+            {
+              paint_tool->picked_layer = layer;
+              gimp_image_set_active_layer (image, layer);
+            }
+          paint_tool->picked_layer = layer;
+        }
       return;
     }
   else if (gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (tool)))
@@ -478,6 +486,7 @@ gimp_paint_tool_modifier_key (GimpTool        *tool,
   if (! gimp_color_tool_is_enabled (GIMP_COLOR_TOOL (tool)) &&
       ! paint_tool->draw_line)
     {
+      paint_tool->picked_layer  = NULL;
       if ((state & gimp_get_all_modifiers_mask ()) == GDK_MOD1_MASK)
         paint_tool->picking_layer = TRUE;
       else
@@ -514,7 +523,8 @@ gimp_paint_tool_cursor_update (GimpTool         *tool,
 
       layer = gimp_image_pick_layer (image,
                                      (gint) coords->x,
-                                     (gint) coords->y);
+                                     (gint) coords->y,
+                                     paint_tool->picked_layer);
 
       modifier = GIMP_CURSOR_MODIFIER_NONE;
       if (gimp_image_get_floating_selection (image))
diff --git a/app/tools/gimppainttool.h b/app/tools/gimppainttool.h
index 690dc3ee61..f927807009 100644
--- a/app/tools/gimppainttool.h
+++ b/app/tools/gimppainttool.h
@@ -45,6 +45,7 @@ struct _GimpPaintTool
   gboolean       draw_line;
 
   gboolean       picking_layer; /*  pick layer in progress (alt pressed)  */
+  GimpLayer     *picked_layer;
 
   gboolean       show_cursor;
   gboolean       draw_brush;
diff --git a/app/tools/gimpselectiontool.c b/app/tools/gimpselectiontool.c
index 96396091bd..8661eb2bcd 100644
--- a/app/tools/gimpselectiontool.c
+++ b/app/tools/gimpselectiontool.c
@@ -180,7 +180,7 @@ gimp_selection_tool_oper_update (GimpTool         *tool,
   image        = gimp_display_get_image (display);
   selection    = gimp_image_get_mask (image);
   drawable     = gimp_image_get_active_drawable (image);
-  layer        = gimp_image_pick_layer (image, coords->x, coords->y);
+  layer        = gimp_image_pick_layer (image, coords->x, coords->y, NULL);
   floating_sel = gimp_image_get_floating_selection (image);
 
   extend_mask = gimp_get_extend_selection_mask ();
diff --git a/pdb/groups/image.pdb b/pdb/groups/image.pdb
index 66ce0b496f..8f6c301f4e 100644
--- a/pdb/groups/image.pdb
+++ b/pdb/groups/image.pdb
@@ -522,7 +522,7 @@ HELP
         headers => [ qw("core/gimpimage-pick-item.h") ],
         code => <<'CODE'
 {
-  layer = gimp_image_pick_layer (image, x, y);
+  layer = gimp_image_pick_layer (image, x, y, NULL);
 }
 CODE
     );


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