[Bf-blender-cvs] [3a7899c] pie-menus: Allow recursive menus in pies.

Antony Riakiotakis noreply at git.blender.org
Fri Jun 20 03:12:11 CEST 2014


Commit: 3a7899c5ebfb199d6f4a10c73422dc0ebb680a11
Author: Antony Riakiotakis
Date:   Fri Jun 20 03:58:57 2014 +0300
https://developer.blender.org/rB3a7899c5ebfb199d6f4a10c73422dc0ebb680a11

Allow recursive menus in pies.

By returning the handler function to the general menu recursive section.
we can handle any menus that exist in the pie pieces. For now the
drag/release style pies do not work very well with this (menu is
respawned as soon as we select something in the child menu) but I hope
this can be improved further.

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

M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface_handlers.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_regions.c
M	source/blender/windowmanager/intern/wm_event_system.c

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

diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index fe8e7d4..215b517 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1714,6 +1714,8 @@ class VIEW3D_PIE_tests(Menu):
         row.prop(sculpt, "use_symmetry_x", text="X", toggle=True)
         row.prop(sculpt, "use_symmetry_y", text="Y", toggle=True)
         row.prop(sculpt, "use_symmetry_z", text="Z", toggle=True)
+        col.prop(sculpt, "detail_refine_method", text="")
+        col.prop(sculpt, "detail_type_method", text="")
 
 
         
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 5410a05..2097b0b 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -707,12 +707,9 @@ void                       UI_panel_category_draw_all(struct ARegion *ar, const
  * as screen/ if ED_KEYMAP_UI is set, or internally in popup functions. */
 
 void UI_add_region_handlers(struct ListBase *handlers);
-void UI_add_popup_handlers(struct bContext *C, struct ListBase *handlers, uiPopupBlockHandle *popup);
-void UI_add_pie_handlers(struct bContext *C, struct ListBase *handlers, uiPopupBlockHandle *popup);
+void UI_add_popup_handlers(struct bContext *C, struct ListBase *handlers, uiPopupBlockHandle *popup, bool accept_dbl_click);
 void UI_remove_popup_handlers(struct ListBase *handlers, uiPopupBlockHandle *popup);
 void UI_remove_popup_handlers_all(struct bContext *C, struct ListBase *handlers);
-void UI_remove_pie_handlers(struct ListBase *handlers, uiPopupBlockHandle *popup);
-void UI_remove_pie_handlers_all(struct bContext *C, struct ListBase *handlers);
 
 /* Module
  *
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 5347c70..cae0a38 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -8314,28 +8314,54 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo
 		return WM_UI_HANDLER_BREAK;
 }
 
+static bool ui_pie_menu_supported_apply(uiBut *but) {
+	if (but->type == NUMSLI)
+		return false;
+
+	return true;
+}
+
 
-static void ui_pie_menu_apply(bContext *C, uiPopupBlockHandle *menu)
+static int ui_pie_menu_apply(bContext *C, uiPopupBlockHandle *menu, const wmEvent *event, bool force)
 {
+	int retval = WM_UI_HANDLER_BREAK;
+
 	uiBut *but = ui_but_find_activated(menu->region);
 
-	if (but) {
-		ui_apply_button(C, but->block, but, but->active, false);
-		button_activate_exit((bContext *)C, but, but->active, false, true);
-		menu->menuretval = UI_RETURN_OK;
+	if (but && ui_pie_menu_supported_apply(but)) {
+		if (but->type == MENU) {
+			/* forcing the pie menu to close will not handle menus */
+			if (!force) {
+				wmEvent e = *event;
+				e.type = LEFTMOUSE;
+				e.val = KM_PRESS;
+
+				retval = ui_handle_menu_button(C, &e, menu);
+			}
+			else {
+				menu->menuretval = UI_RETURN_CANCEL;
+			}
+		}
+		else {
+			ui_apply_button(C, but->block, but, but->active, false);
+			button_activate_exit((bContext *)C, but, but->active, false, true);
+
+			menu->menuretval = UI_RETURN_OK;
+		}
 	}
 	else {
 		menu->menuretval = UI_RETURN_CANCEL;
 	}
