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:
authorBastien Montagne <montagne29@wanadoo.fr>2015-06-29 18:10:42 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-06-29 18:10:42 +0300
commit58d6cbba6da31db8dc8a2b42d528b9a353081904 (patch)
tree04b57a2f809c6f08d84a082edf061f3ece631860 /source/blender/editors/interface/interface_handlers.c
parent94549adec4b6857fb6ec4cf77606da51ff7c26b7 (diff)
parent295d0c52a26730edc6d4ed1276e4051cce006be5 (diff)
Merge branch 'master' into temp-ghash-setopstemp-ghash-setops
Diffstat (limited to 'source/blender/editors/interface/interface_handlers.c')
-rw-r--r--source/blender/editors/interface/interface_handlers.c853
1 files changed, 659 insertions, 194 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 71b7b95208b..58cf6b900b9 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -52,9 +52,9 @@
#include "BLI_linklist.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
+#include "BLI_string_cursor_utf8.h"
#include "BLI_rect.h"
#include "BLI_utildefines.h"
-#include "BLI_string_cursor_utf8.h"
#include "BLF_translation.h"
@@ -99,6 +99,9 @@
/* support dragging multiple number buttons at once */
#define USE_DRAG_MULTINUM
+/* allow dragging/editing all other selected items at once */
+#define USE_ALLSELECT
+
/* so we can avoid very small mouse-moves from jumping away from keyboard navigation [#34936] */
#define USE_KEYNAV_LIMIT
@@ -158,17 +161,63 @@ typedef enum uiHandleButtonState {
} uiHandleButtonState;
+#ifdef USE_ALLSELECT
+
+/* Unfortunately theres no good way handle more generally:
+ * (propagate single clicks on layer buttons to other objects) */
+#define USE_ALLSELECT_LAYER_HACK
+
+typedef struct uiSelectContextElem {
+ PointerRNA ptr;
+ union {
+ bool val_b;
+ int val_i;
+ float val_f;
+ };
+} uiSelectContextElem;
+
+typedef struct uiSelectContextStore {
+ uiSelectContextElem *elems;
+ int elems_len;
+ bool do_free;
+ bool is_enabled;
+ /* When set, simply copy values (don't apply difference).
+ * Rules are:
+ * - dragging numbers uses delta.
+ * - typing in values will assign to all. */
+ bool is_copy;
+} uiSelectContextStore;
+
+static bool ui_selectcontext_begin(
+ bContext *C, uiBut *but, struct uiSelectContextStore *selctx_data);
+static void ui_selectcontext_end(
+ uiBut *but, uiSelectContextStore *selctx_data);
+static void ui_selectcontext_apply(
+ bContext *C, uiBut *but, struct uiSelectContextStore *selctx_data,
+ const double value, const double value_orig);
+
+#define IS_ALLSELECT_EVENT(event) ((event)->alt != 0)
+
+/** just show a tinted color so users know its activated */
+#define UI_BUT_IS_SELECT_CONTEXT UI_BUT_NODE_ACTIVE
+
+#endif /* USE_ALLSELECT */
+
+
#ifdef USE_DRAG_MULTINUM
-/* how far to drag before we check for gesture direction (in pixels),
+/**
+ * how far to drag before we check for gesture direction (in pixels),
* note: half the height of a button is about right... */
#define DRAG_MULTINUM_THRESHOLD_DRAG_X (UI_UNIT_Y / 4)
-/* how far to drag horizontally before we stop checking which buttons the gesture spans (in pixels),
+/**
+ * how far to drag horizontally before we stop checking which buttons the gesture spans (in pixels),
* locking down the buttons so we can drag freely without worrying about vertical movement. */
#define DRAG_MULTINUM_THRESHOLD_DRAG_Y (UI_UNIT_Y / 4)
-/* how strict to be when detecting a vertical gesture, [0.5 == sloppy], [0.9 == strict], (unsigned dot-product)
+/**
+ * how strict to be when detecting a vertical gesture, [0.5 == sloppy], [0.9 == strict], (unsigned dot-product)
* note: we should be quite strict here, since doing a vertical gesture by accident should be avoided,
* however with some care a user should be able to do a vertical movement without *missing*. */
#define DRAG_MULTINUM_THRESHOLD_VERTICAL (0.75f)
@@ -178,6 +227,10 @@ typedef enum uiHandleButtonState {
typedef struct uiButMultiState {
double origvalue;
uiBut *but;
+
+#ifdef USE_ALLSELECT
+ uiSelectContextStore select_others;
+#endif
} uiButMultiState;
typedef struct uiHandleButtonMulti {
@@ -210,8 +263,6 @@ typedef struct uiHandleButtonMulti {
#endif /* USE_DRAG_MULTINUM */
-
-
typedef struct uiHandleButtonData {
wmWindowManager *wm;
wmWindow *window;
@@ -280,6 +331,10 @@ typedef struct uiHandleButtonData {
uiHandleButtonMulti multi_data;
#endif
+#ifdef USE_ALLSELECT
+ uiSelectContextStore select_others;
+#endif
+
/* post activate */
uiButtonActivateType posttype;
uiBut *postbut;
@@ -328,14 +383,14 @@ static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, c
static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event);
static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type);
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
-static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *data,
- const bool mousemove, const bool onfree);
+static void button_activate_exit(
+ bContext *C, uiBut *but, uiHandleButtonData *data,
+ const bool mousemove, const bool onfree);
static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *userdata);
static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type);
-static void button_timers_tooltip_remove(bContext *C, uiBut *but);
#ifdef USE_DRAG_MULTINUM
-static void ui_multibut_restore(uiHandleButtonData *data, uiBlock *block);
+static void ui_multibut_restore(bContext *C, uiHandleButtonData *data, uiBlock *block);
static uiButMultiState *ui_multibut_lookup(uiHandleButtonData *data, const uiBut *but);
#endif
@@ -366,7 +421,7 @@ static void ui_color_snap_hue(const enum eSnapType snap, float *r_hue)
{
const float snap_increment = (snap == SNAP_ON_SMALL) ? 24 : 12;
BLI_assert(snap != SNAP_OFF);
- *r_hue = floorf(0.5f + ((*r_hue) * snap_increment)) / snap_increment;
+ *r_hue = roundf((*r_hue) * snap_increment) / snap_increment;
}
/* assumes event type is MOUSEPAN */
@@ -413,7 +468,7 @@ bool ui_but_is_editable_as_text(const uiBut *but)
{
return ELEM(but->type,
UI_BTYPE_TEXT, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER,
- UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK);
+ UI_BTYPE_SEARCH_MENU);
}
@@ -478,10 +533,9 @@ static float ui_mouse_scale_warp_factor(const bool shift)
return shift ? 0.05f : 1.0f;
}
-static void ui_mouse_scale_warp(uiHandleButtonData *data,
- const float mx, const float my,
- float *r_mx, float *r_my,
- const bool shift)
+static void ui_mouse_scale_warp(
+ uiHandleButtonData *data, const float mx, const float my,
+ float *r_mx, float *r_my, const bool shift)
{
const float fac = ui_mouse_scale_warp_factor(shift);
@@ -894,7 +948,7 @@ static uiButMultiState *ui_multibut_lookup(uiHandleButtonData *data, const uiBut
return NULL;
}
-static void ui_multibut_restore(uiHandleButtonData *data, uiBlock *block)
+static void ui_multibut_restore(bContext *C, uiHandleButtonData *data, uiBlock *block)
{
uiBut *but;
@@ -903,6 +957,16 @@ static void ui_multibut_restore(uiHandleButtonData *data, uiBlock *block)
uiButMultiState *mbut_state = ui_multibut_lookup(data, but);
if (mbut_state) {
ui_but_value_set(but, mbut_state->origvalue);
+
+#ifdef USE_ALLSELECT
+ if (mbut_state->select_others.elems_len > 0) {
+ ui_selectcontext_apply(
+ C, but, &mbut_state->select_others,
+ mbut_state->origvalue, mbut_state->origvalue);
+ }
+#else
+ UNUSED_VARS(C);
+#endif
}
}
}
@@ -910,7 +974,26 @@ static void ui_multibut_restore(uiHandleButtonData *data, uiBlock *block)
static void ui_multibut_free(uiHandleButtonData *data, uiBlock *block)
{
+#ifdef USE_ALLSELECT
+ if (data->multi_data.mbuts) {
+ LinkNode *list = data->multi_data.mbuts;
+ while (list) {
+ LinkNode *next = list->next;
+ uiButMultiState *mbut_state = list->link;
+
+ if (mbut_state->select_others.elems) {
+ MEM_freeN(mbut_state->select_others.elems);
+ }
+
+ MEM_freeN(list->link);
+ MEM_freeN(list);
+ list = next;
+ }
+ }
+#else
BLI_linklist_freeN(data->multi_data.mbuts);
+#endif
+
data->multi_data.mbuts = NULL;
if (data->multi_data.bs_mbuts) {
@@ -979,6 +1062,7 @@ static void ui_multibut_states_create(uiBut *but_active, uiHandleButtonData *dat
uiBut *but;
BLI_assert(data->multi_data.init == BUTTON_MULTI_INIT_SETUP);
+ BLI_assert(data->multi_data.has_mbuts);
data->multi_data.bs_mbuts = UI_butstore_create(but_active->block);
@@ -1016,6 +1100,24 @@ static void ui_multibut_states_apply(bContext *C, uiHandleButtonData *data, uiBl
void *active_back;
ui_but_execute_begin(C, ar, but, &active_back);
+
+#ifdef USE_ALLSELECT
+ if (data->select_others.is_enabled) {
+ /* init once! */
+ if (mbut_state->select_others.elems_len == 0) {
+ ui_selectcontext_begin(C, but, &mbut_state->select_others);
+ }
+ if (mbut_state->select_others.elems_len == 0) {
+ mbut_state->select_others.elems_len = -1;
+ }
+ }
+
+ /* needed so we apply the right deltas */
+ but->active->origvalue = mbut_state->origvalue;
+ but->active->select_others = mbut_state->select_others;
+ but->active->select_others.do_free = false;
+#endif
+
BLI_assert(active_back == NULL);
/* no need to check 'data->state' here */
if (data->str) {
@@ -1064,8 +1166,9 @@ typedef struct uiDragToggleHandle {
int xy_last[2];
} uiDragToggleHandle;
-static bool ui_drag_toggle_set_xy_xy(bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
- const int xy_src[2], const int xy_dst[2])
+static bool ui_drag_toggle_set_xy_xy(
+ bContext *C, ARegion *ar, const bool is_set, const eButType but_type_start,
+ const int xy_src[2], const int xy_dst[2])
{
/* popups such as layers won't re-evaluate on redraw */
const bool do_check = (ar->regiontype == RGN_TYPE_TEMPORARY);
@@ -1225,6 +1328,267 @@ static bool ui_but_is_drag_toggle(const uiBut *but)
#endif /* USE_DRAG_TOGGLE */
+#ifdef USE_ALLSELECT
+
+static bool ui_selectcontext_begin(
+ bContext *C, uiBut *but, uiSelectContextStore *selctx_data)
+{
+ PointerRNA ptr, lptr, idptr;
+ PropertyRNA *prop, *lprop;
+ bool success = false;
+ int index;
+
+ char *path = NULL;
+ ListBase lb = {NULL};
+
+ ptr = but->rnapoin;
+ prop = but->rnaprop;
+ index = but->rnaindex;
+
+ /* for now don't support whole colors */
+ if (index == -1)
+ return false;
+
+ /* if there is a valid property that is editable... */
+ if (ptr.data && prop) {
+ CollectionPointerLink *link;
+ bool use_path_from_id;
+ int i;
+
+ /* some facts we want to know */
+ const bool is_array = RNA_property_array_check(prop);
+ const int rna_type = RNA_property_type(prop);
+
+ if (!UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path)) {
+ goto finally;
+ }
+
+ selctx_data->elems_len = BLI_listbase_count(&lb);
+ if (selctx_data->elems_len == 0) {
+ goto finally;
+ }
+
+ selctx_data->elems = MEM_mallocN(sizeof(uiSelectContextElem) * selctx_data->elems_len, __func__);
+
+ for (i = 0, link = lb.first; i < selctx_data->elems_len; i++, link = link->next) {
+ uiSelectContextElem *other = &selctx_data->elems[i];
+ /* TODO,. de-duplicate copy_to_selected_button */
+ if (link->ptr.data != ptr.data) {
+ if (use_path_from_id) {
+ /* Path relative to ID. */
+ lprop = NULL;
+ RNA_id_pointer_create(link->ptr.id.data, &idptr);
+ RNA_path_resolve_property(&idptr, path, &lptr, &lprop);
+ }
+ else if (path) {
+ /* Path relative to elements from list. */
+ lprop = NULL;
+ RNA_path_resolve_property(&link->ptr, path, &lptr, &lprop);
+ }
+ else {
+ lptr = link->ptr;
+ lprop = prop;
+ }
+
+ /* lptr might not be the same as link->ptr! */
+ if ((lptr.data != ptr.data) &&
+ (lprop == prop) &&
+ RNA_property_editable(&lptr, lprop))
+ {
+ other->ptr = lptr;
+ if (is_array) {
+ if (rna_type == PROP_FLOAT) {
+ other->val_f = RNA_property_float_get_index(&lptr, lprop, index);
+ }
+ else if (rna_type == PROP_INT) {
+ other->val_i = RNA_property_int_get_index(&lptr, lprop, index);
+ }
+ /* ignored for now */
+#if 0
+ else if (rna_type == PROP_BOOLEAN) {
+ other->val_b = RNA_property_boolean_get_index(&lptr, lprop, index);
+ }
+#endif
+ }
+ else {
+ if (rna_type == PROP_FLOAT) {
+ other->val_f = RNA_property_float_get(&lptr, lprop);
+ }
+ else if (rna_type == PROP_INT) {
+ other->val_i = RNA_property_int_get(&lptr, lprop);
+ }
+ /* ignored for now */
+#if 0
+ else if (rna_type == PROP_BOOLEAN) {
+ other->val_b = RNA_property_boolean_get(&lptr, lprop);
+ }
+ else if (rna_type == PROP_ENUM) {
+ other->val_i = RNA_property_enum_get(&lptr, lprop);
+ }
+#endif
+ }
+
+ continue;
+ }
+ }
+
+ selctx_data->elems_len -= 1;
+ i -= 1;
+ }
+ }
+
+ success = (selctx_data->elems_len != 0);
+
+finally:
+ if (selctx_data->elems_len == 0) {
+ MEM_SAFE_FREE(selctx_data->elems);
+ }
+
+ MEM_SAFE_FREE(path);
+ BLI_freelistN(&lb);
+
+ /* caller can clear */
+ selctx_data->do_free = true;
+
+ if (success) {
+ but->flag |= UI_BUT_IS_SELECT_CONTEXT;
+ }
+
+ return success;
+}
+
+static void ui_selectcontext_end(
+ uiBut *but, uiSelectContextStore *selctx_data)
+{
+ if (selctx_data->do_free) {
+ if (selctx_data->elems) {
+ MEM_freeN(selctx_data->elems);
+ }
+ }
+
+ but->flag &= ~UI_BUT_IS_SELECT_CONTEXT;
+}
+
+static void ui_selectcontext_apply(
+ bContext *C, uiBut *but, uiSelectContextStore *selctx_data,
+ const double value, const double value_orig)
+{
+ if (selctx_data->elems) {
+ PropertyRNA *prop = but->rnaprop;
+ PropertyRNA *lprop = but->rnaprop;
+ int index = but->rnaindex;
+ int i;
+ const bool use_delta = (selctx_data->is_copy == false);
+
+ union {
+ bool b;
+ int i;
+ float f;
+ } delta, min, max;
+
+ const bool is_array = RNA_property_array_check(prop);
+ const int rna_type = RNA_property_type(prop);
+
+ if (rna_type == PROP_FLOAT) {
+ delta.f = use_delta ? (value - value_orig) : value;
+ RNA_property_float_range(&but->rnapoin, prop, &min.f, &max.f);
+ }
+ else if (rna_type == PROP_INT) {
+ delta.i = use_delta ? ((int)value - (int)value_orig) : (int)value;
+ RNA_property_int_range(&but->rnapoin, prop, &min.i, &max.i);
+ }
+ else if (rna_type == PROP_ENUM) {
+ delta.i = RNA_property_enum_get(&but->rnapoin, prop); /* not a delta infact */
+ }
+ else if (rna_type == PROP_BOOLEAN) {
+ if (is_array) {
+ delta.b = RNA_property_boolean_get_index(&but->rnapoin, prop, index); /* not a delta infact */
+ }
+ else {
+ delta.b = RNA_property_boolean_get(&but->rnapoin, prop); /* not a delta infact */
+ }
+ }
+
+#ifdef USE_ALLSELECT_LAYER_HACK
+ /* make up for not having 'handle_layer_buttons' */
+ {
+ PropertySubType subtype = RNA_property_subtype(prop);
+
+ if ((rna_type == PROP_BOOLEAN) &&
+ ELEM(subtype, PROP_LAYER, PROP_LAYER_MEMBER) &&
+ is_array &&
+ /* could check for 'handle_layer_buttons' */
+ but->func)
+ {
+ wmWindow *win = CTX_wm_window(C);
+ if (!win->eventstate->shift) {
+ const int len = RNA_property_array_length(&but->rnapoin, prop);
+ int *tmparray = MEM_callocN(sizeof(int) * len, __func__);
+
+ tmparray[index] = true;
+
+ for (i = 0; i < selctx_data->elems_len; i++) {
+ uiSelectContextElem *other = &selctx_data->elems[i];
+ PointerRNA lptr = other->ptr;
+ RNA_property_boolean_set_array(&lptr, lprop, tmparray);
+ RNA_property_update(C, &lptr, lprop);
+ }
+
+ MEM_freeN(tmparray);
+
+ return;
+ }
+ }
+ }
+#endif
+
+ for (i = 0; i < selctx_data->elems_len; i++) {
+ uiSelectContextElem *other = &selctx_data->elems[i];
+ PointerRNA lptr = other->ptr;
+
+ if (rna_type == PROP_FLOAT) {
+ float other_value = use_delta ? (other->val_f + delta.f) : delta.f;
+ CLAMP(other_value, min.f, max.f);
+ if (is_array) {
+ RNA_property_float_set_index(&lptr, lprop, index, other_value);
+ }
+ else {
+ RNA_property_float_set(&lptr, lprop, other_value);
+ }
+ }
+ else if (rna_type == PROP_INT) {
+ int other_value = use_delta ? (other->val_i + delta.i) : delta.i;
+ CLAMP(other_value, min.i, max.i);
+ if (is_array) {
+ RNA_property_int_set_index(&lptr, lprop, index, other_value);
+ }
+ else {
+ RNA_property_int_set(&lptr, lprop, other_value);
+ }
+ }
+ else if (rna_type == PROP_BOOLEAN) {
+ const bool other_value = delta.b;
+ if (is_array) {
+ RNA_property_boolean_set_index(&lptr, lprop, index, other_value);
+ }
+ else {
+ RNA_property_boolean_set(&lptr, lprop, delta.b);
+ }
+ }
+ else if (rna_type == PROP_ENUM) {
+ const int other_value = delta.i;
+ BLI_assert(!is_array);
+ RNA_property_enum_set(&lptr, lprop, other_value);
+ }
+
+ RNA_property_update(C, &lptr, prop);
+ }
+ }
+}
+
+#endif /* USE_ALLSELECT */
+
+
static bool ui_but_contains_point_px_icon(uiBut *but, ARegion *ar, const wmEvent *event)
{
rcti rect;
@@ -1278,10 +1642,11 @@ static bool ui_but_drag_init(bContext *C, uiBut *but, uiHandleButtonData *data,
ar_prev = CTX_wm_region(C);
CTX_wm_region_set(C, data->region);
- WM_event_add_ui_handler(C, &data->window->modalhandlers,
- ui_handler_region_drag_toggle,
- ui_handler_region_drag_toggle_remove,
- drag_info, false);
+ WM_event_add_ui_handler(
+ C, &data->window->modalhandlers,
+ ui_handler_region_drag_toggle,
+ ui_handler_region_drag_toggle_remove,
+ drag_info, WM_HANDLER_BLOCKING);
CTX_wm_region_set(C, ar_prev);
}
@@ -1596,9 +1961,8 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
data->str = data->origstr;
data->origstr = NULL;
data->value = data->origvalue;
- data->origvalue = 0.0;
copy_v3_v3(data->vec, data->origvec);
- data->origvec[0] = data->origvec[1] = data->origvec[2] = 0.0f;
+ /* postpone clearing origdata */
}
else {
/* we avoid applying interactive edits a second time
@@ -1609,6 +1973,27 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
else if (data->applied_interactive) {
return;
}
+
+#ifdef USE_ALLSELECT
+# ifdef USE_DRAG_MULTINUM
+ if (but->flag & UI_BUT_DRAG_MULTI) {
+ /* pass */
+ }
+ else
+# endif
+ if (data->select_others.elems_len == 0) {
+ wmWindow *win = CTX_wm_window(C);
+ /* may have been enabled before activating */
+ if (data->select_others.is_enabled || IS_ALLSELECT_EVENT(win->eventstate)) {
+ ui_selectcontext_begin(C, but, &data->select_others);
+ data->select_others.is_enabled = true;
+ }
+ }
+ if (data->select_others.elems_len == 0) {
+ /* dont check again */
+ data->select_others.elems_len = -1;
+ }
+#endif
}
/* ensures we are writing actual values */
@@ -1629,7 +2014,6 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
ui_apply_but_BUT(C, but, data);
break;
case UI_BTYPE_TEXT:
- case UI_BTYPE_SEARCH_MENU_UNLINK:
case UI_BTYPE_SEARCH_MENU:
ui_apply_but_TEX(C, but, data);
break;
@@ -1705,7 +2089,7 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
if (data->multi_data.has_mbuts) {
if (data->multi_data.init == BUTTON_MULTI_INIT_ENABLE) {
if (data->cancel) {
- ui_multibut_restore(data, block);
+ ui_multibut_restore(C, data, block);
}
else {
ui_multibut_states_apply(C, data, block);
@@ -1714,6 +2098,15 @@ static void ui_apply_but(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
}
#endif
+#ifdef USE_ALLSELECT
+ ui_selectcontext_apply(C, but, &data->select_others, data->value, data->origvalue);
+#endif
+
+ if (data->cancel) {
+ data->origvalue = 0.0;
+ zero_v3(data->origvec);
+ }
+
but->editstr = editstr;
but->editval = editval;
but->editvec = editvec;
@@ -1732,13 +2125,13 @@ static void ui_but_drop(bContext *C, const wmEvent *event, uiBut *but, uiHandleB
for (wmd = drags->first; wmd; wmd = wmd->next) {
if (wmd->type == WM_DRAG_ID) {
/* align these types with UI_but_active_drop_name */
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
ID *id = (ID *)wmd->poin;
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
BLI_strncpy(data->str, id->name + 2, data->maxlen);
- if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_SEARCH_MENU)) {
but->changed = true;
ui_searchbox_update(C, data->searchbox, but, true);
}
@@ -1879,7 +2272,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
/* text/string and ID data */
- else if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ else if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
uiHandleButtonData *active_data = but->active;
if (but->poin == NULL && but->rnapoin.data == NULL) {
@@ -1899,7 +2292,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
else
BLI_strncpy(active_data->str, buf_paste, active_data->maxlen);
- if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (but->type == UI_BTYPE_SEARCH_MENU) {
/* else uiSearchboxData.active member is not updated [#26856] */
but->changed = true;
ui_searchbox_update(C, data->searchbox, but, true);
@@ -1974,15 +2367,17 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
}
}
-/* ************************ password text ******************************
+/**
+ * Password Text
+ * =============
*
* Functions to convert password strings that should not be displayed
- * to asterisk representation (e.g. mysecretpasswd -> *************)
+ * to asterisk representation (e.g. 'mysecretpasswd' -> '*************')
*
* It converts every UTF-8 character to an asterisk, and also remaps
* the cursor position and selection start/end.
*
- * Note: remaping is used, because password could contain UTF-8 characters.
+ * \note: remaping is used, because password could contain UTF-8 characters.
*
*/
@@ -2092,7 +2487,7 @@ static void ui_textedit_set_cursor_pos(uiBut *but, uiHandleButtonData *data, con
BLI_strncpy(origstr, but->editstr, data->maxlen);
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
if (but->flag & UI_HAS_ICON) {
startx += UI_DPI_ICON_SIZE / aspect;
}
@@ -2182,11 +2577,13 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data,
ui_but_update(but);
}
-/* this is used for both utf8 and ascii, its meant to be used for single keys,
+/**
+ * This is used for both utf8 and ascii, its meant to be used for single keys,
* notice the buffer is either copied or not, so its not suitable for pasting in
* - campbell */
-static bool ui_textedit_type_buf(uiBut *but, uiHandleButtonData *data,
- const char *utf8_buf, int utf8_buf_len)
+static bool ui_textedit_type_buf(
+ uiBut *but, uiHandleButtonData *data,
+ const char *utf8_buf, int utf8_buf_len)
{
char *str;
int len;
@@ -2230,8 +2627,9 @@ static bool ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char as
return ui_textedit_type_buf(but, data, buf, 1);
}
-static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, strCursorJumpDirection direction,
- const bool select, strCursorJumpType jump)
+static void ui_textedit_move(
+ uiBut *but, uiHandleButtonData *data, strCursorJumpDirection direction,
+ const bool select, strCursorJumpType jump)
{
const char *str = data->str;
const int len = strlen(str);
@@ -2447,6 +2845,18 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in
}
#ifdef WITH_INPUT_IME
+/* test if the translation context allows IME input - used to
+ * avoid weird character drawing if IME inputs non-ascii chars */
+static bool ui_ime_is_lang_supported(void)
+{
+ const char *uilng = BLF_lang_get();
+ const bool is_lang_supported = STREQ(uilng, "zh_CN") ||
+ STREQ(uilng, "zh_TW") ||
+ STREQ(uilng, "ja_JP");
+
+ return ((U.transopts & USER_DOTRANSLATE) && is_lang_supported);
+}
+
/* enable ime, and set up uibut ime data */
static void ui_textedit_ime_begin(wmWindow *win, uiBut *UNUSED(but))
{
@@ -2477,8 +2887,7 @@ void ui_but_ime_reposition(uiBut *but, int x, int y, bool complete)
wm_window_IME_begin(but->active->window, x, y - 4, 0, 0, complete);
}
-/* should be ui_but_ime_data_get */
-wmIMEData *ui_but_get_ime_data(uiBut *but)
+wmIMEData *ui_but_ime_data_get(uiBut *but)
{
if (but->active && but->active->window) {
return but->active->window->ime_data;
@@ -2512,6 +2921,16 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
}
#endif
+#ifdef USE_ALLSELECT
+ if (is_num_but) {
+ if (IS_ALLSELECT_EVENT(win->eventstate)) {
+ data->select_others.is_enabled = true;
+ data->select_others.is_copy = true;
+
+ }
+ }
+#endif
+
/* retrieve string */
data->maxlen = ui_but_string_get_max_length(but);
data->str = MEM_callocN(sizeof(char) * data->maxlen + 1, "textedit str");
@@ -2539,7 +2958,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
but->selend = len;
/* optional searchbox */
- if (ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (but->type == UI_BTYPE_SEARCH_MENU) {
data->searchbox = ui_searchbox_create(C, data->region, but);
ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */
}
@@ -2552,7 +2971,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
WM_cursor_modal_set(win, BC_TEXTEDITCURSOR);
#ifdef WITH_INPUT_IME
- if (is_num_but == false) {
+ if (is_num_but == false && ui_ime_is_lang_supported()) {
ui_textedit_ime_begin(win, but);
}
#endif
@@ -2789,6 +3208,9 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
ui_searchbox_event(C, data->searchbox, but, event);
break;
}
+ if (event->type == WHEELDOWNMOUSE) {
+ break;
+ }
/* fall-through */
case ENDKEY:
ui_textedit_move(but, data, STRCUR_DIR_NEXT,
@@ -2804,6 +3226,9 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
ui_searchbox_event(C, data->searchbox, but, event);
break;
}
+ if (event->type == WHEELUPMOUSE) {
+ break;
+ }
/* fall-through */
case HOMEKEY:
ui_textedit_move(but, data, STRCUR_DIR_PREV,
@@ -2854,8 +3279,6 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
if (autocomplete == AUTOCOMPLETE_FULL_MATCH)
button_activate_state(C, but, BUTTON_STATE_EXIT);
-
- update = true; /* do live update for tab key */
}
/* the hotkey here is not well defined, was G.qual so we check all */
else if (IS_EVENT_MOD(event, shift, ctrl, alt, oskey)) {
@@ -2934,7 +3357,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
#endif
if (changed) {
- /* only update when typing for TAB key */
+ /* only do live update when but flag request it (UI_BUT_TEXTEDIT_UPDATE). */
if (update && data->interactive) {
ui_apply_but(C, block, but, data, true);
}
@@ -3092,6 +3515,15 @@ static void ui_block_open_begin(bContext *C, uiBut *but, uiHandleButtonData *dat
data->menu->popup = but->block->handle->popup;
}
+#ifdef USE_ALLSELECT
+ {
+ wmWindow *win = CTX_wm_window(C);
+ if (IS_ALLSELECT_EVENT(win->eventstate)) {
+ data->select_others.is_enabled = true;
+ }
+ }
+#endif
+
/* this makes adjacent blocks auto open from now on */
//if (but->block->auto_open == 0) but->block->auto_open = 1;
}
@@ -3121,9 +3553,13 @@ int ui_but_menu_direction(uiBut *but)
return 0;
}
-/* Hack for uiList UI_BTYPE_LISTROW buttons to "give" events to overlaying UI_BTYPE_TEXT buttons (cltr-clic rename feature & co). */
-static uiBut *ui_but_list_row_text_activate(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event,
- uiButtonActivateType activate_type)
+/**
+ * Hack for #uiList #UI_BTYPE_LISTROW buttons to "give" events to overlaying #UI_BTYPE_TEXT buttons
+ * (Ctrl-Click rename feature & co).
+ */
+static uiBut *ui_but_list_row_text_activate(
+ bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event,
+ uiButtonActivateType activate_type)
{
ARegion *ar = CTX_wm_region(C);
uiBut *labelbut = ui_but_find_mouse_over_ex(ar, event->x, event->y, true);
@@ -3293,9 +3729,11 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
+ uiButExtraIconType extra_icon_type;
+
/* unlink icon is on right */
- if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY) && event->val == KM_PRESS &&
- ui_but_is_search_unlink_visible(but))
+ if ((ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY)) &&
+ ((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE))
{
ARegion *ar = data->region;
rcti rect;
@@ -3306,14 +3744,29 @@ static int ui_do_but_SEARCH_UNLINK(bContext *C, uiBlock *block, uiBut *but, uiHa
BLI_rcti_rctf_copy(&rect, &but->rect);
rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect));
+ /* handle click on unlink/eyedropper icon */
if (BLI_rcti_isect_pt(&rect, x, y)) {
- /* most likely NULL, but let's check, and give it temp zero string */
- if (data->str == NULL)
- data->str = MEM_callocN(1, "temp str");
- data->str[0] = 0;
+ /* doing this on KM_PRESS calls eyedropper after clicking unlink icon */
+ if (event->val == KM_RELEASE) {
+ /* unlink */
+ if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) {
+ /* most likely NULL, but let's check, and give it temp zero string */
+ if (data->str == NULL) {
+ data->str = MEM_callocN(1, "temp str");
+ }
+ data->str[0] = 0;
- ui_apply_but_TEX(C, but, data);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
+ ui_apply_but_TEX(C, but, data);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ /* eyedropper */
+ else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
+ WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL);
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
return WM_UI_HANDLER_BREAK;
}
@@ -3352,7 +3805,7 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons
button_activate_state(C, but, BUTTON_STATE_EXIT);
return WM_UI_HANDLER_BREAK;
}
- else if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
+ else if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
/* Support alt+wheel on expanded enum rows */
if (but->type == UI_BTYPE_ROW) {
const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
@@ -3448,8 +3901,9 @@ static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, con
}
/* var names match ui_numedit_but_NUM */
-static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, float softmax, float softrange,
- const enum eSnapType snap)
+static float ui_numedit_apply_snapf(
+ uiBut *but, float tempf, float softmin, float softmax, float softrange,
+ const enum eSnapType snap)
{
if (tempf == softmin || tempf == softmax || snap == SNAP_OFF) {
/* pass */
@@ -3477,15 +3931,25 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa
softrange /= fac;
}
+ /* workaround, too high snapping values */
+ /* snapping by 10's for float buttons is quite annoying (location, scale...),
+ * but allow for rotations */
+ if ((softrange > 2100.0f)) {
+ int unit_type = UI_but_unit_type_get(but);
+ if (!ELEM(unit_type, PROP_UNIT_ROTATION)) {
+ softrange = 20.0f;
+ }
+ }
+
if (snap == SNAP_ON) {
- if (softrange < 2.10f) tempf = 0.1f * floorf(10.0f * tempf);
- else if (softrange < 21.0f) tempf = floorf(tempf);
- else tempf = 10.0f * floorf(tempf / 10.0f);
+ if (softrange < 2.10f) tempf = roundf(tempf * 10.0f) * 0.1f;
+ else if (softrange < 21.0f) tempf = roundf(tempf);
+ else tempf = roundf(tempf * 0.1f) * 10.0f;
}
else if (snap == SNAP_ON_SMALL) {
- if (softrange < 2.10f) tempf = 0.01f * floorf(100.0f * tempf);
- else if (softrange < 21.0f) tempf = 0.1f * floorf(10.0f * tempf);
- else tempf = floor(tempf);
+ if (softrange < 2.10f) tempf = roundf(tempf * 100.0f) * 0.01f;
+ else if (softrange < 21.0f) tempf = roundf(tempf * 10.0f) * 0.1f;
+ else tempf = roundf(tempf);
}
else {
BLI_assert(0);
@@ -3498,8 +3962,9 @@ static float ui_numedit_apply_snapf(uiBut *but, float tempf, float softmin, floa
return tempf;
}
-static float ui_numedit_apply_snap(int temp, float softmin, float softmax,
- const enum eSnapType snap)
+static float ui_numedit_apply_snap(
+ int temp, float softmin, float softmax,
+ const enum eSnapType snap)
{
if (temp == softmin || temp == softmax)
return temp;
@@ -3518,9 +3983,10 @@ static float ui_numedit_apply_snap(int temp, float softmin, float softmax,
return temp;
}
-static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data,
- int mx,
- const enum eSnapType snap, float fac)
+static bool ui_numedit_but_NUM(
+ uiBut *but, uiHandleButtonData *data,
+ int mx,
+ const enum eSnapType snap, float fac)
{
float deler, tempf, softmin, softmax, softrange;
int lvalue, temp;
@@ -3636,7 +4102,7 @@ static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data,
if (!is_float) {
- temp = floorf(tempf + 0.5f);
+ temp = iroundf(tempf);
temp = ui_numedit_apply_snap(temp, softmin, softmax, snap);
@@ -3689,11 +4155,11 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
/* XXX hardcoded keymap check.... */
if (type == MOUSEPAN && event->alt)
retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
- else if (type == WHEELDOWNMOUSE && event->alt) {
+ else if (type == WHEELDOWNMOUSE && event->ctrl) {
mx = but->rect.xmin;
click = 1;
}
- else if (type == WHEELUPMOUSE && event->alt) {
+ else if (type == WHEELUPMOUSE && event->ctrl) {
mx = but->rect.xmax;
click = 1;
}
@@ -3759,7 +4225,6 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
fac = 1.0f;
if (event->shift) fac /= 10.0f;
- if (event->alt) fac /= 20.0f;
if (ui_numedit_but_NUM(but, data, (ui_but_is_cursor_warp(but) ? screen_mx : mx), snap, fac))
ui_numedit_apply(C, block, but, data);
@@ -3854,9 +4319,10 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
return retval;
}
-static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
- int mx, const bool is_horizontal,
- const bool snap, const bool shift)
+static bool ui_numedit_but_SLI(
+ uiBut *but, uiHandleButtonData *data,
+ int mx, const bool is_horizontal,
+ const bool snap, const bool shift)
{
float deler, f, tempf, softmin, softmax, softrange;
int temp, lvalue;
@@ -3909,7 +4375,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
tempf = softmin + f * softrange;
- temp = floorf(tempf + 0.5f);
+ temp = iroundf(tempf);
if (snap) {
if (tempf == softmin || tempf == softmax) {
@@ -3919,14 +4385,14 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
if (shift) {
if (tempf == softmin || tempf == softmax) {}
- else if (softmax - softmin < 2.10f) tempf = 0.01f * floorf(100.0f * tempf);
- else if (softmax - softmin < 21.0f) tempf = 0.1f * floorf(10.0f * tempf);
- else tempf = floorf(tempf);
+ else if (softrange < 2.10f) tempf = roundf(tempf * 100.0f) * 0.01f;
+ else if (softrange < 21.0f) tempf = roundf(tempf * 10.0f) * 0.1f;
+ else tempf = roundf(tempf);
}
else {
- if (softmax - softmin < 2.10f) tempf = 0.1f * floorf(10.0f * tempf);
- else if (softmax - softmin < 21.0f) tempf = floorf(tempf);
- else tempf = 10.0f * floorf(tempf / 10.0f);
+ if (softrange < 2.10f) tempf = roundf(tempf * 10.0f) * 0.1f;
+ else if (softrange < 21.0f) tempf = roundf(tempf);
+ else tempf = roundf(tempf * 0.1f) * 10.0f;
}
}
else {
@@ -3936,7 +4402,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
}
if (!ui_but_is_float(but)) {
- lvalue = floor(data->value + 0.5);
+ lvalue = round(data->value);
CLAMP(temp, softmin, softmax);
@@ -3978,11 +4444,11 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
/* XXX hardcoded keymap check.... */
if (type == MOUSEPAN && event->alt)
retval = WM_UI_HANDLER_BREAK; /* allow accumulating values, otherwise scrolling gets preference */
- else if (type == WHEELDOWNMOUSE && event->alt) {
+ else if (type == WHEELDOWNMOUSE && event->ctrl) {
mx = but->rect.xmin;
click = 2;
}
- else if (type == WHEELUPMOUSE && event->alt) {
+ else if (type == WHEELUPMOUSE && event->ctrl) {
mx = but->rect.xmax;
click = 2;
}
@@ -3991,6 +4457,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
retval = WM_UI_HANDLER_BREAK;
}
+#ifndef USE_ALLSELECT
/* alt-click on sides to get "arrows" like in UI_BTYPE_NUM buttons, and match wheel usage above */
else if (event->type == LEFTMOUSE && event->alt) {
int halfpos = BLI_rctf_cent_x(&but->rect);
@@ -4000,6 +4467,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
else
mx = but->rect.xmax;
}
+#endif
else if (event->type == LEFTMOUSE) {
data->dragstartx = mx;
data->draglastx = mx;
@@ -4286,7 +4754,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
return WM_UI_HANDLER_BREAK;
}
else if (but->type == UI_BTYPE_MENU) {
- if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
+ if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1;
data->value = ui_but_menu_step(but, direction);
@@ -4342,9 +4810,10 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co
return WM_UI_HANDLER_CONTINUE;
}
-static bool ui_numedit_but_UNITVEC(uiBut *but, uiHandleButtonData *data,
- int mx, int my,
- const enum eSnapType snap)
+static bool ui_numedit_but_UNITVEC(
+ uiBut *but, uiHandleButtonData *data,
+ int mx, int my,
+ const enum eSnapType snap)
{
float dx, dy, rad, radsq, mrad, *fp;
int mdx, mdy;
@@ -4410,7 +4879,7 @@ static bool ui_numedit_but_UNITVEC(uiBut *but, uiHandleButtonData *data,
* do this in "angle" space - this gives increments of same size */
for (i = 0; i < 3; i++) {
angle = asinf(fp[i]);
- angle_snap = floorf(0.5f + (angle / snap_steps_angle)) * snap_steps_angle;
+ angle_snap = roundf((angle / snap_steps_angle)) * snap_steps_angle;
fp[i] = sinf(angle_snap);
}
normalize_v3(fp);
@@ -4460,7 +4929,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
return WM_UI_HANDLER_BREAK;
}
- else if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) {
+ else if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) {
ColorPicker *cpicker = but->custom_data;
float hsv_static[3] = {0.0f};
float *hsv = cpicker ? cpicker->color_data : hsv_static;
@@ -4644,9 +5113,10 @@ static void ui_color_picker_to_rgb_HSVCUBE_v(uiBut *but, const float hsv[3], flo
hsv_to_rgb_v(hsv, rgb);
}
-static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
- int mx, int my,
- const enum eSnapType snap, const bool shift)
+static bool ui_numedit_but_HSVCUBE(
+ uiBut *but, uiHandleButtonData *data,
+ int mx, int my,
+ const enum eSnapType snap, const bool shift)
{
ColorPicker *cpicker = but->custom_data;
float *hsv = cpicker->color_data;
@@ -4705,8 +5175,8 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
switch ((int)but->a1) {
case UI_GRAD_SV:
- hsv[2] = x;
- hsv[1] = y;
+ hsv[1] = x;
+ hsv[2] = y;
break;
case UI_GRAD_HV:
hsv[0] = x;
@@ -4763,9 +5233,10 @@ static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
return changed;
}
-static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
- const wmNDOFMotionData *ndof,
- const enum eSnapType snap, const bool shift)
+static void ui_ndofedit_but_HSVCUBE(
+ uiBut *but, uiHandleButtonData *data,
+ const wmNDOFMotionData *ndof,
+ const enum eSnapType snap, const bool shift)
{
ColorPicker *cpicker = but->custom_data;
float *hsv = cpicker->color_data;
@@ -4783,8 +5254,8 @@ static void ui_ndofedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data,
switch ((int)but->a1) {
case UI_GRAD_SV:
- hsv[2] += ndof->rvec[2] * sensitivity;
- hsv[1] += ndof->rvec[0] * sensitivity;
+ hsv[1] += ndof->rvec[2] * sensitivity;
+ hsv[2] += ndof->rvec[0] * sensitivity;
break;
case UI_GRAD_HV:
hsv[0] += ndof->rvec[2] * sensitivity;
@@ -4928,9 +5399,10 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu
return WM_UI_HANDLER_CONTINUE;
}
-static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
- float mx, float my,
- const enum eSnapType snap, const bool shift)
+static bool ui_numedit_but_HSVCIRCLE(
+ uiBut *but, uiHandleButtonData *data,
+ float mx, float my,
+ const enum eSnapType snap, const bool shift)
{
rcti rect;
bool changed = true;
@@ -5025,9 +5497,10 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
return changed;
}
-static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data,
- const wmNDOFMotionData *ndof,
- const enum eSnapType snap, const bool shift)
+static void ui_ndofedit_but_HSVCIRCLE(
+ uiBut *but, uiHandleButtonData *data,
+ const wmNDOFMotionData *ndof,
+ const enum eSnapType snap, const bool shift)
{
ColorPicker *cpicker = but->custom_data;
float *hsv = cpicker->color_data;
@@ -5286,7 +5759,8 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle
return WM_UI_HANDLER_CONTINUE;
}
-static bool ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData *data,
+static bool ui_numedit_but_CURVE(
+ uiBlock *block, uiBut *but, uiHandleButtonData *data,
int evtx, int evty,
bool snap, const bool shift)
{
@@ -5336,8 +5810,8 @@ static bool ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData
cmp[a].x += fx;
cmp[a].y += fy;
if (snap) {
- cmp[a].x = 0.125f * floorf(0.5f + 8.0f * cmp[a].x);
- cmp[a].y = 0.125f * floorf(0.5f + 8.0f * cmp[a].y);
+ cmp[a].x = 0.125f * roundf(8.0f * cmp[a].x);
+ cmp[a].y = 0.125f * roundf(8.0f * cmp[a].y);
}
if (cmp[a].x != origx || cmp[a].y != origy)
moved_point = true;
@@ -5720,9 +6194,10 @@ static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, con
return WM_UI_HANDLER_CONTINUE;
}
-static bool ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data,
- int mx, int my,
- const bool shift)
+static bool ui_numedit_but_TRACKPREVIEW(
+ bContext *C, uiBut *but, uiHandleButtonData *data,
+ int mx, int my,
+ const bool shift)
{
MovieClipScopes *scopes = (MovieClipScopes *)but->poin;
bool changed = true;
@@ -5931,7 +6406,7 @@ static void menu_add_shortcut_cancel(struct bContext *C, void *arg1)
static void popup_change_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
uiBut *but = (uiBut *)arg1;
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
UI_popup_block_invoke(C, menu_change_shortcut, but);
}
@@ -5952,7 +6427,7 @@ static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
uiBut *but = (uiBut *)arg1;
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but);
}
@@ -6001,7 +6476,7 @@ static bool ui_but_menu(bContext *C, uiBut *but)
return false;
}
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
/* highly unlikely getting the label ever fails */
UI_but_string_info_get(C, but, &label, NULL);
@@ -6070,7 +6545,7 @@ static bool ui_but_menu(bContext *C, uiBut *but)
}
}
- if (but->flag & UI_BUT_ANIMATED) {
+ if ((but->flag & UI_BUT_ANIMATED) && (but->rnapoin.type != &RNA_NlaStrip)) {
if (is_array_component) {
uiItemBooleanO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Clear Keyframes"),
ICON_NONE, "ANIM_OT_keyframe_clear_button", "all", 1);
@@ -6217,7 +6692,7 @@ static bool ui_but_menu(bContext *C, uiBut *but)
}
/* Show header tools for header buttons. */
- {
+ if (ui_block_is_menu(but->block) == false) {
ARegion *ar = CTX_wm_region(C);
if (ar && (ar->regiontype == RGN_TYPE_HEADER)) {
uiItemMenuF(layout, IFACE_("Header"), ICON_NONE, ED_screens_header_tools_menu_create, NULL);
@@ -6229,14 +6704,9 @@ static bool ui_but_menu(bContext *C, uiBut *but)
char buf[512];
PointerRNA ptr_props;
- if (but->rnapoin.data && but->rnaprop) {
- BLI_snprintf(buf, sizeof(buf), "%s.%s",
- RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop));
-
- WM_operator_properties_create(&ptr_props, "WM_OT_doc_view_manual");
- RNA_string_set(&ptr_props, "doc_id", buf);
- uiItemFullO(layout, "WM_OT_doc_view_manual", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
- ICON_NONE, ptr_props.data, WM_OP_EXEC_DEFAULT, 0);
+ if (UI_but_online_manual_id(but, buf, sizeof(buf))) {
+ uiItemO(layout, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
+ ICON_NONE, "WM_OT_doc_view_manual_ui_context");
WM_operator_properties_create(&ptr_props, "WM_OT_doc_view");
RNA_string_set(&ptr_props, "doc_id", buf);
@@ -6252,30 +6722,6 @@ static bool ui_but_menu(bContext *C, uiBut *but)
uiItemFullO(layout, "WM_OT_doc_edit", "Submit Description", ICON_NONE, ptr_props.data, WM_OP_INVOKE_DEFAULT, 0);
#endif
}
- else if (but->optype) {
- WM_operator_py_idname(buf, but->optype->idname);
-
-
- WM_operator_properties_create(&ptr_props, "WM_OT_doc_view_manual");
- RNA_string_set(&ptr_props, "doc_id", buf);
- uiItemFullO(layout, "WM_OT_doc_view_manual", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Online Manual"),
- ICON_NONE, ptr_props.data, WM_OP_EXEC_DEFAULT, 0);
-
- WM_operator_properties_create(&ptr_props, "WM_OT_doc_view");
- RNA_string_set(&ptr_props, "doc_id", buf);
- uiItemFullO(layout, "WM_OT_doc_view", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Online Python Reference"),
- ICON_NONE, ptr_props.data, WM_OP_EXEC_DEFAULT, 0);
-
- /* XXX inactive option, not for public! */
-#if 0
- WM_operator_properties_create(&ptr_props, "WM_OT_doc_edit");
- RNA_string_set(&ptr_props, "doc_id", buf);
- RNA_string_set(&ptr_props, "doc_new", but->optype->description);
-
- uiItemFullO(layout, "WM_OT_doc_edit", CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Submit Description"),
- ICON_NONE, ptr_props.data, WM_OP_INVOKE_DEFAULT, 0);
-#endif
- }
}
/* perhaps we should move this into (G.debug & G_DEBUG) - campbell */
@@ -6331,7 +6777,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
WM_operator_name_call(C, "UI_OT_eyedropper_color", WM_OP_INVOKE_DEFAULT, NULL);
return WM_UI_HANDLER_BREAK;
}
- else if (but->type == UI_BTYPE_SEARCH_MENU_UNLINK) {
+ else if ((but->type == UI_BTYPE_SEARCH_MENU) &&
+ (but->flag & UI_BUT_SEARCH_UNLINK))
+ {
if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_POINTER) {
StructRNA *type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
const short idcode = RNA_type_to_ID_code(type);
@@ -6488,11 +6936,16 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
break;
case UI_BTYPE_TEXT:
case UI_BTYPE_SEARCH_MENU:
+ if ((but->type == UI_BTYPE_SEARCH_MENU) &&
+ (but->flag & UI_BUT_SEARCH_UNLINK))
+ {
+ retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
+ if (retval & WM_UI_HANDLER_BREAK) {
+ break;
+ }
+ }
retval = ui_do_but_TEX(C, block, but, data, event);
break;
- case UI_BTYPE_SEARCH_MENU_UNLINK:
- retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
- break;
case UI_BTYPE_MENU:
case UI_BTYPE_BLOCK:
case UI_BTYPE_PULLDOWN:
@@ -6592,8 +7045,13 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
/* just to be sure, check we're dragging more hoz then virt */
abs(event->prevx - event->x) > abs(event->prevy - event->y)))
{
- ui_multibut_states_create(but, data);
- data->multi_data.init = BUTTON_MULTI_INIT_ENABLE;
+ if (data->multi_data.has_mbuts) {
+ ui_multibut_states_create(but, data);
+ data->multi_data.init = BUTTON_MULTI_INIT_ENABLE;
+ }
+ else {
+ data->multi_data.init = BUTTON_MULTI_INIT_DISABLE;
+ }
}
}
@@ -6731,7 +7189,7 @@ bool UI_but_active_drop_name(bContext *C)
uiBut *but = ui_but_find_active_in_region(ar);
if (but) {
- if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK))
+ if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU))
return 1;
}
@@ -6846,13 +7304,6 @@ static bool ui_but_is_interactive(const uiBut *but, const bool labeledit)
return true;
}
-bool ui_but_is_search_unlink_visible(const uiBut *but)
-{
- BLI_assert(but->type == UI_BTYPE_SEARCH_MENU_UNLINK);
- return ((but->editstr == NULL) &&
- (but->drawstr[0] != '\0'));
-}
-
/* x and y are only used in case event is NULL... */
static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, const bool labeledit)
{
@@ -6940,7 +7391,8 @@ static bool button_modal_state(uiHandleButtonState state)
BUTTON_STATE_MENU_OPEN);
}
-static void button_timers_tooltip_remove(bContext *C, uiBut *but)
+/* removes tooltip timer from active but (meaning tooltip is disabled until it's reenabled again) */
+void UI_but_tooltip_timer_remove(bContext *C, uiBut *but)
{
uiHandleButtonData *data;
@@ -7024,7 +7476,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
}
else {
but->flag |= UI_SELECT;
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
}
/* text editing */
@@ -7086,7 +7538,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
if (!(but->block->handle && but->block->handle->popup)) {
if (button_modal_state(state)) {
if (!button_modal_state(data->state))
- WM_event_add_ui_handler(C, &data->window->modalhandlers, ui_handler_region_menu, NULL, data, false);
+ WM_event_add_ui_handler(C, &data->window->modalhandlers, ui_handler_region_menu, NULL, data, 0);
}
else {
if (button_modal_state(data->state)) {
@@ -7131,7 +7583,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
copy_v2_fl(data->ungrab_mval, FLT_MAX);
#endif
- if (ELEM(but->type, UI_BTYPE_CURVE, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK)) {
+ if (ELEM(but->type, UI_BTYPE_CURVE, UI_BTYPE_SEARCH_MENU)) {
/* XXX curve is temp */
}
else {
@@ -7191,8 +7643,9 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
}
}
-static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *data,
- const bool mousemove, const bool onfree)
+static void button_activate_exit(
+ bContext *C, uiBut *but, uiHandleButtonData *data,
+ const bool mousemove, const bool onfree)
{
uiBlock *block = but->block;
uiBut *bt;
@@ -7264,6 +7717,10 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da
if (data->origstr)
MEM_freeN(data->origstr);
+#ifdef USE_ALLSELECT
+ ui_selectcontext_end(but, &data->select_others);
+#endif
+
/* redraw (data is but->active!) */
ED_region_tag_redraw(data->region);
@@ -7470,7 +7927,7 @@ void UI_context_update_anim_flag(const bContext *C)
/************** handle activating a button *************/
-static uiBut *uit_but_find_open_event(ARegion *ar, const wmEvent *event)
+static uiBut *ui_but_find_open_event(ARegion *ar, const wmEvent *event)
{
uiBlock *block;
uiBut *but;
@@ -7501,7 +7958,7 @@ static int ui_handle_button_over(bContext *C, const wmEvent *event, ARegion *ar)
}
}
else if (event->type == EVT_BUT_OPEN) {
- but = uit_but_find_open_event(ar, event);
+ but = ui_but_find_open_event(ar, event);
if (but) {
button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
ui_do_button(C, but->block, but, event);
@@ -7605,7 +8062,8 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
uiBut *but_other = ui_but_find_mouse_over(ar, event);
bool exit = false;
- if ((!ui_block_is_menu(block) || ui_block_is_pie_menu(but->block)) &&
+ /* always deactivate button for pie menus, else moving to blank space will leave activated */
+ if ((!ui_block_is_menu(block) || ui_block_is_pie_menu(block)) &&
!ui_but_contains_point_px(ar, but, event->x, event->y))
{
exit = true;
@@ -7653,7 +8111,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
case WHEELDOWNMOUSE:
case MIDDLEMOUSE:
case MOUSEPAN:
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
/* fall-through */
default:
/* handle button type specific events */
@@ -7814,7 +8272,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar)
if (val == KM_PRESS) {
if (ELEM(type, UPARROWKEY, DOWNARROWKEY) ||
- ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt)))
+ ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->ctrl)))
{
const int value_orig = RNA_property_int_get(&but->rnapoin, but->rnaprop);
int value, min, max, inc;
@@ -7964,13 +8422,14 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u
/* ************************* menu handling *******************************/
-/* function used to prevent loosing the open menu when using nested pulldowns,
+/**
+ * Function used to prevent loosing the open menu when using nested pulldowns,
* when moving mouse towards the pulldown menu over other buttons that could
* steal the highlight from the current button, only checks:
*
* - while mouse moves in triangular area defined old mouse position and
- * left/right side of new menu
- * - only for 1 second
+ * left/right side of new menu.
+ * - only for 1 second.
*/
static void ui_mouse_motion_towards_init_ex(uiPopupBlockHandle *menu, const int xy[2], const bool force)
@@ -7999,8 +8458,9 @@ static void ui_mouse_motion_towards_reinit(uiPopupBlockHandle *menu, const int x
ui_mouse_motion_towards_init_ex(menu, xy, true);
}
-static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, const int xy[2],
- const bool use_wiggle_room)
+static bool ui_mouse_motion_towards_check(
+ uiBlock *block, uiPopupBlockHandle *menu, const int xy[2],
+ const bool use_wiggle_room)
{
float p1[2], p2[2], p3[2], p4[2];
float oldp[2] = {menu->towards_xy[0], menu->towards_xy[1]};
@@ -8188,8 +8648,9 @@ static int ui_menu_scroll(ARegion *ar, uiBlock *block, int my, uiBut *to_bt)
*
* Without this keyboard navigation from menu's wont work.
*/
-static bool ui_menu_pass_event_to_parent_if_nonactive(uiPopupBlockHandle *menu, const uiBut *but,
- const int level, const int retval)
+static bool ui_menu_pass_event_to_parent_if_nonactive(
+ uiPopupBlockHandle *menu, const uiBut *but,
+ const int level, const int retval)
{
if ((level != 0) && (but == NULL)) {
menu->menuretval = UI_RETURN_OUT | UI_RETURN_OUT_PARENT;
@@ -8559,7 +9020,7 @@ static int ui_handle_menu_event(
ui_handle_button_activate(C, ar, but, BUTTON_ACTIVATE);
}
else {
- printf("%s: error, but->menu_key type: %d\n", __func__, but->type);
+ printf("%s: error, but->menu_key type: %u\n", __func__, but->type);
}
break;
@@ -8628,7 +9089,7 @@ static int ui_handle_menu_event(
{
if (!but || !ui_but_contains_point_px(ar, but, event->x, event->y)) {
if (but) {
- button_timers_tooltip_remove(C, but);
+ UI_but_tooltip_timer_remove(C, but);
}
menu->is_grab = true;
@@ -8707,6 +9168,9 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo
block = ar->uiblocks.first;
but = ui_but_find_active_in_region(ar);
+
+ BLI_assert(but);
+
data = but->active;
submenu = data->menu;
@@ -9106,7 +9570,7 @@ static int ui_handle_menus_recursive(
/* now handle events for our own menu */
if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) {
- const bool do_but_search = (but && ELEM(but->type, UI_BTYPE_SEARCH_MENU, UI_BTYPE_SEARCH_MENU_UNLINK));
+ const bool do_but_search = (but && (but->type == UI_BTYPE_SEARCH_MENU));
if (submenu && submenu->menuretval) {
const bool do_ret_out_parent = (submenu->menuretval & UI_RETURN_OUT_PARENT) != 0;
retval = ui_handle_menu_return_submenu(C, event, menu);
@@ -9390,12 +9854,12 @@ static void ui_popup_handler_remove(bContext *C, void *userdata)
void UI_region_handlers_add(ListBase *handlers)
{
WM_event_remove_ui_handler(handlers, ui_region_handler, ui_region_handler_remove, NULL, false);
- WM_event_add_ui_handler(NULL, handlers, ui_region_handler, ui_region_handler_remove, NULL, false);
+ WM_event_add_ui_handler(NULL, handlers, ui_region_handler, ui_region_handler_remove, NULL, 0);
}
-void UI_popup_handlers_add(bContext *C, ListBase *handlers, uiPopupBlockHandle *popup, const bool accept_dbl_click)
+void UI_popup_handlers_add(bContext *C, ListBase *handlers, uiPopupBlockHandle *popup, const char flag)
{
- WM_event_add_ui_handler(C, handlers, ui_popup_handler, ui_popup_handler_remove, popup, accept_dbl_click);
+ WM_event_add_ui_handler(C, handlers, ui_popup_handler, ui_popup_handler_remove, popup, flag);
}
void UI_popup_handlers_remove(ListBase *handlers, uiPopupBlockHandle *popup)
@@ -9408,8 +9872,9 @@ void UI_popup_handlers_remove_all(bContext *C, ListBase *handlers)
WM_event_free_ui_handler_all(C, handlers, ui_popup_handler, ui_popup_handler_remove);
}
-bool UI_textbutton_activate_rna(const bContext *C, ARegion *ar,
- const void *rna_poin_data, const char *rna_prop_id)
+bool UI_textbutton_activate_rna(
+ const bContext *C, ARegion *ar,
+ const void *rna_poin_data, const char *rna_prop_id)
{
uiBlock *block;
uiBut *but = NULL;