mirror of
https://github.com/blender/blender-addons.git
synced 2025-08-16 15:35:05 +00:00
pie menus official, add individual activation system. re: T48709
This commit is contained in:
246
pie_menus_official/__init__.py
Normal file
246
pie_menus_official/__init__.py
Normal file
@ -0,0 +1,246 @@
|
||||
# ##### 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
import bpy
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
PointerProperty,
|
||||
)
|
||||
from bpy.types import (
|
||||
PropertyGroup,
|
||||
AddonPreferences,
|
||||
)
|
||||
|
||||
|
||||
bl_info = {
|
||||
'name': 'UI Pie Menu Official',
|
||||
'author': 'Antony Riakiotakis, Sebastian Koenig',
|
||||
'version': (1, 1, 2),
|
||||
'blender': (2, 7, 7),
|
||||
'location': 'See preferences for Activation list',
|
||||
'description': 'Pie Menu Activate',
|
||||
'warning': '',
|
||||
'wiki_url': '',
|
||||
'category': 'Pie Menu'
|
||||
}
|
||||
|
||||
|
||||
sub_modules_names = (
|
||||
"pie_object_modes_of",
|
||||
"pie_view_of",
|
||||
"pie_shade_of",
|
||||
"pie_manipulator_of",
|
||||
"pie_pivot_of",
|
||||
"pie_snap_of",
|
||||
"pie_clip_marker_of",
|
||||
)
|
||||
|
||||
|
||||
sub_modules = [__import__(__package__ + "." + submod, {}, {}, submod) for submod in sub_modules_names]
|
||||
sub_modules.sort(key=lambda mod: (mod.bl_info['category'], mod.bl_info['name']))
|
||||
|
||||
|
||||
def _get_pref_class(mod):
|
||||
import inspect
|
||||
|
||||
for obj in vars(mod).values():
|
||||
if inspect.isclass(obj) and issubclass(obj, PropertyGroup):
|
||||
if hasattr(obj, 'bl_idname') and obj.bl_idname == mod.__name__:
|
||||
return obj
|
||||
|
||||
|
||||
def get_addon_preferences(name=''):
|
||||
"""Acquisition and registration"""
|
||||
addons = bpy.context.user_preferences.addons
|
||||
if __name__ not in addons: # wm.read_factory_settings()
|
||||
return None
|
||||
addon_prefs = addons[__name__].preferences
|
||||
if name:
|
||||
if not hasattr(addon_prefs, name):
|
||||
for mod in sub_modules:
|
||||
if mod.__name__.split('.')[-1] == name:
|
||||
cls = _get_pref_class(mod)
|
||||
if cls:
|
||||
prop = PointerProperty(type=cls)
|
||||
setattr(UIToolsPreferences, name, prop)
|
||||
bpy.utils.unregister_class(UIToolsPreferences)
|
||||
bpy.utils.register_class(UIToolsPreferences)
|
||||
return getattr(addon_prefs, name, None)
|
||||
else:
|
||||
return addon_prefs
|
||||
|
||||
|
||||
def register_submodule(mod):
|
||||
if not hasattr(mod, '__addon_enabled__'):
|
||||
mod.__addon_enabled__ = False
|
||||
if not mod.__addon_enabled__:
|
||||
mod.register()
|
||||
mod.__addon_enabled__ = True
|
||||
|
||||
|
||||
def unregister_submodule(mod):
|
||||
if mod.__addon_enabled__:
|
||||
mod.unregister()
|
||||
mod.__addon_enabled__ = False
|
||||
|
||||
prefs = get_addon_preferences()
|
||||
name = mod.__name__.split('.')[-1]
|
||||
if hasattr(UIToolsPreferences, name):
|
||||
delattr(UIToolsPreferences, name)
|
||||
if prefs:
|
||||
bpy.utils.unregister_class(UIToolsPreferences)
|
||||
bpy.utils.register_class(UIToolsPreferences)
|
||||
if name in prefs:
|
||||
del prefs[name]
|
||||
|
||||
class UIToolsPreferences(AddonPreferences):
|
||||
bl_idname = __name__
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
for mod in sub_modules:
|
||||
mod_name = mod.__name__.split('.')[-1]
|
||||
info = mod.bl_info
|
||||
column = layout.column()
|
||||
box = column.box()
|
||||
|
||||
# first stage
|
||||
expand = getattr(self, 'show_expanded_' + mod_name)
|
||||
icon = 'TRIA_DOWN' if expand else 'TRIA_RIGHT'
|
||||
col = box.column()
|
||||
row = col.row()
|
||||
sub = row.row()
|
||||
sub.context_pointer_set('addon_prefs', self)
|
||||
sub.alignment = 'LEFT'
|
||||
op = sub.operator('wm.context_toggle', text='', icon=icon,
|
||||
emboss=False)
|
||||
op.data_path = 'addon_prefs.show_expanded_' + mod_name
|
||||
sub.label('{}: {}'.format(info['category'], info['name']))
|
||||
sub = row.row()
|
||||
sub.alignment = 'RIGHT'
|
||||
if info.get('warning'):
|
||||
sub.label('', icon='ERROR')
|
||||
sub.prop(self, 'use_' + mod_name, text='')
|
||||
|
||||
# The second stage
|
||||
if expand:
|
||||
if info.get('description'):
|
||||
split = col.row().split(percentage=0.15)
|
||||
split.label('Description:')
|
||||
split.label(info['description'])
|
||||
if info.get('location'):
|
||||
split = col.row().split(percentage=0.15)
|
||||
split.label('Location:')
|
||||
split.label(info['location'])
|
||||
if info.get('author') and info.get('author') != 'chromoly':
|
||||
split = col.row().split(percentage=0.15)
|
||||
split.label('Author:')
|
||||
split.label(info['author'])
|
||||
if info.get('version'):
|
||||
split = col.row().split(percentage=0.15)
|
||||
split.label('Version:')
|
||||
split.label('.'.join(str(x) for x in info['version']),
|
||||
translate=False)
|
||||
if info.get('warning'):
|
||||
split = col.row().split(percentage=0.15)
|
||||
split.label('Warning:')
|
||||
split.label(' ' + info['warning'], icon='ERROR')
|
||||
|
||||
tot_row = int(bool(info.get('wiki_url')))
|
||||
if tot_row:
|
||||
split = col.row().split(percentage=0.15)
|
||||
split.label(text='Internet:')
|
||||
if info.get('wiki_url'):
|
||||
op = split.operator('wm.url_open',
|
||||
text='Documentation', icon='HELP')
|
||||
op.url = info.get('wiki_url')
|
||||
for i in range(4 - tot_row):
|
||||
split.separator()
|
||||
|
||||
# Details and settings
|
||||
if getattr(self, 'use_' + mod_name):
|
||||
prefs = get_addon_preferences(mod_name)
|
||||
|
||||
if prefs and hasattr(prefs, 'draw'):
|
||||
box = box.column()
|
||||
prefs.layout = box
|
||||
try:
|
||||
prefs.draw(context)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
box.label(text='Error (see console)', icon='ERROR')
|
||||
del prefs.layout
|
||||
|
||||
row = layout.row()
|
||||
row.label("End of Pie Menu Activations")
|
||||
|
||||
|
||||
for mod in sub_modules:
|
||||
info = mod.bl_info
|
||||
mod_name = mod.__name__.split('.')[-1]
|
||||
|
||||
def gen_update(mod):
|
||||
def update(self, context):
|
||||
if getattr(self, 'use_' + mod.__name__.split('.')[-1]):
|
||||
if not mod.__addon_enabled__:
|
||||
register_submodule(mod)
|
||||
else:
|
||||
if mod.__addon_enabled__:
|
||||
unregister_submodule(mod)
|
||||
return update
|
||||
|
||||
prop = BoolProperty(
|
||||
name=info['name'],
|
||||
description=info.get('description', ''),
|
||||
update=gen_update(mod),
|
||||
)
|
||||
setattr(UIToolsPreferences, 'use_' + mod_name, prop)
|
||||
prop = BoolProperty()
|
||||
setattr(UIToolsPreferences, 'show_expanded_' + mod_name, prop)
|
||||
|
||||
classes = (
|
||||
UIToolsPreferences,
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
prefs = get_addon_preferences()
|
||||
for mod in sub_modules:
|
||||
if not hasattr(mod, '__addon_enabled__'):
|
||||
mod.__addon_enabled__ = False
|
||||
name = mod.__name__.split('.')[-1]
|
||||
if getattr(prefs, 'use_' + name):
|
||||
register_submodule(mod)
|
||||
|
||||
|
||||
def unregister():
|
||||
for mod in sub_modules:
|
||||
if mod.__addon_enabled__:
|
||||
unregister_submodule(mod)
|
||||
|
||||
for cls in reversed(classes):
|
||||
bpy.utils.unregister_class(cls)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
|
@ -19,132 +19,22 @@
|
||||
# <pep8 compliant>
|
||||
|
||||
bl_info = {
|
||||
"name": "Pie Menus Official",
|
||||
"author": "Antony Riakiotakis, Sebastian Koenig",
|
||||
"version": (1, 0, 3),
|
||||
"name": "Clip Editor Pies: Key: 'hotkey list Below'",
|
||||
"description": "Clip Editor Pies",
|
||||
# "author": "Antony Riakiotakis, Sebastian Koenig",
|
||||
"version": (0, 1, 0),
|
||||
"blender": (2, 77, 0),
|
||||
"description": "Enable official Pie Menus in Blender",
|
||||
"wiki_url": "http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.72/UI/Pie_Menus",
|
||||
"tracker_url": "https://developer.blender.org/maniphest/task/create/?project=3&type=Bug",
|
||||
"category": "User Interface",
|
||||
}
|
||||
"location": "Q, W, Shift W, E. Shift S, Shift A",
|
||||
"warning": "",
|
||||
"wiki_url": "",
|
||||
"category": "Pie Menu"
|
||||
}
|
||||
|
||||
import bpy
|
||||
from bpy.types import Menu, Operator
|
||||
from bpy.props import EnumProperty
|
||||
|
||||
|
||||
class VIEW3D_PIE_object_mode(Menu):
|
||||
bl_label = "Mode"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.operator_enum("OBJECT_OT_mode_set", "mode")
|
||||
|
||||
|
||||
class VIEW3D_PIE_view_more(Menu):
|
||||
bl_label = "More"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.operator("VIEW3D_OT_view_persportho", text="Persp/Ortho", icon='RESTRICT_VIEW_OFF')
|
||||
pie.operator("VIEW3D_OT_camera_to_view")
|
||||
pie.operator("VIEW3D_OT_view_selected")
|
||||
pie.operator("VIEW3D_OT_view_all")
|
||||
pie.operator("VIEW3D_OT_localview")
|
||||
pie.operator("SCREEN_OT_region_quadview")
|
||||
|
||||
|
||||
class VIEW3D_PIE_view(Menu):
|
||||
bl_label = "View"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.operator_enum("VIEW3D_OT_viewnumpad", "type")
|
||||
pie.operator("wm.call_menu_pie", text="More", icon='PLUS').name = "VIEW3D_PIE_view_more"
|
||||
|
||||
|
||||
class VIEW3D_PIE_shade(Menu):
|
||||
bl_label = "Shade"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.prop(context.space_data, "viewport_shade", expand=True)
|
||||
|
||||
if context.active_object:
|
||||
if(context.mode == 'EDIT_MESH'):
|
||||
pie.operator("MESH_OT_faces_shade_smooth")
|
||||
pie.operator("MESH_OT_faces_shade_flat")
|
||||
else:
|
||||
pie.operator("OBJECT_OT_shade_smooth")
|
||||
pie.operator("OBJECT_OT_shade_flat")
|
||||
|
||||
|
||||
class VIEW3D_manipulator_set(Operator):
|
||||
bl_label = "Set Manipulator"
|
||||
bl_idname = "view3d.manipulator_set"
|
||||
|
||||
type = EnumProperty(
|
||||
name="Type",
|
||||
items=(('TRANSLATE', "Translate", "Use the manipulator for movement transformations"),
|
||||
('ROTATE', "Rotate", "Use the manipulator for rotation transformations"),
|
||||
('SCALE', "Scale", "Use the manipulator for scale transformations"),
|
||||
),
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
# show manipulator if user selects an option
|
||||
context.space_data.show_manipulator = True
|
||||
|
||||
context.space_data.transform_manipulators = {self.type}
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class VIEW3D_PIE_manipulator(Menu):
|
||||
bl_label = "Manipulator"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.operator("view3d.manipulator_set", icon='MAN_TRANS', text="Translate").type = 'TRANSLATE'
|
||||
pie.operator("view3d.manipulator_set", icon='MAN_ROT', text="Rotate").type = 'ROTATE'
|
||||
pie.operator("view3d.manipulator_set", icon='MAN_SCALE', text="Scale").type = 'SCALE'
|
||||
pie.prop(context.space_data, "show_manipulator")
|
||||
|
||||
|
||||
class VIEW3D_PIE_pivot(Menu):
|
||||
bl_label = "Pivot"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.prop(context.space_data, "pivot_point", expand=True)
|
||||
if context.active_object.mode == 'OBJECT':
|
||||
pie.prop(context.space_data, "use_pivot_point_align", text="Center Points")
|
||||
|
||||
|
||||
class VIEW3D_PIE_snap(Menu):
|
||||
bl_label = "Snapping"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
toolsettings = context.tool_settings
|
||||
pie = layout.menu_pie()
|
||||
pie.prop(toolsettings, "snap_element", expand=True)
|
||||
pie.prop(toolsettings, "use_snap")
|
||||
|
||||
from bpy.types import (
|
||||
Menu,
|
||||
Operator,
|
||||
)
|
||||
|
||||
class CLIP_PIE_refine_pie(Menu):
|
||||
# Refinement Options
|
||||
@ -352,43 +242,9 @@ class CLIP_PIE_timecontrol_pie(Menu):
|
||||
pie.operator("screen.frame_offset", text="Next Frame", icon='TRIA_RIGHT').delta = 1
|
||||
|
||||
|
||||
class PieMenuPrefs(bpy.types.AddonPreferences):
|
||||
bl_idname = __name__
|
||||
|
||||
bpy.types.Scene.Enable_Tab_01 = bpy.props.BoolProperty(default=False)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.prop(context.scene, "Enable_Tab_01", text="Hotkey List", icon="INFO")
|
||||
if context.scene.Enable_Tab_01:
|
||||
row = layout.row()
|
||||
layout.label(text="Object Mode: 'TAB', 'PRESS'")
|
||||
layout.label(text="Shade: 'Z', 'PRESS'")
|
||||
layout.label(text="View: 'Q', 'PRESS'")
|
||||
layout.label(text="Manipulator: 'SPACE', 'PRESS', ctrl=True")
|
||||
layout.label(text="Pivot: 'PERIOD', 'PRESS'")
|
||||
layout.label(text="Snap: 'TAB', 'PRESS', ctrl=True, shift=True")
|
||||
layout.label(text="Grease Pencil Stroke Edit Mode: 'TAB', 'PRESS'")
|
||||
layout.label(text="Marker: 'Q', 'PRESS'")
|
||||
layout.label(text="Clipsetup: 'W', 'PRESS'")
|
||||
layout.label(text="Tracking: 'E', 'PRESS'")
|
||||
layout.label(text="Solver: 'S', 'PRESS', shift=True")
|
||||
layout.label(text="Reconstruction: 'W', 'PRESS', shift=True")
|
||||
layout.label(text="Timecontrol: 'A', 'PRESS', oskey=True")
|
||||
|
||||
addon_keymaps = []
|
||||
|
||||
classes = (
|
||||
VIEW3D_manipulator_set,
|
||||
|
||||
VIEW3D_PIE_object_mode,
|
||||
VIEW3D_PIE_view,
|
||||
VIEW3D_PIE_view_more,
|
||||
VIEW3D_PIE_shade,
|
||||
VIEW3D_PIE_manipulator,
|
||||
VIEW3D_PIE_pivot,
|
||||
VIEW3D_PIE_snap,
|
||||
PieMenuPrefs,
|
||||
CLIP_PIE_geometry_reconstruction,
|
||||
CLIP_PIE_tracking_pie,
|
||||
CLIP_PIE_display_pie,
|
||||
@ -410,24 +266,6 @@ def register():
|
||||
|
||||
if wm.keyconfigs.addon:
|
||||
km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS')
|
||||
kmi.properties.name = 'VIEW3D_PIE_object_mode'
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'Z', 'PRESS')
|
||||
kmi.properties.name = 'VIEW3D_PIE_shade'
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'Q', 'PRESS')
|
||||
kmi.properties.name = 'VIEW3D_PIE_view'
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'SPACE', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = 'VIEW3D_PIE_manipulator'
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'PERIOD', 'PRESS')
|
||||
kmi.properties.name = 'VIEW3D_PIE_pivot'
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS', ctrl=True, shift=True)
|
||||
kmi.properties.name = 'VIEW3D_PIE_snap'
|
||||
addon_keymaps.append(km)
|
||||
|
||||
km = wm.keyconfigs.addon.keymaps.new(name='Grease Pencil Stroke Edit Mode')
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS')
|
||||
kmi.properties.name = 'VIEW3D_PIE_object_mode'
|
||||
addon_keymaps.append(km)
|
||||
|
||||
km = wm.keyconfigs.addon.keymaps.new(name="Clip", space_type='CLIP_EDITOR')
|
||||
kmi = km.keymap_items.new("wm.call_menu_pie", 'Q', 'PRESS')
|
||||
@ -443,7 +281,7 @@ def register():
|
||||
addon_keymaps.append(km)
|
||||
|
||||
km = wm.keyconfigs.addon.keymaps.new(name="Frames")
|
||||
kmi = km.keymap_items.new("wm.call_menu_pie", 'A', 'PRESS', oskey=True)
|
||||
kmi = km.keymap_items.new("wm.call_menu_pie", 'A', 'PRESS', shift=True)
|
||||
kmi.properties.name = "CLIP_PIE_timecontrol_pie"
|
||||
|
||||
addon_keymaps.append(km)
|
||||
@ -463,3 +301,6 @@ def unregister():
|
||||
wm.keyconfigs.addon.keymaps.remove(km)
|
||||
|
||||
addon_keymaps.clear()
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
90
pie_menus_official/pie_manipulator_of/__init__.py
Normal file
90
pie_menus_official/pie_manipulator_of/__init__.py
Normal file
@ -0,0 +1,90 @@
|
||||
|
||||
bl_info = {
|
||||
"name": "Manipulator Menu: Key: 'Ctrl Space'",
|
||||
"description": "Manipulator Modes",
|
||||
"author": "Antony Riakiotakis, Sebastian Koenig",
|
||||
"version": (0, 1, 0),
|
||||
"blender": (2, 77, 0),
|
||||
"location": "Ctrl Space",
|
||||
"warning": "",
|
||||
"wiki_url": "",
|
||||
"category": "3d View"
|
||||
}
|
||||
|
||||
import bpy
|
||||
from bpy.types import (
|
||||
Menu,
|
||||
Operator,
|
||||
)
|
||||
from bpy.props import (
|
||||
EnumProperty,
|
||||
)
|
||||
|
||||
# Pie Manipulator Mode - Ctrl Space
|
||||
class VIEW3D_manipulator_set_of(Operator):
|
||||
bl_label = "Set Manipulator"
|
||||
bl_idname = "view3d.manipulator_set"
|
||||
|
||||
type = EnumProperty(
|
||||
name="Type",
|
||||
items=(('TRANSLATE', "Translate", "Use the manipulator for movement transformations"),
|
||||
('ROTATE', "Rotate", "Use the manipulator for rotation transformations"),
|
||||
('SCALE', "Scale", "Use the manipulator for scale transformations"),
|
||||
),
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
# show manipulator if user selects an option
|
||||
context.space_data.show_manipulator = True
|
||||
|
||||
context.space_data.transform_manipulators = {self.type}
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class VIEW3D_PIE_manipulator_of(Menu):
|
||||
bl_label = "Manipulator"
|
||||
bl_idname = "view3d.manipulator_of"
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.operator("view3d.manipulator_set", icon='MAN_TRANS', text="Translate").type = 'TRANSLATE'
|
||||
pie.operator("view3d.manipulator_set", icon='MAN_ROT', text="Rotate").type = 'ROTATE'
|
||||
pie.operator("view3d.manipulator_set", icon='MAN_SCALE', text="Scale").type = 'SCALE'
|
||||
pie.prop(context.space_data, "show_manipulator")
|
||||
|
||||
classes = [
|
||||
VIEW3D_manipulator_set_of,
|
||||
VIEW3D_PIE_manipulator_of,
|
||||
]
|
||||
|
||||
addon_keymaps = []
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
if wm.keyconfigs.addon:
|
||||
# Align
|
||||
km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'SPACE', 'PRESS', ctrl=True)
|
||||
kmi.properties.name = "view3d.manipulator_of"
|
||||
addon_keymaps.append((km, kmi))
|
||||
|
||||
def unregister():
|
||||
for cls in classes:
|
||||
bpy.utils.unregister_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
kc = wm.keyconfigs.addon
|
||||
if kc:
|
||||
km = kc.keymaps['Object Non-modal']
|
||||
for kmi in km.keymap_items:
|
||||
if kmi.idname == 'wm.call_menu_pie':
|
||||
if kmi.properties.name == "view3d.manipulator_of":
|
||||
km.keymap_items.remove(kmi)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
79
pie_menus_official/pie_object_modes_of/__init__.py
Normal file
79
pie_menus_official/pie_object_modes_of/__init__.py
Normal file
@ -0,0 +1,79 @@
|
||||
|
||||
bl_info = {
|
||||
"name": "Mode Set: Key: 'Tab'",
|
||||
"description": "Object Modes",
|
||||
"author": "Antony Riakiotakis, Sebastian Koenig",
|
||||
"version": (0, 1, 0),
|
||||
"blender": (2, 77, 0),
|
||||
"location": "Tab key",
|
||||
"warning": "",
|
||||
"wiki_url": "",
|
||||
"category": "3d View"
|
||||
}
|
||||
|
||||
import bpy
|
||||
from bpy.types import (
|
||||
Menu,
|
||||
Operator,
|
||||
)
|
||||
|
||||
# Pie Object Mode - Tab
|
||||
class VIEW3D_PIE_object_mode_of(Menu):
|
||||
bl_idname = "pie.object_mode_of"
|
||||
bl_label = "Mode"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.operator_enum("OBJECT_OT_mode_set", "mode")
|
||||
|
||||
classes = [
|
||||
VIEW3D_PIE_object_mode_of,
|
||||
]
|
||||
|
||||
addon_keymaps = []
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
if wm.keyconfigs.addon:
|
||||
# Object Modes
|
||||
km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS')
|
||||
kmi.properties.name = "pie.object_mode_of"
|
||||
addon_keymaps.append((km, kmi))
|
||||
|
||||
if wm.keyconfigs.addon:
|
||||
# Grease Pencil Edit Modes
|
||||
km = wm.keyconfigs.addon.keymaps.new(name='Grease Pencil Stroke Edit Mode')
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS')
|
||||
kmi.properties.name = "pie.object_mode_of"
|
||||
addon_keymaps.append((km, kmi))
|
||||
|
||||
|
||||
def unregister():
|
||||
for cls in classes:
|
||||
bpy.utils.unregister_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
kc = wm.keyconfigs.addon
|
||||
if kc:
|
||||
km = kc.keymaps['Object Non-modal']
|
||||
for kmi in km.keymap_items:
|
||||
if kmi.idname == 'wm.call_menu_pie':
|
||||
if kmi.properties.name == "pie.object_mode_of":
|
||||
km.keymap_items.remove(kmi)
|
||||
|
||||
kc = wm.keyconfigs.addon
|
||||
if kc:
|
||||
km = kc.keymaps['Grease Pencil Stroke Edit Mode']
|
||||
for kmi in km.keymap_items:
|
||||
if kmi.idname == 'wm.call_menu_pie':
|
||||
if kmi.properties.name == "pie.object_mode_of":
|
||||
km.keymap_items.remove(kmi)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
65
pie_menus_official/pie_pivot_of/__init__.py
Normal file
65
pie_menus_official/pie_pivot_of/__init__.py
Normal file
@ -0,0 +1,65 @@
|
||||
|
||||
bl_info = {
|
||||
"name": "Pivot Menu: Key: '. key'",
|
||||
"description": "Manipulator Modes",
|
||||
"author": "Antony Riakiotakis, Sebastian Koenig",
|
||||
"version": (0, 1, 0),
|
||||
"blender": (2, 77, 0),
|
||||
"location": ". key",
|
||||
"warning": "",
|
||||
"wiki_url": "",
|
||||
"category": "3d View"
|
||||
}
|
||||
|
||||
import bpy
|
||||
from bpy.types import (
|
||||
Menu,
|
||||
Operator,
|
||||
)
|
||||
|
||||
# Pie Pivot Mode - . key
|
||||
class VIEW3D_PIE_pivot_of(Menu):
|
||||
bl_label = "Pivot"
|
||||
bl_idname = "view3d.pivot_of"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.prop(context.space_data, "pivot_point", expand=True)
|
||||
if context.active_object.mode == 'OBJECT':
|
||||
pie.prop(context.space_data, "use_pivot_point_align", text="Center Points")
|
||||
|
||||
classes = [
|
||||
VIEW3D_PIE_pivot_of
|
||||
]
|
||||
|
||||
addon_keymaps = []
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
if wm.keyconfigs.addon:
|
||||
# Align
|
||||
km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'PERIOD', 'PRESS')
|
||||
kmi.properties.name = "view3d.pivot_of"
|
||||
addon_keymaps.append((km, kmi))
|
||||
|
||||
def unregister():
|
||||
for cls in classes:
|
||||
bpy.utils.unregister_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
kc = wm.keyconfigs.addon
|
||||
if kc:
|
||||
km = kc.keymaps['Object Non-modal']
|
||||
for kmi in km.keymap_items:
|
||||
if kmi.idname == 'wm.call_menu_pie':
|
||||
if kmi.properties.name == "view3d.pivot_of":
|
||||
km.keymap_items.remove(kmi)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
71
pie_menus_official/pie_shade_of/__init__.py
Normal file
71
pie_menus_official/pie_shade_of/__init__.py
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
bl_info = {
|
||||
"name": "Shade Menu: Key: 'Z key'",
|
||||
"description": "View Modes",
|
||||
"author": "Antony Riakiotakis, Sebastian Koenig",
|
||||
"version": (0, 1, 0),
|
||||
"blender": (2, 77, 0),
|
||||
"location": "Z key",
|
||||
"warning": "",
|
||||
"wiki_url": "",
|
||||
"category": "3d View"
|
||||
}
|
||||
|
||||
import bpy
|
||||
from bpy.types import (
|
||||
Menu,
|
||||
Operator,
|
||||
)
|
||||
|
||||
# Pie Shade Mode - Z
|
||||
class VIEW3D_PIE_shade_of(Menu):
|
||||
bl_label = "Shade"
|
||||
bl_idname = "pie.shade_of"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.prop(context.space_data, "viewport_shade", expand=True)
|
||||
|
||||
if context.active_object:
|
||||
if(context.mode == 'EDIT_MESH'):
|
||||
pie.operator("MESH_OT_faces_shade_smooth")
|
||||
pie.operator("MESH_OT_faces_shade_flat")
|
||||
else:
|
||||
pie.operator("OBJECT_OT_shade_smooth")
|
||||
pie.operator("OBJECT_OT_shade_flat")
|
||||
|
||||
classes = [
|
||||
VIEW3D_PIE_shade_of,
|
||||
]
|
||||
|
||||
addon_keymaps = []
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
if wm.keyconfigs.addon:
|
||||
# Align
|
||||
km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'Z', 'PRESS')
|
||||
kmi.properties.name = "pie.shade_of"
|
||||
addon_keymaps.append((km, kmi))
|
||||
|
||||
def unregister():
|
||||
for cls in classes:
|
||||
bpy.utils.unregister_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
kc = wm.keyconfigs.addon
|
||||
if kc:
|
||||
km = kc.keymaps['Object Non-modal']
|
||||
for kmi in km.keymap_items:
|
||||
if kmi.idname == 'wm.call_menu_pie':
|
||||
if kmi.properties.name == "pie.shade_of":
|
||||
km.keymap_items.remove(kmi)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
65
pie_menus_official/pie_snap_of/__init__.py
Normal file
65
pie_menus_official/pie_snap_of/__init__.py
Normal file
@ -0,0 +1,65 @@
|
||||
|
||||
bl_info = {
|
||||
"name": "Snap Menu: Key: 'Ctrl Shift Tab'",
|
||||
"description": "Snap Modes",
|
||||
"author": "Antony Riakiotakis, Sebastian Koenig",
|
||||
"version": (0, 1, 0),
|
||||
"blender": (2, 77, 0),
|
||||
"location": "Ctrl Shift Tab",
|
||||
"warning": "",
|
||||
"wiki_url": "",
|
||||
"category": "3d View"
|
||||
}
|
||||
|
||||
import bpy
|
||||
from bpy.types import (
|
||||
Menu,
|
||||
Operator,
|
||||
)
|
||||
|
||||
# Pie Snap Mode - . key
|
||||
class VIEW3D_PIE_snap_of(Menu):
|
||||
bl_label = "Snapping"
|
||||
bl_idname = "view3d.snap_of"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
toolsettings = context.tool_settings
|
||||
pie = layout.menu_pie()
|
||||
pie.prop(toolsettings, "snap_element", expand=True)
|
||||
pie.prop(toolsettings, "use_snap")
|
||||
|
||||
classes = [
|
||||
VIEW3D_PIE_snap_of
|
||||
]
|
||||
|
||||
addon_keymaps = []
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
if wm.keyconfigs.addon:
|
||||
# Align
|
||||
km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS', ctrl=True, shift=True)
|
||||
kmi.properties.name = "view3d.snap_of"
|
||||
addon_keymaps.append((km, kmi))
|
||||
|
||||
def unregister():
|
||||
for cls in classes:
|
||||
bpy.utils.unregister_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
kc = wm.keyconfigs.addon
|
||||
if kc:
|
||||
km = kc.keymaps['Object Non-modal']
|
||||
for kmi in km.keymap_items:
|
||||
if kmi.idname == 'wm.call_menu_pie':
|
||||
if kmi.properties.name == "view3d.snap_of":
|
||||
km.keymap_items.remove(kmi)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
81
pie_menus_official/pie_view_of/__init__.py
Normal file
81
pie_menus_official/pie_view_of/__init__.py
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
bl_info = {
|
||||
"name": "View Menu: Key: 'Q key'",
|
||||
"description": "View Modes",
|
||||
"author": "Antony Riakiotakis, Sebastian Koenig",
|
||||
"version": (0, 1, 0),
|
||||
"blender": (2, 77, 0),
|
||||
"location": "Q key",
|
||||
"warning": "",
|
||||
"wiki_url": "",
|
||||
"category": "3d View"
|
||||
}
|
||||
|
||||
import bpy
|
||||
from bpy.types import (
|
||||
Menu,
|
||||
Operator,
|
||||
)
|
||||
|
||||
# Pie View Mode - Q
|
||||
class VIEW3D_PIE_view_more_of(Menu):
|
||||
bl_label = "More"
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.operator("VIEW3D_OT_view_persportho", text="Persp/Ortho", icon='RESTRICT_VIEW_OFF')
|
||||
pie.operator("VIEW3D_OT_camera_to_view")
|
||||
pie.operator("VIEW3D_OT_view_selected")
|
||||
pie.operator("VIEW3D_OT_view_all")
|
||||
pie.operator("VIEW3D_OT_localview")
|
||||
pie.operator("SCREEN_OT_region_quadview")
|
||||
|
||||
|
||||
class VIEW3D_PIE_view_of(Menu):
|
||||
bl_label = "View"
|
||||
bl_idname = "pie.view_of"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
pie = layout.menu_pie()
|
||||
pie.operator_enum("VIEW3D_OT_viewnumpad", "type")
|
||||
pie.operator("wm.call_menu_pie", text="More", icon='PLUS').name = "VIEW3D_PIE_view_more_of"
|
||||
|
||||
classes = [
|
||||
VIEW3D_PIE_view_more_of,
|
||||
VIEW3D_PIE_view_of,
|
||||
]
|
||||
|
||||
addon_keymaps = []
|
||||
|
||||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
if wm.keyconfigs.addon:
|
||||
# Align
|
||||
km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal')
|
||||
kmi = km.keymap_items.new('wm.call_menu_pie', 'Q', 'PRESS')
|
||||
kmi.properties.name = "pie.view_of"
|
||||
addon_keymaps.append((km, kmi))
|
||||
|
||||
def unregister():
|
||||
for cls in classes:
|
||||
bpy.utils.unregister_class(cls)
|
||||
wm = bpy.context.window_manager
|
||||
|
||||
kc = wm.keyconfigs.addon
|
||||
if kc:
|
||||
km = kc.keymaps['Object Non-modal']
|
||||
for kmi in km.keymap_items:
|
||||
if kmi.idname == 'wm.call_menu_pie':
|
||||
if kmi.properties.name == "pie.view_of":
|
||||
km.keymap_items.remove(kmi)
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
320
pie_menus_official/utils.py
Normal file
320
pie_menus_official/utils.py
Normal file
@ -0,0 +1,320 @@
|
||||
# ##### 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
|
||||
import bpy
|
||||
|
||||
|
||||
class AddonPreferences:
|
||||
_module = {}
|
||||
|
||||
@classmethod
|
||||
def get_prefs(cls, package=''):
|
||||
if not package:
|
||||
package = __package__
|
||||
if '.' in package:
|
||||
pkg, name = package.split('.')
|
||||
# key = cls.__qualname__
|
||||
if package in cls._module:
|
||||
mod = cls._module[package]
|
||||
else:
|
||||
import importlib
|
||||
mod = cls._module[package] = importlib.import_module(pkg)
|
||||
return mod.get_addon_preferences(name)
|
||||
else:
|
||||
context = bpy.context
|
||||
return context.user_preferences.addons[package].preferences
|
||||
|
||||
@classmethod
|
||||
def register(cls):
|
||||
if '.' in __package__:
|
||||
cls.get_prefs()
|
||||
|
||||
@classmethod
|
||||
def unregister(cls):
|
||||
cls._module.clear()
|
||||
|
||||
|
||||
class SpaceProperty:
|
||||
"""
|
||||
bpy.types.Space #Add the virtual property in
|
||||
|
||||
# Instantiation
|
||||
space_prop = SpaceProperty(
|
||||
[[bpy.types.SpaceView3D, 'lock_cursor_location',
|
||||
bpy.props.BoolProperty()]])
|
||||
|
||||
# When drawing
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
view = context.space_data
|
||||
prop = space_prop.get_prop(view, 'lock_cursor_location')
|
||||
layout.prop(prop, 'lock_cursor_location')
|
||||
|
||||
# register / unregister
|
||||
def register():
|
||||
space_prop.register()
|
||||
|
||||
def unregister():
|
||||
space_prop.unregister()
|
||||
"""
|
||||
|
||||
space_types = {
|
||||
'EMPTY': bpy.types.Space,
|
||||
'NONE': bpy.types.Space,
|
||||
'CLIP_EDITOR': bpy.types.SpaceClipEditor,
|
||||
'CONSOLE': bpy.types.SpaceConsole,
|
||||
'DOPESHEET_EDITOR': bpy.types.SpaceDopeSheetEditor,
|
||||
'FILE_BROWSER': bpy.types.SpaceFileBrowser,
|
||||
'GRAPH_EDITOR': bpy.types.SpaceGraphEditor,
|
||||
'IMAGE_EDITOR': bpy.types.SpaceImageEditor,
|
||||
'INFO': bpy.types.SpaceInfo,
|
||||
'LOGIC_EDITOR': bpy.types.SpaceLogicEditor,
|
||||
'NLA_EDITOR': bpy.types.SpaceNLA,
|
||||
'NODE_EDITOR': bpy.types.SpaceNodeEditor,
|
||||
'OUTLINER': bpy.types.SpaceOutliner,
|
||||
'PROPERTIES': bpy.types.SpaceProperties,
|
||||
'SEQUENCE_EDITOR': bpy.types.SpaceSequenceEditor,
|
||||
'TEXT_EDITOR': bpy.types.SpaceTextEditor,
|
||||
'TIMELINE': bpy.types.SpaceTimeline,
|
||||
'USER_PREFERENCES': bpy.types.SpaceUserPreferences,
|
||||
'VIEW_3D': bpy.types.SpaceView3D,
|
||||
}
|
||||
# space_types_r = {v: k for k, v in space_types.items()}
|
||||
|
||||
def __init__(self, *props):
|
||||
"""
|
||||
:param props: [[space_type, attr, prop], ...]
|
||||
[[Or string bpy.types.Space, String,
|
||||
bpy.props.***()かPropertyGroup], ...]
|
||||
bpy.types.PropertyGroup In advance if you use register_class()so
|
||||
It is registered
|
||||
:type props: list[list]
|
||||
"""
|
||||
self.props = [list(elem) for elem in props]
|
||||
for elem in self.props:
|
||||
space_type = elem[0]
|
||||
if isinstance(space_type, str):
|
||||
elem[0] = self.space_types[space_type]
|
||||
self.registered = []
|
||||
self.save_pre = self.save_post = self.load_post = None
|
||||
|
||||
def gen_save_pre(self):
|
||||
@bpy.app.handlers.persistent
|
||||
def save_pre(dummy):
|
||||
wm = bpy.context.window_manager
|
||||
for (space_type, attr, prop), (cls, wm_prop_name) in zip(
|
||||
self.props, self.registered):
|
||||
if wm_prop_name not in wm:
|
||||
continue
|
||||
d = {p['name']: p for p in wm[wm_prop_name]} # not p.name
|
||||
for screen in bpy.data.screens:
|
||||
ls = []
|
||||
for area in screen.areas:
|
||||
for space in area.spaces:
|
||||
if isinstance(space, space_type):
|
||||
key = str(space.as_pointer())
|
||||
if key in d:
|
||||
ls.append(d[key])
|
||||
else:
|
||||
ls.append({})
|
||||
screen[wm_prop_name] = ls
|
||||
self.save_pre = save_pre
|
||||
return save_pre
|
||||
|
||||
def gen_save_post(self):
|
||||
@bpy.app.handlers.persistent
|
||||
def save_post(dummy):
|
||||
# clean up
|
||||
for cls, wm_prop_name in self.registered:
|
||||
for screen in bpy.data.screens:
|
||||
if wm_prop_name in screen:
|
||||
del screen[wm_prop_name]
|
||||
self.save_post = save_post
|
||||
return save_post
|
||||
|
||||
def gen_load_post(self):
|
||||
@bpy.app.handlers.persistent
|
||||
def load_post(dummy):
|
||||
from collections import OrderedDict
|
||||
for (space_type, attr, prop), (cls, wm_prop_name) in zip(
|
||||
self.props, self.registered):
|
||||
d = OrderedDict()
|
||||
for screen in bpy.data.screens:
|
||||
if wm_prop_name not in screen:
|
||||
continue
|
||||
|
||||
spaces = []
|
||||
for area in screen.areas:
|
||||
for space in area.spaces:
|
||||
if isinstance(space, space_type):
|
||||
spaces.append(space)
|
||||
|
||||
for space, p in zip(spaces, screen[wm_prop_name]):
|
||||
key = p['name'] = str(space.as_pointer())
|
||||
d[key] = p
|
||||
if d:
|
||||
bpy.context.window_manager[wm_prop_name] = list(d.values())
|
||||
|
||||
# clean up
|
||||
for cls, wm_prop_name in self.registered:
|
||||
for screen in bpy.data.screens:
|
||||
if wm_prop_name in screen:
|
||||
del screen[wm_prop_name]
|
||||
|
||||
self.load_post = load_post
|
||||
return load_post
|
||||
|
||||
def get_all(self, space_type=None, attr=''):
|
||||
"""
|
||||
:param space_type: If the property is only only one optional
|
||||
:type space_type: bpy.types.Space
|
||||
:param attr: If the property is only only one optional
|
||||
:type attr: str
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
if space_type and isinstance(space_type, str):
|
||||
space_type = self.space_types.get(space_type)
|
||||
context = bpy.context
|
||||
for (st, attri, prop), (cls, wm_prop_name) in zip(
|
||||
self.props, self.registered):
|
||||
if (st == space_type or issubclass(space_type, st) or
|
||||
not space_type and len(self.props) == 1):
|
||||
if attri == attr or not attr and len(self.props) == 1:
|
||||
seq = getattr(context.window_manager, wm_prop_name)
|
||||
return seq
|
||||
|
||||
def get(self, space, attr=''):
|
||||
"""
|
||||
:type space: bpy.types.Space
|
||||
:param attr: If the property is only only one optional
|
||||
:type attr: str
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
seq = self.get_all(type(space), attr)
|
||||
if seq is not None:
|
||||
key = str(space.as_pointer())
|
||||
if key not in seq:
|
||||
item = seq.add()
|
||||
item.name = key
|
||||
return seq[key]
|
||||
|
||||
def _property_name(self, space_type, attr):
|
||||
return space_type.__name__.lower() + '_' + attr
|
||||
|
||||
def register(self):
|
||||
import inspect
|
||||
for space_type, attr, prop in self.props:
|
||||
if inspect.isclass(prop) and \
|
||||
issubclass(prop, bpy.types.PropertyGroup):
|
||||
cls = prop
|
||||
else:
|
||||
name = 'WM_PG_' + space_type.__name__ + '_' + attr
|
||||
cls = type(name, (bpy.types.PropertyGroup,), {attr: prop})
|
||||
bpy.utils.register_class(cls)
|
||||
|
||||
collection_prop = bpy.props.CollectionProperty(type=cls)
|
||||
wm_prop_name = self._property_name(space_type, attr)
|
||||
setattr(bpy.types.WindowManager, wm_prop_name, collection_prop)
|
||||
|
||||
self.registered.append((cls, wm_prop_name))
|
||||
|
||||
def gen():
|
||||
def get(self):
|
||||
seq = getattr(bpy.context.window_manager, wm_prop_name)
|
||||
key = str(self.as_pointer())
|
||||
if key not in seq:
|
||||
item = seq.add()
|
||||
item.name = key
|
||||
if prop == cls:
|
||||
return seq[key]
|
||||
else:
|
||||
return getattr(seq[key], attr)
|
||||
|
||||
def set(self, value):
|
||||
seq = getattr(bpy.context.window_manager, wm_prop_name)
|
||||
key = str(self.as_pointer())
|
||||
if key not in seq:
|
||||
item = seq.add()
|
||||
item.name = key
|
||||
if prop != cls: # PropertyGroup It is not writable
|
||||
return setattr(seq[key], attr, value)
|
||||
|
||||
return property(get, set)
|
||||
|
||||
setattr(space_type, attr, gen())
|
||||
|
||||
bpy.app.handlers.save_pre.append(self.gen_save_pre())
|
||||
bpy.app.handlers.save_post.append(self.gen_save_post())
|
||||
bpy.app.handlers.load_post.append(self.gen_load_post())
|
||||
|
||||
def unregister(self):
|
||||
bpy.app.handlers.save_pre.remove(self.save_pre)
|
||||
bpy.app.handlers.save_post.remove(self.save_post)
|
||||
bpy.app.handlers.load_post.remove(self.load_post)
|
||||
|
||||
for (space_type, attr, prop), (cls, wm_prop_name) in zip(
|
||||
self.props, self.registered):
|
||||
delattr(bpy.types.WindowManager, wm_prop_name)
|
||||
if wm_prop_name in bpy.context.window_manager:
|
||||
del bpy.context.window_manager[wm_prop_name]
|
||||
delattr(space_type, attr)
|
||||
|
||||
if prop != cls:
|
||||
# originally bpy.types.PropertyGroup Skip Nara
|
||||
bpy.utils.unregister_class(cls)
|
||||
|
||||
for screen in bpy.data.screens:
|
||||
if wm_prop_name in screen:
|
||||
del screen[wm_prop_name]
|
||||
|
||||
self.registered.clear()
|
||||
|
||||
|
||||
def operator_call(op, *args, _scene_update=True, **kw):
|
||||
"""vawm Than
|
||||
operator_call(bpy.ops.view3d.draw_nearest_element,
|
||||
'INVOKE_DEFAULT', type='ENABLE', _scene_update=False)
|
||||
"""
|
||||
import bpy
|
||||
from _bpy import ops as ops_module
|
||||
|
||||
BPyOpsSubModOp = op.__class__
|
||||
op_call = ops_module.call
|
||||
context = bpy.context
|
||||
|
||||
# Get the operator from blender
|
||||
wm = context.window_manager
|
||||
|
||||
# run to account for any rna values the user changes.
|
||||
if _scene_update:
|
||||
BPyOpsSubModOp._scene_update(context)
|
||||
|
||||
if args:
|
||||
C_dict, C_exec, C_undo = BPyOpsSubModOp._parse_args(args)
|
||||
ret = op_call(op.idname_py(), C_dict, kw, C_exec, C_undo)
|
||||
else:
|
||||
ret = op_call(op.idname_py(), None, kw)
|
||||
|
||||
if 'FINISHED' in ret and context.window_manager == wm:
|
||||
if _scene_update:
|
||||
BPyOpsSubModOp._scene_update(context)
|
||||
|
||||
return ret
|
Reference in New Issue
Block a user