Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/interface/interface.c')
-rw-r--r--source/blender/editors/interface/interface.c267
1 files changed, 160 insertions, 107 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index e70b793cfb0..8aed0d58a07 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -74,6 +74,13 @@
#define MENU_ITEM_HEIGHT 20
#define MENU_SEP_HEIGHT 6
+#define PRECISION_FLOAT_MAX 6
+#define PRECISION_FLOAT_MAX_POW 1000000 /* 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); }
+
/*
* a full doc with API notes can be found in bf-blender/trunk/blender/doc/guides/interface_API.txt
*
@@ -449,6 +456,57 @@ void uiCenteredBoundsBlock(uiBlock *block, int addval)
/* 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;
+
+ /* first check if prec is 0 and fallback to a simple default */
+ if((prec= (int)but->a2) == 0) {
+ prec= (but->hardmax < 10.001f) ? 3 : 2;
+ }
+
+ /* check on the number of decimal places neede 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 */
+ if(value != 0.0 && (value= ABS(value)) < 0.1) {
+ 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;
+ }
+ }
+ }
+
+ CLAMP(prec, 1, PRECISION_FLOAT_MAX);
+
+ return prec;
+}
+
static void ui_draw_linkline(uiLinkLine *line)
{
rcti rect;
@@ -556,7 +614,7 @@ static int ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBut
// but->flag= oldbut->flag;
#else
/* exception! redalert flag can't be update from old button.
- * perhaps it should only copy spesific flags rather then all. */
+ * perhaps it should only copy spesific flags rather than all. */
// but->flag= (oldbut->flag & ~UI_BUT_REDALERT) | (but->flag & UI_BUT_REDALERT);
#endif
// but->active= oldbut->active;
@@ -892,13 +950,14 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
/* widgets */
for(but= block->buttons.first; but; but= but->next) {
- ui_but_to_pixelrect(&rect, ar, block, but);
+ if(!(but->flag & (UI_HIDDEN|UI_SCROLLED))) {
+ ui_but_to_pixelrect(&rect, ar, block, but);
- if(!(but->flag & UI_HIDDEN) &&
/* XXX: figure out why invalid coordinates happen when closing render window */
/* and material preview is redrawn in main window (temp fix for bug #23848) */
- rect.xmin < rect.xmax && rect.ymin < rect.ymax)
- ui_draw_but(C, ar, &style, but, &rect);
+ if(rect.xmin < rect.xmax && rect.ymin < rect.ymax)
+ ui_draw_but(C, ar, &style, but, &rect);
+ }
}
/* restore matrix */
@@ -912,17 +971,16 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
/* ************* EVENTS ************* */
-static void ui_is_but_sel(uiBut *but)
+static void ui_is_but_sel(uiBut *but, double *value)
{
- double value; /* only initialized when needed, to avoid calling when not used */
short push=0, true=1;
if(ELEM3(but->type, TOGN, ICONTOGN, OPTIONN)) true= 0;
if( but->bit ) {
int lvalue;
- value= ui_get_but_val(but);
- lvalue= (int)value;
+ UI_GET_BUT_VALUE_INIT(but, *value)
+ lvalue= (int)*value;
if( BTST(lvalue, (but->bitnr)) ) push= true;
else push= !true;
}
@@ -942,24 +1000,24 @@ static void ui_is_but_sel(uiBut *but)
case BUT_TOGDUAL:
case ICONTOG:
case OPTION:
- value= ui_get_but_val(but);
- if(value != (double)but->hardmin) push= 1;
+ UI_GET_BUT_VALUE_INIT(but, *value)
+ if(*value != (double)but->hardmin) push= 1;
break;
case ICONTOGN:
case TOGN:
case OPTIONN:
- value= ui_get_but_val(but);
- if(value==0.0) push= 1;
+ UI_GET_BUT_VALUE_INIT(but, *value)
+ if(*value==0.0) push= 1;
break;
case ROW:
case LISTROW:
- value= ui_get_but_val(but);
+ UI_GET_BUT_VALUE_INIT(but, *value)
/* support for rna enum buts */
if(but->rnaprop && (RNA_property_flag(but->rnaprop) & PROP_ENUM_FLAG)) {
- if((int)value & (int)but->hardmax) push= 1;
+ if((int)*value & (int)but->hardmax) push= 1;
}
else {
- if(value == (double)but->hardmax) push= 1;
+ if(*value == (double)but->hardmax) push= 1;
}
break;
case COL:
@@ -1330,6 +1388,10 @@ void ui_set_but_val(uiBut *but, double value)
break;
}
}
+
+ /* we can't be sure what RNA set functions actually do,
+ * so leave this unset */
+ value= UI_BUT_VALUE_UNSET;
}
else if(but->pointype==0);
else if(but->type==HSVSLI ) {
@@ -1370,19 +1432,19 @@ void ui_set_but_val(uiBut *but, double value)
/* then set value with possible edit override */
if(but->editval)
- *but->editval= value;
+ value= *but->editval= value;
else if(but->pointype==CHA)
- *((char *)but->poin)= (char)value;
+ value= *((char *)but->poin)= (char)value;
else if(but->pointype==SHO)
- *((short *)but->poin)= (short)value;
+ value= *((short *)but->poin)= (short)value;
else if(but->pointype==INT)
- *((int *)but->poin)= (int)value;
+ value= *((int *)but->poin)= (int)value;
else if(but->pointype==FLO)
- *((float *)but->poin)= (float)value;
+ value= *((float *)but->poin)= (float)value;
}
/* update select flag */
- ui_is_but_sel(but);
+ ui_is_but_sel(but, &value);
}
int ui_get_but_string_max_length(uiBut *but)
@@ -1444,8 +1506,8 @@ static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double va
if(scene->unit.scale_length<0.0001f) scene->unit.scale_length= 1.0f; // XXX do_versions
/* Sanity checks */
- if(precision>7) precision= 7;
- else if(precision==0) precision= 2;
+ if(precision > PRECISION_FLOAT_MAX) precision= PRECISION_FLOAT_MAX;
+ else if(precision==0) precision= 2;
bUnit_AsString(str, len_max, ui_get_but_scale_unit(but, value), precision, scene->unit.system, unit_type>>16, do_split, pad);
}
@@ -1529,10 +1591,7 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen)
ui_get_but_string_unit(but, str, maxlen, value, 0);
}
else {
- int prec= (int)but->a2;
- if(prec==0) prec= 3;
- else CLAMP(prec, 1, 7);
-
+ const int prec= ui_but_float_precision(but, value);
BLI_snprintf(str, maxlen, "%.*f", prec, value);
}
}
@@ -1668,23 +1727,20 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
return 0;
}
-void ui_set_but_default(bContext *C, uiBut *but, short all)
+void ui_set_but_default(bContext *C, short all)
{
- /* if there is a valid property that is editable... */
- if (but->rnapoin.data && but->rnaprop && RNA_property_editable(&but->rnapoin, but->rnaprop)) {
- int index = (all)? -1 : but->rnaindex;
-
- if(RNA_property_reset(&but->rnapoin, but->rnaprop, index)) {
- /* perform updates required for this property */
- RNA_property_update(C, &but->rnapoin, but->rnaprop);
- }
- }
+ PointerRNA ptr;
+
+ WM_operator_properties_create(&ptr, "UI_OT_reset_default_button");
+ RNA_boolean_set(&ptr, "all", all);
+ WM_operator_name_call(C, "UI_OT_reset_default_button", WM_OP_EXEC_DEFAULT, &ptr);
+ WM_operator_properties_free(&ptr);
}
static double soft_range_round_up(double value, double max)
{
/* round up to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, .. */
- double newmax= pow(10.0, ceil(log(value)/log(10.0)));
+ double newmax= pow(10.0, ceil(log(value)/M_LN10));
if(newmax*0.2 >= max && newmax*0.2 >= value)
return newmax*0.2;
@@ -1697,7 +1753,7 @@ static double soft_range_round_up(double value, double max)
static double soft_range_round_down(double value, double max)
{
/* round down to .., 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, .. */
- double newmax= pow(10.0, floor(log(value)/log(10.0)));
+ double newmax= pow(10.0, floor(log(value)/M_LN10));
if(newmax*5.0 <= max && newmax*5.0 <= value)
return newmax*5.0;
@@ -1709,50 +1765,70 @@ static double soft_range_round_down(double value, double max)
void ui_set_but_soft_range(uiBut *but, double value)
{
- PropertyType type;
- double softmin, softmax /*, step, precision*/;
-
+ /* ideally we would not limit this but practially, its more then
+ * enough worst case is very long vectors wont use a smart soft-range
+ * which isnt so bad. */
+
if(but->rnaprop) {
- type= RNA_property_type(but->rnaprop);
+ const PropertyType type= RNA_property_type(but->rnaprop);
+ double softmin, softmax /*, step, precision*/;
+ double value_min= value;
+ double value_max= value;
/* clamp button range to something reasonable in case
* we get -inf/inf from RNA properties */
if(type == PROP_INT) {
int imin, imax, istep;
+ const int array_len= RNA_property_array_length(&but->rnapoin, but->rnaprop);
RNA_property_int_ui_range(&but->rnapoin, but->rnaprop, &imin, &imax, &istep);
softmin= (imin == INT_MIN)? -1e4: imin;
softmax= (imin == INT_MAX)? 1e4: imax;
/*step= istep;*/ /*UNUSED*/
/*precision= 1;*/ /*UNUSED*/
+
+ if(array_len >= 2) {
+ int value_range[2];
+ RNA_property_int_get_array_range(&but->rnapoin, but->rnaprop, value_range);
+ value_min= (double)value_range[0];
+ value_max= (double)value_range[1];
+ }
}
else if(type == PROP_FLOAT) {
float fmin, fmax, fstep, fprecision;
+ const int array_len= RNA_property_array_length(&but->rnapoin, but->rnaprop);
RNA_property_float_ui_range(&but->rnapoin, but->rnaprop, &fmin, &fmax, &fstep, &fprecision);
softmin= (fmin == -FLT_MAX)? (float)-1e4: fmin;
softmax= (fmax == FLT_MAX)? (float)1e4: fmax;
/*step= fstep;*/ /*UNUSED*/
/*precision= fprecision;*/ /*UNUSED*/
+
+ if(array_len >= 2) {
+ float value_range[2];
+ RNA_property_float_get_array_range(&but->rnapoin, but->rnaprop, value_range);
+ value_min= (double)value_range[0];
+ value_max= (double)value_range[1];
+ }
}
else
return;
/* if the value goes out of the soft/max range, adapt the range */
- if(value+1e-10 < softmin) {
- if(value < 0.0)
- softmin= -soft_range_round_up(-value, -softmin);
+ if(value_min+1e-10 < softmin) {
+ if(value_min < 0.0)
+ softmin= -soft_range_round_up(-value_min, -softmin);
else
- softmin= soft_range_round_down(value, softmin);
+ softmin= soft_range_round_down(value_min, softmin);
if(softmin < (double)but->hardmin)
softmin= (double)but->hardmin;
}
- else if(value-1e-10 > softmax) {
- if(value < 0.0)
- softmax= -soft_range_round_down(-value, -softmax);
+ else if(value_max-1e-10 > softmax) {
+ if(value_max < 0.0)
+ softmax= -soft_range_round_down(-value_max, -softmax);
else
- softmax= soft_range_round_up(value, softmax);
+ softmax= soft_range_round_up(value_max, softmax);
if(softmax > (double)but->hardmax)
softmax= but->hardmax;
@@ -1848,29 +1924,24 @@ void uiFreeInactiveBlocks(const bContext *C, ListBase *lb)
void uiBlockSetRegion(uiBlock *block, ARegion *region)
{
- ListBase *lb;
+ ListBase *lb= &region->uiblocks;
uiBlock *oldblock= NULL;
- lb= &region->uiblocks;
-
/* each listbase only has one block with this name, free block
* if is already there so it can be rebuilt from scratch */
if(lb) {
- for (oldblock= lb->first; oldblock; oldblock= oldblock->next)
- if (BLI_streq(oldblock->name, block->name))
- break;
+ oldblock= BLI_findstring(lb, block->name, offsetof(uiBlock, name));
if (oldblock) {
oldblock->active= 0;
oldblock->panel= NULL;
}
+
+ /* at the beginning of the list! for dynamical menus/blocks */
+ BLI_addhead(lb, block);
}
block->oldblock= oldblock;
-
- /* at the beginning of the list! for dynamical menus/blocks */
- if(lb)
- BLI_addhead(lb, block);
}
uiBlock *uiBeginBlock(const bContext *C, ARegion *region, const char *name, short dt)
@@ -1930,17 +2001,19 @@ void uiBlockSetEmboss(uiBlock *block, char dt)
void ui_check_but(uiBut *but)
{
/* if something changed in the button */
- double value;
+ double value= UI_BUT_VALUE_UNSET;
// float okwidth; // UNUSED
// int transopts= ui_translate_buttons();
- ui_is_but_sel(but);
+ ui_is_but_sel(but, &value);
// if(but->type==TEX || but->type==IDPOIN) transopts= 0;
/* only update soft range while not editing */
- if(but->rnaprop && !(but->editval || but->editstr || but->editvec))
- ui_set_but_soft_range(but, ui_get_but_val(but));
+ if(but->rnaprop && !(but->editval || but->editstr || but->editvec)) {
+ UI_GET_BUT_VALUE_INIT(but, value)
+ ui_set_but_soft_range(but, value);
+ }
/* test for min and max, icon sliders, etc */
switch( but->type ) {
@@ -1949,17 +2022,20 @@ void ui_check_but(uiBut *but)
case SCROLL:
case NUMSLI:
case HSVSLI:
- value= ui_get_but_val(but);
+ UI_GET_BUT_VALUE_INIT(but, value)
if(value < (double)but->hardmin) ui_set_but_val(but, but->hardmin);
else if(value > (double)but->hardmax) ui_set_but_val(but, but->hardmax);
break;
case NUMABS:
- value= fabs( ui_get_but_val(but) );
- if(value < (double)but->hardmin) ui_set_but_val(but, but->hardmin);
- else if(value > (double)but->hardmax) ui_set_but_val(but, but->hardmax);
+ {
+ double value_abs;
+ UI_GET_BUT_VALUE_INIT(but, value)
+ value_abs= fabs(value);
+ if(value_abs < (double)but->hardmin) ui_set_but_val(but, but->hardmin);
+ else if(value_abs > (double)but->hardmax) ui_set_but_val(but, but->hardmax);
break;
-
+ }
case ICONTOG:
case ICONTOGN:
if(!but->rnaprop || (RNA_property_flag(but->rnaprop) & PROP_ICONS_CONSECUTIVE)) {
@@ -1970,14 +2046,14 @@ void ui_check_but(uiBut *but)
case ICONROW:
if(!but->rnaprop || (RNA_property_flag(but->rnaprop) & PROP_ICONS_CONSECUTIVE)) {
- value= ui_get_but_val(but);
+ UI_GET_BUT_VALUE_INIT(but, value)
but->iconadd= (int)value- (int)(but->hardmin);
}
break;
case ICONTEXTROW:
if(!but->rnaprop || (RNA_property_flag(but->rnaprop) & PROP_ICONS_CONSECUTIVE)) {
- value= ui_get_but_val(but);
+ UI_GET_BUT_VALUE_INIT(but, value)
but->iconadd= (int)value- (int)(but->hardmin);
}
break;
@@ -1994,7 +2070,7 @@ void ui_check_but(uiBut *but)
case ICONTEXTROW:
if(but->x2 - but->x1 > 24) {
- value= ui_get_but_val(but);
+ UI_GET_BUT_VALUE_INIT(but, value)
ui_set_name_menu(but, (int)value);
}
break;
@@ -2004,7 +2080,7 @@ void ui_check_but(uiBut *but)
case HSVSLI:
case NUMABS:
- value= ui_get_but_val(but);
+ UI_GET_BUT_VALUE_INIT(but, value)
if(ui_is_but_float(but)) {
if(value == (double) FLT_MAX) sprintf(but->drawstr, "%sinf", but->str);
@@ -2016,10 +2092,7 @@ void ui_check_but(uiBut *but)
BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str);
}
else {
- int prec= (int)but->a2;
- if(prec==0) prec= (but->hardmax < 10.001f) ? 3 : 2;
- else CLAMP(prec, 1, 7);
-
+ const int prec= ui_but_float_precision(but, value);
BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
}
}
@@ -2037,11 +2110,9 @@ void ui_check_but(uiBut *but)
case LABEL:
if(ui_is_but_float(but)) {
- int prec= (int)but->a2;
- value= ui_get_but_val(but);
- if(prec==0) prec= 3;
- else CLAMP(prec, 1, 7);
-
+ int prec;
+ UI_GET_BUT_VALUE_INIT(but, value)
+ prec= ui_but_float_precision(but, value);
BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value);
}
else {
@@ -2066,8 +2137,10 @@ void ui_check_but(uiBut *but)
strncpy(but->drawstr, but->str, UI_MAX_DRAW_STR);
if (but->flag & UI_SELECT) {
strcat(but->drawstr, "Press a key");
- } else {
- strcat(but->drawstr, WM_key_event_string((short) ui_get_but_val(but)));
+ }
+ else {
+ UI_GET_BUT_VALUE_INIT(but, value)
+ strcat(but->drawstr, WM_key_event_string((short)value));
}
break;
@@ -2489,28 +2562,8 @@ static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *s
icon= RNA_property_ui_icon(prop);
}
}
-
- if(!tip) {
- if(type == ROW && proptype == PROP_ENUM) {
- EnumPropertyItem *item;
- int i, totitem, free;
-
- RNA_property_enum_items(block->evil_C, ptr, prop, &item, &totitem, &free);
-
- for(i=0; i<totitem; i++) {
- if(item[i].identifier[0] && item[i].value == (int)max) {
- if(item[i].description[0])
- tip= item[i].description;
- break;
- }
- }
-
- if(free)
- MEM_freeN(item);
- }
- }
- if(!tip)
+ if(!tip && proptype != PROP_ENUM)
tip= RNA_property_ui_description(prop);
if(min == max || a1 == -1 || a2 == -1) {