2.5
authorTon Roosendaal <ton@blender.org>
Sat, 6 Jun 2009 13:35:04 +0000 (13:35 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 6 Jun 2009 13:35:04 +0000 (13:35 +0000)
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.

source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_regions.c
source/blender/editors/screen/screen_edit.c
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/windowmanager/intern/wm_event_system.c

index 933d57c89832b0d4fce71102bb8cc3394211255b..b9e4b18761f813a61a1faee2566d01e21c089ea4 100644 (file)
@@ -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);
index c6a93d8f74a45d46e6899bd17e082abdf86c8f31..cc8451074ef1387c7ea605dbd45d37811909f99e 100644 (file)
@@ -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);
index 8ea686dfbd6ba728e73f798d3a92a7417db34512..222c3fe892d07d4fffcb503c6a61ac7eb9c9dae3 100644 (file)
@@ -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; i<md->nitems; i++)
+               if (md->items[i].retval==value)
+                       break;
+       
+       if(step==1) {
+               /* skip separators */
+               for(; i<md->nitems-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;
index 93d2ec75e9da0932ed80f173d20690852afac704..4e08310240cc910af254e6d93e59223c6986e582 100644 (file)
@@ -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);
        }
 }
 
index ba423334ccedc814fa5dbd1cb5a5f9715801cfc6..7d6b5ec876436a0636ec6e396b85e52e900b0613 100644 (file)
@@ -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 */
index 53f70f6ab8f131b1c6c9f331d69add333df39590..f5c8e53500286ad565e8677f9bc6319d71138007 100644 (file)
@@ -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  */