[Bf-blender-cvs] [0dc203a] soc-2016-layer_manager: Add operator to remove layers

Julian Eisel noreply at git.blender.org
Sat May 28 15:27:32 CEST 2016


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;




More information about the Bf-blender-cvs mailing list