1
1

VSE: Add API function to select displayed meta strip

Use function `sequence_editor.display_stack(meta_strip)` to set
displayed timeline content.

To view top-level timeline, that does not belong to any meta strip, pass
`None` as argument.

Differential Revision: https://developer.blender.org/D12048
This commit is contained in:
Félix
2022-06-27 19:29:41 +02:00
committed by Richard Antalik
parent a2b9b9d3c4
commit 6b35d9e6fb
7 changed files with 108 additions and 47 deletions

View File

@@ -1911,11 +1911,9 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
SEQ_prefetch_stop(scene);
if (active_seq && active_seq->type == SEQ_TYPE_META && active_seq->flag & SELECT) {
/* Enter meta-strip. */
SEQ_meta_stack_alloc(ed, active_seq);
SEQ_seqbase_active_set(ed, &active_seq->seqbase);
SEQ_channels_displayed_set(ed, &active_seq->channels);
/* Deselect active meta seq. */
SEQ_select_active_set(scene, NULL);
SEQ_meta_stack_set(scene, active_seq);
}
else {
/* Exit meta-strip if possible. */
@@ -1923,14 +1921,12 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
MetaStack *ms = SEQ_meta_stack_active_get(ed);
SEQ_seqbase_active_set(ed, ms->oldbasep);
SEQ_channels_displayed_set(ed, ms->old_channels);
SEQ_select_active_set(scene, ms->parseq);
SEQ_meta_stack_free(ed, ms);
/* Display parent meta. */
Sequence *meta_parent = SEQ_meta_stack_pop(ed);
SEQ_select_active_set(scene, meta_parent);
}
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
// DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;

View File

