|
|
|
@@ -33,6 +33,7 @@
|
|
|
|
|
#include "DNA_armature_types.h"
|
|
|
|
|
#include "DNA_object_types.h"
|
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
#include "DNA_vec_types.h"
|
|
|
|
|
|
|
|
|
|
#include "BKE_fcurve.h"
|
|
|
|
|
#include "BKE_nla.h"
|
|
|
|
@@ -50,15 +51,27 @@
|
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
|
|
|
|
#include "UI_interface.h"
|
|
|
|
|
#include "UI_resources.h"
|
|
|
|
|
|
|
|
|
|
#include "ED_armature.h"
|
|
|
|
|
#include "ED_keyframes_draw.h"
|
|
|
|
|
#include "ED_markers.h"
|
|
|
|
|
#include "ED_numinput.h"
|
|
|
|
|
#include "ED_screen.h"
|
|
|
|
|
#include "ED_space_api.h"
|
|
|
|
|
|
|
|
|
|
#include "GPU_immediate.h"
|
|
|
|
|
#include "GPU_immediate_util.h"
|
|
|
|
|
#include "GPU_matrix.h"
|
|
|
|
|
#include "GPU_state.h"
|
|
|
|
|
|
|
|
|
|
#include "armature_intern.h"
|
|
|
|
|
|
|
|
|
|
#include "BLF_api.h"
|
|
|
|
|
|
|
|
|
|
/* Pixel distance from 0% to 100%. */
|
|
|
|
|
#define SLIDE_PIXEL_DISTANCE (300 * U.dpi_fac)
|
|
|
|
|
|
|
|
|
|
/* **************************************************** */
|
|
|
|
|
/* == POSE 'SLIDING' TOOLS ==
|
|
|
|
|
*
|
|
|
|
@@ -110,15 +123,43 @@ typedef struct tPoseSlideOp {
|
|
|
|
|
/** unused for now, but can later get used for storing runtime settings.... */
|
|
|
|
|
short flag;
|
|
|
|
|
|
|
|
|
|
/* Store overlay settings when invoking the operator. Bones will be temporarily hidden. */
|
|
|
|
|
int overlay_flag;
|
|
|
|
|
|
|
|
|
|
/** which transforms/channels are affected (ePoseSlide_Channels) */
|
|
|
|
|
short channels;
|
|
|
|
|
/** axis-limits for transforms (ePoseSlide_AxisLock) */
|
|
|
|
|
short axislock;
|
|
|
|
|
|
|
|
|
|
/** 0-1 value for determining the influence of whatever is relevant */
|
|
|
|
|
/* Allow overshoot or clamp between 0% and 100%. */
|
|
|
|
|
bool overshoot;
|
|
|
|
|
|
|
|
|
|
/* Reduces percentage delta from mouse movement. */
|
|
|
|
|
bool precision;
|
|
|
|
|
|
|
|
|
|
/* Move percentage in 10% steps. */
|
|
|
|
|
bool increments;
|
|
|
|
|
|
|
|
|
|
/* Pixel value in area space where the slider starts. */
|
|
|
|
|
int slider_start[2];
|
|
|
|
|
|
|
|
|
|
/* Draw callback handler. */
|
|
|
|
|
void *draw_handle;
|
|
|
|
|
|
|
|
|
|
/* Accumulative, unclamped and unrounded percentage. */
|
|
|
|
|
float raw_percentage;
|
|
|
|
|
|
|
|
|
|
/* 0-1 value for determining the influence of whatever is relevant. */
|
|
|
|
|
float percentage;
|
|
|
|
|
|
|
|
|
|
/** numeric input */
|
|
|
|
|
/* Cursor position in region space. */
|
|
|
|
|
int cursor_region_x;
|
|
|
|
|
int cursor_region_y;
|
|
|
|
|
|
|
|
|
|
/* Last cursor position in screen space used for mouse movement delta calculation. */
|
|
|
|
|
int last_cursor_x;
|
|
|
|
|
|
|
|
|
|
/* Numeric input. */
|
|
|
|
|
NumInput num;
|
|
|
|
|
|
|
|
|
|
struct tPoseSlideObject *ob_data_array;
|
|
|
|
@@ -187,6 +228,135 @@ static const EnumPropertyItem prop_axis_lock_types[] = {
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------ */
|
|
|
|
|
|
|
|
|
|
/* Draw a given string centered at the given coordinates. */
|
|
|
|
|
static void draw_centered_string_with_background(
|
|
|
|
|
const char *string, const float x, const float y, const uchar color_bg[4], const int fontid)
|
|
|
|
|
{
|
|
|
|
|
const int bg_margin = 5 * U.dpi_fac;
|
|
|
|
|
float string_pixel_size[2];
|
|
|
|
|
/* Get width and height of printed string to center above ticks. */
|
|
|
|
|
BLF_width_and_height(
|
|
|
|
|
fontid, string, sizeof(string), &string_pixel_size[0], &string_pixel_size[1]);
|
|
|
|
|
const unsigned char col[3] = {color_bg[0], color_bg[1], color_bg[2]};
|
|
|
|
|
const rctf background_rect = {.xmin = x - string_pixel_size[0] / 2 - bg_margin,
|
|
|
|
|
.xmax = x + string_pixel_size[0] / 2 + bg_margin,
|
|
|
|
|
.ymin = y - string_pixel_size[1] / 2 - bg_margin,
|
|
|
|
|
.ymax = y + string_pixel_size[1] / 2 + bg_margin};
|
|
|
|
|
UI_draw_roundbox_3ub_alpha(&background_rect, true, 4.0f, col, color_bg[3]);
|
|
|
|
|
BLF_position(fontid, x - string_pixel_size[0] / 2, y - string_pixel_size[1] / 2, 0.0f);
|
|
|
|
|
BLF_draw(fontid, string, sizeof(string));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw an on screen Slider for a Pose Slide Operator. */
|
|
|
|
|
static void pose_slide_draw_2d_slider(const struct bContext *UNUSED(C), ARegion *region, void *arg)
|
|
|
|
|
{
|
|
|
|
|
tPoseSlideOp *pso = arg;
|
|
|
|
|
|
|
|
|
|
/* Only draw in region from which the Operator was started. */
|
|
|
|
|
if (region != pso->region) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uchar color_text[4];
|
|
|
|
|
uchar color_line[4];
|
|
|
|
|
uchar color_handle[4];
|
|
|
|
|
uchar color_bg[4];
|
|
|
|
|
|
|
|
|
|
char percentage_string[256];
|
|
|
|
|
|
|
|
|
|
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
|
|
|
|
|
|
|
|
|
/* Get theme colors. Text gets a different color when the value is clamped.*/
|
|
|
|
|
UI_GetThemeColor4ubv(TH_TEXT, color_text);
|
|
|
|
|
UI_GetThemeColor4ubv(TH_TEXT, color_line);
|
|
|
|
|
UI_GetThemeColor4ubv(TH_ACTIVE, color_handle);
|
|
|
|
|
UI_GetThemeColor4ubv(TH_HEADER, color_bg);
|
|
|
|
|
color_bg[3] = 160;
|
|
|
|
|
|
|
|
|
|
/* Get the default font. */
|
|
|
|
|
const uiStyle *style = UI_style_get();
|
|
|
|
|
const uiFontStyle *fstyle = &style->widget;
|
|
|
|
|
const int fontid = fstyle->uifont_id;
|
|
|
|
|
BLF_color3ubv(fontid, color_text);
|
|
|
|
|
BLF_rotation(fontid, 0.0f);
|
|
|
|
|
|
|
|
|
|
const float line_width = 4 * U.dpi_fac;
|
|
|
|
|
const float base_tick_height = 16.0 * U.dpi_fac;
|
|
|
|
|
const float text_offset = 24.0 * U.dpi_fac;
|
|
|
|
|
const float overshoot_range_delta = 0.2;
|
|
|
|
|
int initial_tick_percentage;
|
|
|
|
|
int handle_pos_x;
|
|
|
|
|
float overshoot_length_delta;
|
|
|
|
|
|
|
|
|
|
if (pso->overshoot) {
|
|
|
|
|
initial_tick_percentage = (int)((pso->percentage - 0.5f - overshoot_range_delta) * 100);
|
|
|
|
|
handle_pos_x = pso->slider_start[0] + (SLIDE_PIXEL_DISTANCE / 2);
|
|
|
|
|
overshoot_length_delta = SLIDE_PIXEL_DISTANCE * overshoot_range_delta;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
initial_tick_percentage = 0;
|
|
|
|
|
handle_pos_x = pso->slider_start[0] + SLIDE_PIXEL_DISTANCE * pso->percentage;
|
|
|
|
|
overshoot_length_delta = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw main line. */
|
|
|
|
|
const struct rctf main_line_rect = {.xmin = pso->slider_start[0] - overshoot_length_delta,
|
|
|
|
|
.xmax = pso->slider_start[0] + SLIDE_PIXEL_DISTANCE +
|
|
|
|
|
overshoot_length_delta,
|
|
|
|
|
.ymin = pso->slider_start[1] - line_width / 2,
|
|
|
|
|
.ymax = pso->slider_start[1] + line_width / 2};
|
|
|
|
|
UI_draw_roundbox_3ub_alpha(&main_line_rect, true, 0, color_line, 255);
|
|
|
|
|
UI_draw_roundbox_3ub_alpha(&main_line_rect, false, 0, color_bg, 255);
|
|
|
|
|
|
|
|
|
|
/* Draw percentage ticks. */
|
|
|
|
|
const int tick_increment = 10;
|
|
|
|
|
const int percentage_range = pso->overshoot ? 100 + 100 * overshoot_range_delta * 2 : 100;
|
|
|
|
|
|
|
|
|
|
/* Round initial_tick_percentage up to the next tick_increment. */
|
|
|
|
|
int tick_percentage = ceil((float)initial_tick_percentage / tick_increment) * tick_increment;
|
|
|
|
|
|
|
|
|
|
for (; tick_percentage <= initial_tick_percentage + percentage_range;
|
|
|
|
|
tick_percentage += tick_increment) {
|
|
|
|
|
const float x = handle_pos_x +
|
|
|
|
|
SLIDE_PIXEL_DISTANCE * (((float)tick_percentage / 100) - pso->percentage);
|
|
|
|
|
/* 0.5 steps are considered main ticks and are drawn thicker with
|
|
|
|
|
* percentage indicator string below. */
|
|
|
|
|
const bool is_main_tick = tick_percentage % 50 == 0;
|
|
|
|
|
const float tick_height = is_main_tick ? base_tick_height : base_tick_height / 2;
|
|
|
|
|
|
|
|
|
|
const struct rctf tick_rect = {.xmin = x - (line_width / 2),
|
|
|
|
|
.xmax = x + (line_width / 2),
|
|
|
|
|
.ymin = pso->slider_start[1] - (tick_height / 2),
|
|
|
|
|
.ymax = pso->slider_start[1] + (tick_height / 2)};
|
|
|
|
|
|
|
|
|
|
UI_draw_roundbox_3ub_alpha(&tick_rect, true, 1, color_line, 255);
|
|
|
|
|
UI_draw_roundbox_3ub_alpha(&tick_rect, false, 1, color_bg, 255);
|
|
|
|
|
|
|
|
|
|
/* Draw percentage on main ticks. */
|
|
|
|
|
if (is_main_tick) {
|
|
|
|
|
BLI_snprintf(percentage_string, sizeof(percentage_string), "%d%%", tick_percentage);
|
|
|
|
|
draw_centered_string_with_background(
|
|
|
|
|
percentage_string, x, pso->slider_start[1] - text_offset, color_bg, fontid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw handle indicating current percentage. */
|
|
|
|
|
const struct rctf handle_rect = {.xmin = handle_pos_x - (line_width),
|
|
|
|
|
.xmax = handle_pos_x + (line_width),
|
|
|
|
|
.ymin = pso->slider_start[1] - (base_tick_height / 2),
|
|
|
|
|
.ymax = pso->slider_start[1] + (base_tick_height / 2)};
|
|
|
|
|
|
|
|
|
|
UI_draw_roundbox_3ub_alpha(&handle_rect, true, 1, color_handle, 255);
|
|
|
|
|
UI_draw_roundbox_3ub_alpha(&handle_rect, false, 1, color_bg, 255);
|
|
|
|
|
|
|
|
|
|
BLI_snprintf(percentage_string, sizeof(percentage_string), "%.0f%%", pso->percentage * 100);
|
|
|
|
|
draw_centered_string_with_background(
|
|
|
|
|
percentage_string, handle_pos_x, pso->slider_start[1] + text_offset, color_bg, fontid);
|
|
|
|
|
|
|
|
|
|
GPU_blend(GPU_BLEND_NONE);
|
|
|
|
|
immUnbindProgram();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* operator init */
|
|
|
|
|
static int pose_slide_init(bContext *C, wmOperator *op, ePoseSlide_Modes mode)
|
|
|
|
|
{
|
|
|
|
@@ -205,6 +375,7 @@ static int pose_slide_init(bContext *C, wmOperator *op, ePoseSlide_Modes mode)
|
|
|
|
|
|
|
|
|
|
/* set range info from property values - these may get overridden for the invoke() */
|
|
|
|
|
pso->percentage = RNA_float_get(op->ptr, "percentage");
|
|
|
|
|
pso->raw_percentage = pso->percentage;
|
|
|
|
|
pso->prevFrame = RNA_int_get(op->ptr, "prev_frame");
|
|
|
|
|
pso->nextFrame = RNA_int_get(op->ptr, "next_frame");
|
|
|
|
|
|
|
|
|
@@ -257,6 +428,10 @@ static int pose_slide_init(bContext *C, wmOperator *op, ePoseSlide_Modes mode)
|
|
|
|
|
pso->num.val_flag[0] |= NUM_NO_NEGATIVE;
|
|
|
|
|
pso->num.unit_type[0] = B_UNIT_NONE; /* percentages don't have any units... */
|
|
|
|
|
|
|
|
|
|
/* Register UI drawing callback. */
|
|
|
|
|
pso->draw_handle = ED_region_draw_cb_activate(
|
|
|
|
|
pso->region->type, pose_slide_draw_2d_slider, pso, REGION_DRAW_POST_PIXEL);
|
|
|
|
|
|
|
|
|
|
/* return status is whether we've got all the data we were requested to get */
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
@@ -266,6 +441,13 @@ static void pose_slide_exit(wmOperator *op)
|
|
|
|
|
{
|
|
|
|
|
tPoseSlideOp *pso = op->customdata;
|
|
|
|
|
|
|
|
|
|
/* Hide Bone Overlay. */
|
|
|
|
|
View3D *v3d = pso->area->spacedata.first;
|
|
|
|
|
v3d->overlay.flag = pso->overlay_flag;
|
|
|
|
|
|
|
|
|
|
/* Remove UI drawing callback. */
|
|
|
|
|
ED_region_draw_cb_exit(pso->region->type, pso->draw_handle);
|
|
|
|
|
|
|
|
|
|
/* if data exists, clear its data and exit */
|
|
|
|
|
if (pso) {
|
|
|
|
|
/* free the temp pchan links and their data */
|
|
|
|
@@ -602,7 +784,7 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
|
|
|
|
|
|
|
|
|
|
static void pose_slide_rest_pose_apply_vec3(tPoseSlideOp *pso, float vec[3], float default_value)
|
|
|
|
|
{
|
|
|
|
|
/* We only slide to the rest pose. So only use the default rest pose value */
|
|
|
|
|
/* We only slide to the rest pose. So only use the default rest pose value. */
|
|
|
|
|
const int lock = pso->axislock;
|
|
|
|
|
for (int idx = 0; idx < 3; idx++) {
|
|
|
|
|
if ((lock == 0) || ((lock & PS_LOCK_X) && (idx == 0)) || ((lock & PS_LOCK_Y) && (idx == 1)) ||
|
|
|
|
@@ -621,7 +803,7 @@ static void pose_slide_rest_pose_apply_vec3(tPoseSlideOp *pso, float vec[3], flo
|
|
|
|
|
|
|
|
|
|
static void pose_slide_rest_pose_apply_other_rot(tPoseSlideOp *pso, float vec[4], bool quat)
|
|
|
|
|
{
|
|
|
|
|
/* We only slide to the rest pose. So only use the default rest pose value */
|
|
|
|
|
/* We only slide to the rest pose. So only use the default rest pose value. */
|
|
|
|
|
float default_values[] = {1.0f, 0.0f, 0.0f, 0.0f};
|
|
|
|
|
if (!quat) {
|
|
|
|
|
/* Axis Angle */
|
|
|
|
@@ -789,14 +971,18 @@ static void pose_slide_reset(tPoseSlideOp *pso)
|
|
|
|
|
|
|
|
|
|
/* ------------------------------------ */
|
|
|
|
|
|
|
|
|
|
/* draw percentage indicator in header */
|
|
|
|
|
/* Draw percentage indicator in workspace footer. */
|
|
|
|
|
/* TODO: Include hints about locks here... */
|
|
|
|
|
static void pose_slide_draw_status(tPoseSlideOp *pso)
|
|
|
|
|
static void pose_slide_draw_status(bContext *C, tPoseSlideOp *pso)
|
|
|
|
|
{
|
|
|
|
|
char status_str[UI_MAX_DRAW_STR];
|
|
|
|
|
char limits_str[UI_MAX_DRAW_STR];
|
|
|
|
|
char axis_str[50];
|
|
|
|
|
char mode_str[32];
|
|
|
|
|
char overshoot_str[50];
|
|
|
|
|
char precision_str[50];
|
|
|
|
|
char increments_str[50];
|
|
|
|
|
char bone_vis_str[50];
|
|
|
|
|
|
|
|
|
|
switch (pso->mode) {
|
|
|
|
|
case POSESLIDE_PUSH:
|
|
|
|
@@ -871,25 +1057,51 @@ static void pose_slide_draw_status(tPoseSlideOp *pso)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pso->overshoot) {
|
|
|
|
|
BLI_strncpy(overshoot_str, TIP_("[E] - Disable overshoot"), sizeof(overshoot_str));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_strncpy(overshoot_str, TIP_("E - Enable overshoot"), sizeof(overshoot_str));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pso->precision) {
|
|
|
|
|
BLI_strncpy(precision_str, TIP_("[Shift] - Precision active"), sizeof(precision_str));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_strncpy(precision_str, TIP_("Shift - Hold for precision"), sizeof(precision_str));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pso->increments) {
|
|
|
|
|
BLI_strncpy(increments_str, TIP_("[Ctrl] - Increments active"), sizeof(increments_str));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_strncpy(increments_str, TIP_("Ctrl - Hold for 10% increments"), sizeof(increments_str));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_strncpy(bone_vis_str, TIP_("[H] - Toggle bone visibility"), sizeof(increments_str));
|
|
|
|
|
|
|
|
|
|
if (hasNumInput(&pso->num)) {
|
|
|
|
|
Scene *scene = pso->scene;
|
|
|
|
|
char str_ofs[NUM_STR_REP_LEN];
|
|
|
|
|
char str_offs[NUM_STR_REP_LEN];
|
|
|
|
|
|
|
|
|
|
outputNumInput(&pso->num, str_ofs, &scene->unit);
|
|
|
|
|
outputNumInput(&pso->num, str_offs, &scene->unit);
|
|
|
|
|
|
|
|
|
|
BLI_snprintf(
|
|
|
|
|
status_str, sizeof(status_str), "%s: %s | %s", mode_str, str_ofs, limits_str);
|
|
|
|
|
BLI_snprintf(status_str, sizeof(status_str), "%s: %s | %s", mode_str, str_offs, limits_str);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_snprintf(status_str,
|
|
|
|
|
sizeof(status_str),
|
|
|
|
|
"%s: %d %% | %s",
|
|
|
|
|
mode_str,
|
|
|
|
|
(int)(pso->percentage * 100.0f),
|
|
|
|
|
limits_str);
|
|
|
|
|
sizeof(status_str),
|
|
|
|
|
"%s: %d %% | %s | %s | %s | %s | %s",
|
|
|
|
|
mode_str,
|
|
|
|
|
(int)(pso->percentage * 100.0f),
|
|
|
|
|
limits_str,
|
|
|
|
|
overshoot_str,
|
|
|
|
|
precision_str,
|
|
|
|
|
increments_str,
|
|
|
|
|
bone_vis_str);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ED_area_status_text(pso->area, status_str);
|
|
|
|
|
ED_workspace_status_text(C, status_str);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* common code for invoke() methods */
|
|
|
|
@@ -975,24 +1187,74 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p
|
|
|
|
|
WM_cursor_modal_set(win, WM_CURSOR_EW_SCROLL);
|
|
|
|
|
|
|
|
|
|
/* header print */
|
|
|
|
|
pose_slide_draw_status(pso);
|
|
|
|
|
pose_slide_draw_status(C, pso);
|
|
|
|
|
|
|
|
|
|
/* add a modal handler for this operator */
|
|
|
|
|
WM_event_add_modal_handler(C, op);
|
|
|
|
|
|
|
|
|
|
/* Hide Bone Overlay. */
|
|
|
|
|
View3D *v3d = pso->area->spacedata.first;
|
|
|
|
|
pso->overlay_flag = v3d->overlay.flag;
|
|
|
|
|
v3d->overlay.flag |= V3D_OVERLAY_HIDE_BONES;
|
|
|
|
|
|
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* calculate percentage based on position of mouse (we only use x-axis for now.
|
|
|
|
|
* since this is more convenient for users to do), and store new percentage value
|
|
|
|
|
/* Calculate percentage based on mouse movement, clamp or round to increments if
|
|
|
|
|
* enabled by the user. Store the new percentage value.
|
|
|
|
|
*/
|
|
|
|
|
static void pose_slide_mouse_update_percentage(tPoseSlideOp *pso,
|
|
|
|
|
wmOperator *op,
|
|
|
|
|
const wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
pso->percentage = (event->x - pso->region->winrct.xmin) / ((float)pso->region->winx);
|
|
|
|
|
const float percentage_delta = (event->x - pso->last_cursor_x) / ((float)(SLIDE_PIXEL_DISTANCE));
|
|
|
|
|
/* Reduced percentage delta in precision mode (shift held). */
|
|
|
|
|
pso->raw_percentage += pso->precision ? (percentage_delta / 8) : percentage_delta;
|
|
|
|
|
pso->percentage = pso->raw_percentage;
|
|
|
|
|
pso->last_cursor_x = event->x;
|
|
|
|
|
/* Modulo mval so the value wraps properly in area space with the cursor. */
|
|
|
|
|
if (event->mval[0] > 0) {
|
|
|
|
|
pso->cursor_region_x = event->mval[0] % pso->region->winx;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
pso->cursor_region_x = (event->mval[0] % pso->region->winx) + pso->region->winx;
|
|
|
|
|
}
|
|
|
|
|
pso->cursor_region_y = event->mval[1];
|
|
|
|
|
|
|
|
|
|
if (!pso->overshoot) {
|
|
|
|
|
pso->percentage = clamp_f(pso->percentage, 0, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pso->increments) {
|
|
|
|
|
pso->percentage = round(pso->percentage * 10) / 10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RNA_float_set(op->ptr, "percentage", pso->percentage);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Calculate the starting percentage so that 0% or 100% will always be in the area. */
|
|
|
|
|
static void pose_slide_calculate_start_percentage(tPoseSlideOp *pso, const wmEvent *event)
|
|
|
|
|
{
|
|
|
|
|
pso->last_cursor_x = event->x;
|
|
|
|
|
/* A bit of padding to both sides so the text stays on screen. */
|
|
|
|
|
const int padding = 16 * U.dpi_fac;
|
|
|
|
|
|
|
|
|
|
/* Clamp it so 0% or 100% is always on screen. */
|
|
|
|
|
/* Catching edge case where slider doesn't fit in window. */
|
|
|
|
|
if (padding < pso->region->winx - SLIDE_PIXEL_DISTANCE - padding) {
|
|
|
|
|
pso->last_cursor_x = clamp_i(pso->last_cursor_x,
|
|
|
|
|
pso->region->winrct.xmin + padding + SLIDE_PIXEL_DISTANCE / 2,
|
|
|
|
|
pso->region->winrct.xmax - padding - SLIDE_PIXEL_DISTANCE / 2);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
pso->last_cursor_x = clamp_i(pso->last_cursor_x,
|
|
|
|
|
pso->region->winrct.xmin + padding + SLIDE_PIXEL_DISTANCE / 2,
|
|
|
|
|
INT_MAX);
|
|
|
|
|
}
|
|
|
|
|
pso->slider_start[0] = (pso->region->winx / 2) - (SLIDE_PIXEL_DISTANCE / 2);
|
|
|
|
|
pso->slider_start[1] = 64 * U.dpi_fac;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* handle an event to toggle channels mode */
|
|
|
|
|
static void pose_slide_toggle_channels_mode(wmOperator *op,
|
|
|
|
|
tPoseSlideOp *pso,
|
|
|
|
@@ -1056,9 +1318,12 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|
|
|
|
case EVT_PADENTER: {
|
|
|
|
|
if (event->val == KM_PRESS) {
|
|
|
|
|
/* return to normal cursor and header status */
|
|
|
|
|
ED_area_status_text(pso->area, NULL);
|
|
|
|
|
ED_workspace_status_text(C, NULL);
|
|
|
|
|
WM_cursor_modal_restore(win);
|
|
|
|
|
|
|
|
|
|
/* Depsgraph updates + redraws. Redraw needed to remove UI. */
|
|
|
|
|
pose_slide_refresh(C, pso);
|
|
|
|
|
|
|
|
|
|
/* insert keyframes as required... */
|
|
|
|
|
pose_slide_autoKeyframe(C, pso);
|
|
|
|
|
pose_slide_exit(op);
|
|
|
|
@@ -1073,13 +1338,13 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|
|
|
|
case RIGHTMOUSE: {
|
|
|
|
|
if (event->val == KM_PRESS) {
|
|
|
|
|
/* return to normal cursor and header status */
|
|
|
|
|
ED_area_status_text(pso->area, NULL);
|
|
|
|
|
ED_workspace_status_text(C, NULL);
|
|
|
|
|
WM_cursor_modal_restore(win);
|
|
|
|
|
|
|
|
|
|
/* reset transforms back to original state */
|
|
|
|
|
pose_slide_reset(pso);
|
|
|
|
|
|
|
|
|
|
/* depsgraph updates + redraws */
|
|
|
|
|
/* Depsgraph updates + redraws.*/
|
|
|
|
|
pose_slide_refresh(C, pso);
|
|
|
|
|
|
|
|
|
|
/* clean up temp data */
|
|
|
|
@@ -1178,10 +1443,58 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Overshoot. */
|
|
|
|
|
case EVT_EKEY: {
|
|
|
|
|
pso->overshoot = !pso->overshoot;
|
|
|
|
|
do_pose_update = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Precision mode. */
|
|
|
|
|
case EVT_LEFTSHIFTKEY:
|
|
|
|
|
case EVT_RIGHTSHIFTKEY: {
|
|
|
|
|
pso->precision = true;
|
|
|
|
|
do_pose_update = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Increments mode. */
|
|
|
|
|
case EVT_LEFTCTRLKEY:
|
|
|
|
|
case EVT_RIGHTCTRLKEY: {
|
|
|
|
|
pso->increments = true;
|
|
|
|
|
do_pose_update = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Toggle Bone visibility. */
|
|
|
|
|
case EVT_HKEY: {
|
|
|
|
|
View3D *v3d = pso->area->spacedata.first;
|
|
|
|
|
v3d->overlay.flag ^= V3D_OVERLAY_HIDE_BONES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default: /* Some other unhandled key... */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Precision and stepping only active while button is held. */
|
|
|
|
|
else if (event->val == KM_RELEASE) {
|
|
|
|
|
switch (event->type) {
|
|
|
|
|
case EVT_LEFTSHIFTKEY:
|
|
|
|
|
case EVT_RIGHTSHIFTKEY: {
|
|
|
|
|
pso->precision = false;
|
|
|
|
|
do_pose_update = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case EVT_LEFTCTRLKEY:
|
|
|
|
|
case EVT_RIGHTCTRLKEY: {
|
|
|
|
|
pso->increments = false;
|
|
|
|
|
do_pose_update = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
/* unhandled event - maybe it was some view manipulation? */
|
|
|
|
|
/* allow to pass through */
|
|
|
|
@@ -1193,8 +1506,10 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
|
|
|
|
/* Perform pose updates - in response to some user action
|
|
|
|
|
* (e.g. pressing a key or moving the mouse). */
|
|
|
|
|
if (do_pose_update) {
|
|
|
|
|
pose_slide_mouse_update_percentage(pso, op, event);
|
|
|
|
|
|
|
|
|
|
/* update percentage indicator in header */
|
|
|
|
|
pose_slide_draw_status(pso);
|
|
|
|
|
pose_slide_draw_status(C, pso);
|
|
|
|
|
|
|
|
|
|
/* reset transforms (to avoid accumulation errors) */
|
|
|
|
|
pose_slide_reset(pso);
|
|
|
|
@@ -1247,11 +1562,11 @@ static void pose_slide_opdef_properties(wmOperatorType *ot)
|
|
|
|
|
PropertyRNA *prop;
|
|
|
|
|
|
|
|
|
|
prop = RNA_def_float_factor(ot->srna,
|
|
|
|
|
"factor",
|
|
|
|
|
"percentage",
|
|
|
|
|
0.5f,
|
|
|
|
|
0.0f,
|
|
|
|
|
1.0f,
|
|
|
|
|
"Factor",
|
|
|
|
|
"Percentage",
|
|
|
|
|
"Weighting factor for which keyframe is favored more",
|
|
|
|
|
0.0,
|
|
|
|
|
1.0);
|
|
|
|
@@ -1310,6 +1625,8 @@ static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *ev
|
|
|
|
|
|
|
|
|
|
pso = op->customdata;
|
|
|
|
|
|
|
|
|
|
pose_slide_calculate_start_percentage(pso, event);
|
|
|
|
|
|
|
|
|
|
/* Initialize percentage so that it won't pop on first mouse move. */
|
|
|
|
|
pose_slide_mouse_update_percentage(pso, op, event);
|
|
|
|
|
|
|
|
|
@@ -1349,7 +1666,7 @@ void POSE_OT_push(wmOperatorType *ot)
|
|
|
|
|
ot->poll = ED_operator_posemode;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR_X;
|
|
|
|
|
|
|
|
|
|
/* Properties */
|
|
|
|
|
pose_slide_opdef_properties(ot);
|
|
|
|
@@ -1370,6 +1687,8 @@ static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *e
|
|
|
|
|
|
|
|
|
|
pso = op->customdata;
|
|
|
|
|
|
|
|
|
|
pose_slide_calculate_start_percentage(pso, event);
|
|
|
|
|
|
|
|
|
|
/* Initialize percentage so that it won't pop on first mouse move. */
|
|
|
|
|
pose_slide_mouse_update_percentage(pso, op, event);
|
|
|
|
|
|
|
|
|
@@ -1409,7 +1728,7 @@ void POSE_OT_relax(wmOperatorType *ot)
|
|
|
|
|
ot->poll = ED_operator_posemode;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR_X;
|
|
|
|
|
|
|
|
|
|
/* Properties */
|
|
|
|
|
pose_slide_opdef_properties(ot);
|
|
|
|
@@ -1429,6 +1748,8 @@ static int pose_slide_push_rest_invoke(bContext *C, wmOperator *op, const wmEven
|
|
|
|
|
|
|
|
|
|
pso = op->customdata;
|
|
|
|
|
|
|
|
|
|
pso->last_cursor_x = event->x;
|
|
|
|
|
|
|
|
|
|
/* Initialize percentage so that it won't pop on first mouse move. */
|
|
|
|
|
pose_slide_mouse_update_percentage(pso, op, event);
|
|
|
|
|
|
|
|
|
@@ -1468,7 +1789,7 @@ void POSE_OT_push_rest(wmOperatorType *ot)
|
|
|
|
|
ot->poll = ED_operator_posemode;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR_X;
|
|
|
|
|
|
|
|
|
|
/* Properties */
|
|
|
|
|
pose_slide_opdef_properties(ot);
|
|
|
|
@@ -1489,6 +1810,8 @@ static int pose_slide_relax_rest_invoke(bContext *C, wmOperator *op, const wmEve
|
|
|
|
|
|
|
|
|
|
pso = op->customdata;
|
|
|
|
|
|
|
|
|
|
pose_slide_calculate_start_percentage(pso, event);
|
|
|
|
|
|
|
|
|
|
/* Initialize percentage so that it won't pop on first mouse move. */
|
|
|
|
|
pose_slide_mouse_update_percentage(pso, op, event);
|
|
|
|
|
|
|
|
|
@@ -1528,7 +1851,7 @@ void POSE_OT_relax_rest(wmOperatorType *ot)
|
|
|
|
|
ot->poll = ED_operator_posemode;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR_X;
|
|
|
|
|
|
|
|
|
|
/* Properties */
|
|
|
|
|
pose_slide_opdef_properties(ot);
|
|
|
|
@@ -1549,6 +1872,8 @@ static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEven
|
|
|
|
|
|
|
|
|
|
pso = op->customdata;
|
|
|
|
|
|
|
|
|
|
pose_slide_calculate_start_percentage(pso, event);
|
|
|
|
|
|
|
|
|
|
/* Initialize percentage so that it won't pop on first mouse move. */
|
|
|
|
|
pose_slide_mouse_update_percentage(pso, op, event);
|
|
|
|
|
|
|
|
|
@@ -1588,7 +1913,7 @@ void POSE_OT_breakdown(wmOperatorType *ot)
|
|
|
|
|
ot->poll = ED_operator_posemode;
|
|
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
|
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR_X;
|
|
|
|
|
|
|
|
|
|
/* Properties */
|
|
|
|
|
pose_slide_opdef_properties(ot);
|
|
|
|
|