diff options
author | Julian Eisel <eiseljulian@gmail.com> | 2015-09-05 20:28:24 +0300 |
---|---|---|
committer | Julian Eisel <eiseljulian@gmail.com> | 2015-09-05 20:42:05 +0300 |
commit | b529b828306b2179baa95d5b4988f6eeaf46ded8 (patch) | |
tree | 03f50c0027a3614a0b4e0f9d3f8b8a3f5285f4d5 | |
parent | 1478ac35c743430d0b333ae9829689782baf70c2 (diff) |
Fix T45944: Ctrl+Wheel to cycle values failes in toolshelf
Now, ctrl+wheel for cycling tabs is passed to hovered button if it supports cycling values (RNA menus, color/row/number/slider buttons, list boxes)
This might feel a bit glitchy if ctrl+wheel is used to cycle tabs and in newly opened tab, a button with cycling support is under the mouse, which will get mouse input from this point on instead of region. Think this is still better than old behavior.
-rw-r--r-- | source/blender/editors/interface/interface.c | 10 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 38 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 8 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_panel.c | 30 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_regions.c | 17 |
5 files changed, 65 insertions, 38 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index dcf114383f9..a39990ea060 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1805,6 +1805,16 @@ bool ui_but_is_rna_valid(uiBut *but) } } +/** + * Checks if the button supports ctrl+mousewheel cycling + */ +bool ui_but_supports_cycling(const uiBut *but) +{ + return ((ELEM(but->type, UI_BTYPE_ROW, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER, UI_BTYPE_LISTBOX)) || + (but->type == UI_BTYPE_MENU && ui_but_menu_step_poll(but)) || + (but->type == UI_BTYPE_COLOR && but->a1 != -1)); +} + double ui_but_value_get(uiBut *but) { PropertyRNA *prop; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 96f6e5632d3..42a9638d988 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -7359,7 +7359,7 @@ static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event) } -static uiBut *ui_list_find_mouse_over(ARegion *ar, int x, int y) +static uiBut *ui_list_find_mouse_over_ex(ARegion *ar, int x, int y) { uiBlock *block; uiBut *but; @@ -7383,6 +7383,11 @@ static uiBut *ui_list_find_mouse_over(ARegion *ar, int x, int y) return NULL; } +static uiBut *ui_list_find_mouse_over(ARegion *ar, const wmEvent *event) +{ + return ui_list_find_mouse_over_ex(ar, event->x, event->y); +} + /* ****************** button state handling **************************/ static bool button_modal_state(uiHandleButtonState state) @@ -8241,21 +8246,15 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) return retval; } -static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) +static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar, uiBut *listbox) { - uiBut *but; uiList *ui_list; uiListDyn *dyn_data; int retval = WM_UI_HANDLER_CONTINUE; int type = event->type, val = event->val; int mx, my; - but = ui_list_find_mouse_over(ar, event->x, event->y); - if (!but) { - return retval; - } - - ui_list = but->custom_data; + ui_list = listbox->custom_data; if (!ui_list || !ui_list->dyn_data) { return retval; } @@ -8263,7 +8262,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) mx = event->x; my = event->y; - ui_window_to_block(ar, but->block, &mx, &my); + ui_window_to_block(ar, listbox->block, &mx, &my); /* convert pan to scrollwheel */ if (type == MOUSEPAN) { @@ -8279,7 +8278,7 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) if (ELEM(type, UPARROWKEY, DOWNARROWKEY) || ((ELEM(type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->ctrl))) { - const int value_orig = RNA_property_int_get(&but->rnapoin, but->rnaprop); + const int value_orig = RNA_property_int_get(&listbox->rnapoin, listbox->rnaprop); int value, min, max, inc; /* activate up/down the list */ @@ -8332,14 +8331,14 @@ static int ui_handle_list_event(bContext *C, const wmEvent *event, ARegion *ar) CLAMP(value, 0, dyn_data->items_len - 1); - RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max); + RNA_property_int_range(&listbox->rnapoin, listbox->rnaprop, &min, &max); CLAMP(value, min, max); if (value != value_orig) { - RNA_property_int_set(&but->rnapoin, but->rnaprop, value); - RNA_property_update(C, &but->rnapoin, but->rnaprop); + RNA_property_int_set(&listbox->rnapoin, listbox->rnaprop, value); + RNA_property_update(C, &listbox->rnapoin, listbox->rnaprop); - ui_apply_but_undo(but); + ui_apply_but_undo(listbox); ui_list->flag |= UILST_SCROLL_TO_ACTIVE_ITEM; ED_region_tag_redraw(ar); @@ -9624,7 +9623,7 @@ static int ui_handle_menus_recursive( static int ui_region_handler(bContext *C, const wmEvent *event, void *UNUSED(userdata)) { ARegion *ar; - uiBut *but; + uiBut *but, *listbox; int retval; /* here we handle buttons at the region level, non-modal */ @@ -9637,11 +9636,12 @@ static int ui_region_handler(bContext *C, const wmEvent *event, void *UNUSED(use /* either handle events for already activated button or try to activate */ but = ui_but_find_active_in_region(ar); + listbox = ui_list_find_mouse_over(ar, event); - retval = ui_handler_panel_region(C, event, ar); + retval = ui_handler_panel_region(C, event, ar, listbox ? listbox : but); - if (retval == WM_UI_HANDLER_CONTINUE) - retval = ui_handle_list_event(C, event, ar); + if (retval == WM_UI_HANDLER_CONTINUE && listbox) + retval = ui_handle_list_event(C, event, ar, listbox); if (retval == WM_UI_HANDLER_CONTINUE) { if (but) diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 8ad9770983c..575eff50b1e 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -485,6 +485,7 @@ extern bool ui_but_is_unit(const uiBut *but) ATTR_WARN_UNUSED_RESULT; extern bool ui_but_is_compatible(const uiBut *but_a, const uiBut *but_b) ATTR_WARN_UNUSED_RESULT; extern bool ui_but_is_rna_valid(uiBut *but) ATTR_WARN_UNUSED_RESULT; extern bool ui_but_is_utf8(const uiBut *but) ATTR_WARN_UNUSED_RESULT; +extern bool ui_but_supports_cycling(const uiBut *but) ATTR_WARN_UNUSED_RESULT; extern int ui_but_is_pushed_ex(uiBut *but, double *value) ATTR_WARN_UNUSED_RESULT; extern int ui_but_is_pushed(uiBut *but) ATTR_WARN_UNUSED_RESULT; @@ -605,11 +606,14 @@ uiPopupBlockHandle *ui_popup_menu_create( void ui_popup_block_free(struct bContext *C, uiPopupBlockHandle *handle); -int ui_but_menu_step(uiBut *but, int step); +int ui_but_menu_step(uiBut *but, int step); +bool ui_but_menu_step_poll(const uiBut *but); /* interface_panel.c */ -extern int ui_handler_panel_region(struct bContext *C, const struct wmEvent *event, struct ARegion *ar); +extern int ui_handler_panel_region( + struct bContext *C, const struct wmEvent *event, + struct ARegion *ar, const uiBut *active_but); extern void ui_draw_aligned_panel(struct uiStyle *style, uiBlock *block, const rcti *rect, const bool show_pin); /* interface_draw.c */ diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index f4970ceb35e..5ee7556a042 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -1850,7 +1850,7 @@ void UI_panel_category_draw_all(ARegion *ar, const char *category_id_active) /* XXX should become modal keymap */ /* AKey is opening/closing panels, independent of button state now */ -int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar) +int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar, const uiBut *active_but) { uiBlock *block; Panel *pa; @@ -1878,20 +1878,26 @@ int ui_handler_panel_region(bContext *C, const wmEvent *event, ARegion *ar) /* first check if the mouse is in the tab region */ if (event->ctrl || (event->mval[0] < ((PanelCategoryDyn *)ar->panels_category.first)->rect.xmax)) { - const char *category = UI_panel_category_active_get(ar, false); - if (LIKELY(category)) { - PanelCategoryDyn *pc_dyn = UI_panel_category_find(ar, category); - if (LIKELY(pc_dyn)) { - pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev; - if (pc_dyn) { - /* intentionally don't reset scroll in this case, - * this allows for quick browsing between tabs */ - UI_panel_category_active_set(ar, pc_dyn->idname); - ED_region_tag_redraw(ar); + if (active_but && ui_but_supports_cycling(active_but)) { + /* skip - exception to make cycling buttons + * using ctrl+mousewheel work in tabbed regions */ + } + else { + const char *category = UI_panel_category_active_get(ar, false); + if (LIKELY(category)) { + PanelCategoryDyn *pc_dyn = UI_panel_category_find(ar, category); + if (LIKELY(pc_dyn)) { + pc_dyn = (event->type == WHEELDOWNMOUSE) ? pc_dyn->next : pc_dyn->prev; + if (pc_dyn) { + /* intentionally don't reset scroll in this case, + * this allows for quick browsing between tabs */ + UI_panel_category_active_set(ar, pc_dyn->idname); + ED_region_tag_redraw(ar); + } } } + retval = WM_UI_HANDLER_BREAK; } - retval = WM_UI_HANDLER_BREAK; } } } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index c9b15f05519..356e85e9d63 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -107,15 +107,22 @@ static int rna_property_enum_step(const bContext *C, PointerRNA *ptr, PropertyRN return value; } -int ui_but_menu_step(uiBut *but, int direction) +bool ui_but_menu_step_poll(const uiBut *but) { + BLI_assert(but->type == UI_BTYPE_MENU); + /* currenly only RNA buttons */ - if ((but->rnaprop == NULL) || (RNA_property_type(but->rnaprop) != PROP_ENUM)) { - printf("%s: cannot cycle button '%s'\n", __func__, but->str); - return 0; + return (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM); +} + +int ui_but_menu_step(uiBut *but, int direction) +{ + if (ui_but_menu_step_poll(but)) { + return rna_property_enum_step(but->block->evil_C, &but->rnapoin, but->rnaprop, direction); } - return rna_property_enum_step(but->block->evil_C, &but->rnapoin, but->rnaprop, direction); + printf("%s: cannot cycle button '%s'\n", __func__, but->str); + return 0; } /******************** Creating Temporary regions ******************/ |