UI: Animation editor scrubbing area

The main reason for this change is to allow setting the
active frame with the left mouse button, while still being
able to select e.g. keyframes with the same mouse button.

The solution is to introduce a new scrubbing region with
a specialized keymap. There are a couple of related todos,
that will be handled in separate commits.
Those are listed in D4654.

This solves T63193.

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

Reviewers: brecht, billreynish
This commit is contained in:
Jacques Lucke 2019-05-07 15:09:14 +02:00
parent e4669199bf
commit f2b7582b27
Notes: blender-bot 2023-02-14 09:38:57 +01:00
Referenced by issue #63193, Animation Editor Scrubbing Area
29 changed files with 410 additions and 114 deletions

View File

@ -397,7 +397,7 @@ const bTheme U_theme_default = {
.space_graph = {
.back = RGBA(0x42424200),
.title = RGBA(0xffffffff),
.text = RGBA(0x000000ff),
.text = RGBA(0xa6a6a6ff),
.text_hi = RGBA(0xffffffff),
.header = RGBA(0x2e2e2eff),
.header_text = RGBA(0xeeeeeeff),
@ -427,6 +427,7 @@ const bTheme U_theme_default = {
.vertex = RGBA(0x000000ff),
.vertex_select = RGBA(0xff8500ff),
.cframe = RGBA(0x5680c2ff),
.scrubbing_background = RGBA(0x29292999),
.lastsel_point = RGBA(0xffffffff),
.handle_auto = RGBA(0x909000ff),
.handle_vect = RGBA(0x409030ff),
@ -482,7 +483,7 @@ const bTheme U_theme_default = {
.space_action = {
.back = RGBA(0x42424200),
.title = RGBA(0xeeeeeeff),
.text = RGBA(0x000000ff),
.text = RGBA(0xa6a6a6ff),
.text_hi = RGBA(0xffffffff),
.header = RGBA(0x424242ff),
.header_text = RGBA(0xeeeeeeff),
@ -513,6 +514,7 @@ const bTheme U_theme_default = {
.strip = RGBA(0x1a151580),
.strip_select = RGBA(0xff8c00cc),
.cframe = RGBA(0x5680c2ff),
.scrubbing_background = RGBA(0x29292999),
.ds_channel = RGBA(0x0f2c4d24),
.ds_subchannel = RGBA(0x143e6624),
.ds_ipoline = RGBA(0x94e575cc),
@ -539,7 +541,7 @@ const bTheme U_theme_default = {
.space_nla = {
.back = RGBA(0x42424200),
.title = RGBA(0xffffffff),
.text = RGBA(0x000000ff),
.text = RGBA(0xa6a6a6ff),
.text_hi = RGBA(0xffffffff),
.header = RGBA(0x424242ff),
.header_text = RGBA(0xeeeeeeff),
@ -566,6 +568,7 @@ const bTheme U_theme_default = {
.strip = RGBA(0x0c0a0a80),
.strip_select = RGBA(0xff8c00ff),
.cframe = RGBA(0x5680c2ff),
.scrubbing_background = RGBA(0x29292999),
.ds_channel = RGBA(0x5a85b2ff),
.ds_subchannel = RGBA(0x7d98b3ff),
.keyborder = RGBA(0x000000ff),
@ -589,7 +592,7 @@ const bTheme U_theme_default = {
.space_sequencer = {
.back = RGBA(0x42424200),
.title = RGBA(0xeeeeeeff),
.text = RGBA(0x000000ff),
.text = RGBA(0xa6a6a6ff),
.text_hi = RGBA(0xffffffff),
.header = RGBA(0x424242ff),
.header_text = RGBA(0xeeeeeeff),
@ -612,6 +615,7 @@ const bTheme U_theme_default = {
.vertex_select = RGBA(0xff8500ff),
.bone_pose = RGBA(0x50c8ff50),
.cframe = RGBA(0x5680c2ff),
.scrubbing_background = RGBA(0x29292999),
.vertex_size = 3,
.outline_width = 1,
.facedot_size = 4,
@ -861,7 +865,7 @@ const bTheme U_theme_default = {
.space_clip = {
.back = RGBA(0x42424200),
.title = RGBA(0xeeeeeeff),
.text = RGBA(0xe6e6e6ff),
.text = RGBA(0xa6a6a6ff),
.text_hi = RGBA(0xffffffff),
.header = RGBA(0x424242ff),
.header_text = RGBA(0xeeeeeeff),
@ -885,6 +889,7 @@ const bTheme U_theme_default = {
.strip = RGBA(0x0c0a0a80),
.strip_select = RGBA(0xff8c00ff),
.cframe = RGBA(0x5680c2ff),
.scrubbing_background = RGBA(0x29292999),
.handle_auto = RGBA(0x909000ff),
.handle_align = RGBA(0x803060ff),
.handle_sel_auto = RGBA(0xf0ff40ff),

View File

@ -1307,6 +1307,22 @@ def km_markers(params):
return keymap
def km_scrubbing(params):
items = []
keymap = (
"Scrubbing",
{"space_type": 'EMPTY', "region_type": 'WINDOW'},
{"items": items},
)
items.extend([
("anim.change_frame", {"type": "LEFTMOUSE", "value": 'PRESS'}, None),
("graph.cursor_set", {"type": "LEFTMOUSE", "value": 'PRESS'}, None),
])
return keymap
def km_graph_editor_generic(_params):
items = []
keymap = (
@ -6105,6 +6121,7 @@ def generate_keymaps(params=None):
km_view3d(params),
km_mask_editing(params),
km_markers(params),
km_scrubbing(params),
km_graph_editor_generic(params),
km_graph_editor(params),
km_image_generic(params),

View File

@ -31,7 +31,7 @@ from bpy.types import (
# used for DopeSheet, NLA, and Graph Editors
def dopesheet_filter(layout, context, generic_filters_only=False):
def dopesheet_filter(layout, context):
dopesheet = context.space_data.dopesheet
is_nla = context.area.type == 'NLA_EDITOR'
@ -44,18 +44,6 @@ def dopesheet_filter(layout, context, generic_filters_only=False):
else: # graph and dopesheet editors - F-Curves and drivers only
row.prop(dopesheet, "show_only_errors", text="")
if not generic_filters_only:
if bpy.data.collections:
row = layout.row(align=True)
row.prop(dopesheet, "filter_collection", text="")
if not is_nla:
row = layout.row(align=True)
row.prop(dopesheet, "filter_fcurve_name", text="")
else:
row = layout.row(align=True)
row.prop(dopesheet, "filter_text", text="")
#######################################
# Dopesheet Filtering Popovers
@ -260,9 +248,7 @@ class DOPESHEET_HT_editor_buttons(Header):
if st.mode == 'DOPESHEET':
dopesheet_filter(layout, context)
elif st.mode == 'ACTION':
# 'generic_filters_only' limits the options to only the relevant 'generic' subset of
# filters which will work here and are useful (especially for character animation)
dopesheet_filter(layout, context, generic_filters_only=True)
dopesheet_filter(layout, context)
elif st.mode == 'GPENCIL':
row = layout.row(align=True)
row.prop(st.dopesheet, "show_gpencil_3d_only", text="Active Only")

View File

@ -120,6 +120,18 @@ static void do_versions_theme(UserDef *userdef, bTheme *btheme)
if (btheme->space_view3d.obcenter_dia == 0) {
btheme->space_view3d.obcenter_dia = U_theme_default.space_view3d.obcenter_dia;
}
FROM_DEFAULT_V4_UCHAR(space_graph.text);
FROM_DEFAULT_V4_UCHAR(space_action.text);
FROM_DEFAULT_V4_UCHAR(space_nla.text);
FROM_DEFAULT_V4_UCHAR(space_sequencer.text);
FROM_DEFAULT_V4_UCHAR(space_clip.text);
FROM_DEFAULT_V4_UCHAR(space_graph.scrubbing_background);
FROM_DEFAULT_V4_UCHAR(space_action.scrubbing_background);
FROM_DEFAULT_V4_UCHAR(space_nla.scrubbing_background);
FROM_DEFAULT_V4_UCHAR(space_sequencer.scrubbing_background);
FROM_DEFAULT_V4_UCHAR(space_clip.scrubbing_background);
}
#undef FROM_DEFAULT_V4_UCHAR

View File

@ -44,6 +44,7 @@ set(SRC
anim_markers.c
anim_motion_paths.c
anim_ops.c
anim_scrubbing.c
drivers.c
fmodifier_ui.c
keyframes_draw.c

View File

@ -485,16 +485,10 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi
static void acf_summary_name(bAnimListElem *UNUSED(ale), char *name)
{
if (name) {
BLI_strncpy(name, IFACE_("Dope Sheet Summary"), ANIM_CHAN_NAME_SIZE);
BLI_strncpy(name, IFACE_("Summary"), ANIM_CHAN_NAME_SIZE);
}
}
// FIXME: this is really a temp icon I think
static int acf_summary_icon(bAnimListElem *UNUSED(ale))
{
return ICON_BORDERMOVE;
}
/* check if some setting exists for this channel */
static bool acf_summary_setting_valid(bAnimContext *UNUSED(ac),
bAnimListElem *UNUSED(ale),
@ -557,7 +551,7 @@ static bAnimChannelType ACF_SUMMARY = {
acf_summary_name, /* name */
NULL, /* name prop */
acf_summary_icon, /* icon */
NULL, /* icon */
acf_summary_setting_valid, /* has setting */
acf_summary_setting_flag, /* flag for setting */

View File

@ -55,6 +55,7 @@
#include "DEG_depsgraph_build.h"
#include "UI_view2d.h"
#include "UI_interface.h"
#include "ED_anim_api.h"
#include "ED_armature.h"
@ -2542,7 +2543,7 @@ static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectm
float ymax;
if (ac->datatype == ANIMCONT_NLA) {
ymax = NLACHANNEL_FIRST_TOP(snla);
ymax = NLACHANNEL_FIRST_TOP(ac);
}
else {
ymax = ACHANNEL_FIRST_TOP(ac);
@ -2735,7 +2736,7 @@ static int animchannels_channel_get(bAnimContext *ac, const int mval[2])
UI_view2d_listview_view_to_cell(NLACHANNEL_NAMEWIDTH,
NLACHANNEL_STEP(snla),
0,
NLACHANNEL_FIRST_TOP(snla),
NLACHANNEL_FIRST_TOP(ac),
x,
y,
NULL,

View File

@ -0,0 +1,197 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
/** \file
* \ingroup edanimation
*/
#include "BKE_context.h"
#include "GPU_immediate.h"
#include "GPU_matrix.h"
#include "GPU_state.h"
#include "ED_scrubbing.h"
#include "WM_api.h"
#include "WM_types.h"
#include "UI_interface.h"
#include "UI_interface_icons.h"
#include "UI_view2d.h"
#include "UI_resources.h"
#include "DNA_scene_types.h"
#include "BLI_rect.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_timecode.h"
#include "RNA_access.h"
static void get_scrubbing_region_rect(const ARegion *ar, rcti *rect)
{
rect->xmin = 0;
rect->xmax = ar->winx;
rect->ymax = ar->winy;
rect->ymin = rect->ymax - UI_SCRUBBING_MARGIN_Y;
}
static int get_centered_text_y(const rcti *rect)
{
return BLI_rcti_cent_y(rect) - UI_DPI_FAC * 4;
}
static void draw_background(const rcti *rect)
{
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_SCRUBBING_BACKGROUND);
GPU_blend(true);
GPU_blend_set_func_separate(
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
GPU_blend(false);
immUnbindProgram();
}
static void get_current_time_str(
const Scene *scene, bool display_seconds, int frame, uint max_len, char *r_str)
{
if (display_seconds) {
BLI_timecode_string_from_time(r_str, max_len, 0, FRA2TIME(frame), FPS, U.timecode_style);
}
else {
BLI_snprintf(r_str, max_len, "%d", frame);
}
}
static void draw_current_frame(const Scene *scene,
bool display_seconds,
const View2D *v2d,
const rcti *scrubbing_region_rect,
int current_frame)
{
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
const unsigned char color[] = {255, 255, 255, 255};
int frame_x = UI_view2d_view_to_region_x(v2d, current_frame);
char frame_str[64];
get_current_time_str(scene, display_seconds, current_frame, sizeof(frame_str), frame_str);
float text_width = UI_fontstyle_string_width(fstyle, frame_str);
float box_width = text_width + 10 * UI_DPI_FAC;
float box_padding = 3 * UI_DPI_FAC;
float bg_color[4];
UI_GetThemeColor4fv(TH_CFRAME, bg_color);
bg_color[3] = 8.0f;
UI_draw_roundbox_corner_set(UI_CNR_ALL);
UI_draw_roundbox_aa(true,
frame_x - box_width / 2,
scrubbing_region_rect->ymin + box_padding,
frame_x + box_width / 2,
scrubbing_region_rect->ymax - box_padding,
5 * UI_DPI_FAC,
bg_color);
UI_fontstyle_draw_simple(fstyle,
frame_x - text_width / 2,
get_centered_text_y(scrubbing_region_rect),
frame_str,
color);
}
void ED_scrubbing_draw(const ARegion *ar,
const Scene *scene,
bool display_seconds,
bool discrete_frames)
{
const View2D *v2d = &ar->v2d;
GPU_matrix_push_projection();
wmOrtho2_region_pixelspace(ar);
rcti scrubbing_region_rect;
get_scrubbing_region_rect(ar, &scrubbing_region_rect);
draw_background(&scrubbing_region_rect);
rcti numbers_rect = scrubbing_region_rect;
numbers_rect.ymin = get_centered_text_y(&scrubbing_region_rect) - 4 * UI_DPI_FAC;
if (discrete_frames) {
UI_view2d_draw_scale_x__discrete_frames_or_seconds(
ar, v2d, &numbers_rect, scene, display_seconds, TH_TEXT);
}
else {
UI_view2d_draw_scale_x__frames_or_seconds(
ar, v2d, &numbers_rect, scene, display_seconds, TH_TEXT);
}
draw_current_frame(scene, display_seconds, v2d, &scrubbing_region_rect, scene->r.cfra);
GPU_matrix_pop_projection();
}
void ED_channel_search_draw(const bContext *C, ARegion *ar, bDopeSheet *dopesheet)
{
GPU_matrix_push_projection();
wmOrtho2_region_pixelspace(ar);
rcti rect;
rect.xmin = 0;
rect.xmax = ceilf(ar->sizex * UI_DPI_FAC);
rect.ymin = ar->sizey * UI_DPI_FAC - UI_SCRUBBING_MARGIN_Y;
rect.ymax = ceilf(ar->sizey * UI_DPI_FAC);
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
immUniformThemeColor(TH_BACK);
immRectf(pos, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
immUnbindProgram();
uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
PointerRNA ptr;
RNA_pointer_create(&CTX_wm_screen(C)->id, &RNA_DopeSheet, dopesheet, &ptr);
PropertyRNA *prop = RNA_struct_find_property(&ptr, "filter_text");
int padding = 2 * UI_DPI_FAC;
uiDefAutoButR(block,
&ptr,
prop,
-1,
"",
ICON_NONE,
rect.xmin + padding,
rect.ymin + padding,
BLI_rcti_size_x(&rect) - 2 * padding,
BLI_rcti_size_y(&rect) - 2 * padding);
UI_block_end(C, block);
UI_block_draw(C, block);
GPU_matrix_pop_projection();
}

View File

@ -403,7 +403,8 @@ typedef enum eAnimFilter_Flags {
/* -------------- Channel Defines -------------- */
/* channel heights */
#define ACHANNEL_FIRST_TOP(ac) (-0.4f * (ac)->yscale_fac * U.widget_unit)
#define ACHANNEL_FIRST_TOP(ac) \
(UI_view2d_scale_get_y(&(ac)->ar->v2d) * -UI_SCRUBBING_MARGIN_Y - ACHANNEL_SKIP)
#define ACHANNEL_HEIGHT(ac) (0.8f * (ac)->yscale_fac * U.widget_unit)
#define ACHANNEL_SKIP (0.1f * U.widget_unit)
#define ACHANNEL_STEP(ac) (ACHANNEL_HEIGHT(ac) + ACHANNEL_SKIP)
@ -420,14 +421,15 @@ typedef enum eAnimFilter_Flags {
/* -------------- NLA Channel Defines -------------- */
/* NLA channel heights */
#define NLACHANNEL_FIRST_TOP(snla) (-0.4f * U.widget_unit)
#define NLACHANNEL_FIRST_TOP(ac) \
(UI_view2d_scale_get_y(&(ac)->ar->v2d) * -UI_SCRUBBING_MARGIN_Y - NLACHANNEL_SKIP)
#define NLACHANNEL_HEIGHT(snla) \
((snla && (snla->flag & SNLA_NOSTRIPCURVES)) ? (0.8f * U.widget_unit) : (1.2f * U.widget_unit))
#define NLACHANNEL_SKIP (0.1f * U.widget_unit)
#define NLACHANNEL_STEP(snla) (NLACHANNEL_HEIGHT(snla) + NLACHANNEL_SKIP)
/* Additional offset to give some room at the end. */
#define NLACHANNEL_TOT_HEIGHT(snla, item_amount) \
(-NLACHANNEL_FIRST_TOP(snla) + NLACHANNEL_STEP(snla) * (item_amount + 1))
#define NLACHANNEL_TOT_HEIGHT(ac, item_amount) \
(-NLACHANNEL_FIRST_TOP(ac) + NLACHANNEL_STEP(((SpaceNla *)(ac)->sl)) * (item_amount + 1))
/* channel widths */
#define NLACHANNEL_NAMEWIDTH (10 * U.widget_unit)

View File

@ -436,12 +436,11 @@ enum {
ED_KEYMAP_GIZMO = (1 << 2),
ED_KEYMAP_TOOL = (1 << 3),
ED_KEYMAP_VIEW2D = (1 << 4),
ED_KEYMAP_MARKERS = (1 << 5),
ED_KEYMAP_ANIMATION = (1 << 6),
ED_KEYMAP_FRAMES = (1 << 7),
ED_KEYMAP_HEADER = (1 << 8),
ED_KEYMAP_GPENCIL = (1 << 9),
ED_KEYMAP_FOOTER = (1 << 10),
ED_KEYMAP_ANIMATION = (1 << 5),
ED_KEYMAP_FRAMES = (1 << 6),
ED_KEYMAP_HEADER = (1 << 7),
ED_KEYMAP_GPENCIL = (1 << 8),
ED_KEYMAP_FOOTER = (1 << 9),
};
/* SCREEN_OT_space_context_cycle direction */

View File

@ -0,0 +1,40 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2019 Blender Foundation.
* All rights reserved.
*/
/** \file
* \ingroup editors
*/
#ifndef __ED_SCRUBBING_H__
#define __ED_SCRUBBING_H__
struct bContext;
struct View2DGrid;
struct bDopeSheet;
void ED_scrubbing_draw(const struct ARegion *ar,
const struct Scene *scene,
bool display_seconds,
bool discrete_frames);
void ED_channel_search_draw(const struct bContext *C,
struct ARegion *ar,
struct bDopeSheet *dopesheet);
#endif /* __ED_SCRUBBING_H__ */

View File

@ -105,6 +105,7 @@ typedef enum ThemeColorID {
TH_FACE_DOT,
TH_FACEDOT_SIZE,
TH_CFRAME,
TH_SCRUBBING_BACKGROUND,
TH_TIME_KEYFRAME,
TH_TIME_GP_KEYFRAME,
TH_NURB_ULINE,
@ -267,6 +268,8 @@ typedef enum ThemeColorID {
TH_ICON_MODIFIER,
TH_ICON_SHADING,
TH_SCROLL_TEXT,
TH_NLA_TWEAK, /* 'tweaking' track in NLA */
TH_NLA_TWEAK_DUPLI, /* error/warning flag for other strips referencing dupli strip */

View File

@ -258,6 +258,8 @@ void UI_view2d_smooth_view(struct bContext *C,
struct ARegion *ar,
const struct rctf *cur,
const int smooth_viewtx);
#define UI_MARKER_MARGIN_Y (42 * UI_DPI_FAC)
#define UI_SCRUBBING_MARGIN_Y (23 * UI_DPI_FAC)
#endif /* __UI_VIEW2D_H__ */

View File

@ -309,6 +309,9 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
case TH_GRID:
cp = ts->grid;
break;
case TH_SCRUBBING_BACKGROUND:
cp = ts->scrubbing_background;
break;
case TH_VIEW_OVERLAY:
cp = ts->view_overlay;
break;
@ -881,6 +884,10 @@ const uchar *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
cp = btheme->tui.icon_shading;
break;
case TH_SCROLL_TEXT:
cp = btheme->tui.wcol_scroll.text;
break;
case TH_INFO_SELECTED:
cp = ts->info_selected;
break;

View File

@ -185,6 +185,13 @@ static void view2d_masks(View2D *v2d, bool check_scrollers, const rcti *mask_scr
v2d->vert.xmin = v2d->vert.xmax - scroll_width;
}
/* Currently, all regions that have vertical scale text,
* also have the scrubbing area at the top.
* So the scrollbar has to move down a bit. */
if (scroll & V2D_SCROLL_SCALE_VERTICAL) {
v2d->vert.ymax -= UI_SCRUBBING_MARGIN_Y;
}
/* horizontal scroller */
if (scroll & (V2D_SCROLL_BOTTOM)) {
/* on bottom edge of region */

View File

@ -1566,6 +1566,13 @@ static bool event_in_markers_region(const ARegion *ar, const wmEvent *event)
return BLI_rcti_isect_pt(&rect, event->x, event->y);
}
static bool event_in_scrubbing_region(const ARegion *ar, const wmEvent *event)
{
rcti rect = ar->winrct;
rect.ymin = rect.ymax - UI_SCRUBBING_MARGIN_Y;
return BLI_rcti_isect_pt(&rect, event->x, event->y);
}
/**
* \param ar: Region, may be NULL when adding handlers for \a sa.
*/
@ -1604,14 +1611,19 @@ static void ed_default_handlers(
wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "View2D", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
if (flag & ED_KEYMAP_MARKERS) {
/* time-markers */
wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Markers", 0, 0);
WM_event_add_keymap_handler_poll(handlers, keymap, event_in_markers_region);
}
if (flag & ED_KEYMAP_ANIMATION) {
wmKeyMap *keymap;
/* time-markers */
keymap = WM_keymap_ensure(wm->defaultconf, "Markers", 0, 0);
WM_event_add_keymap_handler_poll(handlers, keymap, event_in_markers_region);
/* time-scrubbing */
keymap = WM_keymap_ensure(wm->defaultconf, "Scrubbing", 0, 0);
WM_event_add_keymap_handler_poll(handlers, keymap, event_in_scrubbing_region);
/* frame changing and timeline operators (for time spaces) */
wmKeyMap *keymap = WM_keymap_ensure(wm->defaultconf, "Animation", 0, 0);
keymap = WM_keymap_ensure(wm->defaultconf, "Animation", 0, 0);
WM_event_add_keymap_handler(handlers, keymap);
}
if (flag & ED_KEYMAP_FRAMES) {

View File

@ -47,6 +47,7 @@
#include "BKE_gpencil.h"
#include "UI_view2d.h"
#include "UI_interface.h"
#include "ED_anim_api.h"
#include "ED_gpencil.h"

View File

@ -47,11 +47,13 @@
#include "UI_resources.h"
#include "UI_view2d.h"
#include "UI_interface.h"
#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_anim_api.h"
#include "ED_markers.h"
#include "ED_scrubbing.h"
#include "action_intern.h" /* own include */
#include "GPU_framebuffer.h"
@ -234,20 +236,13 @@ static void action_main_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
/* scrubbing region */
ED_scrubbing_draw(ar, scene, saction->flag & SACTION_DRAWTIME, true);
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
UI_view2d_scrollers_draw(v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
/* frame numbers */
UI_view2d_draw_scale_x__discrete_frames_or_seconds(
ar, v2d, &v2d->hor, scene, saction->flag & SACTION_DRAWTIME, TH_TEXT);
/* draw current frame number-indicator on top of scrollers */
if ((saction->flag & SACTION_NODRAWCFRANUM) == 0) {
UI_view2d_view_orthoSpecial(ar, v2d, 1);
ANIM_draw_cfra_number(C, v2d, cfra_flag);
}
}
/* add handlers, stuff you only do once or on area/region changes */
@ -285,6 +280,9 @@ static void action_channel_region_draw(const bContext *C, ARegion *ar)
draw_channel_names((bContext *)C, &ac, ar);
}
/* channel filter next to scrubbing area */
ED_channel_search_draw(C, ar, ac.ads);
/* reset view matrix */
UI_view2d_view_restore(C);
@ -869,7 +867,7 @@ void ED_spacetype_action(void)
art->draw = action_main_region_draw;
art->listener = action_main_region_listener;
art->message_subscribe = saction_main_region_message_subscribe;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);

View File

@ -47,6 +47,7 @@
#include "ED_mask.h"
#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_scrubbing.h"
#include "ED_select_utils.h"
#include "ED_clip.h"
#include "ED_transform.h"
@ -1041,22 +1042,16 @@ static void graph_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
/* time-scrubbing */
ED_scrubbing_draw(ar, scene, sc->flag & SC_SHOW_SECONDS, true);
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
UI_view2d_scrollers_draw(v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
/* scale indicators */
UI_view2d_draw_scale_x__discrete_frames_or_seconds(
ar, v2d, &v2d->hor, scene, sc->flag & SC_SHOW_SECONDS, TH_TEXT);
UI_view2d_draw_scale_y__values(ar, v2d, &v2d->vert, TH_TEXT);
/* current frame indicator */
if (sc->flag & SC_SHOW_SECONDS) {
cfra_flag |= DRAWCFRA_UNIT_SECONDS;
}
UI_view2d_view_orthoSpecial(ar, v2d, 1);
ANIM_draw_cfra_number(C, v2d, cfra_flag);
}
static void dopesheet_region_draw(const bContext *C, ARegion *ar)
@ -1093,18 +1088,13 @@ static void dopesheet_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
/* time-scrubbing */
ED_scrubbing_draw(ar, scene, sc->flag & SC_SHOW_SECONDS, true);
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
UI_view2d_scrollers_draw(v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
/* frame numbers */
UI_view2d_draw_scale_x__discrete_frames_or_seconds(
ar, v2d, &v2d->hor, scene, sc->flag & SC_SHOW_SECONDS, TH_TEXT);
/* current frame number indicator */
UI_view2d_view_orthoSpecial(ar, v2d, 1);
ANIM_draw_cfra_number(C, v2d, cfra_flag);
}
static void clip_preview_region_draw(const bContext *C, ARegion *ar)

View File

@ -42,6 +42,7 @@
#include "ED_screen.h"
#include "ED_anim_api.h"
#include "ED_markers.h"
#include "ED_scrubbing.h"
#include "GPU_immediate.h"
#include "GPU_state.h"
@ -309,6 +310,9 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
/* time-scrubbing */
ED_scrubbing_draw(ar, scene, display_seconds, false);
/* scrollers */
// FIXME: args for scrollers depend on the type of data being shown...
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
@ -316,14 +320,7 @@ static void graph_main_region_draw(const bContext *C, ARegion *ar)
UI_view2d_scrollers_free(scrollers);
/* scale numbers */
UI_view2d_draw_scale_x__frames_or_seconds(ar, v2d, &v2d->hor, scene, display_seconds, TH_TEXT);
UI_view2d_draw_scale_y__values(ar, v2d, &v2d->vert, TH_TEXT);
/* draw current frame number-indicator on top of scrollers */
if ((sipo->mode != SIPO_MODE_DRIVERS) && ((sipo->flag & SIPO_NODRAWCFRANUM) == 0)) {
UI_view2d_view_orthoSpecial(ar, v2d, 1);
ANIM_draw_cfra_number(C, v2d, cfra_flag);
}
UI_view2d_draw_scale_y__values(ar, v2d, &v2d->vert, TH_SCROLL_TEXT);
}
static void graph_channel_region_init(wmWindowManager *wm, ARegion *ar)
@ -367,6 +364,9 @@ static void graph_channel_region_draw(const bContext *C, ARegion *ar)
graph_draw_channel_names((bContext *)C, &ac, ar);
}
/* channel filter next to scrubbing area */
ED_channel_search_draw(C, ar, ac.ads);
/* reset view matrix */
UI_view2d_view_restore(C);
@ -849,7 +849,7 @@ void ED_spacetype_ipo(void)
art->draw = graph_main_region_draw;
art->listener = graph_region_listener;
art->message_subscribe = graph_region_message_subscribe;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);

View File

@ -52,6 +52,8 @@
#include "WM_api.h"
#include "WM_types.h"
#include "UI_interface.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
@ -389,7 +391,7 @@ static int nlachannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEv
UI_view2d_listview_view_to_cell(NLACHANNEL_NAMEWIDTH,
NLACHANNEL_STEP(snla),
0,
NLACHANNEL_FIRST_TOP(snla),
NLACHANNEL_FIRST_TOP(&ac),
x,
y,
NULL,

View File

@ -689,11 +689,11 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
* - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
* start of list offset, and the second is as a correction for the scrollers.
*/
int height = NLACHANNEL_TOT_HEIGHT(snla, items);
int height = NLACHANNEL_TOT_HEIGHT(ac, items);
v2d->tot.ymin = -height;
/* loop through channels, and set up drawing depending on their type */
float ymax = NLACHANNEL_FIRST_TOP(snla);
float ymax = NLACHANNEL_FIRST_TOP(ac);
for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next, ymax -= NLACHANNEL_STEP(snla)) {
float ymin = ymax - NLACHANNEL_HEIGHT(snla);
@ -822,7 +822,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
* - offset of NLACHANNEL_HEIGHT*2 is added to the height of the channels, as first is for
* start of list offset, and the second is as a correction for the scrollers.
*/
int height = NLACHANNEL_TOT_HEIGHT(snla, items);
int height = NLACHANNEL_TOT_HEIGHT(ac, items);
v2d->tot.ymin = -height;
/* need to do a view-sync here, so that the keys area doesn't jump around
@ -832,7 +832,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
/* draw channels */
{ /* first pass: just the standard GL-drawing for backdrop + text */
size_t channel_index = 0;
float ymax = NLACHANNEL_FIRST_TOP(snla);
float ymax = NLACHANNEL_FIRST_TOP(ac);
for (ale = anim_data.first; ale;
ale = ale->next, ymax -= NLACHANNEL_STEP(snla), channel_index++) {
@ -849,7 +849,7 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
{ /* second pass: UI widgets */
uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS);
size_t channel_index = 0;
float ymax = NLACHANNEL_FIRST_TOP(snla);
float ymax = NLACHANNEL_FIRST_TOP(ac);
/* set blending again, as may not be set in previous step */
GPU_blend_set_func_separate(

View File

@ -429,7 +429,7 @@ static bool nla_channels_get_selected_extents(bAnimContext *ac, float *min, floa
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* loop through all channels, finding the first one that's selected */
float ymax = NLACHANNEL_FIRST_TOP(snla);
float ymax = NLACHANNEL_FIRST_TOP(ac);
for (ale = anim_data.first; ale; ale = ale->next, ymax -= NLACHANNEL_STEP(snla)) {
const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);

View File

@ -47,6 +47,7 @@
#include "WM_types.h"
#include "UI_view2d.h"
#include "UI_interface.h"
#include "nla_intern.h" // own include
@ -542,7 +543,7 @@ static void mouse_nla_strips(
* (i.e a row in the list) where keyframe was */
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
UI_view2d_listview_view_to_cell(
0, NLACHANNEL_STEP(snla), 0, NLACHANNEL_FIRST_TOP(snla), x, y, NULL, &channel_index);
0, NLACHANNEL_STEP(snla), 0, NLACHANNEL_FIRST_TOP(ac), x, y, NULL, &channel_index);
/* x-range to check is +/- 7 (in screen/region-space) on either side of mouse click
* (that is the size of keyframe icons, so user should be expecting similar tolerances)

View File

@ -40,6 +40,7 @@
#include "ED_anim_api.h"
#include "ED_markers.h"
#include "ED_screen.h"
#include "ED_scrubbing.h"
#include "WM_api.h"
#include "WM_types.h"
@ -201,6 +202,9 @@ static void nla_channel_region_draw(const bContext *C, ARegion *ar)
draw_nla_channel_list(C, &ac, ar);
}
/* channel filter next to scrubbing area */
ED_channel_search_draw(C, ar, ac.ads);
/* reset view matrix */
UI_view2d_view_restore(C);
@ -284,20 +288,12 @@ static void nla_main_region_draw(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
ED_scrubbing_draw(ar, scene, snla->flag & SNLA_DRAWTIME, true);
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
UI_view2d_scrollers_draw(v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
/* frame numbers */
UI_view2d_draw_scale_x__discrete_frames_or_seconds(
ar, v2d, &v2d->hor, scene, snla->flag & SNLA_DRAWTIME, TH_TEXT);
/* draw current frame number-indicator on top of scrollers */
if ((snla->flag & SNLA_NODRAWCFRANUM) == 0) {
UI_view2d_view_orthoSpecial(ar, v2d, 1);
ANIM_draw_cfra_number(C, v2d, cfra_flag);
}
}
/* add handlers, stuff you only do once or on area/region changes */
@ -614,7 +610,7 @@ void ED_spacetype_nla(void)
art->draw = nla_main_region_draw;
art->listener = nla_main_region_listener;
art->message_subscribe = nla_main_region_message_subscribe;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES;
BLI_addhead(&st->regiontypes, art);

View File

@ -60,6 +60,7 @@
#include "ED_mask.h"
#include "ED_sequencer.h"
#include "ED_screen.h"
#include "ED_scrubbing.h"
#include "ED_space_api.h"
#include "BIF_glutil.h"
@ -2085,19 +2086,14 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
/* reset view matrix */
UI_view2d_view_restore(C);
/* scrubbing region */
ED_scrubbing_draw(ar, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
/* scrollers */
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
UI_view2d_scrollers_draw(v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
/* scale numbers */
UI_view2d_draw_scale_x__discrete_frames_or_seconds(
ar, v2d, &v2d->hor, scene, !(sseq->flag & SEQ_DRAWFRAMES), TH_TEXT);
UI_view2d_draw_scale_y__block(ar, v2d, &v2d->vert, TH_TEXT);
/* draw current frame number-indicator on top of scrollers */
if ((sseq->flag & SEQ_NO_DRAW_CFRANUM) == 0) {
UI_view2d_view_orthoSpecial(ar, v2d, 1);
ANIM_draw_cfra_number(C, v2d, cfra_flag);
}
/* channel numbers */
UI_view2d_draw_scale_y__block(ar, v2d, &v2d->vert, TH_SCROLL_TEXT);
}

View File

@ -816,7 +816,7 @@ void ED_spacetype_sequencer(void)
art->draw = sequencer_main_region_draw;
art->listener = sequencer_main_region_listener;
art->message_subscribe = sequencer_main_region_message_subscribe;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_FRAMES | ED_KEYMAP_ANIMATION;
art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_ANIMATION;
BLI_addhead(&st->regiontypes, art);

View File

@ -283,6 +283,8 @@ typedef struct ThemeSpace {
char cframe[4];
char time_keyframe[4], time_gp_keyframe[4];
char freestyle_edge_mark[4], freestyle_face_mark[4];
char scrubbing_background[4];
char _pad5[4];
char nurb_uline[4], nurb_vline[4];
char act_spline[4], nurb_sel_uline[4], nurb_sel_vline[4], lastsel_point[4];

View File

@ -2065,6 +2065,11 @@ static void rna_def_userdef_theme_space_graph(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "scrubbing_background", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Scrubbing Region", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "window_sliders", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "shade1");
RNA_def_property_array(prop, 3);
@ -2759,6 +2764,11 @@ static void rna_def_userdef_theme_space_seq(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "scrubbing_background", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Scrubbing Region", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "keyframe", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "vertex_select");
RNA_def_property_array(prop, 3);
@ -2816,6 +2826,11 @@ static void rna_def_userdef_theme_space_action(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "scrubbing_background", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Scrubbing Region", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "value_sliders", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "face");
RNA_def_property_array(prop, 3);
@ -3108,6 +3123,11 @@ static void rna_def_userdef_theme_space_nla(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "scrubbing_background", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Scrubbing Region", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
}
static void rna_def_userdef_theme_colorset(BlenderRNA *brna)
@ -3215,6 +3235,11 @@ static void rna_def_userdef_theme_space_clip(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Current Frame", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "scrubbing_background", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_array(prop, 4);
RNA_def_property_ui_text(prop, "Scrubbing Region", "");
RNA_def_property_update(prop, 0, "rna_userdef_theme_update");
prop = RNA_def_property(srna, "strips", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "strip");
RNA_def_property_array(prop, 3);