[Bf-blender-cvs] [b529b82] master: Fix T45944: Ctrl+Wheel to cycle values failes in toolshelf

Julian Eisel noreply at git.blender.org
Sat Sep 5 19:42:16 CEST 2015


Commit: b529b828306b2179baa95d5b4988f6eeaf46ded8
Author: Julian Eisel
Date:   Sat Sep 5 19:28:24 2015 +0200
Branches: master
https://developer.blender.org/rBb529b828306b2179baa95d5b4988f6eeaf46ded8

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.

===================================================================

M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_panel.c
M	source/blender/editors/interface/interface_regions.c

===================================================================

diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index dcf1143..a39990e 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 96f6e56..42a9638 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 8ad9770..575eff5 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 f4970ce..5ee7556 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 c9b15f0..356e85e 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 ******************/




More information about the Bf-blender-cvs mailing list