VSE: Timeline strip visual design updates
Design updates as per #118288: - Tweak text labels (colors, drop shadows) - Strip border colors, inset outlines - Muted strips are mostly gray, and their thumbnails are faded - Overlapping strips are not semitransparent anymore - Locked stripes only in content area - Missing data blocks - Updates to meta strips w/ missing data blocks Pull Request: https://projects.blender.org/blender/blender/pulls/118581
This commit is contained in:
committed by
Aras Pranckevicius
parent
848571ff01
commit
c64050ecd2
@@ -674,7 +674,7 @@ const bTheme U_theme_default = {
|
||||
.meta = RGBA(0x5b4d91ff),
|
||||
.text_strip = RGBA(0x824c8fff),
|
||||
.color_strip = RGBA(0x8f8f8fff),
|
||||
.active_strip = RGBA(0xd9d9d9ff),
|
||||
.active_strip = RGBA(0xffffffff),
|
||||
.selected_strip = RGBA(0xff8f0dff),
|
||||
.gp_vertex_size = 3,
|
||||
.gp_vertex_select = RGBA(0xff8500ff),
|
||||
|
||||
@@ -823,7 +823,7 @@
|
||||
meta_strip="#5b4d91"
|
||||
mask_strip="#8f5656"
|
||||
text_strip="#824c8f"
|
||||
active_strip="#d9d9d9"
|
||||
active_strip="#ffffff"
|
||||
selected_strip="#ff6a00"
|
||||
frame_current="#5680c2"
|
||||
time_scrub_background="#292929e6"
|
||||
|
||||
@@ -113,6 +113,14 @@ void UI_icon_draw_ex(float x,
|
||||
bool mono_border,
|
||||
const IconTextOverlay *text_overlay);
|
||||
|
||||
/**
|
||||
* Draw an monochrome icon into a given coordinate rectangle. The rectangle is used as-is,
|
||||
* and the icon image fills it. Icon is tinted with indicated color. If icon
|
||||
* is not found or the icon type is not monochrome, the function does nothing.
|
||||
*/
|
||||
void UI_icon_draw_mono_rect(
|
||||
float x, float y, float width, float height, int icon_id, const uchar color[4]);
|
||||
|
||||
void UI_icons_free();
|
||||
void UI_icons_free_drawinfo(void *drawinfo);
|
||||
|
||||
|
||||
@@ -1650,7 +1650,6 @@ static void icon_draw_rect(float x,
|
||||
float y,
|
||||
int w,
|
||||
int h,
|
||||
float /*aspect*/,
|
||||
int rw,
|
||||
int rh,
|
||||
const uint8_t *rect,
|
||||
@@ -2014,8 +2013,7 @@ static void icon_draw_size(float x,
|
||||
const ImBuf *ibuf = static_cast<const ImBuf *>(icon->obj);
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
|
||||
icon_draw_rect(
|
||||
x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->byte_buffer.data, alpha, desaturate);
|
||||
icon_draw_rect(x, y, w, h, ibuf->x, ibuf->y, ibuf->byte_buffer.data, alpha, desaturate);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
}
|
||||
else if (di->type == ICON_TYPE_VECTOR) {
|
||||
@@ -2055,7 +2053,7 @@ static void icon_draw_size(float x,
|
||||
}
|
||||
|
||||
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
|
||||
icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->byte_buffer.data, alpha, desaturate);
|
||||
icon_draw_rect(x, y, w, h, w, h, ibuf->byte_buffer.data, alpha, desaturate);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
}
|
||||
else if (di->type == ICON_TYPE_EVENT) {
|
||||
@@ -2125,7 +2123,7 @@ static void icon_draw_size(float x,
|
||||
return;
|
||||
}
|
||||
|
||||
icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, desaturate);
|
||||
icon_draw_rect(x, y, w, h, iimg->w, iimg->h, iimg->rect, alpha, desaturate);
|
||||
}
|
||||
else if (di->type == ICON_TYPE_PREVIEW) {
|
||||
PreviewImage *pi = (icon->id_type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) :
|
||||
@@ -2144,7 +2142,6 @@ static void icon_draw_size(float x,
|
||||
y,
|
||||
w,
|
||||
h,
|
||||
aspect,
|
||||
pi->w[size],
|
||||
pi->h[size],
|
||||
reinterpret_cast<const uint8_t *>(pi->rect[size]),
|
||||
@@ -2696,6 +2693,35 @@ void UI_icon_draw_ex(float x,
|
||||
text_overlay);
|
||||
}
|
||||
|
||||
void UI_icon_draw_mono_rect(
|
||||
float x, float y, float width, float height, int icon_id, const uchar color[4])
|
||||
{
|
||||
Icon *icon = BKE_icon_get(icon_id);
|
||||
if (icon == nullptr) {
|
||||
return;
|
||||
}
|
||||
DrawInfo *di = icon_ensure_drawinfo(icon);
|
||||
if (di->type != ICON_TYPE_MONO_TEXTURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
float fcolor[4];
|
||||
straight_uchar_to_premul_float(fcolor, color);
|
||||
|
||||
icon_draw_texture(x,
|
||||
y,
|
||||
width,
|
||||
height,
|
||||
di->data.texture.x,
|
||||
di->data.texture.y,
|
||||
di->data.texture.w,
|
||||
di->data.texture.h,
|
||||
fcolor[3],
|
||||
fcolor,
|
||||
false,
|
||||
nullptr);
|
||||
}
|
||||
|
||||
void UI_icon_text_overlay_init_from_count(IconTextOverlay *text_overlay,
|
||||
const int icon_indicator_number)
|
||||
{
|
||||
|
||||
@@ -2156,7 +2156,7 @@ void UI_view2d_text_cache_draw(ARegion *region)
|
||||
}
|
||||
|
||||
if (col_pack_prev != v2s->col.pack) {
|
||||
BLF_color3ubv(font_id, v2s->col.ub);
|
||||
BLF_color4ubv(font_id, v2s->col.ub);
|
||||
col_pack_prev = v2s->col.pack;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ struct Editing;
|
||||
struct ListBase;
|
||||
|
||||
#define DEFAULT_IMG_STRIP_LENGTH 25 /* XXX arbitrary but ok for now. */
|
||||
#define OVERLAP_ALPHA 180
|
||||
|
||||
namespace blender::ed::seq {
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "BIF_glutil.hh"
|
||||
|
||||
#include "SEQ_channels.hh"
|
||||
#include "SEQ_relations.hh"
|
||||
#include "SEQ_render.hh"
|
||||
#include "SEQ_sequencer.hh"
|
||||
@@ -464,6 +465,9 @@ void draw_seq_strip_thumbnail(View2D *v2d,
|
||||
return;
|
||||
}
|
||||
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = ed ? SEQ_channels_displayed_get(ed) : nullptr;
|
||||
|
||||
const float thumb_height = y2 - y1;
|
||||
seq_get_thumb_image_dimensions(
|
||||
seq, pixelx, pixely, &thumb_width, thumb_height, &image_width, &image_height);
|
||||
@@ -479,7 +483,6 @@ void draw_seq_strip_thumbnail(View2D *v2d,
|
||||
}
|
||||
|
||||
float timeline_frame = SEQ_render_thumbnail_first_frame_get(scene, seq, thumb_width, &v2d->cur);
|
||||
float thumb_x_end;
|
||||
|
||||
GSet *last_displayed_thumbnails = last_displayed_thumbnails_list_ensure(C, seq);
|
||||
/* Cleanup thumbnail list outside of rendered range, which is cleaned up one by one to prevent
|
||||
@@ -490,7 +493,7 @@ void draw_seq_strip_thumbnail(View2D *v2d,
|
||||
|
||||
/* Start drawing. */
|
||||
while (timeline_frame < upper_thumb_bound) {
|
||||
thumb_x_end = timeline_frame + thumb_width;
|
||||
float thumb_x_end = timeline_frame + thumb_width;
|
||||
clipped = false;
|
||||
|
||||
/* Checks to make sure that thumbs are loaded only when in view and within the confines of the
|
||||
@@ -510,20 +513,17 @@ void draw_seq_strip_thumbnail(View2D *v2d,
|
||||
if (thumb_x_end > (upper_thumb_bound)) {
|
||||
thumb_x_end = upper_thumb_bound;
|
||||
clipped = true;
|
||||
if (thumb_x_end - timeline_frame < 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float zoom_x = thumb_width / image_width;
|
||||
float zoom_y = thumb_height / image_height;
|
||||
|
||||
float cropx_min = (cut_off / pixelx) / (zoom_y / pixely);
|
||||
float cropx_max = ((thumb_x_end - timeline_frame) / pixelx) / (zoom_y / pixely);
|
||||
if (cropx_max == (thumb_x_end - timeline_frame)) {
|
||||
cropx_max = cropx_max + 1;
|
||||
int cropx_min = int((cut_off / pixelx) / (zoom_y / pixely));
|
||||
int cropx_max = int(((thumb_x_end - timeline_frame) / pixelx) / (zoom_y / pixely));
|
||||
if (cropx_max < 1) {
|
||||
break;
|
||||
}
|
||||
BLI_rcti_init(&crop, int(cropx_min), int(cropx_max), 0, int(image_height) - 1);
|
||||
BLI_rcti_init(&crop, cropx_min, cropx_max - 1, 0, int(image_height) - 1);
|
||||
|
||||
/* Get the image. */
|
||||
ImBuf *ibuf = SEQ_get_thumbnail(&context, seq, timeline_frame, &crop, clipped);
|
||||
@@ -548,19 +548,21 @@ void draw_seq_strip_thumbnail(View2D *v2d,
|
||||
break;
|
||||
}
|
||||
|
||||
/* Transparency on overlap. */
|
||||
if (seq->flag & SEQ_OVERLAP) {
|
||||
/* Transparency on mute. */
|
||||
bool muted = channels ? SEQ_render_is_muted(channels, seq) : false;
|
||||
if (muted) {
|
||||
const uchar alpha = 120;
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
if (ibuf->byte_buffer.data) {
|
||||
uchar *buf = ibuf->byte_buffer.data;
|
||||
for (int pixel = ibuf->x * ibuf->y; pixel--; buf += 4) {
|
||||
buf[3] = OVERLAP_ALPHA;
|
||||
buf[3] = alpha;
|
||||
}
|
||||
}
|
||||
else if (ibuf->float_buffer.data) {
|
||||
float *buf = ibuf->float_buffer.data;
|
||||
for (int pixel = ibuf->x * ibuf->y; pixel--; buf += ibuf->channels) {
|
||||
buf[3] = (OVERLAP_ALPHA / 255.0f);
|
||||
buf[3] = (alpha / 255.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
@@ -48,6 +49,7 @@
|
||||
#include "SEQ_transform.hh"
|
||||
#include "SEQ_utils.hh"
|
||||
|
||||
#include "UI_interface_icons.hh"
|
||||
#include "UI_resources.hh"
|
||||
#include "UI_view2d.hh"
|
||||
|
||||
@@ -67,6 +69,8 @@
|
||||
#define SEQ_HANDLE_SIZE 8.0f
|
||||
#define MUTE_ALPHA 120
|
||||
|
||||
constexpr float MISSING_ICON_SIZE = 16.0f;
|
||||
|
||||
struct StripDrawContext {
|
||||
Sequence *seq;
|
||||
/* Strip boundary in timeline space. Content start/end is clamped by left/right handle. */
|
||||
@@ -82,6 +86,7 @@ struct StripDrawContext {
|
||||
bool is_active_strip;
|
||||
bool is_single_image; /* Strip has single frame of content. */
|
||||
bool show_strip_color_tag;
|
||||
bool missing_data_block;
|
||||
};
|
||||
|
||||
struct TimelineDrawContext {
|
||||
@@ -177,6 +182,25 @@ static void strip_draw_context_set_strip_content_visibility(TimelineDrawContext
|
||||
threshold;
|
||||
}
|
||||
|
||||
static bool meta_strip_has_missing_data(const Sequence *seq)
|
||||
{
|
||||
if (seq->type != SEQ_TYPE_META) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const ListBase *seqbase = &seq->seqbase;
|
||||
if (!seqbase || BLI_listbase_is_empty(seqbase)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (const Sequence *, sub, seqbase) {
|
||||
if (!SEQ_sequence_has_source(sub)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static StripDrawContext strip_draw_context_get(TimelineDrawContext *ctx, Sequence *seq)
|
||||
{
|
||||
StripDrawContext strip_ctx;
|
||||
@@ -211,6 +235,7 @@ static StripDrawContext strip_draw_context_get(TimelineDrawContext *ctx, Sequenc
|
||||
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);
|
||||
strip_ctx.missing_data_block = !SEQ_sequence_has_source(seq) || meta_strip_has_missing_data(seq);
|
||||
|
||||
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);
|
||||
@@ -570,14 +595,14 @@ static void drawmeta_contents(TimelineDrawContext *timeline_ctx, const StripDraw
|
||||
return;
|
||||
}
|
||||
|
||||
Scene *scene = timeline_ctx->scene;
|
||||
const Scene *scene = timeline_ctx->scene;
|
||||
|
||||
uchar col[4];
|
||||
|
||||
int chan_min = MAXSEQ;
|
||||
int chan_max = 0;
|
||||
int chan_range = 0;
|
||||
float draw_range = strip_ctx->top - strip_ctx->bottom;
|
||||
float draw_range = strip_ctx->strip_content_top - strip_ctx->bottom;
|
||||
float draw_height;
|
||||
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
@@ -635,6 +660,12 @@ static void drawmeta_contents(TimelineDrawContext *timeline_ctx, const StripDraw
|
||||
col[3] = 196;
|
||||
}
|
||||
|
||||
if (!SEQ_sequence_has_source(seq)) {
|
||||
col[0] = 112;
|
||||
col[1] = 0;
|
||||
col[2] = 0;
|
||||
}
|
||||
|
||||
/* Clamp within parent sequence strip bounds. */
|
||||
if (x1_chan < strip_ctx->left_handle) {
|
||||
x1_chan = strip_ctx->left_handle;
|
||||
@@ -667,7 +698,7 @@ static void draw_seq_handle(TimelineDrawContext *timeline_ctx,
|
||||
const StripDrawContext *strip_ctx,
|
||||
const short direction)
|
||||
{
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
const Sequence *seq = strip_ctx->seq;
|
||||
if (SEQ_transform_is_locked(timeline_ctx->channels, seq)) {
|
||||
return;
|
||||
}
|
||||
@@ -745,17 +776,16 @@ static void draw_seq_handle(TimelineDrawContext *timeline_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
/* Strip border, and outline for selected/active strips. */
|
||||
static void draw_seq_outline(TimelineDrawContext *timeline_ctx, const StripDrawContext *strip_ctx)
|
||||
{
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
const Sequence *seq = strip_ctx->seq;
|
||||
const bool selected = seq->flag & SELECT;
|
||||
|
||||
/* Get the color for the outline. */
|
||||
/* Outline color. */
|
||||
uchar col[4];
|
||||
if (strip_ctx->is_active_strip && (seq->flag & SELECT)) {
|
||||
UI_GetThemeColor3ubv(TH_SEQ_ACTIVE, col);
|
||||
}
|
||||
else if (seq->flag & SELECT) {
|
||||
UI_GetThemeColor3ubv(TH_SEQ_SELECTED, col);
|
||||
if (selected) {
|
||||
UI_GetThemeColor3ubv(strip_ctx->is_active_strip ? TH_SEQ_ACTIVE : TH_SEQ_SELECTED, col);
|
||||
}
|
||||
else {
|
||||
/* Color for unselected strips is a bit darker than the background. */
|
||||
@@ -765,12 +795,9 @@ static void draw_seq_outline(TimelineDrawContext *timeline_ctx, const StripDrawC
|
||||
|
||||
/* Outline while translating strips:
|
||||
* - Slightly lighter.
|
||||
* - Red when overlapping with other strips.
|
||||
*/
|
||||
* - Red when overlapping with other strips. */
|
||||
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 ((G.moving & G_TRANSFORM_SEQ) && selected && overlap_mode != SEQ_OVERLAP_OVERWRITE) {
|
||||
if (seq->flag & SEQ_OVERLAP) {
|
||||
col[0] = 255;
|
||||
col[1] = col[2] = 33;
|
||||
@@ -780,44 +807,35 @@ static void draw_seq_outline(TimelineDrawContext *timeline_ctx, const StripDrawC
|
||||
}
|
||||
}
|
||||
|
||||
/* 2px wide outline for selected strips: draw as four quads. */
|
||||
if (seq->flag & SELECT) {
|
||||
float delta_x = timeline_ctx->pixelx;
|
||||
float delta_y = timeline_ctx->pixely * 2;
|
||||
/* Selected outline: 2px wide outline, plus 1px wide background inset. */
|
||||
const float x0 = strip_ctx->left_handle;
|
||||
const float x1 = strip_ctx->right_handle;
|
||||
const float y0 = strip_ctx->bottom;
|
||||
const float y1 = strip_ctx->top;
|
||||
if (selected) {
|
||||
const float dx = timeline_ctx->pixelx;
|
||||
const float dy = timeline_ctx->pixely;
|
||||
|
||||
/* Left */
|
||||
timeline_ctx->quads->add_quad(strip_ctx->left_handle - delta_x,
|
||||
strip_ctx->bottom,
|
||||
strip_ctx->left_handle + delta_x,
|
||||
strip_ctx->top,
|
||||
col);
|
||||
/* Bottom */
|
||||
timeline_ctx->quads->add_quad(strip_ctx->left_handle - delta_x,
|
||||
strip_ctx->bottom,
|
||||
strip_ctx->right_handle + delta_x,
|
||||
strip_ctx->bottom + delta_y,
|
||||
col);
|
||||
/* Right */
|
||||
timeline_ctx->quads->add_quad(strip_ctx->right_handle - delta_x,
|
||||
strip_ctx->bottom,
|
||||
strip_ctx->right_handle + delta_x,
|
||||
strip_ctx->top,
|
||||
col);
|
||||
/* Top */
|
||||
timeline_ctx->quads->add_quad(strip_ctx->left_handle - delta_x,
|
||||
strip_ctx->top - delta_y,
|
||||
strip_ctx->right_handle + delta_x,
|
||||
strip_ctx->top,
|
||||
col);
|
||||
/* Left, right, bottom, top. */
|
||||
timeline_ctx->quads->add_quad(x0 - dx, y0, x0 + dx, y1, col);
|
||||
timeline_ctx->quads->add_quad(x1 - dx, y0, x1 + dx, y1, col);
|
||||
timeline_ctx->quads->add_quad(x0, y0, x1, y0 + dy * 2, col);
|
||||
timeline_ctx->quads->add_quad(x0, y1 - dy * 2, x1, y1, col);
|
||||
|
||||
/* Inset. */
|
||||
UI_GetThemeColor3ubv(TH_BACK, col);
|
||||
timeline_ctx->quads->add_quad(x0 + dx, y0 + dy * 2, x0 + dx * 2, y1 - dy * 2, col);
|
||||
timeline_ctx->quads->add_quad(x1 - dx * 2, y0 + dy * 2, x1 - dx, y1 - dy * 2, col);
|
||||
timeline_ctx->quads->add_quad(x0 + dx, y0 + dy * 2, x1 - dx, y0 + dy * 3, col);
|
||||
timeline_ctx->quads->add_quad(x0 + dx, y1 - dy * 3, x1 - dx, y1 - dy * 2, col);
|
||||
}
|
||||
else {
|
||||
/* 1px wide outline for unselected strips. */
|
||||
timeline_ctx->quads->add_wire_quad(
|
||||
strip_ctx->left_handle, strip_ctx->bottom, strip_ctx->right_handle, strip_ctx->top, col);
|
||||
/* Thin wireframe outline for unselected strips. */
|
||||
timeline_ctx->quads->add_wire_quad(x0, y0, x1, y1, col);
|
||||
}
|
||||
}
|
||||
|
||||
static const char *draw_seq_text_get_name(Sequence *seq)
|
||||
static const char *draw_seq_text_get_name(const Sequence *seq)
|
||||
{
|
||||
const char *name = seq->name + 2;
|
||||
if (name[0] == '\0') {
|
||||
@@ -826,7 +844,7 @@ static const char *draw_seq_text_get_name(Sequence *seq)
|
||||
return name;
|
||||
}
|
||||
|
||||
static void draw_seq_text_get_source(Sequence *seq, char *r_source, size_t source_maxncpy)
|
||||
static void draw_seq_text_get_source(const Sequence *seq, char *r_source, size_t source_maxncpy)
|
||||
{
|
||||
*r_source = '\0';
|
||||
|
||||
@@ -888,7 +906,7 @@ static size_t draw_seq_text_get_overlay_string(TimelineDrawContext *timeline_ctx
|
||||
char *r_overlay_string,
|
||||
size_t overlay_string_len)
|
||||
{
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
const Sequence *seq = strip_ctx->seq;
|
||||
|
||||
const char *text_sep = " | ";
|
||||
const char *text_array[5];
|
||||
@@ -923,6 +941,95 @@ static size_t draw_seq_text_get_overlay_string(TimelineDrawContext *timeline_ctx
|
||||
return BLI_string_join_array(r_overlay_string, overlay_string_len, text_array, i);
|
||||
}
|
||||
|
||||
static void get_strip_text_color(const TimelineDrawContext *ctx,
|
||||
const StripDrawContext *strip,
|
||||
uchar r_col[4])
|
||||
{
|
||||
/* Text: 75% opacity, fully opaque when selected/active. */
|
||||
const Sequence *seq = strip->seq;
|
||||
const bool active_or_selected = (seq->flag & SELECT) || strip->is_active_strip;
|
||||
if (active_or_selected) {
|
||||
UI_GetThemeColor3ubv(TH_SEQ_ACTIVE, r_col);
|
||||
r_col[3] = 255;
|
||||
}
|
||||
else {
|
||||
r_col[0] = r_col[1] = r_col[2] = 224;
|
||||
r_col[3] = 192;
|
||||
}
|
||||
|
||||
/* Muted strips: gray color, reduce opacity. */
|
||||
if (SEQ_render_is_muted(ctx->channels, seq)) {
|
||||
r_col[0] = r_col[1] = r_col[2] = 192;
|
||||
r_col[3] *= 0.66f;
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_icon_centered(TimelineDrawContext &ctx,
|
||||
const rctf &rect,
|
||||
int icon_id,
|
||||
const uchar color[4])
|
||||
{
|
||||
const float icon_size_x = MISSING_ICON_SIZE * ctx.pixelx * UI_SCALE_FAC;
|
||||
const float icon_size_y = MISSING_ICON_SIZE * ctx.pixely * UI_SCALE_FAC;
|
||||
if (BLI_rctf_size_x(&rect) * 1.1f < icon_size_x || BLI_rctf_size_y(&rect) * 1.1f < icon_size_y) {
|
||||
return;
|
||||
}
|
||||
|
||||
UI_icon_draw_mono_rect(BLI_rctf_cent_x(&rect) - icon_size_x * 0.5f,
|
||||
BLI_rctf_cent_y(&rect) - icon_size_y * 0.5f,
|
||||
icon_size_x,
|
||||
icon_size_y,
|
||||
icon_id,
|
||||
color);
|
||||
}
|
||||
|
||||
static void draw_strip_icons(TimelineDrawContext *timeline_ctx,
|
||||
const blender::Vector<StripDrawContext> &strips)
|
||||
{
|
||||
timeline_ctx->quads->draw();
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
|
||||
UI_icon_draw_cache_begin();
|
||||
|
||||
const float icon_size_x = MISSING_ICON_SIZE * timeline_ctx->pixelx * UI_SCALE_FAC;
|
||||
|
||||
for (const StripDrawContext &strip : strips) {
|
||||
if (!strip.missing_data_block) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Draw icon in the title bar area. */
|
||||
if ((timeline_ctx->sseq->flag & SEQ_SHOW_OVERLAY) != 0 && !strip.strip_is_too_small &&
|
||||
strip.can_draw_text_overlay)
|
||||
{
|
||||
uchar col[4];
|
||||
get_strip_text_color(timeline_ctx, &strip, col);
|
||||
|
||||
float icon_indent = 2.0f * strip.handle_width - 4 * timeline_ctx->pixelx * UI_SCALE_FAC;
|
||||
rctf rect;
|
||||
rect.xmin = max_ff(strip.left_handle, timeline_ctx->v2d->cur.xmin) + icon_indent;
|
||||
rect.xmax = min_ff(strip.right_handle - strip.handle_width, rect.xmin + icon_size_x);
|
||||
rect.ymin = strip.strip_content_top;
|
||||
rect.ymax = strip.top;
|
||||
draw_icon_centered(*timeline_ctx, rect, ICON_LIBRARY_DATA_BROKEN, col);
|
||||
}
|
||||
|
||||
/* Draw icon in center of content. */
|
||||
if (strip.can_draw_strip_content && strip.seq->type != SEQ_TYPE_META) {
|
||||
rctf rect;
|
||||
rect.xmin = strip.left_handle + strip.handle_width;
|
||||
rect.xmax = strip.right_handle - strip.handle_width;
|
||||
rect.ymin = strip.bottom;
|
||||
rect.ymax = strip.strip_content_top;
|
||||
uchar col[4] = {112, 0, 0, 255};
|
||||
draw_icon_centered(*timeline_ctx, rect, ICON_LIBRARY_DATA_BROKEN, col);
|
||||
}
|
||||
}
|
||||
|
||||
UI_icon_draw_cache_end();
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
/* Draw info text on a sequence strip. */
|
||||
static void draw_seq_text_overlay(TimelineDrawContext *timeline_ctx,
|
||||
const StripDrawContext *strip_ctx)
|
||||
@@ -945,30 +1052,23 @@ static void draw_seq_text_overlay(TimelineDrawContext *timeline_ctx,
|
||||
return;
|
||||
}
|
||||
|
||||
/* White text for the active strip. */
|
||||
uchar col[4];
|
||||
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(timeline_ctx->channels, strip_ctx->seq)) {
|
||||
if (strip_ctx->is_active_strip) {
|
||||
UI_GetColorPtrShade3ubv(col, col, -70);
|
||||
}
|
||||
else {
|
||||
UI_GetColorPtrShade3ubv(col, col, 15);
|
||||
}
|
||||
}
|
||||
get_strip_text_color(timeline_ctx, strip_ctx, col);
|
||||
|
||||
float text_margin = 2.0f * strip_ctx->handle_width;
|
||||
rctf rect;
|
||||
rect.xmin = strip_ctx->left_handle + 2.0f * strip_ctx->handle_width;
|
||||
rect.xmax = strip_ctx->right_handle - 2.0f * strip_ctx->handle_width;
|
||||
rect.xmin = strip_ctx->left_handle + text_margin;
|
||||
rect.xmax = strip_ctx->right_handle - text_margin;
|
||||
rect.ymax = strip_ctx->top;
|
||||
/* Depending on the vertical space, draw text on top or in the center of strip. */
|
||||
rect.ymin = !strip_ctx->can_draw_strip_content ? strip_ctx->bottom :
|
||||
strip_ctx->strip_content_top;
|
||||
CLAMP(rect.xmin, timeline_ctx->v2d->cur.xmin + text_margin, timeline_ctx->v2d->cur.xmax);
|
||||
rect.xmin = max_ff(rect.xmin, timeline_ctx->v2d->cur.xmin + text_margin);
|
||||
if (strip_ctx->missing_data_block) {
|
||||
rect.xmin += MISSING_ICON_SIZE * timeline_ctx->pixelx * UI_SCALE_FAC;
|
||||
}
|
||||
rect.xmin = min_ff(rect.xmin, timeline_ctx->v2d->cur.xmax);
|
||||
|
||||
CLAMP(rect.xmax, timeline_ctx->v2d->cur.xmin + text_margin, timeline_ctx->v2d->cur.xmax);
|
||||
|
||||
UI_view2d_text_cache_add_rectf(
|
||||
@@ -978,7 +1078,7 @@ static void draw_seq_text_overlay(TimelineDrawContext *timeline_ctx,
|
||||
static void draw_strip_offsets(TimelineDrawContext *timeline_ctx,
|
||||
const StripDrawContext *strip_ctx)
|
||||
{
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
const Sequence *seq = strip_ctx->seq;
|
||||
if ((timeline_ctx->sseq->flag & SEQ_SHOW_OVERLAY) == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -991,8 +1091,8 @@ static void draw_strip_offsets(TimelineDrawContext *timeline_ctx,
|
||||
return;
|
||||
}
|
||||
|
||||
Scene *scene = timeline_ctx->scene;
|
||||
ListBase *channels = timeline_ctx->channels;
|
||||
const Scene *scene = timeline_ctx->scene;
|
||||
const ListBase *channels = timeline_ctx->channels;
|
||||
|
||||
uchar col[4], blend_col[4];
|
||||
color3ubv_from_seq(scene, seq, strip_ctx->show_strip_color_tag, col);
|
||||
@@ -1032,23 +1132,19 @@ static void draw_strip_offsets(TimelineDrawContext *timeline_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
static uchar mute_overlap_alpha_factor_get(const ListBase *channels, const Sequence *seq)
|
||||
static uchar mute_alpha_factor_get(const ListBase *channels, const Sequence *seq)
|
||||
{
|
||||
/* Draw muted strips semi-transparent. */
|
||||
if (SEQ_render_is_muted(channels, seq)) {
|
||||
return MUTE_ALPHA;
|
||||
}
|
||||
/* Draw background semi-transparent when overlapping strips. */
|
||||
if (seq->flag & SEQ_OVERLAP) {
|
||||
return OVERLAP_ALPHA;
|
||||
}
|
||||
return 255;
|
||||
}
|
||||
|
||||
static void draw_strip_color_band(TimelineDrawContext *timeline_ctx,
|
||||
const StripDrawContext *strip_ctx)
|
||||
{
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
const Sequence *seq = strip_ctx->seq;
|
||||
if ((timeline_ctx->sseq->flag & SEQ_SHOW_OVERLAY) == 0 || (seq->type != SEQ_TYPE_COLOR)) {
|
||||
return;
|
||||
}
|
||||
@@ -1056,7 +1152,7 @@ static void draw_strip_color_band(TimelineDrawContext *timeline_ctx,
|
||||
SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
|
||||
uchar col[4];
|
||||
rgb_float_to_uchar(col, colvars->col);
|
||||
col[3] = mute_overlap_alpha_factor_get(timeline_ctx->channels, seq);
|
||||
col[3] = mute_alpha_factor_get(timeline_ctx->channels, seq);
|
||||
|
||||
timeline_ctx->quads->add_quad(strip_ctx->left_handle,
|
||||
strip_ctx->bottom,
|
||||
@@ -1076,12 +1172,17 @@ static void draw_strip_color_band(TimelineDrawContext *timeline_ctx,
|
||||
static void draw_strip_background(TimelineDrawContext *timeline_ctx,
|
||||
const StripDrawContext *strip_ctx)
|
||||
{
|
||||
Scene *scene = timeline_ctx->scene;
|
||||
Sequence *seq = strip_ctx->seq;
|
||||
const Scene *scene = timeline_ctx->scene;
|
||||
const Sequence *seq = strip_ctx->seq;
|
||||
|
||||
uchar col[4];
|
||||
color3ubv_from_seq(scene, seq, strip_ctx->show_strip_color_tag, col);
|
||||
col[3] = mute_overlap_alpha_factor_get(timeline_ctx->channels, seq);
|
||||
col[3] = mute_alpha_factor_get(timeline_ctx->channels, seq);
|
||||
/* Muted strips: turn almost gray. */
|
||||
if (col[3] == MUTE_ALPHA) {
|
||||
uchar muted_color[3] = {128, 128, 128};
|
||||
UI_GetColorPtrBlendShade3ubv(col, muted_color, col, 0.8f, 0);
|
||||
}
|
||||
|
||||
/* Draw the main strip body. */
|
||||
float x1 = strip_ctx->is_single_image ? strip_ctx->left_handle : strip_ctx->content_start;
|
||||
@@ -1132,7 +1233,7 @@ static void draw_seq_transition_strip_half(TimelineDrawContext *timeline_ctx,
|
||||
}
|
||||
}
|
||||
|
||||
col[3] = mute_overlap_alpha_factor_get(timeline_ctx->channels, strip_ctx->seq);
|
||||
col[3] = mute_alpha_factor_get(timeline_ctx->channels, strip_ctx->seq);
|
||||
|
||||
float tri[3][2];
|
||||
|
||||
@@ -1179,12 +1280,12 @@ static void draw_seq_locked(TimelineDrawContext *timeline_ctx,
|
||||
immUniform1i("size1", 8);
|
||||
immUniform1i("size2", 4);
|
||||
|
||||
for (const StripDrawContext &strip_ctx : strips) {
|
||||
if (!SEQ_transform_is_locked(timeline_ctx->channels, strip_ctx.seq)) {
|
||||
for (const StripDrawContext &strip : strips) {
|
||||
if (!SEQ_transform_is_locked(timeline_ctx->channels, strip.seq)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
immRectf(pos, strip_ctx.left_handle, strip_ctx.bottom, strip_ctx.right_handle, strip_ctx.top);
|
||||
immRectf(pos, strip.left_handle, strip.bottom, strip.right_handle, strip.strip_content_top);
|
||||
}
|
||||
|
||||
immUnbindProgram();
|
||||
@@ -1194,15 +1295,27 @@ static void draw_seq_locked(TimelineDrawContext *timeline_ctx,
|
||||
|
||||
static void draw_seq_invalid(TimelineDrawContext *timeline_ctx, const StripDrawContext *strip_ctx)
|
||||
{
|
||||
if (SEQ_sequence_has_source(strip_ctx->seq)) {
|
||||
if (!strip_ctx->missing_data_block) {
|
||||
return;
|
||||
}
|
||||
uchar color[4] = {255, 0, 0, 230};
|
||||
timeline_ctx->quads->add_quad(strip_ctx->left_handle,
|
||||
strip_ctx->top,
|
||||
strip_ctx->right_handle,
|
||||
strip_ctx->strip_content_top,
|
||||
color);
|
||||
/* Do not tint title area for muted strips; we want to see gray for them. */
|
||||
if (!SEQ_render_is_muted(timeline_ctx->channels, strip_ctx->seq)) {
|
||||
uchar col_top[4] = {112, 0, 0, 230};
|
||||
timeline_ctx->quads->add_quad(strip_ctx->left_handle,
|
||||
strip_ctx->top,
|
||||
strip_ctx->right_handle,
|
||||
strip_ctx->strip_content_top,
|
||||
col_top);
|
||||
}
|
||||
/* Do not tint content area for meta strips; we want to display children. */
|
||||
if (strip_ctx->seq->type != SEQ_TYPE_META) {
|
||||
uchar col_main[4] = {64, 0, 0, 230};
|
||||
timeline_ctx->quads->add_quad(strip_ctx->left_handle,
|
||||
strip_ctx->strip_content_top,
|
||||
strip_ctx->right_handle,
|
||||
strip_ctx->bottom,
|
||||
col_main);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1422,6 +1535,8 @@ static void draw_seq_strips(TimelineDrawContext *timeline_ctx,
|
||||
return;
|
||||
}
|
||||
|
||||
UI_view2d_view_ortho(timeline_ctx->v2d);
|
||||
|
||||
/* Draw parts of strips below thumbnails. */
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
for (const StripDrawContext &strip_ctx : strips) {
|
||||
@@ -1451,6 +1566,7 @@ static void draw_seq_strips(TimelineDrawContext *timeline_ctx,
|
||||
for (const StripDrawContext &strip_ctx : strips) {
|
||||
draw_seq_fcurve_overlay(timeline_ctx, &strip_ctx);
|
||||
draw_seq_waveform_overlay(timeline_ctx, &strip_ctx);
|
||||
draw_seq_invalid(timeline_ctx, &strip_ctx);
|
||||
}
|
||||
timeline_ctx->quads->draw();
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
@@ -1461,15 +1577,27 @@ static void draw_seq_strips(TimelineDrawContext *timeline_ctx,
|
||||
/* Draw the rest. */
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
for (const StripDrawContext &strip_ctx : strips) {
|
||||
draw_seq_invalid(timeline_ctx, &strip_ctx);
|
||||
draw_effect_inputs_highlight(timeline_ctx, &strip_ctx);
|
||||
draw_multicam_highlight(timeline_ctx, &strip_ctx);
|
||||
draw_seq_solo_highlight(timeline_ctx, &strip_ctx);
|
||||
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);
|
||||
}
|
||||
|
||||
/* Draw icons separately (different shader). */
|
||||
draw_strip_icons(timeline_ctx, strips);
|
||||
|
||||
timeline_ctx->quads->draw();
|
||||
|
||||
/* Draw text labels with a drop shadow. */
|
||||
const int font_id = BLF_default();
|
||||
BLF_enable(font_id, BLF_SHADOW);
|
||||
BLF_shadow(font_id, 3, blender::float4{0.0f, 0.0f, 0.0f, 1.0f});
|
||||
BLF_shadow_offset(font_id, 1, -1);
|
||||
UI_view2d_text_cache_draw(timeline_ctx->region);
|
||||
BLF_disable(font_id, BLF_SHADOW);
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
@@ -1483,18 +1611,6 @@ static void draw_seq_strips(TimelineDrawContext *timeline_ctx)
|
||||
visible_strips_ordered_get(timeline_ctx, unselected, selected);
|
||||
draw_seq_strips(timeline_ctx, unselected);
|
||||
draw_seq_strips(timeline_ctx, selected);
|
||||
|
||||
/* Draw text overlay parts in the opposite order: first selected set, then
|
||||
* unselected (UI_view2d_text_cache_add_rectf adds new text in front of
|
||||
* other entries!). This is to make sure selected strip labels are on top
|
||||
* of others while they are being dragged over. */
|
||||
for (const StripDrawContext &strip_ctx : selected) {
|
||||
draw_seq_text_overlay(timeline_ctx, &strip_ctx);
|
||||
}
|
||||
for (const StripDrawContext &strip_ctx : unselected) {
|
||||
draw_seq_text_overlay(timeline_ctx, &strip_ctx);
|
||||
}
|
||||
UI_view2d_text_cache_draw(timeline_ctx->region);
|
||||
}
|
||||
|
||||
static void draw_timeline_sfra_efra(TimelineDrawContext *ctx)
|
||||
@@ -1570,7 +1686,7 @@ static void draw_timeline_sfra_efra(TimelineDrawContext *ctx)
|
||||
}
|
||||
|
||||
struct CacheDrawData {
|
||||
View2D *v2d;
|
||||
const View2D *v2d;
|
||||
float stripe_ofs_y;
|
||||
float stripe_ht;
|
||||
int cache_flag;
|
||||
@@ -1651,8 +1767,8 @@ static void draw_cache_stripe(const Scene *scene,
|
||||
static void draw_cache_background(const bContext *C, CacheDrawData *draw_data)
|
||||
{
|
||||
using blender::uchar4;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
View2D *v2d = UI_view2d_fromcontext(C);
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
const View2D *v2d = UI_view2d_fromcontext(C);
|
||||
|
||||
const uchar4 bg_final{255, 102, 51, 25};
|
||||
const uchar4 bg_raw{255, 25, 5, 25};
|
||||
@@ -1694,7 +1810,7 @@ static void draw_cache_background(const bContext *C, CacheDrawData *draw_data)
|
||||
static void draw_cache_view(const bContext *C)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
View2D *v2d = UI_view2d_fromcontext(C);
|
||||
const View2D *v2d = UI_view2d_fromcontext(C);
|
||||
|
||||
if ((scene->ed->cache_flag & SEQ_CACHE_VIEW_ENABLE) == 0) {
|
||||
return;
|
||||
|
||||
@@ -71,7 +71,7 @@ void SEQ_transform_offset_after_frame(Scene *scene,
|
||||
* Check if `seq` can be moved.
|
||||
* This function also checks `SeqTimelineChannel` flag.
|
||||
*/
|
||||
bool SEQ_transform_is_locked(ListBase *channels, Sequence *seq);
|
||||
bool SEQ_transform_is_locked(ListBase *channels, const Sequence *seq);
|
||||
|
||||
/* Image transformation. */
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ struct Sequence;
|
||||
struct StripElem;
|
||||
|
||||
void SEQ_sequence_base_unique_name_recursive(Scene *scene, ListBase *seqbasep, Sequence *seq);
|
||||
const char *SEQ_sequence_give_name(Sequence *seq);
|
||||
const char *SEQ_sequence_give_name(const Sequence *seq);
|
||||
ListBase *SEQ_get_seqbase_from_sequence(Sequence *seq, ListBase **channels, int *r_offset);
|
||||
const Sequence *SEQ_get_topmost_sequence(const Scene *scene, int frame);
|
||||
/**
|
||||
|
||||
@@ -599,7 +599,7 @@ void SEQ_transform_offset_after_frame(Scene *scene,
|
||||
}
|
||||
}
|
||||
|
||||
bool SEQ_transform_is_locked(ListBase *channels, Sequence *seq)
|
||||
bool SEQ_transform_is_locked(ListBase *channels, const Sequence *seq)
|
||||
{
|
||||
const SeqTimelineChannel *channel = SEQ_channel_get_by_index(channels, seq->machine);
|
||||
return seq->flag & SEQ_LOCK ||
|
||||
|
||||
@@ -161,7 +161,7 @@ static const char *give_seqname_by_type(int type)
|
||||
}
|
||||
}
|
||||
|
||||
const char *SEQ_sequence_give_name(Sequence *seq)
|
||||
const char *SEQ_sequence_give_name(const Sequence *seq)
|
||||
{
|
||||
const char *name = give_seqname_by_type(seq->type);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user