diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index 49c0e19a15a..f7c62dd448a 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -1048,6 +1048,8 @@ def km_user_interface(_params): ("ui.view_item_select", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, {"properties": [("range_select", True)]}), ("ui.view_item_rename", {"type": 'F2', "value": 'PRESS'}, None), + ("ui.view_item_delete", {"type": 'X', "value": 'PRESS'}, None), + ("ui.view_item_delete", {"type": 'DEL', "value": 'PRESS'}, None), ]) return keymap diff --git a/source/blender/editors/include/UI_abstract_view.hh b/source/blender/editors/include/UI_abstract_view.hh index 22580132810..fa32e2cb9e9 100644 --- a/source/blender/editors/include/UI_abstract_view.hh +++ b/source/blender/editors/include/UI_abstract_view.hh @@ -326,6 +326,8 @@ class AbstractViewItem { void end_renaming(); void rename_apply(const bContext &C); + virtual void delete_item(bContext *C); + protected: AbstractViewItem() = default; diff --git a/source/blender/editors/interface/interface_ops.cc b/source/blender/editors/interface/interface_ops.cc index f38da6cacc7..6ddf8dadefe 100644 --- a/source/blender/editors/interface/interface_ops.cc +++ b/source/blender/editors/interface/interface_ops.cc @@ -2830,6 +2830,33 @@ static void UI_OT_view_item_select(wmOperatorType *ot) "Select all between clicked and active items"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); } + +static wmOperatorStatus ui_view_item_delete_invoke(bContext *C, + wmOperator * /*op*/, + const wmEvent * /*event*/) +{ + AbstractView *view = get_view_focused(C); + + view->foreach_view_item([&](AbstractViewItem &item) { + if (item.is_active() || item.is_selected()) { + item.delete_item(C); + } + }); + + return OPERATOR_FINISHED; +} + +static void UI_OT_view_item_delete(wmOperatorType *ot) +{ + ot->name = "Delete"; + ot->idname = "UI_OT_view_item_delete"; + ot->description = "Delete selected list item"; + + ot->invoke = ui_view_item_delete_invoke; + ot->poll = ui_view_focused_poll; + + ot->flag = OPTYPE_INTERNAL; +} /** \} */ /* -------------------------------------------------------------------- */ @@ -2934,6 +2961,7 @@ void ED_operatortypes_ui() WM_operatortype_append(UI_OT_view_scroll); WM_operatortype_append(UI_OT_view_item_rename); WM_operatortype_append(UI_OT_view_item_select); + WM_operatortype_append(UI_OT_view_item_delete); WM_operatortype_append(UI_OT_override_add_button); WM_operatortype_append(UI_OT_override_remove_button); diff --git a/source/blender/editors/interface/templates/interface_template_bone_collection_tree.cc b/source/blender/editors/interface/templates/interface_template_bone_collection_tree.cc index 0c65282da10..2d87e42e6c0 100644 --- a/source/blender/editors/interface/templates/interface_template_bone_collection_tree.cc +++ b/source/blender/editors/interface/templates/interface_template_bone_collection_tree.cc @@ -343,6 +343,11 @@ class BoneCollectionItem : public AbstractTreeViewItem { return bone_collection_.name; } + void delete_item(bContext *C) override + { + ANIM_armature_bonecoll_remove(&armature_, &bone_collection_); + ED_undo_push(C, "Delete Bone Collection"); + } std::unique_ptr create_drag_controller() const override { /* Reject dragging linked (or otherwise uneditable) bone collections. */ diff --git a/source/blender/editors/interface/templates/interface_template_grease_pencil_layer_tree.cc b/source/blender/editors/interface/templates/interface_template_grease_pencil_layer_tree.cc index 19915ae09d1..0536bd5fa25 100644 --- a/source/blender/editors/interface/templates/interface_template_grease_pencil_layer_tree.cc +++ b/source/blender/editors/interface/templates/interface_template_grease_pencil_layer_tree.cc @@ -284,6 +284,14 @@ class LayerViewItem : public AbstractTreeViewItem { return layer_.name(); } + void delete_item(bContext *C) override + { + grease_pencil_.remove_layer(layer_); + DEG_id_tag_update(&grease_pencil_.id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, nullptr); + ED_undo_push(C, "Delete Grease Pencil Layer"); + } + std::unique_ptr create_drag_controller() const override { return std::make_unique( @@ -446,6 +454,14 @@ class LayerGroupViewItem : public AbstractTreeViewItem { return group_.name(); } + void delete_item(bContext *C) override + { + grease_pencil_.remove_group(group_); + DEG_id_tag_update(&grease_pencil_.id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, nullptr); + ED_undo_push(C, "Delete Grease Pencil Group"); + } + std::unique_ptr create_drag_controller() const override { return std::make_unique( diff --git a/source/blender/editors/interface/templates/interface_template_node_tree_interface.cc b/source/blender/editors/interface/templates/interface_template_node_tree_interface.cc index 22a1bf67e0a..e2c69fb5751 100644 --- a/source/blender/editors/interface/templates/interface_template_node_tree_interface.cc +++ b/source/blender/editors/interface/templates/interface_template_node_tree_interface.cc @@ -160,6 +160,15 @@ class NodeSocketViewItem : public BasicTreeViewItem { return socket_.name; } + void delete_item(bContext *C) override + { + Main *bmain = CTX_data_main(C); + nodetree_.tree_interface.remove_item(socket_.item); + BKE_main_ensure_invariants(*bmain, nodetree_.id); + WM_main_add_notifier(NC_NODE | NA_EDITED, &nodetree_); + ED_undo_push(C, "Delete Node Interface Socket"); + } + std::unique_ptr create_drag_controller() const override; std::unique_ptr create_drop_target() override; }; @@ -232,6 +241,15 @@ class NodePanelViewItem : public BasicTreeViewItem { return panel_.name; } + void delete_item(bContext *C) override + { + Main *bmain = CTX_data_main(C); + nodetree_.tree_interface.remove_item(panel_.item); + BKE_main_ensure_invariants(*bmain, nodetree_.id); + WM_main_add_notifier(NC_NODE | NA_EDITED, &nodetree_); + ED_undo_push(C, "Delete Node Interface Panel"); + } + std::unique_ptr create_drag_controller() const override; std::unique_ptr create_drop_target() override; }; diff --git a/source/blender/editors/interface/views/abstract_view_item.cc b/source/blender/editors/interface/views/abstract_view_item.cc index 4c295f65162..15673b6ac9b 100644 --- a/source/blender/editors/interface/views/abstract_view_item.cc +++ b/source/blender/editors/interface/views/abstract_view_item.cc @@ -240,6 +240,11 @@ void AbstractViewItem::add_rename_button(uiBlock &block) } } +void AbstractViewItem::delete_item(bContext * /*C*/) +{ + /* No deletion by default. Needs type specific implementation. */ +} + /** \} */ /* ---------------------------------------------------------------------- */ diff --git a/source/blender/editors/object/interface_template_shape_key_tree.cc b/source/blender/editors/object/interface_template_shape_key_tree.cc index 8bde4ef6547..3e061e024b4 100644 --- a/source/blender/editors/object/interface_template_shape_key_tree.cc +++ b/source/blender/editors/object/interface_template_shape_key_tree.cc @@ -10,6 +10,7 @@ #include "BKE_context.hh" #include "BKE_key.hh" +#include "BKE_object.hh" #include "BLI_listbase.h" #include "BLT_translation.hh" @@ -236,6 +237,15 @@ class ShapeKeyItem : public ui::AbstractTreeViewItem { return label_; } + void delete_item(bContext *C) override + { + Main *bmain = CTX_data_main(C); + BKE_object_shapekey_remove(bmain, shape_key_.object, shape_key_.kb); + DEG_id_tag_update(&shape_key_.object->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, nullptr); + ED_undo_grouped_push(C, "Delete Shape Key"); + } + void build_context_menu(bContext &C, uiLayout &layout) const override { MenuType *mt = WM_menutype_find("MESH_MT_shape_key_tree_context_menu", true); diff --git a/source/blender/editors/space_file/asset_catalog_tree_view.cc b/source/blender/editors/space_file/asset_catalog_tree_view.cc index 92c4600823f..bd650524e22 100644 --- a/source/blender/editors/space_file/asset_catalog_tree_view.cc +++ b/source/blender/editors/space_file/asset_catalog_tree_view.cc @@ -20,6 +20,7 @@ #include "BLT_translation.hh" #include "ED_asset.hh" +#include "ED_asset_catalog.hh" #include "ED_fileselect.hh" #include "ED_undo.hh" @@ -88,6 +89,7 @@ class AssetCatalogTreeViewItem : public ui::BasicTreeViewItem { bool supports_renaming() const override; bool rename(const bContext &C, StringRefNull new_name) override; + void delete_item(bContext *C) override; /** Add drag support for catalog items. */ std::unique_ptr create_drag_controller() const override; @@ -339,6 +341,13 @@ bool AssetCatalogTreeViewItem::rename(const bContext &C, StringRefNull new_name) return true; } +void AssetCatalogTreeViewItem::delete_item(bContext * /*C*/) +{ + const AssetCatalogTreeView &tree_view = static_cast( + this->get_tree_view()); + ed::asset::catalog_remove(tree_view.asset_library_, catalog_item_.get_catalog_id()); +} + std::unique_ptr AssetCatalogTreeViewItem::create_drop_target() { return std::make_unique(*this, catalog_item_);