UI: New option to display factors as percentages
authorJacques Lucke <mail@jlucke.com>
Wed, 13 Mar 2019 15:58:00 +0000 (16:58 +0100)
committerJacques Lucke <mail@jlucke.com>
Wed, 13 Mar 2019 15:58:00 +0000 (16:58 +0100)
The option can be changed in the Preferences
in `Interface -> Editors -> Factor Display Type`.

Reviewers: campbellbarton, brecht, billreynish

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

release/scripts/startup/bl_ui/space_userpref.py
source/blender/editors/interface/interface.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/rna_userdef.c

index c11a802c90fe5756f92b045577b89268faf6e389..f1870b638a894aacf4fe938f327e2a617bb01ddd 100644 (file)
@@ -215,6 +215,7 @@ class USERPREF_PT_interface_editors(PreferencePanel, Panel):
         flow.prop(view, "show_layout_ui", text="Corner Splitting")
         flow.prop(view, "color_picker_type")
         flow.row().prop(view, "header_align")
+        flow.prop(view, "factor_display_type")
 
 
 class USERPREF_PT_interface_menus(Panel):
index 840c68ec7477c4231fbfa407a130f912985f1ba2..f783c4a6906da2cccd9b9c441ceb363ab6915c06 100644 (file)
@@ -2425,12 +2425,27 @@ void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int
 
                value = ui_but_value_get(but);
 
+               PropertySubType subtype = PROP_NONE;
+               if (but->rnaprop) {
+                       subtype = RNA_property_subtype(but->rnaprop);
+               }
+
                if (ui_but_is_float(but)) {
+                       int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) : float_precision;
+
                        if (ui_but_is_unit(but)) {
-                               ui_get_but_string_unit(but, str, maxlen, value, false, float_precision);
+                               ui_get_but_string_unit(but, str, maxlen, value, false, prec);
+                       }
+                       else if (subtype == PROP_FACTOR) {
+                               if (U.factor_display_type == USER_FACTOR_AS_FACTOR) {
+                                       BLI_snprintf(str, maxlen, "%.*f", prec, value);
+                               }
+                               else {
+                                       BLI_snprintf(str, maxlen, "%.*f", MAX2(0, prec - 2), value * 100);
+                               }
+
                        }
                        else {
-                               int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) : float_precision;
                                if (use_exp_float) {
                                        const int int_digits_num = integer_digits_f(value);
                                        if (int_digits_num < -6 || int_digits_num > 12) {
@@ -2528,44 +2543,80 @@ static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char
        return user_string_to_number(C, str, unit, type, r_value);
 }
 
-bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *r_value)
+static bool ui_number_from_string(bContext *C, const char *str, double *r_value)
 {
-       bool ok = false;
-
 #ifdef WITH_PYTHON
+       return BPY_execute_string_as_number(C, NULL, str, true, r_value);
+#else
+       *r_value = atof(str);
+       return true;
+#endif
+}
 
