Commit: 0dc203a9f5cb26c352f239c2b10885e432661301
Author: Julian Eisel
Date:   Sat May 28 15:22:39 2016 +0200
Branches: soc-2016-layer_manager
https://developer.blender.org/rB0dc203a9f5cb26c352f239c2b10885e432661301

Add operator to remove layers

Calling the operator deletes all selected layer items, if a group is selected, 
all its nested layer items are deleted too.
Also adds another handy iterator, BKE_layeritem_iterate_childs.

Design ToDo: We need to decide what happens with the objects (or GPencil 
strokes, masks, ...) assigned to a layer when deleting the layer.

===================================================================

M       release/scripts/startup/bl_ui/space_layers.py
M       source/blender/blenkernel/BKE_layer.h
M       source/blender/blenkernel/intern/layer.c
M       source/blender/editors/space_layers/layers_intern.h
M       source/blender/editors/space_layers/layers_ops.c
M       source/blender/editors/space_layers/layers_util.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/space_layers.py 
b/release/scripts/startup/bl_ui/space_layers.py
index e46f9d5..1c4f1b5 100644
--- a/release/scripts/startup/bl_ui/space_layers.py
+++ b/release/scripts/startup/bl_ui/space_layers.py
@@ -30,6 +30,7 @@ class LAYERS_HT_header(Header):
         layout.template_header()
         layout.operator("layers.layer_add", text="", icon='NEW')
         layout.operator("layers.group_add", text="", icon='NEWFOLDER')
+        layout.operator("layers.remove", text="", icon='X')
 
 if __name__ == "__main__":  # only for live edit.
     bpy.utils.register_module(__name__)
diff --git a/source/blender/blenkernel/BKE_layer.h 
b/source/blender/blenkernel/BKE_layer.h
index 4df019d..92e41f0 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -115,5 +115,7 @@ void BKE_layeritem_remove(LayerTreeItem *litem, const bool 
remove_children);
 
 void BKE_layeritem_group_assign(LayerTreeItem *group, LayerTreeItem *item);
 
+bool BKE_layeritem_iterate_childs(LayerTreeItem *litem, LayerTreeIterFunc 
foreach, void *customdata);
+
 #endif  /* __BKE_LAYER_H__ */
 
diff --git a/source/blender/blenkernel/intern/layer.c 
b/source/blender/blenkernel/intern/layer.c
index 9270e07..781be58 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -85,6 +85,7 @@ static bool layertree_iterate_list(const ListBase *itemlist, 
LayerTreeIterFunc f
        return true;
 }
 
+
 /**
  * Iterate over all items (including children) in the layer tree, executing \a 
foreach callback for each element.
  * (Pre-order traversal)
@@ -183,4 +184,16 @@ void BKE_layeritem_group_assign(LayerTreeItem *group, 
LayerTreeItem *item)
        BLI_addtail(&group->childs, item);
 }
 
+/**
+ * Iterate over all children (and their children, etc) of \a litem, executing 
\a foreach callback for each element.
+ * (Pre-order traversal)
+ *
+ * \param foreach: Callback that can return false to stop the iteration.
+ * \return if the iteration has been stopped because of a callback returning 
false.
+ */
+bool BKE_layeritem_iterate_childs(LayerTreeItem *litem, LayerTreeIterFunc 
foreach, void *customdata)
+{
+       return layertree_iterate_list(&litem->childs, foreach, customdata);
+}
+
 /** \} */ /* Layer Tree Item */
