[Bf-blender-cvs] [39dd7ec] pie-menus: Pie menus beta code.

Antony Riakiotakis noreply at git.blender.org
Tue Apr 22 13:33:08 CEST 2014


Commit: 39dd7ec5b4645a6a3f6505213e380f828c54bd2f
Author: Antony Riakiotakis
Date:   Tue Apr 22 14:24:28 2014 +0300
https://developer.blender.org/rB39dd7ec5b4645a6a3f6505213e380f828c54bd2f

Pie menus beta code.

What is included here:

* Some initial code that lays out and displays items of a pie menu
 in a circular manner around the mouse. Collision detection is
 still not as expected for a pie menu.

* Code to spawn a pie menu for enums and operator enums (a bogus pie
menu for object mode is included, not yet set to any specific key).
For testing, the sculpt mode stroke mode enum is bound as a pie menu
to A key.

* Support to spawn pie menus from python.

Design could change radically, but best have the code here where all can
checkout and see the state of the code.

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

M	release/scripts/modules/bpy_types.py
M	release/scripts/startup/bl_operators/wm.py
M	release/scripts/startup/bl_ui/space_view3d_toolbar.py
M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface.c
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_layout.c
M	source/blender/editors/interface/interface_regions.c
M	source/blender/editors/interface/interface_widgets.c
M	source/blender/editors/object/object_ops.c
M	source/blender/editors/sculpt_paint/paint_ops.c
M	source/blender/makesrna/RNA_access.h
M	source/blender/makesrna/intern/rna_ui_api.c
M	source/blender/makesrna/intern/rna_wm.c
M	source/blender/makesrna/intern/rna_wm_api.c
M	source/blender/windowmanager/WM_keymap.h
M	source/blender/windowmanager/intern/wm_keymap.c
M	source/blender/windowmanager/intern/wm_operators.c

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

diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index d268347..e6e6de9 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -140,6 +140,15 @@ class WindowManager(bpy_types.ID):
         finally:
             self.pupmenu_end__internal(popup)
 
