Fix T47009: Value typing issue in pie menu.
authorBastien Montagne <montagne29@wanadoo.fr>
Fri, 18 Dec 2015 15:32:51 +0000 (16:32 +0100)
committerBastien Montagne <montagne29@wanadoo.fr>
Fri, 18 Dec 2015 15:32:51 +0000 (16:32 +0100)
When we have an active button in modal state, completely bypass the whole 'pie' handling part of the menu.

Note that behavior is probably still not ideal here (e.g. would be nice to avoid enter/escape to quit
completely the pie menu in that case - but on the other hand Pies were not really designed to handle
that kind of modal stuff either, so think having minimal support for it is enough for now.

source/blender/editors/interface/interface_handlers.c

index 9a85f5b508dcc68cd14b954cca552d4a3415ddad..f72ce5b479d92a29e6a1130af7d243404207eb7b 100644 (file)
@@ -9404,6 +9404,7 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
 {
        ARegion *ar;
        uiBlock *block;
 {
        ARegion *ar;
        uiBlock *block;
+       uiBut *but;
        float event_xy[2];
        double duration;
        bool is_click_style;
        float event_xy[2];
        double duration;
        bool is_click_style;
@@ -9423,6 +9424,9 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
 
        is_click_style = (block->pie_data.flags & UI_PIE_CLICK_STYLE);
 
 
        is_click_style = (block->pie_data.flags & UI_PIE_CLICK_STYLE);
 
+       /* if there's an active modal button, don't check events or outside, except for search menu */
+       but = ui_but_find_active_in_region(ar);
+
        if (menu->scrolltimer == NULL) {
                menu->scrolltimer =
                    WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, PIE_MENU_INTERVAL);
        if (menu->scrolltimer == NULL) {
                menu->scrolltimer =
                    WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, PIE_MENU_INTERVAL);
@@ -9438,209 +9442,214 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
 
        dist = ui_block_calc_pie_segment(block, event_xy);
 
 
        dist = ui_block_calc_pie_segment(block, event_xy);
 
-       if (event->type == TIMER) {
-               if (event->customdata == menu->scrolltimer) {
-                       /* deactivate initial direction after a while */
-                       if (duration > 0.01 * U.pie_initial_timeout) {
-                               block->pie_data.flags &= ~UI_PIE_INITIAL_DIRECTION;
-                       }
+       if (but && button_modal_state(but->active->state)) {
+               retval = ui_handle_menu_button(C, event, menu);
+       }
+       else {
+               if (event->type == TIMER) {
+                       if (event->customdata == menu->scrolltimer) {
+                               /* deactivate initial direction after a while */
+                               if (duration > 0.01 * U.pie_initial_timeout) {
+                                       block->pie_data.flags &= ~UI_PIE_INITIAL_DIRECTION;
+                               }
 
 
-                       /* handle animation */
-                       if (!(block->pie_data.flags & UI_PIE_ANIMATION_FINISHED)) {
-                               double final_time = 0.01 * U.pie_animation_timeout;
-                               float fac = duration / final_time;
-                               float pie_radius = U.pie_menu_radius * UI_DPI_FAC;
+                               /* handle animation */
+                               if (!(block->pie_data.flags & UI_PIE_ANIMATION_FINISHED)) {
+                                       double final_time = 0.01 * U.pie_animation_timeout;
+                                       float fac = duration / final_time;
+                                       float pie_radius = U.pie_menu_radius * UI_DPI_FAC;
 
 
-                               if (fac > 1.0f) {
-                                       fac = 1.0f;
-                                       block->pie_data.flags |= UI_PIE_ANIMATION_FINISHED;
-                               }
+                                       if (fac > 1.0f) {
+                                               fac = 1.0f;
+                                               block->pie_data.flags |= UI_PIE_ANIMATION_FINISHED;
+                                       }
 
 
-                               for (uiBut *but = block->buttons.first; but; but = but->next) {
-                                       if (but->pie_dir != UI_RADIAL_NONE) {
-                                               float vec[2];
-                                               float center[2];
-                       
-                                               ui_but_pie_dir(but->pie_dir, vec);
+                                       for (uiBut *but = block->buttons.first; but; but = but->next) {
+                                               if (but->pie_dir != UI_RADIAL_NONE) {
+                                                       float vec[2];
+                                                       float center[2];
 
 
-                                               center[0] = (vec[0] > 0.01f) ? 0.5f : ((vec[0] < -0.01f) ? -0.5f : 0.0f);
-                                               center[1] = (vec[1] > 0.99f) ? 0.5f : ((vec[1] < -0.99f) ? -0.5f : 0.0f);
+                                                       ui_but_pie_dir(but->pie_dir, vec);
 
 
-                                               center[0] *= BLI_rctf_size_x(&but->rect);
-                                               center[1] *= BLI_rctf_size_y(&but->rect);
-                                               
-                                               mul_v2_fl(vec, pie_radius);
-                                               add_v2_v2(vec, center);
-                                               mul_v2_fl(vec, fac);
-                                               add_v2_v2(vec, block->pie_data.pie_center_spawned);
-                                                           
-                                               BLI_rctf_recenter(&but->rect, vec[0], vec[1]);
+                                                       center[0] = (vec[0] > 0.01f) ? 0.5f : ((vec[0] < -0.01f) ? -0.5f : 0.0f);
+                                                       center[1] = (vec[1] > 0.99f) ? 0.5f : ((vec[1] < -0.99f) ? -0.5f : 0.0f);
+
+                                                       center[0] *= BLI_rctf_size_x(&but->rect);
+                                                       center[1] *= BLI_rctf_size_y(&but->rect);
+
+                                                       mul_v2_fl(vec, pie_radius);
+                                                       add_v2_v2(vec, center);
+                                                       mul_v2_fl(vec, fac);
+                                                       add_v2_v2(vec, block->pie_data.pie_center_spawned);
+
+                                                       BLI_rctf_recenter(&but->rect, vec[0], vec[1]);
+                                               }
                                        }
                                        }
-                               }
-                               block->pie_data.alphafac = fac;
+                                       block->pie_data.alphafac = fac;
 
 
-                               ED_region_tag_redraw(ar);
+                                       ED_region_tag_redraw(ar);
+                               }
                        }
                        }
-               }
 
 
-               /* check pie velociy here if gesture has ended */
-               if (block->pie_data.flags & UI_PIE_GESTURE_END_WAIT) {
-                       float len_sq = 10;
+                       /* check pie velociy here if gesture has ended */
+                       if (block->pie_data.flags & UI_PIE_GESTURE_END_WAIT) {
+                               float len_sq = 10;
 
 
-                       /* use a time threshold to ensure we leave time to the mouse to move */
-                       if (duration - block->pie_data.duration_gesture > 0.02) {
-                               len_sq = len_squared_v2v2(event_xy, block->pie_data.last_pos);
-                               copy_v2_v2(block->pie_data.last_pos, event_xy);
-                               block->pie_data.duration_gesture = duration;
-                       }
+                               /* use a time threshold to ensure we leave time to the mouse to move */
+                               if (duration - block->pie_data.duration_gesture > 0.02) {
+                                       len_sq = len_squared_v2v2(event_xy, block->pie_data.last_pos);
+                                       copy_v2_v2(block->pie_data.last_pos, event_xy);
+                                       block->pie_data.duration_gesture = duration;
+                               }
 
 
-                       if (len_sq < 1.0f) {
-                               uiBut *but = ui_but_find_active_in_region(menu->region);
+                               if (len_sq < 1.0f) {
+                                       uiBut *but = ui_but_find_active_in_region(menu->region);
 
 
-                               if (but) {
-                                       return ui_but_pie_menu_apply(C, menu, but, true);
+                                       if (but) {
+                                               return ui_but_pie_menu_apply(C, menu, but, true);
+                                       }
                                }
                        }
                }
                                }
                        }
                }
-       }
 
 
-       if (event->type == block->pie_data.event && !is_click_style) {
-               if (event->val != KM_RELEASE) {
-                       ui_handle_menu_button(C, event, menu);
+               if (event->type == block->pie_data.event && !is_click_style) {
+                       if (event->val != KM_RELEASE) {
+                               ui_handle_menu_button(C, event, menu);
 
 
-                       if (len_squared_v2v2(event_xy, block->pie_data.pie_center_init) > PIE_CLICK_THRESHOLD_SQ) {
-                               block->pie_data.flags |= UI_PIE_DRAG_STYLE;
-                       }
-                       /* why redraw here? It's simple, we are getting many double click events here.
-                        * Those operate like mouse move events almost */
-                       ED_region_tag_redraw(ar);
-               }
-               else {
-                       /* distance from initial point */
-                       if (!(block->pie_data.flags & UI_PIE_DRAG_STYLE)) {
-                               block->pie_data.flags |= UI_PIE_CLICK_STYLE;
+                               if (len_squared_v2v2(event_xy, block->pie_data.pie_center_init) > PIE_CLICK_THRESHOLD_SQ) {
+                                       block->pie_data.flags |= UI_PIE_DRAG_STYLE;
+                               }
+                               /* why redraw here? It's simple, we are getting many double click events here.
+                                * Those operate like mouse move events almost */
+                               ED_region_tag_redraw(ar);
                        }
                        else {
                        }
                        else {
-                               uiBut *but = ui_but_find_active_in_region(menu->region);
-
-                               if (but && (U.pie_menu_confirm > 0) &&
-                                   (dist >= U.pie_menu_threshold + U.pie_menu_confirm))
-                               {
-                                       if (but)
-                                               return ui_but_pie_menu_apply(C, menu, but, true);
+                               /* distance from initial point */
+                               if (!(block->pie_data.flags & UI_PIE_DRAG_STYLE)) {
+                                       block->pie_data.flags |= UI_PIE_CLICK_STYLE;
                                }
                                }
+                               else {
+                                       uiBut *but = ui_but_find_active_in_region(menu->region);
+
+                                       if (but && (U.pie_menu_confirm > 0) &&
+                                               (dist >= U.pie_menu_threshold + U.pie_menu_confirm))
+                                       {
+                                               if (but)
+                                                       return ui_but_pie_menu_apply(C, menu, but, true);
+                                       }
 
 
-                               retval = ui_but_pie_menu_apply(C, menu, but, true);
+                                       retval = ui_but_pie_menu_apply(C, menu, but, true);
 
 
+                               }
                        }
                }
                        }
                }
-       }
-       else {
-               /* direction from numpad */
-               RadialDirection num_dir = UI_RADIAL_NONE;
+               else {
+                       /* direction from numpad */
+                       RadialDirection num_dir = UI_RADIAL_NONE;
 
 
-               switch (event->type) {
-                       case MOUSEMOVE:
-                               if (!is_click_style) {
-                                       float len_sq = len_squared_v2v2(event_xy, block->pie_data.pie_center_init);
+                       switch (event->type) {
+                               case MOUSEMOVE:
+                                       if (!is_click_style) {
+                                               float len_sq = len_squared_v2v2(event_xy, block->pie_data.pie_center_init);
 
 
-                                       /* here we use the initial position explicitly */
-                                       if (len_sq > PIE_CLICK_THRESHOLD_SQ) {
-                                               block->pie_data.flags |= UI_PIE_DRAG_STYLE;
-                                       }
+                                               /* here we use the initial position explicitly */
+                                               if (len_sq > PIE_CLICK_THRESHOLD_SQ) {
+                                                       block->pie_data.flags |= UI_PIE_DRAG_STYLE;
+                                               }
 
 
-                                       /* here instead, we use the offset location to account for the initial direction timeout */
-                                       if ((U.pie_menu_confirm > 0) &&
-                                           (dist >= U.pie_menu_threshold + U.pie_menu_confirm))
-                                       {
-                                               block->pie_data.flags |= UI_PIE_GESTURE_END_WAIT;
-                                               copy_v2_v2(block->pie_data.last_pos, event_xy);
-                                               block->pie_data.duration_gesture = duration;
+                                               /* here instead, we use the offset location to account for the initial direction timeout */
+                                               if ((U.pie_menu_confirm > 0) &&
+                                                       (dist >= U.pie_menu_threshold + U.pie_menu_confirm))
+                                               {
+                                                       block->pie_data.flags |= UI_PIE_GESTURE_END_WAIT;
+                                                       copy_v2_v2(block->pie_data.last_pos, event_xy);
+                                                       block->pie_data.duration_gesture = duration;
+                                               }
                                        }
                                        }
-                               }
 
 
-                               ui_handle_menu_button(C, event, menu);
-                               
-                               /* mouse move should always refresh the area for pie menus */
-                               ED_region_tag_redraw(ar);
-                               break;
+                                       ui_handle_menu_button(C, event, menu);
 
 
-                       case LEFTMOUSE:
-                               if (is_click_style) {
-                                       if (block->pie_data.flags & UI_PIE_INVALID_DIR) {
-                                               menu->menuretval = UI_RETURN_CANCEL;
-                                       }
-                                       else {
-                                               retval = ui_handle_menu_button(C, event, menu);
+                                       /* mouse move should always refresh the area for pie menus */
+                                       ED_region_tag_redraw(ar);
+                                       break;
+
+                               case LEFTMOUSE:
+                                       if (is_click_style) {
+                                               if (block->pie_data.flags & UI_PIE_INVALID_DIR) {
+                                                       menu->menuretval = UI_RETURN_CANCEL;
+                                               }
+                                               else {
+                                                       retval = ui_handle_menu_button(C, event, menu);
+                                               }
                                        }
                                        }
-                               }
-                               break;
+                                       break;
 
 
-                       case ESCKEY:
-                       case RIGHTMOUSE:
-                               menu->menuretval = UI_RETURN_CANCEL;
-                               break;
+                               case ESCKEY:
+                               case RIGHTMOUSE:
+                                       menu->menuretval = UI_RETURN_CANCEL;
+                                       break;
 
 
-                       case AKEY:
-                       case BKEY:
-                       case CKEY:
-                       case DKEY:
-                       case EKEY:
-                       case FKEY:
-                       case GKEY:
-                       case HKEY:
-                       case IKEY:
-                       case JKEY:
-                       case KKEY:
-                       case LKEY:
-                       case MKEY:
-                       case NKEY:
-                       case OKEY:
-                       case PKEY:
-                       case QKEY:
-                       case RKEY:
-                       case SKEY:
-                       case TKEY:
-                       case UKEY:
-                       case VKEY:
-                       case WKEY:
-                       case XKEY:
-                       case YKEY:
-                       case ZKEY:
-                       {
-                               if ((event->val  == KM_PRESS || event->val == KM_DBL_CLICK) &&
-                                   !IS_EVENT_MOD(event, shift, ctrl, oskey))
+                               case AKEY:
+                               case BKEY:
+                               case CKEY:
+                               case DKEY:
+                               case EKEY:
+                               case FKEY:
+                               case GKEY:
+                               case HKEY:
+                               case IKEY:
+                               case JKEY:
+                               case KKEY:
+                               case LKEY:
+                               case MKEY:
+                               case NKEY:
+                               case OKEY:
+                               case PKEY:
+                               case QKEY:
+                               case RKEY:
+                               case SKEY:
+                               case TKEY:
+                               case UKEY:
+                               case VKEY:
+                               case WKEY:
+                               case XKEY:
+                               case YKEY:
+                               case ZKEY:
                                {
                                {
-                                       for (uiBut *but = block->buttons.first; but; but = but->next) {
-                                               if (but->menu_key == event->type) {
-                                                       ui_but_pie_button_activate(C, but, menu);
+                                       if ((event->val  == KM_PRESS || event->val == KM_DBL_CLICK) &&
+                                               !IS_EVENT_MOD(event, shift, ctrl, oskey))
+                                       {
+                                               for (uiBut *but = block->buttons.first; but; but = but->next) {
+                                                       if (but->menu_key == event->type) {
+                                                               ui_but_pie_button_activate(C, but, menu);
+                                                       }
                                                }
                                        }
                                                }
                                        }
+                                       break;
                                }
                                }
-                               break;
-                       }
 
 #define CASE_NUM_TO_DIR(n, d) \
                        case (ZEROKEY + n): case (PAD0 + n): \
                                { if (num_dir == UI_RADIAL_NONE) num_dir = d; } (void)0
 
 
 #define CASE_NUM_TO_DIR(n, d) \
                        case (ZEROKEY + n): case (PAD0 + n): \
                                { if (num_dir == UI_RADIAL_NONE) num_dir = d; } (void)0
 
-                       CASE_NUM_TO_DIR(1, UI_RADIAL_SW);
-                       CASE_NUM_TO_DIR(2, UI_RADIAL_S);
-                       CASE_NUM_TO_DIR(3, UI_RADIAL_SE);
-                       CASE_NUM_TO_DIR(4, UI_RADIAL_W);
-                       CASE_NUM_TO_DIR(6, UI_RADIAL_E);
-                       CASE_NUM_TO_DIR(7, UI_RADIAL_NW);
-                       CASE_NUM_TO_DIR(8, UI_RADIAL_N);
-                       CASE_NUM_TO_DIR(9, UI_RADIAL_NE);
-                       {
-                               uiBut *but = ui_block_pie_dir_activate(block, event, num_dir);
-                               retval = ui_but_pie_button_activate(C, but, menu);
-                               break;
-                       }
+                               CASE_NUM_TO_DIR(1, UI_RADIAL_SW);
+                               CASE_NUM_TO_DIR(2, UI_RADIAL_S);
+                               CASE_NUM_TO_DIR(3, UI_RADIAL_SE);
+                               CASE_NUM_TO_DIR(4, UI_RADIAL_W);
+                               CASE_NUM_TO_DIR(6, UI_RADIAL_E);
+                               CASE_NUM_TO_DIR(7, UI_RADIAL_NW);
+                               CASE_NUM_TO_DIR(8, UI_RADIAL_N);
+                               CASE_NUM_TO_DIR(9, UI_RADIAL_NE);
+                               {
+                                       uiBut *but = ui_block_pie_dir_activate(block, event, num_dir);
+                                       retval = ui_but_pie_button_activate(C, but, menu);
+                                       break;
+                               }
 #undef CASE_NUM_TO_DIR
 #undef CASE_NUM_TO_DIR
-                       default:
-                               retval = ui_handle_menu_button(C, event, menu);
-                               break;
+                               default:
+                                       retval = ui_handle_menu_button(C, event, menu);
+                                       break;
+                       }
                }
        }
 
                }
        }