+
+	return retval;
 }
 
 /* two types of pie menus, one with operator + enum, other with regular callbacks */
-static int ui_handler_pie(bContext *C, const wmEvent *event, void *userdata)
+static int ui_handler_pie(bContext *C, const wmEvent *event, uiPopupBlockHandle *menu)
 {
 	ARegion *ar;
 	uiBlock *block;
 	int mx, my;
-	uiPopupBlockHandle *menu = userdata;
 	double time_diff;
 
 	/* we block all events, this is modal interaction, except for drop events which is described below */
@@ -8379,10 +8405,10 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, void *userdata)
 		}
 		else {
 			if (time_diff > U.pie_drag_timeout * 0.1) {
-				ui_pie_menu_apply(C, menu);
+				retval = ui_pie_menu_apply(C, menu, event, true);
 			}
 			else {
-				menu->is_click_style = true;
+				block->pie_data.flags |= UI_PIE_CLICK_STYLE;
 			}
 		}
 	}
@@ -8395,12 +8421,13 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, void *userdata)
 				break;
 
 			case LEFTMOUSE:
-				if (menu->is_click_style) {
-					ui_pie_menu_apply(C, menu);
-				}
-				else {
-					ui_handle_menu_button(C, event, menu);
-					menu->menuretval = 0;
+				if (event->val == KM_PRESS) {
+					if (block->pie_data.flags & UI_PIE_CLICK_STYLE) {
+						retval = ui_pie_menu_apply(C, menu, event, false);
+					}
+					else {
+						retval = ui_handle_menu_button(C, event, menu);
+					}
 				}
 				break;
 
@@ -8409,39 +8436,11 @@ static int ui_handler_pie(bContext *C, const wmEvent *event, void *userdata)
 				break;
 
 			default:
-				ui_handle_menu_button(C, event, menu);
+				retval = ui_handle_menu_button(C, event, menu);
 				break;
 		}
 	}
 
-	/* free if done, does not free handle itself */
-	if (menu->menuretval) {
-		/* copy values, we have to free first (closes region) */
-		uiPopupBlockHandle temp = *menu;
-
-		ui_popup_block_free(C, menu);
-		UI_remove_pie_handlers(&CTX_wm_window(C)->modalhandlers, menu);
-
-		if ((temp.menuretval & UI_RETURN_OK) || (temp.menuretval & UI_RETURN_POPUP_OK)) {
-			if (temp.popup_func)
-				temp.popup_func(C, temp.popup_arg, temp.retvalue);
-			if (temp.optype)
-				WM_operator_name_call(C, temp.optype->idname, temp.opcontext, NULL);
-		}
-		else if (temp.cancel_func)
-			temp.cancel_func(C, temp.popup_arg);
-
-		WM_event_add_mousemove(C);
-	}
-	else {
-		/* re-enable tooltips */
-		if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy))
-			ui_blocks_set_tooltips(menu->region, true);
-	}
-
-	/* delayed apply callbacks */
-	ui_apply_but_funcs_after(C);
-
 	return retval;
 }
 
@@ -8466,17 +8465,21 @@ static int ui_handle_menus_recursive(
 		uiBlock *block = menu->region->uiblocks.first;
 		const bool is_menu = ui_block_is_menu(block);
 		bool inside = false;
+		/* root pie menus accept the key that spawned them as double click to improve responsiveness */
+		bool do_recursion = (!(block->flag & UI_BLOCK_RADIAL) || event->type != block->pie_data.event);
 
-		if (is_parent_inside == false) {
-			int mx, my;
+		if (do_recursion) {
+			if (is_parent_inside == false) {
+				int mx, my;
 
-			mx = event->x;
-			my = event->y;
-			ui_window_to_block(menu->region, block, &mx, &my);
-			inside = BLI_rctf_isect_pt(&block->rect, mx, my);
-		}
+				mx = event->x;
+				my = event->y;
+				ui_window_to_block(menu->region, block, &mx, &my);
+				inside = BLI_rctf_isect_pt(&block->rect, mx, my);
+			}
 
-		retval = ui_handle_menus_recursive(C, event, submenu, level + 1, is_parent_inside || inside, is_menu, false);
+			retval = ui_handle_menus_recursive(C, event, submenu, level + 1, is_parent_inside || inside, is_menu, false);
+		}
 	}
 
 	/* now handle events for our own menu */
