Compare commits
3 Commits
tmp-eevee-
...
temp-vse-c
Author | SHA1 | Date | |
---|---|---|---|
0d80c4dbc6 | |||
![]() |
75ecace309 | ||
![]() |
33a914e06b |
@@ -665,6 +665,10 @@ const bTheme U_theme_default = {
|
||||
.row_alternate = RGBA(0xffffff05),
|
||||
.anim_preview_range = RGBA(0xa14d0066),
|
||||
.metadatatext = RGBA(0xffffffff),
|
||||
.list = RGBA(0x18181800),
|
||||
.list_title = RGBA(0xffffffff),
|
||||
.list_text = RGBA(0xffffffff),
|
||||
.list_text_hi = RGBA(0xffffffff),
|
||||
},
|
||||
.space_image = {
|
||||
.back = RGBA(0x30303000),
|
||||
|
@@ -2892,10 +2892,12 @@ def km_sequencer(params):
|
||||
("sequencer.slip", {"type": 'S', "value": 'PRESS'}, None),
|
||||
("wm.context_set_int", {"type": 'O', "value": 'PRESS'},
|
||||
{"properties": [("data_path", 'scene.sequence_editor.overlay_frame'), ("value", 0)]}),
|
||||
("transform.seq_slide", {"type": 'G', "value": 'PRESS'}, None),
|
||||
("transform.seq_slide", {"type": params.select_mouse, "value": 'CLICK_DRAG'}, None),
|
||||
("transform.seq_slide", {"type": 'G', "value": 'PRESS'},
|
||||
{"properties": [("view2d_edge_pan", True)]}),
|
||||
("transform.seq_slide", {"type": params.select_mouse, "value": 'CLICK_DRAG'},
|
||||
{"properties": [("view2d_edge_pan", True)]}),
|
||||
("transform.transform", {"type": 'E', "value": 'PRESS'},
|
||||
{"properties": [("mode", 'TIME_EXTEND')]}),
|
||||
{"properties": [("mode", 'TIME_EXTEND'), ("view2d_edge_pan", True)]}),
|
||||
("marker.add", {"type": 'M', "value": 'PRESS'}, None),
|
||||
("marker.rename", {"type": 'M', "value": 'PRESS', "ctrl": True}, None),
|
||||
("sequencer.select_side_of_frame", {"type": 'LEFT_BRACKET', "value": 'PRESS'},
|
||||
@@ -2997,6 +2999,22 @@ def km_sequencerpreview(params):
|
||||
return keymap
|
||||
|
||||
|
||||
def km_sequencer_channels(params):
|
||||
items = []
|
||||
keymap = (
|
||||
"Sequencer Channels",
|
||||
{"space_type": 'SEQUENCE_EDITOR', "region_type": 'WINDOW'},
|
||||
{"items": items},
|
||||
)
|
||||
|
||||
items.extend([
|
||||
# Rename.
|
||||
("sequencer.channel_rename", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, None),
|
||||
("sequencer.channel_rename", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None),
|
||||
])
|
||||
return keymap
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Editor (Console)
|
||||
|
||||
@@ -7781,6 +7799,7 @@ def generate_keymaps(params=None):
|
||||
km_sequencercommon(params),
|
||||
km_sequencer(params),
|
||||
km_sequencerpreview(params),
|
||||
km_sequencer_channels(params),
|
||||
km_console(params),
|
||||
km_clip(params),
|
||||
km_clip_editor(params),
|
||||
|
@@ -418,6 +418,7 @@ class SEQUENCER_MT_view(Menu):
|
||||
|
||||
if is_sequencer_view:
|
||||
layout.prop(st, "show_region_hud")
|
||||
layout.prop(st, "show_region_channels")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@@ -25,7 +25,7 @@ extern "C" {
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 6
|
||||
#define BLENDER_FILE_SUBVERSION 7
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and show a warning if the file
|
||||
|
@@ -321,6 +321,7 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
|
||||
&scene_src->ed->seqbase,
|
||||
SEQ_DUPE_ALL,
|
||||
flag_subdata);
|
||||
BLI_duplicatelist(&scene_dst->ed->channels, &scene_src->ed->channels);
|
||||
}
|
||||
|
||||
if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
|
||||
@@ -990,6 +991,9 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres
|
||||
BLO_write_struct(writer, Editing, ed);
|
||||
|
||||
SEQ_blend_write(writer, &ed->seqbase);
|
||||
LISTBASE_FOREACH (SeqTimelineChannel *, channel, &ed->channels) {
|
||||
BLO_write_struct(writer, SeqTimelineChannel, channel);
|
||||
}
|
||||
/* new; meta stack too, even when its nasty restore code */
|
||||
LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
|
||||
BLO_write_struct(writer, MetaStack, ms);
|
||||
@@ -1174,6 +1178,7 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
|
||||
|
||||
if (sce->ed) {
|
||||
ListBase *old_seqbasep = &sce->ed->seqbase;
|
||||
ListBase *old_active_channels = &sce->ed->channels;
|
||||
|
||||
BLO_read_data_address(reader, &sce->ed);
|
||||
Editing *ed = sce->ed;
|
||||
@@ -1188,32 +1193,53 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
|
||||
|
||||
/* Read in sequence member data. */
|
||||
SEQ_blend_read(reader, &ed->seqbase);
|
||||
BLO_read_list(reader, &ed->channels);
|
||||
|
||||
/* link metastack, slight abuse of structs here,
|
||||
* have to restore pointer to internal part in struct */
|
||||
{
|
||||
Sequence temp;
|
||||
void *poin;
|
||||
intptr_t offset;
|
||||
void *seqbase_poin;
|
||||
void *channels_poin;
|
||||
intptr_t seqbase_offset;
|
||||
intptr_t channels_offset;
|
||||
|
||||
offset = ((intptr_t) & (temp.seqbase)) - ((intptr_t)&temp);
|
||||
seqbase_offset = ((intptr_t) & (temp.seqbase)) - ((intptr_t)&temp);
|
||||
channels_offset = ((intptr_t) & (temp.channels)) - ((intptr_t)&temp);
|
||||
|
||||
/* root pointer */
|
||||
/* seqbase root pointer */
|
||||
if (ed->seqbasep == old_seqbasep) {
|
||||
ed->seqbasep = &ed->seqbase;
|
||||
}
|
||||
else {
|
||||
poin = POINTER_OFFSET(ed->seqbasep, -offset);
|
||||
seqbase_poin = POINTER_OFFSET(ed->seqbasep, -seqbase_offset);
|
||||
|
||||
poin = BLO_read_get_new_data_address(reader, poin);
|
||||
seqbase_poin = BLO_read_get_new_data_address(reader, seqbase_poin);
|
||||
|
||||
if (poin) {
|
||||
ed->seqbasep = (ListBase *)POINTER_OFFSET(poin, offset);
|
||||
if (seqbase_poin) {
|
||||
ed->seqbasep = (ListBase *)POINTER_OFFSET(seqbase_poin, seqbase_offset);
|
||||
}
|
||||
else {
|
||||
ed->seqbasep = &ed->seqbase;
|
||||
}
|
||||
}
|
||||
|
||||
/* Active channels root pointer. */
|
||||
if (ed->active_channels == old_active_channels) {
|
||||
ed->active_channels = &ed->channels;
|
||||
}
|
||||
else {
|
||||
channels_poin = POINTER_OFFSET(ed->active_channels, -channels_offset);
|
||||
channels_poin = BLO_read_get_new_data_address(reader, channels_poin);
|
||||
|
||||
if (channels_poin) {
|
||||
ed->active_channels = (ListBase *)POINTER_OFFSET(channels_poin, channels_offset);
|
||||
}
|
||||
else {
|
||||
ed->active_channels = &ed->channels;
|
||||
}
|
||||
}
|
||||
|
||||
/* stack */
|
||||
BLO_read_list(reader, &(ed->metastack));
|
||||
|
||||
@@ -1224,15 +1250,30 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
|
||||
ms->oldbasep = &ed->seqbase;
|
||||
}
|
||||
else {
|
||||
poin = POINTER_OFFSET(ms->oldbasep, -offset);
|
||||
poin = BLO_read_get_new_data_address(reader, poin);
|
||||
if (poin) {
|
||||
ms->oldbasep = (ListBase *)POINTER_OFFSET(poin, offset);
|
||||
seqbase_poin = POINTER_OFFSET(ms->oldbasep, -seqbase_offset);
|
||||
seqbase_poin = BLO_read_get_new_data_address(reader, seqbase_poin);
|
||||
if (seqbase_poin) {
|
||||
ms->oldbasep = (ListBase *)POINTER_OFFSET(seqbase_poin, seqbase_offset);
|
||||
}
|
||||
else {
|
||||
ms->oldbasep = &ed->seqbase;
|
||||
}
|
||||
}
|
||||
|
||||
if (ms->old_channels == old_active_channels) {
|
||||
ms->old_channels = &ed->channels;
|
||||
}
|
||||
else {
|
||||
channels_poin = POINTER_OFFSET(ms->old_channels, -channels_offset);
|
||||
channels_poin = BLO_read_get_new_data_address(reader, channels_poin);
|
||||
|
||||
if (channels_poin) {
|
||||
ms->old_channels = (ListBase *)POINTER_OFFSET(channels_poin, channels_offset);
|
||||
}
|
||||
else {
|
||||
ms->old_channels = &ed->channels;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -52,6 +52,8 @@
|
||||
|
||||
#include "BLO_read_write.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_render.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
#include "SEQ_sound.h"
|
||||
|
||||
|
@@ -637,13 +637,6 @@ static ARegion *do_versions_find_region(ListBase *regionbase, int regiontype)
|
||||
return region;
|
||||
}
|
||||
|
||||
static ARegion *do_versions_add_region(int regiontype, const char *name)
|
||||
{
|
||||
ARegion *region = MEM_callocN(sizeof(ARegion), name);
|
||||
region->regiontype = regiontype;
|
||||
return region;
|
||||
}
|
||||
|
||||
static void do_versions_area_ensure_tool_region(Main *bmain,
|
||||
const short space_type,
|
||||
const short region_flag)
|
||||
|
@@ -53,6 +53,7 @@
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_enum_types.h"
|
||||
@@ -62,6 +63,7 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "readfile.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
#include "SEQ_time.h"
|
||||
@@ -944,6 +946,14 @@ static bool seq_transform_filter_set(Sequence *seq, void *UNUSED(user_data))
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool seq_meta_channels_ensure(Sequence *seq, void *UNUSED(user_data))
|
||||
{
|
||||
if (seq->type == SEQ_TYPE_META) {
|
||||
SEQ_channels_ensure(&seq->channels);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void do_version_subsurface_methods(bNode *node)
|
||||
{
|
||||
if (node->type == SH_NODE_SUBSURFACE_SCATTERING) {
|
||||
@@ -2435,6 +2445,82 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 302, 7)) {
|
||||
/* Sequencer channels region. */
|
||||
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
|
||||
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
||||
if (sl->spacetype != SPACE_SEQ) {
|
||||
continue;
|
||||
}
|
||||
if (ELEM(((SpaceSeq *)sl)->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
|
||||
&sl->regionbase;
|
||||
ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_CHANNELS);
|
||||
if (!region) {
|
||||
ARegion *tools_region = BKE_area_find_region_type(area, RGN_TYPE_TOOLS);
|
||||
region = do_versions_add_region(RGN_TYPE_CHANNELS, "channels region");
|
||||
BLI_insertlinkafter(regionbase, tools_region, region);
|
||||
region->alignment = RGN_ALIGN_LEFT;
|
||||
region->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL;
|
||||
}
|
||||
|
||||
ARegion *timeline_region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
|
||||
if (timeline_region != NULL) {
|
||||
timeline_region->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize channels. */
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
if (ed == NULL > 0) {
|
||||
continue;
|
||||
}
|
||||
SEQ_channels_ensure(&ed->channels);
|
||||
SEQ_for_each_callback(&scene->ed->seqbase, seq_meta_channels_ensure, NULL);
|
||||
|
||||
ed->active_channels = &ed->channels;
|
||||
|
||||
ListBase *previous_channels = &ed->channels;
|
||||
LISTBASE_FOREACH (MetaStack *, ms, &ed->metastack) {
|
||||
ms->old_channels = previous_channels;
|
||||
previous_channels = &ms->parseq->channels;
|
||||
/* If `MetaStack` exists, active channels must point to last link. */
|
||||
ed->active_channels = &ms->parseq->channels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 302, 7)) {
|
||||
/* Sequencer channels region. */
|
||||
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
|
||||
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
||||
if (sl->spacetype != SPACE_SEQ) {
|
||||
continue;
|
||||
}
|
||||
if (ELEM(((SpaceSeq *)sl)->view, SEQ_VIEW_PREVIEW, SEQ_VIEW_SEQUENCE_PREVIEW)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ARegion *timeline_region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
|
||||
|
||||
if (timeline_region == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
timeline_region->v2d.cur.ymax = 8.5f;
|
||||
timeline_region->v2d.align &= ~V2D_ALIGN_NO_NEG_Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
|
@@ -225,3 +225,10 @@ void version_socket_update_is_used(bNodeTree *ntree)
|
||||
link->tosock->flag |= SOCK_IN_USE;
|
||||
}
|
||||
}
|
||||
|
||||
ARegion *do_versions_add_region(int regiontype, const char *name)
|
||||
{
|
||||
ARegion *region = (ARegion *)MEM_callocN(sizeof(ARegion), name);
|
||||
region->regiontype = regiontype;
|
||||
return region;
|
||||
}
|
||||
|
@@ -88,6 +88,7 @@ struct bNodeSocket *version_node_add_socket_if_not_exist(struct bNodeTree *ntree
|
||||
* the flag on all sockets after changes to the node tree.
|
||||
*/
|
||||
void version_socket_update_is_used(bNodeTree *ntree);
|
||||
ARegion *do_versions_add_region(int regiontype, const char *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -324,6 +324,13 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
|
||||
if (!USER_VERSION_ATLEAST(301, 2)) {
|
||||
FROM_DEFAULT_V4_UCHAR(space_sequencer.mask);
|
||||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(302, 7)) {
|
||||
FROM_DEFAULT_V4_UCHAR(space_sequencer.list);
|
||||
FROM_DEFAULT_V4_UCHAR(space_sequencer.list_title);
|
||||
FROM_DEFAULT_V4_UCHAR(space_sequencer.list_text);
|
||||
FROM_DEFAULT_V4_UCHAR(space_sequencer.list_text_hi);
|
||||
}
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
|
@@ -32,7 +32,7 @@
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_prototypes.h"
|
||||
|
||||
static void get_time_scrub_region_rect(const ARegion *region, rcti *rect)
|
||||
void ED_time_scrub_region_rect_get(const ARegion *region, rcti *rect)
|
||||
{
|
||||
rect->xmin = 0;
|
||||
rect->xmax = region->winx;
|
||||
@@ -154,7 +154,7 @@ void ED_time_scrub_draw_current_frame(const ARegion *region,
|
||||
wmOrtho2_region_pixelspace(region);
|
||||
|
||||
rcti scrub_region_rect;
|
||||
get_time_scrub_region_rect(region, &scrub_region_rect);
|
||||
ED_time_scrub_region_rect_get(region, &scrub_region_rect);
|
||||
|
||||
draw_current_frame(scene, display_seconds, v2d, &scrub_region_rect, scene->r.cfra);
|
||||
GPU_matrix_pop_projection();
|
||||
@@ -171,7 +171,7 @@ void ED_time_scrub_draw(const ARegion *region,
|
||||
wmOrtho2_region_pixelspace(region);
|
||||
|
||||
rcti scrub_region_rect;
|
||||
get_time_scrub_region_rect(region, &scrub_region_rect);
|
||||
ED_time_scrub_region_rect_get(region, &scrub_region_rect);
|
||||
|
||||
draw_background(&scrub_region_rect);
|
||||
|
||||
|
@@ -14,6 +14,7 @@ extern "C" {
|
||||
struct bContext;
|
||||
struct bDopeSheet;
|
||||
struct wmEvent;
|
||||
struct rcti;
|
||||
|
||||
void ED_time_scrub_draw_current_frame(const struct ARegion *region,
|
||||
const struct Scene *scene,
|
||||
@@ -29,6 +30,7 @@ bool ED_time_scrub_event_in_region(const struct ARegion *region, const struct wm
|
||||
void ED_time_scrub_channel_search_draw(const struct bContext *C,
|
||||
struct ARegion *region,
|
||||
struct bDopeSheet *dopesheet);
|
||||
void ED_time_scrub_region_rect_get(const struct ARegion *region, struct rcti *rect);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -2950,10 +2950,10 @@ typedef enum eFontStyle_Align {
|
||||
UI_STYLE_TEXT_RIGHT = 2,
|
||||
} eFontStyle_Align;
|
||||
|
||||
struct uiFontStyleDraw_Params {
|
||||
typedef struct uiFontStyleDraw_Params {
|
||||
eFontStyle_Align align;
|
||||
uint word_wrap : 1;
|
||||
};
|
||||
} uiFontStyleDraw_Params;
|
||||
|
||||
/* Styled text draw */
|
||||
void UI_fontstyle_set(const struct uiFontStyle *fs);
|
||||
|
@@ -447,6 +447,8 @@ typedef struct View2DEdgePanData {
|
||||
struct ARegion *region;
|
||||
/** View2d we're operating in. */
|
||||
struct View2D *v2d;
|
||||
/* Limit maximum pannable area */
|
||||
struct rctf limit;
|
||||
|
||||
/** Panning should only start once being in the inside rect once (e.g. adding nodes can happen
|
||||
* outside). */
|
||||
@@ -492,6 +494,12 @@ void UI_view2d_edge_pan_init(struct bContext *C,
|
||||
float delay,
|
||||
float zoom_influence);
|
||||
|
||||
/**
|
||||
* Set area which can be panned
|
||||
*/
|
||||
void UI_view2d_edge_pan_set_limits(
|
||||
struct View2DEdgePanData *vpd, float xmin, float xmax, float ymin, float ymax);
|
||||
|
||||
void UI_view2d_edge_pan_reset(struct View2DEdgePanData *vpd);
|
||||
|
||||
/**
|
||||
|
@@ -67,6 +67,7 @@ void UI_view2d_edge_pan_init(bContext *C,
|
||||
vpd->area = CTX_wm_area(C);
|
||||
vpd->region = CTX_wm_region(C);
|
||||
vpd->v2d = &vpd->region->v2d;
|
||||
BLI_rctf_init(&vpd->limit, -FLT_MAX, FLT_MAX, -FLT_MAX, FLT_MAX);
|
||||
|
||||
BLI_assert(speed_ramp > 0.0f);
|
||||
vpd->inside_pad = inside_pad;
|
||||
@@ -87,6 +88,12 @@ void UI_view2d_edge_pan_init(bContext *C,
|
||||
UI_view2d_edge_pan_reset(vpd);
|
||||
}
|
||||
|
||||
void UI_view2d_edge_pan_set_limits(
|
||||
View2DEdgePanData *vpd, float xmin, float xmax, float ymin, float ymax)
|
||||
{
|
||||
BLI_rctf_init(&vpd->limit, xmin, xmax, ymin, ymax);
|
||||
}
|
||||
|
||||
void UI_view2d_edge_pan_reset(View2DEdgePanData *vpd)
|
||||
{
|
||||
vpd->edge_pan_start_time_x = 0.0;
|
||||
@@ -220,20 +227,23 @@ void UI_view2d_edge_pan_apply(bContext *C, View2DEdgePanData *vpd, const int xy[
|
||||
vpd->enabled = true;
|
||||
}
|
||||
|
||||
rctf *cur = &vpd->v2d->cur;
|
||||
rctf *limit = &vpd->limit;
|
||||
|
||||
int pan_dir_x = 0;
|
||||
int pan_dir_y = 0;
|
||||
if (vpd->enabled && ((vpd->outside_pad == 0) || BLI_rcti_isect_pt_v(&outside_rect, xy))) {
|
||||
/* Find whether the mouse is beyond X and Y edges. */
|
||||
if (xy[0] > inside_rect.xmax) {
|
||||
if (xy[0] > inside_rect.xmax && cur->xmax < limit->xmax) {
|
||||
pan_dir_x = 1;
|
||||
}
|
||||
else if (xy[0] < inside_rect.xmin) {
|
||||
else if (xy[0] < inside_rect.xmin && cur->xmin > limit->xmin) {
|
||||
pan_dir_x = -1;
|
||||
}
|
||||
if (xy[1] > inside_rect.ymax) {
|
||||
if (xy[1] > inside_rect.ymax && cur->ymax < limit->ymax) {
|
||||
pan_dir_y = 1;
|
||||
}
|
||||
else if (xy[1] < inside_rect.ymin) {
|
||||
else if (xy[1] < inside_rect.ymin && cur->ymin > limit->ymin) {
|
||||
pan_dir_y = -1;
|
||||
}
|
||||
}
|
||||
|
@@ -43,8 +43,10 @@
|
||||
#include "ED_clip.h"
|
||||
#include "ED_gpencil.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_select.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
#include "SEQ_transform.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "WM_api.h"
|
||||
@@ -645,9 +647,10 @@ static eContextResult screen_ctx_selected_editable_sequences(const bContext *C,
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
Scene *scene = WM_window_get_active_scene(win);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
if (ed) {
|
||||
LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
|
||||
if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) {
|
||||
if (seq->flag & SELECT && !SEQ_transform_is_locked(channels, seq)) {
|
||||
CTX_data_list_add(result, &scene->id, &RNA_Sequence, seq);
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,8 @@ set(SRC
|
||||
sequencer_add.c
|
||||
sequencer_buttons.c
|
||||
sequencer_draw.c
|
||||
sequencer_channels_draw.c
|
||||
sequencer_channels_edit.c
|
||||
sequencer_edit.c
|
||||
sequencer_modifier.c
|
||||
sequencer_ops.c
|
||||
|
344
source/blender/editors/space_sequencer/sequencer_channels_draw.c
Normal file
344
source/blender/editors/space_sequencer/sequencer_channels_draw.c
Normal file
@@ -0,0 +1,344 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2022 Blender Foundation. All rights reserved. */
|
||||
|
||||
/** \file
|
||||
* \ingroup sequencer
|
||||
*/
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_immediate_util.h"
|
||||
#include "GPU_matrix.h"
|
||||
#include "GPU_state.h"
|
||||
#include "GPU_vertex_buffer.h"
|
||||
#include "GPU_viewport.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_prototypes.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
#include "SEQ_time.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
/* Own include. */
|
||||
#include "sequencer_intern.h"
|
||||
|
||||
static ARegion *timeline_region_get(ScrArea *area)
|
||||
{
|
||||
LISTBASE_FOREACH (ARegion *, region, &area->regionbase) {
|
||||
if (region->regiontype == RGN_TYPE_WINDOW) {
|
||||
return region;
|
||||
}
|
||||
}
|
||||
|
||||
BLI_assert_unreachable();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static float draw_offset_get(View2D *timeline_region_v2d)
|
||||
{
|
||||
return timeline_region_v2d->cur.ymin;
|
||||
}
|
||||
|
||||
static float channel_height_pixelspace_get(View2D *timeline_region_v2d)
|
||||
{
|
||||
return UI_view2d_view_to_region_y(timeline_region_v2d, 1.0f) -
|
||||
UI_view2d_view_to_region_y(timeline_region_v2d, 0.0f);
|
||||
}
|
||||
|
||||
static float frame_width_pixelspace_get(View2D *timeline_region_v2d)
|
||||
{
|
||||
|
||||
return UI_view2d_view_to_region_x(timeline_region_v2d, 1.0f) -
|
||||
UI_view2d_view_to_region_x(timeline_region_v2d, 0.0f);
|
||||
}
|
||||
|
||||
static float icon_width_get(SeqChannelDrawContext *context)
|
||||
{
|
||||
return (U.widget_unit * 0.8 * context->scale);
|
||||
}
|
||||
|
||||
static float widget_y_offset(SeqChannelDrawContext *context)
|
||||
{
|
||||
return (((context->channel_height / context->scale) - icon_width_get(context))) / 2;
|
||||
}
|
||||
|
||||
static float channel_index_y_min(SeqChannelDrawContext *context, const int index)
|
||||
{
|
||||
float y = (index - context->draw_offset) * context->channel_height;
|
||||
y /= context->scale;
|
||||
return y;
|
||||
}
|
||||
|
||||
static void displayed_channel_range_get(SeqChannelDrawContext *context, int channel_range[2])
|
||||
{
|
||||
/* Channel 0 is not usable, so should never be drawn. */
|
||||
channel_range[0] = max_ii(1, floor(context->timeline_region_v2d->cur.ymin));
|
||||
channel_range[1] = ceil(context->timeline_region_v2d->cur.ymax);
|
||||
|
||||
rctf strip_boundbox;
|
||||
BLI_rctf_init(&strip_boundbox, 0.0f, 0.0f, 1.0f, 7);
|
||||
SEQ_timeline_expand_boundbox(context->seqbase, &strip_boundbox);
|
||||
CLAMP(channel_range[0], strip_boundbox.ymin, strip_boundbox.ymax);
|
||||
CLAMP(channel_range[1], strip_boundbox.ymin, strip_boundbox.ymax);
|
||||
}
|
||||
|
||||
static float draw_channel_widget_hide(SeqChannelDrawContext *context,
|
||||
uiBlock *block,
|
||||
int channel_index,
|
||||
float offset)
|
||||
{
|
||||
float y = channel_index_y_min(context, channel_index) + widget_y_offset(context);
|
||||
|
||||
const float width = icon_width_get(context);
|
||||
SeqTimelineChannel *channel = SEQ_channel_get_by_index(context->channels, channel_index);
|
||||
const int icon = SEQ_channel_is_muted(channel) ? ICON_CHECKBOX_DEHLT : ICON_CHECKBOX_HLT;
|
||||
const char *tooltip = BLI_sprintfN(
|
||||
"%s channel %d", SEQ_channel_is_muted(channel) ? "Unmute" : "Mute", channel_index);
|
||||
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create(&context->scene->id, &RNA_SequenceTimelineChannel, channel, &ptr);
|
||||
PropertyRNA *hide_prop = RNA_struct_type_find_property(&RNA_SequenceTimelineChannel, "mute");
|
||||
|
||||
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
||||
uiDefIconButR_prop(block,
|
||||
UI_BTYPE_TOGGLE,
|
||||
1,
|
||||
icon,
|
||||
context->v2d->cur.xmax / context->scale - offset,
|
||||
y,
|
||||
width,
|
||||
width,
|
||||
&ptr,
|
||||
hide_prop,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
tooltip);
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
static float draw_channel_widget_lock(SeqChannelDrawContext *context,
|
||||
uiBlock *block,
|
||||
int channel_index,
|
||||
float offset)
|
||||
{
|
||||
|
||||
float y = channel_index_y_min(context, channel_index) + widget_y_offset(context);
|
||||
const float width = icon_width_get(context);
|
||||
|
||||
SeqTimelineChannel *channel = SEQ_channel_get_by_index(context->channels, channel_index);
|
||||
const int icon = SEQ_channel_is_locked(channel) ? ICON_LOCKED : ICON_UNLOCKED;
|
||||
const char *tooltip = BLI_sprintfN(
|
||||
"%s channel %d", SEQ_channel_is_locked(channel) ? "Unlock" : "Lock", channel_index);
|
||||
|
||||
PointerRNA ptr;
|
||||
RNA_pointer_create(&context->scene->id, &RNA_SequenceTimelineChannel, channel, &ptr);
|
||||
PropertyRNA *hide_prop = RNA_struct_type_find_property(&RNA_SequenceTimelineChannel, "lock");
|
||||
|
||||
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
||||
uiDefIconButR_prop(block,
|
||||
UI_BTYPE_TOGGLE,
|
||||
1,
|
||||
icon,
|
||||
context->v2d->cur.xmax / context->scale - offset,
|
||||
y,
|
||||
width,
|
||||
width,
|
||||
&ptr,
|
||||
hide_prop,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
tooltip);
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
static bool channel_is_being_renamed(SpaceSeq *sseq, int channel_index)
|
||||
{
|
||||
return sseq->runtime.rename_channel_index == channel_index;
|
||||
}
|
||||
|
||||
static float text_size_get(SeqChannelDrawContext *context)
|
||||
{
|
||||
const uiStyle *style = UI_style_get_dpi();
|
||||
return UI_fontstyle_height_max(&style->widget) * 1.5f * context->scale;
|
||||
}
|
||||
|
||||
/* Todo: decide what gets priority - label or buttons */
|
||||
static void label_rect_init(SeqChannelDrawContext *context,
|
||||
int channel_index,
|
||||
float used_width,
|
||||
rctf *r_rect)
|
||||
{
|
||||
float text_size = text_size_get(context);
|
||||
float margin = (context->channel_height / context->scale - text_size) / 2.0f;
|
||||
float y = channel_index_y_min(context, channel_index) + margin;
|
||||
|
||||
float margin_x = icon_width_get(context) * 0.65;
|
||||
float width = max_ff(0.0f, context->v2d->cur.xmax / context->scale - used_width);
|
||||
|
||||
/* Text input has own margin. Prevent text jumping around and use as much space as possible. */
|
||||
if (channel_is_being_renamed(CTX_wm_space_seq(context->C), channel_index)) {
|
||||
float input_box_margin = icon_width_get(context) * 0.5f;
|
||||
margin_x -= input_box_margin;
|
||||
width += input_box_margin;
|
||||
}
|
||||
|
||||
BLI_rctf_init(r_rect, margin_x, margin_x + width, y, y + text_size);
|
||||
}
|
||||
|
||||
static void draw_channel_labels(SeqChannelDrawContext *context,
|
||||
uiBlock *block,
|
||||
int channel_index,
|
||||
float used_width)
|
||||
{
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(context->C);
|
||||
rctf rect;
|
||||
label_rect_init(context, channel_index, used_width, &rect);
|
||||
|
||||
if (BLI_rctf_size_y(&rect) <= 1.0f || BLI_rctf_size_x(&rect) <= 1.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (channel_is_being_renamed(sseq, channel_index)) {
|
||||
SeqTimelineChannel *channel = SEQ_channel_get_by_index(context->channels, channel_index);
|
||||
PointerRNA ptr = {NULL};
|
||||
RNA_pointer_create(&context->scene->id, &RNA_SequenceTimelineChannel, channel, &ptr);
|
||||
PropertyRNA *prop = RNA_struct_name_property(ptr.type);
|
||||
|
||||
UI_block_emboss_set(block, UI_EMBOSS);
|
||||
uiBut *but = uiDefButR(block,
|
||||
UI_BTYPE_TEXT,
|
||||
1,
|
||||
"",
|
||||
rect.xmin,
|
||||
rect.ymin,
|
||||
BLI_rctf_size_x(&rect),
|
||||
BLI_rctf_size_y(&rect),
|
||||
&ptr,
|
||||
RNA_property_identifier(prop),
|
||||
-1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
||||
|
||||
if (UI_but_active_only(context->C, context->region, block, but) == false) {
|
||||
sseq->runtime.rename_channel_index = 0;
|
||||
}
|
||||
|
||||
WM_event_add_notifier(context->C, NC_SCENE | ND_SEQUENCER, context->scene);
|
||||
}
|
||||
else {
|
||||
const char *label = SEQ_channel_name_get(context->channels, channel_index);
|
||||
uiDefBut(block,
|
||||
UI_BTYPE_LABEL,
|
||||
0,
|
||||
label,
|
||||
rect.xmin,
|
||||
rect.ymin,
|
||||
rect.xmax - rect.xmin,
|
||||
(rect.ymax - rect.ymin),
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Todo: different text/buttons alignment */
|
||||
static void draw_channel_header(SeqChannelDrawContext *context, uiBlock *block, int channel_index)
|
||||
{
|
||||
float offset = icon_width_get(context) * 1.5f;
|
||||
offset += draw_channel_widget_lock(context, block, channel_index, offset);
|
||||
offset += draw_channel_widget_hide(context, block, channel_index, offset);
|
||||
|
||||
draw_channel_labels(context, block, channel_index, offset);
|
||||
}
|
||||
|
||||
static void draw_channel_headers(SeqChannelDrawContext *context)
|
||||
{
|
||||
GPU_matrix_push();
|
||||
wmOrtho2_pixelspace(context->region->winx / context->scale,
|
||||
context->region->winy / context->scale);
|
||||
uiBlock *block = UI_block_begin(context->C, context->region, __func__, UI_EMBOSS);
|
||||
|
||||
int channel_range[2];
|
||||
displayed_channel_range_get(context, channel_range);
|
||||
|
||||
for (int channel = channel_range[0]; channel <= channel_range[1]; channel++) {
|
||||
draw_channel_header(context, block, channel);
|
||||
}
|
||||
|
||||
UI_block_end(context->C, block);
|
||||
UI_block_draw(context->C, block);
|
||||
|
||||
GPU_matrix_pop();
|
||||
}
|
||||
|
||||
static void draw_background(SeqChannelDrawContext *context)
|
||||
{
|
||||
UI_ThemeClearColor(TH_BACK);
|
||||
}
|
||||
|
||||
void channel_draw_context_init(const bContext *C,
|
||||
ARegion *region,
|
||||
SeqChannelDrawContext *r_context)
|
||||
{
|
||||
r_context->C = C;
|
||||
r_context->area = CTX_wm_area(C);
|
||||
r_context->region = region;
|
||||
r_context->v2d = ®ion->v2d;
|
||||
r_context->scene = CTX_data_scene(C);
|
||||
r_context->ed = SEQ_editing_get(r_context->scene);
|
||||
r_context->seqbase = SEQ_active_seqbase_get(r_context->ed);
|
||||
r_context->channels = SEQ_channels_active_get(r_context->ed);
|
||||
r_context->timeline_region = timeline_region_get(CTX_wm_area(C));
|
||||
r_context->timeline_region_v2d = &r_context->timeline_region->v2d;
|
||||
|
||||
r_context->channel_height = channel_height_pixelspace_get(r_context->timeline_region_v2d);
|
||||
r_context->frame_width = frame_width_pixelspace_get(r_context->timeline_region_v2d);
|
||||
r_context->draw_offset = draw_offset_get(r_context->timeline_region_v2d);
|
||||
|
||||
r_context->scale = min_ff(r_context->channel_height / (U.widget_unit * 0.6), 1);
|
||||
}
|
||||
|
||||
void draw_channels(const bContext *C, ARegion *region)
|
||||
{
|
||||
SeqChannelDrawContext context;
|
||||
channel_draw_context_init(C, region, &context);
|
||||
|
||||
UI_view2d_view_ortho(context.v2d);
|
||||
|
||||
draw_background(&context);
|
||||
draw_channel_headers(&context);
|
||||
|
||||
UI_view2d_view_restore(C);
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2022 Blender Foundation. All rights reserved. */
|
||||
|
||||
/** \file
|
||||
* \ingroup sequencer
|
||||
*/
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
#include "SEQ_time.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
/* Own include. */
|
||||
#include "sequencer_intern.h"
|
||||
|
||||
static int sequencer_rename_channel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
SeqChannelDrawContext context;
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
||||
channel_draw_context_init(C, CTX_wm_region(C), &context);
|
||||
float mouse_y = UI_view2d_region_to_view_y(context.timeline_region_v2d, event->mval[1]);
|
||||
|
||||
sseq->runtime.rename_channel_index = mouse_y;
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, CTX_data_scene(C));
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void SEQUENCER_OT_rename_channel(struct wmOperatorType *ot)
|
||||
{
|
||||
/* Identifiers. */
|
||||
ot->name = "Rename Channel";
|
||||
ot->idname = "SEQUENCER_OT_channel_rename";
|
||||
|
||||
/* Api callbacks. */
|
||||
ot->invoke = sequencer_rename_channel_invoke;
|
||||
ot->poll = sequencer_edit_poll;
|
||||
|
||||
/* Flags. */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
}
|
@@ -67,6 +67,7 @@
|
||||
#include "SEQ_time.h"
|
||||
#include "SEQ_transform.h"
|
||||
#include "SEQ_utils.h"
|
||||
#include "SEQ_channels.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
@@ -95,6 +96,9 @@ void color3ubv_from_seq(const Scene *curscene,
|
||||
const bool show_strip_color_tag,
|
||||
uchar r_col[3])
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(curscene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
|
||||
if (show_strip_color_tag && (uint)seq->color_tag < SEQUENCE_COLOR_TOT &&
|
||||
seq->color_tag != SEQUENCE_COLOR_NONE) {
|
||||
bTheme *btheme = UI_GetTheme();
|
||||
@@ -214,7 +218,7 @@ void color3ubv_from_seq(const Scene *curscene,
|
||||
case SEQ_TYPE_SOUND_RAM:
|
||||
UI_GetThemeColor3ubv(TH_SEQ_AUDIO, r_col);
|
||||
blendcol[0] = blendcol[1] = blendcol[2] = 128;
|
||||
if (seq->flag & SEQ_MUTE) {
|
||||
if (SEQ_render_is_muted(channels, seq)) {
|
||||
UI_GetColorPtrBlendShade3ubv(r_col, blendcol, r_col, 0.5, 20);
|
||||
}
|
||||
break;
|
||||
@@ -568,6 +572,8 @@ static void drawmeta_contents(Scene *scene,
|
||||
float y2,
|
||||
const bool show_strip_color_tag)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
Sequence *seq;
|
||||
uchar col[4];
|
||||
|
||||
@@ -625,7 +631,7 @@ static void drawmeta_contents(Scene *scene,
|
||||
color3ubv_from_seq(scene, seq, show_strip_color_tag, col);
|
||||
}
|
||||
|
||||
if ((seqm->flag & SEQ_MUTE) || (seq->flag & SEQ_MUTE)) {
|
||||
if (SEQ_render_is_muted(channels, seqm) || SEQ_render_is_muted(channels, seq)) {
|
||||
col[3] = 64;
|
||||
}
|
||||
else {
|
||||
@@ -919,7 +925,8 @@ static size_t draw_seq_text_get_overlay_string(SpaceSeq *sseq,
|
||||
}
|
||||
|
||||
/* Draw info text on a sequence strip. */
|
||||
static void draw_seq_text_overlay(View2D *v2d,
|
||||
static void draw_seq_text_overlay(Scene *scene,
|
||||
View2D *v2d,
|
||||
Sequence *seq,
|
||||
SpaceSeq *sseq,
|
||||
float x1,
|
||||
@@ -928,6 +935,8 @@ static void draw_seq_text_overlay(View2D *v2d,
|
||||
float y2,
|
||||
bool seq_active)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
char overlay_string[FILE_MAX];
|
||||
size_t overlay_string_len = draw_seq_text_get_overlay_string(
|
||||
sseq, seq, overlay_string, sizeof(overlay_string));
|
||||
@@ -942,7 +951,7 @@ static void draw_seq_text_overlay(View2D *v2d,
|
||||
col[3] = 255;
|
||||
|
||||
/* Make the text duller when the strip is muted. */
|
||||
if (seq->flag & SEQ_MUTE) {
|
||||
if (SEQ_render_is_muted(channels, seq)) {
|
||||
if (seq_active) {
|
||||
UI_GetColorPtrShade3ubv(col, col, -70);
|
||||
}
|
||||
@@ -963,6 +972,8 @@ static void draw_seq_text_overlay(View2D *v2d,
|
||||
static void draw_sequence_extensions_overlay(
|
||||
Scene *scene, Sequence *seq, uint pos, float pixely, const bool show_strip_color_tag)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
float x1, x2, y1, y2;
|
||||
uchar col[4], blend_col[3];
|
||||
|
||||
@@ -978,7 +989,7 @@ static void draw_sequence_extensions_overlay(
|
||||
if (seq->flag & SELECT) {
|
||||
UI_GetColorPtrShade3ubv(col, col, 50);
|
||||
}
|
||||
col[3] = seq->flag & SEQ_MUTE ? MUTE_ALPHA : 200;
|
||||
col[3] = SEQ_render_is_muted(channels, seq) ? MUTE_ALPHA : 200;
|
||||
UI_GetColorPtrShade3ubv(col, blend_col, 10);
|
||||
|
||||
if (seq->startofs) {
|
||||
@@ -1001,7 +1012,8 @@ static void draw_sequence_extensions_overlay(
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, float y1)
|
||||
static void draw_color_strip_band(
|
||||
ListBase *channels, Sequence *seq, uint pos, float text_margin_y, float y1)
|
||||
{
|
||||
uchar col[4];
|
||||
SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
|
||||
@@ -1010,7 +1022,7 @@ static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y,
|
||||
rgb_float_to_uchar(col, colvars->col);
|
||||
|
||||
/* Draw muted strips semi-transparent. */
|
||||
if (seq->flag & SEQ_MUTE) {
|
||||
if (SEQ_render_is_muted(channels, seq)) {
|
||||
col[3] = MUTE_ALPHA;
|
||||
}
|
||||
/* Draw background semi-transparent when overlapping strips. */
|
||||
@@ -1047,6 +1059,8 @@ static void draw_seq_background(Scene *scene,
|
||||
bool is_single_image,
|
||||
bool show_strip_color_tag)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
uchar col[4];
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
@@ -1066,7 +1080,7 @@ static void draw_seq_background(Scene *scene,
|
||||
}
|
||||
|
||||
/* Draw muted strips semi-transparent. */
|
||||
if (seq->flag & SEQ_MUTE) {
|
||||
if (SEQ_render_is_muted(channels, seq)) {
|
||||
col[3] = MUTE_ALPHA;
|
||||
}
|
||||
/* Draw background semi-transparent when overlapping strips. */
|
||||
@@ -1303,6 +1317,9 @@ static void draw_seq_strip(const bContext *C,
|
||||
float pixelx,
|
||||
bool seq_active)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(CTX_data_scene(C));
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
|
||||
View2D *v2d = ®ion->v2d;
|
||||
float x1, x2, y1, y2;
|
||||
const float handsize_clamped = sequence_handle_size_get_clamped(seq, pixelx);
|
||||
@@ -1349,7 +1366,7 @@ static void draw_seq_strip(const bContext *C,
|
||||
|
||||
/* Draw a color band inside color strip. */
|
||||
if (seq->type == SEQ_TYPE_COLOR && y_threshold) {
|
||||
draw_color_strip_band(seq, pos, text_margin_y, y1);
|
||||
draw_color_strip_band(channels, seq, pos, text_margin_y, y1);
|
||||
}
|
||||
|
||||
/* Draw strip offsets when flag is enabled or during "solo preview". */
|
||||
@@ -1398,7 +1415,7 @@ static void draw_seq_strip(const bContext *C,
|
||||
BLI_rctf_size_x(®ion->v2d.cur) / region->winx);
|
||||
}
|
||||
/* Draw locked state. */
|
||||
if (seq->flag & SEQ_LOCK) {
|
||||
if (SEQ_transform_is_locked(channels, seq)) {
|
||||
draw_seq_locked(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
@@ -1410,7 +1427,7 @@ static void draw_seq_strip(const bContext *C,
|
||||
pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
|
||||
if ((seq->flag & SEQ_LOCK) == 0) {
|
||||
if (!SEQ_transform_is_locked(channels, seq)) {
|
||||
draw_seq_handle(
|
||||
v2d, seq, handsize_clamped, SEQ_LEFTHANDLE, pos, seq_active, pixelx, y_threshold);
|
||||
draw_seq_handle(
|
||||
@@ -1437,7 +1454,7 @@ static void draw_seq_strip(const bContext *C,
|
||||
if (((x2 - x1) > 32 * pixelx * U.dpi_fac) && ((y2 - y1) > 8 * pixely * U.dpi_fac)) {
|
||||
/* Depending on the vertical space, draw text on top or in the center of strip. */
|
||||
draw_seq_text_overlay(
|
||||
v2d, seq, sseq, x1, x2, y_threshold ? text_margin_y : y1, y2, seq_active);
|
||||
scene, v2d, seq, sseq, x1, x2, y_threshold ? text_margin_y : y1, y2, seq_active);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2218,7 +2235,10 @@ void sequencer_draw_preview(const bContext *C,
|
||||
}
|
||||
|
||||
if (!draw_backdrop && scene->ed != NULL) {
|
||||
SeqCollection *collection = SEQ_query_rendered_strips(scene->ed->seqbasep, timeline_frame, 0);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
SeqCollection *collection = SEQ_query_rendered_strips(
|
||||
channels, ed->seqbasep, timeline_frame, 0);
|
||||
Sequence *seq;
|
||||
Sequence *active_seq = SEQ_select_active_get(scene);
|
||||
SEQ_ITERATOR_FOREACH (seq, collection) {
|
||||
@@ -2269,14 +2289,6 @@ static void draw_seq_timeline_channels(View2D *v2d)
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void draw_seq_timeline_channel_numbers(ARegion *region)
|
||||
{
|
||||
View2D *v2d = ®ion->v2d;
|
||||
rcti rect;
|
||||
BLI_rcti_init(&rect, 0, 15 * UI_DPI_FAC, 15 * UI_DPI_FAC, region->winy - UI_TIME_SCRUB_MARGIN_Y);
|
||||
UI_view2d_draw_scale_y__block(region, v2d, &rect, TH_SCROLL_TEXT);
|
||||
}
|
||||
|
||||
static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
@@ -2695,6 +2707,7 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
|
||||
|
||||
UI_view2d_view_ortho(v2d);
|
||||
draw_seq_timeline_channels(v2d);
|
||||
|
||||
if ((sseq->flag & SEQ_SHOW_OVERLAY) && (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_GRID)) {
|
||||
U.v2d_min_gridsize *= 3;
|
||||
UI_view2d_draw_lines_x__discrete_frames_or_seconds(
|
||||
@@ -2748,8 +2761,6 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
|
||||
|
||||
UI_view2d_view_restore(C);
|
||||
ED_time_scrub_draw(region, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
|
||||
|
||||
draw_seq_timeline_channel_numbers(region);
|
||||
}
|
||||
|
||||
void draw_timeline_seq_display(const bContext *C, ARegion *region)
|
||||
|
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "SEQ_add.h"
|
||||
#include "SEQ_animation.h"
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_clipboard.h"
|
||||
#include "SEQ_edit.h"
|
||||
#include "SEQ_effects.h"
|
||||
@@ -345,6 +346,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
|
||||
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
Sequence *seq;
|
||||
int snap_frame;
|
||||
|
||||
@@ -352,7 +354,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* Check meta-strips. */
|
||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||
if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK) &&
|
||||
if (seq->flag & SELECT && !SEQ_transform_is_locked(channels, seq) &&
|
||||
SEQ_transform_sequence_can_be_translated(seq)) {
|
||||
if ((seq->flag & (SEQ_LEFTSEL + SEQ_RIGHTSEL)) == 0) {
|
||||
SEQ_transform_translate_sequence(
|
||||
@@ -374,7 +376,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* Test for effects and overlap. */
|
||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||
if (seq->flag & SELECT && !(seq->flag & SEQ_LOCK)) {
|
||||
if (seq->flag & SELECT && !SEQ_transform_is_locked(channels, seq)) {
|
||||
seq->flag &= ~SEQ_OVERLAP;
|
||||
if (SEQ_transform_test_overlap(ed->seqbasep, seq)) {
|
||||
SEQ_transform_seqbase_shuffle(ed->seqbasep, seq, scene);
|
||||
@@ -918,13 +920,14 @@ static int sequencer_mute_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
Sequence *seq;
|
||||
bool selected;
|
||||
|
||||
selected = !RNA_boolean_get(op->ptr, "unselected");
|
||||
|
||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||
if ((seq->flag & SEQ_LOCK) == 0) {
|
||||
if (!SEQ_transform_is_locked(channels, seq)) {
|
||||
if (selected) {
|
||||
if (seq->flag & SELECT) {
|
||||
seq->flag |= SEQ_MUTE;
|
||||
@@ -974,13 +977,14 @@ static int sequencer_unmute_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
Sequence *seq;
|
||||
bool selected;
|
||||
|
||||
selected = !RNA_boolean_get(op->ptr, "unselected");
|
||||
|
||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||
if ((seq->flag & SEQ_LOCK) == 0) {
|
||||
if (!SEQ_transform_is_locked(channels, seq)) {
|
||||
if (selected) {
|
||||
if (seq->flag & SELECT) {
|
||||
seq->flag &= ~SEQ_MUTE;
|
||||
@@ -1768,25 +1772,12 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS);
|
||||
DEG_relations_tag_update(bmain);
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
||||
sseq->flag |= SPACE_SEQ_CLAMP_SMOOTH;
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int sequencer_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
|
||||
if (region->regiontype == RGN_TYPE_WINDOW) {
|
||||
/* Bounding box of 30 pixels is used for markers shortcuts,
|
||||
* prevent conflict with markers shortcuts here.
|
||||
*/
|
||||
if (event->mval[1] <= 30) {
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
}
|
||||
|
||||
return sequencer_delete_exec(C, op);
|
||||
}
|
||||
|
||||
void SEQUENCER_OT_delete(wmOperatorType *ot)
|
||||
{
|
||||
|
||||
@@ -1796,7 +1787,6 @@ void SEQUENCER_OT_delete(wmOperatorType *ot)
|
||||
ot->description = "Erase selected strips from the sequencer";
|
||||
|
||||
/* Api callbacks. */
|
||||
ot->invoke = sequencer_delete_invoke;
|
||||
ot->exec = sequencer_delete_exec;
|
||||
ot->poll = sequencer_edit_poll;
|
||||
|
||||
@@ -1987,6 +1977,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
/* Enter meta-strip. */
|
||||
SEQ_meta_stack_alloc(ed, active_seq);
|
||||
SEQ_seqbase_active_set(ed, &active_seq->seqbase);
|
||||
SEQ_channels_active_set(ed, &active_seq->channels);
|
||||
SEQ_select_active_set(scene, NULL);
|
||||
}
|
||||
else {
|
||||
@@ -1997,6 +1988,7 @@ static int sequencer_meta_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
|
||||
MetaStack *ms = SEQ_meta_stack_active_get(ed);
|
||||
SEQ_seqbase_active_set(ed, ms->oldbasep);
|
||||
SEQ_channels_active_set(ed, ms->old_channels);
|
||||
SEQ_select_active_set(scene, ms->parseq);
|
||||
SEQ_meta_stack_free(ed, ms);
|
||||
}
|
||||
@@ -3111,8 +3103,10 @@ typedef struct Seq_get_text_cb_data {
|
||||
static bool seq_get_text_strip_cb(Sequence *seq, void *user_data)
|
||||
{
|
||||
Seq_get_text_cb_data *cd = (Seq_get_text_cb_data *)user_data;
|
||||
Editing *ed = SEQ_editing_get(cd->scene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
/* Only text strips that are not muted and don't end with negative frame. */
|
||||
if ((seq->type == SEQ_TYPE_TEXT) && ((seq->flag & SEQ_MUTE) == 0) &&
|
||||
if ((seq->type == SEQ_TYPE_TEXT) && !SEQ_render_is_muted(channels, seq) &&
|
||||
(seq->enddisp > cd->scene->r.sfra)) {
|
||||
BLI_addtail(cd->text_seq, MEM_dupallocN(seq));
|
||||
}
|
||||
|
@@ -25,9 +25,31 @@ struct View2D;
|
||||
struct bContext;
|
||||
struct rctf;
|
||||
struct wmOperator;
|
||||
struct ScrArea;
|
||||
struct Editing;
|
||||
struct ListBase;
|
||||
|
||||
#define OVERLAP_ALPHA 180
|
||||
|
||||
typedef struct SeqChannelDrawContext {
|
||||
const struct bContext *C;
|
||||
struct ScrArea *area;
|
||||
struct ARegion *region;
|
||||
struct ARegion *timeline_region;
|
||||
struct View2D *v2d;
|
||||
struct View2D *timeline_region_v2d;
|
||||
|
||||
struct Scene *scene;
|
||||
struct Editing *ed;
|
||||
struct ListBase *seqbase; /* Active seqbase. */
|
||||
struct ListBase *channels; /* Active channels. */
|
||||
|
||||
float draw_offset;
|
||||
float channel_height;
|
||||
float frame_width;
|
||||
float scale;
|
||||
} SeqChannelDrawContext;
|
||||
|
||||
/* sequencer_draw.c */
|
||||
void draw_timeline_seq(const struct bContext *C, struct ARegion *region);
|
||||
void draw_timeline_seq_display(const struct bContext *C, struct ARegion *region);
|
||||
@@ -78,6 +100,11 @@ void draw_seq_strip_thumbnail(struct View2D *v2d,
|
||||
float pixelx,
|
||||
float pixely);
|
||||
|
||||
/* sequencer_draw_channels.c */
|
||||
void draw_channels(const struct bContext *C, struct ARegion *region);
|
||||
void channel_draw_context_init(const struct bContext *C,
|
||||
struct ARegion *region,
|
||||
struct SeqChannelDrawContext *r_context);
|
||||
/* sequencer_edit.c */
|
||||
struct View2D;
|
||||
void seq_rectf(struct Sequence *seq, struct rctf *rectf);
|
||||
@@ -232,6 +259,9 @@ void SEQUENCER_OT_view_zoom_ratio(struct wmOperatorType *ot);
|
||||
void SEQUENCER_OT_view_selected(struct wmOperatorType *ot);
|
||||
void SEQUENCER_OT_view_ghost_border(struct wmOperatorType *ot);
|
||||
|
||||
/* sequencer_channels_edit.c */
|
||||
void SEQUENCER_OT_rename_channel(struct wmOperatorType *ot);
|
||||
|
||||
/* sequencer_preview.c */
|
||||
void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq);
|
||||
|
||||
|
@@ -102,6 +102,9 @@ void sequencer_operatortypes(void)
|
||||
WM_operatortype_append(SEQUENCER_OT_view_zoom_ratio);
|
||||
WM_operatortype_append(SEQUENCER_OT_view_selected);
|
||||
WM_operatortype_append(SEQUENCER_OT_view_ghost_border);
|
||||
|
||||
/* sequencer_channels_edit.c */
|
||||
WM_operatortype_append(SEQUENCER_OT_rename_channel);
|
||||
}
|
||||
|
||||
void sequencer_keymap(wmKeyConfig *keyconf)
|
||||
@@ -114,6 +117,9 @@ void sequencer_keymap(wmKeyConfig *keyconf)
|
||||
|
||||
/* Preview Region ----------------------------------------------------------- */
|
||||
WM_keymap_ensure(keyconf, "SequencerPreview", SPACE_SEQ, 0);
|
||||
|
||||
/* Channels Region ----------------------------------------------------------- */
|
||||
WM_keymap_ensure(keyconf, "Sequencer Channels", SPACE_SEQ, 0);
|
||||
}
|
||||
|
||||
void ED_operatormacros_sequencer(void)
|
||||
|
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_select.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
@@ -51,11 +52,13 @@
|
||||
SeqCollection *all_strips_from_context(bContext *C)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
|
||||
const bool is_preview = sequencer_view_has_preview_poll(C);
|
||||
if (is_preview) {
|
||||
return SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0);
|
||||
return SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0);
|
||||
}
|
||||
|
||||
return SEQ_query_all_strips(seqbase);
|
||||
@@ -64,11 +67,13 @@ SeqCollection *all_strips_from_context(bContext *C)
|
||||
SeqCollection *selected_strips_from_context(bContext *C)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
|
||||
const bool is_preview = sequencer_view_has_preview_poll(C);
|
||||
if (is_preview) {
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0);
|
||||
SEQ_filter_selected_strips(strips);
|
||||
return strips;
|
||||
}
|
||||
@@ -709,6 +714,7 @@ static Sequence *seq_select_seq_from_preview(
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
||||
View2D *v2d = UI_view2d_fromcontext(C);
|
||||
|
||||
@@ -718,7 +724,8 @@ static Sequence *seq_select_seq_from_preview(
|
||||
/* Always update the coordinates (check extended after). */
|
||||
const bool use_cycle = (!WM_cursor_test_motion_and_update(mval) || extend || toggle);
|
||||
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, sseq->chanshown);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(
|
||||
channels, seqbase, scene->r.cfra, sseq->chanshown);
|
||||
|
||||
/* Allow strips this far from the closest center to be included.
|
||||
* This allows cycling over center points which are near enough
|
||||
@@ -1574,9 +1581,11 @@ static void seq_box_select_seq_from_preview(const bContext *C, rctf *rect, const
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
||||
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, sseq->chanshown);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(
|
||||
channels, seqbase, scene->r.cfra, sseq->chanshown);
|
||||
Sequence *seq;
|
||||
SEQ_ITERATOR_FOREACH (seq, strips) {
|
||||
if (!seq_box_select_rect_image_isect(scene, seq, rect)) {
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include "ED_anim_api.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_util_imbuf.h"
|
||||
#include "ED_time_scrub_ui.h"
|
||||
|
||||
/* Own include. */
|
||||
#include "sequencer_intern.h"
|
||||
@@ -84,6 +85,16 @@ static int sequencer_view_all_exec(bContext *C, wmOperator *op)
|
||||
box.xmax = ms->disp_range[1] + 1;
|
||||
}
|
||||
SEQ_timeline_expand_boundbox(SEQ_active_seqbase_get(ed), &box);
|
||||
|
||||
View2D *v2d = ®ion->v2d;
|
||||
rcti scrub_rect;
|
||||
ED_time_scrub_region_rect_get(region, &scrub_rect);
|
||||
const float pixel_view_size_y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
|
||||
const float scrub_bar_height = BLI_rcti_size_y(&scrub_rect) * pixel_view_size_y;
|
||||
|
||||
/* Channel n has range of <n, n+1>. */
|
||||
box.ymax += 1.0f + scrub_bar_height;
|
||||
|
||||
UI_view2d_smooth_view(C, region, &box, smooth_viewtx);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
@@ -29,8 +30,10 @@
|
||||
|
||||
#include "GPU_state.h"
|
||||
|
||||
#include "ED_markers.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_space_api.h"
|
||||
#include "ED_time_scrub_ui.h"
|
||||
#include "ED_transform.h"
|
||||
#include "ED_view3d.h"
|
||||
#include "ED_view3d_offscreen.h" /* Only for sequencer view3d drawing callback. */
|
||||
@@ -41,6 +44,8 @@
|
||||
|
||||
#include "RNA_access.h"
|
||||
|
||||
#include "SEQ_sequencer.h"
|
||||
#include "SEQ_time.h"
|
||||
#include "SEQ_transform.h"
|
||||
#include "SEQ_utils.h"
|
||||
|
||||
@@ -131,6 +136,14 @@ static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *sce
|
||||
region->regiontype = RGN_TYPE_TOOLS;
|
||||
region->alignment = RGN_ALIGN_LEFT;
|
||||
region->flag = RGN_FLAG_HIDDEN;
|
||||
region->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL;
|
||||
|
||||
/* Toolbar. */
|
||||
region = MEM_callocN(sizeof(ARegion), "channels for sequencer");
|
||||
|
||||
BLI_addtail(&sseq->regionbase, region);
|
||||
region->regiontype = RGN_TYPE_CHANNELS;
|
||||
region->alignment = RGN_ALIGN_LEFT;
|
||||
|
||||
/* Preview region. */
|
||||
/* NOTE: if you change values here, also change them in sequencer_init_preview_region. */
|
||||
@@ -165,7 +178,7 @@ static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *sce
|
||||
region->v2d.tot.xmin = 0.0f;
|
||||
region->v2d.tot.ymin = 0.0f;
|
||||
region->v2d.tot.xmax = scene->r.efra;
|
||||
region->v2d.tot.ymax = 8.0f;
|
||||
region->v2d.tot.ymax = 8.5f;
|
||||
|
||||
region->v2d.cur = region->v2d.tot;
|
||||
|
||||
@@ -182,7 +195,7 @@ static SpaceLink *sequencer_create(const ScrArea *UNUSED(area), const Scene *sce
|
||||
region->v2d.scroll |= (V2D_SCROLL_RIGHT | V2D_SCROLL_VERTICAL_HANDLES);
|
||||
region->v2d.keepzoom = 0;
|
||||
region->v2d.keeptot = 0;
|
||||
region->v2d.align = V2D_ALIGN_NO_NEG_Y;
|
||||
region->v2d.flag |= V2D_VIEWSYNC_AREA_VERTICAL;
|
||||
|
||||
sseq->runtime.last_displayed_thumbnails = NULL;
|
||||
|
||||
@@ -631,6 +644,93 @@ static void sequencer_main_region_draw_overlay(const bContext *C, ARegion *regio
|
||||
draw_timeline_seq_display(C, region);
|
||||
}
|
||||
|
||||
struct View2DScrollers {
|
||||
int vert_min, vert_max; /* vertical scrollbar */
|
||||
int hor_min, hor_max; /* horizontal scrollbar */
|
||||
|
||||
/* These values are written into, even if we don't use them. */
|
||||
rcti _hor, _vert;
|
||||
};
|
||||
|
||||
static void sequencer_main_clamp_view(const bContext *C, ARegion *region)
|
||||
{
|
||||
View2D *v2d = ®ion->v2d;
|
||||
Editing *ed = SEQ_editing_get(CTX_data_scene(C));
|
||||
|
||||
/* Transformation uses edge panning to move view. Also if smooth view is running, don't apply
|
||||
* clamping to prevent overriding this functionality. */
|
||||
if (G.moving || v2d->smooth_timer != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize default view with 7 channels, that are visible even if empty. */
|
||||
rctf strip_boundbox;
|
||||
BLI_rctf_init(&strip_boundbox, 0.0f, 0.0f, 1.0f, 7.0f);
|
||||
SEQ_timeline_expand_boundbox(ed->seqbasep, &strip_boundbox);
|
||||
|
||||
/* Clamp Y max. Scrubbing area height must be added, so strips aren't occluded. */
|
||||
rcti scrub_rect;
|
||||
ED_time_scrub_region_rect_get(region, &scrub_rect);
|
||||
const float pixel_view_size_y = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
|
||||
const float scrub_bar_height = BLI_rcti_size_y(&scrub_rect) * pixel_view_size_y;
|
||||
|
||||
/* Channel n has range of <n, n+1>. */
|
||||
strip_boundbox.ymax += 1.0f + scrub_bar_height;
|
||||
|
||||
/* Clamp Y min. Scroller and marker area height must be added, so strips aren't occluded. */
|
||||
struct View2DScrollers scrollers;
|
||||
UI_view2d_scrollers_calc(v2d, NULL, &scrollers);
|
||||
float scroll_bar_height = scrollers._hor.ymax * pixel_view_size_y;
|
||||
|
||||
ListBase *markers = ED_context_get_markers(C);
|
||||
if (markers != NULL && !BLI_listbase_is_empty(markers)) {
|
||||
float markers_size = UI_MARKER_MARGIN_Y * pixel_view_size_y;
|
||||
strip_boundbox.ymin -= markers_size;
|
||||
}
|
||||
else {
|
||||
strip_boundbox.ymin -= scroll_bar_height;
|
||||
}
|
||||
|
||||
rctf view_clamped = v2d->cur;
|
||||
bool do_clamp = false;
|
||||
|
||||
const float range_y = BLI_rctf_size_y(&view_clamped);
|
||||
if (view_clamped.ymax > strip_boundbox.ymax) {
|
||||
view_clamped.ymax = strip_boundbox.ymax;
|
||||
view_clamped.ymin = max_ff(strip_boundbox.ymin, strip_boundbox.ymax - range_y);
|
||||
do_clamp = true;
|
||||
}
|
||||
if (view_clamped.ymin < strip_boundbox.ymin) {
|
||||
view_clamped.ymin = strip_boundbox.ymin;
|
||||
view_clamped.ymax = min_ff(strip_boundbox.ymax, strip_boundbox.ymin + range_y);
|
||||
do_clamp = true;
|
||||
}
|
||||
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
||||
if (do_clamp) {
|
||||
if ((sseq->flag & SPACE_SEQ_CLAMP_SMOOTH) != 0) {
|
||||
UI_view2d_smooth_view(C, region, &view_clamped, U.smooth_viewtx);
|
||||
}
|
||||
else {
|
||||
v2d->cur = view_clamped;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear flag for smooth view even if no limiting occured. It is set by operators that change
|
||||
* strip position. */
|
||||
sseq->flag &= ~SPACE_SEQ_CLAMP_SMOOTH;
|
||||
}
|
||||
|
||||
static void sequencer_main_region_layout(const bContext *C, ARegion *region)
|
||||
{
|
||||
sequencer_main_clamp_view(C, region);
|
||||
}
|
||||
|
||||
static void sequencer_main_region_view2d_changed(const bContext *C, ARegion *region)
|
||||
{
|
||||
sequencer_main_clamp_view(C, region);
|
||||
}
|
||||
|
||||
static void sequencer_main_region_listener(const wmRegionListenerParams *params)
|
||||
{
|
||||
ARegion *region = params->region;
|
||||
@@ -977,6 +1077,24 @@ static void sequencer_id_remap(ScrArea *UNUSED(area),
|
||||
|
||||
/* ************************************* */
|
||||
|
||||
/* add handlers, stuff you only do once or on area/region changes */
|
||||
static void sequencer_channel_region_init(wmWindowManager *wm, ARegion *region)
|
||||
{
|
||||
wmKeyMap *keymap;
|
||||
|
||||
region->alignment = RGN_ALIGN_LEFT;
|
||||
|
||||
UI_view2d_region_reinit(®ion->v2d, V2D_COMMONVIEW_LIST, region->winx, region->winy);
|
||||
|
||||
keymap = WM_keymap_ensure(wm->defaultconf, "Sequencer Channels", SPACE_SEQ, 0);
|
||||
WM_event_add_keymap_handler_v2d_mask(®ion->handlers, keymap);
|
||||
}
|
||||
|
||||
static void sequencer_channel_region_draw(const bContext *C, ARegion *region)
|
||||
{
|
||||
draw_channels(C, region);
|
||||
}
|
||||
|
||||
void ED_spacetype_sequencer(void)
|
||||
{
|
||||
SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype sequencer");
|
||||
@@ -1005,6 +1123,8 @@ void ED_spacetype_sequencer(void)
|
||||
art->init = sequencer_main_region_init;
|
||||
art->draw = sequencer_main_region_draw;
|
||||
art->draw_overlay = sequencer_main_region_draw_overlay;
|
||||
art->layout = sequencer_main_region_layout;
|
||||
art->on_view2d_changed = sequencer_main_region_view2d_changed;
|
||||
art->listener = sequencer_main_region_listener;
|
||||
art->message_subscribe = sequencer_main_region_message_subscribe;
|
||||
/* NOTE: inclusion of #ED_KEYMAP_GIZMO is currently for scripts and isn't used by default. */
|
||||
@@ -1048,6 +1168,16 @@ void ED_spacetype_sequencer(void)
|
||||
art->draw = sequencer_tools_region_draw;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
/* Channels. */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer channels");
|
||||
art->regionid = RGN_TYPE_CHANNELS;
|
||||
art->prefsizex = UI_COMPACT_PANEL_WIDTH;
|
||||
art->keymapflag = ED_KEYMAP_UI;
|
||||
art->init = sequencer_channel_region_init;
|
||||
art->draw = sequencer_channel_region_draw;
|
||||
art->listener = sequencer_main_region_listener;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
/* Tool header. */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype sequencer tool header region");
|
||||
art->regionid = RGN_TYPE_TOOL_HEADER;
|
||||
|
@@ -17,8 +17,10 @@
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "ED_markers.h"
|
||||
#include "ED_time_scrub_ui.h"
|
||||
|
||||
#include "SEQ_animation.h"
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_edit.h"
|
||||
#include "SEQ_effects.h"
|
||||
#include "SEQ_iterator.h"
|
||||
@@ -33,6 +35,13 @@
|
||||
#include "transform.h"
|
||||
#include "transform_convert.h"
|
||||
|
||||
#define SEQ_EDGE_PAN_INSIDE_PAD 2
|
||||
#define SEQ_EDGE_PAN_OUTSIDE_PAD 0 /* Disable clamping for panning, use whole screen. */
|
||||
#define SEQ_EDGE_PAN_SPEED_RAMP 1
|
||||
#define SEQ_EDGE_PAN_MAX_SPEED 4 /* In UI units per second, slower than default. */
|
||||
#define SEQ_EDGE_PAN_DELAY 1.0f
|
||||
#define SEQ_EDGE_PAN_ZOOM_INFLUENCE 0.5f
|
||||
|
||||
/** Used for sequencer transform. */
|
||||
typedef struct TransDataSeq {
|
||||
struct Sequence *seq;
|
||||
@@ -53,6 +62,10 @@ typedef struct TransSeq {
|
||||
TransDataSeq *tdseq;
|
||||
int selection_channel_range_min;
|
||||
int selection_channel_range_max;
|
||||
|
||||
/* Initial rect of the view2d, used for computing offset during edge panning */
|
||||
rctf initial_v2d_cur;
|
||||
View2DEdgePanData edge_pan;
|
||||
} TransSeq;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -66,17 +79,19 @@ typedef struct TransSeq {
|
||||
*/
|
||||
static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_count, int *r_flag)
|
||||
{
|
||||
Scene *scene = t->scene;
|
||||
Editing *ed = SEQ_editing_get(t->scene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
|
||||
/* for extend we need to do some tricks */
|
||||
if (t->mode == TFM_TIME_EXTEND) {
|
||||
|
||||
/* *** Extend Transform *** */
|
||||
|
||||
Scene *scene = t->scene;
|
||||
int cfra = CFRA;
|
||||
int left = SEQ_transform_get_left_handle_frame(seq);
|
||||
int right = SEQ_transform_get_right_handle_frame(seq);
|
||||
|
||||
if (((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK))) {
|
||||
if (((seq->flag & SELECT) == 0 || SEQ_transform_is_locked(channels, seq))) {
|
||||
*r_count = 0;
|
||||
*r_flag = 0;
|
||||
}
|
||||
@@ -115,7 +130,7 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *r_count, int *r_flag)
|
||||
/* Count */
|
||||
|
||||
/* Non nested strips (resect selection and handles) */
|
||||
if ((seq->flag & SELECT) == 0 || (seq->flag & SEQ_LOCK)) {
|
||||
if ((seq->flag & SELECT) == 0 || SEQ_transform_is_locked(channels, seq)) {
|
||||
*r_count = 0;
|
||||
*r_flag = 0;
|
||||
}
|
||||
@@ -630,6 +645,11 @@ void createTransSeqData(TransInfo *t)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Disable cursor wrapping for edge pan. */
|
||||
if (t->mode == TFM_TRANSLATION) {
|
||||
t->flag |= T_NO_CURSOR_WRAP;
|
||||
}
|
||||
|
||||
tc->custom.type.free_cb = freeSeqData;
|
||||
t->frame_side = transform_convert_frame_side_dir_get(t, (float)CFRA);
|
||||
|
||||
@@ -669,6 +689,18 @@ void createTransSeqData(TransInfo *t)
|
||||
td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransSeq TransData2D");
|
||||
ts->tdseq = tdsq = MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq");
|
||||
|
||||
/* Custom data to enable edge panning during transformation. */
|
||||
UI_view2d_edge_pan_init(t->context,
|
||||
&ts->edge_pan,
|
||||
SEQ_EDGE_PAN_INSIDE_PAD,
|
||||
SEQ_EDGE_PAN_OUTSIDE_PAD,
|
||||
SEQ_EDGE_PAN_SPEED_RAMP,
|
||||
SEQ_EDGE_PAN_MAX_SPEED,
|
||||
SEQ_EDGE_PAN_DELAY,
|
||||
SEQ_EDGE_PAN_ZOOM_INFLUENCE);
|
||||
UI_view2d_edge_pan_set_limits(&ts->edge_pan, -FLT_MAX, FLT_MAX, 1, MAXSEQ + 1);
|
||||
ts->initial_v2d_cur = t->region->v2d.cur;
|
||||
|
||||
/* loop 2: build transdata array */
|
||||
SeqToTransData_build(t, ed->seqbasep, td, td2d, tdsq);
|
||||
|
||||
@@ -706,6 +738,36 @@ BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int s
|
||||
}
|
||||
}
|
||||
|
||||
static void view2d_edge_pan_loc_compensate(TransInfo *t, float loc_in[2], float r_loc[2])
|
||||
{
|
||||
TransSeq *ts = (TransSeq *)TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->custom.type.data;
|
||||
|
||||
/* Initial and current view2D rects for additional transform due to view panning and zooming */
|
||||
const rctf *rect_src = &ts->initial_v2d_cur;
|
||||
const rctf *rect_dst = &t->region->v2d.cur;
|
||||
|
||||
if (t->options & CTX_VIEW2D_EDGE_PAN) {
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(t->context);
|
||||
sseq->flag |= SPACE_SEQ_CLAMP_SMOOTH;
|
||||
|
||||
if (t->state == TRANS_CANCEL) {
|
||||
UI_view2d_edge_pan_cancel(t->context, &ts->edge_pan);
|
||||
}
|
||||
else {
|
||||
/* Edge panning functions expect window coordinates, mval is relative to region */
|
||||
const int xy[2] = {
|
||||
t->region->winrct.xmin + t->mval[0],
|
||||
t->region->winrct.ymin + t->mval[1],
|
||||
};
|
||||
UI_view2d_edge_pan_apply(t->context, &ts->edge_pan, xy);
|
||||
}
|
||||
}
|
||||
|
||||
copy_v2_v2(r_loc, loc_in);
|
||||
/* Additional offset due to change in view2D rect. */
|
||||
BLI_rctf_transform_pt_v(rect_dst, rect_src, r_loc, r_loc);
|
||||
}
|
||||
|
||||
static void flushTransSeq(TransInfo *t)
|
||||
{
|
||||
/* Editing null check already done */
|
||||
@@ -723,7 +785,9 @@ static void flushTransSeq(TransInfo *t)
|
||||
for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
|
||||
tdsq = (TransDataSeq *)td->extra;
|
||||
seq = tdsq->seq;
|
||||
new_frame = round_fl_to_int(td2d->loc[0]);
|
||||
float loc[2];
|
||||
view2d_edge_pan_loc_compensate(t, td->loc, loc);
|
||||
new_frame = round_fl_to_int(loc[0]);
|
||||
|
||||
switch (tdsq->sel_flag) {
|
||||
case SELECT:
|
||||
@@ -731,7 +795,7 @@ static void flushTransSeq(TransInfo *t)
|
||||
const int offset = new_frame - tdsq->start_offset - seq->start;
|
||||
SEQ_transform_translate_sequence(t->scene, seq, offset);
|
||||
}
|
||||
seq->machine = round_fl_to_int(td2d->loc[1]);
|
||||
seq->machine = round_fl_to_int(loc[1]);
|
||||
CLAMP(seq->machine, 1, MAXSEQ);
|
||||
break;
|
||||
|
||||
@@ -771,6 +835,7 @@ static void flushTransSeq(TransInfo *t)
|
||||
seq->flag |= SEQ_OVERLAP;
|
||||
}
|
||||
}
|
||||
|
||||
SEQ_collection_free(transformed_strips);
|
||||
}
|
||||
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_relations.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
@@ -121,7 +122,8 @@ void createTransSeqImageData(TransInfo *t)
|
||||
}
|
||||
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(seqbase, t->scene->r.cfra, 0);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, t->scene->r.cfra, 0);
|
||||
SEQ_filter_selected_strips(strips);
|
||||
|
||||
const int count = SEQ_collection_len(strips);
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "ED_screen.h"
|
||||
#include "ED_uvedit.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
#include "SEQ_time.h"
|
||||
@@ -243,8 +244,10 @@ static bool gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min
|
||||
}
|
||||
else if (area->spacetype == SPACE_SEQ) {
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0);
|
||||
SEQ_filter_selected_strips(strips);
|
||||
int selected_strips = SEQ_collection_len(strips);
|
||||
if (selected_strips > 0) {
|
||||
@@ -303,7 +306,8 @@ static int gizmo2d_calc_transform_orientation(const bContext *C)
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0);
|
||||
SEQ_filter_selected_strips(strips);
|
||||
|
||||
bool use_local_orient = SEQ_collection_len(strips) == 1;
|
||||
@@ -325,7 +329,8 @@ static float gizmo2d_calc_rotation(const bContext *C)
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0);
|
||||
SEQ_filter_selected_strips(strips);
|
||||
|
||||
if (SEQ_collection_len(strips) == 1) {
|
||||
@@ -348,8 +353,10 @@ static bool seq_get_strip_pivot_median(const Scene *scene, float r_pivot[2])
|
||||
{
|
||||
zero_v2(r_pivot);
|
||||
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0);
|
||||
SEQ_filter_selected_strips(strips);
|
||||
bool has_select = SEQ_collection_len(strips) != 0;
|
||||
|
||||
@@ -385,8 +392,10 @@ static bool gizmo2d_calc_transform_pivot(const bContext *C, float r_pivot[2])
|
||||
if (pivot_point == V3D_AROUND_CURSOR) {
|
||||
SEQ_image_preview_unit_to_px(scene, sseq->cursor, r_pivot);
|
||||
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(scene));
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(seqbase, scene->r.cfra, 0);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
SeqCollection *strips = SEQ_query_rendered_strips(channels, seqbase, scene->r.cfra, 0);
|
||||
SEQ_filter_selected_strips(strips);
|
||||
has_select = SEQ_collection_len(strips) != 0;
|
||||
SEQ_collection_free(strips);
|
||||
|
@@ -1255,7 +1255,7 @@ static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot)
|
||||
|
||||
WM_operatortype_props_advanced_begin(ot);
|
||||
|
||||
Transform_Properties(ot, P_SNAP);
|
||||
Transform_Properties(ot, P_SNAP | P_VIEW2D_EDGE_PAN);
|
||||
}
|
||||
|
||||
static void TRANSFORM_OT_rotate_normal(struct wmOperatorType *ot)
|
||||
|
@@ -18,8 +18,10 @@
|
||||
|
||||
#include "UI_view2d.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_effects.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_render.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
|
||||
#include "transform.h"
|
||||
@@ -121,14 +123,16 @@ static SeqCollection *seq_collection_extract_effects(SeqCollection *collection)
|
||||
|
||||
static SeqCollection *query_snap_targets(const TransInfo *t, SeqCollection *snap_sources)
|
||||
{
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(t->scene));
|
||||
Editing *ed = SEQ_editing_get(t->scene);
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(ed);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
const short snap_flag = SEQ_tool_settings_snap_flag_get(t->scene);
|
||||
SeqCollection *snap_targets = SEQ_collection_create(__func__);
|
||||
LISTBASE_FOREACH (Sequence *, seq, seqbase) {
|
||||
if (seq->flag & SELECT) {
|
||||
continue; /* Selected are being transformed. */
|
||||
}
|
||||
if ((seq->flag & SEQ_MUTE) && (snap_flag & SEQ_SNAP_IGNORE_MUTED)) {
|
||||
if (SEQ_render_is_muted(channels, seq) && (snap_flag & SEQ_SNAP_IGNORE_MUTED)) {
|
||||
continue;
|
||||
}
|
||||
if (seq->type == SEQ_TYPE_SOUND_RAM && (snap_flag & SEQ_SNAP_IGNORE_SOUND)) {
|
||||
|
@@ -205,6 +205,7 @@ typedef struct Sequence {
|
||||
|
||||
/** List of strips for metastrips. */
|
||||
ListBase seqbase;
|
||||
ListBase channels;
|
||||
|
||||
/** The linked "bSound" object. */
|
||||
struct bSound *sound;
|
||||
@@ -254,11 +255,19 @@ typedef struct Sequence {
|
||||
typedef struct MetaStack {
|
||||
struct MetaStack *next, *prev;
|
||||
ListBase *oldbasep;
|
||||
ListBase *old_channels;
|
||||
Sequence *parseq;
|
||||
/* the startdisp/enddisp when entering the meta */
|
||||
int disp_range[2];
|
||||
} MetaStack;
|
||||
|
||||
typedef struct SeqTimelineChannel {
|
||||
struct SeqTimelineChannel *next, *prev;
|
||||
char name[64];
|
||||
int index;
|
||||
int flag;
|
||||
} SeqTimelineChannel;
|
||||
|
||||
typedef struct EditingRuntime {
|
||||
struct SequenceLookup *sequence_lookup;
|
||||
} EditingRuntime;
|
||||
@@ -266,9 +275,12 @@ typedef struct EditingRuntime {
|
||||
typedef struct Editing {
|
||||
/** Pointer to the current list of seq's being edited (can be within a meta strip). */
|
||||
ListBase *seqbasep;
|
||||
ListBase *active_channels;
|
||||
void *_pad0;
|
||||
/** Pointer to the top-most seq's. */
|
||||
ListBase seqbase;
|
||||
ListBase metastack;
|
||||
ListBase channels;
|
||||
|
||||
/* Context vars, used to be static */
|
||||
Sequence *act_seq;
|
||||
@@ -779,6 +791,11 @@ enum {
|
||||
SEQ_TRANSFORM_FILTER_BILINEAR = 1,
|
||||
};
|
||||
|
||||
typedef enum eSeqChannelFlag {
|
||||
SEQ_CHANNEL_LOCK = (1 << 0),
|
||||
SEQ_CHANNEL_MUTE = (1 << 1),
|
||||
} eSeqChannelFlag;
|
||||
|
||||
/** \} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -605,6 +605,8 @@ typedef struct SpaceSeqRuntime {
|
||||
struct rctf last_thumbnail_area;
|
||||
/** Stores lists of most recently displayed thumbnails. */
|
||||
struct GHash *last_displayed_thumbnails;
|
||||
int rename_channel_index;
|
||||
int _pad0[3];
|
||||
} SpaceSeqRuntime;
|
||||
|
||||
/** Sequencer. */
|
||||
@@ -677,7 +679,7 @@ typedef enum eSpaceSeq_Flag {
|
||||
SEQ_DRAWFRAMES = (1 << 0),
|
||||
SEQ_MARKER_TRANS = (1 << 1),
|
||||
SEQ_DRAW_COLOR_SEPARATED = (1 << 2),
|
||||
SPACE_SEQ_FLAG_UNUSED_3 = (1 << 3),
|
||||
SPACE_SEQ_CLAMP_SMOOTH = (1 << 3),
|
||||
SPACE_SEQ_FLAG_UNUSED_4 = (1 << 4),
|
||||
SPACE_SEQ_FLAG_UNUSED_5 = (1 << 5),
|
||||
SEQ_USE_ALPHA = (1 << 6), /* use RGBA display mode for preview */
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include "DNA_vfont_types.h"
|
||||
|
||||
#include "BLI_iterator.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
@@ -34,6 +35,7 @@
|
||||
#include "rna_internal.h"
|
||||
|
||||
#include "SEQ_add.h"
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_effects.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_modifier.h"
|
||||
@@ -1374,6 +1376,25 @@ static void rna_Sequence_separate(ID *id, Sequence *seqm, Main *bmain)
|
||||
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene);
|
||||
}
|
||||
|
||||
static char *rna_SeqTimelineChannel_path(PointerRNA *ptr)
|
||||
{
|
||||
SeqTimelineChannel *channel = (SeqTimelineChannel *)ptr->data;
|
||||
|
||||
/* Find channel owner. If NULL, owner is `Editing`, otherwise it's `Sequence`. */
|
||||
Sequence *channel_owner = NULL;
|
||||
|
||||
if (channel_owner == NULL) {
|
||||
return BLI_sprintfN("sequence_editor.channels[%d]", SEQ_channel_index_get(channel));
|
||||
}
|
||||
else {
|
||||
char owner_name_esc[(sizeof(channel_owner->name) - 2) * 2];
|
||||
BLI_str_escape(owner_name_esc, channel_owner->name + 2, sizeof(owner_name_esc));
|
||||
return BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].channels[\"%d\"]",
|
||||
owner_name_esc,
|
||||
SEQ_channel_index_get(channel));
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_strip_element(BlenderRNA *brna)
|
||||
@@ -2081,6 +2102,32 @@ static void rna_def_sequence(BlenderRNA *brna)
|
||||
RNA_api_sequence_strip(srna);
|
||||
}
|
||||
|
||||
static void rna_def_channel(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "SequenceTimelineChannel", NULL);
|
||||
RNA_def_struct_sdna(srna, "SeqTimelineChannel");
|
||||
RNA_def_struct_path_func(srna, "rna_SeqTimelineChannel_path");
|
||||
RNA_def_struct_ui_text(srna, "Channel", "");
|
||||
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_maxlength(prop, sizeof(((SeqTimelineChannel *)NULL)->name));
|
||||
RNA_def_property_ui_text(prop, "Name", "");
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_CHANNEL_LOCK);
|
||||
RNA_def_property_ui_text(prop, "Lock channel", "");
|
||||
|
||||
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_CHANNEL_MUTE);
|
||||
RNA_def_property_ui_text(prop, "Mute channel", "");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_editor(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -2129,6 +2176,11 @@ static void rna_def_editor(BlenderRNA *brna)
|
||||
RNA_def_property_collection_funcs(
|
||||
prop, NULL, NULL, NULL, "rna_SequenceEditor_meta_stack_get", NULL, NULL, NULL, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "channels", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "channels", NULL);
|
||||
RNA_def_property_struct_type(prop, "SequenceTimelineChannel");
|
||||
RNA_def_property_ui_text(prop, "Channels", "");
|
||||
|
||||
prop = RNA_def_property(srna, "active_strip", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "act_seq");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
@@ -2475,6 +2527,11 @@ static void rna_def_meta(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Sequences", "Sequences nested in meta strip");
|
||||
RNA_api_sequences(brna, prop, true);
|
||||
|
||||
prop = RNA_def_property(srna, "channels", PROP_COLLECTION, PROP_NONE);
|
||||
RNA_def_property_collection_sdna(prop, NULL, "channels", NULL);
|
||||
RNA_def_property_struct_type(prop, "SequenceTimelineChannel");
|
||||
RNA_def_property_ui_text(prop, "Channels", "");
|
||||
|
||||
func = RNA_def_function(srna, "separate", "rna_Sequence_separate");
|
||||
RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN);
|
||||
RNA_def_function_ui_description(func, "Separate meta");
|
||||
@@ -3472,6 +3529,7 @@ void RNA_def_sequencer(BlenderRNA *brna)
|
||||
|
||||
rna_def_sequence(brna);
|
||||
rna_def_editor(brna);
|
||||
rna_def_channel(brna);
|
||||
|
||||
rna_def_image(brna);
|
||||
rna_def_meta(brna);
|
||||
|
@@ -5591,7 +5591,8 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
|
||||
|
||||
rna_def_space_generic_show_region_toggles(srna,
|
||||
(1 << RGN_TYPE_TOOL_HEADER) | (1 << RGN_TYPE_UI) |
|
||||
(1 << RGN_TYPE_TOOLS) | (1 << RGN_TYPE_HUD));
|
||||
(1 << RGN_TYPE_TOOLS) | (1 << RGN_TYPE_HUD) |
|
||||
(1 << RGN_TYPE_CHANNELS));
|
||||
|
||||
/* view type, fairly important */
|
||||
prop = RNA_def_property(srna, "view_type", PROP_ENUM, PROP_NONE);
|
||||
|
@@ -3149,6 +3149,7 @@ static void rna_def_userdef_theme_space_seq(BlenderRNA *brna)
|
||||
RNA_def_struct_ui_text(srna, "Theme Sequence Editor", "Theme settings for the Sequence Editor");
|
||||
|
||||
rna_def_userdef_theme_spaces_main(srna);
|
||||
rna_def_userdef_theme_spaces_list_main(srna);
|
||||
|
||||
prop = RNA_def_property(srna, "grid", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_array(prop, 3);
|
||||
|
@@ -32,6 +32,7 @@ set(INC_SYS
|
||||
set(SRC
|
||||
SEQ_add.h
|
||||
SEQ_animation.h
|
||||
SEQ_channels.h
|
||||
SEQ_clipboard.h
|
||||
SEQ_edit.h
|
||||
SEQ_effects.h
|
||||
@@ -49,6 +50,7 @@ set(SRC
|
||||
SEQ_utils.h
|
||||
|
||||
intern/animation.c
|
||||
intern/channels.c
|
||||
intern/clipboard.c
|
||||
intern/disk_cache.c
|
||||
intern/disk_cache.h
|
||||
|
33
source/blender/sequencer/SEQ_channels.h
Normal file
33
source/blender/sequencer/SEQ_channels.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2022 Blender Foundation. All rights reserved. */
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup sequencer
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Editing;
|
||||
struct ListBase;
|
||||
struct Scene;
|
||||
struct SeqTimelineChannel;
|
||||
|
||||
struct ListBase *SEQ_channels_active_get(struct Editing *ed);
|
||||
void SEQ_channels_active_set(struct Editing *ed, struct ListBase *channels);
|
||||
void SEQ_channels_ensure(struct ListBase *channels);
|
||||
void SEQ_channels_duplicate(struct ListBase *channels_dst, struct ListBase *channels_src);
|
||||
struct SeqTimelineChannel *SEQ_channel_get_by_index(const struct ListBase *channels,
|
||||
const int channel_index);
|
||||
struct ListBase *SEQ_channels_active_get(struct Editing *ed);
|
||||
char *SEQ_channel_name_get(struct ListBase *channels, const int channel_index);
|
||||
bool SEQ_channel_is_locked(const struct SeqTimelineChannel *channel);
|
||||
bool SEQ_channel_is_muted(const struct SeqTimelineChannel *channel);
|
||||
int SEQ_channel_index_get(const struct SeqTimelineChannel *channel);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -208,7 +208,8 @@ SeqCollection *SEQ_query_all_strips_recursive(ListBase *seqbase);
|
||||
* \param displayed_channel: viewed channel. when set to 0, no channel filter is applied
|
||||
* \return strip collection
|
||||
*/
|
||||
SeqCollection *SEQ_query_rendered_strips(ListBase *seqbase,
|
||||
SeqCollection *SEQ_query_rendered_strips(ListBase *channels,
|
||||
ListBase *seqbase,
|
||||
int timeline_frame,
|
||||
int displayed_channel);
|
||||
/**
|
||||
|
@@ -104,6 +104,11 @@ struct StripElem *SEQ_render_give_stripelem(struct Sequence *seq, int timeline_f
|
||||
|
||||
void SEQ_render_imbuf_from_sequencer_space(struct Scene *scene, struct ImBuf *ibuf);
|
||||
void SEQ_render_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4]);
|
||||
/**
|
||||
* Check if `seq` is muted for rendering.
|
||||
* This function also checks `SeqTimelineChannel` flag.
|
||||
*/
|
||||
bool SEQ_render_is_muted(const struct ListBase *channels, const struct Sequence *seq);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -11,6 +11,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Editing;
|
||||
struct ListBase;
|
||||
struct Scene;
|
||||
struct SeqCollection;
|
||||
@@ -67,6 +68,12 @@ void SEQ_transform_offset_after_frame(struct Scene *scene,
|
||||
int delta,
|
||||
int timeline_frame);
|
||||
|
||||
/**
|
||||
* Check if `seq` can be moved.
|
||||
* This function also checks `SeqTimelineChannel` flag.
|
||||
*/
|
||||
bool SEQ_transform_is_locked(struct ListBase *channels, struct Sequence *seq);
|
||||
|
||||
/* Image transformation. */
|
||||
|
||||
void SEQ_image_transform_mirror_factor_get(const struct Sequence *seq, float r_mirror[2]);
|
||||
|
75
source/blender/sequencer/intern/channels.c
Normal file
75
source/blender/sequencer/intern/channels.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
* Copyright 2022 Blender Foundation. All rights reserved. */
|
||||
|
||||
/** \file
|
||||
* \ingroup sequencer
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_listBase.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_sequence_types.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_relations.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
|
||||
ListBase *SEQ_channels_active_get(Editing *ed)
|
||||
{
|
||||
return ed->active_channels;
|
||||
}
|
||||
|
||||
void SEQ_channels_active_set(Editing *ed, ListBase *channels)
|
||||
{
|
||||
ed->active_channels = channels;
|
||||
}
|
||||
|
||||
void SEQ_channels_ensure(ListBase *channels)
|
||||
{
|
||||
/* Allocate channels. Channel 0 is never used, but allocated to prevent off by 1 issues. */
|
||||
for (int i = 0; i < MAXSEQ + 1; i++) {
|
||||
SeqTimelineChannel *channel = MEM_callocN(sizeof(SeqTimelineChannel), "seq timeline channel");
|
||||
BLI_snprintf(channel->name, sizeof(channel->name), "Channel %d", i);
|
||||
channel->index = i;
|
||||
BLI_addtail(channels, channel);
|
||||
}
|
||||
}
|
||||
|
||||
void SEQ_channels_duplicate(ListBase *channels_dst, ListBase *channels_src)
|
||||
{
|
||||
LISTBASE_FOREACH (SeqTimelineChannel *, channel, channels_src) {
|
||||
SeqTimelineChannel *channel_duplicate = MEM_dupallocN(channel);
|
||||
BLI_addtail(channels_dst, channel_duplicate);
|
||||
}
|
||||
}
|
||||
|
||||
SeqTimelineChannel *SEQ_channel_get_by_index(const ListBase *channels, const int channel_index)
|
||||
{
|
||||
return BLI_findlink(channels, channel_index);
|
||||
}
|
||||
|
||||
char *SEQ_channel_name_get(ListBase *channels, const int channel_index)
|
||||
{
|
||||
SeqTimelineChannel *channel = SEQ_channel_get_by_index(channels, channel_index);
|
||||
return channel->name;
|
||||
}
|
||||
|
||||
int SEQ_channel_index_get(const SeqTimelineChannel *channel)
|
||||
{
|
||||
return channel->index;
|
||||
}
|
||||
|
||||
bool SEQ_channel_is_locked(const SeqTimelineChannel *channel)
|
||||
{
|
||||
return (channel->flag & SEQ_CHANNEL_LOCK) != 0;
|
||||
}
|
||||
|
||||
bool SEQ_channel_is_muted(const SeqTimelineChannel *channel)
|
||||
{
|
||||
return (channel->flag & SEQ_CHANNEL_MUTE) != 0;
|
||||
}
|
@@ -2422,6 +2422,7 @@ static ImBuf *do_multicam(const SeqRenderData *context,
|
||||
ImBuf *out;
|
||||
Editing *ed;
|
||||
ListBase *seqbasep;
|
||||
ListBase *channels = &seq->channels;
|
||||
|
||||
if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) {
|
||||
return NULL;
|
||||
@@ -2436,7 +2437,8 @@ static ImBuf *do_multicam(const SeqRenderData *context,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out = seq_render_give_ibuf_seqbase(context, timeline_frame, seq->multicam_source, seqbasep);
|
||||
out = seq_render_give_ibuf_seqbase(
|
||||
context, timeline_frame, seq->multicam_source, channels, seqbasep);
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -2462,6 +2464,7 @@ static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, fl
|
||||
{
|
||||
Editing *ed;
|
||||
ListBase *seqbasep;
|
||||
ListBase *channels = &seq->channels;
|
||||
ImBuf *i = NULL;
|
||||
|
||||
ed = context->scene->ed;
|
||||
@@ -2474,7 +2477,8 @@ static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, fl
|
||||
timeline_frame = clamp_i(timeline_frame, seq->startdisp, seq->enddisp - 1);
|
||||
|
||||
if (seq->machine > 1) {
|
||||
i = seq_render_give_ibuf_seqbase(context, timeline_frame, seq->machine - 1, seqbasep);
|
||||
i = seq_render_give_ibuf_seqbase(
|
||||
context, timeline_frame, seq->machine - 1, channels, seqbasep);
|
||||
}
|
||||
|
||||
/* Found nothing? so let's work the way up the meta-strip stack, so
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_render.h"
|
||||
#include "SEQ_time.h"
|
||||
#include "render.h"
|
||||
|
||||
@@ -285,14 +286,14 @@ static bool must_render_strip(const Sequence *seq, SeqCollection *strips_at_time
|
||||
}
|
||||
|
||||
/* Remove strips we don't want to render from collection. */
|
||||
static void collection_filter_rendered_strips(SeqCollection *collection)
|
||||
static void collection_filter_rendered_strips(ListBase *channels, SeqCollection *collection)
|
||||
{
|
||||
Sequence *seq;
|
||||
|
||||
/* Remove sound strips and muted strips from collection, because these are not rendered.
|
||||
* Function #must_render_strip() don't have to check for these strips anymore. */
|
||||
SEQ_ITERATOR_FOREACH (seq, collection) {
|
||||
if (seq->type == SEQ_TYPE_SOUND_RAM || (seq->flag & SEQ_MUTE) != 0) {
|
||||
if (seq->type == SEQ_TYPE_SOUND_RAM || SEQ_render_is_muted(channels, seq)) {
|
||||
SEQ_collection_remove_strip(seq, collection);
|
||||
}
|
||||
}
|
||||
@@ -305,7 +306,8 @@ static void collection_filter_rendered_strips(SeqCollection *collection)
|
||||
}
|
||||
}
|
||||
|
||||
SeqCollection *SEQ_query_rendered_strips(ListBase *seqbase,
|
||||
SeqCollection *SEQ_query_rendered_strips(ListBase *channels,
|
||||
ListBase *seqbase,
|
||||
const int timeline_frame,
|
||||
const int displayed_channel)
|
||||
{
|
||||
@@ -313,7 +315,7 @@ SeqCollection *SEQ_query_rendered_strips(ListBase *seqbase,
|
||||
if (displayed_channel != 0) {
|
||||
collection_filter_channel_up_to_incl(collection, displayed_channel);
|
||||
}
|
||||
collection_filter_rendered_strips(collection);
|
||||
collection_filter_rendered_strips(channels, collection);
|
||||
return collection;
|
||||
}
|
||||
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include "DEG_depsgraph_debug.h"
|
||||
#include "DEG_depsgraph_query.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_prefetch.h"
|
||||
#include "SEQ_relations.h"
|
||||
@@ -387,19 +388,20 @@ static bool seq_prefetch_seq_has_disk_cache(PrefetchJob *pfjob,
|
||||
}
|
||||
|
||||
static bool seq_prefetch_scene_strip_is_rendered(PrefetchJob *pfjob,
|
||||
ListBase *channels,
|
||||
ListBase *seqbase,
|
||||
SeqCollection *scene_strips,
|
||||
bool is_recursive_check)
|
||||
{
|
||||
float cfra = seq_prefetch_cfra(pfjob);
|
||||
Sequence *seq_arr[MAXSEQ + 1];
|
||||
int count = seq_get_shown_sequences(seqbase, cfra, 0, seq_arr);
|
||||
int count = seq_get_shown_sequences(channels, seqbase, cfra, 0, seq_arr);
|
||||
|
||||
/* Iterate over rendered strips. */
|
||||
for (int i = 0; i < count; i++) {
|
||||
Sequence *seq = seq_arr[i];
|
||||
if (seq->type == SEQ_TYPE_META &&
|
||||
seq_prefetch_scene_strip_is_rendered(pfjob, &seq->seqbase, scene_strips, true)) {
|
||||
seq_prefetch_scene_strip_is_rendered(pfjob, channels, &seq->seqbase, scene_strips, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -433,10 +435,10 @@ static SeqCollection *query_scene_strips(ListBase *seqbase)
|
||||
|
||||
/* Prefetch must avoid rendering scene strips, because rendering in background locks UI and can
|
||||
* make it unresponsive for long time periods. */
|
||||
static bool seq_prefetch_must_skip_frame(PrefetchJob *pfjob, ListBase *seqbase)
|
||||
static bool seq_prefetch_must_skip_frame(PrefetchJob *pfjob, ListBase *channels, ListBase *seqbase)
|
||||
{
|
||||
SeqCollection *scene_strips = query_scene_strips(seqbase);
|
||||
if (seq_prefetch_scene_strip_is_rendered(pfjob, seqbase, scene_strips, false)) {
|
||||
if (seq_prefetch_scene_strip_is_rendered(pfjob, channels, seqbase, scene_strips, false)) {
|
||||
SEQ_collection_free(scene_strips);
|
||||
return true;
|
||||
}
|
||||
@@ -485,7 +487,8 @@ static void *seq_prefetch_frames(void *job)
|
||||
pfjob->scene_eval->ed->prefetch_job = pfjob;
|
||||
|
||||
ListBase *seqbase = SEQ_active_seqbase_get(SEQ_editing_get(pfjob->scene_eval));
|
||||
if (seq_prefetch_must_skip_frame(pfjob, seqbase)) {
|
||||
ListBase *channels = SEQ_channels_active_get(SEQ_editing_get(pfjob->scene_eval));
|
||||
if (seq_prefetch_must_skip_frame(pfjob, channels, seqbase)) {
|
||||
pfjob->num_frames_prefetched++;
|
||||
continue;
|
||||
}
|
||||
|
@@ -50,6 +50,7 @@
|
||||
#include "RE_engine.h"
|
||||
#include "RE_pipeline.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_effects.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_modifier.h"
|
||||
@@ -72,6 +73,7 @@
|
||||
|
||||
static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
|
||||
SeqRenderState *state,
|
||||
ListBase *channels,
|
||||
ListBase *seqbasep,
|
||||
float timeline_frame,
|
||||
int chanshown);
|
||||
@@ -256,12 +258,14 @@ static int seq_channel_cmp_fn(const void *a, const void *b)
|
||||
return (*(Sequence **)a)->machine - (*(Sequence **)b)->machine;
|
||||
}
|
||||
|
||||
int seq_get_shown_sequences(ListBase *seqbase,
|
||||
int seq_get_shown_sequences(ListBase *channels,
|
||||
ListBase *seqbase,
|
||||
const int timeline_frame,
|
||||
const int chanshown,
|
||||
Sequence **r_seq_arr)
|
||||
{
|
||||
SeqCollection *collection = SEQ_query_rendered_strips(seqbase, timeline_frame, chanshown);
|
||||
SeqCollection *collection = SEQ_query_rendered_strips(
|
||||
channels, seqbase, timeline_frame, chanshown);
|
||||
const int strip_count = BLI_gset_len(collection->set);
|
||||
|
||||
if (strip_count > MAXSEQ) {
|
||||
@@ -1582,6 +1586,7 @@ static ImBuf *do_render_strip_seqbase(const SeqRenderData *context,
|
||||
{
|
||||
ImBuf *ibuf = NULL;
|
||||
ListBase *seqbase = NULL;
|
||||
ListBase *channels = &seq->channels;
|
||||
int offset;
|
||||
|
||||
seqbase = SEQ_get_seqbase_from_sequence(seq, &offset);
|
||||
@@ -1594,6 +1599,7 @@ static ImBuf *do_render_strip_seqbase(const SeqRenderData *context,
|
||||
|
||||
ibuf = seq_render_strip_stack(context,
|
||||
state,
|
||||
channels,
|
||||
seqbase,
|
||||
/* scene strips don't have their start taken into account */
|
||||
frame_index + offset,
|
||||
@@ -1809,6 +1815,7 @@ static ImBuf *seq_render_strip_stack_apply_effect(
|
||||
|
||||
static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
|
||||
SeqRenderState *state,
|
||||
ListBase *channels,
|
||||
ListBase *seqbasep,
|
||||
float timeline_frame,
|
||||
int chanshown)
|
||||
@@ -1818,7 +1825,8 @@ static ImBuf *seq_render_strip_stack(const SeqRenderData *context,
|
||||
int i;
|
||||
ImBuf *out = NULL;
|
||||
|
||||
count = seq_get_shown_sequences(seqbasep, timeline_frame, chanshown, (Sequence **)&seq_arr);
|
||||
count = seq_get_shown_sequences(
|
||||
channels, seqbasep, timeline_frame, chanshown, (Sequence **)&seq_arr);
|
||||
|
||||
if (count == 0) {
|
||||
return NULL;
|
||||
@@ -1909,6 +1917,7 @@ ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame,
|
||||
Scene *scene = context->scene;
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *seqbasep;
|
||||
ListBase *channels;
|
||||
|
||||
if (ed == NULL) {
|
||||
return NULL;
|
||||
@@ -1918,9 +1927,11 @@ ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame,
|
||||
int count = BLI_listbase_count(&ed->metastack);
|
||||
count = max_ii(count + chanshown, 0);
|
||||
seqbasep = ((MetaStack *)BLI_findlink(&ed->metastack, count))->oldbasep;
|
||||
channels = ((MetaStack *)BLI_findlink(&ed->metastack, count))->old_channels;
|
||||
}
|
||||
else {
|
||||
seqbasep = ed->seqbasep;
|
||||
channels = ed->active_channels;
|
||||
}
|
||||
|
||||
SeqRenderState state;
|
||||
@@ -1929,7 +1940,7 @@ ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame,
|
||||
Sequence *seq_arr[MAXSEQ + 1];
|
||||
int count;
|
||||
|
||||
count = seq_get_shown_sequences(seqbasep, timeline_frame, chanshown, seq_arr);
|
||||
count = seq_get_shown_sequences(channels, seqbasep, timeline_frame, chanshown, seq_arr);
|
||||
|
||||
if (count) {
|
||||
out = seq_cache_get(context, seq_arr[count - 1], timeline_frame, SEQ_CACHE_STORE_FINAL_OUT);
|
||||
@@ -1941,7 +1952,7 @@ ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame,
|
||||
|
||||
if (count && !out) {
|
||||
BLI_mutex_lock(&seq_render_mutex);
|
||||
out = seq_render_strip_stack(context, &state, seqbasep, timeline_frame, chanshown);
|
||||
out = seq_render_strip_stack(context, &state, channels, seqbasep, timeline_frame, chanshown);
|
||||
|
||||
if (context->is_prefetch_render) {
|
||||
seq_cache_put(context, seq_arr[count - 1], timeline_frame, SEQ_CACHE_STORE_FINAL_OUT, out);
|
||||
@@ -1961,12 +1972,13 @@ ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame,
|
||||
ImBuf *seq_render_give_ibuf_seqbase(const SeqRenderData *context,
|
||||
float timeline_frame,
|
||||
int chan_shown,
|
||||
ListBase *channels,
|
||||
ListBase *seqbasep)
|
||||
{
|
||||
SeqRenderState state;
|
||||
seq_render_state_init(&state);
|
||||
|
||||
return seq_render_strip_stack(context, &state, seqbasep, timeline_frame, chan_shown);
|
||||
return seq_render_strip_stack(context, &state, channels, seqbasep, timeline_frame, chan_shown);
|
||||
}
|
||||
|
||||
ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context,
|
||||
@@ -2135,4 +2147,11 @@ void SEQ_render_thumbnails_base_set(const SeqRenderData *context,
|
||||
}
|
||||
}
|
||||
|
||||
bool SEQ_render_is_muted(const ListBase *channels, const Sequence *seq)
|
||||
{
|
||||
|
||||
SeqTimelineChannel *channel = SEQ_channel_get_by_index(channels, seq->machine);
|
||||
return seq->flag & SEQ_MUTE || SEQ_channel_is_muted(channel);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@@ -33,6 +33,7 @@ void seq_render_state_init(SeqRenderState *state);
|
||||
struct ImBuf *seq_render_give_ibuf_seqbase(const struct SeqRenderData *context,
|
||||
float timeline_frame,
|
||||
int chan_shown,
|
||||
struct ListBase *channels,
|
||||
struct ListBase *seqbasep);
|
||||
struct ImBuf *seq_render_effect_execute_threaded(struct SeqEffectHandle *sh,
|
||||
const struct SeqRenderData *context,
|
||||
@@ -43,7 +44,8 @@ struct ImBuf *seq_render_effect_execute_threaded(struct SeqEffectHandle *sh,
|
||||
struct ImBuf *ibuf2,
|
||||
struct ImBuf *ibuf3);
|
||||
void seq_imbuf_to_sequencer_space(struct Scene *scene, struct ImBuf *ibuf, bool make_float);
|
||||
int seq_get_shown_sequences(struct ListBase *seqbase,
|
||||
int seq_get_shown_sequences(struct ListBase *channels,
|
||||
struct ListBase *seqbase,
|
||||
int timeline_frame,
|
||||
int chanshown,
|
||||
struct Sequence **r_seq_arr);
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_edit.h"
|
||||
#include "SEQ_effects.h"
|
||||
#include "SEQ_iterator.h"
|
||||
@@ -135,6 +136,10 @@ Sequence *SEQ_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int
|
||||
|
||||
seq->color_tag = SEQUENCE_COLOR_NONE;
|
||||
|
||||
if (seq->type == SEQ_TYPE_META) {
|
||||
SEQ_channels_ensure(&seq->channels);
|
||||
}
|
||||
|
||||
SEQ_relations_session_uuid_generate(seq);
|
||||
|
||||
return seq;
|
||||
@@ -386,6 +391,7 @@ MetaStack *SEQ_meta_stack_alloc(Editing *ed, Sequence *seq_meta)
|
||||
BLI_addtail(&ed->metastack, ms);
|
||||
ms->parseq = seq_meta;
|
||||
ms->oldbasep = ed->seqbasep;
|
||||
ms->old_channels = ed->active_channels;
|
||||
copy_v2_v2_int(ms->disp_range, &ms->parseq->startdisp);
|
||||
return ms;
|
||||
}
|
||||
@@ -460,6 +466,9 @@ static Sequence *seq_dupli(const Scene *scene_src,
|
||||
BLI_listbase_clear(&seqn->seqbase);
|
||||
/* WARNING: This meta-strip is not recursively duplicated here - do this after! */
|
||||
// seq_dupli_recursive(&seq->seqbase, &seqn->seqbase);
|
||||
|
||||
BLI_listbase_clear(&seqn->channels);
|
||||
SEQ_channels_duplicate(&seqn->channels, &seq->channels);
|
||||
}
|
||||
else if (seq->type == SEQ_TYPE_SCENE) {
|
||||
seqn->strip->stripdata = NULL;
|
||||
@@ -686,6 +695,10 @@ static bool seq_write_data_cb(Sequence *seq, void *userdata)
|
||||
}
|
||||
|
||||
SEQ_modifier_blend_write(writer, &seq->modifiers);
|
||||
|
||||
LISTBASE_FOREACH (SeqTimelineChannel *, channel, &seq->channels) {
|
||||
BLO_write_struct(writer, SeqTimelineChannel, channel);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -753,6 +766,8 @@ static bool seq_read_data_cb(Sequence *seq, void *user_data)
|
||||
}
|
||||
|
||||
SEQ_modifier_blend_read_data(reader, &seq->modifiers);
|
||||
|
||||
BLO_read_list(reader, &seq->channels);
|
||||
return true;
|
||||
}
|
||||
void SEQ_blend_read(BlendDataReader *reader, ListBase *seqbase)
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "SEQ_effects.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_relations.h"
|
||||
#include "SEQ_render.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
#include "SEQ_time.h"
|
||||
#include "SEQ_transform.h"
|
||||
@@ -91,7 +92,10 @@ int SEQ_edit_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute)
|
||||
static void seq_update_muting_recursive(ListBase *channels,
|
||||
ListBase *seqbasep,
|
||||
Sequence *metaseq,
|
||||
int mute)
|
||||
{
|
||||
Sequence *seq;
|
||||
int seqmute;
|
||||
@@ -99,7 +103,7 @@ static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, i
|
||||
/* For sound we go over full meta tree to update muted state,
|
||||
* since sound is played outside of evaluating the imbufs. */
|
||||
for (seq = seqbasep->first; seq; seq = seq->next) {
|
||||
seqmute = (mute || (seq->flag & SEQ_MUTE));
|
||||
seqmute = (mute || SEQ_render_is_muted(channels, seq));
|
||||
|
||||
if (seq->type == SEQ_TYPE_META) {
|
||||
/* if this is the current meta sequence, unmute because
|
||||
@@ -108,7 +112,7 @@ static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, i
|
||||
seqmute = 0;
|
||||
}
|
||||
|
||||
seq_update_muting_recursive(&seq->seqbase, metaseq, seqmute);
|
||||
seq_update_muting_recursive(&seq->channels, &seq->seqbase, metaseq, seqmute);
|
||||
}
|
||||
else if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
|
||||
if (seq->scene_sound) {
|
||||
@@ -125,10 +129,10 @@ void SEQ_edit_update_muting(Editing *ed)
|
||||
MetaStack *ms = ed->metastack.last;
|
||||
|
||||
if (ms) {
|
||||
seq_update_muting_recursive(&ed->seqbase, ms->parseq, 1);
|
||||
seq_update_muting_recursive(&ed->channels, &ed->seqbase, ms->parseq, 1);
|
||||
}
|
||||
else {
|
||||
seq_update_muting_recursive(&ed->seqbase, NULL, 0);
|
||||
seq_update_muting_recursive(&ed->channels, &ed->seqbase, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -20,6 +20,7 @@
|
||||
#include "DNA_sound_types.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_render.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
@@ -321,6 +322,7 @@ int SEQ_time_find_next_prev_edit(Scene *scene,
|
||||
const bool do_unselected)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
Sequence *seq;
|
||||
|
||||
int dist, best_dist, best_frame = timeline_frame;
|
||||
@@ -338,7 +340,7 @@ int SEQ_time_find_next_prev_edit(Scene *scene,
|
||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||
int i;
|
||||
|
||||
if (do_skip_mute && (seq->flag & SEQ_MUTE)) {
|
||||
if (do_skip_mute && SEQ_render_is_muted(channels, seq)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -442,8 +444,8 @@ void SEQ_timeline_expand_boundbox(const ListBase *seqbase, rctf *rect)
|
||||
if (rect->xmax < seq->enddisp + 1) {
|
||||
rect->xmax = seq->enddisp + 1;
|
||||
}
|
||||
if (rect->ymax < seq->machine + 2) {
|
||||
rect->ymax = seq->machine + 2;
|
||||
if (rect->ymax < seq->machine) {
|
||||
rect->ymax = seq->machine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@
|
||||
#include "BKE_sound.h"
|
||||
|
||||
#include "SEQ_animation.h"
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_effects.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_relations.h"
|
||||
@@ -391,6 +392,12 @@ void SEQ_transform_offset_after_frame(Scene *scene,
|
||||
}
|
||||
}
|
||||
|
||||
bool SEQ_transform_is_locked(ListBase *channels, Sequence *seq)
|
||||
{
|
||||
SeqTimelineChannel *channel = SEQ_channel_get_by_index(channels, seq->machine);
|
||||
return seq->flag & SEQ_LOCK || SEQ_channel_is_locked(channel);
|
||||
}
|
||||
|
||||
void SEQ_image_transform_mirror_factor_get(const Sequence *seq, float r_mirror[2])
|
||||
{
|
||||
r_mirror[0] = 1.0f;
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "SEQ_animation.h"
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_edit.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_relations.h"
|
||||
@@ -380,7 +381,8 @@ void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile)
|
||||
|
||||
const Sequence *SEQ_get_topmost_sequence(const Scene *scene, int frame)
|
||||
{
|
||||
const Editing *ed = scene->ed;
|
||||
Editing *ed = scene->ed;
|
||||
ListBase *channels = SEQ_channels_active_get(ed);
|
||||
const Sequence *seq, *best_seq = NULL;
|
||||
int best_machine = -1;
|
||||
|
||||
@@ -389,7 +391,7 @@ const Sequence *SEQ_get_topmost_sequence(const Scene *scene, int frame)
|
||||
}
|
||||
|
||||
for (seq = ed->seqbasep->first; seq; seq = seq->next) {
|
||||
if (seq->flag & SEQ_MUTE || !SEQ_time_strip_intersects_frame(seq, frame)) {
|
||||
if (SEQ_render_is_muted(channels, seq) || !SEQ_time_strip_intersects_frame(seq, frame)) {
|
||||
continue;
|
||||
}
|
||||
/* Only use strips that generate an image, not ones that combine
|
||||
|
Reference in New Issue
Block a user