@@ -43,6 +43,7 @@
#include "SEQ_prefetch.h"
#include "SEQ_proxy.h"
#include "SEQ_relations.h"
#include "SEQ_select.h"
#include "SEQ_sequencer.h"
#include "SEQ_sound.h"
#include "SEQ_time.h"
@@ -1107,6 +1108,26 @@ static void rna_SequenceEditor_overlay_frame_set(PointerRNA *ptr, int value)
}
}
static void rna_SequenceEditor_display_stack(ID *id,
Editing *ed,
ReportList *reports,
Sequence *seqm)
{
/* Check for non-meta sequence */
if (seqm != NULL && seqm->type != SEQ_TYPE_META && SEQ_exists_in_seqbase(seqm, &ed->seqbase)) {
BKE_report(reports, RPT_ERROR, "Sequence type must be 'META'");
return;
}
/* Get editing base of meta sequence */
Scene *scene = (Scene *)id;
SEQ_meta_stack_set(scene, seqm);
/* De-activate strip. This is to prevent strip from different timeline being drawn. */
SEQ_select_active_set(scene, NULL);
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
}
static bool modifier_seq_cmp_fn(Sequence *seq, void *arg_pt)
{
SequenceSearchData *data = arg_pt;
@@ -2116,6 +2137,8 @@ static void rna_def_channel(BlenderRNA *brna)
static void rna_def_editor(BlenderRNA *brna)
{
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *parm;
PropertyRNA *prop;
static const EnumPropertyItem editing_storage_items[] = {
@@ -2259,6 +2282,15 @@ static void rna_def_editor(BlenderRNA *brna)
"Prefetch Frames",
"Render frames ahead of current frame in the background for faster playback");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
/* functions */
func = RNA_def_function(srna, "display_stack", "rna_SequenceEditor_display_stack");
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Display sequences stack");
parm = RNA_def_pointer(
func, "meta_sequence", "Sequence", "Meta Sequence", "Meta to display its stack");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
}
static void rna_def_filter_video(StructRNA *srna)

View File

@@ -68,6 +68,7 @@ void SEQ_cache_iterate(
struct Sequence *SEQ_find_metastrip_by_sequence(ListBase *seqbase /* = ed->seqbase */,
struct Sequence *meta /* = NULL */,
struct Sequence *seq);
bool SEQ_exists_in_seqbase(const struct Sequence *seq, const struct ListBase *seqbase);
#ifdef __cplusplus
}

View File

@@ -69,28 +69,25 @@ struct ListBase *SEQ_active_seqbase_get(const struct Editing *ed);
void SEQ_seqbase_active_set(struct Editing *ed, struct ListBase *seqbase);
struct Sequence *SEQ_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int type);
void SEQ_sequence_free(struct Scene *scene, struct Sequence *seq);
/**
* Create and initialize #MetaStack, append it to `ed->metastack` ListBase
*
* \param ed: sequence editor data
* \param seq_meta: meta strip
* \return pointer to created meta stack
*/
struct MetaStack *SEQ_meta_stack_alloc(struct Editing *ed, struct Sequence *seq_meta);
/**
* Get #MetaStack that corresponds to current level that is being viewed
*
* \param ed: sequence editor data
* \return pointer to meta stack
*/
struct MetaStack *SEQ_meta_stack_active_get(const struct Editing *ed);
/**
* Free #MetaStack and remove it from `ed->metastack` ListBase.
* Open Meta strip content for editing.
*
* \param ed: sequence editor data
* \param ms: meta stack
* \param seqm: meta sequence or NULL for top level view
*/
void SEQ_meta_stack_free(struct Editing *ed, struct MetaStack *ms);
void SEQ_meta_stack_set(const struct Scene *scene, struct Sequence *dst_seq);
/**
* Close last Meta strip open for editing.
*
* \param ed: sequence editor data
*/
struct Sequence *SEQ_meta_stack_pop(struct Editing *ed);
struct Sequence *SEQ_sequence_dupli_recursive(const struct Scene *scene_src,
struct Scene *scene_dst,
struct ListBase *new_seq_list,

View File

@@ -397,23 +397,23 @@ void SEQ_seqbase_active_set(Editing *ed, ListBase *seqbase)
ed->seqbasep = seqbase;
}
MetaStack *SEQ_meta_stack_alloc(Editing *ed, Sequence *seq_meta)
static MetaStack *seq_meta_stack_alloc(const Scene *scene, Sequence *seq_meta)
{
Editing *ed = SEQ_editing_get(scene);
MetaStack *ms = MEM_mallocN(sizeof(MetaStack), "metastack");
BLI_addtail(&ed->metastack, ms);
BLI_addhead(&ed->metastack, ms);
ms->parseq = seq_meta;
ms->oldbasep = ed->seqbasep;
ms->old_channels = ed->displayed_channels;
/* Reference to previously displayed timeline data. */
Sequence *higher_level_meta = seq_sequence_lookup_meta_by_seq(scene, seq_meta);
ms->oldbasep = higher_level_meta ? &higher_level_meta->seqbase : &ed->seqbase;
ms->old_channels = higher_level_meta ? &higher_level_meta->channels : &ed->channels;
copy_v2_v2_int(ms->disp_range, &ms->parseq->startdisp);
return ms;
}
void SEQ_meta_stack_free(Editing *ed, MetaStack *ms)
{
BLI_remlink(&ed->metastack, ms);
MEM_freeN(ms);
}
MetaStack *SEQ_meta_stack_active_get(const Editing *ed)
{
if (ed == NULL) {
@@ -423,6 +423,41 @@ MetaStack *SEQ_meta_stack_active_get(const Editing *ed)
return ed->metastack.last;
}
void SEQ_meta_stack_set(const Scene *scene, Sequence *seqm)
{
Editing *ed = SEQ_editing_get(scene);
/* Clear metastack */
BLI_freelistN(&ed->metastack);
if (seqm != NULL) {
/* Allocate meta stack in a way, that represents meta hierarchy in timeline. */
seq_meta_stack_alloc(scene, seqm);
Sequence *meta_parent = seqm;
while (meta_parent = seq_sequence_lookup_meta_by_seq(scene, meta_parent)) {
seq_meta_stack_alloc(scene, meta_parent);
}
SEQ_seqbase_active_set(ed, &seqm->seqbase);
SEQ_channels_displayed_set(ed, &seqm->channels);
}
else {
/* Go to top level, exiting meta strip. */
SEQ_seqbase_active_set(ed, &ed->seqbase);
SEQ_channels_displayed_set(ed, &ed->channels);
}
}
Sequence *SEQ_meta_stack_pop(Editing *ed)
{
MetaStack *ms = SEQ_meta_stack_active_get(ed);
Sequence *meta_parent = ms->parseq;
SEQ_seqbase_active_set(ed, ms->oldbasep);
SEQ_channels_displayed_set(ed, ms->old_channels);
BLI_remlink(&ed->metastack, ms);
MEM_freeN(ms);
return meta_parent;
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@@ -192,19 +192,6 @@ void SEQ_edit_remove_flagged_sequences(Scene *scene, ListBase *seqbase)
}
}
static bool seq_exists_in_seqbase(Sequence *seq, ListBase *seqbase)
{
LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
if (seq_test->type == SEQ_TYPE_META && seq_exists_in_seqbase(seq, &seq_test->seqbase)) {
return true;
}
if (seq_test == seq) {
return true;
}
}
return false;
}
bool SEQ_edit_move_strip_to_seqbase(Scene *scene,
ListBase *seqbase,
Sequence *seq,
@@ -247,12 +234,12 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene,
return false;
}
if (src_seq->type == SEQ_TYPE_META && seq_exists_in_seqbase(dst_seqm, &src_seq->seqbase)) {
if (src_seq->type == SEQ_TYPE_META && SEQ_exists_in_seqbase(dst_seqm, &src_seq->seqbase)) {
*error_str = N_("Moved strip is parent of provided meta strip");
return false;
}
if (!seq_exists_in_seqbase(dst_seqm, &ed->seqbase)) {
if (!SEQ_exists_in_seqbase(dst_seqm, &ed->seqbase)) {
*error_str = N_("Can not move strip to different scene");
return false;
}

View File

@@ -457,3 +457,16 @@ struct Sequence *SEQ_find_metastrip_by_sequence(ListBase *seqbase, Sequence *met
return NULL;
}
bool SEQ_exists_in_seqbase(const Sequence *seq, const ListBase *seqbase)
{
LISTBASE_FOREACH (Sequence *, seq_test, seqbase) {
if (seq_test->type == SEQ_TYPE_META && SEQ_exists_in_seqbase(seq, &seq_test->seqbase)) {
return true;
}
if (seq_test == seq) {
return true;
}
}
return false;
}