Asset Browser: Add slider UI to pose blending
Add the Slider UI to pose blending. This adds a slider with percentages, and controls for precision control and incremental control. Reviewed By: sybren Maniphest Tasks: T90182 Differential Revision: https://developer.blender.org/D14984
This commit is contained in:
parent
2356afc7af
commit
2522ca03d2
Notes:
blender-bot
2025-02-14 01:26:00 +00:00
Referenced by issue #90182, Slider Widget for blending poses
@ -41,6 +41,7 @@
|
||||
#include "ED_asset.h"
|
||||
#include "ED_keyframing.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_util.h"
|
||||
|
||||
#include "armature_intern.h"
|
||||
|
||||
@ -58,10 +59,8 @@ typedef struct PoseBlendData {
|
||||
|
||||
struct {
|
||||
bool use_release_confirm;
|
||||
int drag_start_xy[2];
|
||||
int init_event_type;
|
||||
|
||||
bool cursor_wrap_enabled;
|
||||
} release_confirm_info;
|
||||
|
||||
/* For temp-loading the Action from the pose library. */
|
||||
@ -78,6 +77,8 @@ typedef struct PoseBlendData {
|
||||
Scene *scene; /* For auto-keying. */
|
||||
ScrArea *area; /* For drawing status text. */
|
||||
|
||||
struct tSlider *slider; /* Slider UI and event handling. */
|
||||
|
||||
/** Info-text to print in header. */
|
||||
char headerstr[UI_MAX_DRAW_STR];
|
||||
} PoseBlendData;
|
||||
@ -146,22 +147,6 @@ static void poselib_blend_apply(bContext *C, wmOperator *op)
|
||||
{
|
||||
PoseBlendData *pbd = (PoseBlendData *)op->customdata;
|
||||
|
||||
if (pbd->state == POSE_BLEND_BLENDING) {
|
||||
BLI_snprintf(pbd->headerstr,
|
||||
sizeof(pbd->headerstr),
|
||||
TIP_("PoseLib blending: \"%s\" at %3.0f%%"),
|
||||
pbd->act->id.name + 2,
|
||||
pbd->blend_factor * 100);
|
||||
ED_area_status_text(pbd->area, pbd->headerstr);
|
||||
|
||||
ED_workspace_status_text(
|
||||
C, TIP_("Tab: show original pose; Horizontal mouse movement: change blend percentage"));
|
||||
}
|
||||
else {
|
||||
ED_area_status_text(pbd->area, TIP_("PoseLib showing original pose"));
|
||||
ED_workspace_status_text(C, TIP_("Tab: show blended pose"));
|
||||
}
|
||||
|
||||
if (!pbd->needs_redraw) {
|
||||
return;
|
||||
}
|
||||
@ -192,27 +177,16 @@ static void poselib_blend_set_factor(PoseBlendData *pbd, const float new_factor)
|
||||
pbd->needs_redraw = true;
|
||||
}
|
||||
|
||||
static void poselib_slide_mouse_update_blendfactor(PoseBlendData *pbd, const wmEvent *event)
|
||||
{
|
||||
if (pbd->release_confirm_info.use_release_confirm) {
|
||||
/* Release confirm calculates factor based on where the dragging was started from. */
|
||||
const float range = 300 * U.pixelsize;
|
||||
const float new_factor = (event->xy[0] - pbd->release_confirm_info.drag_start_xy[0]) / range;
|
||||
poselib_blend_set_factor(pbd, new_factor);
|
||||
}
|
||||
else {
|
||||
const float new_factor = (event->xy[0] - pbd->area->v1->vec.x) / ((float)pbd->area->winx);
|
||||
poselib_blend_set_factor(pbd, new_factor);
|
||||
}
|
||||
}
|
||||
|
||||
/* Return operator return value. */
|
||||
static int poselib_blend_handle_event(bContext *UNUSED(C), wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
PoseBlendData *pbd = op->customdata;
|
||||
|
||||
ED_slider_modal(pbd->slider, event);
|
||||
const float factor = ED_slider_factor_get(pbd->slider);
|
||||
poselib_blend_set_factor(pbd, factor);
|
||||
|
||||
if (event->type == MOUSEMOVE) {
|
||||
poselib_slide_mouse_update_blendfactor(pbd, event);
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
@ -257,18 +231,6 @@ static int poselib_blend_handle_event(bContext *UNUSED(C), wmOperator *op, const
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static void poselib_blend_cursor_update(bContext *C, wmOperator *op)
|
||||
{
|
||||
PoseBlendData *pbd = op->customdata;
|
||||
|
||||
/* Ensure cursor-grab (continuous grabbing) is enabled when using release-confirm. */
|
||||
if (pbd->release_confirm_info.use_release_confirm &&
|
||||
!pbd->release_confirm_info.cursor_wrap_enabled) {
|
||||
WM_cursor_grab_enable(CTX_wm_window(C), WM_CURSOR_WRAP_XY, true, NULL);
|
||||
pbd->release_confirm_info.cursor_wrap_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------- */
|
||||
|
||||
static Object *get_poselib_object(bContext *C)
|
||||
@ -363,11 +325,14 @@ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent *
|
||||
pbd->release_confirm_info.use_release_confirm = (release_confirm_prop != NULL) &&
|
||||
RNA_property_boolean_get(op->ptr,
|
||||
release_confirm_prop);
|
||||
pbd->slider = ED_slider_create(C);
|
||||
ED_slider_init(pbd->slider, event);
|
||||
ED_slider_factor_set(pbd->slider, pbd->blend_factor);
|
||||
ED_slider_allow_overshoot_set(pbd->slider, false);
|
||||
}
|
||||
|
||||
if (pbd->release_confirm_info.use_release_confirm) {
|
||||
BLI_assert(event != NULL);
|
||||
copy_v2_v2_int(pbd->release_confirm_info.drag_start_xy, event->xy);
|
||||
pbd->release_confirm_info.init_event_type = WM_userdef_event_type_from_keymap_type(
|
||||
event->type);
|
||||
}
|
||||
@ -391,6 +356,10 @@ static void poselib_blend_cleanup(bContext *C, wmOperator *op)
|
||||
ED_area_status_text(pbd->area, NULL);
|
||||
ED_workspace_status_text(C, NULL);
|
||||
|
||||
if (pbd->slider) {
|
||||
ED_slider_destroy(C, pbd->slider);
|
||||
}
|
||||
|
||||
/* This signals the depsgraph to unlock and reevaluate the pose on the next evaluation. */
|
||||
bPose *pose = pbd->ob->pose;
|
||||
pose->flag |= POSE_DO_UNLOCK;
|
||||
@ -417,11 +386,6 @@ static void poselib_blend_cleanup(bContext *C, wmOperator *op)
|
||||
break;
|
||||
}
|
||||
|
||||
if (pbd->release_confirm_info.cursor_wrap_enabled) {
|
||||
WM_cursor_grab_disable(win, pbd->release_confirm_info.drag_start_xy);
|
||||
pbd->release_confirm_info.cursor_wrap_enabled = false;
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&pbd->ob->id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pbd->ob);
|
||||
/* Update mouse-hover highlights. */
|
||||
@ -442,9 +406,6 @@ static void poselib_blend_free(wmOperator *op)
|
||||
}
|
||||
poselib_tempload_exit(pbd);
|
||||
|
||||
/* Must have been dealt with before! */
|
||||
BLI_assert(pbd->release_confirm_info.cursor_wrap_enabled == false);
|
||||
|
||||
/* Free temp data for operator */
|
||||
ED_pose_backup_free(pbd->pose_backup);
|
||||
pbd->pose_backup = NULL;
|
||||
@ -460,6 +421,9 @@ static int poselib_blend_exit(bContext *C, wmOperator *op)
|
||||
poselib_blend_cleanup(C, op);
|
||||
poselib_blend_free(op);
|
||||
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
WM_cursor_modal_restore(win);
|
||||
|
||||
if (exit_state == POSE_BLEND_CANCEL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
@ -479,14 +443,28 @@ static int poselib_blend_modal(bContext *C, wmOperator *op, const wmEvent *event
|
||||
{
|
||||
const int operator_result = poselib_blend_handle_event(C, op, event);
|
||||
|
||||
poselib_blend_cursor_update(C, op);
|
||||
|
||||
const PoseBlendData *pbd = op->customdata;
|
||||
if (ELEM(pbd->state, POSE_BLEND_CONFIRM, POSE_BLEND_CANCEL)) {
|
||||
return poselib_blend_exit(C, op);
|
||||
}
|
||||
|
||||
if (pbd->needs_redraw) {
|
||||
char status_string[UI_MAX_DRAW_STR];
|
||||
char slider_string[UI_MAX_DRAW_STR];
|
||||
char tab_string[50];
|
||||
|
||||
ED_slider_status_string_get(pbd->slider, slider_string, sizeof(slider_string));
|
||||
|
||||
if (pbd->state == POSE_BLEND_BLENDING) {
|
||||
strcpy(tab_string, TIP_("[Tab] - Show original pose"));
|
||||
}
|
||||
else {
|
||||
strcpy(tab_string, TIP_("[Tab] - Show blended pose"));
|
||||
}
|
||||
|
||||
BLI_snprintf(status_string, sizeof(status_string), "%s | %s", tab_string, slider_string);
|
||||
ED_workspace_status_text(C, status_string);
|
||||
|
||||
poselib_blend_apply(C, op);
|
||||
}
|
||||
|
||||
@ -501,6 +479,9 @@ static int poselib_blend_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
WM_cursor_modal_set(win, WM_CURSOR_EW_SCROLL);
|
||||
|
||||
/* Do initial apply to have something to look at. */
|
||||
poselib_blend_apply(C, op);
|
||||
|
||||
@ -594,7 +575,7 @@ void POSELIB_OT_blend_pose_asset(wmOperatorType *ot)
|
||||
ot->poll = poselib_blend_poll;
|
||||
|
||||
/* Flags: */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR_X;
|
||||
|
||||
/* Properties: */
|
||||
prop = RNA_def_float_factor(ot->srna,
|
||||
|
@ -484,6 +484,7 @@ float ED_slider_factor_get(struct tSlider *slider)
|
||||
|
||||
void ED_slider_factor_set(struct tSlider *slider, const float factor)
|
||||
{
|
||||
slider->raw_factor = factor;
|
||||
slider->factor = factor;
|
||||
if (!slider->overshoot) {
|
||||
slider->factor = clamp_f(slider->factor, 0, 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user