replace dynamic_menu.py with Menu classmethods much less complicated.
authorCampbell Barton <ideasman42@gmail.com>
Fri, 25 Dec 2009 22:16:19 +0000 (22:16 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Fri, 25 Dec 2009 22:16:19 +0000 (22:16 +0000)
access append/prepend eg.

bpy.types.INFO_MT_file_import.append(lambda self, context: self.layout.operator("import_some.format"))

21 files changed:
release/scripts/io/export_3ds.py
release/scripts/io/export_fbx.py
release/scripts/io/export_mdd.py
release/scripts/io/export_obj.py
release/scripts/io/export_ply.py
release/scripts/io/export_x3d.py
release/scripts/io/import_anim_bvh.py
release/scripts/io/import_scene_3ds.py
release/scripts/io/import_scene_obj.py
release/scripts/modules/bpy_types.py
release/scripts/modules/dynamic_menu.py [deleted file]
release/scripts/op/add_armature_human.py
release/scripts/op/add_mesh_torus.py
release/scripts/op/mesh_skin.py
release/scripts/op/uvcalc_follow_active.py
release/scripts/op/uvcalc_smart_project.py
release/scripts/templates/operator.py
release/scripts/ui/properties_data_armature_rigify.py
release/scripts/ui/space_info.py
release/scripts/ui/space_view3d.py
source/blender/python/sphinx_doc_gen.py

index 163b683f60fc0788918ca0e3bb9fa8b135a08a63..23fd44acc3f70349a91748dbdf8b7a5a9a928df4 100644 (file)
@@ -1139,10 +1139,8 @@ class Export3DS(bpy.types.Operator):
 bpy.types.register(Export3DS)
 
 # Add to a menu
-import dynamic_menu
-
 def menu_func(self, context):
     default_path = bpy.data.filename.replace(".blend", ".3ds")
     self.layout.operator(Export3DS.bl_idname, text="Autodesk 3DS...").path = default_path
 
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
+bpy.types.INFO_MT_file_export.append(menu_func)
index 19a3345bd94ee41e972b49d0b15fad0cd628780f..25e79bbf2147fedd05b258659f38e10f4891727e 100644 (file)
@@ -3462,13 +3462,9 @@ bpy.types.register(ExportFBX)
 # SMALL or COSMETICAL
 # - find a way to get blender version, and put it in bpy.util?, old was Blender.Get('version')
 
-
-# Add to a menu
-import dynamic_menu
-
 def menu_func(self, context):
     default_path = bpy.data.filename.replace(".blend", ".fbx")
     self.layout.operator(ExportFBX.bl_idname, text="Autodesk FBX...").path = default_path
 
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
+menu_item = bpy.types.INFO_MT_file_export.append(menu_func)
 
index 66db8c1402759ec9328b3b345937df4f717c410e..7d0e49d48ce23a0b0fbec77f2d462be4a93510da 100644 (file)
@@ -183,14 +183,11 @@ class ExportMDD(bpy.types.Operator):
 bpy.types.register(ExportMDD)
 
 # Add to a menu
-import dynamic_menu
-
-
 def menu_func(self, context):
     default_path = bpy.data.filename.replace(".blend", ".mdd")
     self.layout.operator(ExportMDD.bl_idname, text="Vertex Keyframe Animation (.mdd)...").path = default_path
 
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
+bpy.types.INFO_MT_file_export.append(menu_func)
 
 if __name__ == '__main__':
     bpy.ops.export.mdd(path="/tmp/test.mdd")
index 85af371680a24ca45d1f33dbab867cb7d6753bd4..5b55c5159a6cbc4165e4e91472d13a009ecc3115 100644 (file)
@@ -987,19 +987,13 @@ class ExportOBJ(bpy.types.Operator):
         wm.add_fileselect(self)
         return {'RUNNING_MODAL'}
 
-
-
-
-
 bpy.types.register(ExportOBJ)
 
-import dynamic_menu
-
 def menu_func(self, context):
     default_path = bpy.data.filename.replace(".blend", ".obj")
     self.layout.operator(ExportOBJ.bl_idname, text="Wavefront (.obj)...").path = default_path
 
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
+menu_item = bpy.types.INFO_MT_file_export.append(menu_func)
 
 if __name__ == "__main__":
     bpy.ops.EXPORT_OT_obj(filename="/tmp/test.obj")
index f27b76d2cbe1aa93651685bd6ca859e908a2e509..15b65e8d2fda6c57636e5a6005d9a2ba7013e6ad 100644 (file)
@@ -318,14 +318,11 @@ class ExportPLY(bpy.types.Operator):
 
 bpy.types.register(ExportPLY)
 
-import dynamic_menu
-
-
 def menu_func(self, context):
     default_path = bpy.data.filename.replace(".blend", ".ply")
     self.layout.operator(ExportPLY.bl_idname, text="Stanford (.ply)...").path = default_path
 
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
+bpy.types.INFO_MT_file_export.append(menu_func)
 
 if __name__ == "__main__":
     bpy.ops.export.ply(path="/tmp/test.ply")
index c4f1b53146f1bec1528571b59751cc0373fcc27a..4c3540a458ee6edf0a6f4b294ff48f2fbdb34fda 100644 (file)
@@ -1242,13 +1242,12 @@ class ExportX3D(bpy.types.Operator):
 
 bpy.types.register(ExportX3D)
 
-import dynamic_menu
 
 def menu_func(self, context):
     default_path = bpy.data.filename.replace(".blend", ".x3d")
     self.layout.operator(ExportX3D.bl_idname, text="X3D Extensible 3D (.x3d)...").path = default_path
 
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
+bpy.types.INFO_MT_file_export.append(menu_func)
 
 # NOTES
 # - blender version is hardcoded
index cd040012840ae54b369cdb976a47b23bb458d06f..2afd2db3cb2e847af3db03315aef4b89691b75f3 100644 (file)
@@ -897,7 +897,5 @@ class BvhImporter(bpy.types.Operator):
 
 bpy.types.register(BvhImporter)
 
-
-import dynamic_menu
 menu_func = lambda self, context: self.layout.operator(BvhImporter.bl_idname, text="Motion Capture (.bvh)...")
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
+bpy.types.INFO_MT_file_import.append(menu_func)
index 3e174baa14cde034c7f47d2743e001de25658657..4420f6ef6f0fb4e0f4dc318820a47137de11b1e8 100644 (file)
@@ -1168,10 +1168,9 @@ class IMPORT_OT_autodesk_3ds(bpy.types.Operator):
 
 bpy.types.register(IMPORT_OT_autodesk_3ds)
 
-import dynamic_menu
 menu_func = lambda self, context: self.layout.operator(IMPORT_OT_autodesk_3ds.bl_idname, text="3D Studio (.3ds)...")
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
+bpy.types.INFO_MT_file_import.append(menu_func)
 
 # NOTES:
-# why add 1 extra vertex? and remove it when done?
+# why add 1 extra vertex? and remove it when done? - "Answer - eekadoodle - would need to re-order UV's without this since face order isnt always what we give blender, BMesh will solve :D"
 # disabled scaling to size, this requires exposing bb (easy) and understanding how it works (needs some time)
index f135bfbb6c055f947e5f93aaaa697fc7db61341c..228084561b8a75e313ce67983d3132bc46512d2d 100644 (file)
@@ -1627,9 +1627,8 @@ class IMPORT_OT_obj(bpy.types.Operator):
 bpy.types.register(IMPORT_OT_obj)
 
 
-import dynamic_menu
 menu_func = lambda self, context: self.layout.operator(IMPORT_OT_obj.bl_idname, text="Wavefront (.obj)...")
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_import, menu_func)
+menu_item = bpy.types.INFO_MT_file_import.append(menu_func)
 
 
 # NOTES (all line numbers refer to 2.4x import_obj.py, not this file)
