Cleanup: refactor VSE timeline drawing code
- Use context variables for drawing functions. - Move conditions to functions drawing specific elements as preconditions - Disentangle calculation of common coordinates. - Use more descriptive variable names (in context at least) Individual drawing functions are mostly unchanged, so improvements there are minimal. No intended functional changes.
This commit is contained in:
@@ -435,6 +435,14 @@ void draw_seq_strip_thumbnail(View2D *v2d,
|
||||
float pixelx,
|
||||
float pixely)
|
||||
{
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
||||
if ((sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
|
||||
(sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_THUMBNAILS) == 0 ||
|
||||
!ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool clipped = false;
|
||||
float image_height, image_width, thumb_width;
|
||||
rcti crop;
|
||||
|
||||
@@ -79,6 +79,152 @@
|
||||
|
||||
static Sequence *special_seq_update = nullptr;
|
||||
|
||||
typedef struct StripDrawContext {
|
||||
Sequence *seq;
|
||||
float content_start, content_end, bottom, top; /* Strip boundary in timeline space. */
|
||||
float left_handle, right_handle; /* Position in frames. */
|
||||
float strip_content_top; /* Position in timeline space deliminates content and text overlay. */
|
||||
float handle_width; /* Width of strip handle in frames. */
|
||||
|
||||
bool can_draw_text_overlay;
|
||||
bool can_draw_strip_content;
|
||||
bool is_too_small; /* Shorthand for (!can_draw_text_overlay && !can_draw_strip_content). */
|
||||
bool is_active_strip;
|
||||
bool is_single_image; /* Strip has single frame of content. */
|
||||
bool show_strip_color_tag;
|
||||
} StripDrawContext;
|
||||
|
||||
typedef struct TimelineDrawContext {
|
||||
const bContext *C;
|
||||
ARegion *region;
|
||||
Scene *scene;
|
||||
SpaceSeq *sseq;
|
||||
View2D *v2d;
|
||||
Editing *ed;
|
||||
ListBase *channels;
|
||||
GPUViewport *viewport;
|
||||
GPUFrameBuffer *framebuffer_overlay;
|
||||
float pixelx, pixely; /* Width and height of pixel in timeline space. */
|
||||
} TimelineDrawContext;
|
||||
|
||||
static TimelineDrawContext timeline_draw_context_get(const bContext *C)
|
||||
{
|
||||
TimelineDrawContext ctx;
|
||||
|
||||
ctx.C = C;
|
||||
ctx.region = CTX_wm_region(C);
|
||||
ctx.scene = CTX_data_scene(C);
|
||||
ctx.sseq = CTX_wm_space_seq(C);
|
||||
ctx.v2d = UI_view2d_fromcontext(C);
|
||||
|
||||
ctx.ed = SEQ_editing_get(ctx.scene);
|
||||
ctx.channels = SEQ_channels_displayed_get(ctx.ed);
|
||||
|
||||
ctx.viewport = WM_draw_region_get_viewport(ctx.region);
|
||||
ctx.framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(ctx.viewport);
|
||||
|
||||
ctx.pixely = BLI_rctf_size_y(&ctx.v2d->cur) / BLI_rcti_size_y(&ctx.v2d->mask);
|
||||
ctx.pixelx = BLI_rctf_size_x(&ctx.v2d->cur) / BLI_rcti_size_x(&ctx.v2d->mask);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static bool seq_draw_waveforms_poll(const bContext * /*C*/, SpaceSeq *sseq, Sequence *seq)
|
||||
{
|
||||
const bool strip_is_valid = seq->type == SEQ_TYPE_SOUND_RAM && seq->sound != nullptr;
|
||||
const bool overlays_enabled = (sseq->flag & SEQ_SHOW_OVERLAY) != 0;
|
||||
const bool ovelay_option = ((sseq->timeline_overlay.flag & SEQ_TIMELINE_ALL_WAVEFORMS) != 0 ||
|
||||
(seq->flag & SEQ_AUDIO_DRAW_WAVEFORM));
|
||||
|
||||
if ((sseq->timeline_overlay.flag & SEQ_TIMELINE_NO_WAVEFORMS) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strip_is_valid && overlays_enabled && ovelay_option) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool strip_hides_text_overlay_first(TimelineDrawContext *ctx, StripDrawContext *strip_ctx)
|
||||
{
|
||||
return seq_draw_waveforms_poll(ctx->C, ctx->sseq, strip_ctx->seq) ||
|
||||
strip_ctx->seq->type == SEQ_TYPE_COLOR;
|
||||
}
|
||||
|
||||
static void strip_draw_context_set_text_overlay_visibility(TimelineDrawContext *ctx,
|
||||
StripDrawContext *strip_ctx)
|
||||
{
|
||||
float threshold = 8 * ctx->pixely * UI_SCALE_FAC;
|
||||
if (strip_hides_text_overlay_first(ctx, strip_ctx)) {
|
||||
threshold = 20 * UI_SCALE_FAC;
|
||||
}
|
||||
|
||||
const bool overlays_enabled = (ctx->sseq->timeline_overlay.flag &
|
||||
(SEQ_TIMELINE_SHOW_STRIP_NAME | SEQ_TIMELINE_SHOW_STRIP_SOURCE |
|
||||
SEQ_TIMELINE_SHOW_STRIP_DURATION)) != 0;
|
||||
|
||||
strip_ctx->can_draw_text_overlay = (strip_ctx->top - strip_ctx->bottom) / ctx->pixely >=
|
||||
threshold;
|
||||
strip_ctx->can_draw_text_overlay &= overlays_enabled;
|
||||
}
|
||||
|
||||
static void strip_draw_context_set_strip_content_visibility(TimelineDrawContext *ctx,
|
||||
StripDrawContext *strip_ctx)
|
||||
{
|
||||
float threshold = 20 * UI_SCALE_FAC;
|
||||
if (strip_hides_text_overlay_first(ctx, strip_ctx)) {
|
||||
threshold = 8 * ctx->pixely * UI_SCALE_FAC;
|
||||
}
|
||||
|
||||
strip_ctx->can_draw_strip_content = ((strip_ctx->top - strip_ctx->bottom) / ctx->pixely) >
|
||||
threshold;
|
||||
}
|
||||
|
||||
static StripDrawContext strip_draw_context_get(TimelineDrawContext *ctx, Sequence *seq)
|
||||
{
|
||||
StripDrawContext strip_ctx;
|
||||
Scene *scene = ctx->scene;
|
||||
|
||||
strip_ctx.seq = seq;
|
||||
strip_ctx.bottom = seq->machine + SEQ_STRIP_OFSBOTTOM;
|
||||
strip_ctx.top = seq->machine + SEQ_STRIP_OFSTOP;
|
||||
strip_ctx.content_start = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
strip_ctx.content_end = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
if (SEQ_time_has_left_still_frames(scene, seq)) {
|
||||
SEQ_time_start_frame_get(seq);
|
||||
}
|
||||
if (SEQ_time_has_right_still_frames(scene, seq)) {
|
||||
SEQ_time_content_end_frame_get(scene, seq);
|
||||
}
|
||||
/* Limit body to strip bounds. Meta strip can end up with content outside of strip range. */
|
||||
strip_ctx.content_start = min_ff(strip_ctx.content_start,
|
||||
SEQ_time_right_handle_frame_get(scene, seq));
|
||||
strip_ctx.content_end = max_ff(strip_ctx.content_end,
|
||||
SEQ_time_left_handle_frame_get(scene, seq));
|
||||
strip_ctx.left_handle = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
strip_ctx.right_handle = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
|
||||
strip_draw_context_set_text_overlay_visibility(ctx, &strip_ctx);
|
||||
strip_draw_context_set_strip_content_visibility(ctx, &strip_ctx);
|
||||
strip_ctx.is_too_small = (!strip_ctx.can_draw_text_overlay && !strip_ctx.can_draw_strip_content);
|
||||
strip_ctx.is_active_strip = seq == SEQ_select_active_get(scene);
|
||||
strip_ctx.is_single_image = SEQ_transform_single_image_check(seq);
|
||||
strip_ctx.handle_width = sequence_handle_size_get_clamped(ctx->scene, seq, ctx->pixelx);
|
||||
strip_ctx.show_strip_color_tag = (ctx->sseq->timeline_overlay.flag &
|
||||
SEQ_TIMELINE_SHOW_STRIP_COLOR_TAG);
|
||||
|
||||
if (strip_ctx.can_draw_text_overlay) {
|
||||
strip_ctx.strip_content_top = strip_ctx.top - min_ff(0.40f, 20 * UI_SCALE_FAC * ctx->pixely);
|
||||
}
|
||||
else {
|
||||
strip_ctx.strip_content_top = strip_ctx.top;
|
||||
}
|
||||
|
||||
return strip_ctx;
|
||||
}
|
||||
|
||||
void color3ubv_from_seq(const Scene *curscene,
|
||||
const Sequence *seq,
|
||||
const bool show_strip_color_tag,
|
||||
@@ -240,24 +386,6 @@ struct WaveVizData {
|
||||
bool final_sample; /* There are no more samples. */
|
||||
};
|
||||
|
||||
static bool seq_draw_waveforms_poll(const bContext * /*C*/, SpaceSeq *sseq, Sequence *seq)
|
||||
{
|
||||
const bool strip_is_valid = seq->type == SEQ_TYPE_SOUND_RAM && seq->sound != nullptr;
|
||||
const bool overlays_enabled = (sseq->flag & SEQ_SHOW_OVERLAY) != 0;
|
||||
const bool ovelay_option = ((sseq->timeline_overlay.flag & SEQ_TIMELINE_ALL_WAVEFORMS) != 0 ||
|
||||
(seq->flag & SEQ_AUDIO_DRAW_WAVEFORM));
|
||||
|
||||
if ((sseq->timeline_overlay.flag & SEQ_TIMELINE_NO_WAVEFORMS) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strip_is_valid && overlays_enabled && ovelay_option) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void waveform_job_start_if_needed(const bContext *C, Sequence *seq)
|
||||
{
|
||||
bSound *sound = seq->sound;
|
||||
@@ -396,31 +524,34 @@ static size_t waveform_append_sample(WaveVizData *waveform_data,
|
||||
return data_written;
|
||||
}
|
||||
|
||||
/**
|
||||
* \param x1, x2, y1, y2: The starting and end X value to draw the wave, same for y1 and y2.
|
||||
* \param frames_per_pixel: The amount of pixels a whole frame takes up (x-axis direction).
|
||||
*/
|
||||
static void draw_seq_waveform_overlay(
|
||||
const bContext *C, ARegion *region, Sequence *seq, float x1, float y1, float x2, float y2)
|
||||
static void draw_seq_waveform_overlay(TimelineDrawContext *timeline_ctx,
|
||||
StripDrawContext *strip_ctx)
|
||||
{
|
||||
const View2D *v2d = ®ion->v2d;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
if (!seq_draw_waveforms_poll(timeline_ctx->C, timeline_ctx->sseq, strip_ctx->seq) ||
|
||||
strip_ctx->is_too_small)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const float frames_per_pixel = BLI_rctf_size_x(®ion->v2d.cur) / region->winx;
|
||||
const View2D *v2d = timeline_ctx->v2d;
|
||||
Scene *scene = timeline_ctx->scene;
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
|
||||
const float frames_per_pixel = BLI_rctf_size_x(&v2d->cur) / timeline_ctx->region->winx;
|
||||
const float samples_per_frame = SOUND_WAVE_SAMPLES_PER_SECOND / FPS;
|
||||
|
||||
/* Align strip start with nearest pixel to prevent waveform flickering. */
|
||||
const float x1_aligned = align_frame_with_pixel(x1, frames_per_pixel);
|
||||
const float x1_aligned = align_frame_with_pixel(strip_ctx->content_start, frames_per_pixel);
|
||||
/* Offset x1 and x2 values, to match view min/max, if strip is out of bounds. */
|
||||
const float frame_start = max_ff(v2d->cur.xmin, x1_aligned);
|
||||
const float frame_end = min_ff(v2d->cur.xmax, x2);
|
||||
const float frame_end = min_ff(v2d->cur.xmax, strip_ctx->right_handle);
|
||||
const int pixels_to_draw = round_fl_to_int((frame_end - frame_start) / frames_per_pixel);
|
||||
|
||||
if (pixels_to_draw < 2) {
|
||||
return; /* Not much to draw, exit before running job. */
|
||||
}
|
||||
|
||||
waveform_job_start_if_needed(C, seq);
|
||||
waveform_job_start_if_needed(timeline_ctx->C, seq);
|
||||
|
||||
SoundWaveform *waveform = static_cast<SoundWaveform *>(seq->sound->waveform);
|
||||
if (waveform == nullptr || waveform->length == 0) {
|
||||
@@ -501,9 +632,9 @@ static void draw_seq_waveform_overlay(
|
||||
|
||||
bool is_line_strip = (value_max - value_min < 0.05f);
|
||||
/* The y coordinate for the middle of the strip. */
|
||||
float y_mid = (y1 + y2) / 2.0f;
|
||||
float y_mid = (strip_ctx->bottom + strip_ctx->strip_content_top) / 2.0f;
|
||||
/* The length from the middle of the strip to the top/bottom. */
|
||||
float y_scale = (y2 - y1) / 2.0f;
|
||||
float y_scale = (strip_ctx->strip_content_top - strip_ctx->bottom) / 2.0f;
|
||||
|
||||
vec2f pos = {frame_start + i * frames_per_pixel, y_mid + value_min * y_scale};
|
||||
WaveVizData *new_data = &waveform_data[wave_data_len];
|
||||
@@ -517,20 +648,26 @@ static void draw_seq_waveform_overlay(
|
||||
MEM_freeN(waveform_data);
|
||||
}
|
||||
|
||||
static void drawmeta_contents(Scene *scene,
|
||||
Sequence *seqm,
|
||||
float x1,
|
||||
float y1,
|
||||
float x2,
|
||||
float y2,
|
||||
const bool show_strip_color_tag)
|
||||
static void drawmeta_contents(TimelineDrawContext *timeline_ctx, StripDrawContext *strip_ctx)
|
||||
{
|
||||
Sequence *seq_meta = strip_ctx->seq;
|
||||
if (!strip_ctx->can_draw_strip_content || (timeline_ctx->sseq->flag & SEQ_SHOW_OVERLAY) == 0) {
|
||||
return;
|
||||
}
|
||||
if ((seq_meta->type != SEQ_TYPE_META) &&
|
||||
((seq_meta->type != SEQ_TYPE_SCENE) || (seq_meta->flag & SEQ_SCENE_STRIPS) == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Scene *scene = timeline_ctx->scene;
|
||||
|
||||
uchar col[4];
|
||||
|
||||
int chan_min = MAXSEQ;
|
||||
int chan_max = 0;
|
||||
int chan_range = 0;
|
||||
float draw_range = y2 - y1;
|
||||
float draw_range = strip_ctx->top - strip_ctx->bottom;
|
||||
float draw_height;
|
||||
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
@@ -539,14 +676,14 @@ static void drawmeta_contents(Scene *scene,
|
||||
ListBase *meta_channels;
|
||||
int offset;
|
||||
|
||||
meta_seqbase = SEQ_get_seqbase_from_sequence(seqm, &meta_channels, &offset);
|
||||
meta_seqbase = SEQ_get_seqbase_from_sequence(seq_meta, &meta_channels, &offset);
|
||||
|
||||
if (!meta_seqbase || BLI_listbase_is_empty(meta_seqbase)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (seqm->type == SEQ_TYPE_SCENE) {
|
||||
offset = seqm->start - offset;
|
||||
if (seq_meta->type == SEQ_TYPE_SCENE) {
|
||||
offset = seq_meta->start - offset;
|
||||
}
|
||||
else {
|
||||
offset = 0;
|
||||
@@ -572,7 +709,7 @@ static void drawmeta_contents(Scene *scene,
|
||||
const int startdisp = SEQ_time_left_handle_frame_get(scene, seq) + offset;
|
||||
const int enddisp = SEQ_time_right_handle_frame_get(scene, seq) + offset;
|
||||
|
||||
if ((startdisp > x2 || enddisp < x1) == 0) {
|
||||
if ((startdisp > strip_ctx->right_handle || enddisp < strip_ctx->left_handle) == 0) {
|
||||
float y_chan = (seq->machine - chan_min) / float(chan_range) * draw_range;
|
||||
float x1_chan = startdisp;
|
||||
float x2_chan = enddisp;
|
||||
@@ -583,10 +720,10 @@ static void drawmeta_contents(Scene *scene,
|
||||
rgb_float_to_uchar(col, colvars->col);
|
||||
}
|
||||
else {
|
||||
color3ubv_from_seq(scene, seq, show_strip_color_tag, col);
|
||||
color3ubv_from_seq(scene, seq, strip_ctx->show_strip_color_tag, col);
|
||||
}
|
||||
|
||||
if (SEQ_render_is_muted(channels, seqm) || SEQ_render_is_muted(meta_channels, seq)) {
|
||||
if (SEQ_render_is_muted(channels, seq_meta) || SEQ_render_is_muted(meta_channels, seq)) {
|
||||
col[3] = 64;
|
||||
}
|
||||
else {
|
||||
@@ -596,15 +733,15 @@ static void drawmeta_contents(Scene *scene,
|
||||
immUniformColor4ubv(col);
|
||||
|
||||
/* Clamp within parent sequence strip bounds. */
|
||||
if (x1_chan < x1) {
|
||||
x1_chan = x1;
|
||||
if (x1_chan < strip_ctx->left_handle) {
|
||||
x1_chan = strip_ctx->left_handle;
|
||||
}
|
||||
if (x2_chan > x2) {
|
||||
x2_chan = x2;
|
||||
if (x2_chan > strip_ctx->right_handle) {
|
||||
x2_chan = strip_ctx->right_handle;
|
||||
}
|
||||
|
||||
y1_chan = y1 + y_chan + (draw_height * SEQ_STRIP_OFSBOTTOM);
|
||||
y2_chan = y1 + y_chan + (draw_height * SEQ_STRIP_OFSTOP);
|
||||
y1_chan = strip_ctx->bottom + y_chan + (draw_height * SEQ_STRIP_OFSBOTTOM);
|
||||
y2_chan = strip_ctx->bottom + y_chan + (draw_height * SEQ_STRIP_OFSTOP);
|
||||
|
||||
immRectf(pos, x1_chan, y1_chan, x2_chan, y2_chan);
|
||||
}
|
||||
@@ -627,46 +764,39 @@ float sequence_handle_size_get_clamped(const Scene *scene, Sequence *seq, const
|
||||
}
|
||||
|
||||
/* Draw a handle, on left or right side of strip. */
|
||||
static void draw_seq_handle(const Scene *scene,
|
||||
View2D *v2d,
|
||||
Sequence *seq,
|
||||
const float handsize_clamped,
|
||||
const short direction,
|
||||
uint pos,
|
||||
bool seq_active,
|
||||
float pixelx,
|
||||
const bool draw_strip_preview)
|
||||
static void draw_seq_handle(TimelineDrawContext *timeline_ctx,
|
||||
StripDrawContext *strip_ctx,
|
||||
const short direction)
|
||||
{
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
|
||||
if (SEQ_transform_is_locked(timeline_ctx->channels, seq)) {
|
||||
return;
|
||||
}
|
||||
|
||||
float rx1 = 0, rx2 = 0;
|
||||
float x1, x2, y1, y2;
|
||||
uint whichsel = 0;
|
||||
uchar col[4];
|
||||
|
||||
x1 = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
x2 = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
|
||||
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
|
||||
y2 = seq->machine + SEQ_STRIP_OFSTOP;
|
||||
|
||||
/* Set up co-ordinates and dimensions for either left or right handle. */
|
||||
if (direction == SEQ_LEFTHANDLE) {
|
||||
rx1 = x1;
|
||||
rx2 = x1 + handsize_clamped;
|
||||
rx1 = strip_ctx->left_handle;
|
||||
rx2 = strip_ctx->left_handle + strip_ctx->handle_width;
|
||||
whichsel = SEQ_LEFTSEL;
|
||||
}
|
||||
else if (direction == SEQ_RIGHTHANDLE) {
|
||||
rx1 = x2 - handsize_clamped;
|
||||
rx2 = x2;
|
||||
rx1 = strip_ctx->right_handle - strip_ctx->handle_width;
|
||||
rx2 = strip_ctx->right_handle;
|
||||
whichsel = SEQ_RIGHTSEL;
|
||||
}
|
||||
|
||||
if (!(seq->type & SEQ_TYPE_EFFECT) || SEQ_effect_get_num_inputs(seq->type) == 0) {
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
if (seq->flag & whichsel) {
|
||||
if (seq_active) {
|
||||
if (strip_ctx->is_active_strip) {
|
||||
UI_GetThemeColor3ubv(TH_SEQ_ACTIVE, col);
|
||||
}
|
||||
else {
|
||||
@@ -681,12 +811,13 @@ static void draw_seq_handle(const Scene *scene,
|
||||
immUniformColor4ub(0, 0, 0, 50);
|
||||
}
|
||||
|
||||
immRectf(pos, rx1, y1, rx2, y2);
|
||||
immRectf(pos, rx1, strip_ctx->bottom, rx2, strip_ctx->top);
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
/* Draw numbers for start and end of the strip next to its handles. */
|
||||
if (draw_strip_preview &&
|
||||
if (strip_ctx->can_draw_strip_content &&
|
||||
(((seq->flag & SELECT) && (G.moving & G_TRANSFORM_SEQ)) || (seq->flag & whichsel)))
|
||||
{
|
||||
|
||||
@@ -696,46 +827,42 @@ static void draw_seq_handle(const Scene *scene,
|
||||
BLF_set_default();
|
||||
|
||||
/* Calculate if strip is wide enough for showing the labels. */
|
||||
numstr_len = SNPRINTF_RLEN(numstr,
|
||||
"%d%d",
|
||||
SEQ_time_left_handle_frame_get(scene, seq),
|
||||
SEQ_time_right_handle_frame_get(scene, seq));
|
||||
numstr_len = SNPRINTF_RLEN(
|
||||
numstr, "%d%d", int(strip_ctx->left_handle), int(strip_ctx->right_handle));
|
||||
float tot_width = BLF_width(fontid, numstr, numstr_len);
|
||||
|
||||
if ((x2 - x1) / pixelx > 20 + tot_width) {
|
||||
if ((strip_ctx->right_handle - strip_ctx->left_handle) / timeline_ctx->pixelx > 20 + tot_width)
|
||||
{
|
||||
col[0] = col[1] = col[2] = col[3] = 255;
|
||||
float text_margin = 1.2f * handsize_clamped;
|
||||
float text_margin = 1.2f * strip_ctx->handle_width;
|
||||
|
||||
float text_x = strip_ctx->left_handle;
|
||||
const float text_y = strip_ctx->bottom + 0.09f;
|
||||
if (direction == SEQ_LEFTHANDLE) {
|
||||
numstr_len = SNPRINTF_RLEN(numstr, "%d", SEQ_time_left_handle_frame_get(scene, seq));
|
||||
x1 += text_margin;
|
||||
y1 += 0.09f;
|
||||
numstr_len = SNPRINTF_RLEN(numstr, "%d", int(strip_ctx->left_handle));
|
||||
text_x += text_margin;
|
||||
}
|
||||
else {
|
||||
numstr_len = SNPRINTF_RLEN(numstr, "%d", SEQ_time_right_handle_frame_get(scene, seq) - 1);
|
||||
x1 = x2 - (text_margin + pixelx * BLF_width(fontid, numstr, numstr_len));
|
||||
y1 += 0.09f;
|
||||
numstr_len = SNPRINTF_RLEN(numstr, "%d", int(strip_ctx->right_handle - 1));
|
||||
text_x = strip_ctx->right_handle -
|
||||
(text_margin + timeline_ctx->pixelx * BLF_width(fontid, numstr, numstr_len));
|
||||
}
|
||||
UI_view2d_text_cache_add(v2d, x1, y1, numstr, numstr_len, col);
|
||||
UI_view2d_text_cache_add(timeline_ctx->v2d, text_x, text_y, numstr, numstr_len, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_seq_outline(Scene *scene,
|
||||
Sequence *seq,
|
||||
uint pos,
|
||||
float x1,
|
||||
float x2,
|
||||
float y1,
|
||||
float y2,
|
||||
float pixelx,
|
||||
float pixely,
|
||||
bool seq_active)
|
||||
static void draw_seq_outline(TimelineDrawContext *timeline_ctx, StripDrawContext *strip_ctx)
|
||||
{
|
||||
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
uchar col[3];
|
||||
|
||||
/* Get the color for the outline. */
|
||||
if (seq_active && (seq->flag & SELECT)) {
|
||||
if (strip_ctx->is_active_strip && (seq->flag & SELECT)) {
|
||||
UI_GetThemeColor3ubv(TH_SEQ_ACTIVE, col);
|
||||
}
|
||||
else if (seq->flag & SELECT) {
|
||||
@@ -750,7 +877,7 @@ static void draw_seq_outline(Scene *scene,
|
||||
* - Slightly lighter.
|
||||
* - Red when overlapping with other strips.
|
||||
*/
|
||||
const eSeqOverlapMode overlap_mode = SEQ_tool_settings_overlap_mode_get(scene);
|
||||
const eSeqOverlapMode overlap_mode = SEQ_tool_settings_overlap_mode_get(timeline_ctx->scene);
|
||||
if ((G.moving & G_TRANSFORM_SEQ) && (seq->flag & SELECT) &&
|
||||
overlap_mode != SEQ_OVERLAP_OVERWRITE) {
|
||||
if (seq->flag & SEQ_OVERLAP) {
|
||||
@@ -768,18 +895,36 @@ static void draw_seq_outline(Scene *scene,
|
||||
* draw outline as four boxes instead. */
|
||||
if (seq->flag & SELECT) {
|
||||
/* Left */
|
||||
immRectf(pos, x1 - pixelx, y1, x1 + pixelx, y2);
|
||||
immRectf(pos,
|
||||
strip_ctx->left_handle - timeline_ctx->pixelx,
|
||||
strip_ctx->bottom,
|
||||
strip_ctx->left_handle + timeline_ctx->pixelx,
|
||||
strip_ctx->top);
|
||||
/* Bottom */
|
||||
immRectf(pos, x1 - pixelx, y1, x2 + pixelx, y1 + 2 * pixely);
|
||||
immRectf(pos,
|
||||
strip_ctx->left_handle - timeline_ctx->pixelx,
|
||||
strip_ctx->bottom,
|
||||
strip_ctx->right_handle + timeline_ctx->pixelx,
|
||||
strip_ctx->bottom + 2 * timeline_ctx->pixely);
|
||||
/* Right */
|
||||
immRectf(pos, x2 - pixelx, y1, x2 + pixelx, y2);
|
||||
immRectf(pos,
|
||||
strip_ctx->right_handle - timeline_ctx->pixelx,
|
||||
strip_ctx->bottom,
|
||||
strip_ctx->right_handle + timeline_ctx->pixelx,
|
||||
strip_ctx->top);
|
||||
/* Top */
|
||||
immRectf(pos, x1 - pixelx, y2 - 2 * pixely, x2 + pixelx, y2);
|
||||
immRectf(pos,
|
||||
strip_ctx->left_handle - timeline_ctx->pixelx,
|
||||
strip_ctx->top - 2 * timeline_ctx->pixely,
|
||||
strip_ctx->right_handle + timeline_ctx->pixelx,
|
||||
strip_ctx->top);
|
||||
}
|
||||
else {
|
||||
/* 1px wide outline for unselected strips. */
|
||||
imm_draw_box_wire_2d(pos, x1, y1, x2, y2);
|
||||
imm_draw_box_wire_2d(
|
||||
pos, strip_ctx->left_handle, strip_ctx->bottom, strip_ctx->right_handle, strip_ctx->top);
|
||||
}
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static const char *draw_seq_text_get_name(Sequence *seq)
|
||||
@@ -848,22 +993,23 @@ static void draw_seq_text_get_source(Sequence *seq, char *r_source, size_t sourc
|
||||
}
|
||||
}
|
||||
|
||||
static size_t draw_seq_text_get_overlay_string(const Scene *scene,
|
||||
SpaceSeq *sseq,
|
||||
Sequence *seq,
|
||||
static size_t draw_seq_text_get_overlay_string(TimelineDrawContext *timeline_ctx,
|
||||
StripDrawContext *strip_ctx,
|
||||
char *r_overlay_string,
|
||||
size_t overlay_string_len)
|
||||
{
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
|
||||
const char *text_sep = " | ";
|
||||
const char *text_array[5];
|
||||
int i = 0;
|
||||
|
||||
if (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_NAME) {
|
||||
if (timeline_ctx->sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_NAME) {
|
||||
text_array[i++] = draw_seq_text_get_name(seq);
|
||||
}
|
||||
|
||||
char source[FILE_MAX];
|
||||
if (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_SOURCE) {
|
||||
if (timeline_ctx->sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_SOURCE) {
|
||||
draw_seq_text_get_source(seq, source, sizeof(source));
|
||||
if (source[0] != '\0') {
|
||||
if (i != 0) {
|
||||
@@ -874,9 +1020,8 @@ static size_t draw_seq_text_get_overlay_string(const Scene *scene,
|
||||
}
|
||||
|
||||
char strip_duration_text[16];
|
||||
if (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_DURATION) {
|
||||
const int strip_duration = SEQ_time_right_handle_frame_get(scene, seq) -
|
||||
SEQ_time_left_handle_frame_get(scene, seq);
|
||||
if (timeline_ctx->sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_DURATION) {
|
||||
const int strip_duration = strip_ctx->right_handle - strip_ctx->left_handle;
|
||||
SNPRINTF(strip_duration_text, "%d", strip_duration);
|
||||
if (i != 0) {
|
||||
text_array[i++] = text_sep;
|
||||
@@ -889,22 +1034,52 @@ static size_t draw_seq_text_get_overlay_string(const Scene *scene,
|
||||
return BLI_string_join_array(r_overlay_string, overlay_string_len, text_array, i);
|
||||
}
|
||||
|
||||
/* Draw info text on a sequence strip. */
|
||||
static void draw_seq_text_overlay(Scene *scene,
|
||||
View2D *v2d,
|
||||
Sequence *seq,
|
||||
SpaceSeq *sseq,
|
||||
float x1,
|
||||
float x2,
|
||||
float y1,
|
||||
float y2,
|
||||
bool seq_active)
|
||||
/* For text on the strip. */
|
||||
static void calculate_seq_text_offsets(TimelineDrawContext *timeline_ctx,
|
||||
StripDrawContext *strip_ctx,
|
||||
float *x1,
|
||||
float *x2)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_displayed_get(ed);
|
||||
float text_margin = 2.0f * strip_ctx->handle_width;
|
||||
|
||||
*x1 += text_margin;
|
||||
*x2 -= text_margin;
|
||||
|
||||
CLAMP(*x1, timeline_ctx->v2d->cur.xmin + text_margin, timeline_ctx->v2d->cur.xmax);
|
||||
CLAMP(*x2, timeline_ctx->v2d->cur.xmin + text_margin, timeline_ctx->v2d->cur.xmax);
|
||||
}
|
||||
|
||||
/* Draw info text on a sequence strip. */
|
||||
static void draw_seq_text_overlay(TimelineDrawContext *timeline_ctx, StripDrawContext *strip_ctx)
|
||||
{
|
||||
/* If a waveform or a color strip is drawn,
|
||||
* avoid drawing text when there is not enough vertical space. */
|
||||
if (!strip_ctx->can_draw_text_overlay &&
|
||||
(seq_draw_waveforms_poll(timeline_ctx->C, timeline_ctx->sseq, strip_ctx->seq) ||
|
||||
strip_ctx->seq->type == SEQ_TYPE_COLOR))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((timeline_ctx->sseq->flag & SEQ_SHOW_OVERLAY) == 0) {
|
||||
return;
|
||||
}
|
||||
/* Draw text only if there is enough horizontal or vertical space. */
|
||||
if (((strip_ctx->right_handle - strip_ctx->left_handle) <=
|
||||
32 * timeline_ctx->pixelx * UI_SCALE_FAC) ||
|
||||
strip_ctx->is_too_small)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Depending on the vertical space, draw text on top or in the center of strip. */
|
||||
float x1 = strip_ctx->left_handle, x2 = strip_ctx->right_handle;
|
||||
calculate_seq_text_offsets(timeline_ctx, strip_ctx, &x1, &x2);
|
||||
float y1 = !strip_ctx->can_draw_strip_content ? strip_ctx->bottom :
|
||||
strip_ctx->strip_content_top; // Y1
|
||||
|
||||
char overlay_string[FILE_MAX];
|
||||
size_t overlay_string_len = draw_seq_text_get_overlay_string(
|
||||
scene, sseq, seq, overlay_string, sizeof(overlay_string));
|
||||
timeline_ctx, strip_ctx, overlay_string, sizeof(overlay_string));
|
||||
|
||||
if (overlay_string_len == 0) {
|
||||
return;
|
||||
@@ -912,12 +1087,12 @@ static void draw_seq_text_overlay(Scene *scene,
|
||||
|
||||
/* White text for the active strip. */
|
||||
uchar col[4];
|
||||
col[0] = col[1] = col[2] = seq_active ? 255 : 10;
|
||||
col[0] = col[1] = col[2] = strip_ctx->is_active_strip ? 255 : 10;
|
||||
col[3] = 255;
|
||||
|
||||
/* Make the text duller when the strip is muted. */
|
||||
if (SEQ_render_is_muted(channels, seq)) {
|
||||
if (seq_active) {
|
||||
if (SEQ_render_is_muted(timeline_ctx->channels, strip_ctx->seq)) {
|
||||
if (strip_ctx->is_active_strip) {
|
||||
UI_GetColorPtrShade3ubv(col, col, -70);
|
||||
}
|
||||
else {
|
||||
@@ -929,28 +1104,37 @@ static void draw_seq_text_overlay(Scene *scene,
|
||||
rect.xmin = x1;
|
||||
rect.ymin = y1;
|
||||
rect.xmax = x2;
|
||||
rect.ymax = y2;
|
||||
rect.ymax = strip_ctx->top;
|
||||
|
||||
UI_view2d_text_cache_add_rectf(v2d, &rect, overlay_string, overlay_string_len, col);
|
||||
UI_view2d_text_cache_add_rectf(
|
||||
timeline_ctx->v2d, &rect, overlay_string, overlay_string_len, col);
|
||||
}
|
||||
|
||||
static void draw_sequence_extensions_overlay(
|
||||
Scene *scene, Sequence *seq, uint pos, float pixely, const bool show_strip_color_tag)
|
||||
static void draw_strip_offsets(TimelineDrawContext *timeline_ctx, StripDrawContext *strip_ctx)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_displayed_get(ed);
|
||||
float x1, x2, y1, y2;
|
||||
uchar col[4], blend_col[3];
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
|
||||
x1 = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
x2 = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
if ((timeline_ctx->sseq->flag & SEQ_SHOW_OVERLAY) == 0) {
|
||||
return;
|
||||
}
|
||||
if (strip_ctx->is_single_image || timeline_ctx->pixely <= 0) {
|
||||
return;
|
||||
}
|
||||
if ((timeline_ctx->sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_OFFSETS) == 0 &&
|
||||
(strip_ctx->seq != special_seq_update))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
|
||||
y2 = seq->machine + SEQ_STRIP_OFSTOP;
|
||||
Scene *scene = timeline_ctx->scene;
|
||||
ListBase *channels = timeline_ctx->channels;
|
||||
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
color3ubv_from_seq(scene, seq, show_strip_color_tag, col);
|
||||
uchar col[4], blend_col[3];
|
||||
color3ubv_from_seq(scene, seq, strip_ctx->show_strip_color_tag, col);
|
||||
if (seq->flag & SELECT) {
|
||||
UI_GetColorPtrShade3ubv(col, col, 50);
|
||||
}
|
||||
@@ -964,21 +1148,38 @@ static void draw_sequence_extensions_overlay(
|
||||
|
||||
if (left_handle_frame > strip_content_start) {
|
||||
immUniformColor4ubv(col);
|
||||
immRectf(pos, strip_content_start, y1 - pixely, x1, y1 - SEQ_STRIP_OFSBOTTOM);
|
||||
immRectf(pos,
|
||||
strip_content_start,
|
||||
strip_ctx->bottom - timeline_ctx->pixely,
|
||||
strip_ctx->content_start,
|
||||
strip_ctx->bottom - SEQ_STRIP_OFSBOTTOM);
|
||||
|
||||
/* Outline. */
|
||||
immUniformColor3ubv(blend_col);
|
||||
imm_draw_box_wire_2d(pos, x1, y1 - pixely, strip_content_start, y1 - SEQ_STRIP_OFSBOTTOM);
|
||||
imm_draw_box_wire_2d(pos,
|
||||
strip_ctx->content_start,
|
||||
strip_ctx->bottom - timeline_ctx->pixely,
|
||||
strip_content_start,
|
||||
strip_ctx->bottom - SEQ_STRIP_OFSBOTTOM);
|
||||
}
|
||||
if (right_handle_frame < strip_content_end) {
|
||||
immUniformColor4ubv(col);
|
||||
immRectf(pos, x2, y2 + pixely, strip_content_end, y2 + SEQ_STRIP_OFSBOTTOM);
|
||||
immRectf(pos,
|
||||
strip_ctx->content_end,
|
||||
strip_ctx->top + timeline_ctx->pixely,
|
||||
strip_content_end,
|
||||
strip_ctx->top + SEQ_STRIP_OFSBOTTOM);
|
||||
|
||||
/* Outline. */
|
||||
immUniformColor3ubv(blend_col);
|
||||
imm_draw_box_wire_2d(pos, x2, y2 + pixely, strip_content_end, y2 + SEQ_STRIP_OFSBOTTOM);
|
||||
imm_draw_box_wire_2d(pos,
|
||||
strip_ctx->content_end,
|
||||
strip_ctx->top + timeline_ctx->pixely,
|
||||
strip_content_end,
|
||||
strip_ctx->top + SEQ_STRIP_OFSBOTTOM);
|
||||
}
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static uchar mute_overlap_alpha_factor_get(const ListBase *channels, const Sequence *seq)
|
||||
@@ -996,88 +1197,92 @@ static uchar mute_overlap_alpha_factor_get(const ListBase *channels, const Seque
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_color_strip_band(
|
||||
const Scene *scene, ListBase *channels, Sequence *seq, uint pos, float text_margin_y, float y1)
|
||||
static void draw_strip_color_band(TimelineDrawContext *timeline_ctx, StripDrawContext *strip_ctx)
|
||||
{
|
||||
uchar col[4];
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
Scene *scene = timeline_ctx->scene;
|
||||
|
||||
if ((timeline_ctx->sseq->flag & SEQ_SHOW_OVERLAY) == 0 || (seq->type != SEQ_TYPE_COLOR)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
uchar col[4];
|
||||
rgb_float_to_uchar(col, colvars->col);
|
||||
col[3] = mute_overlap_alpha_factor_get(timeline_ctx->channels, seq);
|
||||
|
||||
col[3] = mute_overlap_alpha_factor_get(channels, seq);
|
||||
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
immUniformColor4ubv(col);
|
||||
|
||||
immRectf(pos,
|
||||
SEQ_time_left_handle_frame_get(scene, seq),
|
||||
y1,
|
||||
strip_ctx->bottom,
|
||||
SEQ_time_right_handle_frame_get(scene, seq),
|
||||
text_margin_y);
|
||||
strip_ctx->strip_content_top);
|
||||
|
||||
/* 1px line to better separate the color band. */
|
||||
UI_GetColorPtrShade3ubv(col, col, -20);
|
||||
immUniformColor4ubv(col);
|
||||
|
||||
immBegin(GPU_PRIM_LINES, 2);
|
||||
immVertex2f(pos, SEQ_time_left_handle_frame_get(scene, seq), text_margin_y);
|
||||
immVertex2f(pos, SEQ_time_right_handle_frame_get(scene, seq), text_margin_y);
|
||||
immVertex2f(pos, SEQ_time_left_handle_frame_get(scene, seq), strip_ctx->strip_content_top);
|
||||
immVertex2f(pos, SEQ_time_right_handle_frame_get(scene, seq), strip_ctx->strip_content_top);
|
||||
immEnd();
|
||||
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void draw_seq_background(Scene *scene,
|
||||
Sequence *seq,
|
||||
uint pos,
|
||||
float x1,
|
||||
float x2,
|
||||
float y1,
|
||||
float y2,
|
||||
bool is_single_image,
|
||||
bool show_strip_color_tag)
|
||||
static void draw_strip_background(TimelineDrawContext *timeline_ctx, StripDrawContext *strip_ctx)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_displayed_get(ed);
|
||||
uchar col[4];
|
||||
Scene *scene = timeline_ctx->scene;
|
||||
ListBase *channels = timeline_ctx->channels;
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
color3ubv_from_seq(scene, seq, show_strip_color_tag, col);
|
||||
|
||||
uchar col[4];
|
||||
color3ubv_from_seq(scene, seq, strip_ctx->show_strip_color_tag, col);
|
||||
col[3] = mute_overlap_alpha_factor_get(channels, seq);
|
||||
|
||||
immUniformColor4ubv(col);
|
||||
|
||||
/* Draw the main strip body. */
|
||||
if (is_single_image) {
|
||||
if (strip_ctx->is_single_image) {
|
||||
immRectf(pos,
|
||||
SEQ_time_left_handle_frame_get(scene, seq),
|
||||
y1,
|
||||
strip_ctx->bottom,
|
||||
SEQ_time_right_handle_frame_get(scene, seq),
|
||||
y2);
|
||||
strip_ctx->top);
|
||||
}
|
||||
else {
|
||||
immRectf(pos, x1, y1, x2, y2);
|
||||
immRectf(
|
||||
pos, strip_ctx->content_start, strip_ctx->bottom, strip_ctx->content_end, strip_ctx->top);
|
||||
}
|
||||
|
||||
/* Draw background for hold still regions. */
|
||||
if (!is_single_image) {
|
||||
if (!strip_ctx->is_single_image) {
|
||||
UI_GetColorPtrShade3ubv(col, col, -35);
|
||||
immUniformColor4ubv(col);
|
||||
|
||||
if (SEQ_time_has_left_still_frames(scene, seq)) {
|
||||
float left_handle_frame = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
const float content_start = SEQ_time_start_frame_get(seq);
|
||||
immRectf(pos, left_handle_frame, y1, content_start, y2);
|
||||
immRectf(pos, left_handle_frame, strip_ctx->bottom, content_start, strip_ctx->top);
|
||||
}
|
||||
if (SEQ_time_has_right_still_frames(scene, seq)) {
|
||||
float right_handle_frame = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
const float content_end = SEQ_time_content_end_frame_get(scene, seq);
|
||||
immRectf(pos, content_end, y1, right_handle_frame, y2);
|
||||
immRectf(pos, content_end, strip_ctx->bottom, right_handle_frame, strip_ctx->top);
|
||||
}
|
||||
}
|
||||
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
@@ -1085,20 +1290,18 @@ typedef enum {
|
||||
STRIP_TRANSITION_OUT,
|
||||
} TransitionType;
|
||||
|
||||
static void draw_seq_transition_strip_half(const Scene *scene,
|
||||
const Sequence *transition_seq,
|
||||
const float x1,
|
||||
const float x2,
|
||||
const float y1,
|
||||
const float y2,
|
||||
const int timeline_overlay_flags,
|
||||
static void draw_seq_transition_strip_half(TimelineDrawContext *timeline_ctx,
|
||||
StripDrawContext *strip_ctx,
|
||||
const TransitionType transition_type)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
|
||||
const int timeline_overlay_flags = timeline_ctx->sseq->timeline_overlay.flag;
|
||||
|
||||
Editing *ed = SEQ_editing_get(timeline_ctx->scene);
|
||||
const ListBase *channels = SEQ_channels_displayed_get(ed);
|
||||
|
||||
const Sequence *seq1 = transition_seq->seq1;
|
||||
const Sequence *seq2 = transition_seq->seq2;
|
||||
const Sequence *seq1 = strip_ctx->seq->seq1;
|
||||
const Sequence *seq2 = strip_ctx->seq->seq2;
|
||||
const Sequence *target_seq = (transition_type == STRIP_TRANSITION_IN) ? seq1 : seq2;
|
||||
|
||||
const bool show_strip_color_tag = (timeline_overlay_flags & SEQ_TIMELINE_SHOW_STRIP_COLOR_TAG);
|
||||
@@ -1110,7 +1313,7 @@ static void draw_seq_transition_strip_half(const Scene *scene,
|
||||
}
|
||||
else {
|
||||
uchar ucol[3];
|
||||
color3ubv_from_seq(scene, target_seq, show_strip_color_tag, ucol);
|
||||
color3ubv_from_seq(timeline_ctx->scene, target_seq, show_strip_color_tag, ucol);
|
||||
/* If the transition inputs are of the same type, draw the right side slightly darker. */
|
||||
if ((seq1->type == seq2->type) && (transition_type == STRIP_TRANSITION_OUT)) {
|
||||
UI_GetColorPtrShade3ubv(ucol, ucol, -15);
|
||||
@@ -1118,7 +1321,7 @@ static void draw_seq_transition_strip_half(const Scene *scene,
|
||||
rgb_uchar_to_float(col, ucol);
|
||||
}
|
||||
|
||||
col[3] = mute_overlap_alpha_factor_get(channels, transition_seq) / 255.0f;
|
||||
col[3] = mute_overlap_alpha_factor_get(channels, strip_ctx->seq) / 255.0f;
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
@@ -1131,14 +1334,14 @@ static void draw_seq_transition_strip_half(const Scene *scene,
|
||||
float vert_pos[3][2];
|
||||
|
||||
if (transition_type == STRIP_TRANSITION_IN) {
|
||||
copy_v2_fl2(vert_pos[0], x1, y1);
|
||||
copy_v2_fl2(vert_pos[1], x1, y2);
|
||||
copy_v2_fl2(vert_pos[2], x2, y1);
|
||||
copy_v2_fl2(vert_pos[0], strip_ctx->content_start, strip_ctx->bottom);
|
||||
copy_v2_fl2(vert_pos[1], strip_ctx->content_start, strip_ctx->strip_content_top);
|
||||
copy_v2_fl2(vert_pos[2], strip_ctx->content_end, strip_ctx->bottom);
|
||||
}
|
||||
else {
|
||||
copy_v2_fl2(vert_pos[0], x1, y2);
|
||||
copy_v2_fl2(vert_pos[1], x2, y2);
|
||||
copy_v2_fl2(vert_pos[2], x2, y1);
|
||||
copy_v2_fl2(vert_pos[0], strip_ctx->content_start, strip_ctx->strip_content_top);
|
||||
copy_v2_fl2(vert_pos[1], strip_ctx->content_end, strip_ctx->strip_content_top);
|
||||
copy_v2_fl2(vert_pos[2], strip_ctx->content_end, strip_ctx->bottom);
|
||||
}
|
||||
|
||||
immBegin(GPU_PRIM_TRIS, 3);
|
||||
@@ -1152,22 +1355,25 @@ static void draw_seq_transition_strip_half(const Scene *scene,
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
static void draw_seq_transition_strip(const Scene *scene,
|
||||
const Sequence *seq,
|
||||
const float x1,
|
||||
const float x2,
|
||||
const float y1,
|
||||
const float y2,
|
||||
const int timeline_overlay_flags)
|
||||
static void draw_seq_transition_strip(TimelineDrawContext *timeline_ctx,
|
||||
StripDrawContext *strip_ctx)
|
||||
{
|
||||
draw_seq_transition_strip_half(
|
||||
scene, seq, x1, x2, y1, y2, timeline_overlay_flags, STRIP_TRANSITION_IN);
|
||||
draw_seq_transition_strip_half(
|
||||
scene, seq, x1, x2, y1, y2, timeline_overlay_flags, STRIP_TRANSITION_OUT);
|
||||
if (!strip_ctx->can_draw_strip_content || (timeline_ctx->sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
|
||||
!ELEM(strip_ctx->seq->type, SEQ_TYPE_CROSS, SEQ_TYPE_GAMCROSS, SEQ_TYPE_WIPE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
draw_seq_transition_strip_half(timeline_ctx, strip_ctx, STRIP_TRANSITION_IN);
|
||||
draw_seq_transition_strip_half(timeline_ctx, strip_ctx, STRIP_TRANSITION_OUT);
|
||||
}
|
||||
|
||||
static void draw_seq_locked(float x1, float y1, float x2, float y2)
|
||||
static void draw_seq_locked(TimelineDrawContext *timeline_ctx, StripDrawContext *strip_ctx)
|
||||
{
|
||||
if (!SEQ_transform_is_locked(timeline_ctx->channels, strip_ctx->seq)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
@@ -1178,40 +1384,35 @@ static void draw_seq_locked(float x1, float y1, float x2, float y2)
|
||||
immUniform1i("size1", 8);
|
||||
immUniform1i("size2", 4);
|
||||
|
||||
immRectf(pos, x1, y1, x2, y2);
|
||||
immRectf(
|
||||
pos, strip_ctx->left_handle, strip_ctx->bottom, strip_ctx->right_handle, strip_ctx->top);
|
||||
|
||||
immUnbindProgram();
|
||||
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y)
|
||||
static void draw_seq_invalid(StripDrawContext *strip_ctx)
|
||||
{
|
||||
if (SEQ_sequence_has_source(strip_ctx->seq)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor4f(1.0f, 0.0f, 0.0f, 0.9f);
|
||||
immRectf(pos, x1, y2, x2, text_margin_y);
|
||||
immRectf(pos,
|
||||
strip_ctx->left_handle,
|
||||
strip_ctx->top,
|
||||
strip_ctx->right_handle,
|
||||
strip_ctx->strip_content_top);
|
||||
|
||||
immUnbindProgram();
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
/* For text on the strip. */
|
||||
static void calculate_seq_text_offsets(
|
||||
const Scene *scene, View2D *v2d, Sequence *seq, float *x1, float *x2, float pixelx)
|
||||
{
|
||||
const float handsize_clamped = sequence_handle_size_get_clamped(scene, seq, pixelx);
|
||||
float text_margin = 2.0f * handsize_clamped;
|
||||
|
||||
*x1 += text_margin;
|
||||
*x2 -= text_margin;
|
||||
|
||||
CLAMP(*x1, v2d->cur.xmin + text_margin, v2d->cur.xmax);
|
||||
CLAMP(*x2, v2d->cur.xmin + text_margin, v2d->cur.xmax);
|
||||
}
|
||||
|
||||
static void fcurve_batch_add_verts(GPUVertBuf *vbo,
|
||||
float y1,
|
||||
float y2,
|
||||
@@ -1235,25 +1436,32 @@ static void fcurve_batch_add_verts(GPUVertBuf *vbo,
|
||||
* - Volume for sound strips.
|
||||
* - Opacity for the other types.
|
||||
*/
|
||||
static void draw_seq_fcurve_overlay(
|
||||
Scene *scene, View2D *v2d, Sequence *seq, float x1, float y1, float x2, float y2, float pixelx)
|
||||
static void draw_seq_fcurve_overlay(TimelineDrawContext *timeline_ctx, StripDrawContext *strip_ctx)
|
||||
{
|
||||
FCurve *fcu;
|
||||
if (!strip_ctx->can_draw_strip_content || (timeline_ctx->sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
|
||||
(timeline_ctx->sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_FCURVES) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (seq->type == SEQ_TYPE_SOUND_RAM) {
|
||||
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, nullptr);
|
||||
Scene *scene = timeline_ctx->scene;
|
||||
|
||||
FCurve *fcu;
|
||||
if (strip_ctx->seq->type == SEQ_TYPE_SOUND_RAM) {
|
||||
fcu = id_data_find_fcurve(&scene->id, strip_ctx->seq, &RNA_Sequence, "volume", 0, nullptr);
|
||||
}
|
||||
else {
|
||||
fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "blend_alpha", 0, nullptr);
|
||||
fcu = id_data_find_fcurve(
|
||||
&scene->id, strip_ctx->seq, &RNA_Sequence, "blend_alpha", 0, nullptr);
|
||||
}
|
||||
|
||||
if (fcu && !BKE_fcurve_is_empty(fcu)) {
|
||||
|
||||
/* Clamp curve evaluation to the editor's borders. */
|
||||
int eval_start = max_ff(x1, v2d->cur.xmin);
|
||||
int eval_end = min_ff(x2, v2d->cur.xmax + 1);
|
||||
int eval_start = max_ff(strip_ctx->left_handle, timeline_ctx->v2d->cur.xmin);
|
||||
int eval_end = min_ff(strip_ctx->right_handle, timeline_ctx->v2d->cur.xmax + 1);
|
||||
|
||||
int eval_step = max_ii(1, floor(pixelx));
|
||||
int eval_step = max_ii(1, floor(timeline_ctx->pixelx));
|
||||
|
||||
if (eval_start >= eval_end) {
|
||||
return;
|
||||
@@ -1267,7 +1475,7 @@ static void draw_seq_fcurve_overlay(
|
||||
GPU_vertbuf_data_alloc(vbo, max_verts);
|
||||
uint vert_count = 0;
|
||||
|
||||
const float y_height = y2 - y1;
|
||||
const float y_height = strip_ctx->top - strip_ctx->bottom;
|
||||
float curve_val;
|
||||
float prev_val = INT_MIN;
|
||||
bool skip = false;
|
||||
@@ -1285,12 +1493,23 @@ static void draw_seq_fcurve_overlay(
|
||||
|
||||
/* If some frames were skipped above, we need to close the shape. */
|
||||
if (skip) {
|
||||
fcurve_batch_add_verts(
|
||||
vbo, y1, y2, y_height, timeline_frame - eval_step, prev_val, &vert_count);
|
||||
fcurve_batch_add_verts(vbo,
|
||||
strip_ctx->bottom,
|
||||
strip_ctx->top,
|
||||
y_height,
|
||||
timeline_frame - eval_step,
|
||||
prev_val,
|
||||
&vert_count);
|
||||
skip = false;
|
||||
}
|
||||
|
||||
fcurve_batch_add_verts(vbo, y1, y2, y_height, timeline_frame, curve_val, &vert_count);
|
||||
fcurve_batch_add_verts(vbo,
|
||||
strip_ctx->bottom,
|
||||
strip_ctx->top,
|
||||
y_height,
|
||||
timeline_frame,
|
||||
curve_val,
|
||||
&vert_count);
|
||||
prev_val = curve_val;
|
||||
}
|
||||
|
||||
@@ -1310,187 +1529,29 @@ static void draw_seq_fcurve_overlay(
|
||||
}
|
||||
|
||||
/* Draw visible strips. Bounds check are already made. */
|
||||
static void draw_seq_strip(const bContext *C,
|
||||
SpaceSeq *sseq,
|
||||
Scene *scene,
|
||||
ARegion *region,
|
||||
Sequence *seq,
|
||||
float pixelx,
|
||||
bool seq_active)
|
||||
static void draw_seq_strip(TimelineDrawContext *timeline_ctx, StripDrawContext *strip_ctx)
|
||||
{
|
||||
Editing *ed = SEQ_editing_get(CTX_data_scene(C));
|
||||
ListBase *channels = SEQ_channels_displayed_get(ed);
|
||||
|
||||
View2D *v2d = ®ion->v2d;
|
||||
float x1, x2, y1, y2;
|
||||
const float handsize_clamped = sequence_handle_size_get_clamped(scene, seq, pixelx);
|
||||
float pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
|
||||
|
||||
/* Check if we are doing "solo preview". */
|
||||
bool is_single_image = char(SEQ_transform_single_image_check(seq));
|
||||
|
||||
/* Use the seq->color_tag to display the tag color. */
|
||||
const bool show_strip_color_tag = (sseq->timeline_overlay.flag &
|
||||
SEQ_TIMELINE_SHOW_STRIP_COLOR_TAG);
|
||||
|
||||
/* Draw strip body. */
|
||||
x1 = SEQ_time_has_left_still_frames(scene, seq) ? SEQ_time_start_frame_get(seq) :
|
||||
SEQ_time_left_handle_frame_get(scene, seq);
|
||||
y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
|
||||
x2 = SEQ_time_has_right_still_frames(scene, seq) ? SEQ_time_content_end_frame_get(scene, seq) :
|
||||
SEQ_time_right_handle_frame_get(scene, seq);
|
||||
y2 = seq->machine + SEQ_STRIP_OFSTOP;
|
||||
|
||||
/* Limit body to strip bounds. Meta strip can end up with content outside of strip range. */
|
||||
x1 = min_ff(x1, SEQ_time_right_handle_frame_get(scene, seq));
|
||||
x2 = max_ff(x2, SEQ_time_left_handle_frame_get(scene, seq));
|
||||
|
||||
float text_margin_y;
|
||||
/* Whether there is enough space for the strip preview. */
|
||||
const bool draw_strip_preview = ((y2 - y1) / pixely) > 20 * UI_SCALE_FAC;
|
||||
/* If there is not enough vertical space, don't draw any previews nor the title. */
|
||||
const bool strip_content_none = (y2 - y1) < 8 * pixely * UI_SCALE_FAC;
|
||||
/* Only a single vertical element is drawn on the strip: the waveform in the case of
|
||||
* sound strips, or the strip title for most other strip types. */
|
||||
bool strip_content_single;
|
||||
|
||||
if ((sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_NAME) ||
|
||||
(sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_SOURCE) ||
|
||||
(sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_DURATION))
|
||||
{
|
||||
|
||||
/* Calculate height needed for drawing text on strip. */
|
||||
text_margin_y = y2 - min_ff(0.40f, 20 * UI_SCALE_FAC * pixely);
|
||||
|
||||
strip_content_single = !draw_strip_preview;
|
||||
}
|
||||
else {
|
||||
text_margin_y = y2;
|
||||
strip_content_single = true;
|
||||
}
|
||||
/* When a text overlay is enabled and there is space for both the text and the strip content,
|
||||
* draw below the text. */
|
||||
/* When text is disabled or there is space for only one or the other, use entire strip area. */
|
||||
const float strip_preview_y2 = strip_content_single ? y2 : text_margin_y;
|
||||
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
|
||||
draw_seq_background(scene, seq, pos, x1, x2, y1, y2, is_single_image, show_strip_color_tag);
|
||||
|
||||
/* Draw a color band inside color strip. */
|
||||
if ((sseq->flag & SEQ_SHOW_OVERLAY) && (seq->type == SEQ_TYPE_COLOR)) {
|
||||
draw_color_strip_band(scene, channels, seq, pos, strip_preview_y2, y1);
|
||||
}
|
||||
|
||||
/* Draw strip offsets when flag is enabled or during "solo preview". */
|
||||
if (sseq->flag & SEQ_SHOW_OVERLAY) {
|
||||
if (!is_single_image && pixely > 0) {
|
||||
if ((sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_OFFSETS) ||
|
||||
(seq == special_seq_update)) {
|
||||
draw_sequence_extensions_overlay(scene, seq, pos, pixely, show_strip_color_tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
immUnbindProgram();
|
||||
|
||||
if (draw_strip_preview && (sseq->flag & SEQ_SHOW_OVERLAY) &&
|
||||
ELEM(seq->type, SEQ_TYPE_CROSS, SEQ_TYPE_GAMCROSS, SEQ_TYPE_WIPE))
|
||||
{
|
||||
draw_seq_transition_strip(
|
||||
scene, seq, x1, x2, y1, strip_preview_y2, sseq->timeline_overlay.flag);
|
||||
}
|
||||
|
||||
x1 = SEQ_time_left_handle_frame_get(scene, seq);
|
||||
x2 = SEQ_time_right_handle_frame_get(scene, seq);
|
||||
|
||||
if (draw_strip_preview && (sseq->flag & SEQ_SHOW_OVERLAY)) {
|
||||
if ((seq->type == SEQ_TYPE_META) ||
|
||||
((seq->type == SEQ_TYPE_SCENE) && (seq->flag & SEQ_SCENE_STRIPS)))
|
||||
{
|
||||
drawmeta_contents(scene, seq, x1, y1, x2, strip_preview_y2, show_strip_color_tag);
|
||||
}
|
||||
}
|
||||
|
||||
if ((sseq->flag & SEQ_SHOW_OVERLAY) &&
|
||||
(sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_THUMBNAILS) &&
|
||||
ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE))
|
||||
{
|
||||
draw_seq_strip_thumbnail(v2d, C, scene, seq, y1, strip_preview_y2, pixelx, pixely);
|
||||
}
|
||||
|
||||
if (draw_strip_preview && (sseq->flag & SEQ_SHOW_OVERLAY) &&
|
||||
(sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_FCURVES))
|
||||
{
|
||||
draw_seq_fcurve_overlay(scene, v2d, seq, x1, y1, x2, strip_preview_y2, pixelx);
|
||||
}
|
||||
|
||||
/* Draw sound strip waveform. */
|
||||
if (seq_draw_waveforms_poll(C, sseq, seq) && !strip_content_none) {
|
||||
draw_seq_waveform_overlay(
|
||||
C, region, seq, x1, strip_content_single ? y1 : y1 + 0.05f, x2, strip_preview_y2);
|
||||
}
|
||||
/* Draw locked state. */
|
||||
if (SEQ_transform_is_locked(channels, seq)) {
|
||||
draw_seq_locked(x1, y1, x2, y2);
|
||||
}
|
||||
|
||||
/* Draw Red line on the top of invalid strip (Missing media). */
|
||||
if (!SEQ_sequence_has_source(seq)) {
|
||||
draw_seq_invalid(x1, x2, y2, text_margin_y);
|
||||
}
|
||||
|
||||
pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
|
||||
if (!SEQ_transform_is_locked(channels, seq)) {
|
||||
draw_seq_handle(scene,
|
||||
v2d,
|
||||
seq,
|
||||
handsize_clamped,
|
||||
SEQ_LEFTHANDLE,
|
||||
pos,
|
||||
seq_active,
|
||||
pixelx,
|
||||
draw_strip_preview);
|
||||
draw_seq_handle(scene,
|
||||
v2d,
|
||||
seq,
|
||||
handsize_clamped,
|
||||
SEQ_RIGHTHANDLE,
|
||||
pos,
|
||||
seq_active,
|
||||
pixelx,
|
||||
draw_strip_preview);
|
||||
}
|
||||
|
||||
draw_seq_outline(scene, seq, pos, x1, x2, y1, y2, pixelx, pixely, seq_active);
|
||||
|
||||
immUnbindProgram();
|
||||
|
||||
/* If a waveform or a color strip is drawn,
|
||||
* avoid drawing text when there is not enough vertical space. */
|
||||
if (strip_content_single &&
|
||||
(seq_draw_waveforms_poll(C, sseq, seq) || seq->type == SEQ_TYPE_COLOR)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sseq->flag & SEQ_SHOW_OVERLAY) {
|
||||
/* Draw text only if there is enough horizontal or vertical space. */
|
||||
if (((x2 - x1) > 32 * pixelx * UI_SCALE_FAC) && !strip_content_none) {
|
||||
calculate_seq_text_offsets(scene, v2d, seq, &x1, &x2, pixelx);
|
||||
/* Depending on the vertical space, draw text on top or in the center of strip. */
|
||||
draw_seq_text_overlay(scene,
|
||||
v2d,
|
||||
seq,
|
||||
sseq,
|
||||
x1,
|
||||
x2,
|
||||
strip_content_single ? y1 : text_margin_y,
|
||||
y2,
|
||||
seq_active);
|
||||
}
|
||||
}
|
||||
draw_strip_background(timeline_ctx, strip_ctx);
|
||||
draw_strip_color_band(timeline_ctx, strip_ctx);
|
||||
draw_strip_offsets(timeline_ctx, strip_ctx);
|
||||
draw_seq_transition_strip(timeline_ctx, strip_ctx);
|
||||
drawmeta_contents(timeline_ctx, strip_ctx);
|
||||
draw_seq_strip_thumbnail(timeline_ctx->v2d,
|
||||
timeline_ctx->C,
|
||||
timeline_ctx->scene,
|
||||
strip_ctx->seq,
|
||||
strip_ctx->bottom,
|
||||
strip_ctx->strip_content_top,
|
||||
timeline_ctx->pixelx,
|
||||
timeline_ctx->pixely);
|
||||
draw_seq_fcurve_overlay(timeline_ctx, strip_ctx);
|
||||
draw_seq_waveform_overlay(timeline_ctx, strip_ctx);
|
||||
draw_seq_locked(timeline_ctx, strip_ctx);
|
||||
draw_seq_invalid(strip_ctx); /* Draw Red line on the top of invalid strip (Missing media). */
|
||||
draw_seq_handle(timeline_ctx, strip_ctx, SEQ_LEFTHANDLE);
|
||||
draw_seq_handle(timeline_ctx, strip_ctx, SEQ_RIGHTHANDLE);
|
||||
draw_seq_outline(timeline_ctx, strip_ctx);
|
||||
draw_seq_text_overlay(timeline_ctx, strip_ctx);
|
||||
}
|
||||
|
||||
static void draw_effect_inputs_highlight(const Scene *scene, Sequence *seq)
|
||||
@@ -1536,8 +1597,10 @@ static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_seq_timeline_channels(View2D *v2d)
|
||||
static void draw_seq_timeline_channels(TimelineDrawContext *ctx)
|
||||
{
|
||||
View2D *v2d = ctx->v2d;
|
||||
UI_view2d_view_ortho(v2d);
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
@@ -1556,14 +1619,19 @@ static void draw_seq_timeline_channels(View2D *v2d)
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
|
||||
static void draw_seq_strips(TimelineDrawContext *timeline_ctx)
|
||||
{
|
||||
if (timeline_ctx->ed == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bContext *C = timeline_ctx->C;
|
||||
Editing *ed = timeline_ctx->ed;
|
||||
ARegion *region = timeline_ctx->region;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
View2D *v2d = ®ion->v2d;
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
||||
Sequence *last_seq = SEQ_select_active_get(scene);
|
||||
int sel = 0, j;
|
||||
float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
|
||||
|
||||
/* Loop through twice, first unselected, then selected. */
|
||||
for (j = 0; j < 2; j++) {
|
||||
@@ -1594,7 +1662,8 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
|
||||
}
|
||||
|
||||
/* Strip passed all tests, draw it now. */
|
||||
draw_seq_strip(C, sseq, scene, region, seq, pixelx, seq == last_seq ? true : false);
|
||||
StripDrawContext strip_ctx = strip_draw_context_get(timeline_ctx, seq);
|
||||
draw_seq_strip(timeline_ctx, &strip_ctx);
|
||||
}
|
||||
|
||||
/* Draw selected next time round. */
|
||||
@@ -1604,7 +1673,8 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
|
||||
/* When selected draw the last selected (active) strip last,
|
||||
* removes some overlapping error. */
|
||||
if (last_seq && (last_seq->flag & SELECT)) {
|
||||
draw_seq_strip(C, sseq, scene, region, last_seq, pixelx, true);
|
||||
StripDrawContext strip_ctx = strip_draw_context_get(timeline_ctx, last_seq);
|
||||
draw_seq_strip(timeline_ctx, &strip_ctx);
|
||||
|
||||
/* When active strip is an effect, highlight its inputs. */
|
||||
if (SEQ_effect_get_num_inputs(last_seq->type) > 0) {
|
||||
@@ -1647,10 +1717,14 @@ static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
|
||||
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
UI_view2d_text_cache_draw(region);
|
||||
}
|
||||
|
||||
static void seq_draw_sfra_efra(const Scene *scene, View2D *v2d)
|
||||
static void draw_timeline_sfra_efra(TimelineDrawContext *ctx)
|
||||
{
|
||||
const Scene *scene = ctx->scene;
|
||||
const View2D *v2d = ctx->v2d;
|
||||
const Editing *ed = SEQ_editing_get(scene);
|
||||
const int frame_sta = scene->r.sfra;
|
||||
const int frame_end = scene->r.efra + 1;
|
||||
@@ -1973,78 +2047,88 @@ static void draw_overlap_frame_indicator(const Scene *scene, const View2D *v2d)
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void draw_timeline_grid(TimelineDrawContext *ctx)
|
||||
{
|
||||
if ((ctx->sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
|
||||
(ctx->sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_GRID) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
U.v2d_min_gridsize *= 3;
|
||||
UI_view2d_draw_lines_x__discrete_frames_or_seconds(
|
||||
ctx->v2d, ctx->scene, (ctx->sseq->flag & SEQ_DRAWFRAMES) == 0, false);
|
||||
U.v2d_min_gridsize /= 3;
|
||||
}
|
||||
|
||||
static void draw_timeline_backdrop(TimelineDrawContext *ctx)
|
||||
{
|
||||
if (ctx->sseq->view = !SEQ_VIEW_SEQUENCE || (ctx->sseq->draw_flag & SEQ_DRAW_BACKDROP) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int preview_frame = ctx->scene->r.cfra;
|
||||
if (sequencer_draw_get_transform_preview(ctx->sseq, ctx->scene)) {
|
||||
preview_frame = sequencer_draw_get_transform_preview_frame(ctx->scene);
|
||||
}
|
||||
|
||||
sequencer_draw_preview(
|
||||
ctx->C, ctx->scene, ctx->region, ctx->sseq, preview_frame, 0, false, true);
|
||||
UI_view2d_view_ortho(ctx->v2d);
|
||||
}
|
||||
|
||||
static void draw_timeline_markers(TimelineDrawContext *ctx)
|
||||
{
|
||||
if ((ctx->sseq->flag & SEQ_SHOW_MARKERS) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
UI_view2d_view_orthoSpecial(ctx->region, ctx->v2d, true);
|
||||
ED_markers_draw(ctx->C, DRAW_MARKERS_MARGIN);
|
||||
}
|
||||
|
||||
static void draw_timeline_gizmos(TimelineDrawContext *ctx)
|
||||
{
|
||||
if ((ctx->sseq->gizmo_flag & SEQ_GIZMO_HIDE) != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
WM_gizmomap_draw(ctx->region->gizmo_map, ctx->C, WM_GIZMOMAP_DRAWSTEP_2D);
|
||||
}
|
||||
|
||||
static void draw_timeline_pre_view_callbacks(TimelineDrawContext *ctx)
|
||||
{
|
||||
GPU_framebuffer_bind_no_srgb(ctx->framebuffer_overlay);
|
||||
GPU_depth_test(GPU_DEPTH_NONE);
|
||||
GPU_framebuffer_bind(ctx->framebuffer_overlay);
|
||||
ED_region_draw_cb_draw(ctx->C, ctx->region, REGION_DRAW_PRE_VIEW);
|
||||
GPU_framebuffer_bind_no_srgb(ctx->framebuffer_overlay);
|
||||
}
|
||||
|
||||
static void draw_timeline_post_view_callbacks(TimelineDrawContext *ctx)
|
||||
{
|
||||
GPU_framebuffer_bind(ctx->framebuffer_overlay);
|
||||
ED_region_draw_cb_draw(ctx->C, ctx->region, REGION_DRAW_POST_VIEW);
|
||||
GPU_framebuffer_bind_no_srgb(ctx->framebuffer_overlay);
|
||||
}
|
||||
|
||||
void draw_timeline_seq(const bContext *C, ARegion *region)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
||||
View2D *v2d = ®ion->v2d;
|
||||
|
||||
seq_prefetch_wm_notify(C, scene);
|
||||
|
||||
GPUViewport *viewport = WM_draw_region_get_viewport(region);
|
||||
GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
|
||||
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
|
||||
GPU_depth_test(GPU_DEPTH_NONE);
|
||||
|
||||
TimelineDrawContext ctx = timeline_draw_context_get(C);
|
||||
draw_timeline_pre_view_callbacks(&ctx);
|
||||
UI_ThemeClearColor(TH_BACK);
|
||||
draw_seq_timeline_channels(&ctx);
|
||||
draw_timeline_grid(&ctx);
|
||||
draw_timeline_backdrop(&ctx);
|
||||
draw_timeline_sfra_efra(&ctx);
|
||||
draw_seq_strips(&ctx);
|
||||
draw_timeline_markers(&ctx);
|
||||
ANIM_draw_previewrange(C, ctx.v2d, 1);
|
||||
draw_timeline_gizmos(&ctx);
|
||||
draw_timeline_post_view_callbacks(&ctx);
|
||||
ED_time_scrub_draw(region, ctx.scene, !(ctx.sseq->flag & SEQ_DRAWFRAMES), true);
|
||||
|
||||
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(
|
||||
v2d, scene, (sseq->flag & SEQ_DRAWFRAMES) == 0, false);
|
||||
U.v2d_min_gridsize /= 3;
|
||||
}
|
||||
|
||||
/* Only draw backdrop in timeline view. */
|
||||
if (sseq->view == SEQ_VIEW_SEQUENCE && sseq->draw_flag & SEQ_DRAW_BACKDROP) {
|
||||
int preview_frame = scene->r.cfra;
|
||||
if (sequencer_draw_get_transform_preview(sseq, scene)) {
|
||||
preview_frame = sequencer_draw_get_transform_preview_frame(scene);
|
||||
}
|
||||
|
||||
sequencer_draw_preview(C, scene, region, sseq, preview_frame, 0, false, true);
|
||||
UI_view2d_view_ortho(v2d);
|
||||
}
|
||||
|
||||
/* Draw attached callbacks. */
|
||||
GPU_framebuffer_bind(framebuffer_overlay);
|
||||
ED_region_draw_cb_draw(C, region, REGION_DRAW_PRE_VIEW);
|
||||
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
|
||||
|
||||
seq_draw_sfra_efra(scene, v2d);
|
||||
|
||||
if (ed) {
|
||||
draw_seq_strips(C, ed, region);
|
||||
/* Draw text added in previous function. */
|
||||
UI_view2d_text_cache_draw(region);
|
||||
}
|
||||
|
||||
UI_view2d_view_ortho(v2d);
|
||||
|
||||
UI_view2d_view_orthoSpecial(region, v2d, true);
|
||||
int marker_draw_flag = DRAW_MARKERS_MARGIN;
|
||||
if (sseq->flag & SEQ_SHOW_MARKERS) {
|
||||
ED_markers_draw(C, marker_draw_flag);
|
||||
}
|
||||
|
||||
UI_view2d_view_ortho(v2d);
|
||||
ANIM_draw_previewrange(C, v2d, 1);
|
||||
|
||||
if ((sseq->gizmo_flag & SEQ_GIZMO_HIDE) == 0) {
|
||||
WM_gizmomap_draw(region->gizmo_map, C, WM_GIZMOMAP_DRAWSTEP_2D);
|
||||
}
|
||||
|
||||
/* Draw registered callbacks. */
|
||||
GPU_framebuffer_bind(framebuffer_overlay);
|
||||
ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
|
||||
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
|
||||
|
||||
UI_view2d_view_restore(C);
|
||||
ED_time_scrub_draw(region, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
|
||||
seq_prefetch_wm_notify(C, ctx.scene);
|
||||
}
|
||||
|
||||
void draw_timeline_seq_display(const bContext *C, ARegion *region)
|
||||
|
||||
Reference in New Issue
Block a user