diff --git a/source/blender/editors/space_layers/layers_intern.h 
b/source/blender/editors/space_layers/layers_intern.h
index f3de55b..1c78bf2 100644
--- a/source/blender/editors/space_layers/layers_intern.h
+++ b/source/blender/editors/space_layers/layers_intern.h
@@ -38,6 +38,9 @@ typedef enum eLayerTileFlag {
  */
 typedef struct LayerTile {
        eLayerTileFlag flag;
+
+       /* LayerTreeItem this tile represents */
+       struct LayerTreeItem *litem;
 } LayerTile;
 
 /* layers_draw.c */
@@ -46,6 +49,7 @@ void layer_group_draw(struct LayerTreeItem *litem, struct 
uiLayout *layout);
 
 /* layers_util.c */
 LayerTile *layers_tile_add(const struct SpaceLayers *slayer, struct 
LayerTreeItem *litem);
+void       layers_tile_remove(const struct SpaceLayers *slayer, LayerTile 
*tile, const bool remove_children);
 LayerTile *layers_tile_find_at_coordinate(
         struct SpaceLayers *slayer, ARegion *ar, const int co[2],
         int *r_tile_idx);
diff --git a/source/blender/editors/space_layers/layers_ops.c 
b/source/blender/editors/space_layers/layers_ops.c
index 3efe3bc..f8cdc70 100644
--- a/source/blender/editors/space_layers/layers_ops.c
+++ b/source/blender/editors/space_layers/layers_ops.c
@@ -79,6 +79,54 @@ static void LAYERS_OT_layer_add(wmOperatorType *ot)
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+static int layer_remove_invoke(bContext *C, wmOperator *UNUSED(op), const 
wmEvent *UNUSED(event))
+{
+       SpaceLayers *slayer = CTX_wm_space_layers(C);
+       ListBase remlist = {NULL};
+
+       /* First iterate over tiles. Ghash iterator doesn't allow removing items
+        * while iterating, so temporarily store selected items in a list */
+       GHashIterator gh_iter;
+       GHASH_ITER(gh_iter, slayer->tiles) {
+               LayerTile *tile = BLI_ghashIterator_getValue(&gh_iter);
+               if (tile->flag & LAYERTILE_SELECTED) {
+                       LinkData *tile_link = BLI_genericNodeN(tile);
+                       BLI_addhead(&remlist, tile_link);
+               }
+       }
+       /* Now, delete all items in the list. */
+       for (LinkData *tile_link = remlist.first, *next_link; tile_link; 
tile_link = next_link) {
+               LayerTile *tile = tile_link->data;
+               LayerTreeItem *litem = tile->litem;
+
+               layers_tile_remove(slayer, tile, true);
+               BKE_layeritem_remove(litem, true);
+
+               next_link = tile_link->next;
+               BLI_freelinkN(&remlist, tile_link);
+       }
+       BLI_assert(BLI_listbase_is_empty(&remlist));
+
+       WM_event_add_notifier(C, NC_SCENE | ND_LAYER, NULL);
+
+       return OPERATOR_FINISHED;
+}
+
+static void LAYERS_OT_remove(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Remove Layers";
+       ot->idname = "LAYERS_OT_remove";
+       ot->description = "Remove selected layers";
+
+       /* api callbacks */
+       ot->invoke = layer_remove_invoke;
+       ot->poll = ED_operator_layers_active;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
 typedef struct {
        SpaceLayers *slayer;
        LayerTreeItem *group;
@@ -318,6 +366,7 @@ void layers_operatortypes(void)
        /* organization */
        WM_operatortype_append(LAYERS_OT_layer_add);
        WM_operatortype_append(LAYERS_OT_group_add);
+       WM_operatortype_append(LAYERS_OT_remove);
        WM_operatortype_append(LAYERS_OT_layer_rename);
 
        /* states (activating selecting, highlighting) */
diff --git a/source/blender/editors/space_layers/layers_util.c 
b/source/blender/editors/space_layers/layers_util.c
index bde548d..7d560b9 100644
--- a/source/blender/editors/space_layers/layers_util.c
+++ b/source/blender/editors/space_layers/layers_util.c
@@ -44,10 +44,33 @@
 LayerTile *layers_tile_add(const SpaceLayers *slayer, LayerTreeItem *litem)
 {
        LayerTile *tile = MEM_callocN(sizeof(LayerTile), __func__);
+
+       tile->litem = litem;
        BLI_ghash_insert(slayer->tiles, litem, tile);
+
        return tile;
 }
 
+static bool layer_tile_remove_children_cb(LayerTreeItem *litem, void 
*customdata)
+{
+       SpaceLayers *slayer = customdata;
+       BLI_ghash_remove(slayer->tiles, litem, NULL, MEM_freeN);
+       return true;
+}
+
+/**
+ * \note Call before removing corresponding LayerTreeItem!
+ */
+void layers_tile_remove(const SpaceLayers *slayer, LayerTile *tile, const bool 
remove_children)
+{
+       /* remove tiles of children first */
+       if (remove_children) {
+               BKE_layeritem_iterate_childs(tile->litem, 
layer_tile_remove_children_cb, (void *)slayer);
+       }
+       /* remove tile */
+       BLI_ghash_remove(slayer->tiles, tile->litem, NULL, MEM_freeN);
+}
+
 typedef struct {
        /* input values */
        SpaceLayers *slayer;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to