From 9d8fa4f959ff704e113d70ed713d1b8aec0ef014 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Sat, 6 Jun 2009 13:35:04 +0000 Subject: 2.5 Several usablity tweaks: - Search menu allows ScrollWheel to view items - Tooltip on button on bottom of window showed wrong - Tooltips were popping up while draggin (MMB) or scrolling (wheel). Now they stay away. - Stolen from Gimp (blame venomgfx for hint!): ScrollWheel allows to go over menu items and use number buttons, only on mouse-over. Note for devs: the WM_event_add_mousemove() call (to add a fake event to bring UI back alive after view changes) now works much more reliably. It ensures the mouse move is only handled after all notifiers/redraws were done. --- .../blender/editors/interface/interface_handlers.c | 52 ++++++++++++++++++++-- .../blender/editors/interface/interface_intern.h | 1 + .../blender/editors/interface/interface_regions.c | 44 +++++++++++++++++- source/blender/editors/screen/screen_edit.c | 3 ++ source/blender/makesdna/DNA_windowmanager_types.h | 2 +- .../blender/windowmanager/intern/wm_event_system.c | 18 +++++--- 6 files changed, 109 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 933d57c8983..b9e4b18761f 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1245,6 +1245,8 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle int mx, my, changed= 0, inbox=0, retval= WM_UI_HANDLER_CONTINUE; switch(event->type) { + case WHEELUPMOUSE: + case WHEELDOWNMOUSE: case MOUSEMOVE: if(data->searchbox) ui_searchbox_event(C, data->searchbox, but, event); @@ -1760,7 +1762,16 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton ui_window_to_block(data->region, block, &mx, &my); if(data->state == BUTTON_STATE_HIGHLIGHT) { - if(event->val==KM_PRESS) { + /* XXX hardcoded keymap check.... */ + if(event->type == WHEELDOWNMOUSE && event->alt) { + mx= but->x1; + click= 1; + } + else if(event->type == WHEELUPMOUSE && event->alt) { + mx= but->x2; + click= 1; + } + else if(event->val==KM_PRESS) { if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->shift) { button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); retval= WM_UI_HANDLER_BREAK; @@ -1774,6 +1785,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton else if(ELEM(event->type, PADENTER, RETKEY) && event->val==KM_PRESS) click= 1; } + } else if(data->state == BUTTON_STATE_NUM_EDITING) { if(event->type == ESCKEY) { @@ -1961,7 +1973,16 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton ui_window_to_block(data->region, block, &mx, &my); if(data->state == BUTTON_STATE_HIGHLIGHT) { - if(event->val==KM_PRESS) { + /* XXX hardcoded keymap check.... */ + if(event->type == WHEELDOWNMOUSE && event->alt) { + mx= but->x1; + click= 2; + } + else if(event->type == WHEELUPMOUSE && event->alt) { + mx= but->x2; + click= 2; + } + else if(event->val==KM_PRESS) { if(ELEM3(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->shift) { button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); retval= WM_UI_HANDLER_BREAK; @@ -2004,7 +2025,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton } if(click) { - if (event->ctrl) { + if (event->ctrl || click==2) { /* nudge slider to the left or right */ float f, tempf, softmin, softmax, softrange; int temp; @@ -2062,6 +2083,21 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm button_activate_state(C, but, BUTTON_STATE_MENU_OPEN); return WM_UI_HANDLER_BREAK; } + else if(ELEM3(but->type, MENU, ICONROW, ICONTEXTROW)) { + + if(event->type == WHEELDOWNMOUSE && event->alt) { + data->value= ui_step_name_menu(but, -1); + button_activate_state(C, but, BUTTON_STATE_EXIT); + ui_apply_button(C, but->block, but, data, 1); + return WM_UI_HANDLER_BREAK; + } + else if(event->type == WHEELUPMOUSE && event->alt) { + data->value= ui_step_name_menu(but, 1); + button_activate_state(C, but, BUTTON_STATE_EXIT); + ui_apply_button(C, but->block, but, data, 1); + return WM_UI_HANDLER_BREAK; + } + } } return WM_UI_HANDLER_CONTINUE; @@ -3232,6 +3268,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but) if(data->state == BUTTON_STATE_HIGHLIGHT) { switch(event->type) { + case MOUSEMOVE: /* verify if we are still over the button, if not exit */ if(!ui_mouse_inside_button(ar, but, event->x, event->y)) { @@ -3265,6 +3302,15 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but) retval= WM_UI_HANDLER_CONTINUE; break; + case WHEELUPMOUSE: + case WHEELDOWNMOUSE: + case MIDDLEMOUSE: + /* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */ + if(data->tooltiptimer) { + WM_event_remove_window_timer(data->window, data->tooltiptimer); + data->tooltiptimer= NULL; + } + /* pass on purposedly */ default: /* handle button type specific events */ retval= ui_do_button(C, block, but, event); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index c6a93d8f74a..cc8451074ef 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -371,6 +371,7 @@ uiPopupBlockHandle *ui_popup_menu_create(struct bContext *C, struct ARegion *but void ui_popup_block_free(struct bContext *C, uiPopupBlockHandle *handle); void ui_set_name_menu(uiBut *but, int value); +int ui_step_name_menu(uiBut *but, int step); struct AutoComplete; struct AutoComplete *autocomplete_begin(char *startname, int maxlen); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 8ea686dfbd6..222c3fe892d 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -225,6 +225,44 @@ void ui_set_name_menu(uiBut *but, int value) menudata_free(md); } +int ui_step_name_menu(uiBut *but, int step) +{ + MenuData *md; + int value= ui_get_but_val(but); + int i; + + md= decompose_menu_string(but->str); + for (i=0; initems; i++) + if (md->items[i].retval==value) + break; + + if(step==1) { + /* skip separators */ + for(; initems-1; i++) { + if(md->items[i+1].retval != -1) { + value= md->items[i+1].retval; + break; + } + } + } + else { + if(i>0) { + /* skip separators */ + for(; i>0; i--) { + if(md->items[i-1].retval != -1) { + value= md->items[i-1].retval; + break; + } + } + } + } + + menudata_free(md); + + return value; +} + + /******************** Creating Temporary regions ******************/ ARegion *ui_add_temporary_region(bScreen *sc) @@ -354,8 +392,8 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) } } if(y1 < 0) { - y1 += 36; - y2 += 36; + y1 += 56*aspect; + y2 += 56*aspect; } /* widget rect, in region coords */ @@ -506,9 +544,11 @@ void ui_searchbox_event(bContext *C, ARegion *ar, uiBut *but, wmEvent *event) uiSearchboxData *data= ar->regiondata; switch(event->type) { + case WHEELUPMOUSE: case UPARROWKEY: ui_searchbox_select(C, ar, but, -1); break; + case WHEELDOWNMOUSE: case DOWNARROWKEY: ui_searchbox_select(C, ar, but, 1); break; diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 93d2ec75e9d..4e08310240c 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1283,6 +1283,9 @@ void ED_screen_set(bContext *C, bScreen *sc) ED_screen_refresh(CTX_wm_manager(C), CTX_wm_window(C)); WM_event_add_notifier(C, NC_WINDOW, NULL); + + /* makes button hilites work */ + WM_event_add_mousemove(C); } } diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index ba423334cce..7d6b5ec8764 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -97,7 +97,7 @@ typedef struct wmWindow { short active; /* set to 1 if an active window, for quick rejects */ short cursor; /* current mouse cursor type */ short lastcursor; /* for temp waitcursor */ - short pad2; + short addmousemove; /* internal: tag this for extra mousemove event, makes cursors/buttons active on UI switching */ int pad3; struct wmEvent *eventstate; /* storage for event system */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 53f70f6ab8f..f5c8e535002 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1088,6 +1088,17 @@ void wm_event_do_handlers(bContext *C) wm_event_free(event); } + + /* only add mousemove when queue was read entirely */ + if(win->addmousemove) { + wmEvent event= *(win->eventstate); + event.type= MOUSEMOVE; + event.prevx= event.x; + event.prevy= event.y; + wm_event_add(win, &event); + win->addmousemove= 0; + } + CTX_wm_window_set(C, NULL); } } @@ -1238,11 +1249,8 @@ void WM_event_remove_ui_handler(ListBase *handlers, wmUIHandlerFunc func, wmUIHa void WM_event_add_mousemove(bContext *C) { wmWindow *window= CTX_wm_window(C); - wmEvent event= *(window->eventstate); - event.type= MOUSEMOVE; - event.prevx= event.x; - event.prevy= event.y; - wm_event_add(window, &event); + + window->addmousemove= 1; } /* for modal callbacks, check configuration for how to interpret exit with tweaks */ -- cgit v1.2.3