@@ -8509,7 +8512,12 @@ static int ui_handle_menus_recursive(
 			}
 		}
 		else {
-			retval = ui_handle_menu_event(C, event, menu, level, is_parent_inside, is_parent_menu, is_floating);
+			uiBlock *block = menu->region->uiblocks.first;
+
+			if (block->flag & UI_BLOCK_RADIAL)
+				retval = ui_handler_pie(C, event, menu);
+			else if (event->type == LEFTMOUSE || event->val != KM_DBL_CLICK)
+				retval = ui_handle_menu_event(C, event, menu, level, is_parent_inside, is_parent_menu, is_floating);
 		}
 	}
 
@@ -8715,14 +8723,9 @@ void UI_add_region_handlers(ListBase *handlers)
 	WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region, NULL, false);
 }
 
-void UI_add_popup_handlers(bContext *C, ListBase *handlers, uiPopupBlockHandle *popup)
-{
-	WM_event_add_ui_handler(C, handlers, ui_handler_popup, ui_handler_remove_popup, popup, false);
-}
-
-void UI_add_pie_handlers(struct bContext *C, struct ListBase *handlers, uiPopupBlockHandle *pie)
+void UI_add_popup_handlers(bContext *C, ListBase *handlers, uiPopupBlockHandle *popup, bool accept_dbl_click)
 {
-	WM_event_add_ui_handler(C, handlers, ui_handler_pie, ui_handler_remove_popup, pie, true);
+	WM_event_add_ui_handler(C, handlers, ui_handler_popup, ui_handler_remove_popup, popup, accept_dbl_click);
 }
 
 
@@ -8736,17 +8739,6 @@ void UI_remove_popup_handlers_all(bContext *C, ListBase *handlers)
 	WM_event_free_ui_handler_all(C, handlers, ui_handler_popup, ui_handler_remove_popup);
 }
 
-void UI_remove_pie_handlers(ListBase *handlers, uiPopupBlockHandle *popup)
-{
-	WM_event_remove_ui_handler(handlers, ui_handler_pie, ui_handler_remove_popup, popup, false);
-}
-
-void UI_remove_pie_handlers_all(bContext *C, ListBase *handlers)
-{
-	WM_event_free_ui_handler_all(C, handlers, ui_handler_pie, ui_handler_remove_popup);
-}
-
-
 bool UI_textbutton_activate_rna(const bContext *C, ARegion *ar,
                                 const void *rna_poin_data, const char *rna_prop_id)
 {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index ba6bdc2..f21ab75 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -163,6 +163,8 @@ typedef enum RadialDirection {
 #define UI_PIE_INITIAL_DIRECTION   (1 << 1) /* use initial center of pie menu to calculate direction */
 #define UI_PIE_3_ITEMS             (1 << 2) /* pie menu has only 3 items, careful when centering */
 #define UI_PIE_INVALID_DIR         (1 << 3) /* mouse not far enough from center position  */
+#define UI_PIE_CANCELLED           (1 << 4) /* pie menu cancelled but we still wait for a release event  */
+#define UI_PIE_CLICK_STYLE         (1 << 5) /* pie menu changed to click style, click to confirm  */
 
 typedef struct uiLinkLine {  /* only for draw/edit */
 	struct uiLinkLine *next, *prev;
@@ -507,9 +509,6 @@ struct uiPopupBlockHandle {
 	/* menu direction */
 	int direction;
 
-	/* pie menus */
-	bool is_click_style; /* button released before timeout, this is a click style menu */
-
 /* #ifdef USE_DRAG_POPUP */
 	bool is_grab;
 	int     grab_xy_prev[2];

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list