index 15bf71e017ed5c6a57fdf89f718ee5e604423170..50e8d8ded93c3316a0a725c0974c1b2c18b4aacd 100644 (file)
@@ -379,6 +379,32 @@ class Macro(StructRNA, metaclass=OrderedMeta):
 
 class Menu(StructRNA):
     __slots__ = ()
+    
+    @classmethod
+    def _dyn_menu_initialize(cls):
+        draw_funcs = getattr(cls.draw, "_draw_funcs", None)
+
+        if draw_funcs is None:
+            def draw_ls(*args):
+                for func in draw_ls._draw_funcs:
+                    func(*args)
+    
+            draw_funcs = draw_ls._draw_funcs = [cls.draw]
+            cls.draw = draw_ls
+        
+        return draw_funcs
+    
+    @classmethod
+    def append(cls, draw_func):
+        """Prepend an draw function to this menu, takes the same arguments as the menus draw function."""
+        draw_funcs = cls._dyn_menu_initialize()
+        draw_funcs.append(draw_func)
+
+    @classmethod
+    def prepend(cls, draw_func):
+        """Prepend a draw function to this menu, takes the same arguments as the menus draw function."""
+        draw_funcs = cls._dyn_menu_initialize()
+        draw_funcs.insert(0, draw_func)
 
     def path_menu(self, searchpaths, operator):
         layout = self.layout