-       if (str[0] != '\0') {
-               bool is_unit_but = (ui_but_is_float(but) && ui_but_is_unit(but));
-               /* only enable verbose if we won't run again with units */
-               if (BPY_execute_string_as_number(C, NULL, str, is_unit_but == false, r_value)) {
-                       /* if the value parsed ok without unit conversion
-                        * this button may still need a unit multiplier */
-                       if (is_unit_but) {
-                               char str_new[128];
-
-                               BLI_snprintf(str_new, sizeof(str_new), "%f", *r_value);
-                               ok = ui_set_but_string_eval_num_unit(C, but, str_new, r_value);
-                       }
-                       else {
-                               ok = true; /* parse normal string via py (no unit conversion needed) */
-                       }
+static bool ui_number_from_string_factor(bContext *C, const char *str, double *r_value)
+{
+       int len = strlen(str);
+       if (BLI_strn_endswith(str, "%", len)) {
+               char *str_new = BLI_strdupn(str, len - 1);
+               bool success = ui_number_from_string(C, str_new, r_value);
+               MEM_freeN(str_new);
+               *r_value /= 100.0;
+               return success;
+       }
+       else {
+               if (!ui_number_from_string(C, str, r_value)) {
+                       return false;
                }
-               else if (is_unit_but) {
-                       /* parse failed, this is a unit but so run replacements and parse again */
-                       ok = ui_set_but_string_eval_num_unit(C, but, str, r_value);
+               if (U.factor_display_type == USER_FACTOR_AS_PERCENTAGE) {
+                       *r_value /= 100.0;
                }
+               return true;
        }
+}
 
-#else /* WITH_PYTHON */
-
-       *r_value = atof(str);
-       ok = true;
+static bool ui_number_from_string_percentage(bContext *C, const char *str, double *r_value)
+{
+       int len = strlen(str);
+       if (BLI_strn_endswith(str, "%", len)) {
+               char *str_new = BLI_strdupn(str, len - 1);
+               bool success = ui_number_from_string(C, str_new, r_value);
+               MEM_freeN(str_new);
+               return success;
+       }
+       else {
+               return ui_number_from_string(C, str, r_value);
+       }
+}
 
-       UNUSED_VARS(C, but);
+bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *r_value)
+{
+       if (str[0] == '\0') {
+               *r_value = 0.0;
+               return true;
+       }
 
-#endif /* WITH_PYTHON */
+       PropertySubType subtype = PROP_NONE;
+       if (but->rnaprop) {
+               subtype = RNA_property_subtype(but->rnaprop);
+       }
 
-       return ok;
+       if (ui_but_is_float(but)) {
+               if (ui_but_is_unit(but)) {
+                       return ui_set_but_string_eval_num_unit(C, but, str, r_value);
+               }
+               else if (subtype == PROP_FACTOR) {
+                       return ui_number_from_string_factor(C, str, r_value);
+               }
+               else if (subtype == PROP_PERCENTAGE) {
+                       return ui_number_from_string_percentage(C, str, r_value);
+               }
+               else {
+                       return ui_number_from_string(C, str, r_value);
+               }
+       }
+       else {
+               return ui_number_from_string(C, str, r_value);
+       }
 }
 
 /* just the assignment/free part */
@@ -3094,6 +3145,16 @@ static void ui_but_build_drawstr_float(uiBut *but, double value)
                int prec = ui_but_calc_float_precision(but, value);
                STR_CONCATF(but->drawstr, slen, "%.*f px", prec, value);
        }
+       else if (subtype == PROP_FACTOR) {
+               int precision = ui_but_calc_float_precision(but, value);
+
+               if (U.factor_display_type == USER_FACTOR_AS_FACTOR) {
+                       STR_CONCATF(but->drawstr, slen, "%.*f", precision, value);
+               }
+               else {
+                       STR_CONCATF(but->drawstr, slen, "%.*f %%", MAX2(0, precision - 2), value * 100);
+               }
+       }
        else if (ui_but_is_unit(but)) {
                char new_str[sizeof(but->drawstr)];
                ui_get_but_string_unit(but, new_str, sizeof(new_str), value, true, -1);
index 048b7e60d57478824ea0fe547bf787d7d85066e6..461bfb79f912d199f67dcb41d7e90402f7ad1b0c 100644 (file)
@@ -757,7 +757,9 @@ typedef struct UserDef {
        /** #eMultiSample_Type, amount of samples for Grease Pencil. */
        short gpencil_multisamples;
 
-       char _pad5[4];
+       char factor_display_type;
+
+       char _pad5[3];
 } UserDef;
 
 /* from blenkernel blender.c */
@@ -1111,6 +1113,12 @@ typedef enum eOpensubdiv_Computee_Type {
        USER_OPENSUBDIV_COMPUTE_GLSL_COMPUTE = 6,
 } eOpensubdiv_Computee_Type;
 
+/** #UserDef.factor_display_type */
+typedef enum eUserpref_FactorDisplay {
+       USER_FACTOR_AS_FACTOR = 0,
+       USER_FACTOR_AS_PERCENTAGE = 1,
+} eUserpref_FactorDisplay;
+
 #ifdef __cplusplus
 }
 #endif
index dda36d89eb1c2c4ea779972041f7053cefe3d23e..197a53a897286cec5ec903cfdff36f68adeaff23 100644 (file)
@@ -3775,6 +3775,17 @@ static void rna_def_userdef_view(BlenderRNA *brna)
                                 "Show the frames per second screen refresh rate, while animation is played back");
        RNA_def_property_update(prop, 0, "rna_userdef_update");
 
+       static const EnumPropertyItem factor_display_items[] = {
+               {USER_FACTOR_AS_FACTOR, "FACTOR", 0, "Factor", "Display factors as values between 0 and 1"},
+               {USER_FACTOR_AS_PERCENTAGE, "PERCENTAGE", 0, "Percentage", "Display factors as percentages"},
+               {0, NULL, 0, NULL, NULL},
+       };
+
+       prop = RNA_def_property(srna, "factor_display_type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, factor_display_items);
+       RNA_def_property_ui_text(prop, "Factor Display Type", "How factor values are displayed");
+       RNA_def_property_update(prop, 0, "rna_userdef_update");
+
        /* Weight Paint */
 
        prop = RNA_def_property(srna, "use_weight_color_range", PROP_BOOLEAN, PROP_NONE);