Index: source/blender/editors/include/ED_numinput.h =================================================================== --- source/blender/editors/include/ED_numinput.h (revision 45759) +++ source/blender/editors/include/ED_numinput.h (working copy) @@ -43,6 +43,8 @@ short flag; /* Different flags to indicate different behaviors */ char inv[3]; /* If the value is inverted or not */ float val[3]; /* Direct value of the input */ + float lterm[3]; /* Value of the left-hand term (used for math operations) */ + float rterm[3]; /* Value of the right-hand term (used for math operations) */ int ctrl[3]; /* Control to indicate what to do with the numbers that are typed */ float increment; } NumInput; @@ -53,7 +55,11 @@ #define NUM_NO_ZERO 8 #define NUM_NO_FRACTION 16 #define NUM_AFFECT_ALL 32 - +#define NUM_OP_PLUS 64 +#define NUM_OP_MIN 128 +#define NUM_OP_DIV 256 +#define NUM_OP_MUL 512 +#define NUM_OP_POW 1024 /*********************** NumInput ********************************/ void initNumInput(NumInput *n); Index: source/blender/editors/util/numinput.c =================================================================== --- source/blender/editors/util/numinput.c (revision 45759) +++ source/blender/editors/util/numinput.c (working copy) @@ -30,7 +30,7 @@ */ -#include /* fabs */ +#include /* fabs, pow */ #include /* for size_t */ #include "BLI_utildefines.h" @@ -66,6 +66,7 @@ char cur; char inv[] = "1/"; short i, j; + int nlen = n->ctrl[i]; for (j = 0; j <= n->idx_max; j++) { /* if AFFECTALL and no number typed and cursor not on number, use first number */ @@ -86,8 +87,28 @@ if (n->val[i] > 1e10f || n->val[i] < -1e10f) BLI_snprintf(&str[j * 20], 20, "%s%.4e%c", inv, n->val[i], cur); - else - switch (n->ctrl[i]) { + else { + if (((n->flag & NUM_OP_PLUS) || (n->flag & NUM_OP_MIN) || (n->flag & NUM_OP_MUL) || + (n->flag & NUM_OP_DIV) || (n->flag & NUM_OP_POW)) && fmod((n->val[i]), 1.0f) != 0) + { + char vbuf[7]; + short k; + sprintf(vbuf, "%.4f", fmod((ABS(n->val[i])), 1.0f)); + //printf("%s\n", vbuf); //0.5000 + if (vbuf[5] != '0') + nlen = 100000; + else { + for (k = 4; k > 1; k--) { + if (vbuf[k] != '0') { + //printf("%c\n", vbuf[k]); + nlen = pow(10, k); + break; + } + } + } + + } + switch (nlen) { case 0: BLI_snprintf(&str[j * 20], 20, "%sNONE%c", inv, cur); break; @@ -114,6 +135,7 @@ default: BLI_snprintf(&str[j * 20], 20, "%s%.4e%c", inv, n->val[i], cur); } + } } } @@ -159,6 +181,31 @@ } } +void clearOpFlags(NumInput *n) +{ + short idx = n->idx; + + n->lterm[0] = n->val[0]; + n->lterm[1] = n->val[1]; + n->lterm[2] = n->val[2]; + n->rterm[0] = + n->rterm[1] = + n->rterm[2] = 0.0f; + if (n->ctrl[idx] != 0) + n->ctrl[idx] = n->ctrl[idx] > 0 ? 1 : -1; + + if (n->flag & NUM_OP_PLUS) + n->flag ^= NUM_OP_PLUS; + else if (n->flag & NUM_OP_MIN) + n->flag ^= NUM_OP_MIN; + else if (n->flag & NUM_OP_MUL) + n->flag ^= NUM_OP_MUL; + else if (n->flag & NUM_OP_DIV) + n->flag ^= NUM_OP_DIV; + else if (n->flag & NUM_OP_POW) + n->flag ^= NUM_OP_POW; +} + char handleNumInput(NumInput *n, wmEvent *event) { float Val = 0; @@ -189,6 +236,12 @@ n->val[0] = n->val[1] = n->val[2] = 0.0f; + n->lterm[0] = + n->lterm[1] = + n->lterm[2] = 0.0f; + n->rterm[0] = + n->rterm[1] = + n->rterm[2] = 0.0f; n->ctrl[0] = n->ctrl[1] = n->ctrl[2] = 0; @@ -198,9 +251,12 @@ } else { n->val[idx] = 0.0f; + n->lterm[idx] = 0.0f; + n->rterm[idx] = 0.0f; n->ctrl[idx] = 0; n->inv[idx] = 0; } + clearOpFlags(n); break; case PERIODKEY: case PADPERIOD: @@ -217,26 +273,47 @@ n->ctrl[idx] = -10; } break; + case PADPLUSKEY: + n->flag |= NUM_OP_PLUS; + break; + case EQUALKEY: + if (event->shift) + clearOpFlags(n); + n->flag |= NUM_OP_PLUS; + break; case PADMINUS: if (event->alt) break; case MINUSKEY: - if (n->flag & NUM_NO_NEGATIVE) - break; + if(event->shift) { + if (n->flag & NUM_NO_NEGATIVE) + break; - if (n->ctrl[idx]) { - n->ctrl[idx] *= -1; - n->val[idx] *= -1; - } - else - n->ctrl[idx] = -1; + if (n->ctrl[idx]) { + n->ctrl[idx] *= -1; + n->val[idx] *= -1; + n->lterm[idx] *= -1; + n->rterm[idx] *= -1; + } + else + n->ctrl[idx] = -1; + } + else { + clearOpFlags(n); + n->flag |= NUM_OP_MIN; + } break; case PADSLASHKEY: case SLASHKEY: - if (n->flag & NUM_NO_FRACTION) - return 0; - - n->inv[idx] = !n->inv[idx]; + if(event->shift) { + if (n->flag & NUM_NO_FRACTION) + return 0; + n->inv[idx] = !n->inv[idx]; + } + else { + clearOpFlags(n); + n->flag |= NUM_OP_DIV; + } break; case TABKEY: if (idx_max == 0) @@ -249,30 +326,54 @@ break; case PAD9: case NINEKEY: - Val += 1.0f; + if (event->shift) + break; + Val += 1.0f; case PAD8: case EIGHTKEY: + if (event->shift) { + clearOpFlags(n); + n->flag |= NUM_OP_MUL; + break; + } Val += 1.0f; case PAD7: case SEVENKEY: + if (event->shift) + break; Val += 1.0f; case PAD6: case SIXKEY: + if (event->shift) { + clearOpFlags(n); + n->flag |= NUM_OP_POW; + break; + } Val += 1.0f; case PAD5: case FIVEKEY: + if (event->shift) + break; Val += 1.0f; case PAD4: case FOURKEY: + if (event->shift) + break; Val += 1.0f; case PAD3: case THREEKEY: + if (event->shift) + break; Val += 1.0f; case PAD2: case TWOKEY: + if (event->shift) + break; Val += 1.0f; case PAD1: case ONEKEY: + if (event->shift) + break; Val += 1.0f; case PAD0: case ZEROKEY: @@ -280,18 +381,80 @@ n->ctrl[idx] = 1; if (fabsf(n->val[idx]) > 9999999.0f) ; - else if (n->ctrl[idx] == 1) { - n->val[idx] *= 10; - n->val[idx] += Val; + else if (ABS(n->ctrl[idx]) == 1) { + if (n->flag & NUM_OP_PLUS) { + n->rterm[idx] *= 10; + n->rterm[idx] += Val; + n->val[idx] = n->lterm[idx] + n->rterm[idx]; + } + else if (n->flag & NUM_OP_MIN) { + n->rterm[idx] *= 10; + n->rterm[idx] += Val; + n->val[idx] = n->lterm[idx] - n->rterm[idx]; + } + else if (n->flag & NUM_OP_MUL) { + n->rterm[idx] *= 10; + n->rterm[idx] += Val; + n->val[idx] = n->lterm[idx] * n->rterm[idx]; + } + else if (n->flag & NUM_OP_DIV) { + n->rterm[idx] *= 10; + n->rterm[idx] += Val; + n->val[idx] = n->lterm[idx] / n->rterm[idx]; + } + else if (n->flag & NUM_OP_POW) { + n->rterm[idx] *= 10; + n->rterm[idx] += Val; + n->val[idx] = pow(n->lterm[idx], n->rterm[idx]); + } + else { + n->val[idx] *= 10; + if (n->ctrl[idx] > 0) + n->val[idx] += Val; + else + n->val[idx] -= Val; + } + if (n->flag & NUM_NO_NEGATIVE) + CLAMP(n->val[idx], 0, 9999999); + + if (n->flag & NUM_NO_FRACTION) + round(n->val[idx]); } - else if (n->ctrl[idx] == -1) { - n->val[idx] *= 10; - n->val[idx] -= Val; - } else { /* float resolution breaks when over six digits after comma */ if (ABS(n->ctrl[idx]) < 10000000) { - n->val[idx] += Val / (float)n->ctrl[idx]; + if (n->flag & NUM_OP_PLUS) { + n->rterm[idx] += Val / fabs((float)n->ctrl[idx]); + n->val[idx] = n->lterm[idx] + n->rterm[idx]; + } + else if (n->flag & NUM_OP_MIN) { + n->rterm[idx] += Val / fabs((float)n->ctrl[idx]); + n->val[idx] = n->lterm[idx] - n->rterm[idx]; + } + else if (n->flag & NUM_OP_MUL) { + n->rterm[idx] += Val / fabs((float)n->ctrl[idx]); + n->val[idx] = n->lterm[idx] * n->rterm[idx]; + } + else if (n->flag & NUM_OP_DIV) { + n->rterm[idx] += Val / fabs((float)n->ctrl[idx]); + n->val[idx] = n->lterm[idx] / n->rterm[idx]; + } + else if (n->flag & NUM_OP_POW) { + n->rterm[idx] += Val / fabs((float)n->ctrl[idx]); + n->val[idx] = pow(n->lterm[idx], n->rterm[idx]); + } + else { + if (n->ctrl[idx] > 0) + n->val[idx] += Val / fabs((float)n->ctrl[idx]); + else + n->val[idx] -= Val / fabs((float)n->ctrl[idx]); + } + if (n->flag & NUM_NO_NEGATIVE) + CLAMP(n->val[idx], 0, 9999999); + + if (n->flag & NUM_NO_FRACTION) + round(n->val[idx]); + n->ctrl[idx] *= 10; } }