@@ -410,3 +436,4 @@ class Menu(StructRNA):
         """
         import bpy
         self.path_menu(bpy.utils.preset_paths(self.preset_subdir), self.preset_operator)
+
diff --git a/release/scripts/modules/dynamic_menu.py b/release/scripts/modules/dynamic_menu.py
deleted file mode 100644 (file)
index 9583dae..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-# ##### BEGIN GPL LICENSE BLOCK #####
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software Foundation,
-#  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-#
-# ##### END GPL LICENSE BLOCK #####
-
-# <pep8 compliant>
-
-import bpy
-
-
-def collect_baseclasses(_class, bases):
-
-    if _class is type or _class is object:
-        return bases
-
-    bases.append(_class)
-    for _superclass in _class.__bases__:
-        collect_baseclasses(_superclass, bases)
-
-    return bases
-
-
-def collect_subclasses(_class, subs):
-
-    if _class is type or _class is object:
-        return subs
-
-    subs.append(_class)
-    for _subclass in _class.__subclasses__():
-        collect_subclasses(_subclass, subs)
-
-    return subs
-
-
-class DynMenu(bpy.types.Menu):
-
-    def draw(self, context):
-        '''
-        This is a draw function that is used to call all subclasses draw functions
-        starting from the registered classes draw function and working down.
-
-        DynMenu.setup() must be called first.
-
-        Sort/group classes could be nice
-        '''
-
-        subclass_ls = []
-        collect_subclasses(self.__class__, subclass_ls)
-        # print(subclass_ls)
-
-        for subclass in subclass_ls:
-            # print("drawwing", subclass) # , dir(subclass))
-            subclass.internal_draw(self, context)
-            # print("subclass.internal_draw", subclass.internal_draw)
-
-
-def setup(menu_class):
-    '''
-    Setup subclasses (not needed when self.add() is used)
-    '''
-    bases = collect_baseclasses(menu_class, [])
-
-    # Incase 'DynMenu' isnt last
-    while bases[-1] is not DynMenu:
-        bases.pop()
-    bases.pop() # remove 'DynMenu'
-
-    root_class = bases[-1] # this is the registered class
-
-    for subclass in collect_subclasses(root_class, []):
-        #print(subclass)
-
-        draw = getattr(subclass, 'draw', None)
-        if draw and not hasattr(subclass, 'internal_draw'):
-            # print("replace", subclass, draw)
-            try:
-                del subclass.draw
-            except:
-                pass
-            subclass.internal_draw = draw
-
-    root_class.draw = DynMenu.draw
-
-
-def add(menu_class, func):
-    '''
-    Add a single function directly without having to make a class
-
-    important that the returned value should be stored in the module that called it.
-    '''
-
-    newclass = type('<menuclass>', (menu_class,), {})
-    newclass.internal_draw = func
-    setup(menu_class)
-    return newclass
-
-'''
-# so we dont need to import this module
-DynMenu.setup = setup
-DynMenu.add = add
-
-# Only so we can access as bpy.types.
-# dont ever use this directly!
-bpy.types.register(DynMenu)
-'''
index 8696312eae04d2a73520481c9031085b29fd4b8d..e618ed51ee5eaf4da82367f4b3dbd6f4a53a6bfd 100644 (file)
@@ -613,11 +613,9 @@ class AddHuman(bpy.types.Operator):
 bpy.types.register(AddHuman)
 
 # Add to a menu
-import dynamic_menu
-
 menu_func = (lambda self, context: self.layout.operator(AddHuman.bl_idname, icon='OUTLINER_OB_ARMATURE', text="Human (Meta-Rig)"))
 
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_armature_add, menu_func)
+bpy.types.INFO_MT_armature_add.append(menu_func)
 
 if __name__ == "__main__":
     bpy.ops.mesh.armature_human_advanced_add()
index 685f1cae8a4be177aa2ca14194782e99aae83b7d..372afb3654f06534f65d5a7d9b3bfe0e6bdaba25 100644 (file)
@@ -127,13 +127,11 @@ class AddTorus(bpy.types.Operator):
 # Register the operator
 bpy.types.register(AddTorus)
 
-# Add to a menu
-import dynamic_menu
-
+# Add to the menu
 menu_func = (lambda self, context: self.layout.operator(AddTorus.bl_idname,
                                         text="Torus", icon='MESH_DONUT'))
 
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_mesh_add, menu_func)
+bpy.types.INFO_MT_mesh_add.append(menu_func)
 
 if __name__ == "__main__":
     bpy.ops.mesh.primitive_torus_add()
index 251cfb32b9354e52bdf519b7c5e62f900c3b726d..d442717afbf9dfdd5ff99f3d7e37fc569bc697ef 100644 (file)
@@ -650,8 +650,7 @@ class MESH_OT_skin(bpy.types.Operator):
 bpy.types.register(MESH_OT_skin)
 
 # Add to a menu
-import dynamic_menu
-menu_item = dynamic_menu.add(bpy.types.VIEW3D_MT_edit_mesh_faces, (lambda self, context: self.layout.operator("mesh.skin", text="Bridge Faces")) )
+bpy.types.VIEW3D_MT_edit_mesh_faces.append((lambda self, context: self.layout.operator("mesh.skin", text="Bridge Faces")))
 
 if __name__ == "__main__":
     bpy.ops.mesh.skin()
index 8ab5b8ec454377467df51de39fa618d9106c5160..41f97f9cca51e1027ef1f7d290e10c39660d60d8 100644 (file)
@@ -262,11 +262,8 @@ class FollowActiveQuads(bpy.types.Operator):
 bpy.types.register(FollowActiveQuads)
 
 # Add to a menu
-import dynamic_menu
-
 menu_func = (lambda self, context: self.layout.operator(FollowActiveQuads.bl_idname))
-
-menu_item = dynamic_menu.add(bpy.types.VIEW3D_MT_uv_map, menu_func)
+bpy.types.VIEW3D_MT_uv_map.append(menu_func)
 
 if __name__ == '__main__':
     bpy.ops.uv.follow_active_quads()
index 25840e04cf8a5e8fe5b77a6282fa80370e5ff218..6da6020f85bb69c7231727cbcd094ba7987e8b83 100644 (file)
@@ -1135,13 +1135,10 @@ class SmartProject(bpy.types.Operator):
 bpy.types.register(SmartProject)
 
 # Add to a menu
-import dynamic_menu
-
 menu_func = (lambda self, context: self.layout.operator(SmartProject.bl_idname,
                                         text="Smart Project"))
 
-menu_item = dynamic_menu.add(bpy.types.VIEW3D_MT_uv_map, menu_func)
+bpy.types.VIEW3D_MT_uv_map.append(menu_func)
 
 if __name__ == '__main__':
     bpy.ops.uv.smart_project()
-
index 9402a931db88007677865cb67a882329a59038a4..f175ca06f287a513c4d60f3c597f21f24002ee5e 100644 (file)
@@ -49,10 +49,8 @@ class ExportSomeData(bpy.types.Operator):
 bpy.types.register(ExportSomeData)
 
 # Only needed if you want to add into a dynamic menu
-import dynamic_menu
 menu_func = lambda self, context: self.layout.operator("export.some_data", text="Example Exporter...")
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_file_export, menu_func)
+bpy.types.INFO_MT_file_export.append(menu_func)
 
-# Use for running this script directly
 if __name__ == "__main__":
     bpy.ops.export.some_data(path="/tmp/test.ply")
index c0270d9b8caf72f214c87e4aaf172697d808584a..9423997151b17881d508ffe8702ac1fee5344a71 100644 (file)
@@ -313,11 +313,7 @@ class ActiveClear(bpy.types.Operator):
         return {'FINISHED'}
 
 
-import space_info
-import dynamic_menu
-
-
-class INFO_MT_armature_metarig_add(dynamic_menu.DynMenu):
+class INFO_MT_armature_metarig_add(bpy.types.Menu):
     bl_idname = "INFO_MT_armature_metarig_add"
     bl_label = "Meta-Rig"
 
@@ -349,5 +345,6 @@ bpy.types.register(ActiveClear)
 
 bpy.types.register(INFO_MT_armature_metarig_add)
 
+import space_info
 menu_func = (lambda self, context: self.layout.menu("INFO_MT_armature_metarig_add", icon='OUTLINER_OB_ARMATURE'))
-menu_item = dynamic_menu.add(bpy.types.INFO_MT_armature_add, menu_func)
+space_info.INFO_MT_armature_add.append(menu_func)
index 1f7ba15de6116a22ede40a8aa4586c299e6a85c4..3f35bbc06d80d45979e1903f4671c8177ad0a696 100644 (file)
@@ -19,9 +19,6 @@
 # <pep8 compliant>
 import bpy
 
-import dynamic_menu
-# reload(dynamic_menu)
-
 
 class INFO_HT_header(bpy.types.Header):
     bl_space_type = 'INFO'
@@ -115,21 +112,8 @@ class INFO_MT_file(bpy.types.Menu):
         layout.operator_context = 'EXEC_AREA'
         layout.operator("wm.exit_blender", text="Quit", icon='QUIT')
 
-# test for expanding menus
-'''
-class INFO_MT_file_more(INFO_MT_file):
-    bl_label = "File"
-
-    def draw(self, context):
-        layout = self.layout
-
-        layout.operator("wm.read_homefile", text="TESTING ")
-
-dynamic_menu.setup(INFO_MT_file_more)
-'''
-
 
-class INFO_MT_file_import(dynamic_menu.DynMenu):
+class INFO_MT_file_import(bpy.types.Menu):
     bl_idname = "INFO_MT_file_import"
     bl_label = "Import"
 
@@ -138,7 +122,7 @@ class INFO_MT_file_import(dynamic_menu.DynMenu):
             self.layout.operator("wm.collada_import", text="COLLADA (.dae)...")
 
 
-class INFO_MT_file_export(dynamic_menu.DynMenu):
+class INFO_MT_file_export(bpy.types.Menu):
     bl_idname = "INFO_MT_file_export"
     bl_label = "Export"
 
@@ -164,7 +148,7 @@ class INFO_MT_file_external_data(bpy.types.Menu):
         layout.operator("file.find_missing_files")
 
 
-class INFO_MT_mesh_add(dynamic_menu.DynMenu):
+class INFO_MT_mesh_add(bpy.types.Menu):
     bl_idname = "INFO_MT_mesh_add"
     bl_label = "Mesh"
 
@@ -183,7 +167,7 @@ class INFO_MT_mesh_add(dynamic_menu.DynMenu):
         layout.operator("mesh.primitive_monkey_add", icon='MESH_MONKEY', text="Monkey")
 
 
-class INFO_MT_armature_add(dynamic_menu.DynMenu):
+class INFO_MT_armature_add(bpy.types.Menu):
     bl_idname = "INFO_MT_armature_add"
     bl_label = "Armature"
 
index 26f2953be40755e9a712befba0857e49793dbd8d..831b900579aa98bc3f7310e8abdaa4b29092e570 100644 (file)
@@ -18,7 +18,6 @@
 
 # <pep8 compliant>
 import bpy
-import dynamic_menu
 
 
 class VIEW3D_HT_header(bpy.types.Header):
@@ -205,7 +204,7 @@ class VIEW3D_MT_snap(bpy.types.Menu):
         layout.operator("view3d.snap_cursor_to_active", text="Cursor to Active")
 
 
-class VIEW3D_MT_uv_map(dynamic_menu.DynMenu):
+class VIEW3D_MT_uv_map(bpy.types.Menu):
     bl_label = "UV Mapping"
 
     def draw(self, context):
@@ -1231,7 +1230,7 @@ class VIEW3D_MT_edit_mesh_edges(bpy.types.Menu):
         layout.operator("mesh.region_to_loop")
 
 
-class VIEW3D_MT_edit_mesh_faces(dynamic_menu.DynMenu):
+class VIEW3D_MT_edit_mesh_faces(bpy.types.Menu):
     bl_label = "Faces"
     bl_idname = "VIEW3D_MT_edit_mesh_faces"
 
index 3c15c09403d6f364442f70bfcc75cb08d9feba5b..24910b911e4bb76720ec71b255197310fe1ea755 100644 (file)
@@ -27,8 +27,6 @@ This will generate python files in "./source/blender/python/doc/bpy/sphinx-in"
 Generate html docs  by running...
     
     sphinx-build source/blender/python/doc/bpy/sphinx-in source/blender/python/doc/bpy/sphinx-out
-    
-
 '''
 
 # if you dont have graphvis installed ommit the --graph arg.
@@ -75,7 +73,7 @@ def py_function_args(func):
     INVALID = py_function_args
     defaults = ([INVALID] * (len(names) - len(defaults))) + defaults
     
-    if names[0] == "self":
+    if names[0] in ("self", "cls"): # normal class function or classmethod
         del names[0]
         del defaults[0]