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:
@@ -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;
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user