Refactor: Allow to explicitly set the range on the slider UI element #107406

Merged
Christoph Lendenfeld merged 5 commits from ChrisLend/blender:slider_overshoot_refactor into main 2023-05-05 17:22:46 +02:00
4 changed files with 47 additions and 42 deletions

View File

@ -117,7 +117,8 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, PoseBlendData *pbd)
AnimData *adt = BKE_animdata_from_id(&pbd->ob->id);
if (adt != NULL && adt->action != NULL &&
!BKE_id_is_editable(CTX_data_main(C), &adt->action->id)) {
!BKE_id_is_editable(CTX_data_main(C), &adt->action->id))
{
/* Changes to linked-in Actions are not allowed. */
return;
}
@ -366,9 +367,9 @@ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent *
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, true);
ED_slider_allow_overshoot_set(pbd->slider, true, true);
ED_slider_allow_increments_set(pbd->slider, false);
ED_slider_is_bidirectional_set(pbd->slider, true);
ED_slider_factor_bounds_set(pbd->slider, -1, 1);
}
if (pbd->release_confirm_info.use_release_confirm) {

View File

@ -94,15 +94,17 @@ void ED_slider_status_string_get(const struct tSlider *slider,
float ED_slider_factor_get(struct tSlider *slider);
void ED_slider_factor_set(struct tSlider *slider, float factor);
bool ED_slider_allow_overshoot_get(struct tSlider *slider);
void ED_slider_allow_overshoot_set(struct tSlider *slider, bool value);
/* One bool value for each side of the slider. Allows to enable overshoot only on one side. */
void ED_slider_allow_overshoot_set(struct tSlider *slider, bool lower, bool upper);
/**

I think a comment here would be in order, something like:

/**
 * Set the bounds for the slider, which are applied until the user enables overshooting.
 */
void ED_slider_factor_bounds_set(struct tSlider *slider, float lower_bound, float upper_bound);

Just to make it clear what the relation between 'bounds' and 'overshoot' is.

I think a comment here would be in order, something like: ``` /** * Set the bounds for the slider, which are applied until the user enables overshooting. */ void ED_slider_factor_bounds_set(struct tSlider *slider, float lower_bound, float upper_bound); ``` Just to make it clear what the relation between 'bounds' and 'overshoot' is.
* Set the soft limits for the slider, which are applied until the user enables overshooting.
*/
void ED_slider_factor_bounds_set(struct tSlider *slider, float lower_bound, float upper_bound);
bool ED_slider_allow_increments_get(struct tSlider *slider);
void ED_slider_allow_increments_set(struct tSlider *slider, bool value);
bool ED_slider_is_bidirectional_get(struct tSlider *slider);
void ED_slider_is_bidirectional_set(struct tSlider *slider, bool value);
/* ************** XXX OLD CRUFT WARNING ************* */
/**

View File

@ -469,7 +469,7 @@ static int decimate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
tGraphSliderOp *gso = op->customdata;
gso->factor_prop = RNA_struct_find_property(op->ptr, "factor");
gso->modal_update = decimate_modal_update;
ED_slider_allow_overshoot_set(gso->slider, false);
ED_slider_allow_overshoot_set(gso->slider, false, false);
return invoke_result;
}
@ -1091,7 +1091,7 @@ static int gaussian_smooth_invoke(bContext *C, wmOperator *op, const wmEvent *ev
gaussian_smooth_allocate_operator_data(gso, filter_width, sigma);
gso->free_operator_data = gaussian_smooth_free_operator_data;
ED_slider_allow_overshoot_set(gso->slider, false);
ED_slider_allow_overshoot_set(gso->slider, false, false);
ED_slider_factor_set(gso->slider, 0.0f);
common_draw_status_header(C, gso, "Gaussian Smooth");

View File

@ -69,23 +69,22 @@ typedef struct tSlider {
/** Accumulative factor (not clamped or rounded). */
float raw_factor;
/** 0-1 value for determining the influence of whatever is relevant. */
/** Current value for determining the influence of whatever is relevant. */
float factor;
/** Last mouse cursor position used for mouse movement delta calculation. */
float last_cursor[2];
/** Allow negative values as well.
* This is set by the code that uses the slider, as not all operations support
* negative values. */
bool is_bidirectional;
/** Range of the slider without overshoot. */
float factor_bounds[2];
/** Enable range beyond 0-100%.
/** Enable range beyond factor_bounds.
* This is set by the code that uses the slider, as not all operations support
* extrapolation. */
bool allow_overshoot;
bool allow_overshoot_lower;
bool allow_overshoot_upper;
/** Allow overshoot or clamp between 0% and 100%.
/** Allow overshoot or clamp between factor_bounds.
* This is set by the artist while using the slider. */
bool overshoot;
@ -296,11 +295,11 @@ static void slider_draw(const struct bContext *UNUSED(C), ARegion *region, void
line_start_factor = slider->factor - 0.5f - OVERSHOOT_RANGE_DELTA;
handle_pos_x = region->winx / 2;
}
else if (slider->is_bidirectional) {
handle_pos_x = main_line_rect.xmin + SLIDE_PIXEL_DISTANCE * (slider->factor / 2 + 0.5f);
}
else {
handle_pos_x = main_line_rect.xmin + SLIDE_PIXEL_DISTANCE * slider->factor;
const float total_range = slider->factor_bounds[1] - slider->factor_bounds[0];
/* 0-1 value of the representing the position of the slider in the allowed range. */
const float range_factor = (slider->factor - slider->factor_bounds[0]) / total_range;
handle_pos_x = main_line_rect.xmin + SLIDE_PIXEL_DISTANCE * range_factor;
}
draw_backdrop(fontid, &main_line_rect, color_bg, slider->region_header->winy, base_tick_height);
@ -365,10 +364,15 @@ static void slider_update_factor(tSlider *slider, const wmEvent *event)
copy_v2fl_v2i(slider->last_cursor, event->xy);
if (!slider->overshoot) {
slider->factor = clamp_f(slider->factor, -1, 1);
slider->factor = clamp_f(slider->factor, slider->factor_bounds[0], slider->factor_bounds[1]);
}
if (!slider->is_bidirectional) {
slider->factor = max_ff(slider->factor, 0);
else {
if (!slider->allow_overshoot_lower) {
slider->factor = max_ff(slider->factor, slider->factor_bounds[0]);
}
if (!slider->allow_overshoot_upper) {
slider->factor = min_ff(slider->factor, slider->factor_bounds[1]);
}
}
if (slider->increments) {
@ -384,9 +388,13 @@ tSlider *ED_slider_create(struct bContext *C)
slider->region_header = CTX_wm_region(C);
/* Default is true, caller needs to manually set to false. */
slider->allow_overshoot = true;
slider->allow_overshoot_lower = true;
slider->allow_overshoot_upper = true;
slider->allow_increments = true;
slider->factor_bounds[0] = 0;
slider->factor_bounds[1] = 1;
/* Set initial factor. */
slider->raw_factor = 0.5f;
slider->factor = 0.5;
@ -419,7 +427,7 @@ bool ED_slider_modal(tSlider *slider, const wmEvent *event)
/* Handle key presses. */
switch (event->type) {
case EVT_EKEY:
if (slider->allow_overshoot) {
if (slider->allow_overshoot_lower || slider->allow_overshoot_upper) {
slider->overshoot = event->val == KM_PRESS ? !slider->overshoot : slider->overshoot;
slider_update_factor(slider, event);
}
@ -455,7 +463,7 @@ void ED_slider_status_string_get(const struct tSlider *slider,
char precision_str[50];
char increments_str[50];
if (slider->allow_overshoot) {
if (slider->allow_overshoot_lower || slider->allow_overshoot_upper) {
if (slider->overshoot) {
STRNCPY(overshoot_str, TIP_("[E] - Disable overshoot"));
}
@ -521,14 +529,10 @@ void ED_slider_factor_set(struct tSlider *slider, const float factor)
}
}
bool ED_slider_allow_overshoot_get(struct tSlider *slider)
void ED_slider_allow_overshoot_set(struct tSlider *slider, const bool lower, const bool upper)
{
return slider->allow_overshoot;
}
void ED_slider_allow_overshoot_set(struct tSlider *slider, const bool value)
{
slider->allow_overshoot = value;
slider->allow_overshoot_lower = lower;
slider->allow_overshoot_upper = upper;
}
bool ED_slider_allow_increments_get(struct tSlider *slider)
@ -541,14 +545,12 @@ void ED_slider_allow_increments_set(struct tSlider *slider, const bool value)
slider->allow_increments = value;
}
bool ED_slider_is_bidirectional_get(struct tSlider *slider)
void ED_slider_factor_bounds_set(struct tSlider *slider,
float factor_bound_lower,
float factor_bound_upper)
{
return slider->is_bidirectional;
}
void ED_slider_is_bidirectional_set(struct tSlider *slider, const bool value)
{
slider->is_bidirectional = value;
slider->factor_bounds[0] = factor_bound_lower;
slider->factor_bounds[1] = factor_bound_upper;
}
/** \} */