2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-01-12 19:02:08 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-01-12 19:02:08 +00:00
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup spseq
|
2011-02-27 20:29:51 +00:00
|
|
|
*/
|
|
|
|
|
|
2009-01-12 19:02:08 +00:00
|
|
|
#include <math.h>
|
2020-03-19 09:33:03 +01:00
|
|
|
#include <stdlib.h>
|
2009-01-12 19:02:08 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2015-07-03 12:34:23 +02:00
|
|
|
#include "BLI_timecode.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2015-08-16 17:32:01 +10:00
|
|
|
#include "BLT_translation.h"
|
2012-10-26 17:32:50 +00:00
|
|
|
|
2009-01-12 19:02:08 +00:00
|
|
|
#include "DNA_scene_types.h"
|
2016-01-27 11:01:41 +01:00
|
|
|
#include "DNA_sound_types.h"
|
2009-01-12 19:02:08 +00:00
|
|
|
|
|
|
|
|
#include "BKE_context.h"
|
|
|
|
|
#include "BKE_global.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_lib_id.h"
|
2010-08-13 14:23:44 +00:00
|
|
|
#include "BKE_main.h"
|
2009-01-23 23:14:02 +00:00
|
|
|
#include "BKE_report.h"
|
2009-08-09 21:16:39 +00:00
|
|
|
#include "BKE_sound.h"
|
2012-02-29 12:08:26 +00:00
|
|
|
|
2020-12-19 06:44:57 +01:00
|
|
|
#include "SEQ_add.h"
|
|
|
|
|
#include "SEQ_clipboard.h"
|
|
|
|
|
#include "SEQ_edit.h"
|
|
|
|
|
#include "SEQ_effects.h"
|
|
|
|
|
#include "SEQ_iterator.h"
|
|
|
|
|
#include "SEQ_prefetch.h"
|
|
|
|
|
#include "SEQ_relations.h"
|
|
|
|
|
#include "SEQ_render.h"
|
|
|
|
|
#include "SEQ_select.h"
|
2020-11-01 21:03:31 +01:00
|
|
|
#include "SEQ_sequencer.h"
|
2020-12-19 06:44:57 +01:00
|
|
|
#include "SEQ_time.h"
|
|
|
|
|
#include "SEQ_transform.h"
|
|
|
|
|
#include "SEQ_utils.h"
|
2020-11-01 21:03:31 +01:00
|
|
|
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
#include "WM_api.h"
|
2009-01-12 19:02:08 +00:00
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
#include "RNA_define.h"
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* For menu, popup, icons, etc. */
|
2015-02-06 16:38:32 +01:00
|
|
|
#include "ED_numinput.h"
|
2020-05-01 20:06:38 -06:00
|
|
|
#include "ED_outliner.h"
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
#include "ED_screen.h"
|
2009-12-14 21:42:25 +00:00
|
|
|
#include "ED_sequencer.h"
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2015-01-29 12:36:23 +01:00
|
|
|
#include "UI_interface.h"
|
2020-08-19 13:36:55 +02:00
|
|
|
#include "UI_resources.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "UI_view2d.h"
|
2014-11-24 18:18:35 +01:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
2019-06-07 11:27:34 +02:00
|
|
|
#include "DEG_depsgraph_build.h"
|
2019-06-04 16:52:48 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Own include. */
|
2009-01-12 19:02:08 +00:00
|
|
|
#include "sequencer_intern.h"
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Structs & Enums
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2009-01-12 19:02:08 +00:00
|
|
|
typedef struct TransSeq {
|
|
|
|
|
int start, machine;
|
|
|
|
|
int startstill, endstill;
|
|
|
|
|
int startdisp, enddisp;
|
|
|
|
|
int startofs, endofs;
|
2011-07-05 16:31:21 +00:00
|
|
|
int anim_startofs, anim_endofs;
|
2011-06-11 17:05:20 +00:00
|
|
|
/* int final_left, final_right; */ /* UNUSED */
|
2009-01-12 19:02:08 +00:00
|
|
|
int len;
|
|
|
|
|
} TransSeq;
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
== Sequencer ==
This patch adds:
* support for proxy building again (missing feature from Blender 2.49)
additionally to the way, Blender 2.49 worked, you can select several
strips at once and make Blender build proxies in the background (using
the job system)
Also a new thing: movie proxies are now build into AVI files, and
the proxy system is moved into ImBuf-library, so that other parts
of blender can also benefit from it.
* Timecode support: to fix seeking issues with files, that have
a) varying frame rates
b) very large GOP lengths
c) are broken inbetween
d) use different time code tracks
the proxy builder can now also build timecode indices, which are
used (optionally) for seeking.
For the first time, it is possible, to do frame exact seeking on
all file types.
* Support for different video-streams in one video file (can be
selected in sequencer, other parts of blender can also use it,
but UI has to be added accordingly)
* IMPORTANT: this patch *requires* ffmpeg 0.7 or newer, since
older versions don't support the pkt_pts field, that is essential
for building timecode indices.
Windows and Mac libs are already updated, Linux-users have to build
their own ffmpeg verions until distros keep up.
2011-08-28 14:46:03 +00:00
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Public Context Checks
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-07-02 11:47:00 +02:00
|
|
|
bool ED_space_sequencer_maskedit_mask_poll(bContext *C)
|
2012-07-24 09:53:29 +00:00
|
|
|
{
|
|
|
|
|
return ED_space_sequencer_maskedit_poll(C);
|
2020-11-19 12:59:29 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
bool ED_space_sequencer_check_show_maskedit(SpaceSeq *sseq, Scene *scene)
|
|
|
|
|
{
|
|
|
|
|
if (sseq && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
|
2020-12-19 05:57:27 +01:00
|
|
|
return (SEQ_active_mask_get(scene) != NULL);
|
2009-01-26 09:13:15 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
bool ED_space_sequencer_maskedit_poll(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
|
|
|
|
|
|
|
|
|
if (sseq) {
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
|
return ED_space_sequencer_check_show_maskedit(sseq, scene);
|
2020-06-18 05:25:20 +02:00
|
|
|
}
|
|
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Are we displaying the seq output (not channels or histogram). */
|
|
|
|
|
bool ED_space_sequencer_check_show_imbuf(SpaceSeq *sseq)
|
|
|
|
|
{
|
|
|
|
|
return (ELEM(sseq->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW) &&
|
|
|
|
|
ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ED_space_sequencer_check_show_strip(SpaceSeq *sseq)
|
|
|
|
|
{
|
|
|
|
|
return (ELEM(sseq->view, SEQ_VIEW_SEQUENCE, SEQ_VIEW_SEQUENCE_PREVIEW) &&
|
|
|
|
|
ELEM(sseq->mainb, SEQ_DRAW_SEQUENCE, SEQ_DRAW_IMG_IMBUF));
|
2009-01-20 14:19:39 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2020-11-19 12:59:29 +01:00
|
|
|
/** \name Shared Poll Functions
|
2020-06-06 00:05:54 +10:00
|
|
|
* \{ */
|
|
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
/* Operator functions. */
|
|
|
|
|
bool sequencer_edit_poll(bContext *C)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2020-12-19 05:57:27 +01:00
|
|
|
return (SEQ_editing_get(CTX_data_scene(C), false) != NULL);
|
2020-11-19 12:59:29 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
#if 0 /* UNUSED */
|
|
|
|
|
bool sequencer_strip_poll(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
Editing *ed;
|
2020-12-19 05:57:27 +01:00
|
|
|
return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) &&
|
2020-11-19 12:59:29 +01:00
|
|
|
(ed->act_seq != NULL));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
bool sequencer_strip_has_path_poll(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
Editing *ed;
|
|
|
|
|
Sequence *seq;
|
2020-12-19 05:57:27 +01:00
|
|
|
return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) &&
|
2020-11-19 12:59:29 +01:00
|
|
|
((seq = ed->act_seq) != NULL) && (SEQ_HAS_PATH(seq)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool sequencer_view_preview_poll(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(CTX_data_scene(C), false);
|
2020-11-19 12:59:29 +01:00
|
|
|
if (ed && sseq && (sseq->mainb == SEQ_DRAW_IMG_IMBUF)) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool sequencer_view_strips_poll(bContext *C)
|
|
|
|
|
{
|
|
|
|
|
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
|
|
|
|
if (sseq && ED_space_sequencer_check_show_strip(sseq)) {
|
|
|
|
|
return 1;
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
2020-11-19 12:59:29 +01:00
|
|
|
|
|
|
|
|
return 0;
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Remove Gaps Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2013-03-26 20:34:13 +00:00
|
|
|
static int sequencer_gap_remove_exec(bContext *C, wmOperator *op)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2013-03-26 15:00:56 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-15 21:42:06 +01:00
|
|
|
const bool do_all = RNA_boolean_get(op->ptr, "all");
|
2020-12-19 05:57:27 +01:00
|
|
|
const Editing *ed = SEQ_editing_get(scene, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-15 21:42:06 +01:00
|
|
|
SEQ_edit_remove_gaps(scene, ed->seqbasep, CFRA, do_all);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-26 15:00:56 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2019-08-01 10:19:19 +02:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-26 15:00:56 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-26 20:34:13 +00:00
|
|
|
void SEQUENCER_OT_gap_remove(struct wmOperatorType *ot)
|
2013-03-26 15:00:56 +00:00
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2013-03-26 20:34:13 +00:00
|
|
|
ot->name = "Remove Gaps";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_gap_remove";
|
2013-03-27 18:31:18 +00:00
|
|
|
ot->description =
|
|
|
|
|
"Remove gap at current frame to first strip at the right, independent of selection or "
|
|
|
|
|
"locked state of strips";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2013-03-26 15:00:56 +00:00
|
|
|
// ot->invoke = sequencer_snap_invoke;
|
2013-03-26 20:34:13 +00:00
|
|
|
ot->exec = sequencer_gap_remove_exec;
|
2013-03-26 15:00:56 +00:00
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2013-03-26 15:00:56 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2013-03-26 15:00:56 +00:00
|
|
|
RNA_def_boolean(ot->srna, "all", 0, "All Gaps", "Do all gaps to right of current frame");
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Insert Gaps Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2013-03-26 20:34:13 +00:00
|
|
|
static int sequencer_gap_insert_exec(bContext *C, wmOperator *op)
|
2013-03-26 15:00:56 +00:00
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-15 21:42:06 +01:00
|
|
|
const int frames = RNA_int_get(op->ptr, "frames");
|
2020-12-19 05:57:27 +01:00
|
|
|
const Editing *ed = SEQ_editing_get(scene, false);
|
|
|
|
|
SEQ_transform_offset_after_frame(scene, ed->seqbasep, frames, CFRA);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2013-03-26 15:00:56 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
return OPERATOR_FINISHED;
|
2011-08-12 06:08:22 +00:00
|
|
|
}
|
|
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
void SEQUENCER_OT_gap_insert(struct wmOperatorType *ot)
|
2010-07-08 10:03:29 +00:00
|
|
|
{
|
2020-11-19 12:59:29 +01:00
|
|
|
/* Identifiers. */
|
|
|
|
|
ot->name = "Insert Gaps";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_gap_insert";
|
|
|
|
|
ot->description =
|
|
|
|
|
"Insert gap at current frame to first strips at the right, independent of selection or "
|
|
|
|
|
"locked state of strips";
|
2010-07-08 10:03:29 +00:00
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
/* Api callbacks. */
|
|
|
|
|
// ot->invoke = sequencer_snap_invoke;
|
|
|
|
|
ot->exec = sequencer_gap_insert_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2009-06-09 21:29:59 +00:00
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
/* Flags. */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2015-01-05 02:12:50 +11:00
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
RNA_def_int(ot->srna,
|
|
|
|
|
"frames",
|
|
|
|
|
10,
|
|
|
|
|
0,
|
|
|
|
|
INT_MAX,
|
|
|
|
|
"Frames",
|
|
|
|
|
"Frames to insert after current strip",
|
|
|
|
|
0,
|
|
|
|
|
1000);
|
2015-01-05 02:12:50 +11:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Snap Strips to the Current Frame Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2009-06-09 21:29:59 +00:00
|
|
|
static int sequencer_snap_exec(bContext *C, wmOperator *op)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2009-01-12 19:02:08 +00:00
|
|
|
Sequence *seq;
|
2009-06-09 21:29:59 +00:00
|
|
|
int snap_frame;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
snap_frame = RNA_int_get(op->ptr, "frame");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Check metas. */
|
2012-03-29 22:26:11 +00:00
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
|
|
|
|
if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK) &&
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_transform_sequence_can_be_translated(seq)) {
|
2012-03-29 22:26:11 +00:00
|
|
|
if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) {
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_transform_translate_sequence(
|
2012-08-08 11:15:40 +00:00
|
|
|
scene, seq, (snap_frame - seq->startofs + seq->startstill) - seq->start);
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (seq->flag & SEQ_LEFTSEL) {
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_transform_set_left_handle_frame(seq, snap_frame);
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
|
else { /* SEQ_RIGHTSEL */
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_transform_set_right_handle_frame(seq, snap_frame);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_transform_handle_xlimits(seq, seq->flag & SEQ_LEFTSEL, seq->flag & SEQ_RIGHTSEL);
|
|
|
|
|
SEQ_transform_fix_single_image_seq_offsets(seq);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_time_update_sequence(scene, seq);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2021-03-31 09:27:31 +02:00
|
|
|
/* Test for effects and overlap. */
|
2012-03-29 22:26:11 +00:00
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
|
|
|
|
if (seq->flag & SELECT && !(seq->depth == 0 && seq->flag & SEQ_LOCK)) {
|
2009-01-12 19:02:08 +00:00
|
|
|
seq->flag &= ~SEQ_OVERLAP;
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
|
|
|
|
|
SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
2020-06-18 04:26:41 +02:00
|
|
|
}
|
|
|
|
|
|
2021-01-25 05:51:36 +01:00
|
|
|
/* Recalculate bounds of effect strips, offsetting the keyframes if not snapping any handle. */
|
2020-06-18 04:26:41 +02:00
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
|
|
|
|
if (seq->type & SEQ_TYPE_EFFECT) {
|
2021-01-25 05:51:36 +01:00
|
|
|
const bool either_handle_selected = (seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) != 0;
|
|
|
|
|
|
2019-03-26 21:16:47 +11:00
|
|
|
if (seq->seq1 && (seq->seq1->flag & SELECT)) {
|
2021-01-25 05:51:36 +01:00
|
|
|
if (!either_handle_selected) {
|
|
|
|
|
SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
|
|
|
|
|
}
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_time_update_sequence(scene, seq);
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
|
|
|
|
else if (seq->seq2 && (seq->seq2->flag & SELECT)) {
|
2021-01-25 05:51:36 +01:00
|
|
|
if (!either_handle_selected) {
|
|
|
|
|
SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
|
|
|
|
|
}
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_time_update_sequence(scene, seq);
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
|
|
|
|
else if (seq->seq3 && (seq->seq3->flag & SELECT)) {
|
2021-01-25 05:51:36 +01:00
|
|
|
if (!either_handle_selected) {
|
|
|
|
|
SEQ_offset_animdata(scene, seq, (snap_frame - seq->startdisp));
|
|
|
|
|
}
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_time_update_sequence(scene, seq);
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_sort(scene);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-28 18:02:14 +02:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-06-09 21:29:59 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int sequencer_snap_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2009-06-09 21:29:59 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-06-09 21:29:59 +00:00
|
|
|
int snap_frame;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
snap_frame = CFRA;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-06-09 21:29:59 +00:00
|
|
|
RNA_int_set(op->ptr, "frame", snap_frame);
|
|
|
|
|
return sequencer_snap_exec(C, op);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
2009-06-09 21:29:59 +00:00
|
|
|
void SEQUENCER_OT_snap(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2020-06-01 14:41:12 +10:00
|
|
|
ot->name = "Snap Strips to the Current Frame";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "SEQUENCER_OT_snap";
|
|
|
|
|
ot->description = "Frame where selected strips will be snapped";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->invoke = sequencer_snap_invoke;
|
|
|
|
|
ot->exec = sequencer_snap_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-09-12 17:16:12 +00:00
|
|
|
RNA_def_int(ot->srna,
|
|
|
|
|
"frame",
|
|
|
|
|
0,
|
|
|
|
|
INT_MIN,
|
|
|
|
|
INT_MAX,
|
|
|
|
|
"Frame",
|
|
|
|
|
"Frame where selected strips will be snapped",
|
|
|
|
|
INT_MIN,
|
|
|
|
|
INT_MAX);
|
2009-06-09 21:29:59 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Trim Strips Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2014-10-23 16:48:34 +02:00
|
|
|
typedef struct SlipData {
|
2014-10-21 19:02:05 +02:00
|
|
|
int init_mouse[2];
|
|
|
|
|
float init_mouseloc[2];
|
|
|
|
|
TransSeq *ts;
|
|
|
|
|
Sequence **seq_array;
|
|
|
|
|
bool *trim;
|
|
|
|
|
int num_seq;
|
|
|
|
|
bool slow;
|
2020-04-05 23:55:51 +02:00
|
|
|
int slow_offset; /* Offset at the point where offset was turned on. */
|
2015-02-06 16:38:32 +01:00
|
|
|
NumInput num_input;
|
2014-10-23 16:48:34 +02:00
|
|
|
} SlipData;
|
2014-10-20 15:40:06 +02:00
|
|
|
|
|
|
|
|
static void transseq_backup(TransSeq *ts, Sequence *seq)
|
|
|
|
|
{
|
|
|
|
|
ts->start = seq->start;
|
|
|
|
|
ts->machine = seq->machine;
|
|
|
|
|
ts->startstill = seq->startstill;
|
|
|
|
|
ts->endstill = seq->endstill;
|
|
|
|
|
ts->startdisp = seq->startdisp;
|
|
|
|
|
ts->enddisp = seq->enddisp;
|
|
|
|
|
ts->startofs = seq->startofs;
|
|
|
|
|
ts->endofs = seq->endofs;
|
|
|
|
|
ts->anim_startofs = seq->anim_startofs;
|
|
|
|
|
ts->anim_endofs = seq->anim_endofs;
|
|
|
|
|
ts->len = seq->len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void transseq_restore(TransSeq *ts, Sequence *seq)
|
|
|
|
|
{
|
|
|
|
|
seq->start = ts->start;
|
|
|
|
|
seq->machine = ts->machine;
|
|
|
|
|
seq->startstill = ts->startstill;
|
|
|
|
|
seq->endstill = ts->endstill;
|
|
|
|
|
seq->startdisp = ts->startdisp;
|
|
|
|
|
seq->enddisp = ts->enddisp;
|
|
|
|
|
seq->startofs = ts->startofs;
|
|
|
|
|
seq->endofs = ts->endofs;
|
|
|
|
|
seq->anim_startofs = ts->anim_startofs;
|
|
|
|
|
seq->anim_endofs = ts->anim_endofs;
|
|
|
|
|
seq->len = ts->len;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-31 22:20:22 +11:00
|
|
|
static int slip_add_sequences_recursive(
|
2014-11-24 18:18:35 +01:00
|
|
|
ListBase *seqbasep, Sequence **seq_array, bool *trim, int offset, bool do_trim)
|
2014-10-21 19:02:05 +02:00
|
|
|
{
|
2014-10-20 15:40:06 +02:00
|
|
|
Sequence *seq;
|
|
|
|
|
int num_items = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-20 15:40:06 +02:00
|
|
|
for (seq = seqbasep->first; seq; seq = seq->next) {
|
2014-11-24 18:18:35 +01:00
|
|
|
if (!do_trim || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) {
|
2014-10-20 17:37:13 +02:00
|
|
|
seq_array[offset + num_items] = seq;
|
2020-12-15 16:11:41 +11:00
|
|
|
trim[offset + num_items] = do_trim && ((seq->type & SEQ_TYPE_EFFECT) == 0);
|
2014-10-20 17:37:13 +02:00
|
|
|
num_items++;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-20 15:40:06 +02:00
|
|
|
if (seq->type == SEQ_TYPE_META) {
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Trim the sub-sequences. */
|
2020-03-31 22:20:22 +11:00
|
|
|
num_items += slip_add_sequences_recursive(
|
2014-10-23 16:48:34 +02:00
|
|
|
&seq->seqbase, seq_array, trim, num_items + offset, false);
|
2014-10-20 15:40:06 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-20 15:40:06 +02:00
|
|
|
return num_items;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-31 22:20:22 +11:00
|
|
|
static int slip_count_sequences_recursive(ListBase *seqbasep, bool first_level)
|
2014-10-21 19:02:05 +02:00
|
|
|
{
|
2014-10-20 15:40:06 +02:00
|
|
|
Sequence *seq;
|
|
|
|
|
int trimmed_sequences = 0;
|
|
|
|
|
|
|
|
|
|
for (seq = seqbasep->first; seq; seq = seq->next) {
|
2014-10-20 18:51:46 +02:00
|
|
|
if (!first_level || (!(seq->type & SEQ_TYPE_EFFECT) && (seq->flag & SELECT))) {
|
2014-10-20 17:37:13 +02:00
|
|
|
trimmed_sequences++;
|
|
|
|
|
|
2014-10-20 15:40:06 +02:00
|
|
|
if (seq->type == SEQ_TYPE_META) {
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Trim the sub-sequences. */
|
2020-03-31 22:20:22 +11:00
|
|
|
trimmed_sequences += slip_count_sequences_recursive(&seq->seqbase, false);
|
2014-10-20 15:40:06 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return trimmed_sequences;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-23 16:48:34 +02:00
|
|
|
static int sequencer_slip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2014-10-20 15:40:06 +02:00
|
|
|
{
|
2014-10-23 16:48:34 +02:00
|
|
|
SlipData *data;
|
2014-10-20 15:40:06 +02:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2014-10-20 15:40:06 +02:00
|
|
|
float mouseloc[2];
|
2020-09-09 18:41:07 +02:00
|
|
|
int num_seq;
|
2014-10-20 15:40:06 +02:00
|
|
|
View2D *v2d = UI_view2d_fromcontext(C);
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Recursively count the trimmed elements. */
|
2020-03-31 22:20:22 +11:00
|
|
|
num_seq = slip_count_sequences_recursive(ed->seqbasep, true);
|
2014-10-20 15:40:06 +02:00
|
|
|
|
2019-03-26 21:16:47 +11:00
|
|
|
if (num_seq == 0) {
|
2014-10-20 15:40:06 +02:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2014-10-20 15:40:06 +02:00
|
|
|
|
2014-10-23 16:48:34 +02:00
|
|
|
data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata");
|
2014-10-20 15:40:06 +02:00
|
|
|
data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform");
|
|
|
|
|
data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences");
|
|
|
|
|
data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim");
|
|
|
|
|
data->num_seq = num_seq;
|
|
|
|
|
|
2015-02-06 16:38:32 +01:00
|
|
|
initNumInput(&data->num_input);
|
|
|
|
|
data->num_input.idx_max = 0;
|
|
|
|
|
data->num_input.val_flag[0] |= NUM_NO_FRACTION;
|
|
|
|
|
data->num_input.unit_sys = USER_UNIT_NONE;
|
|
|
|
|
data->num_input.unit_type[0] = 0;
|
|
|
|
|
|
2020-03-31 22:20:22 +11:00
|
|
|
slip_add_sequences_recursive(ed->seqbasep, data->seq_array, data->trim, 0, true);
|
2015-02-06 16:38:32 +01:00
|
|
|
|
2020-09-09 18:41:07 +02:00
|
|
|
for (int i = 0; i < num_seq; i++) {
|
2014-10-23 16:48:34 +02:00
|
|
|
transseq_backup(data->ts + i, data->seq_array[i]);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-10-20 15:40:06 +02:00
|
|
|
|
|
|
|
|
UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]);
|
|
|
|
|
|
|
|
|
|
copy_v2_v2_int(data->init_mouse, event->mval);
|
|
|
|
|
copy_v2_v2(data->init_mouseloc, mouseloc);
|
|
|
|
|
|
|
|
|
|
data->slow = false;
|
|
|
|
|
|
|
|
|
|
WM_event_add_modal_handler(C, op);
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Notify so we draw extensions immediately. */
|
2014-10-20 15:40:06 +02:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-23 16:48:34 +02:00
|
|
|
static bool sequencer_slip_recursively(Scene *scene, SlipData *data, int offset)
|
2014-10-20 15:40:06 +02:00
|
|
|
{
|
2020-03-10 15:53:18 +11:00
|
|
|
/* Only data types supported for now. */
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2020-03-10 16:05:43 +11:00
|
|
|
bool changed = false;
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Iterate in reverse so meta-strips are iterated after their children. */
|
2020-03-10 16:05:43 +11:00
|
|
|
for (int i = data->num_seq - 1; i >= 0; i--) {
|
|
|
|
|
Sequence *seq = data->seq_array[i];
|
|
|
|
|
int endframe;
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Offset seq start. */
|
2020-03-10 16:05:43 +11:00
|
|
|
seq->start = data->ts[i].start + offset;
|
|
|
|
|
|
|
|
|
|
if (data->trim[i]) {
|
|
|
|
|
/* Find the end-frame. */
|
|
|
|
|
endframe = seq->start + seq->len;
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Compute the sequence offsets. */
|
2020-03-10 16:05:43 +11:00
|
|
|
if (endframe > seq->enddisp) {
|
|
|
|
|
seq->endstill = 0;
|
|
|
|
|
seq->endofs = endframe - seq->enddisp;
|
|
|
|
|
changed = true;
|
2014-10-20 15:40:06 +02:00
|
|
|
}
|
2020-03-10 16:05:43 +11:00
|
|
|
else if (endframe <= seq->enddisp) {
|
|
|
|
|
seq->endstill = seq->enddisp - endframe;
|
|
|
|
|
seq->endofs = 0;
|
|
|
|
|
changed = true;
|
2014-10-20 15:40:06 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-10 16:05:43 +11:00
|
|
|
if (seq->start > seq->startdisp) {
|
|
|
|
|
seq->startstill = seq->start - seq->startdisp;
|
|
|
|
|
seq->startofs = 0;
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
else if (seq->start <= seq->startdisp) {
|
|
|
|
|
seq->startstill = 0;
|
|
|
|
|
seq->startofs = seq->startdisp - seq->start;
|
|
|
|
|
changed = true;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2014-10-20 15:40:06 +02:00
|
|
|
}
|
2020-03-10 16:05:43 +11:00
|
|
|
else {
|
2020-04-05 23:55:51 +02:00
|
|
|
/* No transform data (likely effect strip). Only move start and end. */
|
2020-03-10 16:05:43 +11:00
|
|
|
seq->startdisp = data->ts[i].startdisp + offset;
|
|
|
|
|
seq->enddisp = data->ts[i].enddisp + offset;
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-10 16:05:43 +11:00
|
|
|
/* Effects are only added if we they are in a meta-strip.
|
|
|
|
|
* In this case, dependent strips will just be transformed and
|
|
|
|
|
* we can skip calculating for effects.
|
2020-04-05 23:55:51 +02:00
|
|
|
* This way we can avoid an extra loop just for effects. */
|
2020-03-10 16:05:43 +11:00
|
|
|
if (!(seq->type & SEQ_TYPE_EFFECT)) {
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_time_update_sequence(scene, seq);
|
2020-03-10 16:05:43 +11:00
|
|
|
}
|
2014-10-20 15:40:06 +02:00
|
|
|
}
|
2020-03-10 16:05:43 +11:00
|
|
|
if (changed) {
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
|
2020-03-10 16:05:43 +11:00
|
|
|
}
|
|
|
|
|
return changed;
|
2014-10-20 15:40:06 +02:00
|
|
|
}
|
|
|
|
|
|
2020-04-06 02:09:20 +02:00
|
|
|
/* Make sure, that each strip contains at least 1 frame of content. */
|
|
|
|
|
static void sequencer_slip_apply_limits(SlipData *data, int *offset)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < data->num_seq; i++) {
|
|
|
|
|
if (data->trim[i]) {
|
|
|
|
|
Sequence *seq = data->seq_array[i];
|
|
|
|
|
int seq_content_start = data->ts[i].start + *offset;
|
|
|
|
|
int seq_content_end = seq_content_start + seq->len + seq->anim_startofs + seq->anim_endofs;
|
|
|
|
|
int diff = 0;
|
|
|
|
|
|
|
|
|
|
if (seq_content_start >= seq->enddisp) {
|
|
|
|
|
diff = seq->enddisp - seq_content_start - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (seq_content_end <= seq->startdisp) {
|
|
|
|
|
diff = seq->startdisp - seq_content_end + 1;
|
|
|
|
|
}
|
|
|
|
|
*offset += diff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-23 16:48:34 +02:00
|
|
|
static int sequencer_slip_exec(bContext *C, wmOperator *op)
|
2014-10-20 15:40:06 +02:00
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2014-10-20 15:40:06 +02:00
|
|
|
int offset = RNA_int_get(op->ptr, "offset");
|
|
|
|
|
bool success = false;
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Recursively count the trimmed elements. */
|
2020-09-09 18:41:07 +02:00
|
|
|
int num_seq = slip_count_sequences_recursive(ed->seqbasep, true);
|
2014-10-20 15:40:06 +02:00
|
|
|
|
2019-03-26 21:16:47 +11:00
|
|
|
if (num_seq == 0) {
|
2014-10-20 15:40:06 +02:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2014-10-20 15:40:06 +02:00
|
|
|
|
2020-09-09 18:41:07 +02:00
|
|
|
SlipData *data = op->customdata = MEM_mallocN(sizeof(SlipData), "trimdata");
|
2014-10-20 15:40:06 +02:00
|
|
|
data->ts = MEM_mallocN(num_seq * sizeof(TransSeq), "trimdata_transform");
|
|
|
|
|
data->seq_array = MEM_mallocN(num_seq * sizeof(Sequence *), "trimdata_sequences");
|
|
|
|
|
data->trim = MEM_mallocN(num_seq * sizeof(bool), "trimdata_trim");
|
|
|
|
|
data->num_seq = num_seq;
|
|
|
|
|
|
2020-03-31 22:20:22 +11:00
|
|
|
slip_add_sequences_recursive(ed->seqbasep, data->seq_array, data->trim, 0, true);
|
2014-10-20 15:40:06 +02:00
|
|
|
|
2020-09-09 18:41:07 +02:00
|
|
|
for (int i = 0; i < num_seq; i++) {
|
2014-10-20 15:40:06 +02:00
|
|
|
transseq_backup(data->ts + i, data->seq_array[i]);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-06 02:09:20 +02:00
|
|
|
sequencer_slip_apply_limits(data, &offset);
|
2014-10-23 16:48:34 +02:00
|
|
|
success = sequencer_slip_recursively(scene, data, offset);
|
2014-10-20 15:40:06 +02:00
|
|
|
|
|
|
|
|
MEM_freeN(data->seq_array);
|
|
|
|
|
MEM_freeN(data->trim);
|
|
|
|
|
MEM_freeN(data->ts);
|
|
|
|
|
MEM_freeN(data);
|
|
|
|
|
|
2014-11-14 15:04:52 +01:00
|
|
|
if (success) {
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2019-10-08 09:46:37 +02:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
2014-11-14 15:04:52 +01:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2020-07-03 17:20:58 +02:00
|
|
|
return OPERATOR_CANCELLED;
|
2014-10-20 15:40:06 +02:00
|
|
|
}
|
|
|
|
|
|
2020-04-03 13:25:03 +02:00
|
|
|
static void sequencer_slip_update_header(Scene *scene, ScrArea *area, SlipData *data, int offset)
|
2015-02-06 16:38:32 +01:00
|
|
|
{
|
2016-05-14 10:00:52 +02:00
|
|
|
char msg[UI_MAX_DRAW_STR];
|
2015-02-06 16:38:32 +01:00
|
|
|
|
2020-04-03 13:25:03 +02:00
|
|
|
if (area) {
|
2018-06-28 12:06:00 +02:00
|
|
|
if (hasNumInput(&data->num_input)) {
|
|
|
|
|
char num_str[NUM_STR_REP_LEN];
|
|
|
|
|
outputNumInput(&data->num_input, num_str, &scene->unit);
|
2020-05-28 12:15:41 -04:00
|
|
|
BLI_snprintf(msg, sizeof(msg), TIP_("Slip offset: %s"), num_str);
|
2018-06-28 12:06:00 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2020-05-28 12:15:41 -04:00
|
|
|
BLI_snprintf(msg, sizeof(msg), TIP_("Slip offset: %d"), offset);
|
2018-06-28 12:06:00 +02:00
|
|
|
}
|
2015-02-06 16:38:32 +01:00
|
|
|
}
|
|
|
|
|
|
2020-04-03 13:25:03 +02:00
|
|
|
ED_area_status_text(area, msg);
|
2015-02-06 16:38:32 +01:00
|
|
|
}
|
|
|
|
|
|
2014-10-23 16:48:34 +02:00
|
|
|
static int sequencer_slip_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
2014-10-20 15:40:06 +02:00
|
|
|
{
|
2019-06-11 10:55:13 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2014-10-20 15:40:06 +02:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2014-10-23 16:48:34 +02:00
|
|
|
SlipData *data = (SlipData *)op->customdata;
|
2020-04-03 13:25:03 +02:00
|
|
|
ScrArea *area = CTX_wm_area(C);
|
2015-02-06 16:38:32 +01:00
|
|
|
const bool has_numInput = hasNumInput(&data->num_input);
|
|
|
|
|
bool handled = true;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Modal numinput active, try to handle numeric inputs. */
|
2015-02-06 16:38:32 +01:00
|
|
|
if (event->val == KM_PRESS && has_numInput && handleNumInput(C, &data->num_input, event)) {
|
2020-04-06 02:09:20 +02:00
|
|
|
float offset_fl;
|
|
|
|
|
applyNumInput(&data->num_input, &offset_fl);
|
|
|
|
|
int offset = round_fl_to_int(offset_fl);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-06 02:09:20 +02:00
|
|
|
sequencer_slip_apply_limits(data, &offset);
|
|
|
|
|
sequencer_slip_update_header(scene, area, data, offset);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-02-06 16:38:32 +01:00
|
|
|
RNA_int_set(op->ptr, "offset", offset);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-02-06 16:38:32 +01:00
|
|
|
if (sequencer_slip_recursively(scene, data, offset)) {
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-02-06 16:38:32 +01:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-20 15:40:06 +02:00
|
|
|
switch (event->type) {
|
|
|
|
|
case MOUSEMOVE: {
|
2015-02-06 16:38:32 +01:00
|
|
|
if (!has_numInput) {
|
|
|
|
|
float mouseloc[2];
|
|
|
|
|
int offset;
|
|
|
|
|
int mouse_x;
|
|
|
|
|
View2D *v2d = UI_view2d_fromcontext(C);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-02-06 16:38:32 +01:00
|
|
|
if (data->slow) {
|
|
|
|
|
mouse_x = event->mval[0] - data->slow_offset;
|
|
|
|
|
mouse_x *= 0.1f;
|
|
|
|
|
mouse_x += data->slow_offset;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mouse_x = event->mval[0];
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-01 14:41:12 +10:00
|
|
|
/* Choose the side based on which side of the current frame the mouse is. */
|
2015-02-06 16:38:32 +01:00
|
|
|
UI_view2d_region_to_view(v2d, mouse_x, 0, &mouseloc[0], &mouseloc[1]);
|
|
|
|
|
offset = mouseloc[0] - data->init_mouseloc[0];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-06 02:09:20 +02:00
|
|
|
sequencer_slip_apply_limits(data, &offset);
|
2020-04-03 13:25:03 +02:00
|
|
|
sequencer_slip_update_header(scene, area, data, offset);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-02-06 16:38:32 +01:00
|
|
|
RNA_int_set(op->ptr, "offset", offset);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-02-06 16:38:32 +01:00
|
|
|
if (sequencer_slip_recursively(scene, data, offset)) {
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
|
|
|
|
}
|
2014-10-20 15:40:06 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-20 15:40:06 +02:00
|
|
|
case LEFTMOUSE:
|
2020-03-18 10:38:37 -06:00
|
|
|
case EVT_RETKEY:
|
|
|
|
|
case EVT_SPACEKEY: {
|
2014-10-20 15:40:06 +02:00
|
|
|
MEM_freeN(data->seq_array);
|
|
|
|
|
MEM_freeN(data->trim);
|
|
|
|
|
MEM_freeN(data->ts);
|
|
|
|
|
MEM_freeN(data);
|
|
|
|
|
op->customdata = NULL;
|
2020-04-03 13:25:03 +02:00
|
|
|
if (area) {
|
|
|
|
|
ED_area_status_text(area, NULL);
|
2018-06-28 12:06:00 +02:00
|
|
|
}
|
2019-10-08 09:46:37 +02:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
2014-10-20 15:40:06 +02:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-18 10:38:37 -06:00
|
|
|
case EVT_ESCKEY:
|
2014-10-20 15:40:06 +02:00
|
|
|
case RIGHTMOUSE: {
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-09 18:41:07 +02:00
|
|
|
for (int i = 0; i < data->num_seq; i++) {
|
2014-10-20 15:40:06 +02:00
|
|
|
transseq_restore(data->ts + i, data->seq_array[i]);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-09-09 18:41:07 +02:00
|
|
|
for (int i = 0; i < data->num_seq; i++) {
|
2014-10-20 15:40:06 +02:00
|
|
|
Sequence *seq = data->seq_array[i];
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_add_reload_new_file(bmain, scene, seq, false);
|
|
|
|
|
SEQ_time_update_sequence(scene, seq);
|
2014-10-20 15:40:06 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-20 15:40:06 +02:00
|
|
|
MEM_freeN(data->seq_array);
|
|
|
|
|
MEM_freeN(data->ts);
|
|
|
|
|
MEM_freeN(data->trim);
|
|
|
|
|
MEM_freeN(data);
|
|
|
|
|
op->customdata = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-20 15:40:06 +02:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-03 13:25:03 +02:00
|
|
|
if (area) {
|
|
|
|
|
ED_area_status_text(area, NULL);
|
2018-06-28 12:06:00 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-20 15:40:06 +02:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-03-18 10:38:37 -06:00
|
|
|
case EVT_RIGHTSHIFTKEY:
|
|
|
|
|
case EVT_LEFTSHIFTKEY:
|
2015-02-06 16:38:32 +01:00
|
|
|
if (!has_numInput) {
|
|
|
|
|
if (event->val == KM_PRESS) {
|
|
|
|
|
data->slow = true;
|
|
|
|
|
data->slow_offset = event->mval[0];
|
|
|
|
|
}
|
|
|
|
|
else if (event->val == KM_RELEASE) {
|
|
|
|
|
data->slow = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2015-02-06 16:38:32 +01:00
|
|
|
}
|
2014-10-20 15:40:06 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-20 15:40:06 +02:00
|
|
|
default:
|
2015-02-06 16:38:32 +01:00
|
|
|
handled = false;
|
2014-10-20 15:40:06 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Modal numinput inactive, try to handle numeric inputs. */
|
2015-02-06 16:38:32 +01:00
|
|
|
if (!handled && event->val == KM_PRESS && handleNumInput(C, &data->num_input, event)) {
|
2020-04-06 02:09:20 +02:00
|
|
|
float offset_fl;
|
|
|
|
|
applyNumInput(&data->num_input, &offset_fl);
|
|
|
|
|
int offset = round_fl_to_int(offset_fl);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-06 02:09:20 +02:00
|
|
|
sequencer_slip_apply_limits(data, &offset);
|
|
|
|
|
sequencer_slip_update_header(scene, area, data, offset);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-02-06 16:38:32 +01:00
|
|
|
RNA_int_set(op->ptr, "offset", offset);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-02-06 16:38:32 +01:00
|
|
|
if (sequencer_slip_recursively(scene, data, offset)) {
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-20 15:40:06 +02:00
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-23 16:48:34 +02:00
|
|
|
void SEQUENCER_OT_slip(struct wmOperatorType *ot)
|
2014-10-20 15:40:06 +02:00
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2014-10-20 15:40:06 +02:00
|
|
|
ot->name = "Trim Strips";
|
2014-10-23 16:48:34 +02:00
|
|
|
ot->idname = "SEQUENCER_OT_slip";
|
2014-10-20 15:40:06 +02:00
|
|
|
ot->description = "Trim the contents of the active strip";
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2014-10-23 16:48:34 +02:00
|
|
|
ot->invoke = sequencer_slip_invoke;
|
|
|
|
|
ot->modal = sequencer_slip_modal;
|
|
|
|
|
ot->exec = sequencer_slip_exec;
|
2014-10-20 15:40:06 +02:00
|
|
|
ot->poll = sequencer_edit_poll;
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2014-10-20 15:40:06 +02:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
|
|
|
|
2014-10-22 22:26:45 +02:00
|
|
|
RNA_def_int(ot->srna,
|
|
|
|
|
"offset",
|
|
|
|
|
0,
|
|
|
|
|
INT32_MIN,
|
|
|
|
|
INT32_MAX,
|
|
|
|
|
"Offset",
|
|
|
|
|
"Offset to the data of the strip",
|
|
|
|
|
INT32_MIN,
|
|
|
|
|
INT32_MAX);
|
2014-10-20 15:40:06 +02:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Mute Strips Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
static int sequencer_mute_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
Sequence *seq;
|
2014-04-01 11:34:00 +11:00
|
|
|
bool selected;
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
selected = !RNA_boolean_get(op->ptr, "unselected");
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
|
|
|
|
if ((seq->flag & SEQ_LOCK) == 0) {
|
2020-04-05 23:55:51 +02:00
|
|
|
if (selected) {
|
2012-09-13 10:51:18 +00:00
|
|
|
if (seq->flag & SELECT) {
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
seq->flag |= SEQ_MUTE;
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_invalidate_dependent(scene, seq);
|
2012-09-13 10:51:18 +00:00
|
|
|
}
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-09-13 10:51:18 +00:00
|
|
|
if ((seq->flag & SELECT) == 0) {
|
2009-01-12 19:02:08 +00:00
|
|
|
seq->flag |= SEQ_MUTE;
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_invalidate_dependent(scene, seq);
|
2012-09-13 10:51:18 +00:00
|
|
|
}
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
void SEQUENCER_OT_mute(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Mute Strips";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_mute";
|
2015-06-12 14:04:07 +02:00
|
|
|
ot->description = "Mute (un)selected strips";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_mute_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-09-19 12:26:20 +00:00
|
|
|
RNA_def_boolean(
|
|
|
|
|
ot->srna, "unselected", 0, "Unselected", "Mute unselected rather than selected strips");
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Unmute Strips Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
static int sequencer_unmute_exec(bContext *C, wmOperator *op)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2009-01-12 19:02:08 +00:00
|
|
|
Sequence *seq;
|
2014-04-01 11:34:00 +11:00
|
|
|
bool selected;
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
selected = !RNA_boolean_get(op->ptr, "unselected");
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
|
|
|
|
if ((seq->flag & SEQ_LOCK) == 0) {
|
2020-04-05 23:55:51 +02:00
|
|
|
if (selected) {
|
2012-09-13 10:51:18 +00:00
|
|
|
if (seq->flag & SELECT) {
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
seq->flag &= ~SEQ_MUTE;
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_invalidate_dependent(scene, seq);
|
2012-09-13 10:51:18 +00:00
|
|
|
}
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2012-09-13 10:51:18 +00:00
|
|
|
if ((seq->flag & SELECT) == 0) {
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
seq->flag &= ~SEQ_MUTE;
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_invalidate_dependent(scene, seq);
|
2012-09-13 10:51:18 +00:00
|
|
|
}
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
}
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
void SEQUENCER_OT_unmute(struct wmOperatorType *ot)
|
2009-01-12 19:02:08 +00:00
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2018-11-22 02:02:03 +01:00
|
|
|
ot->name = "Unmute Strips";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "SEQUENCER_OT_unmute";
|
2015-06-12 14:04:07 +02:00
|
|
|
ot->description = "Unmute (un)selected strips";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_unmute_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2015-06-12 14:04:07 +02:00
|
|
|
RNA_def_boolean(
|
|
|
|
|
ot->srna, "unselected", 0, "Unselected", "Unmute unselected rather than selected strips");
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
}
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Lock Strips Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int sequencer_lock_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-25 14:53:41 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2009-01-25 14:53:41 +00:00
|
|
|
Sequence *seq;
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
2009-01-25 14:53:41 +00:00
|
|
|
if (seq->flag & SELECT) {
|
|
|
|
|
seq->flag |= SEQ_LOCK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2009-01-25 14:53:41 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_lock(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Lock Strips";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_lock";
|
2019-03-13 08:48:55 +11:00
|
|
|
ot->description = "Lock strips so they can't be transformed";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_lock_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-01-25 14:53:41 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Unlock Strips Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int sequencer_unlock_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-25 14:53:41 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2009-01-25 14:53:41 +00:00
|
|
|
Sequence *seq;
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
2009-01-25 14:53:41 +00:00
|
|
|
if (seq->flag & SELECT) {
|
|
|
|
|
seq->flag &= ~SEQ_LOCK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2009-01-25 14:53:41 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_unlock(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2018-11-22 02:02:03 +01:00
|
|
|
ot->name = "Unlock Strips";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->idname = "SEQUENCER_OT_unlock";
|
2019-03-13 08:48:55 +11:00
|
|
|
ot->description = "Unlock strips so they can be transformed";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_unlock_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-01-25 14:53:41 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Reload Strips Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2012-03-26 22:26:30 +00:00
|
|
|
static int sequencer_reload_exec(bContext *C, wmOperator *op)
|
2009-01-25 14:53:41 +00:00
|
|
|
{
|
2019-06-11 10:55:13 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2009-01-25 14:53:41 +00:00
|
|
|
Sequence *seq;
|
2014-02-03 18:55:59 +11:00
|
|
|
const bool adjust_length = RNA_boolean_get(op->ptr, "adjust_length");
|
2009-01-25 14:53:41 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
2012-03-24 06:38:07 +00:00
|
|
|
if (seq->flag & SELECT) {
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_update_changed_seq_and_deps(scene, seq, 0, 1);
|
|
|
|
|
SEQ_add_reload_new_file(bmain, scene, seq, !adjust_length);
|
2012-03-26 22:26:30 +00:00
|
|
|
|
|
|
|
|
if (adjust_length) {
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
|
|
|
|
|
SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene);
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2012-03-26 22:26:30 +00:00
|
|
|
}
|
2009-01-25 14:53:41 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2009-01-25 14:53:41 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_reload(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2012-03-26 22:26:30 +00:00
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Reload Strips";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_reload";
|
|
|
|
|
ot->description = "Reload strips in the sequencer";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_reload_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER; /* No undo, the data changed is stored outside 'main'. */
|
2012-03-26 13:48:45 +00:00
|
|
|
|
2012-04-14 15:44:31 +00:00
|
|
|
prop = RNA_def_boolean(ot->srna,
|
|
|
|
|
"adjust_length",
|
|
|
|
|
0,
|
|
|
|
|
"Adjust Length",
|
2012-05-16 14:25:25 +00:00
|
|
|
"Adjust length of strips to their data length");
|
2012-03-26 22:26:30 +00:00
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2012-03-26 13:48:45 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Refresh Sequencer Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-07-02 11:47:00 +02:00
|
|
|
static bool sequencer_refresh_all_poll(bContext *C)
|
2015-07-28 18:20:25 +02:00
|
|
|
{
|
|
|
|
|
if (G.is_rendering) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return sequencer_edit_poll(C);
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int sequencer_refresh_all_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-25 14:53:41 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2009-01-25 14:53:41 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
|
2009-01-25 14:53:41 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2009-01-25 14:53:41 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_refresh_all(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Refresh Sequencer";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_refresh_all";
|
|
|
|
|
ot->description = "Refresh the sequencer editor";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_refresh_all_exec;
|
2015-07-28 18:20:25 +02:00
|
|
|
ot->poll = sequencer_refresh_all_poll;
|
2009-01-25 14:53:41 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Reassign Inputs Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
int seq_effect_find_selected(Scene *scene,
|
|
|
|
|
Sequence *activeseq,
|
|
|
|
|
int type,
|
|
|
|
|
Sequence **r_selseq1,
|
|
|
|
|
Sequence **r_selseq2,
|
|
|
|
|
Sequence **r_selseq3,
|
|
|
|
|
const char **r_error_str)
|
|
|
|
|
{
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2020-11-19 12:59:29 +01:00
|
|
|
Sequence *seq1 = NULL, *seq2 = NULL, *seq3 = NULL, *seq;
|
|
|
|
|
|
|
|
|
|
*r_error_str = NULL;
|
|
|
|
|
|
|
|
|
|
if (!activeseq) {
|
2020-12-19 05:57:27 +01:00
|
|
|
seq2 = SEQ_select_active_get(scene);
|
2020-11-19 12:59:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
|
|
|
|
if (seq->flag & SELECT) {
|
2020-12-19 05:57:27 +01:00
|
|
|
if (seq->type == SEQ_TYPE_SOUND_RAM && SEQ_effect_get_num_inputs(type) != 0) {
|
2020-11-19 12:59:29 +01:00
|
|
|
*r_error_str = N_("Cannot apply effects to audio sequence strips");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (!ELEM(seq, activeseq, seq2)) {
|
|
|
|
|
if (seq2 == NULL) {
|
|
|
|
|
seq2 = seq;
|
|
|
|
|
}
|
|
|
|
|
else if (seq1 == NULL) {
|
|
|
|
|
seq1 = seq;
|
|
|
|
|
}
|
|
|
|
|
else if (seq3 == NULL) {
|
|
|
|
|
seq3 = seq;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
*r_error_str = N_("Cannot apply effect to more than 3 sequence strips");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Make sequence selection a little bit more intuitive
|
|
|
|
|
* for 3 strips: the last-strip should be seq3. */
|
|
|
|
|
if (seq3 != NULL && seq2 != NULL) {
|
|
|
|
|
Sequence *tmp = seq2;
|
|
|
|
|
seq2 = seq3;
|
|
|
|
|
seq3 = tmp;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
switch (SEQ_effect_get_num_inputs(type)) {
|
2020-11-19 12:59:29 +01:00
|
|
|
case 0:
|
|
|
|
|
*r_selseq1 = *r_selseq2 = *r_selseq3 = NULL;
|
|
|
|
|
return 1; /* Success. */
|
|
|
|
|
case 1:
|
|
|
|
|
if (seq2 == NULL) {
|
|
|
|
|
*r_error_str = N_("At least one selected sequence strip is needed");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (seq1 == NULL) {
|
|
|
|
|
seq1 = seq2;
|
|
|
|
|
}
|
|
|
|
|
if (seq3 == NULL) {
|
|
|
|
|
seq3 = seq2;
|
|
|
|
|
}
|
|
|
|
|
ATTR_FALLTHROUGH;
|
|
|
|
|
case 2:
|
|
|
|
|
if (seq1 == NULL || seq2 == NULL) {
|
|
|
|
|
*r_error_str = N_("2 selected sequence strips are needed");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (seq3 == NULL) {
|
|
|
|
|
seq3 = seq2;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (seq1 == NULL && seq2 == NULL && seq3 == NULL) {
|
|
|
|
|
*r_error_str = N_("TODO: in what cases does this happen?");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*r_selseq1 = seq1;
|
|
|
|
|
*r_selseq2 = seq2;
|
|
|
|
|
*r_selseq3 = seq3;
|
|
|
|
|
|
|
|
|
|
/* TODO(Richard): This function needs some refactoring, this is just quick hack for T73828. */
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_effect_get_num_inputs(type) < 3) {
|
2020-11-19 12:59:29 +01:00
|
|
|
*r_selseq3 = NULL;
|
|
|
|
|
}
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_effect_get_num_inputs(type) < 2) {
|
2020-11-19 12:59:29 +01:00
|
|
|
*r_selseq2 = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-03 22:25:22 +00:00
|
|
|
static int sequencer_reassign_inputs_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Sequence *seq1, *seq2, *seq3, *last_seq = SEQ_select_active_get(scene);
|
2010-12-03 17:05:21 +00:00
|
|
|
const char *error_msg;
|
2010-07-03 22:25:22 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_effect_get_num_inputs(last_seq->type) == 0) {
|
2020-06-18 05:25:20 +02:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: strip has no inputs");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (!seq_effect_find_selected(
|
2020-07-26 14:58:44 +02:00
|
|
|
scene, last_seq, last_seq->type, &seq1, &seq2, &seq3, &error_msg) ||
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_effect_get_num_inputs(last_seq->type) == 0) {
|
2010-07-03 22:25:22 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, error_msg);
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Check if reassigning would create recursivity. */
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_relations_render_loop_check(seq1, last_seq) ||
|
|
|
|
|
SEQ_relations_render_loop_check(seq2, last_seq) ||
|
|
|
|
|
SEQ_relations_render_loop_check(seq3, last_seq)) {
|
2020-08-04 13:26:21 +02:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Cannot reassign inputs: recursion detected");
|
2010-07-03 22:25:22 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
last_seq->seq1 = seq1;
|
|
|
|
|
last_seq->seq2 = seq2;
|
|
|
|
|
last_seq->seq3 = seq3;
|
|
|
|
|
|
2021-01-12 18:36:27 +01:00
|
|
|
int old_start = last_seq->start;
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_update_changed_seq_and_deps(scene, last_seq, 1, 1);
|
2021-01-12 18:36:27 +01:00
|
|
|
SEQ_offset_animdata(scene, last_seq, (last_seq->start - old_start));
|
2010-07-03 22:25:22 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2010-07-03 22:25:22 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-02 11:47:00 +02:00
|
|
|
static bool sequencer_effect_poll(bContext *C)
|
2010-07-03 22:25:22 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2010-07-03 22:25:22 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (ed) {
|
2020-12-19 05:57:27 +01:00
|
|
|
Sequence *last_seq = SEQ_select_active_get(scene);
|
2012-06-07 15:49:02 +00:00
|
|
|
if (last_seq && (last_seq->type & SEQ_TYPE_EFFECT)) {
|
2010-07-03 22:25:22 +00:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_reassign_inputs(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Reassign Inputs";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_reassign_inputs";
|
|
|
|
|
ot->description = "Reassign the inputs for the effect strip";
|
2010-07-03 22:25:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_reassign_inputs_exec;
|
|
|
|
|
ot->poll = sequencer_effect_poll;
|
2010-07-03 22:25:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2010-07-03 22:25:22 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Swap Inputs Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2010-10-30 12:04:00 +00:00
|
|
|
static int sequencer_swap_inputs_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Sequence *seq, *last_seq = SEQ_select_active_get(scene);
|
2010-10-30 12:04:00 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
if (last_seq->seq1 == NULL || last_seq->seq2 == NULL) {
|
2010-10-30 12:04:00 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "No valid inputs to swap");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
seq = last_seq->seq1;
|
|
|
|
|
last_seq->seq1 = last_seq->seq2;
|
|
|
|
|
last_seq->seq2 = seq;
|
|
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_update_changed_seq_and_deps(scene, last_seq, 1, 1);
|
2010-10-30 12:04:00 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2010-10-30 12:04:00 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
void SEQUENCER_OT_swap_inputs(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Swap Inputs";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_swap_inputs";
|
|
|
|
|
ot->description = "Swap the first two inputs for the effect strip";
|
2010-10-30 12:04:00 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_swap_inputs_exec;
|
|
|
|
|
ot->poll = sequencer_effect_poll;
|
2010-10-30 12:04:00 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2010-10-30 12:04:00 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Split Strips Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
static int mouse_frame_side(View2D *v2d, short mouse_x, int frame)
|
|
|
|
|
{
|
|
|
|
|
int mval[2];
|
|
|
|
|
float mouseloc[2];
|
|
|
|
|
|
|
|
|
|
mval[0] = mouse_x;
|
|
|
|
|
mval[1] = 0;
|
|
|
|
|
|
|
|
|
|
/* Choose the side based on which side of the current frame the mouse is on. */
|
|
|
|
|
UI_view2d_region_to_view(v2d, mval[0], mval[1], &mouseloc[0], &mouseloc[1]);
|
|
|
|
|
|
|
|
|
|
return mouseloc[0] > frame ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-16 21:39:12 +01:00
|
|
|
static const EnumPropertyItem prop_split_types[] = {
|
|
|
|
|
{SEQ_SPLIT_SOFT, "SOFT", 0, "Soft", ""},
|
|
|
|
|
{SEQ_SPLIT_HARD, "HARD", 0, "Hard", ""},
|
2019-02-03 14:01:45 +11:00
|
|
|
{0, NULL, 0, NULL, NULL},
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
};
|
|
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
EnumPropertyItem prop_side_types[] = {
|
|
|
|
|
{SEQ_SIDE_MOUSE, "MOUSE", 0, "Mouse Position", ""},
|
|
|
|
|
{SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""},
|
|
|
|
|
{SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""},
|
|
|
|
|
{SEQ_SIDE_BOTH, "BOTH", 0, "Both", ""},
|
|
|
|
|
{SEQ_SIDE_NO_CHANGE, "NO_CHANGE", 0, "No Change", ""},
|
|
|
|
|
{0, NULL, 0, NULL, NULL},
|
|
|
|
|
};
|
|
|
|
|
|
2020-02-16 21:39:12 +01:00
|
|
|
static int sequencer_split_exec(bContext *C, wmOperator *op)
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
{
|
2019-06-11 10:55:13 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2020-11-19 05:26:57 +01:00
|
|
|
bool changed = false;
|
2020-01-22 14:54:44 +01:00
|
|
|
bool seq_selected = false;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-19 05:26:57 +01:00
|
|
|
const int split_frame = RNA_int_get(op->ptr, "frame");
|
|
|
|
|
const int split_channel = RNA_int_get(op->ptr, "channel");
|
|
|
|
|
const bool use_cursor_position = RNA_boolean_get(op->ptr, "use_cursor_position");
|
|
|
|
|
const eSeqSplitMethod method = RNA_enum_get(op->ptr, "type");
|
|
|
|
|
const int split_side = RNA_enum_get(op->ptr, "side");
|
|
|
|
|
const bool ignore_selection = RNA_boolean_get(op->ptr, "ignore_selection");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_prefetch_stop(scene);
|
2020-07-29 15:02:44 +02:00
|
|
|
|
2021-01-26 17:46:34 +01:00
|
|
|
LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
|
|
|
|
|
seq->tmp = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-19 05:26:57 +01:00
|
|
|
LISTBASE_FOREACH_BACKWARD (Sequence *, seq, ed->seqbasep) {
|
|
|
|
|
if (use_cursor_position && seq->machine != split_channel) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ignore_selection || seq->flag & SELECT) {
|
|
|
|
|
if (SEQ_edit_strip_split(bmain, scene, ed->seqbasep, seq, split_frame, method) != NULL) {
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
}
|
2020-11-19 05:26:57 +01:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
if (changed) { /* Got new strips? */
|
2020-01-22 14:54:44 +01:00
|
|
|
if (ignore_selection) {
|
|
|
|
|
if (use_cursor_position) {
|
2021-03-31 09:27:31 +02:00
|
|
|
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
|
2020-02-16 21:39:12 +01:00
|
|
|
if (seq->enddisp == split_frame && seq->machine == split_channel) {
|
2020-01-22 14:54:44 +01:00
|
|
|
seq_selected = seq->flag & SEQ_ALLSEL;
|
2009-01-31 09:58:38 +00:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
2020-01-22 14:54:44 +01:00
|
|
|
if (!seq_selected) {
|
2021-03-31 09:27:31 +02:00
|
|
|
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
|
2020-02-16 21:39:12 +01:00
|
|
|
if (seq->startdisp == split_frame && seq->machine == split_channel) {
|
2020-01-22 14:54:44 +01:00
|
|
|
seq->flag &= ~SEQ_ALLSEL;
|
|
|
|
|
}
|
2009-01-31 09:58:38 +00:00
|
|
|
}
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-01-22 14:54:44 +01:00
|
|
|
else {
|
2020-02-16 21:39:12 +01:00
|
|
|
if (split_side != SEQ_SIDE_BOTH) {
|
2021-03-31 09:27:31 +02:00
|
|
|
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
|
2020-02-16 21:39:12 +01:00
|
|
|
if (split_side == SEQ_SIDE_LEFT) {
|
|
|
|
|
if (seq->startdisp >= split_frame) {
|
2020-01-22 14:54:44 +01:00
|
|
|
seq->flag &= ~SEQ_ALLSEL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2020-02-16 21:39:12 +01:00
|
|
|
if (seq->enddisp <= split_frame) {
|
2020-01-22 14:54:44 +01:00
|
|
|
seq->flag &= ~SEQ_ALLSEL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-04-05 23:55:51 +02:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_sort(scene);
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
if (changed) {
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2011-09-20 08:48:48 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
2020-07-03 17:20:58 +02:00
|
|
|
|
|
|
|
|
/* Passthrough to selection if used as tool. */
|
|
|
|
|
return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
}
|
|
|
|
|
|
2020-02-16 21:39:12 +01:00
|
|
|
static int sequencer_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
{
|
2009-01-24 06:08:46 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2012-03-29 22:26:11 +00:00
|
|
|
View2D *v2d = UI_view2d_fromcontext(C);
|
2010-05-19 08:44:38 +00:00
|
|
|
|
2020-02-16 21:39:12 +01:00
|
|
|
int split_side = RNA_enum_get(op->ptr, "side");
|
|
|
|
|
int split_frame = CFRA;
|
2010-05-19 08:44:38 +00:00
|
|
|
|
2020-02-16 21:39:12 +01:00
|
|
|
if (split_side == SEQ_SIDE_MOUSE) {
|
2018-09-05 11:56:31 +10:00
|
|
|
if (ED_operator_sequencer_active(C) && v2d) {
|
2020-02-16 21:39:12 +01:00
|
|
|
split_side = mouse_frame_side(v2d, event->mval[0], split_frame);
|
2018-09-05 11:56:31 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2020-02-16 21:39:12 +01:00
|
|
|
split_side = SEQ_SIDE_BOTH;
|
2018-09-05 11:56:31 +10:00
|
|
|
}
|
|
|
|
|
}
|
2020-01-22 14:54:44 +01:00
|
|
|
float mouseloc[2];
|
|
|
|
|
UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &mouseloc[0], &mouseloc[1]);
|
|
|
|
|
if (RNA_boolean_get(op->ptr, "use_cursor_position")) {
|
|
|
|
|
RNA_int_set(op->ptr, "frame", mouseloc[0]);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2020-02-16 21:39:12 +01:00
|
|
|
RNA_int_set(op->ptr, "frame", split_frame);
|
2020-01-22 14:54:44 +01:00
|
|
|
}
|
|
|
|
|
RNA_int_set(op->ptr, "channel", mouseloc[1]);
|
2020-02-16 21:39:12 +01:00
|
|
|
RNA_enum_set(op->ptr, "side", split_side);
|
2020-04-05 23:55:51 +02:00
|
|
|
/*RNA_enum_set(op->ptr, "type", split_hard); */
|
|
|
|
|
|
2020-02-16 21:39:12 +01:00
|
|
|
return sequencer_split_exec(C, op);
|
2009-01-12 19:02:08 +00:00
|
|
|
}
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
|
2021-04-19 23:43:55 +10:00
|
|
|
static void sequencer_split_ui(bContext *C, wmOperator *op)
|
2020-08-19 13:36:55 +02:00
|
|
|
{
|
|
|
|
|
uiLayout *layout = op->layout;
|
2021-04-19 23:43:55 +10:00
|
|
|
wmWindowManager *wm = CTX_wm_manager(C);
|
2020-08-19 13:36:55 +02:00
|
|
|
uiLayoutSetPropSep(layout, true);
|
|
|
|
|
uiLayoutSetPropDecorate(layout, false);
|
|
|
|
|
|
|
|
|
|
PointerRNA ptr;
|
2021-04-19 23:43:55 +10:00
|
|
|
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
|
2020-08-19 13:36:55 +02:00
|
|
|
|
|
|
|
|
uiLayout *row = uiLayoutRow(layout, false);
|
|
|
|
|
uiItemR(row, &ptr, "type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
|
|
|
|
|
uiItemR(layout, &ptr, "frame", 0, NULL, ICON_NONE);
|
|
|
|
|
uiItemR(layout, &ptr, "side", 0, NULL, ICON_NONE);
|
|
|
|
|
|
|
|
|
|
uiItemS(layout);
|
|
|
|
|
|
|
|
|
|
uiItemR(layout, &ptr, "use_cursor_position", 0, NULL, ICON_NONE);
|
|
|
|
|
if (RNA_boolean_get(&ptr, "use_cursor_position")) {
|
|
|
|
|
uiItemR(layout, &ptr, "channel", 0, NULL, ICON_NONE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-16 21:39:12 +01:00
|
|
|
void SEQUENCER_OT_split(struct wmOperatorType *ot)
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2020-02-16 21:39:12 +01:00
|
|
|
ot->name = "Split Strips";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_split";
|
|
|
|
|
ot->description = "Split the selected strips in two";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2020-02-16 21:39:12 +01:00
|
|
|
ot->invoke = sequencer_split_invoke;
|
|
|
|
|
ot->exec = sequencer_split_exec;
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = sequencer_edit_poll;
|
2020-08-19 13:36:55 +02:00
|
|
|
ot->ui = sequencer_split_ui;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-09-05 11:56:31 +10:00
|
|
|
PropertyRNA *prop;
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
RNA_def_int(ot->srna,
|
|
|
|
|
"frame",
|
|
|
|
|
0,
|
|
|
|
|
INT_MIN,
|
|
|
|
|
INT_MAX,
|
|
|
|
|
"Frame",
|
2020-02-16 21:39:12 +01:00
|
|
|
"Frame where selected strips will be split",
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
INT_MIN,
|
|
|
|
|
INT_MAX);
|
2020-01-22 14:54:44 +01:00
|
|
|
RNA_def_int(ot->srna,
|
|
|
|
|
"channel",
|
|
|
|
|
0,
|
|
|
|
|
INT_MIN,
|
|
|
|
|
INT_MAX,
|
|
|
|
|
"Channel",
|
|
|
|
|
"Channel in which strip will be cut",
|
|
|
|
|
INT_MIN,
|
|
|
|
|
INT_MAX);
|
2009-09-12 17:16:12 +00:00
|
|
|
RNA_def_enum(ot->srna,
|
|
|
|
|
"type",
|
2020-02-16 21:39:12 +01:00
|
|
|
prop_split_types,
|
|
|
|
|
SEQ_SPLIT_SOFT,
|
2009-09-12 17:16:12 +00:00
|
|
|
"Type",
|
2020-02-16 21:39:12 +01:00
|
|
|
"The type of split operation to perform on strips");
|
|
|
|
|
|
2020-01-22 14:54:44 +01:00
|
|
|
RNA_def_boolean(ot->srna,
|
|
|
|
|
"use_cursor_position",
|
|
|
|
|
0,
|
|
|
|
|
"Use Cursor Position",
|
2020-06-01 14:41:12 +10:00
|
|
|
"Split at position of the cursor instead of current frame");
|
2020-02-16 21:39:12 +01:00
|
|
|
|
2018-09-05 11:56:31 +10:00
|
|
|
prop = RNA_def_enum(ot->srna,
|
|
|
|
|
"side",
|
|
|
|
|
prop_side_types,
|
|
|
|
|
SEQ_SIDE_MOUSE,
|
|
|
|
|
"Side",
|
2020-02-16 21:39:12 +01:00
|
|
|
"The side that remains selected after splitting");
|
2020-01-22 14:54:44 +01:00
|
|
|
|
2018-09-05 11:56:31 +10:00
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2020-01-22 14:54:44 +01:00
|
|
|
|
|
|
|
|
prop = RNA_def_boolean(
|
|
|
|
|
ot->srna,
|
|
|
|
|
"ignore_selection",
|
|
|
|
|
false,
|
|
|
|
|
"Ignore Selection",
|
|
|
|
|
"Make cut event if strip is not selected preserving selection state after cut");
|
|
|
|
|
|
|
|
|
|
RNA_def_property_flag(prop, PROP_HIDDEN);
|
Added back some functionality to the sequencer
- removed static vars _last_seq, last_imagename and last_sounddir, replacing them with with vars in the "Editing" struct. didnt manage to get the active sequence to load so currently thats lost when loading.
- removed flag SEQ_ACTIVE
- Added operators cut, mute, unmute, deselect_all, select_invert, select, select_more, select_less, select_pick_linked, select_linked and borderselect.
2009-01-19 21:42:18 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Duplicate Strips Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2020-04-05 23:39:20 +02:00
|
|
|
static int apply_unique_name_fn(Sequence *seq, void *arg_pt)
|
2010-07-07 16:37:41 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = (Scene *)arg_pt;
|
|
|
|
|
char name[sizeof(seq->name) - 2];
|
2010-07-07 16:37:41 +00:00
|
|
|
|
2012-10-14 03:56:47 +00:00
|
|
|
BLI_strncpy_utf8(name, seq->name + 2, sizeof(name));
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
|
|
|
|
|
SEQ_dupe_animdata(scene, name, seq->name + 2);
|
2010-07-07 16:37:41 +00:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-21 18:47:09 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
ListBase nseqbase = {NULL, NULL};
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2019-03-26 21:16:47 +11:00
|
|
|
if (ed == NULL) {
|
2009-01-28 22:36:34 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT, 0);
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (nseqbase.first) {
|
2012-03-29 22:26:11 +00:00
|
|
|
Sequence *seq = nseqbase.first;
|
2020-07-30 14:53:42 +02:00
|
|
|
/* Rely on the nseqbase list being added at the end.
|
2020-12-19 05:57:27 +01:00
|
|
|
* Their UUIDs has been re-generated by the SEQ_sequence_base_dupli_recursive(), */
|
2010-12-21 14:49:34 +00:00
|
|
|
BLI_movelisttolist(ed->seqbasep, &nseqbase);
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2019-03-26 21:16:47 +11:00
|
|
|
for (; seq; seq = seq->next) {
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_iterator_recursive_apply(seq, apply_unique_name_fn, scene);
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2010-02-16 17:58:50 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2010-02-16 17:58:50 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2009-01-21 18:47:09 +00:00
|
|
|
}
|
|
|
|
|
|
2009-07-08 21:41:35 +00:00
|
|
|
void SEQUENCER_OT_duplicate(wmOperatorType *ot)
|
2009-01-21 18:47:09 +00:00
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Duplicate Strips";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_duplicate";
|
|
|
|
|
ot->description = "Duplicate the selected strips";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_add_duplicate_exec;
|
|
|
|
|
ot->poll = ED_operator_sequencer_active;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-01-21 18:47:09 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Erase Strips Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-21 18:47:09 +00:00
|
|
|
{
|
2019-06-07 11:27:34 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_prefetch_stop(scene);
|
2020-08-05 01:40:02 +02:00
|
|
|
|
2021-03-31 09:27:31 +02:00
|
|
|
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
|
2020-07-26 16:07:34 +02:00
|
|
|
if (seq->flag & SELECT) {
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_edit_flag_for_removal(scene, ed->seqbasep, seq);
|
2014-02-20 13:52:49 +06:00
|
|
|
}
|
|
|
|
|
}
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_edit_remove_flagged_sequences(scene, ed->seqbasep);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
2019-06-07 11:27:34 +02:00
|
|
|
DEG_relations_tag_update(bmain);
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2009-01-21 18:47:09 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int sequencer_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
2012-08-27 09:15:48 +00:00
|
|
|
{
|
2020-03-06 16:56:42 +01:00
|
|
|
ARegion *region = CTX_wm_region(C);
|
2012-08-27 09:15:48 +00:00
|
|
|
|
2020-03-06 16:56:42 +01:00
|
|
|
if (region->regiontype == RGN_TYPE_WINDOW) {
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Bounding box of 30 pixels is used for markers shortcuts,
|
|
|
|
|
* prevent conflict with markers shortcuts here.
|
2012-08-27 09:15:48 +00:00
|
|
|
*/
|
2019-03-26 21:16:47 +11:00
|
|
|
if (event->mval[1] <= 30) {
|
2012-08-27 09:15:48 +00:00
|
|
|
return OPERATOR_PASS_THROUGH;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2012-08-27 09:15:48 +00:00
|
|
|
}
|
|
|
|
|
|
2020-05-29 09:53:52 -04:00
|
|
|
return sequencer_delete_exec(C, op);
|
2012-08-27 09:15:48 +00:00
|
|
|
}
|
2009-01-21 18:47:09 +00:00
|
|
|
|
|
|
|
|
void SEQUENCER_OT_delete(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Erase Strips";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_delete";
|
|
|
|
|
ot->description = "Erase selected strips from the sequencer";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-08-27 09:15:48 +00:00
|
|
|
ot->invoke = sequencer_delete_invoke;
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_delete_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-01-21 18:47:09 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Clear Strip Offset Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2011-08-14 03:59:22 +00:00
|
|
|
static int sequencer_offset_clear_exec(bContext *C, wmOperator *UNUSED(op))
|
|
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2011-08-14 03:59:22 +00:00
|
|
|
Sequence *seq;
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* For effects, try to find a replacement input. */
|
2012-03-29 22:26:11 +00:00
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
2012-06-07 15:49:02 +00:00
|
|
|
if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
|
2012-03-29 22:26:11 +00:00
|
|
|
seq->startofs = seq->endofs = seq->startstill = seq->endstill = 0;
|
2011-08-14 03:59:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Update lengths, etc. */
|
2012-03-29 22:26:11 +00:00
|
|
|
seq = ed->seqbasep->first;
|
2012-03-24 06:38:07 +00:00
|
|
|
while (seq) {
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_time_update_sequence(scene, seq);
|
2012-03-29 22:26:11 +00:00
|
|
|
seq = seq->next;
|
2011-08-14 03:59:22 +00:00
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
2012-06-07 15:49:02 +00:00
|
|
|
if ((seq->type & SEQ_TYPE_EFFECT) == 0 && (seq->flag & SELECT)) {
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
|
|
|
|
|
SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene);
|
2011-08-14 03:59:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2011-08-14 03:59:22 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_offset_clear(wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Clear Strip Offset";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_offset_clear";
|
|
|
|
|
ot->description = "Clear strip offsets from the start and end frames";
|
2011-08-14 03:59:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_offset_clear_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2011-08-14 03:59:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2011-08-14 03:59:22 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Separate Images Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2009-01-21 18:47:09 +00:00
|
|
|
static int sequencer_separate_images_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2011-01-09 01:17:56 +00:00
|
|
|
Sequence *seq, *seq_new;
|
2009-01-21 18:47:09 +00:00
|
|
|
Strip *strip_new;
|
|
|
|
|
StripElem *se, *se_new;
|
2020-11-06 14:10:59 +01:00
|
|
|
int start_ofs, timeline_frame, frame_end;
|
2012-03-29 22:26:11 +00:00
|
|
|
int step = RNA_int_get(op->ptr, "length");
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
seq = ed->seqbasep->first; /* Poll checks this is valid. */
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_prefetch_stop(scene);
|
2020-08-17 20:19:11 +02:00
|
|
|
|
2009-01-21 18:47:09 +00:00
|
|
|
while (seq) {
|
2012-06-07 15:49:02 +00:00
|
|
|
if ((seq->flag & SELECT) && (seq->type == SEQ_TYPE_IMAGE) && (seq->len > 1)) {
|
2014-03-18 22:45:33 +06:00
|
|
|
Sequence *seq_next;
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Remove seq so overlap tests don't conflict,
|
2019-04-10 08:40:49 +02:00
|
|
|
* see seq_free_sequence below for the real freeing. */
|
2009-01-21 18:47:09 +00:00
|
|
|
BLI_remlink(ed->seqbasep, seq);
|
2015-11-09 19:47:10 +01:00
|
|
|
/* if (seq->ipo) id_us_min(&seq->ipo->id); */
|
2010-07-03 17:47:06 +00:00
|
|
|
/* XXX, remove fcurve and assign to split image strips */
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
start_ofs = timeline_frame = SEQ_transform_get_left_handle_frame(seq, false);
|
|
|
|
|
frame_end = SEQ_transform_get_right_handle_frame(seq, false);
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2020-11-06 14:10:59 +01:00
|
|
|
while (timeline_frame < frame_end) {
|
2020-04-05 23:55:51 +02:00
|
|
|
/* New seq. */
|
2020-11-06 14:10:59 +01:00
|
|
|
se = SEQ_render_give_stripelem(seq, timeline_frame);
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
seq_new = SEQ_sequence_dupli_recursive(
|
2019-01-11 19:48:56 +01:00
|
|
|
scene, scene, ed->seqbasep, seq, SEQ_DUPE_UNIQUE_NAME);
|
2011-07-06 10:58:23 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
seq_new->start = start_ofs;
|
2012-06-07 15:49:02 +00:00
|
|
|
seq_new->type = SEQ_TYPE_IMAGE;
|
2009-01-21 18:47:09 +00:00
|
|
|
seq_new->len = 1;
|
2012-03-29 22:26:11 +00:00
|
|
|
seq_new->endstill = step - 1;
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* New strip. */
|
2012-03-29 22:26:11 +00:00
|
|
|
strip_new = seq_new->strip;
|
|
|
|
|
strip_new->us = 1;
|
2009-01-21 18:47:09 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* New stripdata, only one element now. */
|
2019-01-15 23:24:20 +11:00
|
|
|
/* Note this assume all elements (images) have the same dimension,
|
|
|
|
|
* since we only copy the name here. */
|
2014-07-21 22:55:06 +02:00
|
|
|
se_new = MEM_reallocN(strip_new->stripdata, sizeof(*se_new));
|
2011-01-09 01:17:56 +00:00
|
|
|
BLI_strncpy(se_new->name, se->name, sizeof(se_new->name));
|
2014-07-21 22:55:06 +02:00
|
|
|
strip_new->stripdata = se_new;
|
|
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_time_update_sequence(scene, seq_new);
|
2010-07-03 17:47:06 +00:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (step > 1) {
|
2010-07-03 17:47:06 +00:00
|
|
|
seq_new->flag &= ~SEQ_OVERLAP;
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_transform_test_overlap(ed->seqbasep, seq_new)) {
|
|
|
|
|
SEQ_transform_seqbase_shuffle(ed->seqbasep, seq_new, scene);
|
2010-07-03 17:47:06 +00:00
|
|
|
}
|
2009-01-21 18:47:09 +00:00
|
|
|
}
|
|
|
|
|
|
2010-07-03 17:47:06 +00:00
|
|
|
/* XXX, COPY FCURVES */
|
2009-12-13 03:20:29 +00:00
|
|
|
|
2020-11-06 14:10:59 +01:00
|
|
|
timeline_frame++;
|
2009-01-21 18:47:09 +00:00
|
|
|
start_ofs += step;
|
|
|
|
|
}
|
|
|
|
|
|
2014-03-18 22:45:33 +06:00
|
|
|
seq_next = seq->next;
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_sequence_free(scene, seq, true);
|
2014-03-18 22:45:33 +06:00
|
|
|
seq = seq_next;
|
2012-03-24 06:38:07 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2009-01-21 18:47:09 +00:00
|
|
|
seq = seq->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_sort(scene);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2009-01-21 18:47:09 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-12 20:32:42 +00:00
|
|
|
void SEQUENCER_OT_images_separate(wmOperatorType *ot)
|
2009-01-21 18:47:09 +00:00
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Separate Images";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_images_separate";
|
|
|
|
|
ot->description = "On image sequence strips, it returns a strip for each image";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_separate_images_exec;
|
2016-02-12 00:42:37 +11:00
|
|
|
ot->invoke = WM_operator_props_popup_confirm;
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-10-19 21:34:38 +00:00
|
|
|
|
2012-10-11 23:46:12 +00:00
|
|
|
RNA_def_int(ot->srna, "length", 1, 1, INT_MAX, "Length", "Length of each frame", 1, 1000);
|
2009-01-21 18:47:09 +00:00
|
|
|
}
|
2009-01-23 23:14:02 +00:00
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Toggle Meta Strip Operator
|
|
|
|
|
* \{ */
|
2009-01-23 23:14:02 +00:00
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-23 23:14:02 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2021-03-02 12:34:03 +01:00
|
|
|
Sequence *active_seq = SEQ_select_active_get(scene);
|
2009-01-23 23:14:02 +00:00
|
|
|
|
2021-03-02 12:34:03 +01:00
|
|
|
if (active_seq && active_seq->type == SEQ_TYPE_META && active_seq->flag & SELECT) {
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Enter metastrip. */
|
2021-03-02 12:34:03 +01:00
|
|
|
SEQ_meta_stack_alloc(ed, active_seq);
|
|
|
|
|
SEQ_seqbase_active_set(ed, &active_seq->seqbase);
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_select_active_set(scene, NULL);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Exit metastrip if possible. */
|
2009-01-23 23:14:02 +00:00
|
|
|
if (BLI_listbase_is_empty(&ed->metastack)) {
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2009-01-23 23:14:02 +00:00
|
|
|
|
2021-03-02 12:34:03 +01:00
|
|
|
MetaStack *ms = SEQ_meta_stack_active_get(ed);
|
|
|
|
|
SEQ_seqbase_active_set(ed, ms->oldbasep);
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_select_active_set(scene, ms->parseq);
|
2021-03-02 12:34:03 +01:00
|
|
|
SEQ_meta_stack_free(ed, ms);
|
2009-01-23 23:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2009-12-08 13:57:51 +00:00
|
|
|
|
2009-01-23 23:14:02 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_meta_toggle(wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Toggle Meta Strip";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_meta_toggle";
|
|
|
|
|
ot->description = "Toggle a metastrip (to edit enclosed strips)";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_meta_toggle_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-01-23 23:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Make Meta Strip Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2009-01-23 23:14:02 +00:00
|
|
|
static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2021-03-02 12:34:03 +01:00
|
|
|
Sequence *active_seq = SEQ_select_active_get(scene);
|
|
|
|
|
ListBase *active_seqbase = SEQ_active_seqbase_get(ed);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2021-03-02 12:34:03 +01:00
|
|
|
if (SEQ_transform_seqbase_isolated_sel_check(active_seqbase) == false) {
|
2014-11-06 14:06:24 +01:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
|
2009-01-23 23:14:02 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_prefetch_stop(scene);
|
2020-08-17 20:19:11 +02:00
|
|
|
|
2021-03-02 12:34:03 +01:00
|
|
|
int channel_max = 1, meta_start_frame = MAXFRAME, meta_end_frame = MINFRAME;
|
|
|
|
|
Sequence *seqm = SEQ_sequence_alloc(active_seqbase, 1, 1, SEQ_TYPE_META);
|
2009-01-23 23:14:02 +00:00
|
|
|
|
2021-03-02 12:34:03 +01:00
|
|
|
/* Remove all selected from main list, and put in meta.
|
|
|
|
|
* Sequence is moved within the same edit, no need to re-generate the UUID. */
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (Sequence *, seq, active_seqbase) {
|
|
|
|
|
if (seq != seqm && seq->flag & SELECT) {
|
|
|
|
|
BLI_remlink(active_seqbase, seq);
|
2009-01-23 23:14:02 +00:00
|
|
|
BLI_addtail(&seqm->seqbase, seq);
|
2021-03-02 12:34:03 +01:00
|
|
|
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
|
|
|
|
|
channel_max = max_ii(seq->machine, channel_max);
|
|
|
|
|
meta_start_frame = min_ii(seq->startdisp, meta_start_frame);
|
|
|
|
|
meta_end_frame = max_ii(seq->enddisp, meta_end_frame);
|
2009-01-23 23:14:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-02 12:34:03 +01:00
|
|
|
seqm->machine = active_seq ? active_seq->machine : channel_max;
|
|
|
|
|
strcpy(seqm->name + 2, "MetaStrip");
|
|
|
|
|
SEQ_sequence_base_unique_name_recursive(&ed->seqbase, seqm);
|
|
|
|
|
seqm->start = meta_start_frame;
|
|
|
|
|
seqm->len = meta_end_frame - meta_start_frame;
|
|
|
|
|
SEQ_time_update_sequence(scene, seqm);
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_select_active_set(scene, seqm);
|
2021-03-02 12:34:03 +01:00
|
|
|
if (SEQ_transform_test_overlap(active_seqbase, seqm)) {
|
|
|
|
|
SEQ_transform_seqbase_shuffle(active_seqbase, seqm, scene);
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2009-01-23 23:14:02 +00:00
|
|
|
|
2019-06-04 16:52:48 +02:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2009-12-08 13:57:51 +00:00
|
|
|
|
2009-01-23 23:14:02 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_meta_make(wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Make Meta Strip";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_meta_make";
|
|
|
|
|
ot->description = "Group selected strips into a metastrip";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_meta_make_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-01-23 23:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name UnMeta Strip Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2013-11-26 00:38:50 +01:00
|
|
|
static int sequencer_meta_separate_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-01-23 23:14:02 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2021-03-02 12:34:03 +01:00
|
|
|
Sequence *active_seq = SEQ_select_active_get(scene);
|
2009-01-23 23:14:02 +00:00
|
|
|
|
2021-03-02 12:34:03 +01:00
|
|
|
if (active_seq == NULL || active_seq->type != SEQ_TYPE_META) {
|
2009-01-23 23:14:02 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2009-01-23 23:14:02 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_prefetch_stop(scene);
|
2020-08-17 20:19:11 +02:00
|
|
|
|
2021-03-02 12:34:03 +01:00
|
|
|
LISTBASE_FOREACH (Sequence *, seq, &active_seq->seqbase) {
|
|
|
|
|
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
|
2014-06-04 22:05:33 +06:00
|
|
|
}
|
|
|
|
|
|
2021-03-02 12:34:03 +01:00
|
|
|
/* Remove all selected from meta, and put in main list.
|
|
|
|
|
* Sequence is moved within the same edit, no need to re-generate the UUID. */
|
|
|
|
|
BLI_movelisttolist(ed->seqbasep, &active_seq->seqbase);
|
|
|
|
|
BLI_listbase_clear(&active_seq->seqbase);
|
2009-01-23 23:14:02 +00:00
|
|
|
|
2021-03-02 12:34:03 +01:00
|
|
|
ListBase *active_seqbase = SEQ_active_seqbase_get(ed);
|
|
|
|
|
SEQ_edit_flag_for_removal(scene, active_seqbase, active_seq);
|
|
|
|
|
SEQ_edit_remove_flagged_sequences(scene, active_seqbase);
|
2009-01-23 23:14:02 +00:00
|
|
|
|
2021-03-02 12:34:03 +01:00
|
|
|
/* Test for effects and overlap. */
|
|
|
|
|
LISTBASE_FOREACH (Sequence *, seq, active_seqbase) {
|
2012-03-24 06:38:07 +00:00
|
|
|
if (seq->flag & SELECT) {
|
2009-01-23 23:14:02 +00:00
|
|
|
seq->flag &= ~SEQ_OVERLAP;
|
2021-03-02 12:34:03 +01:00
|
|
|
if (SEQ_transform_test_overlap(active_seqbase, seq)) {
|
|
|
|
|
SEQ_transform_seqbase_shuffle(active_seqbase, seq, scene);
|
2009-01-23 23:14:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_sort(scene);
|
2019-06-04 16:52:48 +02:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2009-01-23 23:14:02 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_meta_separate(wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "UnMeta Strip";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_meta_separate";
|
|
|
|
|
ot->description = "Put the contents of a metastrip back in the sequencer";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_meta_separate_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-01-23 23:14:02 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Jump to Strip Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2013-11-26 06:39:14 +11:00
|
|
|
static bool strip_jump_internal(Scene *scene,
|
|
|
|
|
const short side,
|
2014-02-03 18:55:59 +11:00
|
|
|
const bool do_skip_mute,
|
|
|
|
|
const bool do_center)
|
2009-10-29 10:03:34 +00:00
|
|
|
{
|
2013-11-26 06:39:14 +11:00
|
|
|
bool changed = false;
|
2020-11-06 14:10:59 +01:00
|
|
|
int timeline_frame = CFRA;
|
2020-12-19 05:57:27 +01:00
|
|
|
int next_frame = SEQ_time_find_next_prev_edit(
|
2020-11-06 14:10:59 +01:00
|
|
|
scene, timeline_frame, side, do_skip_mute, do_center, false);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-11-06 14:10:59 +01:00
|
|
|
if (next_frame != timeline_frame) {
|
|
|
|
|
CFRA = next_frame;
|
2013-11-26 06:39:14 +11:00
|
|
|
changed = true;
|
2009-10-28 19:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
2013-11-26 06:39:14 +11:00
|
|
|
return changed;
|
2009-10-28 19:53:25 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-02 11:47:00 +02:00
|
|
|
static bool sequencer_strip_jump_poll(bContext *C)
|
2012-12-06 05:48:51 +00:00
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Prevent changes during render. */
|
2019-03-26 21:16:47 +11:00
|
|
|
if (G.is_rendering) {
|
2012-12-06 05:48:51 +00:00
|
|
|
return 0;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2012-12-06 05:48:51 +00:00
|
|
|
|
|
|
|
|
return sequencer_edit_poll(C);
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-23 07:39:51 +00:00
|
|
|
static int sequencer_strip_jump_exec(bContext *C, wmOperator *op)
|
2009-10-28 19:53:25 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2014-02-03 18:55:59 +11:00
|
|
|
const bool next = RNA_boolean_get(op->ptr, "next");
|
|
|
|
|
const bool center = RNA_boolean_get(op->ptr, "center");
|
2009-10-28 19:53:25 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Currently do_skip_mute is always true. */
|
2014-03-20 15:45:20 +06:00
|
|
|
if (!strip_jump_internal(scene, next ? SEQ_SIDE_RIGHT : SEQ_SIDE_LEFT, true, center)) {
|
2009-12-08 13:57:51 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2012-08-23 08:10:45 +00:00
|
|
|
}
|
2009-12-08 13:57:51 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2009-10-28 19:53:25 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-23 07:39:51 +00:00
|
|
|
void SEQUENCER_OT_strip_jump(wmOperatorType *ot)
|
2009-10-28 19:53:25 +00:00
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-08-23 07:39:51 +00:00
|
|
|
ot->name = "Jump to Strip";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_strip_jump";
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->description = "Move frame to previous edit point";
|
2012-08-23 08:10:45 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-08-23 07:39:51 +00:00
|
|
|
ot->exec = sequencer_strip_jump_exec;
|
2012-12-06 05:48:51 +00:00
|
|
|
ot->poll = sequencer_strip_jump_poll;
|
2012-08-23 08:10:45 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2020-01-22 02:07:54 +01:00
|
|
|
ot->flag = OPTYPE_UNDO;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Properties. */
|
2014-04-01 11:34:00 +11:00
|
|
|
RNA_def_boolean(ot->srna, "next", true, "Next Strip", "");
|
2020-12-24 11:07:32 -06:00
|
|
|
RNA_def_boolean(ot->srna, "center", true, "Use Strip Center", "");
|
2009-10-30 20:40:41 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Swap Strip Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
static const EnumPropertyItem prop_side_lr_types[] = {
|
|
|
|
|
{SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""},
|
|
|
|
|
{SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""},
|
|
|
|
|
{0, NULL, 0, NULL, NULL},
|
|
|
|
|
};
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
static void swap_sequence(Scene *scene, Sequence *seqa, Sequence *seqb)
|
2009-10-30 20:40:41 +00:00
|
|
|
{
|
|
|
|
|
int gap = seqb->startdisp - seqa->enddisp;
|
2013-02-03 12:19:14 +00:00
|
|
|
int seq_a_start;
|
|
|
|
|
int seq_b_start;
|
|
|
|
|
|
|
|
|
|
seq_b_start = (seqb->start - seqb->startdisp) + seqa->startdisp;
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_transform_translate_sequence(scene, seqb, seq_b_start - seqb->start);
|
|
|
|
|
SEQ_time_update_sequence(scene, seqb);
|
2013-02-03 12:19:14 +00:00
|
|
|
|
|
|
|
|
seq_a_start = (seqa->start - seqa->startdisp) + seqb->enddisp + gap;
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_transform_translate_sequence(scene, seqa, seq_a_start - seqa->start);
|
|
|
|
|
SEQ_time_update_sequence(scene, seqa);
|
2009-10-30 20:40:41 +00:00
|
|
|
}
|
|
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
static Sequence *find_next_prev_sequence(Scene *scene, Sequence *test, int lr, int sel)
|
2009-10-30 20:40:41 +00:00
|
|
|
{
|
2020-11-19 12:59:29 +01:00
|
|
|
/* sel: 0==unselected, 1==selected, -1==don't care. */
|
|
|
|
|
Sequence *seq, *best_seq = NULL;
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2020-11-19 12:59:29 +01:00
|
|
|
|
|
|
|
|
int dist, best_dist;
|
|
|
|
|
best_dist = MAXFRAME * 2;
|
2009-10-30 20:40:41 +00:00
|
|
|
|
2019-05-31 23:21:16 +10:00
|
|
|
if (ed == NULL) {
|
2019-04-17 08:24:14 +02:00
|
|
|
return NULL;
|
2019-05-31 23:21:16 +10:00
|
|
|
}
|
2009-10-30 20:40:41 +00:00
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
seq = ed->seqbasep->first;
|
|
|
|
|
while (seq) {
|
|
|
|
|
if ((seq != test) && (test->machine == seq->machine) && (test->depth == seq->depth) &&
|
|
|
|
|
((sel == -1) || (sel == (seq->flag & SELECT)))) {
|
|
|
|
|
dist = MAXFRAME * 2;
|
|
|
|
|
|
|
|
|
|
switch (lr) {
|
|
|
|
|
case SEQ_SIDE_LEFT:
|
|
|
|
|
if (seq->enddisp <= test->startdisp) {
|
|
|
|
|
dist = test->enddisp - seq->startdisp;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case SEQ_SIDE_RIGHT:
|
|
|
|
|
if (seq->startdisp >= test->enddisp) {
|
|
|
|
|
dist = seq->startdisp - test->enddisp;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dist == 0) {
|
|
|
|
|
best_seq = seq;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (dist < best_dist) {
|
|
|
|
|
best_dist = dist;
|
|
|
|
|
best_seq = seq;
|
|
|
|
|
}
|
2009-10-30 20:40:41 +00:00
|
|
|
}
|
2020-11-19 12:59:29 +01:00
|
|
|
seq = seq->next;
|
2009-10-30 20:40:41 +00:00
|
|
|
}
|
2020-11-19 12:59:29 +01:00
|
|
|
return best_seq; /* Can be null. */
|
|
|
|
|
}
|
2009-10-30 20:40:41 +00:00
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
static bool seq_is_parent(Sequence *par, Sequence *seq)
|
|
|
|
|
{
|
|
|
|
|
return ((par->seq1 == seq) || (par->seq2 == seq) || (par->seq3 == seq));
|
2009-10-30 20:40:41 +00:00
|
|
|
}
|
|
|
|
|
|
2009-12-15 10:04:54 +00:00
|
|
|
static int sequencer_swap_exec(bContext *C, wmOperator *op)
|
2009-10-30 20:40:41 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
|
|
|
|
Sequence *active_seq = SEQ_select_active_get(scene);
|
2009-12-13 15:48:57 +00:00
|
|
|
Sequence *seq, *iseq;
|
2012-03-29 22:26:11 +00:00
|
|
|
int side = RNA_enum_get(op->ptr, "side");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-26 21:16:47 +11:00
|
|
|
if (active_seq == NULL) {
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-10-30 20:40:41 +00:00
|
|
|
seq = find_next_prev_sequence(scene, active_seq, side, -1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (seq) {
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Disallow effect strips. */
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_effect_get_num_inputs(seq->type) >= 1 &&
|
2019-03-26 21:16:47 +11:00
|
|
|
(seq->effectdata || seq->seq1 || seq->seq2 || seq->seq3)) {
|
2009-10-30 20:40:41 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2020-12-19 05:57:27 +01:00
|
|
|
if ((SEQ_effect_get_num_inputs(active_seq->type) >= 1) &&
|
2019-03-26 21:16:47 +11:00
|
|
|
(active_seq->effectdata || active_seq->seq1 || active_seq->seq2 || active_seq->seq3)) {
|
2009-10-30 20:40:41 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-10-30 20:40:41 +00:00
|
|
|
switch (side) {
|
2018-06-04 09:31:30 +02:00
|
|
|
case SEQ_SIDE_LEFT:
|
2010-02-07 23:41:17 +00:00
|
|
|
swap_sequence(scene, seq, active_seq);
|
2009-10-30 20:40:41 +00:00
|
|
|
break;
|
2018-06-04 09:31:30 +02:00
|
|
|
case SEQ_SIDE_RIGHT:
|
2010-02-07 23:41:17 +00:00
|
|
|
swap_sequence(scene, active_seq, seq);
|
2009-10-30 20:40:41 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* XXX - Should be a generic function. */
|
2012-03-29 22:26:11 +00:00
|
|
|
for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) {
|
2012-06-07 15:49:02 +00:00
|
|
|
if ((iseq->type & SEQ_TYPE_EFFECT) &&
|
|
|
|
|
(seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_time_update_sequence(scene, iseq);
|
2009-12-15 11:27:46 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Do this in a new loop since both effects need to be calculated first. */
|
2012-03-29 22:26:11 +00:00
|
|
|
for (iseq = scene->ed->seqbasep->first; iseq; iseq = iseq->next) {
|
2012-06-07 15:49:02 +00:00
|
|
|
if ((iseq->type & SEQ_TYPE_EFFECT) &&
|
|
|
|
|
(seq_is_parent(iseq, active_seq) || seq_is_parent(iseq, seq))) {
|
2020-04-05 23:55:51 +02:00
|
|
|
/* This may now overlap. */
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_transform_test_overlap(ed->seqbasep, iseq)) {
|
|
|
|
|
SEQ_transform_seqbase_shuffle(ed->seqbasep, iseq, scene);
|
2009-12-13 15:48:57 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_sort(scene);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-12-08 13:57:51 +00:00
|
|
|
return OPERATOR_FINISHED;
|
2009-10-30 20:40:41 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-12-08 13:57:51 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2009-10-30 20:40:41 +00:00
|
|
|
}
|
|
|
|
|
|
2009-12-15 10:04:54 +00:00
|
|
|
void SEQUENCER_OT_swap(wmOperatorType *ot)
|
2009-10-30 20:40:41 +00:00
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Swap Strip";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_swap";
|
|
|
|
|
ot->description = "Swap active strip with strip to the right or left";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_swap_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Properties. */
|
2009-12-15 10:04:54 +00:00
|
|
|
RNA_def_enum(
|
|
|
|
|
ot->srna, "side", prop_side_lr_types, SEQ_SIDE_RIGHT, "Side", "Side of the strip to swap");
|
2009-10-30 21:40:07 +00:00
|
|
|
}
|
2009-11-08 15:03:10 +00:00
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Set Render Size Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op))
|
2009-11-08 15:03:10 +00:00
|
|
|
{
|
|
|
|
|
int retval = OPERATOR_CANCELLED;
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Sequence *active_seq = SEQ_select_active_get(scene);
|
2010-11-28 18:54:43 +00:00
|
|
|
StripElem *se = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-03-26 21:16:47 +11:00
|
|
|
if (active_seq == NULL) {
|
2009-12-15 10:35:50 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-11-28 18:23:21 +00:00
|
|
|
if (active_seq->strip) {
|
|
|
|
|
switch (active_seq->type) {
|
2012-06-07 15:49:02 +00:00
|
|
|
case SEQ_TYPE_IMAGE:
|
2020-11-05 14:05:25 +01:00
|
|
|
se = SEQ_render_give_stripelem(active_seq, scene->r.cfra);
|
2012-03-29 22:26:11 +00:00
|
|
|
break;
|
2012-06-07 15:49:02 +00:00
|
|
|
case SEQ_TYPE_MOVIE:
|
2012-03-29 22:26:11 +00:00
|
|
|
se = active_seq->strip->stripdata;
|
|
|
|
|
break;
|
2012-06-07 15:49:02 +00:00
|
|
|
case SEQ_TYPE_SCENE:
|
|
|
|
|
case SEQ_TYPE_META:
|
|
|
|
|
case SEQ_TYPE_SOUND_RAM:
|
|
|
|
|
case SEQ_TYPE_SOUND_HD:
|
2012-03-29 22:26:11 +00:00
|
|
|
default:
|
|
|
|
|
break;
|
2010-11-28 18:23:21 +00:00
|
|
|
}
|
2009-11-08 15:03:10 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-11-28 18:23:21 +00:00
|
|
|
if (se) {
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Prevent setting the render size if sequence values aren't initialized. */
|
2012-09-09 00:00:21 +00:00
|
|
|
if ((se->orig_width > 0) && (se->orig_height > 0)) {
|
2012-03-29 22:26:11 +00:00
|
|
|
scene->r.xsch = se->orig_width;
|
|
|
|
|
scene->r.ysch = se->orig_height;
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
|
2010-11-28 18:23:21 +00:00
|
|
|
retval = OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2009-11-08 15:03:10 +00:00
|
|
|
return retval;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_rendersize(wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Set Render Size";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_rendersize";
|
|
|
|
|
ot->description = "Set render size and aspect from active sequence";
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_rendersize_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2018-06-04 09:31:30 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-11-11 09:59:51 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Copy Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2012-02-13 17:29:10 +00:00
|
|
|
static void seq_copy_del_sound(Scene *scene, Sequence *seq)
|
2009-12-17 16:28:45 +00:00
|
|
|
{
|
2012-06-07 15:49:02 +00:00
|
|
|
if (seq->type == SEQ_TYPE_META) {
|
2009-12-17 16:28:45 +00:00
|
|
|
Sequence *iseq;
|
2012-03-29 22:26:11 +00:00
|
|
|
for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) {
|
2012-02-13 17:29:10 +00:00
|
|
|
seq_copy_del_sound(scene, iseq);
|
2009-12-17 16:28:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
2012-03-24 06:38:07 +00:00
|
|
|
else if (seq->scene_sound) {
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_remove_scene_sound(scene, seq->scene_sound);
|
2010-02-07 23:41:17 +00:00
|
|
|
seq->scene_sound = NULL;
|
2009-12-17 23:29:11 +00:00
|
|
|
}
|
2009-12-17 16:28:45 +00:00
|
|
|
}
|
|
|
|
|
|
2009-12-17 14:45:47 +00:00
|
|
|
static int sequencer_copy_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2018-12-28 13:37:51 +01:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2009-12-17 14:45:47 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_clipboard_free();
|
2009-12-17 16:28:45 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_transform_seqbase_isolated_sel_check(ed->seqbasep) == false) {
|
2009-12-17 23:29:11 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Please select all related strips");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-30 14:53:42 +02:00
|
|
|
/* NOTE: The UUID is re-generated on paste, so we can keep UUID in the clipboard since
|
|
|
|
|
* nobody can reach them anyway.
|
|
|
|
|
* This reduces chance or running out of UUIDs if a cat falls asleep on Ctrl-C. */
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_sequence_base_dupli_recursive(scene,
|
2020-07-30 14:53:42 +02:00
|
|
|
scene,
|
|
|
|
|
&seqbase_clipboard,
|
|
|
|
|
ed->seqbasep,
|
|
|
|
|
0,
|
|
|
|
|
(LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_FREE_NO_MAIN));
|
2011-03-25 11:45:55 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
seqbase_clipboard_frame = scene->r.cfra;
|
2009-12-17 16:28:45 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Remove anything that references the current scene. */
|
2020-04-03 19:15:01 +02:00
|
|
|
LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) {
|
2018-12-28 13:37:51 +01:00
|
|
|
seq_copy_del_sound(scene, seq);
|
2009-12-17 16:28:45 +00:00
|
|
|
}
|
2009-12-17 14:45:47 +00:00
|
|
|
|
2018-12-28 13:37:51 +01:00
|
|
|
/* Replace datablock pointers with copies, to keep things working in case
|
2019-06-12 09:04:10 +10:00
|
|
|
* data-blocks get deleted or another .blend file is opened. */
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_clipboard_pointers_store(bmain, &seqbase_clipboard);
|
2018-12-28 13:37:51 +01:00
|
|
|
|
2009-12-17 14:45:47 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_copy(wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Copy";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_copy";
|
2019-08-24 00:45:21 +02:00
|
|
|
ot->description = "Copy selected strips to clipboard";
|
2009-12-17 14:45:47 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_copy_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
2009-12-17 14:45:47 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER;
|
2009-12-17 14:45:47 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Paste Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
void ED_sequencer_deselect_all(Scene *scene)
|
|
|
|
|
{
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2020-11-19 12:59:29 +01:00
|
|
|
|
|
|
|
|
if (ed == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-31 09:27:31 +02:00
|
|
|
LISTBASE_FOREACH (Sequence *, seq, SEQ_active_seqbase_get(ed)) {
|
2020-11-19 12:59:29 +01:00
|
|
|
seq->flag &= ~SEQ_ALLSEL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-15 22:01:58 +01:00
|
|
|
static int sequencer_paste_exec(bContext *C, wmOperator *op)
|
2009-12-17 14:45:47 +00:00
|
|
|
{
|
2013-07-24 06:51:04 +00:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, true); /* Create if needed. */
|
2010-06-24 10:04:18 +00:00
|
|
|
ListBase nseqbase = {NULL, NULL};
|
2009-12-17 16:28:45 +00:00
|
|
|
int ofs;
|
2013-07-24 05:01:22 +00:00
|
|
|
Sequence *iseq, *iseq_first;
|
2009-12-17 16:28:45 +00:00
|
|
|
|
2020-12-15 22:01:58 +01:00
|
|
|
if (BLI_listbase_count(&seqbase_clipboard) == 0) {
|
|
|
|
|
BKE_report(op->reports, RPT_INFO, "No strips to paste");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-29 05:45:06 +00:00
|
|
|
ED_sequencer_deselect_all(scene);
|
2020-12-15 22:01:58 +01:00
|
|
|
if (RNA_boolean_get(op->ptr, "keep_offset")) {
|
|
|
|
|
ofs = scene->r.cfra - seqbase_clipboard_frame;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
int min_seq_startdisp = INT_MAX;
|
|
|
|
|
LISTBASE_FOREACH (Sequence *, seq, &seqbase_clipboard) {
|
|
|
|
|
if (seq->startdisp < min_seq_startdisp) {
|
|
|
|
|
min_seq_startdisp = seq->startdisp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Paste strips after playhead. */
|
|
|
|
|
ofs = scene->r.cfra - min_seq_startdisp;
|
|
|
|
|
}
|
2009-12-17 14:45:47 +00:00
|
|
|
|
2019-06-12 09:04:10 +10:00
|
|
|
/* Copy strips, temporarily restoring pointers to actual data-blocks. This
|
2018-12-28 13:37:51 +01:00
|
|
|
* must happen on the clipboard itself, so that copying does user counting
|
2019-06-12 09:04:10 +10:00
|
|
|
* on the actual data-blocks. */
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_clipboard_pointers_restore(&seqbase_clipboard, bmain);
|
|
|
|
|
SEQ_sequence_base_dupli_recursive(scene, scene, &nseqbase, &seqbase_clipboard, 0, 0);
|
|
|
|
|
SEQ_clipboard_pointers_store(bmain, &seqbase_clipboard);
|
2009-12-17 16:28:45 +00:00
|
|
|
|
2013-07-24 05:01:22 +00:00
|
|
|
iseq_first = nseqbase.first;
|
2011-03-25 11:45:55 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
/* NOTE: SEQ_sequence_base_dupli_recursive() takes care of generating new UUIDs for sequences
|
2020-07-30 14:53:42 +02:00
|
|
|
* in the new list. */
|
2010-12-21 14:49:34 +00:00
|
|
|
BLI_movelisttolist(ed->seqbasep, &nseqbase);
|
2009-12-17 16:28:45 +00:00
|
|
|
|
2013-07-24 05:01:22 +00:00
|
|
|
for (iseq = iseq_first; iseq; iseq = iseq->next) {
|
2020-05-10 08:26:24 +02:00
|
|
|
/* Make sure, that pasted strips have unique names. */
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_iterator_recursive_apply(iseq, apply_unique_name_fn, scene);
|
2020-05-10 15:42:06 +02:00
|
|
|
/* Translate after name has been changed, otherwise this will affect animdata of original
|
|
|
|
|
* strip. */
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_transform_translate_sequence(scene, iseq, ofs);
|
2020-05-10 08:26:24 +02:00
|
|
|
/* Ensure, that pasted strips don't overlap. */
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_transform_test_overlap(ed->seqbasep, iseq)) {
|
|
|
|
|
SEQ_transform_seqbase_shuffle(ed->seqbasep, iseq, scene);
|
2013-07-24 05:01:22 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-14 22:47:34 +02:00
|
|
|
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
2020-06-26 16:59:01 +02:00
|
|
|
DEG_relations_tag_update(bmain);
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2020-05-01 20:06:38 -06:00
|
|
|
ED_outliner_select_sync_from_sequence_tag(C);
|
2009-12-17 14:45:47 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_paste(wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Paste";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_paste";
|
2019-08-24 00:45:21 +02:00
|
|
|
ot->description = "Paste strips from clipboard";
|
2009-12-17 14:45:47 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_paste_exec;
|
|
|
|
|
ot->poll = ED_operator_sequencer_active;
|
2009-12-17 14:45:47 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2020-12-15 22:01:58 +01:00
|
|
|
|
|
|
|
|
/* Properties. */
|
|
|
|
|
PropertyRNA *prop = RNA_def_boolean(
|
|
|
|
|
ot->srna, "keep_offset", false, "Keep Offset", "Keep strip offset to playhead when pasting");
|
|
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
2009-12-17 14:45:47 +00:00
|
|
|
}
|
2010-06-21 17:37:50 +00:00
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Sequencer Swap Data Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2010-06-21 17:37:50 +00:00
|
|
|
static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2010-06-21 17:37:50 +00:00
|
|
|
Sequence *seq_act;
|
|
|
|
|
Sequence *seq_other;
|
2011-05-28 09:59:34 +00:00
|
|
|
const char *error_msg;
|
2010-06-21 17:37:50 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_select_active_get_pair(scene, &seq_act, &seq_other) == 0) {
|
2012-10-14 15:29:09 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Please select two strips");
|
2010-06-21 17:37:50 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_edit_sequence_swap(seq_act, seq_other, &error_msg) == 0) {
|
2011-05-28 09:59:34 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, error_msg);
|
2010-06-21 17:37:50 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-26 21:16:47 +11:00
|
|
|
if (seq_act->scene_sound) {
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_remove_scene_sound(scene, seq_act->scene_sound);
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2012-07-02 10:41:56 +00:00
|
|
|
|
2019-03-26 21:16:47 +11:00
|
|
|
if (seq_other->scene_sound) {
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_remove_scene_sound(scene, seq_other->scene_sound);
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2010-07-04 10:51:10 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
seq_act->scene_sound = NULL;
|
|
|
|
|
seq_other->scene_sound = NULL;
|
2010-07-04 10:51:10 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_time_update_sequence(scene, seq_act);
|
|
|
|
|
SEQ_time_update_sequence(scene, seq_other);
|
2010-06-21 17:37:50 +00:00
|
|
|
|
2019-03-26 21:16:47 +11:00
|
|
|
if (seq_act->sound) {
|
|
|
|
|
BKE_sound_add_scene_sound_defaults(scene, seq_act);
|
|
|
|
|
}
|
|
|
|
|
if (seq_other->sound) {
|
|
|
|
|
BKE_sound_add_scene_sound_defaults(scene, seq_other);
|
|
|
|
|
}
|
2010-07-04 10:22:31 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_invalidate_cache_raw(scene, seq_act);
|
|
|
|
|
SEQ_relations_invalidate_cache_raw(scene, seq_other);
|
2017-05-31 14:26:04 +02:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2010-06-21 17:37:50 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_swap_data(wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Sequencer Swap Data";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_swap_data";
|
|
|
|
|
ot->description = "Swap 2 sequencer strips";
|
2010-06-21 17:37:50 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_swap_data_exec;
|
|
|
|
|
ot->poll = ED_operator_sequencer_active;
|
2010-06-21 17:37:50 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2010-06-21 17:37:50 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Change Effect Input Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2017-10-18 15:07:26 +11:00
|
|
|
static const EnumPropertyItem prop_change_effect_input_types[] = {
|
2011-08-12 06:08:22 +00:00
|
|
|
{0, "A_B", 0, "A -> B", ""},
|
|
|
|
|
{1, "B_C", 0, "B -> C", ""},
|
|
|
|
|
{2, "A_C", 0, "A -> C", ""},
|
2019-02-03 14:01:45 +11:00
|
|
|
{0, NULL, 0, NULL, NULL},
|
2011-08-12 06:08:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int sequencer_change_effect_input_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
|
|
|
|
Sequence *seq = SEQ_select_active_get(scene);
|
2011-08-12 06:08:22 +00:00
|
|
|
|
|
|
|
|
Sequence **seq_1, **seq_2;
|
|
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
switch (RNA_enum_get(op->ptr, "swap")) {
|
2011-08-12 06:08:22 +00:00
|
|
|
case 0:
|
2012-03-29 22:26:11 +00:00
|
|
|
seq_1 = &seq->seq1;
|
|
|
|
|
seq_2 = &seq->seq2;
|
2011-08-12 06:08:22 +00:00
|
|
|
break;
|
|
|
|
|
case 1:
|
2012-03-29 22:26:11 +00:00
|
|
|
seq_1 = &seq->seq2;
|
|
|
|
|
seq_2 = &seq->seq3;
|
2011-08-12 06:08:22 +00:00
|
|
|
break;
|
|
|
|
|
default: /* 2 */
|
2012-03-29 22:26:11 +00:00
|
|
|
seq_1 = &seq->seq1;
|
|
|
|
|
seq_2 = &seq->seq3;
|
2011-08-12 06:08:22 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (*seq_1 == NULL || *seq_2 == NULL) {
|
2012-10-26 17:32:50 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "One of the effect inputs is unset, cannot swap");
|
2011-08-12 06:08:22 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2020-07-03 17:20:58 +02:00
|
|
|
|
|
|
|
|
SWAP(Sequence *, *seq_1, *seq_2);
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_update_changed_seq_and_deps(scene, seq, 0, 1);
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Invalidate cache. */
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2011-08-12 06:08:22 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_change_effect_input(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Change Effect Input";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_change_effect_input";
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_change_effect_input_exec;
|
|
|
|
|
ot->poll = sequencer_effect_poll;
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->prop = RNA_def_enum(
|
|
|
|
|
ot->srna, "swap", prop_change_effect_input_types, 0, "Swap", "The effect inputs to swap");
|
2011-08-12 06:08:22 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Change Effect Type Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2020-11-19 12:59:29 +01:00
|
|
|
EnumPropertyItem sequencer_prop_effect_types[] = {
|
|
|
|
|
{SEQ_TYPE_CROSS, "CROSS", 0, "Crossfade", "Crossfade effect strip type"},
|
|
|
|
|
{SEQ_TYPE_ADD, "ADD", 0, "Add", "Add effect strip type"},
|
|
|
|
|
{SEQ_TYPE_SUB, "SUBTRACT", 0, "Subtract", "Subtract effect strip type"},
|
|
|
|
|
{SEQ_TYPE_ALPHAOVER, "ALPHA_OVER", 0, "Alpha Over", "Alpha Over effect strip type"},
|
|
|
|
|
{SEQ_TYPE_ALPHAUNDER, "ALPHA_UNDER", 0, "Alpha Under", "Alpha Under effect strip type"},
|
|
|
|
|
{SEQ_TYPE_GAMCROSS, "GAMMA_CROSS", 0, "Gamma Cross", "Gamma Cross effect strip type"},
|
|
|
|
|
{SEQ_TYPE_MUL, "MULTIPLY", 0, "Multiply", "Multiply effect strip type"},
|
|
|
|
|
{SEQ_TYPE_OVERDROP, "OVER_DROP", 0, "Alpha Over Drop", "Alpha Over Drop effect strip type"},
|
|
|
|
|
{SEQ_TYPE_WIPE, "WIPE", 0, "Wipe", "Wipe effect strip type"},
|
|
|
|
|
{SEQ_TYPE_GLOW, "GLOW", 0, "Glow", "Glow effect strip type"},
|
|
|
|
|
{SEQ_TYPE_TRANSFORM, "TRANSFORM", 0, "Transform", "Transform effect strip type"},
|
|
|
|
|
{SEQ_TYPE_COLOR, "COLOR", 0, "Color", "Color effect strip type"},
|
|
|
|
|
{SEQ_TYPE_SPEED, "SPEED", 0, "Speed", "Color effect strip type"},
|
|
|
|
|
{SEQ_TYPE_MULTICAM, "MULTICAM", 0, "Multicam Selector", ""},
|
|
|
|
|
{SEQ_TYPE_ADJUSTMENT, "ADJUSTMENT", 0, "Adjustment Layer", ""},
|
|
|
|
|
{SEQ_TYPE_GAUSSIAN_BLUR, "GAUSSIAN_BLUR", 0, "Gaussian Blur", ""},
|
|
|
|
|
{SEQ_TYPE_TEXT, "TEXT", 0, "Text", ""},
|
|
|
|
|
{SEQ_TYPE_COLORMIX, "COLORMIX", 0, "Color Mix", ""},
|
|
|
|
|
{0, NULL, 0, NULL, NULL},
|
|
|
|
|
};
|
|
|
|
|
|
2011-08-12 06:08:22 +00:00
|
|
|
static int sequencer_change_effect_type_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
|
|
|
|
Sequence *seq = SEQ_select_active_get(scene);
|
2012-03-29 22:26:11 +00:00
|
|
|
const int new_type = RNA_enum_get(op->ptr, "type");
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Free previous effect and init new effect. */
|
2011-08-12 06:08:22 +00:00
|
|
|
struct SeqEffectHandle sh;
|
|
|
|
|
|
2012-06-07 15:49:02 +00:00
|
|
|
if ((seq->type & SEQ_TYPE_EFFECT) == 0) {
|
2011-08-12 06:08:22 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Can someone explain the logic behind only allowing to increase this,
|
2011-08-12 06:08:22 +00:00
|
|
|
* copied from 2.4x - campbell */
|
2020-12-19 05:57:27 +01:00
|
|
|
if (SEQ_effect_get_num_inputs(seq->type) < SEQ_effect_get_num_inputs(new_type)) {
|
2011-08-12 06:08:22 +00:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "New effect needs more input strips");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
sh = SEQ_effect_handle_get(seq);
|
2020-07-03 17:20:58 +02:00
|
|
|
sh.free(seq, true);
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-07-03 17:20:58 +02:00
|
|
|
seq->type = new_type;
|
|
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
sh = SEQ_effect_handle_get(seq);
|
2020-07-03 17:20:58 +02:00
|
|
|
sh.init(seq);
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_update_changed_seq_and_deps(scene, seq, 0, 1);
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Invalidate cache. */
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2011-08-12 06:08:22 +00:00
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_change_effect_type(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Change Effect Type";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_change_effect_type";
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_change_effect_type_exec;
|
|
|
|
|
ot->poll = sequencer_effect_poll;
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2012-06-07 15:49:02 +00:00
|
|
|
ot->prop = RNA_def_enum(ot->srna,
|
|
|
|
|
"type",
|
|
|
|
|
sequencer_prop_effect_types,
|
2019-09-29 16:17:48 -07:00
|
|
|
SEQ_TYPE_CROSS,
|
2012-06-07 15:49:02 +00:00
|
|
|
"Type",
|
|
|
|
|
"Sequencer effect type");
|
2011-08-12 06:08:22 +00:00
|
|
|
}
|
|
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Change Data/Files Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2011-08-12 06:08:22 +00:00
|
|
|
static int sequencer_change_path_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Main *bmain = CTX_data_main(C);
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
|
|
|
|
Sequence *seq = SEQ_select_active_get(scene);
|
2014-04-11 11:25:41 +10:00
|
|
|
const bool is_relative_path = RNA_boolean_get(op->ptr, "relative_path");
|
2015-04-20 18:07:34 +02:00
|
|
|
const bool use_placeholders = RNA_boolean_get(op->ptr, "use_placeholders");
|
2020-11-06 14:10:59 +01:00
|
|
|
int minext_frameme, numdigits;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-07 15:49:02 +00:00
|
|
|
if (seq->type == SEQ_TYPE_IMAGE) {
|
2011-08-12 06:08:22 +00:00
|
|
|
char directory[FILE_MAX];
|
2015-04-20 18:07:34 +02:00
|
|
|
int len;
|
2011-08-12 06:08:22 +00:00
|
|
|
StripElem *se;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Need to find min/max frame for placeholders. */
|
2015-04-20 18:07:34 +02:00
|
|
|
if (use_placeholders) {
|
2020-11-06 14:10:59 +01:00
|
|
|
len = sequencer_image_seq_get_minmax_frame(op, seq->sfra, &minext_frameme, &numdigits);
|
2015-04-20 18:07:34 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
len = RNA_property_collection_length(op->ptr, RNA_struct_find_property(op->ptr, "files"));
|
|
|
|
|
}
|
2019-03-26 21:16:47 +11:00
|
|
|
if (len == 0) {
|
2011-08-12 06:08:22 +00:00
|
|
|
return OPERATOR_CANCELLED;
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-08-12 06:08:22 +00:00
|
|
|
RNA_string_get(op->ptr, "directory", directory);
|
2011-10-12 00:21:08 +00:00
|
|
|
if (is_relative_path) {
|
2011-10-15 14:14:22 +00:00
|
|
|
/* TODO, shouldn't this already be relative from the filesel?
|
2011-10-12 00:21:08 +00:00
|
|
|
* (as the 'filepath' is) for now just make relative here,
|
|
|
|
|
* but look into changing after 2.60 - campbell */
|
2018-06-05 15:10:33 +02:00
|
|
|
BLI_path_rel(directory, BKE_main_blendfile_path(bmain));
|
2011-10-12 00:21:08 +00:00
|
|
|
}
|
2011-08-12 06:08:22 +00:00
|
|
|
BLI_strncpy(seq->strip->dir, directory, sizeof(seq->strip->dir));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:38:07 +00:00
|
|
|
if (seq->strip->stripdata) {
|
2011-08-12 06:08:22 +00:00
|
|
|
MEM_freeN(seq->strip->stripdata);
|
|
|
|
|
}
|
2012-03-29 22:26:11 +00:00
|
|
|
seq->strip->stripdata = se = MEM_callocN(len * sizeof(StripElem), "stripelem");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-20 18:07:34 +02:00
|
|
|
if (use_placeholders) {
|
2020-11-06 14:10:59 +01:00
|
|
|
sequencer_image_seq_reserve_frames(op, se, len, minext_frameme, numdigits);
|
2015-04-20 18:07:34 +02:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
RNA_BEGIN (op->ptr, itemptr, "files") {
|
|
|
|
|
char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
|
|
|
|
|
BLI_strncpy(se->name, filename, sizeof(se->name));
|
|
|
|
|
MEM_freeN(filename);
|
|
|
|
|
se++;
|
|
|
|
|
}
|
|
|
|
|
RNA_END;
|
2011-08-12 06:08:22 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Reset these else we wont see all the images. */
|
2012-03-29 22:26:11 +00:00
|
|
|
seq->anim_startofs = seq->anim_endofs = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Correct start/end frames so we don't move.
|
|
|
|
|
* Important not to set seq->len = len; allow the function to handle it. */
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_add_reload_new_file(bmain, scene, seq, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_time_update_sequence(scene, seq);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Invalidate cache. */
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_free_imbuf(scene, &ed->seqbase, false);
|
2011-08-12 06:08:22 +00:00
|
|
|
}
|
2016-01-27 11:01:41 +01:00
|
|
|
else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
|
|
|
|
|
bSound *sound = seq->sound;
|
|
|
|
|
if (sound == NULL) {
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
char filepath[FILE_MAX];
|
|
|
|
|
RNA_string_get(op->ptr, "filepath", filepath);
|
2020-06-23 09:54:14 +10:00
|
|
|
BLI_strncpy(sound->filepath, filepath, sizeof(sound->filepath));
|
2016-01-27 11:01:41 +01:00
|
|
|
BKE_sound_load(bmain, sound);
|
|
|
|
|
}
|
2011-08-12 06:08:22 +00:00
|
|
|
else {
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Lame, set rna filepath. */
|
2011-08-12 06:08:22 +00:00
|
|
|
PointerRNA seq_ptr;
|
2011-08-14 14:43:11 +00:00
|
|
|
PropertyRNA *prop;
|
2011-08-12 06:08:22 +00:00
|
|
|
char filepath[FILE_MAX];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-08-12 06:08:22 +00:00
|
|
|
RNA_pointer_create(&scene->id, &RNA_Sequence, seq, &seq_ptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-08-12 06:08:22 +00:00
|
|
|
RNA_string_get(op->ptr, "filepath", filepath);
|
2012-03-29 22:26:11 +00:00
|
|
|
prop = RNA_struct_find_property(&seq_ptr, "filepath");
|
2011-08-14 14:43:11 +00:00
|
|
|
RNA_property_string_set(&seq_ptr, prop, filepath);
|
|
|
|
|
RNA_property_update(C, &seq_ptr, prop);
|
2011-08-12 06:08:22 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-08-12 06:08:22 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2013-03-13 09:03:46 +00:00
|
|
|
static int sequencer_change_path_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
2011-08-12 06:08:22 +00:00
|
|
|
{
|
2012-03-29 22:26:11 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Sequence *seq = SEQ_select_active_get(scene);
|
2012-12-06 02:38:39 +00:00
|
|
|
char filepath[FILE_MAX];
|
|
|
|
|
|
|
|
|
|
BLI_join_dirfile(filepath, sizeof(filepath), seq->strip->dir, seq->strip->stripdata->name);
|
2011-08-12 06:08:22 +00:00
|
|
|
|
|
|
|
|
RNA_string_set(op->ptr, "directory", seq->strip->dir);
|
2012-12-06 02:38:39 +00:00
|
|
|
RNA_string_set(op->ptr, "filepath", filepath);
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Set default display depending on seq type. */
|
2012-06-07 15:49:02 +00:00
|
|
|
if (seq->type == SEQ_TYPE_IMAGE) {
|
2014-04-01 11:34:00 +11:00
|
|
|
RNA_boolean_set(op->ptr, "filter_movie", false);
|
2011-08-12 06:08:22 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2014-04-01 11:34:00 +11:00
|
|
|
RNA_boolean_set(op->ptr, "filter_image", false);
|
2011-08-12 06:08:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WM_event_add_fileselect(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_change_path(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Change Data/Files";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_change_path";
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = sequencer_change_path_exec;
|
|
|
|
|
ot->invoke = sequencer_change_path_invoke;
|
|
|
|
|
ot->poll = sequencer_strip_has_path_poll;
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2012-03-29 22:26:11 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2011-08-12 06:08:22 +00:00
|
|
|
|
2016-02-07 22:56:20 +11:00
|
|
|
WM_operator_properties_filesel(ot,
|
|
|
|
|
FILE_TYPE_FOLDER,
|
|
|
|
|
FILE_SPECIAL,
|
|
|
|
|
FILE_OPENFILE,
|
|
|
|
|
WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH |
|
|
|
|
|
WM_FILESEL_FILES,
|
|
|
|
|
FILE_DEFAULTDISPLAY,
|
2020-11-02 23:55:59 +01:00
|
|
|
FILE_SORT_DEFAULT);
|
2015-04-20 18:07:34 +02:00
|
|
|
RNA_def_boolean(ot->srna,
|
|
|
|
|
"use_placeholders",
|
|
|
|
|
false,
|
|
|
|
|
"Use Placeholders",
|
|
|
|
|
"Use placeholders for missing frames of the strip");
|
2011-08-12 06:08:22 +00:00
|
|
|
}
|
2015-07-03 12:34:23 +02:00
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Export Subtitles Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2015-07-03 12:34:23 +02:00
|
|
|
static int sequencer_export_subtitles_invoke(bContext *C,
|
|
|
|
|
wmOperator *op,
|
|
|
|
|
const wmEvent *UNUSED(event))
|
|
|
|
|
{
|
2018-06-01 17:08:38 +02:00
|
|
|
Main *bmain = CTX_data_main(C);
|
2015-07-03 12:34:23 +02:00
|
|
|
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
|
|
|
|
|
char filepath[FILE_MAX];
|
|
|
|
|
|
2019-03-26 21:16:47 +11:00
|
|
|
if (BKE_main_blendfile_path(bmain)[0] == '\0') {
|
2015-07-03 12:34:23 +02:00
|
|
|
BLI_strncpy(filepath, "untitled", sizeof(filepath));
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
|
|
|
|
else {
|
2018-06-05 15:10:33 +02:00
|
|
|
BLI_strncpy(filepath, BKE_main_blendfile_path(bmain), sizeof(filepath));
|
2019-03-26 21:16:47 +11:00
|
|
|
}
|
2015-07-03 12:34:23 +02:00
|
|
|
|
2018-06-17 16:13:24 +02:00
|
|
|
BLI_path_extension_replace(filepath, sizeof(filepath), ".srt");
|
2015-07-03 12:34:23 +02:00
|
|
|
RNA_string_set(op->ptr, "filepath", filepath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WM_event_add_fileselect(C, op);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int sequencer_export_subtitles_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2015-11-06 05:09:14 +11:00
|
|
|
Sequence *seq, *seq_next;
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2015-10-04 16:42:19 +02:00
|
|
|
ListBase text_seq = {0};
|
2015-07-03 12:34:23 +02:00
|
|
|
int iter = 0;
|
|
|
|
|
FILE *file;
|
|
|
|
|
char filepath[FILE_MAX];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-03 12:34:23 +02:00
|
|
|
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
|
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "No filename given");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-03 12:34:23 +02:00
|
|
|
RNA_string_get(op->ptr, "filepath", filepath);
|
2018-06-17 16:13:24 +02:00
|
|
|
BLI_path_extension_ensure(filepath, sizeof(filepath), ".srt");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Avoid File write exceptions. */
|
2015-07-03 12:34:23 +02:00
|
|
|
if (!BLI_exists(filepath)) {
|
|
|
|
|
BLI_make_existing_file(filepath);
|
|
|
|
|
if (!BLI_file_touch(filepath)) {
|
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Can't create subtitle file");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2015-07-03 12:34:23 +02:00
|
|
|
}
|
|
|
|
|
else if (!BLI_file_is_writable(filepath)) {
|
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "Can't overwrite export file");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-08-26 09:59:15 +10:00
|
|
|
SEQ_ALL_BEGIN (ed, seq) {
|
2015-07-03 12:34:23 +02:00
|
|
|
if (seq->type == SEQ_TYPE_TEXT) {
|
2015-10-04 16:42:19 +02:00
|
|
|
BLI_addtail(&text_seq, MEM_dupallocN(seq));
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2015-07-03 12:34:23 +02:00
|
|
|
}
|
2020-08-21 18:55:27 +02:00
|
|
|
SEQ_ALL_END;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-10-04 16:42:19 +02:00
|
|
|
if (BLI_listbase_is_empty(&text_seq)) {
|
|
|
|
|
BKE_report(op->reports, RPT_ERROR, "No subtitles (text strips) to export");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-12-19 05:57:27 +01:00
|
|
|
BLI_listbase_sort(&text_seq, SEQ_time_cmp_time_startdisp);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Open and write file. */
|
2015-10-04 16:42:19 +02:00
|
|
|
file = BLI_fopen(filepath, "w");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-10-04 16:42:19 +02:00
|
|
|
for (seq = text_seq.first; seq; seq = seq_next) {
|
|
|
|
|
TextVars *data = seq->effectdata;
|
|
|
|
|
char timecode_str_start[32];
|
|
|
|
|
char timecode_str_end[32];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-10-04 16:42:19 +02:00
|
|
|
BLI_timecode_string_from_time(timecode_str_start,
|
|
|
|
|
sizeof(timecode_str_start),
|
2015-10-17 01:01:57 +11:00
|
|
|
-2,
|
|
|
|
|
FRA2TIME(seq->startdisp),
|
|
|
|
|
FPS,
|
|
|
|
|
USER_TIMECODE_SUBRIP);
|
2015-10-04 16:42:19 +02:00
|
|
|
BLI_timecode_string_from_time(timecode_str_end,
|
|
|
|
|
sizeof(timecode_str_end),
|
2015-10-17 01:01:57 +11:00
|
|
|
-2,
|
|
|
|
|
FRA2TIME(seq->enddisp),
|
|
|
|
|
FPS,
|
|
|
|
|
USER_TIMECODE_SUBRIP);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-10-04 16:42:19 +02:00
|
|
|
fprintf(
|
|
|
|
|
file, "%d\n%s --> %s\n%s\n\n", iter++, timecode_str_start, timecode_str_end, data->text);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-10-04 16:42:19 +02:00
|
|
|
seq_next = seq->next;
|
|
|
|
|
MEM_freeN(seq);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-03 12:34:23 +02:00
|
|
|
fclose(file);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-07-03 12:34:23 +02:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-02 11:47:00 +02:00
|
|
|
static bool sequencer_strip_is_text_poll(bContext *C)
|
2015-07-03 12:34:23 +02:00
|
|
|
{
|
|
|
|
|
Editing *ed;
|
|
|
|
|
Sequence *seq;
|
2020-12-19 05:57:27 +01:00
|
|
|
return (((ed = SEQ_editing_get(CTX_data_scene(C), false)) != NULL) &&
|
2015-07-03 12:34:23 +02:00
|
|
|
((seq = ed->act_seq) != NULL) && (seq->type == SEQ_TYPE_TEXT));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot)
|
|
|
|
|
{
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2015-07-03 12:34:23 +02:00
|
|
|
ot->name = "Export Subtitles";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_export_subtitles";
|
|
|
|
|
ot->description = "Export .srt file containing text strips";
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2015-07-03 12:34:23 +02:00
|
|
|
ot->exec = sequencer_export_subtitles_exec;
|
|
|
|
|
ot->invoke = sequencer_export_subtitles_invoke;
|
|
|
|
|
ot->poll = sequencer_strip_is_text_poll;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2015-07-03 12:34:23 +02:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-02-07 22:56:20 +11:00
|
|
|
WM_operator_properties_filesel(ot,
|
|
|
|
|
FILE_TYPE_FOLDER,
|
|
|
|
|
FILE_BLENDER,
|
|
|
|
|
FILE_SAVE,
|
|
|
|
|
WM_FILESEL_FILEPATH,
|
|
|
|
|
FILE_DEFAULTDISPLAY,
|
2020-11-02 23:55:59 +01:00
|
|
|
FILE_SORT_DEFAULT);
|
2015-07-03 12:34:23 +02:00
|
|
|
}
|
2019-11-02 22:53:39 -07:00
|
|
|
|
2020-06-06 00:05:54 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Set Range to Strips Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2019-11-02 22:53:39 -07:00
|
|
|
static int sequencer_set_range_to_strips_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
Editing *ed = SEQ_editing_get(scene, false);
|
2019-11-02 22:53:39 -07:00
|
|
|
Sequence *seq;
|
|
|
|
|
|
|
|
|
|
int sfra = MAXFRAME;
|
|
|
|
|
int efra = -MAXFRAME;
|
|
|
|
|
bool selected = false;
|
|
|
|
|
const bool preview = RNA_boolean_get(op->ptr, "preview");
|
|
|
|
|
|
|
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
|
|
|
|
if (seq->flag & SELECT) {
|
|
|
|
|
selected = true;
|
|
|
|
|
sfra = min_ii(sfra, seq->startdisp);
|
|
|
|
|
efra = max_ii(efra, seq->enddisp - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!selected) {
|
|
|
|
|
BKE_report(op->reports, RPT_WARNING, "Select one or more strips");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
2020-07-03 17:20:58 +02:00
|
|
|
if (efra < 0) {
|
2019-11-02 22:53:39 -07:00
|
|
|
BKE_report(op->reports, RPT_ERROR, "Can't set a negative range");
|
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (preview) {
|
|
|
|
|
scene->r.flag |= SCER_PRV_RANGE;
|
|
|
|
|
scene->r.psfra = max_ii(0, sfra);
|
|
|
|
|
scene->r.pefra = efra;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
scene->r.flag &= ~SCER_PRV_RANGE;
|
|
|
|
|
scene->r.sfra = max_ii(0, sfra);
|
|
|
|
|
scene->r.efra = efra;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
|
|
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_set_range_to_strips(struct wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Identifiers. */
|
2019-11-02 22:53:39 -07:00
|
|
|
ot->name = "Set Range to Strips";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_set_range_to_strips";
|
|
|
|
|
ot->description = "Set the frame range to the selected strips start and end";
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Api callbacks. */
|
2019-11-02 22:53:39 -07:00
|
|
|
ot->exec = sequencer_set_range_to_strips_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
|
|
|
|
|
2020-04-05 23:55:51 +02:00
|
|
|
/* Flags. */
|
2019-11-02 22:53:39 -07:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
|
|
|
|
|
|
|
|
prop = RNA_def_boolean(ot->srna, "preview", false, "Preview", "Set the preview range instead");
|
2020-01-22 02:07:54 +01:00
|
|
|
RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN);
|
2019-11-02 22:53:39 -07:00
|
|
|
}
|
2020-06-06 00:05:54 +10:00
|
|
|
|
|
|
|
|
/** \} */
|
2020-11-19 12:59:29 +01:00
|
|
|
|
2020-12-16 20:34:26 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Clear Strip Transform Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
enum {
|
|
|
|
|
STRIP_TRANSFORM_POSITION,
|
|
|
|
|
STRIP_TRANSFORM_SCALE,
|
|
|
|
|
STRIP_TRANSFORM_ROTATION,
|
|
|
|
|
STRIP_TRANSFORM_ALL,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const EnumPropertyItem transform_reset_properties[] = {
|
|
|
|
|
{STRIP_TRANSFORM_POSITION, "POSITION", 0, "Position", "Reset strip transform location"},
|
|
|
|
|
{STRIP_TRANSFORM_SCALE, "SCALE", 0, "Scale", "Reset strip transform scale"},
|
|
|
|
|
{STRIP_TRANSFORM_ROTATION, "ROTATION", 0, "Rotation", "Reset strip transform rotation"},
|
|
|
|
|
{STRIP_TRANSFORM_ALL, "ALL", 0, "All", "Reset strip transform location, scale and rotation"},
|
|
|
|
|
{0, NULL, 0, NULL, NULL},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int sequencer_strip_transform_clear_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
const Editing *ed = SEQ_editing_get(scene, false);
|
2020-12-16 20:34:26 +01:00
|
|
|
Sequence *seq;
|
|
|
|
|
const int property = RNA_enum_get(op->ptr, "property");
|
|
|
|
|
|
|
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
|
|
|
|
if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) {
|
|
|
|
|
StripTransform *transform = seq->strip->transform;
|
|
|
|
|
switch (property) {
|
|
|
|
|
case STRIP_TRANSFORM_POSITION:
|
|
|
|
|
transform->xofs = 0;
|
|
|
|
|
transform->yofs = 0;
|
|
|
|
|
break;
|
|
|
|
|
case STRIP_TRANSFORM_SCALE:
|
|
|
|
|
transform->scale_x = 1.0f;
|
|
|
|
|
transform->scale_y = 1.0f;
|
|
|
|
|
break;
|
|
|
|
|
case STRIP_TRANSFORM_ROTATION:
|
|
|
|
|
transform->rotation = 0.0f;
|
|
|
|
|
break;
|
|
|
|
|
case STRIP_TRANSFORM_ALL:
|
|
|
|
|
transform->xofs = 0;
|
|
|
|
|
transform->yofs = 0;
|
|
|
|
|
transform->scale_x = 1.0f;
|
|
|
|
|
transform->scale_y = 1.0f;
|
|
|
|
|
transform->rotation = 0.0f;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
|
2020-12-16 20:34:26 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_strip_transform_clear(struct wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* Identifiers. */
|
|
|
|
|
ot->name = "Clear Strip Transform";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_strip_transform_clear";
|
|
|
|
|
ot->description = "Reset image transformation to default value";
|
|
|
|
|
|
|
|
|
|
/* Api callbacks. */
|
|
|
|
|
ot->exec = sequencer_strip_transform_clear_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
|
|
|
|
|
|
|
|
|
/* Flags. */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
|
|
|
|
|
|
|
|
ot->prop = RNA_def_enum(ot->srna,
|
|
|
|
|
"property",
|
|
|
|
|
transform_reset_properties,
|
|
|
|
|
STRIP_TRANSFORM_ALL,
|
|
|
|
|
"Property",
|
|
|
|
|
"Strip transform property to be reset");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Transform Set Fit Operator
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
static const EnumPropertyItem scale_fit_methods[] = {
|
|
|
|
|
{SEQ_SCALE_TO_FIT, "FIT", 0, "Scale to Fit", "Scale image so fits in preview"},
|
|
|
|
|
{SEQ_SCALE_TO_FILL, "FILL", 0, "Scale to Fill", "Scale image so it fills preview completely"},
|
|
|
|
|
{SEQ_STRETCH_TO_FILL, "STRETCH", 0, "Stretch to Fill", "Stretch image so it fills preview"},
|
|
|
|
|
{0, NULL, 0, NULL, NULL},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int sequencer_strip_transform_fit_exec(bContext *C, wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
2020-12-19 05:57:27 +01:00
|
|
|
const Editing *ed = SEQ_editing_get(scene, false);
|
2020-12-16 20:34:26 +01:00
|
|
|
Sequence *seq;
|
|
|
|
|
const eSeqImageFitMethod fit_method = RNA_enum_get(op->ptr, "fit_method");
|
|
|
|
|
|
|
|
|
|
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
|
|
|
|
if (seq->flag & SELECT && seq->type != SEQ_TYPE_SOUND_RAM) {
|
|
|
|
|
const int timeline_frame = CFRA;
|
|
|
|
|
StripElem *strip_elem = SEQ_render_give_stripelem(seq, timeline_frame);
|
|
|
|
|
|
|
|
|
|
if (strip_elem == NULL) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SEQ_set_scale_to_fit(seq,
|
|
|
|
|
strip_elem->orig_width,
|
|
|
|
|
strip_elem->orig_height,
|
|
|
|
|
scene->r.xsch,
|
|
|
|
|
scene->r.ysch,
|
|
|
|
|
fit_method);
|
2020-12-19 05:57:27 +01:00
|
|
|
SEQ_relations_invalidate_cache_preprocessed(scene, seq);
|
2020-12-16 20:34:26 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SEQUENCER_OT_strip_transform_fit(struct wmOperatorType *ot)
|
|
|
|
|
{
|
|
|
|
|
/* Identifiers. */
|
|
|
|
|
ot->name = "Strip Transform Set Fit";
|
|
|
|
|
ot->idname = "SEQUENCER_OT_strip_transform_fit";
|
|
|
|
|
|
|
|
|
|
/* Api callbacks. */
|
|
|
|
|
ot->exec = sequencer_strip_transform_fit_exec;
|
|
|
|
|
ot->poll = sequencer_edit_poll;
|
|
|
|
|
|
|
|
|
|
/* Flags. */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
|
|
|
|
|
|
|
|
ot->prop = RNA_def_enum(ot->srna,
|
|
|
|
|
"fit_method",
|
|
|
|
|
scale_fit_methods,
|
|
|
|
|
SEQ_SCALE_TO_FIT,
|
|
|
|
|
"Fit Method",
|
|
|
|
|
"Scale fit fit_method");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|