Fix: Outliner: Not using sequencer scene in various places

The outliner was not using the correct sequencer scene
for some places including:
* strip selection & selection sync
* strip hiding & unhiding

Found while looking into #145206.

Pull Request: https://projects.blender.org/blender/blender/pulls/145250
This commit is contained in:
Falk David
2025-08-29 12:49:58 +02:00
committed by Falk David
parent 03003365cc
commit fefeb939a2
5 changed files with 48 additions and 24 deletions

View File

@@ -236,6 +236,9 @@ enum eOLSetState {
* Also so we can have one place to assign these variables.
*/
struct TreeViewContext {
/* Workspace. */
WorkSpace *workspace;
/* Scene level. */
Scene *scene;
ViewLayer *view_layer;

View File

@@ -730,35 +730,43 @@ static void tree_element_constraint_activate(bContext *C,
}
static void tree_element_strip_activate(bContext *C,
Scene *scene,
WorkSpace *workspace,
TreeElement *te,
const eOLSetState set)
{
Scene *sequencer_scene = workspace->sequencer_scene;
if (!sequencer_scene) {
return;
}
const TreeElementStrip *te_strip = tree_element_cast<TreeElementStrip>(te);
Strip *strip = &te_strip->get_strip();
Editing *ed = seq::editing_get(scene);
Editing *ed = seq::editing_get(sequencer_scene);
if (BLI_findindex(ed->current_strips(), strip) != -1) {
if (set == OL_SETSEL_EXTEND) {
seq::select_active_set(scene, nullptr);
seq::select_active_set(sequencer_scene, nullptr);
}
vse::deselect_all_strips(scene);
vse::deselect_all_strips(sequencer_scene);
if ((set == OL_SETSEL_EXTEND) && strip->flag & SELECT) {
strip->flag &= ~SELECT;
}
else {
strip->flag |= SELECT;
seq::select_active_set(scene, strip);
seq::select_active_set(sequencer_scene, strip);
}
}
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, sequencer_scene);
}
static void tree_element_strip_dup_activate(Scene *scene, TreeElement * /*te*/)
static void tree_element_strip_dup_activate(WorkSpace *workspace, TreeElement * /*te*/)
{
Editing *ed = seq::editing_get(scene);
Scene *sequencer_scene = workspace->sequencer_scene;
if (!sequencer_scene) {
return;
}
Editing *ed = seq::editing_get(sequencer_scene);
#if 0
select_single_seq(strip, 1);
@@ -882,10 +890,10 @@ void tree_element_type_active_set(bContext *C,
tree_element_bonecollection_activate(C, te, tselem);
break;
case TSE_STRIP:
tree_element_strip_activate(C, tvc.scene, te, set);
tree_element_strip_activate(C, tvc.workspace, te, set);
break;
case TSE_STRIP_DUP:
tree_element_strip_dup_activate(tvc.scene, te);
tree_element_strip_dup_activate(tvc.workspace, te);
break;
case TSE_GP_LAYER:
tree_element_gplayer_activate(C, te, tselem);
@@ -1014,11 +1022,15 @@ static eOLDrawState tree_element_bone_collection_state_get(const TreeElement *te
return OL_DRAWSEL_NONE;
}
static eOLDrawState tree_element_strip_state_get(const Scene *scene, const TreeElement *te)
static eOLDrawState tree_element_strip_state_get(const WorkSpace *workspace, const TreeElement *te)
{
const Scene *sequencer_scene = workspace->sequencer_scene;
if (!sequencer_scene) {
return OL_DRAWSEL_NONE;
}
const TreeElementStrip *te_strip = tree_element_cast<TreeElementStrip>(te);
const Strip *strip = &te_strip->get_strip();
const Editing *ed = scene->ed;
const Editing *ed = seq::editing_get(sequencer_scene);
if (ed && ed->act_strip == strip && strip->flag & SELECT) {
return OL_DRAWSEL_NORMAL;
@@ -1189,7 +1201,7 @@ eOLDrawState tree_element_type_active_state_get(const TreeViewContext &tvc,
case TSE_R_LAYER:
return tree_element_viewlayer_state_get(tvc.view_layer, te);
case TSE_STRIP:
return tree_element_strip_state_get(tvc.scene, te);
return tree_element_strip_state_get(tvc.workspace, te);
case TSE_STRIP_DUP:
return tree_element_strip_dup_state_get(te);
case TSE_GP_LAYER:

View File

@@ -12,6 +12,7 @@
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
#include "DNA_space_types.h"
#include "DNA_workspace_types.h"
#include "BLI_listbase.h"
@@ -246,15 +247,19 @@ static void outliner_select_sync_to_pose_bone(TreeElement *te,
}
}
static void outliner_select_sync_to_strip(Scene *scene, const TreeElement *te)
static void outliner_select_sync_to_strip(WorkSpace *workspace, const TreeElement *te)
{
Scene *sequencer_scene = workspace->sequencer_scene;
if (!sequencer_scene) {
return;
}
const TreeStoreElem *tselem = TREESTORE(te);
const TreeElementStrip *te_strip = tree_element_cast<TreeElementStrip>(te);
Strip *strip = &te_strip->get_strip();
if (tselem->flag & TSE_ACTIVE) {
seq::select_active_set(scene, strip);
seq::select_active_set(sequencer_scene, strip);
}
if (tselem->flag & TSE_SELECTED) {
@@ -266,7 +271,8 @@ static void outliner_select_sync_to_strip(Scene *scene, const TreeElement *te)
}
/** Sync select and active flags from outliner to active view layer, bones, and sequencer. */
static void outliner_sync_selection_from_outliner(Scene *scene,
static void outliner_sync_selection_from_outliner(WorkSpace *workspace,
Scene *scene,
ViewLayer *view_layer,
ListBase *tree,
const SyncSelectTypes *sync_types,
@@ -294,12 +300,12 @@ static void outliner_sync_selection_from_outliner(Scene *scene,
}
else if (tselem->type == TSE_STRIP) {
if (sync_types->seq_strip) {
outliner_select_sync_to_strip(scene, te);
outliner_select_sync_to_strip(workspace, te);
}
}
outliner_sync_selection_from_outliner(
scene, view_layer, &te->subtree, sync_types, selected_items);
workspace, scene, view_layer, &te->subtree, sync_types, selected_items);
}
}
@@ -328,7 +334,7 @@ void ED_outliner_select_sync_from_outliner(bContext *C, SpaceOutliner *space_out
/* To store elements that have been selected to prevent linked object sync errors */
SelectedItems selected_items;
outliner_sync_selection_from_outliner(
scene, view_layer, &space_outliner->tree, &sync_types, &selected_items);
CTX_wm_workspace(C), scene, view_layer, &space_outliner->tree, &sync_types, &selected_items);
/* Tag for updates and clear dirty flag to prevent a sync to the outliner on draw. */
if (sync_types.object) {
@@ -344,7 +350,7 @@ void ED_outliner_select_sync_from_outliner(bContext *C, SpaceOutliner *space_out
}
if (sync_types.seq_strip) {
space_outliner->sync_select_dirty &= ~WM_OUTLINER_SYNC_SELECT_FROM_SEQUENCE;
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, CTX_data_sequencer_scene(C));
}
}
@@ -498,12 +504,13 @@ static void outliner_sync_selection_to_outliner(const Scene *scene,
static void get_sync_select_active_data(const bContext *C, SyncSelectActiveData *active_data)
{
Scene *scene = CTX_data_scene(C);
Scene *sequencer_scene = CTX_data_sequencer_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
BKE_view_layer_synced_ensure(scene, view_layer);
active_data->object = BKE_view_layer_active_object_get(view_layer);
active_data->edit_bone = CTX_data_active_bone(C);
active_data->pose_channel = CTX_data_active_pose_bone(C);
active_data->strip = seq::select_active_get(scene);
active_data->strip = sequencer_scene ? seq::select_active_get(sequencer_scene) : nullptr;
}
void outliner_sync_selection(const bContext *C,

View File

@@ -3521,9 +3521,9 @@ static wmOperatorStatus outliner_data_operation_exec(bContext *C, wmOperator *op
break;
}
case TSE_STRIP: {
Scene *scene = CTX_data_scene(C);
outliner_do_data_operation(space_outliner, datalevel, event, sequence_fn, scene);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
Scene *sequencer_scene = CTX_data_sequencer_scene(C);
outliner_do_data_operation(space_outliner, datalevel, event, sequence_fn, sequencer_scene);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, sequencer_scene);
ED_undo_push(C, "Sequencer operation");
break;

View File

@@ -41,6 +41,8 @@ namespace blender::ed::outliner {
void outliner_viewcontext_init(const bContext *C, TreeViewContext *tvc)
{
memset(tvc, 0, sizeof(*tvc));
/* Workspace. */
tvc->workspace = CTX_wm_workspace(C);
/* Scene level. */
tvc->scene = CTX_data_scene(C);