From 80b74ce9e937da516b654a08080e4befcb8cf96e Mon Sep 17 00:00:00 2001 From: Jehan Date: Mon, 4 May 2020 17:11:14 +0200 Subject: [PATCH] app: raise-layers* and lower-layers* actions multi-selection aware. --- app/actions/layers-actions.c | 45 ++++++++----- app/actions/layers-commands.c | 115 ++++++++++++++++++++++++++++++---- 2 files changed, 134 insertions(+), 26 deletions(-) diff --git a/app/actions/layers-actions.c b/app/actions/layers-actions.c index 9eaf535bc8..3e917bc97f 100644 --- a/app/actions/layers-actions.c +++ b/app/actions/layers-actions.c @@ -789,11 +789,13 @@ layers_actions_update (GimpActionGroup *group, gboolean last_mode = FALSE; gboolean first_mode = FALSE; - gboolean have_masks = FALSE; /* At least 1 selected layer has a mask. */ - gboolean have_no_masks = FALSE; /* At least 1 selected layer has no mask. */ - gboolean have_groups = FALSE; /* At least 1 selected layer is a group. */ - gboolean have_no_groups = FALSE; /* At least 1 selected layer is not a group. */ - gboolean have_writable = FALSE; /* At least 1 selected layer has no contents lock. */ + gboolean have_masks = FALSE; /* At least 1 selected layer has a mask. */ + gboolean have_no_masks = FALSE; /* At least 1 selected layer has no mask. */ + gboolean have_groups = FALSE; /* At least 1 selected layer is a group. */ + gboolean have_no_groups = FALSE; /* At least 1 selected layer is not a group. */ + gboolean have_writable = FALSE; /* At least 1 selected layer has no contents lock. */ + gboolean have_prev = FALSE; /* At least 1 selected layer has a previous sibling. */ + gboolean have_next = FALSE; /* At least 1 selected layer has a next sibling. */ gboolean all_masks_shown = TRUE; gboolean all_masks_disabled = TRUE; @@ -814,6 +816,8 @@ layers_actions_update (GimpActionGroup *group, { GimpLayerMode *modes; GimpLayerMode mode; + GList *layer_list; + GList *iter2; gint n_modes; gint i = 0; @@ -865,12 +869,25 @@ layers_actions_update (GimpActionGroup *group, else first_mode = TRUE; - if (have_masks && have_no_masks && - have_groups && have_no_groups && + layer_list = gimp_item_get_container_iter (GIMP_ITEM (iter->data)); + iter2 = g_list_find (layer_list, iter->data); + + if (iter2) + { + if (g_list_previous (iter2)) + have_prev = TRUE; + + if (g_list_next (iter2)) + have_next = TRUE; + } + + if (have_masks && have_no_masks && + have_groups && have_no_groups && have_writable && ! all_masks_shown && - ! all_masks_disabled && - ! lock_alpha && can_lock_alpha && - ! prev_mode && ! next_mode) + ! all_masks_disabled && + ! lock_alpha && can_lock_alpha && + ! prev_mode && ! next_mode && + have_prev && have_next) break; } @@ -1016,10 +1033,10 @@ layers_actions_update (GimpActionGroup *group, SET_SENSITIVE ("layers-select-previous", layer && !fs && !ac && prev); SET_SENSITIVE ("layers-select-next", layer && !fs && !ac && next); - SET_SENSITIVE ("layers-raise", layer && !fs && !ac && prev); - SET_SENSITIVE ("layers-raise-to-top", layer && !fs && !ac && prev); - SET_SENSITIVE ("layers-lower", layer && !fs && !ac && next); - SET_SENSITIVE ("layers-lower-to-bottom", layer && !fs && !ac && next); + SET_SENSITIVE ("layers-raise", n_layers > 0 && !fs && !ac && have_prev); + SET_SENSITIVE ("layers-raise-to-top", n_layers > 0 && !fs && !ac && have_prev); + SET_SENSITIVE ("layers-lower", n_layers > 0 && !fs && !ac && have_next); + SET_SENSITIVE ("layers-lower-to-bottom", n_layers > 0 && !fs && !ac && have_next); SET_VISIBLE ("layers-anchor", layer && fs && !ac); SET_VISIBLE ("layers-merge-down", !fs); diff --git a/app/actions/layers-commands.c b/app/actions/layers-commands.c index 0bd8e3943f..34801f91a0 100644 --- a/app/actions/layers-commands.c +++ b/app/actions/layers-commands.c @@ -609,11 +609,32 @@ layers_raise_cmd_callback (GimpAction *action, gpointer data) { GimpImage *image; - GimpLayer *layer; - return_if_no_layer (image, layer, data); + GList *layers; + GList *iter; + GList *raised_layers = NULL; + return_if_no_layers (image, layers, data); + + for (iter = layers; iter; iter = iter->next) + { + gint index; + + index = gimp_item_get_index (iter->data); + if (index > 0) + raised_layers = g_list_prepend (raised_layers, iter->data); + } + + gimp_image_undo_group_start (image, + GIMP_UNDO_GROUP_ITEM_DISPLACE, + ngettext ("Raise Layer", + "Raise Layers", + g_list_length (raised_layers))); + for (iter = raised_layers; iter; iter = iter->next) + gimp_image_raise_item (image, iter->data, NULL); - gimp_image_raise_item (image, GIMP_ITEM (layer), NULL); gimp_image_flush (image); + gimp_image_undo_group_end (image); + + g_list_free (raised_layers); } void @@ -622,11 +643,33 @@ layers_raise_to_top_cmd_callback (GimpAction *action, gpointer data) { GimpImage *image; - GimpLayer *layer; - return_if_no_layer (image, layer, data); + GList *layers; + GList *iter; + GList *raised_layers = NULL; + return_if_no_layers (image, layers, data); + + for (iter = layers; iter; iter = iter->next) + { + gint index; + + index = gimp_item_get_index (iter->data); + if (index > 0) + raised_layers = g_list_prepend (raised_layers, iter->data); + } + + gimp_image_undo_group_start (image, + GIMP_UNDO_GROUP_ITEM_DISPLACE, + ngettext ("Raise Layer to Top", + "Raise Layers to Top", + g_list_length (raised_layers))); + + for (iter = raised_layers; iter; iter = iter->next) + gimp_image_raise_item_to_top (image, iter->data); - gimp_image_raise_item_to_top (image, GIMP_ITEM (layer)); gimp_image_flush (image); + gimp_image_undo_group_end (image); + + g_list_free (raised_layers); } void @@ -635,11 +678,35 @@ layers_lower_cmd_callback (GimpAction *action, gpointer data) { GimpImage *image; - GimpLayer *layer; - return_if_no_layer (image, layer, data); + GList *layers; + GList *iter; + GList *lowered_layers = NULL; + return_if_no_layers (image, layers, data); + + for (iter = layers; iter; iter = iter->next) + { + GList *layer_list; + gint index; + + layer_list = gimp_item_get_container_iter (GIMP_ITEM (iter->data)); + index = gimp_item_get_index (iter->data); + if (index < g_list_length (layer_list) - 1) + lowered_layers = g_list_prepend (lowered_layers, iter->data); + } + + gimp_image_undo_group_start (image, + GIMP_UNDO_GROUP_ITEM_DISPLACE, + ngettext ("Lower Layer", + "Lower Layers", + g_list_length (lowered_layers))); + + for (iter = lowered_layers; iter; iter = iter->next) + gimp_image_lower_item (image, iter->data, NULL); - gimp_image_lower_item (image, GIMP_ITEM (layer), NULL); gimp_image_flush (image); + gimp_image_undo_group_end (image); + + g_list_free (lowered_layers); } void @@ -648,11 +715,35 @@ layers_lower_to_bottom_cmd_callback (GimpAction *action, gpointer data) { GimpImage *image; - GimpLayer *layer; - return_if_no_layer (image, layer, data); + GList *layers; + GList *iter; + GList *lowered_layers = NULL; + return_if_no_layers (image, layers, data); + + for (iter = layers; iter; iter = iter->next) + { + GList *layer_list; + gint index; + + layer_list = gimp_item_get_container_iter (GIMP_ITEM (iter->data)); + index = gimp_item_get_index (iter->data); + if (index < g_list_length (layer_list) - 1) + lowered_layers = g_list_prepend (lowered_layers, iter->data); + } + + gimp_image_undo_group_start (image, + GIMP_UNDO_GROUP_ITEM_DISPLACE, + ngettext ("Lower Layer to Bottom", + "Lower Layers to Bottom", + g_list_length (lowered_layers))); + + for (iter = lowered_layers; iter; iter = iter->next) + gimp_image_lower_item_to_bottom (image, iter->data); - gimp_image_lower_item_to_bottom (image, GIMP_ITEM (layer)); gimp_image_flush (image); + gimp_image_undo_group_end (image); + + g_list_free (lowered_layers); } void