added time units, currently only used when metric or imperial are enabled.
authorCampbell Barton <ideasman42@gmail.com>
Wed, 12 Aug 2009 05:20:16 +0000 (05:20 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 12 Aug 2009 05:20:16 +0000 (05:20 +0000)
long/short units...
day,d,  hour,hr,h,  minute,min,m, second,sec,s,  millisecond,ms,  microsecond,us

Also may fix some bugs that were reported.

Note, to convert fps to time evil_C needs to be used to get the scene.

release/ui/space_info.py
source/blender/blenkernel/intern/unit.c
source/blender/editors/interface/interface.c
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/RNA_types.h
source/blender/makesrna/intern/rna_userdef.c

index 9ebbc68c2190168d4289b940c766c1b5fc31fa53..fde443f50f6149a40203fbfa3a768fe5b9379051 100644 (file)
@@ -325,10 +325,10 @@ class INFO_PT_edit(bpy.types.Panel):
                sub1.itemS()
                
                sub1.itemL(text="Units:")
-               sub1.itemR(edit, "unit_type")
+               sub1.itemR(edit, "unit_system")
                
                sub2 = sub1.column()
-               sub2.active = (edit.unit_type != 'NONE')
+               sub2.active = (edit.unit_system != 'NONE')
                sub2.itemR(edit, "unit_scale_length")
                sub2.itemR(edit, "use_unit_split")
 
index 87a21cc97983e3269d65703e2b048a96195d1835..646b62b2d09e1b7967307ca55165ef729878b773 100644 (file)
 /* define a single unit */
 typedef struct bUnitDef {
        char *name;
-
-       /* optional, can be null */
-       char *name_plural;
+       char *name_plural;      /* can be NULL */
        char *name_short;       /* this is used for display*/
-       char *name_alt;         /* alternative name */
+       char *name_alt;         /* can be NULL */
        
        double mul;
        double bias;            /* not used yet, needed for converting temperature */
@@ -43,13 +41,22 @@ typedef struct bUnitDef {
 /* define a single unit */
 typedef struct bUnitCollection {
        struct bUnitDef *units;
-       int def;                                        /* default unit, use for 0.0, or none given */
+       int base_unit;                          /* use for 0.0, or none given */
        int flag;                                       /* options for this system */
 } bUnitCollection;
 
+/* Dummy */
+static struct bUnitDef buDummyDef[] = {
+       {"", NULL, "", NULL,    1.0, 0.0},
+       {NULL, NULL, NULL,      NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buDummyCollecton = {buDummyDef, 0, 0};
+
+
+/* Lengths */
 static struct bUnitDef buMetricLenDef[] = {
        {"kilometer", "kilometers",             "km", NULL,     1000.0, 0.0},
-       {"meter", "meters",                             "m",  NULL,     1.0, 0.0},
+       {"meter", "meters",                             "m",  NULL,     1.0, 0.0}, /* base unit */
        {"centimeter", "centimeters",   "cm", NULL,     0.01, 0.0},
        {"millimeter", "millimeters",   "mm", NULL,     0.001, 0.0},
        {"micrometer", "micrometers",   "um", "┬Ám",    0.000001, 0.0}, // micron too?
@@ -59,27 +66,41 @@ static struct bUnitDef buMetricLenDef[] = {
 };
 static struct bUnitCollection buMetricLenCollecton = {buMetricLenDef, 1, 0};
 
-#define IMPERIAL_DEFAULT 3 /* inch */
 static struct bUnitDef buImperialLenDef[] = {
        {"mile", "miles",                               "mi", "m",      1609.344, 0.0},
        {"yard", "yards",                               "yd", NULL,     0.9144, 0.0},
        {"foot", "feet",                                "'", "ft",      0.3048, 0.0},
-       {"inch", "inches",                              "\"", "in",     0.0254, 0.0},
+       {"inch", "inches",                              "\"", "in",     0.0254, 0.0}, /* base unit */
        {"thou", "thous",                               "mil", NULL,0.0000254, 0.0},
        {NULL, NULL, NULL, NULL, 0.0, 0.0}
 };
 static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 2, 0};
 
+
+/* Time */
+static struct bUnitDef buNaturalTimeDef[] = {
+       /* weeks? - probably not needed for blender */
+       {"day", "days",                                 "d", NULL,      90000.0, 0.0},
+       {"hour", "hours",                               "hr", "h",      3600.0, 0.0},
+       {"minute", "minutes",                   "min", "m",     60.0, 0.0},
+       {"second", "seconds",                   "sec", "s",     1.0, 0.0}, /* base unit */
+       {"millisecond", "milliseconds", "ms", NULL,     0.001, 0.0},
+       {"microsecond", "microseconds", "us", NULL,     0.000001, 0.0},
+       {NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buNaturalTimeCollecton = {buNaturalTimeDef, 3, 0};
+
 static struct bUnitCollection *bUnitSystems[][8] = {
-       {0,&buMetricLenCollecton, 0,0,0,0,0,0}, /* metric */
-       {0,&buImperialLenCollecton, 0,0,0,0,0,0}, /* imperial */
+       {0,0,0,0,0,0,0,0},
+       {0,&buMetricLenCollecton, 0,0,0,0, &buNaturalTimeCollecton,0}, /* metric */
+       {0,&buImperialLenCollecton, 0,0,0,0, &buNaturalTimeCollecton,0}, /* imperial */
        {0,0,0,0,0,0,0,0}
 };
 
 /* internal, has some option not exposed */
 static bUnitCollection *unit_get_system(int system, int type)
 {
-       return bUnitSystems[system-1][type];
+       return bUnitSystems[system][type]; /* select system to use, metric/imperial/other? */
 }
 
 static bUnitDef *unit_best_fit(double value, bUnitCollection *usys, bUnitDef *unit_start)
@@ -91,7 +112,7 @@ static bUnitDef *unit_best_fit(double value, bUnitCollection *usys, bUnitDef *un
                if (value_abs >= unit->mul)
                        return unit;
 
-       return &usys->units[usys->def];
+       return &usys->units[usys->base_unit];
 }
 
 /* convert into 2 units and 2 values for "2ft, 3inch" syntax */
@@ -119,7 +140,7 @@ static int unit_as_string(char *str, double value, int prec, bUnitCollection *us
        }
        else if(value == 0.0) {
                /* use the default units since there is no way to convert */
-               unit= &usys->units[usys->def];
+               unit= &usys->units[usys->base_unit];
        }
        else {
                unit= unit_best_fit(value, usys, NULL);
@@ -181,6 +202,9 @@ void bUnit_AsString(char *str, double value, int prec, int system, int type, int
 {
        bUnitCollection *usys = unit_get_system(system, type);
 
+       if(usys==NULL || usys->units[0].name==NULL)
+               usys= &buDummyCollecton;
+
        if(split) {
                int i;
                bUnitDef *unit_a, *unit_b;
@@ -209,7 +233,10 @@ static int unit_scale_str(char *str, char *str_tmp, double scale_pref, bUnitDef
        char *str_found;
        int change= 0;
 
-       if(replace_str && (str_found= strstr(str, replace_str))) {
+       if(replace_str==NULL || replace_str[0] == '\0')
+               return 0;
+
+       if((str_found= strstr(str, replace_str))) {
                /* previous char cannot be a letter */
                if (str_found == str || isalpha(*(str_found-1))==0) {
                        int len_name = strlen(replace_str);
@@ -255,6 +282,9 @@ int bUnit_ReplaceString(char *str, char *str_orig, double scale_pref, int system
        char str_tmp[256];
        int change= 0;
        
+       if(usys==NULL || usys->units[0].name==NULL)
+               return 0;
+
        strcpy(str, str_orig);
        
        for(unit= usys->units; unit->name; unit++) {
@@ -262,6 +292,6 @@ int bUnit_ReplaceString(char *str, char *str_orig, double scale_pref, int system
                while(unit_replace(str, str_tmp, scale_pref, unit))
                        change= 1;
        }
-
+       // printf("replace %s\n", str);
        return change;
 }
index 26984e954e16efa09231425954d55883307bc228..f3d181c560a36487135152afa9694354e4462151 100644 (file)
@@ -1308,6 +1308,36 @@ int ui_get_but_string_max_length(uiBut *but)
                return UI_MAX_DRAW_STR;
 }
 
+static double ui_get_but_scale_unit(uiBut *but, double value)
+{
+       int subtype= RNA_property_subtype(but->rnaprop);
+
+       if(subtype & PROP_UNIT_LENGTH) {
+               return value * U.unit_scale_length;
+       }
+       else if(subtype & PROP_UNIT_TIME) { /* WARNING - using evil_C :| */
+               Scene *scene= CTX_data_scene((bContext *)but->block->evil_C);
+               return FRA2TIME(value);
+       }
+       else {
+               return value;
+       }
+}
+
+static void ui_get_but_string_unit(uiBut *but, char *str, double value, int pad)
+{
+       int do_split= U.unit_flag & USER_UNIT_OPT_SPLIT ? 1:0;
+       int unit_system=  RNA_SUBTYPE_UNIT_VALUE(RNA_property_subtype(but->rnaprop));
+       int precission= but->a2;
+
+       /* Sanity checks */
+       if(precission>4)                precission= 4;
+       else if(precission==0)  precission= 2;
+
+       bUnit_AsString(str, ui_get_but_scale_unit(but, value), precission, U.unit_system, unit_system, do_split, pad);
+}
+
+
 void ui_get_but_string(uiBut *but, char *str, int maxlen)
 {
        if(but->rnaprop && ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) {
@@ -1364,12 +1394,8 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen)
 
                if(ui_is_but_float(but)) {
 
-                       if(but->rnaprop && (RNA_property_subtype(but->rnaprop) & PROP_UNIT_LENGTH && U.unit_type != USER_UNIT_NONE)) {
-                               int prec = but->a2;
-                               if(prec>4)                      prec= 4;
-                               else if(prec==0)        prec= 2;
-
-                               bUnit_AsString(str, value*U.unit_scale_length, prec, U.unit_type, PROP_UNIT_LENGTH>>16, U.unit_flag&USER_UNIT_OPT_SPLIT, 0);
+                       if(U.unit_system != USER_UNIT_NONE && but->rnaprop && RNA_SUBTYPE_UNIT_VALUE(RNA_property_subtype(but->rnaprop))) {
+                               ui_get_but_string_unit(but, str, value, 0);
                        }
                        else if(but->a2) { /* amount of digits defined */
                                if(but->a2==1) BLI_snprintf(str, maxlen, "%.1f", value);
@@ -1449,7 +1475,7 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
                {
                        char str_unit_convert[256];
                        
-                       bUnit_ReplaceString(str_unit_convert, str, U.unit_scale_length, U.unit_type, PROP_UNIT_LENGTH>>16);
+                       bUnit_ReplaceString(str_unit_convert, str, 1.0/ui_get_but_scale_unit(but, 1.0), U.unit_system, RNA_SUBTYPE_UNIT_VALUE(RNA_property_subtype(but->rnaprop)));
 
                        if(BPY_button_eval(C, str_unit_convert, &value)) {
                                value = ui_get_but_val(but); /* use its original value */
@@ -1803,16 +1829,12 @@ void ui_check_but(uiBut *but)
                        if(value == FLT_MAX) sprintf(but->drawstr, "%sinf", but->str);
                        else if(value == -FLT_MAX) sprintf(but->drawstr, "%s-inf", but->str);
                        /* support length type buttons */
-                       else if(but->rnaprop && (RNA_property_subtype(but->rnaprop) & PROP_UNIT_LENGTH && U.unit_type != USER_UNIT_NONE)) {
+                       else if(U.unit_system != USER_UNIT_NONE && but->rnaprop && RNA_SUBTYPE_UNIT_VALUE(RNA_property_subtype(but->rnaprop))) {
                                char new_str[256];
-                               int prec = but->a2;
-                               if(prec>4)                      prec= 4;
-                               else if(prec==0)        prec= 2;
 
                                if(U.unit_scale_length==0.0) U.unit_scale_length= 1.0; // XXX do_versions
 
-                               bUnit_AsString(new_str, value*U.unit_scale_length, prec, U.unit_type, PROP_UNIT_LENGTH>>16, U.unit_flag&USER_UNIT_OPT_SPLIT, 1);
-
+                               ui_get_but_string_unit(but, new_str, value, TRUE);
                                sprintf(but->drawstr, "%s%s", but->str, new_str);
                        }
                        else if(but->a2) { /* amount of digits defined */
index 6b9b1086c7f522ff1006b7979ddce13829a43d39..ae0ad6cc0be7950fbdc3a8e508f0fc2d0044f220 100644 (file)
@@ -300,7 +300,7 @@ typedef struct UserDef {
 
        int scrollback; /* console scrollback limit */
        float unit_scale_length, pad1; /* maybe have other unit conversions? */
-       char unit_type, unit_flag; /* imperial, metric etc */
+       char unit_system, unit_flag; /* imperial, metric etc */
        short dpi;              /* range 48-128? */
        short encoding;
        short transopts;
index 4833640a04b94a134d77e19ff647594acdee7aa3..72ecf0e7a937cc3209b9125ed19dbfcf0f32260d 100644 (file)
@@ -80,6 +80,7 @@ typedef enum PropertyUnit {
 } PropertyUnit;
 
 #define RNA_SUBTYPE_UNIT(subtype) (subtype & 0x00FF0000)
+#define RNA_SUBTYPE_UNIT_VALUE(subtype) (subtype>>16)
 
 /* also update rna_property_subtypename when you change this */
 typedef enum PropertySubType {
index 69ff1300f83940ce77b8a4ad46120e05e9dcab82..165bd0ddd5bcefa43e18e98043690786bb04d0d0 100644 (file)
@@ -1733,7 +1733,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
                {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""},
                {0, NULL, 0, NULL, NULL}};
 
-       static EnumPropertyItem unit_types[] = {
+       static EnumPropertyItem unit_systems[] = {
                {USER_UNIT_NONE, "NONE", 0, "None", ""},
                {USER_UNIT_METRIC, "METRIC", 0, "Metric", ""},
                {USER_UNIT_IMPERIAL, "IMPERIAL", 0, "Imperial", ""},
@@ -1780,9 +1780,9 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Global Undo", "Global undo works by keeping a full copy of the file itself in memory, so takes extra memory.");
 
        /* Units */
-       prop= RNA_def_property(srna, "unit_type", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_items(prop, unit_types);
-       RNA_def_property_ui_text(prop, "Unit Type", "The unit system to use for button display.");
+       prop= RNA_def_property(srna, "unit_system", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(prop, unit_systems);
+       RNA_def_property_ui_text(prop, "Unit System", "The unit system to use for button display.");
        RNA_def_property_update(prop, NC_WINDOW, NULL);
 
        prop= RNA_def_property(srna, "unit_scale_length", PROP_FLOAT, PROP_UNSIGNED);