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_handlers.c')
-rw-r--r--source/blender/editors/interface/interface_handlers.c67
1 files changed, 53 insertions, 14 deletions
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 0dec751526a..57f9b2ae356 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -304,6 +304,9 @@ typedef struct uiHandleButtonData {
bool used_mouse;
wmTimer *autoopentimer;
+ /* auto open (hold) */
+ wmTimer *hold_action_timer;
+
/* text selection/editing */
/* size of 'str' (including terminator) */
int maxlen;
@@ -7808,6 +7811,15 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
data->flashtimer = NULL;
}
+ /* add hold timer if it's used */
+ if (state == BUTTON_STATE_WAIT_RELEASE && (but->hold_func != NULL)) {
+ data->hold_action_timer = WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_AUTO_OPEN_THRESH);
+ }
+ else if (data->hold_action_timer) {
+ WM_event_remove_timer(data->wm, data->window, data->hold_action_timer);
+ data->hold_action_timer = NULL;
+ }
+
/* add a blocking ui handler at the window handler for blocking, modal states
* but not for popups, because we already have a window level handler*/
if (!(but->block->handle && but->block->handle->popup)) {
@@ -8422,6 +8434,25 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
button_activate_state(C, but, BUTTON_STATE_EXIT);
break;
+ case TIMER:
+ {
+ if (event->customdata == data->hold_action_timer) {
+ if (true) {
+ data->cancel = true;
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ }
+ else {
+ /* Do this so we can still mouse-up, closing the menu and running the button.
+ * This is nice to support but there are times when the button gets left pressed.
+ * Keep disavled for now. */
+ WM_event_remove_timer(data->wm, data->window, data->hold_action_timer);
+ data->hold_action_timer = NULL;
+ }
+ retval = WM_UI_HANDLER_CONTINUE;
+ but->hold_func(C, data->region, but);
+ }
+ break;
+ }
case MOUSEMOVE:
if (ELEM(but->type, UI_BTYPE_LINK, UI_BTYPE_INLINK)) {
but->flag |= UI_SELECT;
@@ -9348,21 +9379,29 @@ static int ui_handle_menu_event(
if (inside == 0) {
uiSafetyRct *saferct = block->saferct.first;
- if (ELEM(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) &&
- ELEM(event->val, KM_PRESS, KM_DBL_CLICK))
- {
- if ((is_parent_menu == false) && (U.uiflag & USER_MENUOPENAUTO) == 0) {
- /* for root menus, allow clicking to close */
- if (block->flag & (UI_BLOCK_OUT_1))
- menu->menuretval = UI_RETURN_OK;
- else
- menu->menuretval = UI_RETURN_OUT;
+ if (ELEM(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE)) {
+ if (ELEM(event->val, KM_PRESS, KM_DBL_CLICK)) {
+ if ((is_parent_menu == false) && (U.uiflag & USER_MENUOPENAUTO) == 0) {
+ /* for root menus, allow clicking to close */
+ if (block->flag & (UI_BLOCK_OUT_1))
+ menu->menuretval = UI_RETURN_OK;
+ else
+ menu->menuretval = UI_RETURN_OUT;
+ }
+ else if (saferct && !BLI_rctf_isect_pt(&saferct->parent, event->x, event->y)) {
+ if (block->flag & (UI_BLOCK_OUT_1))
+ menu->menuretval = UI_RETURN_OK;
+ else
+ menu->menuretval = UI_RETURN_OUT;
+ }
}
- else if (saferct && !BLI_rctf_isect_pt(&saferct->parent, event->x, event->y)) {
- if (block->flag & (UI_BLOCK_OUT_1))
- menu->menuretval = UI_RETURN_OK;
- else
- menu->menuretval = UI_RETURN_OUT;
+ else if (ELEM(event->val, KM_RELEASE, KM_CLICK)) {
+ /* For buttons that use a hold function, exit when mouse-up outside the menu. */
+ if (block->flag & UI_BLOCK_POPUP_HOLD) {
+ /* Note, we could check the cursor is over the parent button. */
+ menu->menuretval = UI_RETURN_CANCEL;
+ retval = WM_UI_HANDLER_CONTINUE;
+ }
}
}
}