From ebb843846dca2439c92bedc8b0005ea42beed15e Mon Sep 17 00:00:00 2001 From: Wayne Dixon Date: Fri, 26 Sep 2025 11:25:45 +0200 Subject: [PATCH] Fix: Camera marker selection logic in animation editors Fix camera marker selection logic in the Dope Sheet (and other editors that show camera markers). It is now once again possible to select the camera that is bound to a marker by CTRL-clicking the marker. SHIFT CTRL will extend this selection. (SHIFT+) click still (range-)selects the markers, but not the cameras themselves. This hasn't changed. Pull Request: https://projects.blender.org/blender/blender/pulls/145324 --- .../blender/editors/animation/anim_markers.cc | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/animation/anim_markers.cc b/source/blender/editors/animation/anim_markers.cc index 412f2fd05e0..d79fd901da4 100644 --- a/source/blender/editors/animation/anim_markers.cc +++ b/source/blender/editors/animation/anim_markers.cc @@ -1318,8 +1318,10 @@ static void select_marker_camera_switch( using namespace blender::ed; if (camera) { BLI_assert(CTX_data_mode_enum(C) == CTX_MODE_OBJECT); + const bool is_sequencer = CTX_wm_space_seq(C) != nullptr; Scene *scene = is_sequencer ? CTX_data_sequencer_scene(C) : CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); Base *base; int sel = 0; @@ -1329,20 +1331,21 @@ static void select_marker_camera_switch( } LISTBASE_FOREACH (TimeMarker *, marker, markers) { - if (marker->frame == cfra) { + if (marker->frame == cfra && marker->camera) { sel = (marker->flag & SELECT); break; } } BKE_view_layer_synced_ensure(scene, view_layer); + LISTBASE_FOREACH (TimeMarker *, marker, markers) { if (marker->camera) { if (marker->frame == cfra) { base = BKE_view_layer_base_find(view_layer, marker->camera); if (base) { object::base_select(base, object::eObjectSelect_Mode(sel)); - if (sel) { + if (!extend) { object::base_activate(C, base); } } @@ -1373,6 +1376,7 @@ static wmOperatorStatus ed_marker_select(bContext *C, const bool is_sequencer = CTX_wm_space_seq(C) != nullptr; ListBase *markers = is_sequencer ? ED_sequencer_context_get_markers(C) : ED_context_get_markers(C); + const View2D *v2d = UI_view2d_fromcontext(C); wmOperatorStatus ret_val = OPERATOR_FINISHED; TimeMarker *nearest_marker = region_position_is_over_marker(v2d, markers, mval[0]); @@ -1394,8 +1398,6 @@ static wmOperatorStatus ed_marker_select(bContext *C, else { /* Deselect all markers. */ deselect_markers(markers); - - select_marker_camera_switch(C, camera, extend, markers, cfra); } } @@ -1403,7 +1405,7 @@ static wmOperatorStatus ed_marker_select(bContext *C, TimeMarker *marker, *marker_cycle_selected = nullptr; TimeMarker *marker_found = nullptr; - /* support for selection cycling */ + /* Support for selection cycling. */ LISTBASE_FOREACH (TimeMarker *, marker, markers) { if (marker->frame == cfra) { if (marker->flag & SELECT) { @@ -1414,9 +1416,9 @@ static wmOperatorStatus ed_marker_select(bContext *C, } } - /* if extend is not set, then deselect markers */ + /* If extend is not set, then deselect markers. */ LISTBASE_CIRCULAR_FORWARD_BEGIN (TimeMarker *, markers, marker, marker_cycle_selected) { - /* this way a not-extend select will always give 1 selected marker */ + /* This way a not-extend select will always give 1 selected marker. */ if (marker->frame == cfra) { marker_found = marker; break; @@ -1433,11 +1435,15 @@ static wmOperatorStatus ed_marker_select(bContext *C, } } } + /* If extend is set (by holding Shift), then add the camera to the selection too. */ + if (found && camera) { + select_marker_camera_switch(C, true, extend, markers, nearest_marker->frame); + } WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, nullptr); WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, nullptr); - /* allowing tweaks, but needs OPERATOR_FINISHED, otherwise renaming fails, see #25987. */ + /* Allowing tweaks, but needs OPERATOR_FINISHED, otherwise renaming fails, see #25987. */ return ret_val; }