VSE: Improve drawing of strip title and preview

This patch includes set of smaller changes to address visual
inconsistencies and bugs:

- Strip previews are drawn under title bar
- All strip previews now disappear when there isn't enough space for
  drawing
- Like the sound strip, the color strip expands to fill the whole strip
  when there is little vertical space, "taking over" the strip title
  Color is more important visual indicator than the name of the strip
- Disabling strip title no longer disables strip handle frame previews
- All strip previews are now be affected by the "Show overlays" toggle
- Turning off strip text overlay no longer makes the color strip
  preview disappear
This commit is contained in:
ok_what
2023-08-07 21:35:45 +02:00
committed by Richard Antalik
parent 04a07d5e08
commit 5f0a8759b0
7 changed files with 191 additions and 99 deletions

View File

@@ -676,7 +676,7 @@ const bTheme U_theme_default = {
.scene = RGBA(0x808033ff),
.audio = RGBA(0x448080ff),
.effect = RGBA(0x514a73ff),
.transition = RGBA(0x8f4571ff),
.transition = RGBA(0x50458fff),
.meta = RGBA(0x5b4d91ff),
.text_strip = RGBA(0x824c8fff),
.color_strip = RGBA(0x8f8f8fff),

View File

@@ -819,6 +819,7 @@
scene_strip="#828f50"
audio_strip="#4c8f8f"
effect_strip="#4c456c"
transition_strip="#50458F"
color_strip="#8f8f8f"
meta_strip="#5b4d91"
mask_strip="#8f5656"

View File

@@ -126,6 +126,7 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
*/
{
/* Keep this block, even when empty. */
FROM_DEFAULT_V4_UCHAR(space_sequencer.transition);
}
#undef FROM_DEFAULT_V4_UCHAR

View File

@@ -196,6 +196,7 @@ enum ThemeColorID {
TH_SEQ_SCENE,
TH_SEQ_AUDIO,
TH_SEQ_EFFECT,
TH_SEQ_TRANSITION,
TH_SEQ_META,
TH_SEQ_TEXT,
TH_SEQ_PREVIEW,

View File

@@ -691,6 +691,9 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
case TH_SEQ_EFFECT:
cp = ts->effect;
break;
case TH_SEQ_TRANSITION:
cp = ts->transition;
break;
case TH_SEQ_META:
cp = ts->meta;
break;

View File

@@ -150,9 +150,15 @@ void color3ubv_from_seq(const Scene *curscene,
case SEQ_TYPE_CROSS:
case SEQ_TYPE_GAMCROSS:
case SEQ_TYPE_WIPE:
r_col[0] = 130;
r_col[1] = 130;
r_col[2] = 130;
UI_GetThemeColor3ubv(TH_SEQ_TRANSITION, r_col);
/* Slightly offset hue to distinguish different transition types. */
if (seq->type == SEQ_TYPE_GAMCROSS) {
rgb_byte_set_hue_float_offset(r_col, 0.03);
}
else if (seq->type == SEQ_TYPE_WIPE) {
rgb_byte_set_hue_float_offset(r_col, 0.06);
}
break;
/* Effects. */
@@ -642,7 +648,7 @@ static void draw_seq_handle(const Scene *scene,
uint pos,
bool seq_active,
float pixelx,
bool y_threshold)
const bool draw_strip_preview)
{
float rx1 = 0, rx2 = 0;
float x1, x2, y1, y2;
@@ -693,7 +699,7 @@ static void draw_seq_handle(const Scene *scene,
}
/* Draw numbers for start and end of the strip next to its handles. */
if (y_threshold &&
if (draw_strip_preview &&
(((seq->flag & SELECT) && (G.moving & G_TRANSFORM_SEQ)) || (seq->flag & whichsel)))
{
@@ -988,6 +994,21 @@ static void draw_sequence_extensions_overlay(
GPU_blend(GPU_BLEND_NONE);
}
static uchar mute_overlap_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. */
else if (seq->flag & SEQ_OVERLAP) {
return OVERLAP_ALPHA;
}
else {
return 255;
}
}
static void draw_color_strip_band(
const Scene *scene, ListBase *channels, Sequence *seq, uint pos, float text_margin_y, float y1)
{
@@ -997,17 +1018,7 @@ static void draw_color_strip_band(
GPU_blend(GPU_BLEND_ALPHA);
rgb_float_to_uchar(col, colvars->col);
/* Draw muted strips semi-transparent. */
if (SEQ_render_is_muted(channels, seq)) {
col[3] = MUTE_ALPHA;
}
/* Draw background semi-transparent when overlapping strips. */
else if (seq->flag & SEQ_OVERLAP) {
col[3] = OVERLAP_ALPHA;
}
else {
col[3] = 255;
}
col[3] = mute_overlap_alpha_factor_get(channels, seq);
immUniformColor4ubv(col);
@@ -1044,32 +1055,9 @@ static void draw_seq_background(Scene *scene,
uchar col[4];
GPU_blend(GPU_BLEND_ALPHA);
/* Get the correct color per strip type, transitions use their inputs ones. */
if (ELEM(seq->type, SEQ_TYPE_CROSS, SEQ_TYPE_GAMCROSS, SEQ_TYPE_WIPE)) {
Sequence *seq1 = seq->seq1;
if (seq1->type == SEQ_TYPE_COLOR) {
SolidColorVars *colvars = (SolidColorVars *)seq1->effectdata;
rgb_float_to_uchar(col, colvars->col);
}
else {
color3ubv_from_seq(scene, seq1, show_strip_color_tag, col);
}
}
else {
color3ubv_from_seq(scene, seq, show_strip_color_tag, col);
}
color3ubv_from_seq(scene, seq, show_strip_color_tag, col);
/* Draw muted strips semi-transparent. */
if (SEQ_render_is_muted(channels, seq)) {
col[3] = MUTE_ALPHA;
}
/* Draw background semi-transparent when overlapping strips. */
else if (seq->flag & SEQ_OVERLAP) {
col[3] = OVERLAP_ALPHA;
}
else {
col[3] = 255;
}
col[3] = mute_overlap_alpha_factor_get(channels, seq);
immUniformColor4ubv(col);
@@ -1102,39 +1090,95 @@ static void draw_seq_background(Scene *scene,
}
}
/* Draw right half of transition strips. */
if (ELEM(seq->type, SEQ_TYPE_CROSS, SEQ_TYPE_GAMCROSS, SEQ_TYPE_WIPE)) {
float vert_pos[3][2];
Sequence *seq1 = seq->seq1;
Sequence *seq2 = seq->seq2;
GPU_blend(GPU_BLEND_NONE);
}
if (seq2->type == SEQ_TYPE_COLOR) {
SolidColorVars *colvars = (SolidColorVars *)seq2->effectdata;
rgb_float_to_uchar(col, colvars->col);
}
else {
color3ubv_from_seq(scene, seq2, show_strip_color_tag, col);
/* If the transition inputs are of the same type, draw the right side slightly darker. */
if (seq1->type == seq2->type) {
UI_GetColorPtrShade3ubv(col, col, -15);
}
}
immUniformColor4ubv(col);
typedef enum {
STRIP_TRANSITION_IN,
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,
const TransitionType transition_type)
{
Editing *ed = SEQ_editing_get(scene);
const ListBase *channels = SEQ_channels_displayed_get(ed);
const Sequence *seq1 = transition_seq->seq1;
const Sequence *seq2 = transition_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);
float col[4];
if (target_seq->type == SEQ_TYPE_COLOR) {
SolidColorVars *colvars = (SolidColorVars *)target_seq->effectdata;
memcpy(col, colvars->col, sizeof(colvars->col));
}
else {
uchar ucol[3];
color3ubv_from_seq(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);
}
rgb_uchar_to_float(col, ucol);
}
col[3] = mute_overlap_alpha_factor_get(channels, transition_seq) / 255.0f;
GPU_blend(GPU_BLEND_ALPHA);
const uint pos = GPU_vertformat_attr_add(
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
immUniformColor4fv(col);
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);
}
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);
immBegin(GPU_PRIM_TRIS, 3);
immVertex2fv(pos, vert_pos[0]);
immVertex2fv(pos, vert_pos[1]);
immVertex2fv(pos, vert_pos[2]);
immEnd();
}
immBegin(GPU_PRIM_TRIS, 3);
immVertex2fv(pos, vert_pos[0]);
immVertex2fv(pos, vert_pos[1]);
immVertex2fv(pos, vert_pos[2]);
immEnd();
immUnbindProgram();
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)
{
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);
}
static void draw_seq_locked(float x1, float y1, float x2, float y2)
{
GPU_blend(GPU_BLEND_ALPHA);
@@ -1327,7 +1371,14 @@ static void draw_seq_strip(const bContext *C,
x2 = max_ff(x2, SEQ_time_left_handle_frame_get(scene, seq));
float text_margin_y;
bool y_threshold;
/* 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))
@@ -1336,13 +1387,16 @@ static void draw_seq_strip(const bContext *C,
/* Calculate height needed for drawing text on strip. */
text_margin_y = y2 - min_ff(0.40f, 20 * UI_SCALE_FAC * pixely);
/* Is there enough space for drawing something else than text? */
y_threshold = ((y2 - y1) / pixely) > 20 * UI_SCALE_FAC;
strip_content_single = !draw_strip_preview;
}
else {
text_margin_y = y2;
y_threshold = false;
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);
@@ -1350,8 +1404,8 @@ static void draw_seq_strip(const bContext *C,
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 (seq->type == SEQ_TYPE_COLOR && y_threshold) {
draw_color_strip_band(scene, channels, seq, pos, text_margin_y, y1);
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". */
@@ -1365,32 +1419,41 @@ static void draw_seq_strip(const bContext *C,
}
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 ((seq->type == SEQ_TYPE_META) ||
((seq->type == SEQ_TYPE_SCENE) && (seq->flag & SEQ_SCENE_STRIPS)))
{
drawmeta_contents(scene, seq, x1, y1, x2, y2, show_strip_color_tag);
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, y_threshold ? text_margin_y : y2, pixelx, pixely);
draw_seq_strip_thumbnail(v2d, C, scene, seq, y1, strip_preview_y2, pixelx, pixely);
}
if ((sseq->flag & SEQ_SHOW_OVERLAY) && (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_FCURVES))
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, y2, pixelx);
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)) {
if (seq_draw_waveforms_poll(C, sseq, seq) && !strip_content_none) {
draw_seq_waveform_overlay(
C, region, seq, x1, y_threshold ? y1 + 0.05f : y1, x2, y_threshold ? text_margin_y : y2);
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)) {
@@ -1406,34 +1469,51 @@ static void draw_seq_strip(const bContext *C,
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, y_threshold);
draw_seq_handle(
scene, v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE, pos, seq_active, pixelx, y_threshold);
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();
calculate_seq_text_offsets(scene, v2d, seq, &x1, &x2, pixelx);
/* If a waveform is drawn, avoid drawing text when there is not enough vertical space. */
if (seq->type == SEQ_TYPE_SOUND_RAM) {
if (!y_threshold && (sseq->timeline_overlay.flag & SEQ_TIMELINE_NO_WAVEFORMS) == 0 &&
((sseq->timeline_overlay.flag & SEQ_TIMELINE_ALL_WAVEFORMS) ||
(seq->flag & SEQ_AUDIO_DRAW_WAVEFORM)))
{
return;
}
/* 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) {
/* Don't draw strip if there is not enough vertical or horizontal space. */
if (((x2 - x1) > 32 * pixelx * UI_SCALE_FAC) && ((y2 - y1) > 8 * pixely * UI_SCALE_FAC)) {
/* 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, y_threshold ? text_margin_y : y1, y2, seq_active);
draw_seq_text_overlay(scene,
v2d,
seq,
sseq,
x1,
x2,
strip_content_single ? y1 : text_margin_y,
y2,
seq_active);
}
}
}

View File

@@ -3302,6 +3302,12 @@ static void rna_def_userdef_theme_space_seq(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Effect Strip", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "transition_strip", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "transition");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Transition Strip", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "color_strip", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Color Strip", "");