add popup menu to allow python scripts to show popups without having to define a...
authorCampbell Barton <ideasman42@gmail.com>
Sat, 1 Jun 2013 04:06:38 +0000 (04:06 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 1 Jun 2013 04:06:38 +0000 (04:06 +0000)
doc/python_api/examples/bpy.types.WindowManager.popup_menu.py [new file with mode: 0644]
release/scripts/modules/bpy_types.py
source/blender/editors/interface/interface_regions.c
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_define.c
source/blender/makesrna/intern/rna_wm.c
source/blender/makesrna/intern/rna_wm_api.c

diff --git a/doc/python_api/examples/bpy.types.WindowManager.popup_menu.py b/doc/python_api/examples/bpy.types.WindowManager.popup_menu.py
new file mode 100644 (file)
index 0000000..c1887d8
--- /dev/null
@@ -0,0 +1,14 @@
+"""
+Popup Menus
++++++++++++
+Popup menus can be useful for creating menus without having to register menu classes.
+
+Note that they will not block the scripts execution, so the caller can't wait for user input.
+"""
+
+import bpy
+
+def draw(self, context):
+    self.layout.label("Hello World")
+
+bpy.context.window_manager.popup_menu(draw, title="Greeting", icon='INFO')
index a4080b673db763bc25a1db18e711597d59c3f14b..d3ac5a6093c12c476f3558878ce8a838338e5343 100644 (file)
@@ -128,6 +128,19 @@ class Object(bpy_types.ID):
                      if self in scene.objects[:])
 
 
