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.c165
1 files changed, 116 insertions, 49 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 682db20af55..5f36c5e21bf 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -366,10 +366,10 @@ static void ui_block_bounds_calc_centered_pie(uiBlock *block)
static void ui_block_bounds_calc_popup(
wmWindow *window, uiBlock *block,
- eBlockBoundsCalc bounds_calc, const int xy[2])
+ eBlockBoundsCalc bounds_calc, const int xy[2], int r_xy[2])
{
int width, height, oldwidth, oldheight;
- int oldbounds, xmax, ymax;
+ int oldbounds, xmax, ymax, raw_x, raw_y;
const int margin = UI_SCREEN_MARGIN;
rcti rect, rect_bounds;
int ofs_dummy[2];
@@ -407,8 +407,8 @@ static void ui_block_bounds_calc_popup(
/* offset block based on mouse position, user offset is scaled
* along in case we resized the block in ui_block_bounds_calc_text */
- rect.xmin = xy[0] + block->rect.xmin + (block->mx * width) / oldwidth;
- rect.ymin = xy[1] + block->rect.ymin + (block->my * height) / oldheight;
+ raw_x = rect.xmin = xy[0] + block->rect.xmin + (block->mx * width) / oldwidth;
+ raw_y = rect.ymin = xy[1] + block->rect.ymin + (block->my * height) / oldheight;
rect.xmax = rect.xmin + width;
rect.ymax = rect.ymin + height;
@@ -422,6 +422,13 @@ static void ui_block_bounds_calc_popup(
/* now recompute bounds and safety */
ui_block_bounds_calc(block);
+
+ /* If given, adjust input coordinates such that they would generate real final popup position.
+ * Needed to handle correctly floating panels once they have been dragged around, see T52999. */
+ if (r_xy) {
+ r_xy[0] = xy[0] + block->rect.xmin - raw_x;
+ r_xy[1] = xy[1] + block->rect.ymin - raw_y;
+ }
}
/* used for various cases */
@@ -488,6 +495,9 @@ static int ui_but_calc_float_precision(uiBut *but, double value)
else if (prec == -1) {
prec = (but->hardmax < 10.001f) ? 3 : 2;
}
+ else {
+ CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
+ }
return UI_calc_float_precision(prec, value);
}
@@ -684,7 +694,7 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu
if (oldbut->active) {
/* flags from the buttons we want to refresh, may want to add more here... */
- const int flag_copy = UI_BUT_REDALERT;
+ const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON;
found_active = true;
@@ -973,7 +983,9 @@ void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_str
}
}
-static bool ui_but_event_operator_string(const bContext *C, uiBut *but, char *buf, const size_t buf_len)
+static bool ui_but_event_operator_string(
+ const bContext *C, uiBut *but,
+ char *buf, const size_t buf_len)
{
MenuType *mt;
bool found = false;
@@ -981,7 +993,10 @@ static bool ui_but_event_operator_string(const bContext *C, uiBut *but, char *bu
if (but->optype) {
IDProperty *prop = (but->opptr) ? but->opptr->data : NULL;
- if (WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, true, buf_len, buf)) {
+ if (WM_key_event_operator_string(
+ C, but->optype->idname, but->opcontext, prop, true,
+ buf, buf_len))
+ {
found = true;
}
}
@@ -996,8 +1011,9 @@ static bool ui_but_event_operator_string(const bContext *C, uiBut *but, char *bu
IDP_AssignString(prop_menu_name, mt->idname, sizeof(mt->idname));
- if (WM_key_event_operator_string(C, "WM_OT_call_menu", WM_OP_INVOKE_REGION_WIN, prop_menu,
- true, buf_len, buf))
+ if (WM_key_event_operator_string(
+ C, "WM_OT_call_menu", WM_OP_INVOKE_REGION_WIN, prop_menu, true,
+ buf, buf_len))
{
found = true;
}
@@ -1009,8 +1025,10 @@ static bool ui_but_event_operator_string(const bContext *C, uiBut *but, char *bu
return found;
}
-static bool ui_but_event_property_operator_string(const bContext *C, uiBut *but, char *buf, const size_t buf_len)
-{
+static bool ui_but_event_property_operator_string(
+ const bContext *C, uiBut *but,
+ char *buf, const size_t buf_len)
+{
/* context toggle operator names to check... */
const char *ctx_toggle_opnames[] = {
"WM_OT_context_toggle",
@@ -1104,8 +1122,9 @@ static bool ui_but_event_property_operator_string(const bContext *C, uiBut *but,
/* check each until one works... */
for (i = 0; (i < num_ops) && (ctx_toggle_opnames[i]); i++) {
- if (WM_key_event_operator_string(C, ctx_toggle_opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false,
- buf_len, buf))
+ if (WM_key_event_operator_string(
+ C, ctx_toggle_opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false,
+ buf, buf_len))
{
found = true;
break;
@@ -1165,6 +1184,8 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
uiBut *but;
char buf[128];
+ BLI_assert(block->flag & UI_BLOCK_LOOP);
+
/* only do it before bounding */
if (block->rect.xmin != block->rect.xmax)
return;
@@ -1179,6 +1200,9 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block)
}
else {
for (but = block->buttons.first; but; but = but->next) {
+ if (but->dt != UI_EMBOSS_PULLDOWN) {
+ continue;
+ }
if (ui_but_event_operator_string(C, but, buf, sizeof(buf))) {
ui_but_add_shortcut(but, buf, false);
@@ -1223,7 +1247,7 @@ void UI_block_update_from_old(const bContext *C, uiBlock *block)
block->oldblock = NULL;
}
-void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2])
+void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2], int r_xy[2])
{
wmWindow *window = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
@@ -1291,7 +1315,7 @@ void UI_block_end_ex(const bContext *C, uiBlock *block, const int xy[2])
/* fallback */
case UI_BLOCK_BOUNDS_POPUP_MOUSE:
case UI_BLOCK_BOUNDS_POPUP_MENU:
- ui_block_bounds_calc_popup(window, block, block->bounds_type, xy);
+ ui_block_bounds_calc_popup(window, block, block->bounds_type, xy, r_xy);
break;
}
@@ -1309,7 +1333,7 @@ void UI_block_end(const bContext *C, uiBlock *block)
{
wmWindow *window = CTX_wm_window(C);
- UI_block_end_ex(C, block, &window->eventstate->x);
+ UI_block_end_ex(C, block, &window->eventstate->x, NULL);
}
/* ************** BLOCK DRAWING FUNCTION ************* */
@@ -1337,7 +1361,7 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u
rctf rectf;
ui_block_to_window_rctf(ar, block, &rectf, (but) ? &but->rect : &block->rect);
- BLI_rcti_rctf_copy_floor(rect, &rectf);
+ BLI_rcti_rctf_copy_round(rect, &rectf);
BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin);
}
@@ -1932,13 +1956,14 @@ void ui_but_value_set(uiBut *but, double value)
else {
/* first do rounding */
if (but->pointype == UI_BUT_POIN_CHAR) {
- value = (char)floor(value + 0.5);
+ value = round_db_to_uchar_clamp(value);
}
else if (but->pointype == UI_BUT_POIN_SHORT) {
- value = (short)floor(value + 0.5);
+ value = round_db_to_short_clamp(value);
+ }
+ else if (but->pointype == UI_BUT_POIN_INT) {
+ value = round_db_to_int_clamp(value);
}
- else if (but->pointype == UI_BUT_POIN_INT)
- value = (int)floor(value + 0.5);
else if (but->pointype == UI_BUT_POIN_FLOAT) {
float fval = (float)value;
if (fval >= -0.00001f && fval <= 0.00001f) fval = 0.0f; /* prevent negative zero */
@@ -2146,9 +2171,14 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
/**
* \param float_precision For number buttons the precision to use or -1 to fallback to the button default.
+ * \param use_exp_float Use exponent representation of floats when out of reasonable range (outside of 1e3/1e-3).
*/
-void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision)
+void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision, const bool use_exp_float, bool *r_use_exp_float)
{
+ if (r_use_exp_float) {
+ *r_use_exp_float = false;
+ }
+
if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
PropertyType type;
const char *buf = NULL;
@@ -2216,17 +2246,38 @@ void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int
ui_get_but_string_unit(but, str, maxlen, value, false, float_precision);
}
else {
- const int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) : float_precision;
- BLI_snprintf(str, maxlen, "%.*f", prec, value);
+ 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) {
+ BLI_snprintf(str, maxlen, "%.*g", prec, value);
+ if (r_use_exp_float) {
+ *r_use_exp_float = true;
+ }
+ }
+ else {
+ prec -= int_digits_num;
+ CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
+ BLI_snprintf(str, maxlen, "%.*f", prec, value);
+ }
+ }
+ else {
+#if 0 /* TODO, but will likely break some stuff, so better after 2.79 release. */
+ prec -= int_digits_num;
+ CLAMP(prec, 0, UI_PRECISION_FLOAT_MAX);
+#endif
+ BLI_snprintf(str, maxlen, "%.*f", prec, value);
+ }
}
}
- else
+ else {
BLI_snprintf(str, maxlen, "%d", (int)value);
+ }
}
}
void ui_but_string_get(uiBut *but, char *str, const size_t maxlen)
{
- ui_but_string_get_ex(but, str, maxlen, -1);
+ ui_but_string_get_ex(but, str, maxlen, -1, false, NULL);
}
/**
@@ -2288,7 +2339,7 @@ char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size)
#ifdef WITH_PYTHON
-static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char *str, double *value)
+static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char *str, double *r_value)
{
char str_unit_convert[256];
const int unit_type = UI_but_unit_type_get(but);
@@ -2300,13 +2351,13 @@ static bool ui_set_but_string_eval_num_unit(bContext *C, uiBut *but, const char
bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), but->drawstr,
ui_get_but_scale_unit(but, 1.0), but->block->unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type));
- return BPY_execute_string_as_number(C, str_unit_convert, value, true);
+ return BPY_execute_string_as_number(C, str_unit_convert, true, r_value);
}
#endif /* WITH_PYTHON */
-bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *value)
+bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double *r_value)
{
bool ok = false;
@@ -2315,13 +2366,13 @@ bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double
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, str, value, is_unit_but == false)) {
+ if (BPY_execute_string_as_number(C, 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", *value);
- ok = ui_set_but_string_eval_num_unit(C, but, str_new, value);
+ 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) */
@@ -2329,17 +2380,16 @@ bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double
}
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, value);
+ ok = ui_set_but_string_eval_num_unit(C, but, str, r_value);
}
}
#else /* WITH_PYTHON */
- *value = atof(str);
+ *r_value = atof(str);
ok = true;
- (void)C;
- (void)but;
+ UNUSED_VARS(C, but);
#endif /* WITH_PYTHON */
@@ -2449,7 +2499,9 @@ bool ui_but_string_set(bContext *C, uiBut *but, const char *str)
return false;
}
- if (!ui_but_is_float(but)) value = (int)floor(value + 0.5);
+ if (!ui_but_is_float(but)) {
+ value = floor(value + 0.5);
+ }
/* not that we use hard limits here */
if (value < (double)but->hardmin) value = but->hardmin;
@@ -2629,6 +2681,10 @@ static void ui_but_free(const bContext *C, uiBut *but)
MEM_freeN(but->tip_argN);
}
+ if (but->hold_argN) {
+ MEM_freeN(but->hold_argN);
+ }
+
if (but->active) {
/* XXX solve later, buttons should be free-able without context ideally,
* however they may have open tooltips or popup windows, which need to
@@ -3168,7 +3224,9 @@ static uiBut *ui_def_but(
}
if (block->flag & UI_BLOCK_RADIAL) {
- but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT);
+ but->drawflag |= UI_BUT_TEXT_LEFT;
+ if (but->str && but->str[0])
+ but->drawflag |= UI_BUT_ICON_LEFT;
}
else if ((block->flag & UI_BLOCK_LOOP) ||
ELEM(but->type,
@@ -3245,7 +3303,7 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu
uiBut *but = (uiBut *)but_p;
/* see comment in ui_item_enum_expand, re: uiname */
- EnumPropertyItem *item, *item_array;
+ const EnumPropertyItem *item, *item_array;
bool free;
uiLayout *split, *column = NULL;
@@ -3355,9 +3413,8 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu
UI_block_layout_set_current(block, layout);
if (free) {
- MEM_freeN(item_array);
+ MEM_freeN((void *)item_array);
}
-
BLI_assert((block->flag & UI_BLOCK_IS_FLIP) == 0);
block->flag |= UI_BLOCK_IS_FLIP;
}
@@ -3388,7 +3445,7 @@ static uiBut *ui_def_but_rna(
/* use rna values if parameters are not specified */
if ((proptype == PROP_ENUM) && ELEM(type, UI_BTYPE_MENU, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) {
/* UI_BTYPE_MENU is handled a little differently here */
- EnumPropertyItem *item;
+ const EnumPropertyItem *item;
int value;
bool free;
int i;
@@ -3430,7 +3487,7 @@ static uiBut *ui_def_but_rna(
}
if (free) {
- MEM_freeN(item);
+ MEM_freeN((void *)item);
}
}
else {
@@ -3913,6 +3970,8 @@ uiBut *uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, int o
uiBut *uiDefIconTextButO(uiBlock *block, int type, const char *opname, int opcontext, int icon, const char *str, int x, int y, short width, short height, const char *tip)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0);
+ if (str && str[0] == '\0')
+ return uiDefIconButO_ptr(block, type, ot, opcontext, icon, x, y, width, height, tip);
return uiDefIconTextButO_ptr(block, type, ot, opcontext, icon, str, x, y, width, height, tip);
}
@@ -4390,7 +4449,7 @@ static void operator_enum_search_cb(const struct bContext *C, void *but, const c
}
else {
PointerRNA *ptr = UI_but_operator_ptr_get(but); /* Will create it if needed! */
- EnumPropertyItem *item, *item_array;
+ const EnumPropertyItem *item, *item_array;
bool do_free;
RNA_property_enum_items_gettexted((bContext *)C, ptr, prop, &item_array, NULL, &do_free);
@@ -4403,8 +4462,9 @@ static void operator_enum_search_cb(const struct bContext *C, void *but, const c
}
}
- if (do_free)
- MEM_freeN(item_array);
+ if (do_free) {
+ MEM_freeN((void *)item_array);
+ }
}
}
@@ -4473,12 +4533,18 @@ void UI_but_focus_on_enter_event(wmWindow *win, uiBut *but)
wm_event_add(win, &event);
}
+void UI_but_func_hold_set(uiBut *but, uiButHandleHoldFunc func, void *argN)
+{
+ but->hold_func = func;
+ but->hold_argN = argN;
+}
+
void UI_but_string_info_get(bContext *C, uiBut *but, ...)
{
va_list args;
uiStringInfo *si;
- EnumPropertyItem *items = NULL, *item = NULL;
+ const EnumPropertyItem *items = NULL, *item = NULL;
int totitems;
bool free_items = false;
@@ -4654,8 +4720,9 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
}
va_end(args);
- if (free_items && items)
- MEM_freeN(items);
+ if (free_items && items) {
+ MEM_freeN((void *)items);
+ }
}
/* Program Init/Exit */