Commit: d5c9b509ec0e06318186f25212ffb2ba12177692
Author: Bastien Montagne
Date:   Wed Jan 8 17:04:10 2014 +0100
https://developer.blender.org/rBd5c9b509ec0e06318186f25212ffb2ba12177692

Fix issues with float precision in numinput, like 'R 123' who would show 
additional 'noise' digits.

Expose float precision helper in UI_interface.h API, so that numinput can use 
this helper as numbuttons already do.

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D186

===================================================================

M       source/blender/editors/include/UI_interface.h
M       source/blender/editors/interface/interface.c
M       source/blender/editors/interface/interface_utils.c
M       source/blender/editors/util/numinput.c

===================================================================

diff --git a/source/blender/editors/include/UI_interface.h 
b/source/blender/editors/include/UI_interface.h
index 735e7f3..10a4b38 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -941,4 +941,9 @@ void UI_template_fix_linking(void);
 bool UI_editsource_enable_check(void);
 void UI_editsource_active_but_test(uiBut *but);
 
+/* Float precision helpers */
+#define UI_PRECISION_FLOAT_MAX 7
+
+int uiFloatPrecisionCalc(int prec, double value);
+
 #endif  /* __UI_INTERFACE_H__ */
diff --git a/source/blender/editors/interface/interface.c 
b/source/blender/editors/interface/interface.c
index e6e1752..2492456 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -78,9 +78,6 @@
 
 #include "interface_intern.h"
 
-#define PRECISION_FLOAT_MAX 7
-#define PRECISION_FLOAT_MAX_POW 10000000 /* pow(10, PRECISION_FLOAT_MAX)  */
-
 /* avoid unneeded calls to ui_get_but_val */
 #define UI_BUT_VALUE_UNSET DBL_MAX
 #define UI_GET_BUT_VALUE_INIT(_but, _value) if (_value == DBL_MAX) {  (_value) 
= ui_get_but_val(_but); } (void)0
@@ -432,67 +429,21 @@ void uiExplicitBoundsBlock(uiBlock *block, int minx, int 
miny, int maxx, int max
        block->bounds_type = UI_BLOCK_BOUNDS_NONE;
 }
 
-/* ************** LINK LINE DRAWING  ************* */
-
-/* link line drawing is not part of buttons or theme.. so we stick with it 
here */
-
 static int ui_but_float_precision(uiBut *but, double value)
 {
        int prec;
-       const double pow10_neg[PRECISION_FLOAT_MAX + 1] = {1.0, 0.1, 0.01, 
0.001, 0.0001, 0.00001, 0.000001, 0.0000001};
 
        /* first check if prec is 0 and fallback to a simple default */
        if ((prec = (int)but->a2) == -1) {
                prec = (but->hardmax < 10.001f) ? 3 : 2;
        }
 
-       BLI_assert(prec <= PRECISION_FLOAT_MAX);
-       BLI_assert(pow10_neg[prec] == pow(10, -prec));
-
-       /* check on the number of decimal places need to display
-        * the number, this is so 0.00001 is not displayed as 0.00,
-        * _but_, this is only for small values si 10.0001 will not get
-        * the same treatment */
-       value = ABS(value);
-       if ((value < pow10_neg[prec]) &&
-           (value > (1.0 / PRECISION_FLOAT_MAX_POW)))
-       {
-               int value_i = (int)((value * PRECISION_FLOAT_MAX_POW) + 0.5);
-               if (value_i != 0) {
-                       const int prec_span = 3; /* show: 0.01001, 5 would 
allow 0.0100001 for eg. */
-                       int test_prec;
-                       int prec_min = -1;
-                       int dec_flag = 0;
-                       int i = PRECISION_FLOAT_MAX;
-                       while (i && value_i) {
-                               if (value_i % 10) {
-                                       dec_flag |= 1 << i;
-                                       prec_min = i;
-                               }
-                               value_i /= 10;
-                               i--;
-                       }
-
-                       /* even though its a small value, if the second last 
digit is not 0, use it */
-                       test_prec = prec_min;
-
-                       dec_flag = (dec_flag >> (prec_min + 1)) & ((1 << 
prec_span) - 1);
-
-                       while (dec_flag) {
-                               test_prec++;
-                               dec_flag = dec_flag >> 1;
-                       }
-
-                       if (test_prec > prec) {
-                               prec = test_prec;
-                       }
-               }
-       }
+       return uiFloatPrecisionCalc(prec, value);
+}
 
