diff options
-rw-r--r-- | doc/python_api/sphinx_doc_gen.py | 2 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_channels_defines.c | 18 | ||||
-rw-r--r-- | source/blender/editors/include/ED_anim_api.h | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_ops.c | 3 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_context.c | 88 |
5 files changed, 114 insertions, 0 deletions
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index 7e2be8ddf75..ea6919ae6dc 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -1103,6 +1103,7 @@ context_type_map = { "selectable_objects": ("Object", True), "selected_asset_files": ("FileSelectEntry", True), "selected_bones": ("EditBone", True), + "selected_editable_actions": ("Action", True), "selected_editable_bones": ("EditBone", True), "selected_editable_fcurves": ("FCurve", True), "selected_editable_keyframes": ("Keyframe", True), @@ -1118,6 +1119,7 @@ context_type_map = { "selected_pose_bones": ("PoseBone", True), "selected_pose_bones_from_active_object": ("PoseBone", True), "selected_sequences": ("Sequence", True), + "selected_visible_actions": ("Action", True), "selected_visible_fcurves": ("FCurve", True), "sequences": ("Sequence", True), "soft_body": ("SoftBodyModifier", False), diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 9f2681fbf7a..8e0452de8ea 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -4212,6 +4212,24 @@ void ANIM_channel_debug_print_info(bAnimListElem *ale, short indent_level) } } +/* Retrieves the Action associated with this animation channel. */ +bAction *ANIM_channel_action_get(const bAnimListElem *ale) +{ + if (ale->datatype == ALE_ACT) { + return (bAction *)ale->key_data; + } + + if (ELEM(ale->type, ANIMTYPE_GROUP, ANIMTYPE_FCURVE)) { + ID *owner = ale->fcurve_owner_id; + + if (owner && GS(owner->name) == ID_AC) { + return (bAction *)owner; + } + } + + return NULL; +} + /* --------------------------- */ /* Check if some setting for a channel is enabled diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index e9601220f2e..5d5d9140a24 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -577,6 +577,9 @@ const bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale); /* Print debugging info about a given channel */ void ANIM_channel_debug_print_info(bAnimListElem *ale, short indent_level); +/* Retrieves the Action associated with this animation channel. */ +bAction *ANIM_channel_action_get(const bAnimListElem *ale); + /* Draw the given channel */ void ANIM_channel_draw( bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc, size_t channel_index); diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index c962a1107ae..9cce7dd5c85 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -846,6 +846,9 @@ bool UI_context_copy_to_selected_list(bContext *C, else if (RNA_struct_is_a(ptr->type, &RNA_Keyframe)) { *r_lb = CTX_data_collection_get(C, "selected_editable_keyframes"); } + else if (RNA_struct_is_a(ptr->type, &RNA_Action)) { + *r_lb = CTX_data_collection_get(C, "selected_editable_actions"); + } else if (RNA_struct_is_a(ptr->type, &RNA_NlaStrip)) { *r_lb = CTX_data_collection_get(C, "selected_nla_strips"); } diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index a8c63027254..2dc79a0e335 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -113,6 +113,8 @@ const char *screen_context_dir[] = { "active_gpencil_frame", "active_annotation_layer", "active_operator", + "selected_visible_actions", + "selected_editable_actions", "visible_fcurves", "editable_fcurves", "selected_visible_fcurves", @@ -975,6 +977,90 @@ static eContextResult screen_ctx_active_operator(const bContext *C, bContextData } return CTX_RESULT_NO_DATA; } +static eContextResult screen_ctx_sel_actions_impl(const bContext *C, + bContextDataResult *result, + bool editable) +{ + bAnimContext ac; + if (ANIM_animdata_get_context(C, &ac) && ELEM(ac.spacetype, SPACE_ACTION, SPACE_GRAPH)) { + /* In the Action and Shape Key editor always use the action field at the top. */ + if (ac.spacetype == SPACE_ACTION) { + SpaceAction *saction = (SpaceAction *)ac.sl; + + if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY)) { + if (saction->action && !(editable && ID_IS_LINKED(saction->action))) { + CTX_data_id_list_add(result, &saction->action->id); + } + + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return CTX_RESULT_OK; + } + } + + /* Search for selected animation data items. */ + ListBase anim_data = {NULL, NULL}; + + int filter = ANIMFILTER_DATA_VISIBLE; + bool check_selected = false; + + switch (ac.spacetype) { + case SPACE_GRAPH: + filter |= ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL; + break; + + case SPACE_ACTION: + filter |= ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS; + check_selected = true; + break; + } + + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + GSet *seen_set = BLI_gset_ptr_new("seen actions"); + + LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { + /* In dopesheet check selection status of individual items, skipping + * if not selected or has no selection flag. This is needed so that + * selecting action or group rows without any channels works. */ + if (check_selected && ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_SELECT) <= 0) { + continue; + } + + bAction *action = ANIM_channel_action_get(ale); + + if (action) { + if (editable && ID_IS_LINKED(action)) { + continue; + } + + /* Add the action to the output list if not already added. */ + if (!BLI_gset_haskey(seen_set, action)) { + CTX_data_id_list_add(result, &action->id); + BLI_gset_add(seen_set, action); + } + } + } + + BLI_gset_free(seen_set, NULL); + + ANIM_animdata_freelist(&anim_data); + + CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION); + return CTX_RESULT_OK; + } + return CTX_RESULT_NO_DATA; +} + +static eContextResult screen_ctx_selected_visible_actions(const bContext *C, + bContextDataResult *result) +{ + return screen_ctx_sel_actions_impl(C, result, false); +} +static eContextResult screen_ctx_selected_editable_actions(const bContext *C, + bContextDataResult *result) +{ + return screen_ctx_sel_actions_impl(C, result, true); +} static eContextResult screen_ctx_sel_edit_fcurves_(const bContext *C, bContextDataResult *result, const int extra_filter) @@ -1185,6 +1271,8 @@ static void ensure_ed_screen_context_functions(void) register_context_function("editable_gpencil_layers", screen_ctx_editable_gpencil_layers); register_context_function("editable_gpencil_strokes", screen_ctx_editable_gpencil_strokes); register_context_function("active_operator", screen_ctx_active_operator); + register_context_function("selected_visible_actions", screen_ctx_selected_visible_actions); + register_context_function("selected_editable_actions", screen_ctx_selected_editable_actions); register_context_function("editable_fcurves", screen_ctx_editable_fcurves); register_context_function("visible_fcurves", screen_ctx_visible_fcurves); register_context_function("selected_editable_fcurves", screen_ctx_selected_editable_fcurves); |