+class WindowManager(bpy_types.ID):
+    __slots__ = ()
+
+    def popup_menu(self, draw_func, title="", icon='NONE'):
+        import bpy
+        popup = self.pupmenu_begin__internal(title, icon)
+
+        try:
+            draw_func(popup, bpy.context)
+        finally:
+            self.pupmenu_end__internal(popup)
+
+
 class _GenericBone:
     """
     functions for bones, common between Armature/Pose/Edit bones.
index 3d149d9951abed5680ba414cbf408de0a7c2495a..76e523f13299f0d1e4286625010b68b72c329960 100644 (file)
@@ -2368,7 +2368,6 @@ struct uiPopupMenu {
 
        int mx, my;
        bool popup, slideout;
-       int startx, starty, maxrow;
 
        uiMenuCreateFunc menu_func;
        void *menu_arg;
index 9aeb1166aa602b203597efc7af54e7dcdbec0512..b18d3c83342018d245b4510ae649ee5ddde3636a 100644 (file)
@@ -626,6 +626,7 @@ extern StructRNA RNA_TransformConstraint;
 extern StructRNA RNA_TransformSequence;
 extern StructRNA RNA_UILayout;
 extern StructRNA RNA_UIList;
+extern StructRNA RNA_UIPopupMenu;
 extern StructRNA RNA_UVWarpModifier;
 extern StructRNA RNA_UVProjectModifier;
 extern StructRNA RNA_UVProjector;
index 6649d58d718e42a904527d3d14f8d17020944f42..20b1d56b22e8861daf8d772c3311545f515a09b3 100644 (file)
@@ -3015,6 +3015,7 @@ void RNA_def_function_return(FunctionRNA *func, PropertyRNA *ret)
                return;
        }
 
+       BLI_assert(func->c_ret == NULL);
        func->c_ret = ret;
 
        RNA_def_function_output(func, ret);
index aae1581def620bfd5aa989d8787b13cc63f1d971..1bd1e48e768897e15ddb5df5db2797f84dceeb4b 100644 (file)
@@ -450,6 +450,8 @@ EnumPropertyItem wm_report_items[] = {
 
 #include "WM_api.h"
 
+#include "UI_interface.h"
+
 #include "BKE_idprop.h"
 
 #include "MEM_guardedalloc.h"
@@ -561,6 +563,17 @@ static int rna_Event_unicode_length(PointerRNA *ptr)
        }
 }
 
+static PointerRNA rna_PopupMenu_layout_get(PointerRNA *ptr)
+{
+       struct uiPopupMenu *pup = ptr->data;
+       uiLayout *layout = uiPupMenuLayout(pup);
+
+       PointerRNA rptr;
+       RNA_pointer_create(ptr->id.data, &RNA_UILayout, layout, &rptr);
+
+       return rptr;
+}
+
 static void rna_Window_screen_set(PointerRNA *ptr, PointerRNA value)
 {
        wmWindow *win = (wmWindow *)ptr->data;
@@ -1659,6 +1672,26 @@ static void rna_def_timer(BlenderRNA *brna)
        RNA_define_verify_sdna(1); /* not in sdna */
 }
 
+static void rna_def_popupmenu(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+
+       srna = RNA_def_struct(brna, "UIPopupMenu", NULL);
+       RNA_def_struct_ui_text(srna, "PopupMenu", "");
+       RNA_def_struct_sdna(srna, "uiPopupMenu");
+
+       RNA_define_verify_sdna(0); /* not in sdna */
+
+       /* could wrap more, for now this is enough */
+       prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
+       RNA_def_property_struct_type(prop, "UILayout");
+       RNA_def_property_pointer_funcs(prop, "rna_PopupMenu_layout_get",
+                                      NULL, NULL, NULL);
+
+       RNA_define_verify_sdna(1); /* not in sdna */
+}
+
 static void rna_def_window(BlenderRNA *brna)
 {
        StructRNA *srna;
@@ -2018,6 +2051,7 @@ void RNA_def_wm(BlenderRNA *brna)
        rna_def_operator_type_macro(brna);
        rna_def_event(brna);
        rna_def_timer(brna);
+       rna_def_popupmenu(brna);
        rna_def_window(brna);
        rna_def_windowmanager(brna);
        rna_def_keyconfig(brna);
index b747c8053dfb856cc1e1cfb52b149e18059661fd..5805bcefdb4e8ad1d165c3b90679314d36dd9a37 100644 (file)
@@ -45,6 +45,7 @@
 
 #ifdef RNA_RUNTIME
 
+#include "UI_interface.h"
 #include "BKE_context.h"
 
 static wmKeyMap *rna_keymap_active(wmKeyMap *km, bContext *C)
@@ -250,6 +251,24 @@ static void rna_KeyConfig_remove(wmWindowManager *wm, ReportList *reports, Point
        RNA_POINTER_INVALIDATE(keyconf_ptr);
 }
 
+/* popup menu wrapper */
+static PointerRNA rna_PupMenuBegin(bContext *C, const char *title, int icon)
+{
+       PointerRNA r_ptr;
+       void *data;
+
+       data = (void *)uiPupMenuBegin(C, title, icon);
+
+       RNA_pointer_create(NULL, &RNA_UIPopupMenu, data, &r_ptr);
+
+       return r_ptr;
+}
+
+static void rna_PupMenuEnd(bContext *C, PointerRNA *handle)
+{
+       uiPupMenuEnd(C, handle->data);
+}
+
 #else
 
 #define WM_GEN_INVOKE_EVENT (1 << 0)
@@ -348,7 +367,25 @@ void RNA_api_wm(StructRNA *srna)
        func = RNA_def_function(srna, "invoke_confirm", "rna_Operator_confirm");
        RNA_def_function_ui_description(func, "Operator confirmation");
        rna_generic_op_invoke(func, WM_GEN_INVOKE_EVENT | WM_GEN_INVOKE_RETURN);
-       
+
+
+       /* wrap uiPupMenuBegin */
+       func = RNA_def_function(srna, "pupmenu_begin__internal", "rna_PupMenuBegin");
+       RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
+       parm = RNA_def_string(func, "title", "", 0, "", "");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm = RNA_def_property(func, "icon", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_items(parm, icon_items);
+       /* return */
+       parm = RNA_def_pointer(func, "menu", "UIPopupMenu", "", "");
+       RNA_def_property_flag(parm, PROP_RNAPTR | PROP_NEVER_NULL);
+       RNA_def_function_return(func, parm);
+
+       /* wrap uiPupMenuEnd */
+       func = RNA_def_function(srna, "pupmenu_end__internal", "rna_PupMenuEnd");
+       RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_USE_CONTEXT);
+       parm = RNA_def_pointer(func, "menu", "UIPopupMenu", "", "");
+       RNA_def_property_flag(parm, PROP_RNAPTR | PROP_NEVER_NULL);
 }
 
 void RNA_api_operator(StructRNA *srna)