This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/editors/space_clip/clip_dopesheet_draw.c
Harley Acheson cd1631b17d BLF: Refactor of DPI
Correction of U.dpi to hold actual monitor DPI. Simplify font sizing by
omitting DPI as API argument, always using 72 internally.

See D15961 for more details.

Differential Revision: https://developer.blender.org/D15961

Reviewed by Campbell Barton
2022-09-23 17:36:49 -07:00

419 lines
13 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2012 Blender Foundation. All rights reserved. */
/** \file
* \ingroup spclip
*/
#include "DNA_movieclip_types.h"
#include "DNA_scene_types.h"
#include "BLI_math.h"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
#include "BKE_movieclip.h"
#include "ED_clip.h"
#include "ED_screen.h"
#include "WM_types.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "UI_view2d.h"
#include "BLF_api.h"
#include "RNA_access.h"
#include "RNA_prototypes.h"
#include "GPU_immediate.h"
#include "GPU_state.h"
#include "clip_intern.h" /* own include */
static void track_channel_color(MovieTrackingTrack *track,
const float default_color[3],
float color[3])
{
if (track->flag & TRACK_CUSTOMCOLOR) {
float bg[3];
UI_GetThemeColor3fv(TH_HEADER, bg);
interp_v3_v3v3(color, track->color, bg, 0.5);
}
else {
if (default_color) {
copy_v3_v3(color, default_color);
}
else {
UI_GetThemeColor3fv(TH_HEADER, color);
}
}
}
static void draw_keyframe_shape(
float x, float y, bool sel, float alpha, uint pos_id, uint color_id)
{
float color[4] = {0.91f, 0.91f, 0.91f, alpha};
if (sel) {
UI_GetThemeColorShadeAlpha4fv(TH_STRIP_SELECT, 50, -255 * (1.0f - alpha), color);
}
immAttr4fv(color_id, color);
immVertex2f(pos_id, x, y);
}
static void clip_draw_dopesheet_background(ARegion *region, MovieClip *clip, uint pos_id)
{
View2D *v2d = &region->v2d;
MovieTracking *tracking = &clip->tracking;
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
MovieTrackingDopesheetCoverageSegment *coverage_segment;
for (coverage_segment = dopesheet->coverage_segments.first; coverage_segment;
coverage_segment = coverage_segment->next) {
if (coverage_segment->coverage < TRACKING_COVERAGE_OK) {
int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip,
coverage_segment->start_frame);
int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, coverage_segment->end_frame);
if (coverage_segment->coverage == TRACKING_COVERAGE_BAD) {
immUniformColor4f(1.0f, 0.0f, 0.0f, 0.07f);
}
else {
immUniformColor4f(1.0f, 1.0f, 0.0f, 0.07f);
}
immRectf(pos_id, start_frame, v2d->cur.ymin, end_frame, v2d->cur.ymax);
}
}
}
void clip_draw_dopesheet_main(SpaceClip *sc, ARegion *region, Scene *scene)
{
MovieClip *clip = ED_space_clip_get_clip(sc);
View2D *v2d = &region->v2d;
/* frame range */
clip_draw_sfra_efra(v2d, scene);
if (clip) {
MovieTracking *tracking = &clip->tracking;
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
MovieTrackingDopesheetChannel *channel;
float strip[4], selected_strip[4];
float height = (dopesheet->tot_channel * CHANNEL_STEP) + CHANNEL_HEIGHT;
uint keyframe_len = 0;
GPUVertFormat *format = immVertexFormat();
uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
*/
v2d->tot.ymin = (float)(-height);
float y = (float)CHANNEL_FIRST;
/* setup colors for regular and selected strips */
UI_GetThemeColor3fv(TH_STRIP, strip);
UI_GetThemeColor3fv(TH_STRIP_SELECT, selected_strip);
strip[3] = 0.5f;
selected_strip[3] = 1.0f;
GPU_blend(GPU_BLEND_ALPHA);
clip_draw_dopesheet_background(region, clip, pos_id);
for (channel = dopesheet->channels.first; channel; channel = channel->next) {
float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
MovieTrackingTrack *track = channel->track;
int i;
bool sel = (track->flag & TRACK_DOPE_SEL) != 0;
/* selection background */
if (sel) {
float color[4] = {0.0f, 0.0f, 0.0f, 0.3f};
float default_color[4] = {0.8f, 0.93f, 0.8f, 0.3f};
track_channel_color(track, default_color, color);
immUniformColor4fv(color);
immRectf(pos_id,
v2d->cur.xmin,
(float)y - CHANNEL_HEIGHT_HALF,
v2d->cur.xmax + EXTRA_SCROLL_PAD,
(float)y + CHANNEL_HEIGHT_HALF);
}
/* tracked segments */
for (i = 0; i < channel->tot_segment; i++) {
int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip,
channel->segments[2 * i]);
int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip,
channel->segments[2 * i + 1]);
immUniformColor4fv(sel ? selected_strip : strip);
if (start_frame != end_frame) {
immRectf(pos_id,
start_frame,
(float)y - STRIP_HEIGHT_HALF,
end_frame,
(float)y + STRIP_HEIGHT_HALF);
keyframe_len += 2;
}
else {
keyframe_len++;
}
}
/* keyframes */
i = 0;
while (i < track->markersnr) {
MovieTrackingMarker *marker = &track->markers[i];
if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) {
keyframe_len++;
}
i++;
}
}
/* adjust y-position for next one */
y -= CHANNEL_STEP;
}
immUnbindProgram();
if (keyframe_len > 0) {
/* draw keyframe markers */
format = immVertexFormat();
pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
uint outline_color_id = GPU_vertformat_attr_add(
format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);
GPU_program_point_size(true);
immBindBuiltinProgram(GPU_SHADER_KEYFRAME_SHAPE);
immUniform1f("outline_scale", 1.0f);
immUniform2f(
"ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1);
immBegin(GPU_PRIM_POINTS, keyframe_len);
/* all same size with black outline */
immAttr1f(size_id, 2.0f * STRIP_HEIGHT_HALF);
immAttr4ub(outline_color_id, 0, 0, 0, 255);
immAttr1u(flags_id, 0);
y = (float)CHANNEL_FIRST; /* start again at the top */
for (channel = dopesheet->channels.first; channel; channel = channel->next) {
float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
MovieTrackingTrack *track = channel->track;
int i;
bool sel = (track->flag & TRACK_DOPE_SEL) != 0;
float alpha = (track->flag & TRACK_LOCKED) ? 0.5f : 1.0f;
/* tracked segments */
for (i = 0; i < channel->tot_segment; i++) {
int start_frame = BKE_movieclip_remap_clip_to_scene_frame(clip,
channel->segments[2 * i]);
int end_frame = BKE_movieclip_remap_clip_to_scene_frame(clip,
channel->segments[2 * i + 1]);
if (start_frame != end_frame) {
draw_keyframe_shape(start_frame, y, sel, alpha, pos_id, color_id);
draw_keyframe_shape(end_frame, y, sel, alpha, pos_id, color_id);
}
else {
draw_keyframe_shape(start_frame, y, sel, alpha, pos_id, color_id);
}
}
/* keyframes */
i = 0;
while (i < track->markersnr) {
MovieTrackingMarker *marker = &track->markers[i];
if ((marker->flag & (MARKER_DISABLED | MARKER_TRACKED)) == 0) {
int framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);
draw_keyframe_shape(framenr, y, sel, alpha, pos_id, color_id);
}
i++;
}
}
/* adjust y-position for next one */
y -= CHANNEL_STEP;
}
immEnd();
GPU_program_point_size(false);
immUnbindProgram();
}
GPU_blend(GPU_BLEND_NONE);
}
}
void clip_draw_dopesheet_channels(const bContext *C, ARegion *region)
{
ScrArea *area = CTX_wm_area(C);
SpaceClip *sc = CTX_wm_space_clip(C);
View2D *v2d = &region->v2d;
MovieClip *clip = ED_space_clip_get_clip(sc);
const uiStyle *style = UI_style_get();
int fontid = style->widget.uifont_id;
if (!clip) {
return;
}
MovieTracking *tracking = &clip->tracking;
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
int height = (dopesheet->tot_channel * CHANNEL_STEP) + CHANNEL_HEIGHT;
if (height > BLI_rcti_size_y(&v2d->mask)) {
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
*/
v2d->tot.ymin = (float)(-height);
}
/* need to do a view-sync here, so that the keys area doesn't jump around
* (it must copy this) */
UI_view2d_sync(NULL, area, v2d, V2D_LOCK_COPY);
/* loop through channels, and set up drawing depending on their type
* first pass: just the standard GL-drawing for backdrop + text
*/
float y = (float)CHANNEL_FIRST;
GPUVertFormat *format = immVertexFormat();
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
MovieTrackingDopesheetChannel *channel;
for (channel = dopesheet->channels.first; channel; channel = channel->next) {
float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
MovieTrackingTrack *track = channel->track;
float color[3];
track_channel_color(track, NULL, color);
immUniformColor3fv(color);
immRectf(pos,
v2d->cur.xmin,
(float)y - CHANNEL_HEIGHT_HALF,
v2d->cur.xmax + EXTRA_SCROLL_PAD,
(float)y + CHANNEL_HEIGHT_HALF);
}
/* adjust y-position for next one */
y -= CHANNEL_STEP;
}
immUnbindProgram();
/* second pass: text */
y = (float)CHANNEL_FIRST;
BLF_size(fontid, 11.0f * U.dpi_fac);
for (channel = dopesheet->channels.first; channel; channel = channel->next) {
float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
MovieTrackingTrack *track = channel->track;
bool sel = (track->flag & TRACK_DOPE_SEL) != 0;
UI_FontThemeColor(fontid, sel ? TH_TEXT_HI : TH_TEXT);
float font_height = BLF_height(fontid, channel->name, sizeof(channel->name));
BLF_position(fontid, v2d->cur.xmin + CHANNEL_PAD, y - font_height / 2.0f, 0.0f);
BLF_draw(fontid, channel->name, strlen(channel->name));
}
/* adjust y-position for next one */
y -= CHANNEL_STEP;
}
/* third pass: widgets */
uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
y = (float)CHANNEL_FIRST;
/* get RNA properties (once) */
PropertyRNA *chan_prop_lock = RNA_struct_type_find_property(&RNA_MovieTrackingTrack, "lock");
BLI_assert(chan_prop_lock);
GPU_blend(GPU_BLEND_ALPHA);
for (channel = dopesheet->channels.first; channel; channel = channel->next) {
float yminc = (float)(y - CHANNEL_HEIGHT_HALF);
float ymaxc = (float)(y + CHANNEL_HEIGHT_HALF);
/* check if visible */
if (IN_RANGE(yminc, v2d->cur.ymin, v2d->cur.ymax) ||
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax)) {
MovieTrackingTrack *track = channel->track;
const int icon = (track->flag & TRACK_LOCKED) ? ICON_LOCKED : ICON_UNLOCKED;
PointerRNA ptr;
RNA_pointer_create(&clip->id, &RNA_MovieTrackingTrack, track, &ptr);
UI_block_emboss_set(block, UI_EMBOSS_NONE);
uiDefIconButR_prop(block,
UI_BTYPE_ICON_TOGGLE,
1,
icon,
v2d->cur.xmax - UI_UNIT_X - CHANNEL_PAD,
y - UI_UNIT_Y / 2.0f,
UI_UNIT_X,
UI_UNIT_Y,
&ptr,
chan_prop_lock,
0,
0,
0,
0,
0,
NULL);
UI_block_emboss_set(block, UI_EMBOSS);
}
/* adjust y-position for next one */
y -= CHANNEL_STEP;
}
GPU_blend(GPU_BLEND_NONE);
UI_block_end(C, block);
UI_block_draw(C, block);
}