VSE: Add new Scene and Strip

This operator allows to add a new scene at the same time that the strip. This is very handy for storyboarding.

Reviewed By: ISS

Maniphest Tasks: T97678

Differential Revision: https://developer.blender.org/D14790
This commit is contained in:
Antonio Vazquez 2022-05-16 19:46:20 +02:00
parent 205c6d8d08
commit be84fe4ce1
Notes: blender-bot 2023-02-14 08:08:56 +01:00
Referenced by issue #97678, VSE: Add new Scene and Strip in one step
6 changed files with 166 additions and 11 deletions

View File

@ -676,15 +676,7 @@ class SEQUENCER_MT_add(Menu):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
bpy_data_scenes_len = len(bpy.data.scenes)
if bpy_data_scenes_len > 10:
layout.operator_context = 'INVOKE_DEFAULT'
layout.operator("sequencer.scene_strip_add", text="Scene...", icon='SCENE_DATA')
elif bpy_data_scenes_len > 1:
layout.operator_menu_enum("sequencer.scene_strip_add", "scene", text="Scene", icon='SCENE_DATA')
else:
layout.menu("SEQUENCER_MT_add_empty", text="Scene", icon='SCENE_DATA')
del bpy_data_scenes_len
layout.menu("SEQUENCER_MT_add_scene", text="Scene", icon='SCENE_DATA')
bpy_data_movieclips_len = len(bpy.data.movieclips)
if bpy_data_movieclips_len > 10:
@ -734,6 +726,34 @@ class SEQUENCER_MT_add(Menu):
col.enabled = selected_sequences_len(context) >= 1
class SEQUENCER_MT_add_scene(Menu):
bl_label = "Scene"
bl_translation_context = i18n_contexts.operator_default
def draw(self, context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("sequencer.scene_strip_add_new", text="New Scene", icon="ADD").type='NEW'
bpy_data_scenes_len = len(bpy.data.scenes)
if bpy_data_scenes_len > 10:
layout.separator()
layout.operator_context = 'INVOKE_DEFAULT'
layout.operator("sequencer.scene_strip_add", text="Scene...", icon='SCENE_DATA')
elif bpy_data_scenes_len > 1:
layout.separator()
scene = context.scene
for sc_item in bpy.data.scenes:
if sc_item == scene:
continue
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("sequencer.scene_strip_add", text=sc_item.name).scene = sc_item.name
del bpy_data_scenes_len
class SEQUENCER_MT_add_empty(Menu):
bl_label = "Empty"
@ -2609,6 +2629,7 @@ classes = (
SEQUENCER_MT_marker,
SEQUENCER_MT_navigation,
SEQUENCER_MT_add,
SEQUENCER_MT_add_scene,
SEQUENCER_MT_add_effect,
SEQUENCER_MT_add_transitions,
SEQUENCER_MT_add_empty,

View File

@ -18,6 +18,11 @@ struct Scene *ED_scene_add(struct Main *bmain,
struct bContext *C,
struct wmWindow *win,
enum eSceneCopyMethod method) ATTR_NONNULL();
/** Special mode for adding a scene assigned to sequencer strip. */
struct Scene *ED_scene_sequencer_add(struct Main *bmain,
struct bContext *C,
enum eSceneCopyMethod method,
const bool assign_strip);
/**
* \note Only call outside of area/region loops.
* \return true if successful.

View File

@ -67,7 +67,10 @@ static Scene *scene_add(Main *bmain, Scene *scene_old, eSceneCopyMethod method)
}
/** Add a new scene in the sequence editor. */
static Scene *ED_scene_sequencer_add(Main *bmain, bContext *C, eSceneCopyMethod method)
Scene *ED_scene_sequencer_add(Main *bmain,
bContext *C,
eSceneCopyMethod method,
const bool assign_strip)
{
Sequence *seq = NULL;
Scene *scene_active = CTX_data_scene(C);
@ -88,6 +91,11 @@ static Scene *ED_scene_sequencer_add(Main *bmain, bContext *C, eSceneCopyMethod
Scene *scene_new = scene_add(bmain, scene_strip, method);
/* If don't need assign the scene to the strip, nothing else to do. */
if (!assign_strip) {
return scene_new;
}
/* As the scene is created in sequencer, do not set the new scene as active.
* This is useful for story-boarding where we want to keep actual scene active.
* The new scene is linked to the active strip and the viewport updated. */
@ -291,7 +299,7 @@ static int scene_new_sequencer_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
int type = RNA_enum_get(op->ptr, "type");
if (ED_scene_sequencer_add(bmain, C, type) == NULL) {
if (ED_scene_sequencer_add(bmain, C, type, true) == NULL) {
return OPERATOR_CANCELLED;
}

View File

@ -31,6 +31,7 @@
#include "BKE_mask.h"
#include "BKE_movieclip.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_sound.h"
#include "IMB_imbuf.h"
@ -54,6 +55,7 @@
#include "SEQ_transform.h"
#include "SEQ_utils.h"
#include "ED_scene.h"
/* For menu, popup, icons, etc. */
#include "ED_screen.h"
#include "ED_sequencer.h"
@ -469,6 +471,123 @@ void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot)
ot->prop = prop;
}
static EnumPropertyItem strip_new_scene_items[] = {
{SCE_COPY_NEW, "NEW", 0, "New", "Add new Strip with a new empty Scene with default settings"},
{SCE_COPY_EMPTY,
"EMPTY",
0,
"Copy Settings",
"Add a new Strip, with an empty scene, and copy settings from the current scene"},
{SCE_COPY_LINK_COLLECTION,
"LINK_COPY",
0,
"Linked Copy",
"Add a Strip and link in the collections from the current scene (shallow copy)"},
{SCE_COPY_FULL,
"FULL_COPY",
0,
"Full Copy",
"Add a Strip and make a full copy of the current scene"},
{0, NULL, 0, NULL, NULL},
};
static int sequencer_add_scene_strip_new_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
const Editing *ed = SEQ_editing_ensure(scene);
if (RNA_boolean_get(op->ptr, "replace_sel")) {
ED_sequencer_deselect_all(scene);
}
SeqLoadData load_data;
load_data_init_from_operator(&load_data, C, op);
int type = RNA_enum_get(op->ptr, "type");
Scene *scene_new = ED_scene_sequencer_add(bmain, C, type, false);
if (scene_new == NULL) {
return OPERATOR_CANCELLED;
}
load_data.scene = scene_new;
Sequence *seq = SEQ_add_scene_strip(scene, ed->seqbasep, &load_data);
seq_load_apply_generic_options(C, op, seq);
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
DEG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
}
static int sequencer_add_scene_strip_new_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
sequencer_disable_one_time_properties(C, op);
sequencer_generic_invoke_xy__internal(C, op, 0, SEQ_TYPE_SCENE);
return sequencer_add_scene_strip_new_exec(C, op);
}
static const EnumPropertyItem *strip_new_sequencer_enum_itemf(bContext *C,
PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop),
bool *r_free)
{
EnumPropertyItem *item = NULL;
int totitem = 0;
uint item_index;
item_index = RNA_enum_from_value(strip_new_scene_items, SCE_COPY_NEW);
RNA_enum_item_add(&item, &totitem, &strip_new_scene_items[item_index]);
bool has_scene_or_no_context = false;
if (C == NULL) {
/* For documentation generation. */
has_scene_or_no_context = true;
}
else {
Scene *scene = CTX_data_scene(C);
Sequence *seq = SEQ_select_active_get(scene);
if ((seq && (seq->type == SEQ_TYPE_SCENE) && (seq->scene != NULL))) {
has_scene_or_no_context = true;
}
}
if (has_scene_or_no_context) {
int values[] = {SCE_COPY_EMPTY, SCE_COPY_LINK_COLLECTION, SCE_COPY_FULL};
for (int i = 0; i < ARRAY_SIZE(values); i++) {
item_index = RNA_enum_from_value(strip_new_scene_items, values[i]);
RNA_enum_item_add(&item, &totitem, &strip_new_scene_items[item_index]);
}
}
RNA_enum_item_end(&item, &totitem);
*r_free = true;
return item;
}
void SEQUENCER_OT_scene_strip_add_new(struct wmOperatorType *ot)
{
/* Identifiers. */
ot->name = "Add Strip with a new Scene";
ot->idname = "SEQUENCER_OT_scene_strip_add_new";
ot->description = "Create a new Strip and add a assign a new Scene as source";
/* Api callbacks. */
ot->invoke = sequencer_add_scene_strip_new_invoke;
ot->exec = sequencer_add_scene_strip_new_exec;
ot->poll = ED_operator_sequencer_active_editable;
/* Flags. */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME);
ot->prop = RNA_def_enum(ot->srna, "type", strip_new_scene_items, SCE_COPY_NEW, "Type", "");
RNA_def_enum_funcs(ot->prop, strip_new_sequencer_enum_itemf);
RNA_def_property_flag(ot->prop, PROP_ENUM_NO_TRANSLATE);
}
static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);

View File

@ -232,6 +232,7 @@ void SEQUENCER_OT_select_grouped(struct wmOperatorType *ot);
/* sequencer_add.c */
void SEQUENCER_OT_scene_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_scene_strip_add_new(struct wmOperatorType *ot);
void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_movieclip_strip_add(struct wmOperatorType *ot);
void SEQUENCER_OT_mask_strip_add(struct wmOperatorType *ot);

View File

@ -82,6 +82,7 @@ void sequencer_operatortypes(void)
/* sequencer_add.c */
WM_operatortype_append(SEQUENCER_OT_scene_strip_add);
WM_operatortype_append(SEQUENCER_OT_scene_strip_add_new);
WM_operatortype_append(SEQUENCER_OT_movieclip_strip_add);
WM_operatortype_append(SEQUENCER_OT_mask_strip_add);
WM_operatortype_append(SEQUENCER_OT_movie_strip_add);