diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h index 9d8c2ae99ac..e7b52a49e8c 100644 --- a/source/blender/editors/include/ED_numinput.h +++ b/source/blender/editors/include/ED_numinput.h @@ -66,10 +66,19 @@ enum { /*********************** NumInput ********************************/ +/* There are important things to note here for code using numinput: + * * Values passed to applyNumInput() should be valid and are stored as default ones (val_org), if it is not EDITED. + * * bool returned by applyNumInput should be used to decide whether to apply numinput-specific post-process to data. + * * *Once applyNumInput has been called*, hasNumInput returns a valid value to decide whether to use numinput + * as drawstr source or not (i.e. to call outputNumInput). + * + * Those two steps have to be separated (so do not use a common call to hasNumInput() to do both in the same time!). + */ + void initNumInput(NumInput *n); void outputNumInput(NumInput *n, char *str); bool hasNumInput(const NumInput *n); -void applyNumInput(NumInput *n, float *vec); +bool applyNumInput(NumInput *n, float *vec); bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event); #define NUM_MODAL_INCREMENT_UP 18 diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index d3af2d0d1d9..e1c240f72d0 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2845,20 +2845,20 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2])) values.scale /= snap_hack; } #endif - + + if (applyNumInput(&t->num, values.vector)) { + values.scale = values.scale / data->warp_init_dist; + } + /* header print for NumInput */ if (hasNumInput(&t->num)) { char c[NUM_STR_REP_LEN * 2]; - - applyNumInput(&t->num, values.vector); outputNumInput(&(t->num), c); BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bend Angle: %s Radius: %s Alt, Clamp %s"), &c[0], &c[NUM_STR_REP_LEN], WM_bool_as_string(is_clamp)); - - values.scale = values.scale / data->warp_init_dist; } else { /* default header print */ @@ -3312,8 +3312,7 @@ static void applyResize(TransInfo *t, const int mval[2]) snapGridIncrement(t, size); - if (hasNumInput(&t->num)) { - applyNumInput(&t->num, size); + if (applyNumInput(&t->num, size)) { constraintNumInput(t, size); } @@ -3422,8 +3421,7 @@ static void applySkinResize(TransInfo *t, const int UNUSED(mval[2])) snapGridIncrement(t, size); - if (hasNumInput(&t->num)) { - applyNumInput(&t->num, size); + if (applyNumInput(&t->num, size)) { constraintNumInput(t, size); } @@ -3884,17 +3882,17 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2])) applySnapping(t, &final); + if (applyNumInput(&t->num, &final)) { + /* Clamp between -PI and PI */ + final = angle_wrap_rad(final); + } + if (hasNumInput(&t->num)) { char c[NUM_STR_REP_LEN]; - applyNumInput(&t->num, &final); - outputNumInput(&(t->num), c); ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext); - - /* Clamp between -PI and PI */ - final = angle_wrap_rad(final); } else { ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Rot: %.2f%s %s"), @@ -3991,11 +3989,11 @@ static void applyTrackball(TransInfo *t, const int UNUSED(mval[2])) snapGridIncrement(t, phi); + applyNumInput(&t->num, phi); + if (hasNumInput(&t->num)) { char c[NUM_STR_REP_LEN * 2]; - applyNumInput(&t->num, phi); - outputNumInput(&(t->num), c); ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Trackball: %s %s %s"), @@ -4250,7 +4248,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) if (t->con.mode & CON_APPLY) { float pvec[3] = {0.0f, 0.0f, 0.0f}; float tvec[3]; - if (hasNumInput(&t->num)) { + if (applyNumInput(&t->num, t->values)) { removeAspectRatio(t, t->values); } applySnapping(t, t->values); @@ -4260,8 +4258,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) } else { snapGridIncrement(t, t->values); - applyNumInput(&t->num, t->values); - if (hasNumInput(&t->num)) { + if (applyNumInput(&t->num, t->values)) { removeAspectRatio(t, t->values); } applySnapping(t, t->values); @@ -4431,11 +4428,11 @@ static void applyTilt(TransInfo *t, const int UNUSED(mval[2])) snapGridIncrement(t, &final); + applyNumInput(&t->num, &final); + if (hasNumInput(&t->num)) { char c[NUM_STR_REP_LEN]; - applyNumInput(&t->num, &final); - outputNumInput(&(t->num), c); BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Tilt: %s° %s"), &c[0], t->proptext); @@ -4986,8 +4983,7 @@ static void applyBoneSize(TransInfo *t, const int mval[2]) snapGridIncrement(t, size); - if (hasNumInput(&t->num)) { - applyNumInput(&t->num, size); + if (applyNumInput(&t->num, size)) { constraintNumInput(t, size); } @@ -6191,11 +6187,11 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) /* only do this so out of range values are not displayed */ CLAMP(final, -1.0f, 1.0f); + applyNumInput(&t->num, &final); + if (hasNumInput(&t->num)) { char c[NUM_STR_REP_LEN]; - applyNumInput(&t->num, &final); - outputNumInput(&(t->num), c); if (is_proportional) { @@ -6713,11 +6709,12 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2])) CLAMP(final, 0.0f, 1.0f); } + applyNumInput(&t->num, &final); + /* header string */ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Vert Slide: "), MAX_INFO_LEN - ofs); if (hasNumInput(&t->num)) { char c[NUM_STR_REP_LEN]; - applyNumInput(&t->num, &final); outputNumInput(&(t->num), c); ofs += BLI_strncpy_rlen(str + ofs, &c[0], MAX_INFO_LEN - ofs); } @@ -6780,11 +6777,11 @@ static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2])) snapGridIncrement(t, &final); + applyNumInput(&t->num, &final); + if (hasNumInput(&t->num)) { char c[NUM_STR_REP_LEN]; - applyNumInput(&t->num, &final); - outputNumInput(&(t->num), c); BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Roll: %s"), &c[0]); diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 24f51635e07..56ef2bb6e4e 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -148,8 +148,7 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) vec[2] = 1.0f; } - if (hasNumInput(&t->num)) { - applyNumInput(&t->num, vec); + if (applyNumInput(&t->num, vec)) { constraintNumInput(t, vec); removeAspectRatio(t, vec); } diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c index 4c097ca7da6..850f1d1c5cc 100644 --- a/source/blender/editors/util/numinput.c +++ b/source/blender/editors/util/numinput.c @@ -52,6 +52,7 @@ enum { /* (1 << 8) and below are reserved for public flags! */ NUM_EDIT_FULL = (1 << 9), /* Enable full editing, with units and math operators support. */ + NUM_FAKE_EDITED = (1 << 10), /* Fake edited state (temp, avoids issue with backspace). */ }; /* NumInput.val_flag[] */ @@ -148,6 +149,10 @@ bool hasNumInput(const NumInput *n) { short i; + if (n->flag & NUM_FAKE_EDITED) { + return true; + } + for (i = 0; i <= n->idx_max; i++) { if (n->val_flag[i] & NUM_EDITED) { return true; @@ -160,31 +165,45 @@ bool hasNumInput(const NumInput *n) /** * \warning \a vec must be set beforehand otherwise we risk uninitialized vars. */ -void applyNumInput(NumInput *n, float *vec) +bool applyNumInput(NumInput *n, float *vec) { short i, j; float val; if (hasNumInput(n)) { for (j = 0; j <= n->idx_max; j++) { - /* if AFFECTALL and no number typed and cursor not on number, use first number */ - i = (n->flag & NUM_AFFECT_ALL && n->idx != j && !(n->val_flag[j] & NUM_EDITED)) ? 0 : j; - val = (!(n->val_flag[i] & NUM_EDITED) && n->val_flag[i] & NUM_NULL_ONE) ? 1.0f : n->val[i]; + if (n->flag & NUM_FAKE_EDITED) { + val = n->val[j]; + } + else { + /* if AFFECTALL and no number typed and cursor not on number, use first number */ + i = (n->flag & NUM_AFFECT_ALL && n->idx != j && !(n->val_flag[j] & NUM_EDITED)) ? 0 : j; + val = (!(n->val_flag[i] & NUM_EDITED) && n->val_flag[i] & NUM_NULL_ONE) ? 1.0f : n->val[i]; - if (n->val_flag[i] & NUM_NO_NEGATIVE && val < 0.0f) { - val = 0.0f; - } - if (n->val_flag[i] & NUM_NO_ZERO && val == 0.0f) { - val = 0.0001f; - } - if (n->val_flag[i] & NUM_NO_FRACTION && val != floorf(val)) { - val = floorf(val + 0.5f); + if (n->val_flag[i] & NUM_NO_NEGATIVE && val < 0.0f) { + val = 0.0f; + } if (n->val_flag[i] & NUM_NO_ZERO && val == 0.0f) { - val = 1.0f; + val = 0.0001f; + } + if (n->val_flag[i] & NUM_NO_FRACTION && val != floorf(val)) { + val = floorf(val + 0.5f); + if (n->val_flag[i] & NUM_NO_ZERO && val == 0.0f) { + val = 1.0f; + } } } vec[j] = val; } + n->flag &= ~NUM_FAKE_EDITED; + return true; + } + else { + /* Else, we set the 'org' values for numinput! */ + for (j = 0; j <= n->idx_max; j++) { + n->val[j] = n->val_org[j] = vec[j]; + } + return false; } } @@ -257,6 +276,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) n->val_flag[0] &= ~NUM_EDITED; n->val_flag[1] &= ~NUM_EDITED; n->val_flag[2] &= ~NUM_EDITED; + n->flag |= NUM_FAKE_EDITED; updated = true; break; } @@ -286,6 +306,9 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) memmove(&n->str[cur], &n->str[t_cur], strlen(&n->str[t_cur]) + 1); /* +1 for trailing '\0'. */ updated = true; } + if (!n->str[0]) { + n->val[idx] = n->val_org[idx]; + } } else { return false; @@ -318,12 +341,10 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event) } return false; case TABKEY: - n->val_org[idx] = n->val[idx]; n->val_flag[idx] &= ~(NUM_NEGATE | NUM_INVERSE); idx = (idx + idx_max + (event->ctrl ? 0 : 2)) % (idx_max + 1); n->idx = idx; - n->val[idx] = n->val_org[idx]; if (n->val_flag[idx] & NUM_EDITED) { value_to_editstr(n, idx); }