-       CLAMP(prec, 0, PRECISION_FLOAT_MAX);
+/* ************** LINK LINE DRAWING  ************* */
 
-       return prec;
-}
+/* link line drawing is not part of buttons or theme.. so we stick with it 
here */
 
 static void ui_draw_linkline(uiLinkLine *line, int highlightActiveLines)
 {
@@ -1803,7 +1754,7 @@ static void ui_get_but_string_unit(uiBut *but, char *str, 
int len_max, double va
        if (float_precision == -1) {
                /* Sanity checks */
                precision = (int)but->a2;
-               if      (precision > PRECISION_FLOAT_MAX) precision = 
PRECISION_FLOAT_MAX;
+               if      (precision > UI_PRECISION_FLOAT_MAX) precision = 
UI_PRECISION_FLOAT_MAX;
                else if (precision == -1)                 precision = 2;
        }
        else {
diff --git a/source/blender/editors/interface/interface_utils.c 
b/source/blender/editors/interface/interface_utils.c
index e1f39b1..812eb93 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -36,6 +36,7 @@
 #include "DNA_object_types.h"
 
 #include "BLI_utildefines.h"
+#include "BLI_math.h"
 #include "BLI_string.h"
 
 #include "BLF_translation.h"
@@ -224,3 +225,58 @@ int uiIconFromID(ID *id)
 
        return (ptr.type) ? RNA_struct_ui_icon(ptr.type) : ICON_NONE;
 }
+
+/********************************** Misc 
**************************************/
+
+/**
+ * Returns the best "UI" precision for given floating value, so that e.g. 
10.000001 rather gets drawn as '10'...
+ */
+int uiFloatPrecisionCalc(int prec, double value)
+{
+       static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {1e0, 1e-1, 
1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7};
+       static const double max_pow = 10000000.0;  /* pow(10, 
UI_PRECISION_FLOAT_MAX) */
+
+       BLI_assert(prec <= UI_PRECISION_FLOAT_MAX);
+       BLI_assert(pow10_neg[prec] == pow(10, -prec));
+
+       /* check on the number of decimal places need to display the number, 
this is so 0.00001 is not displayed as 0.00,
+        * _but_, this is only for small values si 10.0001 will not get the 
same treatment.
+        */
+       value = ABS(value);
+       if ((value < pow10_neg[prec]) && (value > (1.0 / max_pow))) {
+               int value_i = (int)((value * max_pow) + 0.5);
+               if (value_i != 0) {
+                       const int prec_span = 3; /* show: 0.01001, 5 would 
allow 0.0100001 for eg. */
+                       int test_prec;
+                       int prec_min = -1;
+                       int dec_flag = 0;
+                       int i = UI_PRECISION_FLOAT_MAX;
+                       while (i && value_i) {
+                               if (value_i % 10) {
+                                       dec_flag |= 1 << i;
+                                       prec_min = i;
+                               }
+                               value_i /= 10;
+                               i--;
+                       }
+
+                       /* even though its a small value, if the second last 
digit is not 0, use it */
+                       test_prec = prec_min;
+
+                       dec_flag = (dec_flag >> (prec_min + 1)) & ((1 << 
prec_span) - 1);
+
+                       while (dec_flag) {
+                               test_prec++;
+                               dec_flag = dec_flag >> 1;
+                       }
+
+                       if (test_prec > prec) {
+                               prec = test_prec;
+                       }
+               }
+       }
+
+       CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
+
+       return prec;
+}
diff --git a/source/blender/editors/util/numinput.c 
b/source/blender/editors/util/numinput.c
index 2828973..b9459d5 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -45,6 +45,7 @@
 #endif
 
 #include "ED_numinput.h"
+#include "UI_interface.h"
 
 
 /* NumInput.val_flag[] */
@@ -80,13 +81,15 @@ void outputNumInput(NumInput *n, char *str)
 {
        short i, j;
        const int ln = NUM_STR_REP_LEN;
-       const int prec = 4; /* draw-only, and avoids too much issues with 
radian->degrees conversion. */
+       int prec = 2; /* draw-only, and avoids too much issues with 
radian->degrees conversion. */
 
        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;
 
                if (n->val_flag[i] & NUM_EDITED) {
+                       /* Get the best precision, allows us to draw '10.0001' 
as '10' instead! */
+                       prec = uiFloatPrecisionCalc(prec, (double)n->val[i]);
                        if (i == n->idx) {
                                const char *heading_exp = "", *trailing_exp = 
"";
                                char before_cursor[NUM_STR_REP_LEN];

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to