+    def pie_menu(self, event, draw_func, title="", icon='NONE'):
+        import bpy
+        pie = self.piemenu_begin__internal(title, icon, event.type)
+
+        try:
+            draw_func(pie, bpy.context)
+        finally:
+            self.piemenu_end__internal(pie)
+
 
 class _GenericBone:
     """
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 3fdde1a..19f79c5 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -526,6 +526,31 @@ class WM_OT_context_menu_enum(Operator):
             layout.prop(value_base, prop_string, expand=True)
 
         context.window_manager.popup_menu(draw_func=draw_cb, title=prop.name, icon=prop.icon)
+        
+        return {'PASS_THROUGH'}
+
+class WM_OT_context_pie_enum(Operator):
+    bl_idname = "wm.context_pie_enum"
+    bl_label = "Context Enum Pie"
+    bl_options = {'UNDO', 'INTERNAL'}
+    data_path = rna_path_prop
+
+    def invoke(self, context, event):
+        data_path = self.data_path
+        value = context_path_validate(context, data_path)
+
+        if value is Ellipsis:
+            return {'PASS_THROUGH'}
+
+        base_path, prop_string = data_path.rsplit(".", 1)
+        value_base = context_path_validate(context, base_path)
+        prop = value_base.bl_rna.properties[prop_string]
+
+        def draw_cb(self, context):
+            layout = self.layout
+            layout.prop(value_base, prop_string, expand=True)
+
+        context.window_manager.pie_menu(draw_func=draw_cb, title=prop.name, icon=prop.icon, event=event)
 
         return {'PASS_THROUGH'}
 
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index f938f30..6e236f5 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1676,6 +1676,16 @@ class VIEW3D_PT_tools_grease_pencil(GreasePencilPanel, Panel):
     bl_region_type = 'TOOLS'
     bl_category = "Grease Pencil"
 
+class VIEW3D_PIE_object_mode(Menu):
+    bl_label = "Pies!"
+
+    def draw(self, context):
+        layout = self.layout
+
+        pie = layout.pie()
+        pie.operator_enum("object.mode_set", "mode")
+        #pie.label("blackberry")
+        #pie.label("cheese")
 
 if __name__ == "__main__":  # only for live edit.
     bpy.utils.register_module(__name__)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 32db99f..11b0d88 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -99,6 +99,7 @@ typedef struct uiLayout uiLayout;
 #define UI_EMBOSSN      1   /* Nothing, only icon and/or text */
 #define UI_EMBOSSP      2   /* Pulldown menu style */
 #define UI_EMBOSST      3   /* Table */
+#define UI_EMBOSSR      4   /* Pie Menu */
 
 /* uiBlock->direction */
 #define UI_DIRECTION       (UI_TOP | UI_DOWN | UI_LEFT | UI_RIGHT)
@@ -134,6 +135,7 @@ typedef struct uiLayout uiLayout;
 /* block->flag bits 14-17 are identical to but->drawflag bits */
 
 #define UI_BLOCK_LIST_ITEM   (1 << 19)
+#define UI_BLOCK_RADIAL      (1 << 20)
 
 /* uiPopupBlockHandle->menuretval */
 #define UI_RETURN_CANCEL     (1 << 0)   /* cancel all menus cascading */
@@ -352,6 +354,13 @@ struct uiLayout *uiPupMenuLayout(uiPopupMenu *head);
 void uiPupMenuReports(struct bContext *C, struct ReportList *reports) ATTR_NONNULL();
 bool uiPupMenuInvoke(struct bContext *C, const char *idname, struct ReportList *reports) ATTR_NONNULL(1, 2);
 
+/* Pie menus */
+typedef struct uiPieMenu uiPieMenu;
+
+void uiPieMenuInvoke(struct bContext *C, const char *idname, short event);
+struct uiPieMenu *uiPieMenuBegin(struct bContext *C, const char *title, int icon, short event) ATTR_NONNULL();
+void uiPieMenuEnd(struct bContext *C, uiPieMenu *pie);
+struct uiLayout *uiPieMenuLayout(struct uiPieMenu *pie);
 /* Popup Blocks
  *
  * Functions used to create popup blocks. These are like popup menus
@@ -407,7 +416,8 @@ typedef enum {
 	UI_BLOCK_BOUNDS_TEXT,
 	UI_BLOCK_BOUNDS_POPUP_MOUSE,
 	UI_BLOCK_BOUNDS_POPUP_MENU,
-	UI_BLOCK_BOUNDS_POPUP_CENTER
+	UI_BLOCK_BOUNDS_POPUP_CENTER,
+	UI_BLOCK_BOUNDS_PIE_CENTER,
 } eBlockBoundsCalc;
 
 void uiBoundsBlock(struct uiBlock *block, int addval);
@@ -727,6 +737,7 @@ void UI_exit(void);
 #define UI_LAYOUT_HEADER        1
 #define UI_LAYOUT_MENU          2
 #define UI_LAYOUT_TOOLBAR       3
+#define UI_LAYOUT_PIEMENU       4
 
 #define UI_UNIT_X               ((void)0, U.widget_unit)
 #define UI_UNIT_Y               ((void)0, U.widget_unit)
@@ -817,8 +828,8 @@ uiLayout *uiLayoutListBox(uiLayout *layout, struct uiList *ui_list, struct Point
 uiLayout *uiLayoutAbsolute(uiLayout *layout, int align);
 uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align);
 uiLayout *uiLayoutOverlap(uiLayout *layout);
-
 uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout);
+uiLayout *uiLayoutRadial(uiLayout *layout);
 
 /* templates */
 void uiTemplateHeader(uiLayout *layout, struct bContext *C);
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 691c510..9b671a9 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -95,7 +95,7 @@ bool ui_block_is_menu(const uiBlock *block)
 {
 	return (((block->flag & UI_BLOCK_LOOP) != 0) &&
 	        /* non-menu popups use keep-open, so check this is off */
-	        ((block->flag & UI_BLOCK_KEEP_OPEN) == 0));
+			((block->flag & UI_BLOCK_KEEP_OPEN) == 0));
 }
 
 /* ************* window matrix ************** */
@@ -310,6 +310,35 @@ static void ui_centered_bounds_block(const bContext *C, uiBlock *block)
 	ui_bounds_block(block);
 	
 }
+
+static void ui_centered_pie_bounds_block(const bContext *C, uiBlock *block)
+{
+	wmWindow *window = CTX_wm_window(C);
+	int x, y;
+	int startx, starty;
+	int width, height;
+
+	/* note: this is used for the splash where window bounds event has not been
+	 * updated by ghost, get the window bounds from ghost directly */
+
+	x = window->eventstate->x;
+	y = window->eventstate->y;
+
+	ui_bounds_block(block);
+
+	width  = BLI_rctf_size_x(&block->rect);
+	height = BLI_rctf_size_y(&block->rect);
+
+	startx = x - (width * 0.5f);
+	starty = y - (height * 0.5f);
+
+	ui_block_translate(block, startx - block->rect.xmin, starty - block->rect.ymin);
+
+	/* now recompute bounds and safety */
+	ui_bounds_block(block);
+}
+
+
 static void ui_popup_bounds_block(const bContext *C, uiBlock *block, eBlockBoundsCalc bounds_calc)
 {
 	wmWindow *window = CTX_wm_window(C);
@@ -1120,12 +1149,14 @@ void uiEndBlock(const bContext *C, uiBlock *block)
 	if (block->layouts.first) {
 		uiBlockLayoutResolve(block, NULL, NULL);
 	}
-	ui_block_do_align(block);
+	if (!(block->flag & UI_BLOCK_RADIAL))
+		ui_block_do_align(block);
+
 	if ((block->flag & UI_BLOCK_LOOP) && (block->flag & UI_BLOCK_NUMSELECT)) {
 		ui_menu_block_set_keyaccels(block); /* could use a different flag to check */
 	}
 
-	if (block->flag & UI_BLOCK_LOOP) {
+	if ((block->flag & UI_BLOCK_LOOP) && !(block->flag & UI_BLOCK_RADIAL)) {
 		ui_menu_block_set_keymaps(C, block);
 	}
 	
@@ -1142,6 +1173,9 @@ void uiEndBlock(const bContext *C, uiBlock *block)
 		case UI_BLOCK_BOUNDS_POPUP_CENTER:
 			ui_centered_bounds_block(C, block);
 			break;
+		case UI_BLOCK_BOUNDS_PIE_CENTER:
+			ui_centered_pie_bounds_block(C, block);
+			break;
 
 			/* fallback */
 		case UI_BLOCK_BOUNDS_POPUP_MOUSE:
@@ -1241,7 +1275,7 @@ void uiDrawBlock(const bContext *C, uiBlock *block)
 	wmOrtho2(-0.01f, ar->winx - 0.01f, -0.01f, ar->winy - 0.01f);
 	
 	/* back */
-	if (block->flag & UI_BLOCK_LOOP)
+	if ((block->flag & UI_BLOCK_LOOP) && !(block->flag & UI_BLOCK_RADIAL))
 		ui_draw_menu_back(&style, block, &rect);
 	else if (block->panel)
 		ui_draw_aligned_panel(&style, block, &rect, UI_panel_category_is_visible(ar));
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index a38a733..b9c7a6c 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -88,6 +88,7 @@ typedef enum {
 	
 	UI_WTYPE_PULLDOWN,
 	UI_WTYPE_MENU_ITEM,
+	UI_WTYPE_MENU_ITEM_RADIAL,
 	UI_WTYPE_MENU_BACK,
 
 	/* specials */
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 942ffec..713b704 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -106,6 +106,7 @@ typedef enum uiItemType {
 	ITEM_LAYOUT_ABSOLUTE,
 	ITEM_LAYOUT_SPLIT,
 	ITEM_LAYOUT_OVERLAP,
+	ITEM_LAYOUT_RADIAL,
 
 	ITEM_LAYOUT_ROOT
 #if 0
@@ -218,7 +219,7 @@ static int ui_item_fit(int item, int pos, int all, int available, int last, int
 
 static int ui_layout_vary_direction(uiLayout *layout)
 {
-	return (layout->root->type == UI_LAYOUT_HEADER || layout->alignment != UI_LAYOUT_ALIGN_EXPAND) ? UI_ITEM_VARY_X : UI_ITEM_VARY_Y;
+	return (ELEM(layout->root->type, UI_LAYOUT_HEADER, UI_LAYOUT_PIEMENU) || layout->alignment != UI_LAYOUT_ALIGN_EXPAND) ? UI_ITEM_VARY_X : UI_ITEM_VARY_Y;
 }
 
 /* estimated size of text + icon */
@@ -561,7 +562,10 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt
 	RNA_property_enum_items_gettexted(block->evil_C, ptr, prop, &item_array, NULL, &free);
 
 	/* we dont want nested rows, cols in menus */
-	if (layout->root->type != UI_LAYOUT_MENU) {
+	if (layout->root->type == UI_LAYOUT_PIEMENU) {
+		uiBlockSetCurLayout(block, uiLayoutRadial(layout));
+	}
+	else if (layout->root->type != UI_LAYOUT_MENU) {
 		uiBlockSetCurLayout(block, ui_item_local_sublayout(layout, layout, 1));
 	}
 	else {
@@ -869,6 +873,7 @@ void uiItemsFullEnumO(uiLayou

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list