diff --git a/source/__init__.py b/source/__init__.py index c5a89af..268c211 100644 --- a/source/__init__.py +++ b/source/__init__.py @@ -2,19 +2,26 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -# Contributed to by meta-androcto, pitiwazou, chromoly, italic, kc98 +bl_info = { + "name":"3D Viewport Pie Menus", + "description": "A set of handy pie menus to enhance various workflows", + "author": "pitiwazou, meta-androcto, Demeter Dzadik", + "version": (1, 4, 1), + "blender": (2, 8, 0), + "location": "See Add-on Preferences for shortcut list", + "warning": "", + "doc_url": "", + 'tracker_url': "https://projects.blender.org/extensions/space_view3d_pie_menus", + 'support': 'COMMUNITY', + "category": "Modeling", +} -import bpy -from bpy.props import ( - BoolProperty, - PointerProperty, -) -from bpy.types import ( - PropertyGroup, - AddonPreferences, -) +from bpy.utils import register_class, unregister_class +import importlib -sub_modules_names = ( +module_names = ( + "prefs", + "hotkeys", "pie_modes_menu", "pie_views_numpad_menu", "pie_sculpt_menu", @@ -33,207 +40,45 @@ sub_modules_names = ( ) -sub_modules = [__import__(__package__ + "." + submod, {}, {}, submod) for submod in sub_modules_names] +modules = [ + __import__(__package__ + "." + submod, {}, {}, submod) + for submod in module_names +] -def _get_pref_class(mod): - import inspect +def register_unregister_modules(modules: list, register: bool): + """Recursively register or unregister modules by looking for either + un/register() functions or lists named `registry` which should be a list of + registerable classes. + """ + register_func = register_class if register else unregister_class - 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 + for m in modules: + if register: + importlib.reload(m) + if hasattr(m, 'registry'): + for c in m.registry: + try: + register_func(c) + except Exception as e: + un = 'un' if not register else '' + print( + f"Warning: CloudRig failed to {un}register class: {c.__name__}" + ) + print(e) + if hasattr(m, 'modules'): + register_unregister_modules(m.modules, register) -def get_addon_preferences(name=''): - """Acquisition and registration""" - addons = bpy.context.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) - create_property(PIEToolsPreferences, name, prop) - bpy.utils.unregister_class(PIEToolsPreferences) - bpy.utils.register_class(PIEToolsPreferences) - return getattr(addon_prefs, name, None) - else: - return addon_prefs - - -def create_property(cls, name, prop): - if not hasattr(cls, '__annotations__'): - cls.__annotations__ = dict() - cls.__annotations__[name] = prop - - -def register_submodule(mod): - 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(PIEToolsPreferences, name): - delattr(PIEToolsPreferences, name) - if prefs: - bpy.utils.unregister_class(PIEToolsPreferences) - bpy.utils.register_class(PIEToolsPreferences) - if name in prefs: - del prefs[name] - - -class PIEToolsPreferences(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) - op = sub.operator('wm.context_toggle', text='', icon=icon, - emboss=False) - op.data_path = 'addon_prefs.show_expanded_' + mod_name - sub.label(text='{}: {}'.format(info['category'], info['name'])) - sub = row.row() - sub.alignment = 'RIGHT' - if info.get('warning'): - sub.label(text='', icon='ERROR') - sub.prop(self, 'use_' + mod_name, text='') - - # The second stage - if expand: - if info.get('description'): - split = col.row().split(factor=0.15) - split.label(text='Description:') - split.label(text=info['description']) - if info.get('location'): - split = col.row().split(factor=0.15) - split.label(text='Location:') - split.label(text=info['location']) - """ - if info.get('author'): - split = col.row().split(factor=0.15) - split.label(text='Author:') - split.label(text=info['author']) - """ - if info.get('version'): - split = col.row().split(factor=0.15) - split.label(text='Version:') - split.label(text='.'.join(str(x) for x in info['version']), - translate=False) - if info.get('warning'): - split = col.row().split(factor=0.15) - split.label(text='Warning:') - split.label(text=' ' + info['warning'], icon='ERROR') - - tot_row = int(bool(info.get('doc_url'))) - if tot_row: - split = col.row().split(factor=0.15) - split.label(text='Internet:') - if info.get('doc_url'): - op = split.operator('wm.url_open', - text='Documentation', icon='HELP') - op.url = info.get('doc_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: - import traceback - traceback.print_exc() - box.label(text='Error (see console)', icon='ERROR') - del prefs.layout - - row = layout.row() - row.label(text="End of Pie Menu Activations", icon="FILE_PARENT") - - -for mod in sub_modules: - info = mod.bl_info - mod_name = mod.__name__.split('.')[-1] - - def gen_update(mod): - def update(self, context): - enabled = getattr(self, 'use_' + mod.__name__.split('.')[-1]) - if enabled: - register_submodule(mod) - else: - unregister_submodule(mod) - mod.__addon_enabled__ = enabled - return update - - create_property( - PIEToolsPreferences, - 'use_' + mod_name, - BoolProperty( - name=info['name'], - description=info.get('description', ''), - update=gen_update(mod), - default=True, - )) - - create_property( - PIEToolsPreferences, - 'show_expanded_' + mod_name, - BoolProperty()) - - -classes = ( - PIEToolsPreferences, -) + if register and hasattr(m, 'register'): + m.register() + elif hasattr(m, 'unregister'): + m.unregister() 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) + register_unregister_modules(modules, True) 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() + register_unregister_modules(reversed(modules), False) diff --git a/source/blender_manifest.toml b/source/blender_manifest.toml index 80ae0f5..e70ba38 100644 --- a/source/blender_manifest.toml +++ b/source/blender_manifest.toml @@ -1,7 +1,7 @@ schema_version = "1.0.0" id = "viewport_pie_menus" name = "3D Viewport Pie Menus" -version = "1.3.0" +version = "1.3.1" tagline = "Pie Menu Activation" maintainer = "Community" type = "add-on" @@ -9,4 +9,14 @@ tags = ["User Interface"] blender_version_min = "4.2.0" license = ["SPDX:GPL-2.0-or-later"] website = "https://projects.blender.org/extensions/space_view3d_pie_menus" -copyright = ["2024 meta-androcto"] +copyright = [ + "2024 Demeter Dzadik", + "2016-2022 meta-androcto", + "2016-2022 pitiwazou", + "2016-2022 chromoly", + "2016-2022 italic", + "2016-2022 kc98", + "2016-2022 saidenka", +] +[permissions] +files = "To load brush icons from disk" \ No newline at end of file diff --git a/source/hotkeys.py b/source/hotkeys.py new file mode 100644 index 0000000..5fcfd33 --- /dev/null +++ b/source/hotkeys.py @@ -0,0 +1,183 @@ +import bpy +import json +from . import __package__ as base_package + +def get_addon_prefs_class(): + class_name = bpy.context.preferences.addons[base_package].preferences.__class__.__name__ + py_class = bpy.types.AddonPreferences.bl_rna_get_subclass_py(class_name) + return py_class + + + +def register_hotkey( + bl_idname, hotkey_kwargs, *, key_cat='Window', op_kwargs={} +): + """This function inserts a 'hash' into the created KeyMapItems' properties, + so they can be compared to each other, and duplicates can be avoided.""" + + wm = bpy.context.window_manager + + space_type = wm.keyconfigs.default.keymaps[key_cat].space_type + + addon_keyconfig = wm.keyconfigs.addon + if not addon_keyconfig: + # This happens when running Blender in background mode. + return + + # We limit the hash to a few digits, otherwise it errors when trying to store it. + kmi_hash = ( + hash(json.dumps([bl_idname, hotkey_kwargs, key_cat, space_type, op_kwargs])) + % 1000000 + ) + + storage_class = get_addon_prefs_class() + + # If it already exists, don't create it again. + for ( + existing_kmi_hash, + existing_kmi_tup, + ) in storage_class.keymap_items.items(): + existing_addon_kc, existing_addon_km, existing_kmi = existing_kmi_tup + if kmi_hash == existing_kmi_hash: + # The hash we just calculated matches one that is in storage. + user_kc = wm.keyconfigs.user + user_km = user_kc.keymaps.get(existing_addon_km.name) + # NOTE: It's possible on Reload Scripts that some KeyMapItems remain in storage, + # but are unregistered by Blender for no reason. + # I noticed this particularly in the Weight Paint keymap. + # So it's not enough to check if a KMI with a hash is in storage, we also need to check if a corresponding user KMI exists. + user_kmi = find_kmi_in_km_by_hash( + user_km, kmi_hash + ) + if user_kmi: + # print("Hotkey already exists, skipping: ", existing_kmi.name, existing_kmi.to_string(), kmi_hash) + return + + # print("Registering hotkey: ", bl_idname, hotkey_kwargs, key_cat) + + addon_keymaps = addon_keyconfig.keymaps + addon_km = addon_keymaps.get(key_cat) + if not addon_km: + addon_km = addon_keymaps.new(name=key_cat, space_type=space_type) + + addon_kmi = addon_km.keymap_items.new(bl_idname, **hotkey_kwargs) + for key in op_kwargs: + value = op_kwargs[key] + setattr(addon_kmi.properties, key, value) + + addon_kmi.properties['hash'] = kmi_hash + + storage_class.keymap_items[kmi_hash] = ( + addon_keyconfig, + addon_km, + addon_kmi, + ) + + +def draw_hotkey_list(layout, context): + hotkey_class = get_addon_prefs_class() + user_kc = context.window_manager.keyconfigs.user + + keymap_data = list(hotkey_class.keymap_items.items()) + keymap_data = sorted(keymap_data, key=lambda tup: tup[1][2].name) + + prev_kmi = None + for kmi_hash, kmi_tup in keymap_data: + addon_kc, addon_km, addon_kmi = kmi_tup + + user_km = user_kc.keymaps.get(addon_km.name) + if not user_km: + # This really shouldn't happen. + continue + user_kmi = find_kmi_in_km_by_hash(user_km, kmi_hash) + + col = layout.column() + col.context_pointer_set("keymap", user_km) + if user_kmi and prev_kmi and prev_kmi.name != user_kmi.name: + col.separator() + user_row = col.row() + + if False: + # Debug code: Draw add-on and user KeyMapItems side-by-side. + split = user_row.split(factor=0.5) + addon_row = split.row() + user_row = split.row() + hotkey_class.draw_kmi(addon_km, addon_kmi, addon_row) + if not user_kmi: + # This should only happen for one frame during Reload Scripts. + print( + base_package + "Can't find this hotkey to draw: ", + addon_kmi.name, + addon_kmi.to_string(), + kmi_hash, + ) + continue + + draw_kmi(user_km, user_kmi, user_row) + prev_kmi = user_kmi + +def draw_kmi(km, kmi, layout): + """A simplified version of draw_kmi from rna_keymap_ui.py.""" + + map_type = kmi.map_type + + col = layout.column() + + split = col.split(factor=0.7) + + # header bar + row = split.row(align=True) + row.prop(kmi, "active", text="", emboss=False) + km_name = km.name + if km_name == 'Armature': + km_name = 'Armature Edit' + row.label(text=f'{km_name} - {kmi.name}') + + row = split.row(align=True) + sub = row.row(align=True) + sub.enabled = kmi.active + sub.prop(kmi, "type", text="", full_event=True) + + if kmi.is_user_modified: + row.operator( + "preferences.keyitem_restore", text="", icon='LOOP_BACK' + ).item_id = kmi.id + +def print_kmi(kmi): + idname = kmi.idname + keys = kmi.to_string() + props = str(list(kmi.properties.items())) + print(idname, props, keys) + +def find_kmi_in_km_by_hash(keymap, kmi_hash): + """There's no solid way to match modified user keymap items to their + add-on equivalent, which is necessary to draw them in the UI reliably. + + To remedy this, we store a hash in the KeyMapItem's properties. + + This function lets us find a KeyMapItem with a stored hash in a KeyMap. + Eg., we can pass a User KeyMap and an Addon KeyMapItem's hash, to find the + corresponding user keymap, even if it was modified. + + The hash value is unfortunately exposed to the users, so we just hope they don't touch that. + """ + + for kmi in keymap.keymap_items: + if not kmi.properties: + continue + if 'hash' not in kmi.properties: + continue + + if kmi.properties['hash'] == kmi_hash: + return kmi + +def unregister(): + cls = get_addon_prefs_class() + for ( + kmi_hash, + kmi_tup, + ) in cls.keymap_items.items(): + kc, km, kmi = kmi_tup + km.keymap_items.remove(kmi) + + cls.keymap_items = {} diff --git a/source/icons/brush.sculpt.blob.dat b/source/icons/brush.sculpt.blob.dat new file mode 100644 index 0000000..890a73e Binary files /dev/null and b/source/icons/brush.sculpt.blob.dat differ diff --git a/source/icons/brush.sculpt.boundary.dat b/source/icons/brush.sculpt.boundary.dat new file mode 100644 index 0000000..1b71d24 Binary files /dev/null and b/source/icons/brush.sculpt.boundary.dat differ diff --git a/source/icons/brush.sculpt.clay.dat b/source/icons/brush.sculpt.clay.dat new file mode 100644 index 0000000..8e33384 Binary files /dev/null and b/source/icons/brush.sculpt.clay.dat differ diff --git a/source/icons/brush.sculpt.clay_strips.dat b/source/icons/brush.sculpt.clay_strips.dat new file mode 100644 index 0000000..8d1382d Binary files /dev/null and b/source/icons/brush.sculpt.clay_strips.dat differ diff --git a/source/icons/brush.sculpt.clay_thumb.dat b/source/icons/brush.sculpt.clay_thumb.dat new file mode 100644 index 0000000..b063fff Binary files /dev/null and b/source/icons/brush.sculpt.clay_thumb.dat differ diff --git a/source/icons/brush.sculpt.cloth.dat b/source/icons/brush.sculpt.cloth.dat new file mode 100644 index 0000000..15ad0c7 Binary files /dev/null and b/source/icons/brush.sculpt.cloth.dat differ diff --git a/source/icons/brush.sculpt.crease.dat b/source/icons/brush.sculpt.crease.dat new file mode 100644 index 0000000..686d04c Binary files /dev/null and b/source/icons/brush.sculpt.crease.dat differ diff --git a/source/icons/brush.sculpt.displacement_eraser.dat b/source/icons/brush.sculpt.displacement_eraser.dat new file mode 100644 index 0000000..5c479fd Binary files /dev/null and b/source/icons/brush.sculpt.displacement_eraser.dat differ diff --git a/source/icons/brush.sculpt.displacement_smear.dat b/source/icons/brush.sculpt.displacement_smear.dat new file mode 100644 index 0000000..ed84702 Binary files /dev/null and b/source/icons/brush.sculpt.displacement_smear.dat differ diff --git a/source/icons/brush.sculpt.draw.dat b/source/icons/brush.sculpt.draw.dat new file mode 100644 index 0000000..014ce10 Binary files /dev/null and b/source/icons/brush.sculpt.draw.dat differ diff --git a/source/icons/brush.sculpt.draw_face_sets.dat b/source/icons/brush.sculpt.draw_face_sets.dat new file mode 100644 index 0000000..ade40de Binary files /dev/null and b/source/icons/brush.sculpt.draw_face_sets.dat differ diff --git a/source/icons/brush.sculpt.draw_sharp.dat b/source/icons/brush.sculpt.draw_sharp.dat new file mode 100644 index 0000000..cf60632 Binary files /dev/null and b/source/icons/brush.sculpt.draw_sharp.dat differ diff --git a/source/icons/brush.sculpt.elastic_deform.dat b/source/icons/brush.sculpt.elastic_deform.dat new file mode 100644 index 0000000..db57ef2 Binary files /dev/null and b/source/icons/brush.sculpt.elastic_deform.dat differ diff --git a/source/icons/brush.sculpt.fill.dat b/source/icons/brush.sculpt.fill.dat new file mode 100644 index 0000000..08fe071 Binary files /dev/null and b/source/icons/brush.sculpt.fill.dat differ diff --git a/source/icons/brush.sculpt.flatten.dat b/source/icons/brush.sculpt.flatten.dat new file mode 100644 index 0000000..a4439d7 Binary files /dev/null and b/source/icons/brush.sculpt.flatten.dat differ diff --git a/source/icons/brush.sculpt.grab.dat b/source/icons/brush.sculpt.grab.dat new file mode 100644 index 0000000..819c926 Binary files /dev/null and b/source/icons/brush.sculpt.grab.dat differ diff --git a/source/icons/brush.sculpt.inflate.dat b/source/icons/brush.sculpt.inflate.dat new file mode 100644 index 0000000..7e85ee2 Binary files /dev/null and b/source/icons/brush.sculpt.inflate.dat differ diff --git a/source/icons/brush.sculpt.layer.dat b/source/icons/brush.sculpt.layer.dat new file mode 100644 index 0000000..3373621 Binary files /dev/null and b/source/icons/brush.sculpt.layer.dat differ diff --git a/source/icons/brush.sculpt.mask.dat b/source/icons/brush.sculpt.mask.dat new file mode 100644 index 0000000..a285c4c Binary files /dev/null and b/source/icons/brush.sculpt.mask.dat differ diff --git a/source/icons/brush.sculpt.multiplane_scrape.dat b/source/icons/brush.sculpt.multiplane_scrape.dat new file mode 100644 index 0000000..ea64b2d Binary files /dev/null and b/source/icons/brush.sculpt.multiplane_scrape.dat differ diff --git a/source/icons/brush.sculpt.nudge.dat b/source/icons/brush.sculpt.nudge.dat new file mode 100644 index 0000000..f5a93ed Binary files /dev/null and b/source/icons/brush.sculpt.nudge.dat differ diff --git a/source/icons/brush.sculpt.paint.dat b/source/icons/brush.sculpt.paint.dat new file mode 100644 index 0000000..e499d33 Binary files /dev/null and b/source/icons/brush.sculpt.paint.dat differ diff --git a/source/icons/brush.sculpt.pinch.dat b/source/icons/brush.sculpt.pinch.dat new file mode 100644 index 0000000..7dbbdef Binary files /dev/null and b/source/icons/brush.sculpt.pinch.dat differ diff --git a/source/icons/brush.sculpt.pose.dat b/source/icons/brush.sculpt.pose.dat new file mode 100644 index 0000000..6bd7764 Binary files /dev/null and b/source/icons/brush.sculpt.pose.dat differ diff --git a/source/icons/brush.sculpt.rotate.dat b/source/icons/brush.sculpt.rotate.dat new file mode 100644 index 0000000..b7b8f08 Binary files /dev/null and b/source/icons/brush.sculpt.rotate.dat differ diff --git a/source/icons/brush.sculpt.scrape.dat b/source/icons/brush.sculpt.scrape.dat new file mode 100644 index 0000000..afb5a46 Binary files /dev/null and b/source/icons/brush.sculpt.scrape.dat differ diff --git a/source/icons/brush.sculpt.simplify.dat b/source/icons/brush.sculpt.simplify.dat new file mode 100644 index 0000000..f7de2f9 Binary files /dev/null and b/source/icons/brush.sculpt.simplify.dat differ diff --git a/source/icons/brush.sculpt.smear.dat b/source/icons/brush.sculpt.smear.dat new file mode 100644 index 0000000..a9867ce Binary files /dev/null and b/source/icons/brush.sculpt.smear.dat differ diff --git a/source/icons/brush.sculpt.smooth.dat b/source/icons/brush.sculpt.smooth.dat new file mode 100644 index 0000000..c42049c Binary files /dev/null and b/source/icons/brush.sculpt.smooth.dat differ diff --git a/source/icons/brush.sculpt.snake_hook.dat b/source/icons/brush.sculpt.snake_hook.dat new file mode 100644 index 0000000..ce47b71 Binary files /dev/null and b/source/icons/brush.sculpt.snake_hook.dat differ diff --git a/source/icons/brush.sculpt.thumb.dat b/source/icons/brush.sculpt.thumb.dat new file mode 100644 index 0000000..f54a141 Binary files /dev/null and b/source/icons/brush.sculpt.thumb.dat differ diff --git a/source/icons/brush.sculpt.topology.dat b/source/icons/brush.sculpt.topology.dat new file mode 100644 index 0000000..ec3699a Binary files /dev/null and b/source/icons/brush.sculpt.topology.dat differ diff --git a/source/pie_align_menu.py b/source/pie_align_menu.py index f289bc8..5b9d5d1 100644 --- a/source/pie_align_menu.py +++ b/source/pie_align_menu.py @@ -2,30 +2,19 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Alt X'", - "description": "V/E/F Align tools", - "author": "pitiwazou, meta-androcto", - "version": (0, 1, 2), - "blender": (2, 80, 0), - "location": "Mesh Edit Mode", - "warning": "", - "doc_url": "", - "category": "Edit Align Pie" -} - import bpy from bpy.types import ( Menu, Operator, ) from bpy.props import EnumProperty +from .hotkeys import register_hotkey -# Pie Align - Alt + X +# Align Pie - Alt + X class PIE_MT_Align(Menu): bl_idname = "PIE_MT_align" - bl_label = "Pie Align" + bl_label = "Align Pie" def draw(self, context): layout = self.layout @@ -99,7 +88,7 @@ class PIE_OT_AlignSelectedXYZ(Operator): ('Z', "Z", "Z Axis"), ), description="Choose an axis for alignment", - default='X' + default='X', ) @classmethod @@ -129,6 +118,7 @@ class PIE_OT_AlignSelectedXYZ(Operator): # Align To 0 # # ################# # + class PIE_OT_AlignToXYZ0(Operator): bl_idname = "align.2xyz" bl_label = "Align To X, Y or Z = 0" @@ -143,7 +133,7 @@ class PIE_OT_AlignToXYZ0(Operator): ('2', "Z", "Z Axis"), ), description="Choose an axis for alignment", - default='0' + default='0', ) @classmethod @@ -177,7 +167,7 @@ class PIE_OT_AlignXYZAll(Operator): ('2', "Z", "Z Axis"), ), description="Choose an axis for alignment", - default='0' + default='0', ) side: EnumProperty( name="Side", @@ -186,7 +176,7 @@ class PIE_OT_AlignXYZAll(Operator): ('NEGATIVE', "Back", "Align acriss the negative chosen axis"), ], description="Choose a side for alignment", - default='POSITIVE' + default='POSITIVE', ) @classmethod @@ -223,40 +213,18 @@ class PIE_OT_AlignXYZAll(Operator): return {'FINISHED'} -classes = ( +registry = ( PIE_MT_Align, PIE_OT_AlignSelectedXYZ, PIE_OT_AlignToXYZ0, PIE_OT_AlignXYZAll, ) -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='Mesh') - kmi = km.keymap_items.new('wm.call_menu_pie', 'X', 'PRESS', alt=True) - kmi.properties.name = "PIE_MT_align" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_align'}, + hotkey_kwargs={'type': "X", 'value': "PRESS", 'alt': True}, + key_cat="Mesh", + ) diff --git a/source/pie_animation_menu.py b/source/pie_animation_menu.py index 5b9ae6b..4af148e 100644 --- a/source/pie_animation_menu.py +++ b/source/pie_animation_menu.py @@ -2,30 +2,16 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Shift Spacebar'", - "description": "Pie menu for Timeline controls", - "author": "pitiwazou, meta-androcto", - "version": (0, 1, 1), - "blender": (2, 80, 0), - "location": "3D View", - "warning": "", - "doc_url": "", - "category": "Animation Pie" -} - import bpy from bpy.types import ( Menu, Operator, ) - -# Pie Animation - +from .hotkeys import register_hotkey class PIE_MT_PieAnimation(Menu): bl_idname = "PIE_MT_animation" - bl_label = "Pie Animation" + bl_label = "Animation Pie" def draw(self, context): layout = self.layout @@ -35,23 +21,28 @@ class PIE_MT_PieAnimation(Menu): # 6 - RIGHT pie.operator("screen.frame_jump", text="Jump FF", icon='FF').end = True # 2 - BOTTOM - pie.operator("screen.animation_play", text="Reverse", icon='PLAY_REVERSE').reverse = True + pie.operator( + "screen.animation_play", text="Reverse", icon='PLAY_REVERSE' + ).reverse = True # 8 - TOP if not context.screen.is_animation_playing: # Play / Pause pie.operator("screen.animation_play", text="Play", icon='PLAY') else: pie.operator("screen.animation_play", text="Stop", icon='PAUSE') # 7 - TOP - LEFT - pie.operator("screen.keyframe_jump", text="Previous FR", icon='PREV_KEYFRAME').next = False + pie.operator( + "screen.keyframe_jump", text="Previous FR", icon='PREV_KEYFRAME' + ).next = False # 9 - TOP - RIGHT - pie.operator("screen.keyframe_jump", text="Next FR", icon='NEXT_KEYFRAME').next = True + pie.operator( + "screen.keyframe_jump", text="Next FR", icon='NEXT_KEYFRAME' + ).next = True # 1 - BOTTOM - LEFT pie.operator("insert.autokeyframe", text="Auto Keyframe", icon='REC') # 3 - BOTTOM - RIGHT pie.menu("VIEW3D_MT_object_animation", text="Keyframe Menu", icon="KEYINGSET") -# Insert Auto Keyframe class PIE_OT_InsertAutoKeyframe(Operator): bl_idname = "insert.autokeyframe" bl_label = "Insert Auto Keyframe" @@ -70,38 +61,13 @@ class PIE_OT_InsertAutoKeyframe(Operator): return {'FINISHED'} -classes = ( - PIE_MT_PieAnimation, - PIE_OT_InsertAutoKeyframe -) - -addon_keymaps = [] +registry = (PIE_MT_PieAnimation, PIE_OT_InsertAutoKeyframe) def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Animation - km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal') - kmi = km.keymap_items.new('wm.call_menu_pie', 'SPACE', 'PRESS', shift=True) - kmi.properties.name = "PIE_MT_animation" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_animation'}, + hotkey_kwargs={'type': "SPACE", 'value': "PRESS", 'shift': True}, + key_cat="Object Mode", + ) diff --git a/source/pie_apply_transform_menu.py b/source/pie_apply_transform_menu.py index 14e155f..5164029 100644 --- a/source/pie_apply_transform_menu.py +++ b/source/pie_apply_transform_menu.py @@ -2,30 +2,17 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Ctrl A'", - "description": "Apply Transform Menu", - "author": "pitiwazou, meta-androcto", - "version": (0, 1, 1), - "blender": (2, 80, 0), - "location": "3D View", - "warning": "", - "doc_url": "", - "category": "Apply Transform Pie" -} - import bpy from bpy.types import ( Menu, Operator, ) -from bpy.props import EnumProperty +from .hotkeys import register_hotkey -# Pie Apply Transforms - Ctrl + A class PIE_MT_PieApplyTransforms(Menu): bl_idname = "PIE_MT_applytransforms" - bl_label = "Pie Apply Transforms" + bl_label = "Apply Transforms Pie" def draw(self, context): layout = self.layout @@ -53,10 +40,9 @@ class PIE_MT_PieApplyTransforms(Menu): pie.menu("PIE_MT_clear_menu", text="Clear Transform Menu") -# Clear Menu class PIE_MT_ClearMenu(Menu): bl_idname = "PIE_MT_clear_menu" - bl_label = "Clear Menu" + bl_label = "Clear Transforms" def draw(self, context): layout = self.layout @@ -67,10 +53,9 @@ class PIE_MT_ClearMenu(Menu): layout.operator("object.origin_clear", text="Clear Origin", icon='NONE') -# Clear all class PIE_OT_ClearAll(Operator): bl_idname = "clear.all" - bl_label = "Clear All" + bl_label = "Clear All Transforms" bl_description = "Clear All Transforms" bl_options = {'REGISTER', 'UNDO'} @@ -81,39 +66,17 @@ class PIE_OT_ClearAll(Operator): return {'FINISHED'} -classes = ( +registry = ( PIE_MT_PieApplyTransforms, PIE_MT_ClearMenu, PIE_OT_ClearAll, ) -addon_keymaps = [] - def register(): - for cls in classes: - bpy.utils.register_class(cls) - wm = bpy.context.window_manager - - if wm.keyconfigs.addon: - # Apply Transform - km = wm.keyconfigs.addon.keymaps.new(name='Object Mode') - kmi = km.keymap_items.new('wm.call_menu_pie', 'A', 'PRESS', ctrl=True) - kmi.properties.name = "PIE_MT_applytransforms" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_applytransforms'}, + hotkey_kwargs={'type': "A", 'value': "PRESS", 'ctrl': True}, + key_cat="Object Mode", + ) diff --git a/source/pie_defaults_menu.py b/source/pie_defaults_menu.py index f103e0b..a93bba8 100644 --- a/source/pie_defaults_menu.py +++ b/source/pie_defaults_menu.py @@ -2,43 +2,41 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Ctrl U'", - "description": "Save/Open & File Menus", - "blender": (2, 80, 0), - "location": "All Editors", - "warning": "", - "doc_url": "", - "category": "Interface" -} - import bpy -from bpy.types import ( - Menu, - Operator, -) -import os +from bpy.types import Menu +from .hotkeys import register_hotkey -# Pie Save/Open +# Save/Open Pie class PIE_MT_Load_Defaults(Menu): bl_idname = "PIE_MT_loaddefaults" - bl_label = "Save Defaults" + bl_label = "Defaults Pie" def draw(self, context): layout = self.layout prefs = context.preferences pie = layout.menu_pie() # 4 - LEFT - pie.operator("wm.read_factory_settings", text="Load Factory Settings", icon='IMPORT') + pie.operator( + "wm.read_factory_settings", text="Load Factory Settings", icon='IMPORT' + ) # 6 - RIGHT - pie.operator("wm.read_factory_userpref", text="Load Factory Preferences", icon='RECOVER_LAST') + pie.operator( + "wm.read_factory_userpref", + text="Load Factory Preferences", + icon='RECOVER_LAST', + ) # 2 - BOTTOM pie.operator("wm.read_userpref", text="Revert to Saved Prefs", icon='NONE') # 8 - TOP pie.operator("wm.save_homefile", text="Save StartUp File", icon='FILE_NEW') # 7 - TOP - LEFT - pie.prop(prefs, "use_preferences_save", text="Auto-Save Preferences", icon='LINK_BLEND') + pie.prop( + prefs, + "use_preferences_save", + text="Auto-Save Preferences", + icon='LINK_BLEND', + ) # 9 - TOP - RIGHT pie.operator("wm.save_userpref", text="Save User Preferences", icon='NONE') # 1 - BOTTOM - LEFT @@ -47,37 +45,13 @@ class PIE_MT_Load_Defaults(Menu): pie.separator() -classes = ( - PIE_MT_Load_Defaults, -) - -addon_keymaps = [] +registry = (PIE_MT_Load_Defaults,) def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Save/Open/... - km = wm.keyconfigs.addon.keymaps.new(name='Window') - kmi = km.keymap_items.new('wm.call_menu_pie', 'U', 'PRESS', ctrl=True) - kmi.properties.name = "PIE_MT_loaddefaults" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_loaddefaults'}, + hotkey_kwargs={'type': "U", 'value': "PRESS", 'ctrl': True}, + key_cat="Window", + ) diff --git a/source/pie_delete_menu.py b/source/pie_delete_menu.py index 7173deb..5a96e57 100644 --- a/source/pie_delete_menu.py +++ b/source/pie_delete_menu.py @@ -2,86 +2,59 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'X'", - "description": "Edit mode V/E/F Delete Modes", - "author": "pitiwazou, meta-androcto", - "version": (0, 1, 0), - "blender": (2, 80, 0), - "location": "Mesh Edit Mode", - "warning": "", - "doc_url": "", - "category": "Edit Delete Pie" -} - import bpy from bpy.types import Menu +from .hotkeys import register_hotkey -# Pie Delete - X class PIE_MT_PieDelete(Menu): bl_idname = "PIE_MT_delete" - bl_label = "Pie Delete" + bl_label = "Delete Pie" def draw(self, context): layout = self.layout pie = layout.menu_pie() # 4 - LEFT box = pie.split().column() - box.operator("mesh.dissolve_limited", text="Limited Dissolve", icon='STICKY_UVS_LOC') + box.operator( + "mesh.dissolve_limited", text="Limited Dissolve", icon='STICKY_UVS_LOC' + ) box.operator("mesh.delete_edgeloop", text="Delete Edge Loops", icon='NONE') box.operator("mesh.edge_collapse", text="Edge Collapse", icon='UV_EDGESEL') # 6 - RIGHT box = pie.split().column() box.operator("mesh.remove_doubles", text="Merge By Distance", icon='NONE') - box.operator("mesh.delete", text="Only Edge & Faces", icon='NONE').type = 'EDGE_FACE' - box.operator("mesh.delete", text="Only Faces", icon='UV_FACESEL').type = 'ONLY_FACE' + box.operator("mesh.delete", text="Only Edge & Faces", icon='NONE').type = ( + 'EDGE_FACE' + ) + box.operator("mesh.delete", text="Only Faces", icon='UV_FACESEL').type = ( + 'ONLY_FACE' + ) # 2 - BOTTOM pie.operator("mesh.dissolve_edges", text="Dissolve Edges", icon='SNAP_EDGE') # 8 - TOP pie.operator("mesh.delete", text="Delete Edges", icon='EDGESEL').type = 'EDGE' # 7 - TOP - LEFT - pie.operator("mesh.delete", text="Delete Vertices", icon='VERTEXSEL').type = 'VERT' + pie.operator("mesh.delete", text="Delete Vertices", icon='VERTEXSEL').type = ( + 'VERT' + ) # 9 - TOP - RIGHT pie.operator("mesh.delete", text="Delete Faces", icon='FACESEL').type = 'FACE' # 1 - BOTTOM - LEFT - pie.operator("mesh.dissolve_verts", text="Dissolve Vertices", icon='SNAP_VERTEX') + pie.operator( + "mesh.dissolve_verts", text="Dissolve Vertices", icon='SNAP_VERTEX' + ) # 3 - BOTTOM - RIGHT pie.operator("mesh.dissolve_faces", text="Dissolve Faces", icon='SNAP_FACE') -classes = ( - PIE_MT_PieDelete, -) - - -addon_keymaps = [] +registry = (PIE_MT_PieDelete,) def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Delete - km = wm.keyconfigs.addon.keymaps.new(name='Mesh') - kmi = km.keymap_items.new('wm.call_menu_pie', 'X', 'PRESS') - kmi.properties.name = "PIE_MT_delete" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_delete'}, + hotkey_kwargs={'type': "X", 'value': "PRESS"}, + key_cat="Mesh", + ) diff --git a/source/pie_editor_switch_menu.py b/source/pie_editor_switch_menu.py index 0ba1d1b..936ea1b 100644 --- a/source/pie_editor_switch_menu.py +++ b/source/pie_editor_switch_menu.py @@ -2,55 +2,57 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Ctrl Alt S' ", - "description": "Switch Editor Type Menu", - "author": "saidenka, meta-androcto", - "version": (0, 1, 2), - "blender": (3, 40, 1), - "location": "All Editors", - "warning": "", - "doc_url": "", - "category": "Editor Switch Pie" -} - import bpy from bpy.types import ( Menu, Operator, ) -from bpy.props import ( - StringProperty, -) +from bpy.props import StringProperty +from .hotkeys import register_hotkey # Pie Menu class PIE_MT_AreaPieEditor(Menu): bl_idname = "PIE_MT_editor" - bl_label = "Editor Switch" + bl_label = "Editor Switch Pie" def draw(self, context): layout = self.layout pie = layout.menu_pie() # 4 - LEFT - pie.operator(PIE_OT_SetAreaType.bl_idname, - text="Video Sequence Editor", icon="SEQUENCE").types = "SEQUENCE_EDITOR" + pie.operator( + PIE_OT_SetAreaType.bl_idname, text="Video Sequence Editor", icon="SEQUENCE" + ).types = "SEQUENCE_EDITOR" # 6 - RIGHT pie.menu(PIE_MT_AreaTypePieNode.bl_idname, text="Node Editors", icon="NODETREE") # 2 - BOTTOM - pie.menu(PIE_MT_AreaTypePieOther.bl_idname, text="Script/Data Editors", icon="PREFERENCES") + pie.menu( + PIE_MT_AreaTypePieOther.bl_idname, + text="Script/Data Editors", + icon="PREFERENCES", + ) # 8 - TOP - pie.operator(PIE_OT_SetAreaType.bl_idname, text="3D View", icon="VIEW3D").types = "VIEW_3D" + pie.operator( + PIE_OT_SetAreaType.bl_idname, text="3D View", icon="VIEW3D" + ).types = "VIEW_3D" # 7 - TOP - LEFT - pie.operator(PIE_OT_SetAreaType.bl_idname, text="Image Editor", icon="IMAGE").types = "IMAGE_EDITOR" + pie.operator( + PIE_OT_SetAreaType.bl_idname, text="Image Editor", icon="IMAGE" + ).types = "IMAGE_EDITOR" # 9 - TOP - RIGHT - pie.operator(PIE_OT_SetAreaType.bl_idname, text="UV Editor", icon="UV").types = "UV" + pie.operator( + PIE_OT_SetAreaType.bl_idname, text="UV Editor", icon="UV" + ).types = "UV" # 1 - BOTTOM - LEFT - pie.operator(PIE_OT_SetAreaType.bl_idname, - text="Movie Clip Editor", icon="TRACKER").types = "CLIP_EDITOR" + pie.operator( + PIE_OT_SetAreaType.bl_idname, text="Movie Clip Editor", icon="TRACKER" + ).types = "CLIP_EDITOR" # 3 - BOTTOM - RIGHT - pie.menu(PIE_MT_AreaTypePieAnim.bl_idname, text="Animation Editors", icon="ACTION") + pie.menu( + PIE_MT_AreaTypePieAnim.bl_idname, text="Animation Editors", icon="ACTION" + ) + # Sub Menu Script/Data Editors @@ -61,19 +63,33 @@ class PIE_MT_AreaTypePieOther(Menu): bl_description = "Is pie menu change editor type (other)" def draw(self, context): - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Outliner", icon="OUTLINER").types = "OUTLINER" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Properties", icon="PROPERTIES").types = "PROPERTIES" self.layout.operator( - PIE_OT_SetAreaType.bl_idname, - text="File Browser", - icon="FILEBROWSER").types = "FILES" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Preferences", - icon="PREFERENCES").types = "PREFERENCES" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Text Editor", icon="TEXT").types = "TEXT_EDITOR" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Python Console", icon="CONSOLE").types = "CONSOLE" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Info", icon="INFO").types = "INFO" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Spreadsheet", icon="SPREADSHEET").types = "SPREADSHEET" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Asset Browser", icon="ASSET_MANAGER").types = "ASSETS" + PIE_OT_SetAreaType.bl_idname, text="Outliner", icon="OUTLINER" + ).types = "OUTLINER" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Properties", icon="PROPERTIES" + ).types = "PROPERTIES" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="File Browser", icon="FILEBROWSER" + ).types = "FILES" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Preferences", icon="PREFERENCES" + ).types = "PREFERENCES" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Text Editor", icon="TEXT" + ).types = "TEXT_EDITOR" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Python Console", icon="CONSOLE" + ).types = "CONSOLE" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Info", icon="INFO" + ).types = "INFO" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Spreadsheet", icon="SPREADSHEET" + ).types = "SPREADSHEET" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Asset Browser", icon="ASSET_MANAGER" + ).types = "ASSETS" # Sub Menu Node editors. @@ -83,13 +99,18 @@ class PIE_MT_AreaTypePieNode(Menu): bl_description = "Menu to change node editor types" def draw(self, context): - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Shader", icon="NODE_MATERIAL").types = "ShaderNodeTree" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Compositor", - icon="NODE_COMPOSITING").types = "CompositorNodeTree" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Texture", - icon="NODE_TEXTURE").types = "TextureNodeTree" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Geometry", - icon="NODETREE").types = "GeometryNodeTree" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Shader", icon="NODE_MATERIAL" + ).types = "ShaderNodeTree" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Compositor", icon="NODE_COMPOSITING" + ).types = "CompositorNodeTree" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Texture", icon="NODE_TEXTURE" + ).types = "TextureNodeTree" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Geometry", icon="NODETREE" + ).types = "GeometryNodeTree" # Sub Menu animation Editors. @@ -99,11 +120,19 @@ class PIE_MT_AreaTypePieAnim(Menu): bl_description = "Menu for changing editor type (animation related)" def draw(self, context): - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="DopeSheet", icon="ACTION").types = "DOPESHEET" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="DopeSheet", icon="ACTION" + ).types = "DOPESHEET" self.layout.operator(PIE_OT_Timeline.bl_idname, text="Timeline", icon="TIME") - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Graph Editor", icon="GRAPH").types = "FCURVES" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="Drivers", icon="DRIVER").types = "DRIVERS" - self.layout.operator(PIE_OT_SetAreaType.bl_idname, text="NLA Editor", icon="NLA").types = "NLA_EDITOR" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Graph Editor", icon="GRAPH" + ).types = "FCURVES" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="Drivers", icon="DRIVER" + ).types = "DRIVERS" + self.layout.operator( + PIE_OT_SetAreaType.bl_idname, text="NLA Editor", icon="NLA" + ).types = "NLA_EDITOR" # Operators. @@ -131,42 +160,20 @@ class PIE_OT_Timeline(Operator): return {'FINISHED'} -classes = ( +registry = ( PIE_MT_AreaPieEditor, PIE_MT_AreaTypePieOther, PIE_OT_SetAreaType, PIE_MT_AreaTypePieAnim, PIE_OT_Timeline, - PIE_MT_AreaTypePieNode + PIE_MT_AreaTypePieNode, ) -addon_keymaps = [] - def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Snapping - km = wm.keyconfigs.addon.keymaps.new(name='Window') - kmi = km.keymap_items.new('wm.call_menu_pie', 'S', 'PRESS', ctrl=True, alt=True) - kmi.properties.name = "PIE_MT_editor" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_editor'}, + hotkey_kwargs={'type': "S", 'value': "PRESS", 'ctrl': True, 'alt': True}, + key_cat="Window", + ) diff --git a/source/pie_manipulator_menu.py b/source/pie_manipulator_menu.py index 4dc048a..2949929 100644 --- a/source/pie_manipulator_menu.py +++ b/source/pie_manipulator_menu.py @@ -2,17 +2,6 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Alt Spacebar'", - "description": "Manipulator Menu", - "author": "pitiwazou, meta-androcto", - "version": (0, 1, 1), - "blender": (2, 80, 0), - "location": "3D View", - "warning": "", - "doc_url": "", - "category": "Manipulator Pie" -} import bpy from bpy.types import ( @@ -23,6 +12,7 @@ from bpy.props import ( BoolProperty, EnumProperty, ) +from .hotkeys import register_hotkey class PIE_OT_WManupulators(Operator): @@ -67,10 +57,9 @@ class PIE_OT_WManupulators(Operator): return self.execute(context) -# Pie Manipulators - Ctrl + Space class PIE_MT_Manipulator(Menu): bl_idname = "PIE_MT_manipulator" - bl_label = "Pie Manipulator" + bl_label = "Manipulator Pie" def draw(self, context): layout = self.layout @@ -81,43 +70,21 @@ class PIE_MT_Manipulator(Menu): pie.operator("w.manipulators", text="Scale", icon='NONE').type = 'SCALE' # 2 - BOTTOM props = pie.operator("wm.context_toggle", text="Show/Hide Toggle", icon='NONE') - props.data_path = "space_data.show_gizmo_context" + props.data_path = "space_data.show_gizmo" # 8 - TOP pie.operator("w.manipulators", text="Translate", icon='NONE').type = 'TRANSLATE' -classes = ( +registry = ( PIE_OT_WManupulators, PIE_MT_Manipulator, ) -addon_keymaps = [] - def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Manipulators - km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D') - kmi = km.keymap_items.new('wm.call_menu_pie', 'SPACE', 'PRESS', alt=True) - kmi.properties.name = "PIE_MT_manipulator" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_manipulator'}, + hotkey_kwargs={'type': "SPACE", 'value': "PRESS", 'alt': True}, + key_cat="3D View", + ) diff --git a/source/pie_modes_menu.py b/source/pie_modes_menu.py index 2f39822..f2f68c1 100644 --- a/source/pie_modes_menu.py +++ b/source/pie_modes_menu.py @@ -2,23 +2,10 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Ctrl Tab'", - "description": "Switch between 3d view object/edit modes", - "author": "pitiwazou, meta-androcto, italic", - "version": (0, 1, 2), - "blender": (2, 80, 0), - "location": "3D View", - "warning": "", - "doc_url": "", - "category": "Mode Switch Pie" -} import bpy -from bpy.types import ( - Menu, - Operator -) +from bpy.types import Menu, Operator +from .hotkeys import register_hotkey class PIE_OT_ClassObject(Operator): @@ -105,11 +92,14 @@ class PIE_OT_SetObjectModePie(Operator): mode: bpy.props.StringProperty(name="Interactive mode", default="OBJECT") def execute(self, context): - if (context.active_object): + if context.active_object: try: bpy.ops.object.mode_set(mode=self.mode) except TypeError: - msg = context.active_object.name + " It is not possible to enter into the interactive mode" + msg = ( + context.active_object.name + + " It is not possible to enter into the interactive mode" + ) self.report(type={"WARNING"}, message=msg) else: self.report(type={"WARNING"}, message="There is no active object") @@ -183,6 +173,7 @@ class PIE_OT_VertsEdgesFaces(Operator): # Menus class PIE_MT_ObjectEditotherModes(Menu): """Edit/Object Others modes""" + bl_idname = "MENU_MT_objecteditmodeothermodes" bl_label = "Edit Selection Modes" @@ -194,13 +185,16 @@ class PIE_MT_ObjectEditotherModes(Menu): box.operator("class.vertex", text="Vertex", icon='VERTEXSEL') box.operator("class.edge", text="Edge", icon='EDGESEL') box.operator("class.face", text="Face", icon='FACESEL') - box.operator("verts.edgesfaces", text="Vertex/Edges/Faces", icon='OBJECT_DATAMODE') + box.operator( + "verts.edgesfaces", text="Vertex/Edges/Faces", icon='OBJECT_DATAMODE' + ) class PIE_MT_ObjectEditMode(Menu): """Modes Switch""" + bl_idname = "PIE_MT_objecteditmode" - bl_label = "Mode Switch (Ctrl Tab)" + bl_label = "Mode Switch Pie" def draw(self, context): layout = self.layout @@ -215,29 +209,50 @@ class PIE_MT_ObjectEditMode(Menu): box = pie.box() box.label(text=message, icon="INFO") - elif ob and ob.type == 'MESH' and ob.mode in { - 'OBJECT', 'SCULPT', 'VERTEX_PAINT', - 'WEIGHT_PAINT', 'TEXTURE_PAINT', - 'PARTICLE_EDIT', 'GPENCIL_EDIT', - }: + elif ( + ob + and ob.type == 'MESH' + and ob.mode + in { + 'OBJECT', + 'SCULPT', + 'VERTEX_PAINT', + 'WEIGHT_PAINT', + 'TEXTURE_PAINT', + 'PARTICLE_EDIT', + 'GPENCIL_EDIT', + } + ): pie = layout.menu_pie() # 4 - LEFT pie.operator("class.pieweightpaint", text="Weight Paint", icon='WPAINT_HLT') # 6 - RIGHT - pie.operator("class.pietexturepaint", text="Texture Paint", icon='TPAINT_HLT') + pie.operator( + "class.pietexturepaint", text="Texture Paint", icon='TPAINT_HLT' + ) # 2 - BOTTOM - pie.menu("MENU_MT_objecteditmodeothermodes", text="Edit Modes", icon='EDITMODE_HLT') + pie.menu( + "MENU_MT_objecteditmodeothermodes", + text="Edit Modes", + icon='EDITMODE_HLT', + ) # 8 - TOP - pie.operator("class.object", text="Object/Edit Toggle", icon='OBJECT_DATAMODE') + pie.operator( + "class.object", text="Object/Edit Toggle", icon='OBJECT_DATAMODE' + ) # 7 - TOP - LEFT - pie.operator("sculpt.sculptmode_toggle", text="Sculpt", icon='SCULPTMODE_HLT') + pie.operator( + "sculpt.sculptmode_toggle", text="Sculpt", icon='SCULPTMODE_HLT' + ) # 9 - TOP - RIGHT pie.operator("class.pievertexpaint", text="Vertex Paint", icon='VPAINT_HLT') # 1 - BOTTOM - LEFT pie.separator() # 3 - BOTTOM - RIGHT if context.object.particle_systems: - pie.operator("class.pieparticleedit", text="Particle Edit", icon='PARTICLEMODE') + pie.operator( + "class.pieparticleedit", text="Particle Edit", icon='PARTICLEMODE' + ) else: pie.separator() @@ -246,20 +261,32 @@ class PIE_MT_ObjectEditMode(Menu): # 4 - LEFT pie.operator("class.pieweightpaint", text="Weight Paint", icon='WPAINT_HLT') # 6 - RIGHT - pie.operator("class.pietexturepaint", text="Texture Paint", icon='TPAINT_HLT') + pie.operator( + "class.pietexturepaint", text="Texture Paint", icon='TPAINT_HLT' + ) # 2 - BOTTOM - pie.menu("MENU_MT_objecteditmodeothermodes", text="Edit Modes", icon='EDITMODE_HLT') + pie.menu( + "MENU_MT_objecteditmodeothermodes", + text="Edit Modes", + icon='EDITMODE_HLT', + ) # 8 - TOP - pie.operator("class.object", text="Edit/Object Toggle", icon='OBJECT_DATAMODE') + pie.operator( + "class.object", text="Edit/Object Toggle", icon='OBJECT_DATAMODE' + ) # 7 - TOP - LEFT - pie.operator("sculpt.sculptmode_toggle", text="Sculpt", icon='SCULPTMODE_HLT') + pie.operator( + "sculpt.sculptmode_toggle", text="Sculpt", icon='SCULPTMODE_HLT' + ) # 9 - TOP - RIGHT pie.operator("class.pievertexpaint", text="Vertex Paint", icon='VPAINT_HLT') # 1 - BOTTOM - LEFT pie.separator() # 3 - BOTTOM - RIGHT if context.object.particle_systems: - pie.operator("class.pieparticleedit", text="Particle Edit", icon='PARTICLEMODE') + pie.operator( + "class.pieparticleedit", text="Particle Edit", icon='PARTICLEMODE' + ) else: pie.separator() @@ -272,7 +299,9 @@ class PIE_MT_ObjectEditMode(Menu): # 2 - BOTTOM pie.separator() # 8 - TOP - pie.operator("object.editmode_toggle", text="Edit/Object", icon='OBJECT_DATAMODE') + pie.operator( + "object.editmode_toggle", text="Edit/Object", icon='OBJECT_DATAMODE' + ) # 7 - TOP - LEFT pie.separator() # 9 - TOP - RIGHT @@ -285,13 +314,21 @@ class PIE_MT_ObjectEditMode(Menu): elif ob and ob.type == 'ARMATURE': pie = layout.menu_pie() # 4 - LEFT - pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Object", icon="OBJECT_DATAMODE").mode = "OBJECT" + pie.operator( + PIE_OT_SetObjectModePie.bl_idname, text="Object", icon="OBJECT_DATAMODE" + ).mode = "OBJECT" # 6 - RIGHT - pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Pose", icon="POSE_HLT").mode = "POSE" + pie.operator( + PIE_OT_SetObjectModePie.bl_idname, text="Pose", icon="POSE_HLT" + ).mode = "POSE" # 2 - BOTTOM - pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Edit", icon="EDITMODE_HLT").mode = "EDIT" + pie.operator( + PIE_OT_SetObjectModePie.bl_idname, text="Edit", icon="EDITMODE_HLT" + ).mode = "EDIT" # 8 - TOP - pie.operator("object.editmode_toggle", text="Edit Mode", icon='OBJECT_DATAMODE') + pie.operator( + "object.editmode_toggle", text="Edit Mode", icon='OBJECT_DATAMODE' + ) # 7 - TOP - LEFT pie.separator() # 9 - TOP - RIGHT @@ -306,7 +343,11 @@ class PIE_MT_ObjectEditMode(Menu): pie.separator() pie.separator() pie.separator() - pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE') + pie.operator( + "object.editmode_toggle", + text="Edit/Object Toggle", + icon='OBJECT_DATAMODE', + ) pie.separator() pie.separator() pie.separator() @@ -318,7 +359,11 @@ class PIE_MT_ObjectEditMode(Menu): pie.separator() pie.separator() pie.separator() - pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE') + pie.operator( + "object.editmode_toggle", + text="Edit/Object Toggle", + icon='OBJECT_DATAMODE', + ) pie.separator() pie.separator() pie.separator() @@ -330,7 +375,11 @@ class PIE_MT_ObjectEditMode(Menu): pie.separator() pie.separator() pie.separator() - pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE') + pie.operator( + "object.editmode_toggle", + text="Edit/Object Toggle", + icon='OBJECT_DATAMODE', + ) pie.separator() pie.separator() pie.separator() @@ -342,7 +391,11 @@ class PIE_MT_ObjectEditMode(Menu): pie.separator() pie.separator() pie.separator() - pie.operator("object.editmode_toggle", text="Edit/Object Toggle", icon='OBJECT_DATAMODE') + pie.operator( + "object.editmode_toggle", + text="Edit/Object Toggle", + icon='OBJECT_DATAMODE', + ) pie.separator() pie.separator() pie.separator() @@ -350,14 +403,21 @@ class PIE_MT_ObjectEditMode(Menu): if ob and ob.type == 'GPENCIL': pie = layout.menu_pie() # 4 - LEFT - pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Sculpt", - icon="SCULPTMODE_HLT").mode = "SCULPT_GPENCIL" + pie.operator( + PIE_OT_SetObjectModePie.bl_idname, text="Sculpt", icon="SCULPTMODE_HLT" + ).mode = "SCULPT_GPENCIL" # 6 - RIGHT - pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Draw", icon="GREASEPENCIL").mode = "PAINT_GPENCIL" + pie.operator( + PIE_OT_SetObjectModePie.bl_idname, text="Draw", icon="GREASEPENCIL" + ).mode = "PAINT_GPENCIL" # 2 - BOTTOM - pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Edit", icon="EDITMODE_HLT").mode = "EDIT_GPENCIL" + pie.operator( + PIE_OT_SetObjectModePie.bl_idname, text="Edit", icon="EDITMODE_HLT" + ).mode = "EDIT_GPENCIL" # 8 - TOP - pie.operator(PIE_OT_SetObjectModePie.bl_idname, text="Object", icon="OBJECT_DATAMODE").mode = "OBJECT" + pie.operator( + PIE_OT_SetObjectModePie.bl_idname, text="Object", icon="OBJECT_DATAMODE" + ).mode = "OBJECT" # 7 - TOP - LEFT pie.separator() # 9 - TOP - RIGHT @@ -368,7 +428,8 @@ class PIE_MT_ObjectEditMode(Menu): pie.operator( PIE_OT_SetObjectModePie.bl_idname, text="Weight Paint", - icon="WPAINT_HLT").mode = "WEIGHT_GPENCIL" + icon="WPAINT_HLT", + ).mode = "WEIGHT_GPENCIL" elif ob and ob.type in {"LIGHT", "CAMERA", "EMPTY", "SPEAKER"}: message = "Active Object has only Object Mode available" @@ -380,7 +441,7 @@ class PIE_MT_ObjectEditMode(Menu): box.label(text=message, icon="INFO") -classes = ( +registry = ( PIE_MT_ObjectEditMode, PIE_OT_ClassObject, PIE_OT_ClassVertex, @@ -395,38 +456,11 @@ classes = ( PIE_OT_SetObjectModePie, ) -addon_keymaps = [] - def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Select Mode - km = wm.keyconfigs.addon.keymaps.new(name='Object Non-modal') - kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS', ctrl=True) - kmi.properties.name = "PIE_MT_objecteditmode" - addon_keymaps.append((km, kmi)) - - km = wm.keyconfigs.addon.keymaps.new(name='Grease Pencil Stroke Edit Mode') - kmi = km.keymap_items.new('wm.call_menu_pie', 'TAB', 'PRESS', ctrl=True) - kmi.properties.name = "PIE_MT_objecteditmode" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_objecteditmode'}, + hotkey_kwargs={'type': "TAB", 'value': "PRESS", 'ctrl': True}, + key_cat="3D View", + ) diff --git a/source/pie_origin.py b/source/pie_origin.py index 1fde987..133c7f2 100644 --- a/source/pie_origin.py +++ b/source/pie_origin.py @@ -2,23 +2,13 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Ctrl Alt X'", - "description": "Origin Snap/Place Menu", - "author": "pitiwazou, meta-androcto", - "version": (0, 1, 2), - "blender": (2, 80, 0), - "location": "3D View", - "warning": "", - "doc_url": "", - "category": "Origin Pie" -} import bpy from bpy.types import ( Menu, Operator, ) +from .hotkeys import register_hotkey # Pivot to selection @@ -41,8 +31,10 @@ class PIE_OT_PivotToSelection(Operator): return {'FINISHED'} + # Pivot to Bottom + def origin_to_bottom(ob): if ob.type != 'MESH': return @@ -60,11 +52,14 @@ def origin_to_bottom(ob): ob.location.z += a + class PIE_OT_PivotBottom(Operator): bl_idname = "object.pivotobottom" bl_label = "Pivot To Bottom" - bl_description = ("Set the Pivot Point To Lowest Point\n" - "Needs an Active Object of the Mesh type") + bl_description = ( + "Set the Pivot Point To Lowest Point\n" + "Needs an Active Object of the Mesh type" + ) bl_options = {'REGISTER', 'UNDO'} @classmethod @@ -86,8 +81,10 @@ class PIE_OT_PivotBottom(Operator): class PIE_OT_PivotBottom_edit(Operator): bl_idname = "object.pivotobottom_edit" bl_label = "Pivot To Bottom" - bl_description = ("Set the Pivot Point To Lowest Point\n" - "Needs an Active Object of the Mesh type") + bl_description = ( + "Set the Pivot Point To Lowest Point\n" + "Needs an Active Object of the Mesh type" + ) bl_options = {'REGISTER', 'UNDO'} @classmethod @@ -209,7 +206,7 @@ class PIE_OT_SetOriginToSelected_edit(Operator): @classmethod def poll(cls, context): - return (context.area.type == "VIEW_3D" and context.active_object is not None) + return context.area.type == "VIEW_3D" and context.active_object is not None def execute(self, context): check = vfeOrigin_pie(context) @@ -223,7 +220,7 @@ class PIE_OT_SetOriginToSelected_edit(Operator): # Pie Origin/Pivot - Shift + S class PIE_MT_OriginPivot(Menu): bl_idname = "ORIGIN_MT_pivotmenu" - bl_label = "Origin Menu" + bl_label = "Origin Pie" def draw(self, context): layout = self.layout @@ -231,63 +228,86 @@ class PIE_MT_OriginPivot(Menu): pie = layout.menu_pie() if obj and obj.type == 'MESH' and obj.mode in {'OBJECT'}: # 4 - LEFT - pie.operator("object.origin_set", text="Origin to Center of Mass", - icon='NONE').type = 'ORIGIN_CENTER_OF_MASS' + pie.operator( + "object.origin_set", text="Origin to Center of Mass", icon='NONE' + ).type = 'ORIGIN_CENTER_OF_MASS' # 6 - RIGHT - pie.operator("object.origin_set", text="Origin to Cursor", - icon='PIVOT_CURSOR').type = 'ORIGIN_CURSOR' + pie.operator( + "object.origin_set", text="Origin to Cursor", icon='PIVOT_CURSOR' + ).type = 'ORIGIN_CURSOR' # 2 - BOTTOM - pie.operator("object.pivotobottom", text="Origin to Bottom", - icon='TRIA_DOWN') + pie.operator( + "object.pivotobottom", text="Origin to Bottom", icon='TRIA_DOWN' + ) # 8 - TOP - pie.operator("object.pivot2selection", text="Origin To Selection", - icon='SNAP_INCREMENT') + pie.operator( + "object.pivot2selection", + text="Origin To Selection", + icon='SNAP_INCREMENT', + ) # 7 - TOP - LEFT - pie.operator("object.origin_set", text="Geometry To Origin", - icon='NONE').type = 'GEOMETRY_ORIGIN' + pie.operator( + "object.origin_set", text="Geometry To Origin", icon='NONE' + ).type = 'GEOMETRY_ORIGIN' # 9 - TOP - RIGHT - pie.operator("object.origin_set", text="Origin To Geometry", - icon='NONE').type = 'ORIGIN_GEOMETRY' + pie.operator( + "object.origin_set", text="Origin To Geometry", icon='NONE' + ).type = 'ORIGIN_GEOMETRY' elif obj and obj.type == 'MESH' and obj.mode in {'EDIT'}: # 4 - LEFT - pie.operator("object.origintomass_edit", text="Origin to Center of Mass", - icon='NONE') + pie.operator( + "object.origintomass_edit", text="Origin to Center of Mass", icon='NONE' + ) # 6 - RIGHT - pie.operator("object.pivot2cursor_edit", text="Origin to Cursor", - icon='PIVOT_CURSOR') + pie.operator( + "object.pivot2cursor_edit", text="Origin to Cursor", icon='PIVOT_CURSOR' + ) # 2 - BOTTOM - pie.operator("object.pivotobottom_edit", text="Origin to Bottom", - icon='TRIA_DOWN') + pie.operator( + "object.pivotobottom_edit", text="Origin to Bottom", icon='TRIA_DOWN' + ) # 8 - TOP - pie.operator("object.setorigintoselected_edit", text="Origin To Selected", - icon='SNAP_INCREMENT') + pie.operator( + "object.setorigintoselected_edit", + text="Origin To Selected", + icon='SNAP_INCREMENT', + ) # 7 - TOP - LEFT - pie.operator("object.geometrytoorigin_edit", text="Geometry To Origin", - icon='NONE') + pie.operator( + "object.geometrytoorigin_edit", text="Geometry To Origin", icon='NONE' + ) # 9 - TOP - RIGHT - pie.operator("object.origintogeometry_edit", text="Origin To Geometry", - icon='NONE') + pie.operator( + "object.origintogeometry_edit", text="Origin To Geometry", icon='NONE' + ) else: # 4 - LEFT - pie.operator("object.origin_set", text="Origin to Center of Mass", - icon='NONE').type = 'ORIGIN_CENTER_OF_MASS' + pie.operator( + "object.origin_set", text="Origin to Center of Mass", icon='NONE' + ).type = 'ORIGIN_CENTER_OF_MASS' # 6 - RIGHT - pie.operator("object.origin_set", text="Origin To 3D Cursor", - icon='PIVOT_CURSOR').type = 'ORIGIN_CURSOR' + pie.operator( + "object.origin_set", text="Origin To 3D Cursor", icon='PIVOT_CURSOR' + ).type = 'ORIGIN_CURSOR' # 2 - BOTTOM - pie.operator("object.pivot2selection", text="Origin To Selection", - icon='SNAP_INCREMENT') + pie.operator( + "object.pivot2selection", + text="Origin To Selection", + icon='SNAP_INCREMENT', + ) # 8 - TOP - pie.operator("object.origin_set", text="Origin To Geometry", - icon='NONE').type = 'ORIGIN_GEOMETRY' + pie.operator( + "object.origin_set", text="Origin To Geometry", icon='NONE' + ).type = 'ORIGIN_GEOMETRY' # 7 - TOP - LEFT - pie.operator("object.origin_set", text="Geometry To Origin", - icon='NONE').type = 'GEOMETRY_ORIGIN' + pie.operator( + "object.origin_set", text="Geometry To Origin", icon='NONE' + ).type = 'GEOMETRY_ORIGIN' -classes = ( +registry = ( PIE_MT_OriginPivot, PIE_OT_PivotToSelection, PIE_OT_PivotBottom, @@ -296,36 +316,14 @@ classes = ( PIE_OT_PivotBottom_edit, PIE_OT_OriginToGeometry_edit, PIE_OT_GeometryToOrigin_edit, - PIE_OT_SetOriginToSelected_edit + PIE_OT_SetOriginToSelected_edit, ) -addon_keymaps = [] - def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Origin/Pivot - km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D') - kmi = km.keymap_items.new('wm.call_menu_pie', 'X', 'PRESS', ctrl=True, alt=True) - kmi.properties.name = "ORIGIN_MT_pivotmenu" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'ORIGIN_MT_pivotmenu'}, + hotkey_kwargs={'type': "X", 'value': "PRESS", 'ctrl': True, 'alt': True}, + key_cat="3D View", + ) diff --git a/source/pie_proportional_menu.py b/source/pie_proportional_menu.py index 05068bc..b75e65c 100644 --- a/source/pie_proportional_menu.py +++ b/source/pie_proportional_menu.py @@ -2,23 +2,13 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Shift O'", - "description": "Proportional Object/Edit Tools", - "author": "pitiwazou, meta-androcto", - "version": (0, 1, 1), - "blender": (2, 80, 0), - "location": "3D View Object & Edit modes", - "warning": "", - "doc_url": "", - "category": "Proportional Edit Pie" -} import bpy from bpy.types import ( Menu, Operator, ) +from .hotkeys import register_hotkey # Proportional Edit Object @@ -300,7 +290,7 @@ class PIE_OT_ProportionalInverseSquareEdt(Operator): # Pie ProportionalEditObj - O class PIE_MT_ProportionalObj(Menu): bl_idname = "PIE_MT_proportional_obj" - bl_label = "Pie Proportional Obj" + bl_label = "Proportional Editing Pie" def draw(self, context): layout = self.layout @@ -312,11 +302,19 @@ class PIE_MT_ProportionalObj(Menu): # 2 - BOTTOM pie.operator("proportional_obj.linear", text="Linear", icon='LINCURVE') # 8 - TOP - pie.prop(context.tool_settings, "use_proportional_edit_objects", text="Proportional On/Off") + pie.prop( + context.tool_settings, + "use_proportional_edit_objects", + text="Proportional On/Off", + ) # 7 - TOP - LEFT pie.operator("proportional_obj.root", text="Root", icon='ROOTCURVE') # 9 - TOP - RIGHT - pie.operator("proportional_obj.inversesquare", text="Inverse Square", icon='INVERSESQUARECURVE') + pie.operator( + "proportional_obj.inversesquare", + text="Inverse Square", + icon='INVERSESQUARECURVE', + ) # 1 - BOTTOM - LEFT pie.operator("proportional_obj.sharp", text="Sharp", icon='SHARPCURVE') # 3 - BOTTOM - RIGHT @@ -326,7 +324,7 @@ class PIE_MT_ProportionalObj(Menu): # Pie ProportionalEditEdt - O class PIE_MT_ProportionalEdt(Menu): bl_idname = "PIE_MT_proportional_edt" - bl_label = "Pie Proportional Edit" + bl_label = "Proportional Editing Pie" def draw(self, context): layout = self.layout @@ -336,13 +334,21 @@ class PIE_MT_ProportionalEdt(Menu): # 6 - RIGHT pie.operator("proportional_edt.sphere", text="Sphere", icon='SPHERECURVE') # 2 - BOTTOM - pie.operator("proportional_edt.inversesquare", text="Inverse Square", icon='INVERSESQUARECURVE') + pie.operator( + "proportional_edt.inversesquare", + text="Inverse Square", + icon='INVERSESQUARECURVE', + ) # 8 - TOP - pie.operator("proportional_edt.active", text="Proportional On/Off", icon='PROP_ON') + pie.operator( + "proportional_edt.active", text="Proportional On/Off", icon='PROP_ON' + ) # 7 - TOP - LEFT pie.operator("proportional_edt.connected", text="Connected", icon='PROP_CON') # 9 - TOP - RIGHT - pie.operator("proportional_edt.projected", text="Projected", icon='PROP_PROJECTED') + pie.operator( + "proportional_edt.projected", text="Projected", icon='PROP_PROJECTED' + ) # 1 - BOTTOM - LEFT pie.operator("proportional_edt.root", text="Root", icon='ROOTCURVE') # 3 - BOTTOM - RIGHT @@ -352,7 +358,7 @@ class PIE_MT_ProportionalEdt(Menu): # Pie ProportionalEditEdt - O class PIE_MT_ProportionalMore(Menu): bl_idname = "PIE_MT_proportional_more" - bl_label = "Pie Proportional More" + bl_label = "More Falloff Shapes" def draw(self, context): layout = self.layout @@ -367,7 +373,7 @@ class PIE_MT_ProportionalMore(Menu): # Pie ProportionalEditEdt2 class PIE_MT_proportionalmoreob(Menu): bl_idname = "PIE_MT_proportional_moreob" - bl_label = "Pie Proportional More" + bl_label = "Proportional Falloffs" def draw(self, context): layout = self.layout @@ -377,7 +383,7 @@ class PIE_MT_proportionalmoreob(Menu): box.operator("proportional_obj.random", text="Random", icon='RNDCURVE') -classes = ( +registry = ( PIE_OT_ProportionalEditObj, PIE_OT_ProportionalSmoothObj, PIE_OT_ProportionalSphereObj, @@ -401,42 +407,20 @@ classes = ( PIE_MT_ProportionalObj, PIE_MT_ProportionalEdt, PIE_MT_ProportionalMore, - PIE_MT_proportionalmoreob + PIE_MT_proportionalmoreob, ) -addon_keymaps = [] - def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # ProportionalEditObj - km = wm.keyconfigs.addon.keymaps.new(name='Object Mode') - kmi = km.keymap_items.new('wm.call_menu_pie', 'O', 'PRESS', shift=True) - kmi.properties.name = "PIE_MT_proportional_obj" - addon_keymaps.append((km, kmi)) - - # ProportionalEditEdt - km = wm.keyconfigs.addon.keymaps.new(name='Mesh') - kmi = km.keymap_items.new('wm.call_menu_pie', 'O', 'PRESS', shift=True) - kmi.properties.name = "PIE_MT_proportional_edt" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_proportional_obj'}, + hotkey_kwargs={'type': "O", 'value': "PRESS", 'shift': True}, + key_cat="Object Mode", + ) + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_proportional_obj'}, + hotkey_kwargs={'type': "O", 'value': "PRESS", 'shift': True}, + key_cat="Mesh", + ) diff --git a/source/pie_save_open_menu.py b/source/pie_save_open_menu.py index 1ec7b77..07b31a4 100644 --- a/source/pie_save_open_menu.py +++ b/source/pie_save_open_menu.py @@ -2,32 +2,22 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Ctrl S'", - "description": "Save/Open & File Menus", - "blender": (2, 80, 0), - "location": "All Editors", - "warning": "", - "doc_url": "", - "category": "Save Open Pie" -} -import bpy -from bpy.types import ( - Menu, - Operator, -) import os +import bpy +from bpy.types import Menu +from .hotkeys import register_hotkey -# Pie Save/Open +# Save/Open Pie class PIE_MT_SaveOpen(Menu): bl_idname = "PIE_MT_saveopen" - bl_label = "Pie Save/Open" + bl_label = "Save/Open Pie" @staticmethod def _save_as_mainfile_calc_incremental_name(): import re + dirname, base_name = os.path.split(bpy.data.filepath) base_name_no_ext, ext = os.path.splitext(base_name) match = re.match(r"(.*)_([\d]+)$", base_name_no_ext) @@ -61,7 +51,9 @@ class PIE_MT_SaveOpen(Menu): default_operator_contest = layout.operator_context layout.operator_context = 'EXEC_DEFAULT' pie.operator( - "wm.save_as_mainfile", text="Incremental Save", icon='NONE', + "wm.save_as_mainfile", + text="Incremental Save", + icon='NONE', ).filepath = self._save_as_mainfile_calc_incremental_name() layout.operator_context = default_operator_contest else: @@ -99,7 +91,9 @@ class PIE_MT_recover(Menu): pie = layout.menu_pie() box = pie.split().column() box.operator("wm.recover_auto_save", text="Recover Auto Save...", icon='NONE') - box.operator("wm.recover_last_session", text="Recover Last Session", icon='RECOVER_LAST') + box.operator( + "wm.recover_last_session", text="Recover Last Session", icon='RECOVER_LAST' + ) box.operator("wm.revert_mainfile", text="Revert", icon='FILE_REFRESH') box.separator() box.operator("file.report_missing_files", text="Report Missing Files") @@ -132,7 +126,7 @@ class PIE_MT_openio(Menu): box.menu("TOPBAR_MT_file_open_recent", icon='FILE_FOLDER') -classes = ( +registry = ( PIE_MT_SaveOpen, PIE_MT_fileio, PIE_MT_recover, @@ -140,33 +134,11 @@ classes = ( PIE_MT_openio, ) -addon_keymaps = [] - def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Save/Open/... - km = wm.keyconfigs.addon.keymaps.new(name='Window') - kmi = km.keymap_items.new('wm.call_menu_pie', 'S', 'PRESS', ctrl=True) - kmi.properties.name = "PIE_MT_saveopen" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_saveopen'}, + hotkey_kwargs={'type': "S", 'value': "PRESS", 'ctrl': True}, + key_cat="Window", + ) diff --git a/source/pie_sculpt_menu.py b/source/pie_sculpt_menu.py index cd57b7b..706bf19 100644 --- a/source/pie_sculpt_menu.py +++ b/source/pie_sculpt_menu.py @@ -2,118 +2,119 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'W'", - "description": "Sculpt Brush Menu", - "author": "pitiwazou, meta-androcto", - "version": (0, 1, 0), - "blender": (2, 80, 0), - "location": "W key", - "warning": "", - "doc_url": "", - "category": "Sculpt Pie" -} - import os import bpy -from bpy.types import ( - Menu, - Operator, -) +from bpy.types import Menu +from pathlib import Path +from .hotkeys import register_hotkey -# Sculpt Draw -class PIE_OT_SculptSculptDraw(Operator): - bl_idname = "sculpt.sculptraw" - bl_label = "Sculpt SculptDraw" - bl_options = {'REGISTER', 'UNDO'} - - def execute(self, context): - context.tool_settings.sculpt.brush = bpy.data.brushes['SculptDraw'] - return {'FINISHED'} - - -# Pie Sculp Pie Menus - W -class PIE_MT_SculptPie(Menu): - bl_idname = "PIE_MT_sculpt" - bl_label = "Pie Sculpt" +# Sculpt Pie Pie Menus - W +class PIE_MT_sculpt_brush_select(Menu): + bl_idname = "PIE_MT_sculpt_brush_select" + bl_label = "Sculpt Pie" def draw(self, context): global brush_icons layout = self.layout pie = layout.menu_pie() pie.scale_y = 1.2 + # 4 - LEFT - pie.operator("paint.brush_select", - text=" Crease", icon_value=brush_icons["crease"]).sculpt_tool = 'CREASE' + draw_brush_operator(pie, 'Crease', 'crease') # 6 - RIGHT - pie.operator("paint.brush_select", - text=" Blob", icon_value=brush_icons["blob"]).sculpt_tool = 'BLOB' + draw_brush_operator(pie, 'Blob', 'blob') # 2 - BOTTOM - pie.menu(PIE_MT_Sculpttwo.bl_idname, text="More Brushes") + pie.menu(PIE_MT_sculpt_brush_select_misc.bl_idname, text="More Brushes") # 8 - TOP - pie.operator("sculpt.sculptraw", - text=" Draw", icon_value=brush_icons["draw"]) + draw_brush_operator(pie, 'Draw', 'draw') # 7 - TOP - LEFT - pie.operator("paint.brush_select", - text=" Clay", icon_value=brush_icons["clay"]).sculpt_tool = 'CLAY' + draw_brush_operator(pie, 'Clay', 'clay') # 9 - TOP - RIGHT - pie.operator("paint.brush_select", - text=" Clay Strips", icon_value=brush_icons["clay_strips"]).sculpt_tool = 'CLAY_STRIPS' + draw_brush_operator(pie, 'Clay Strips', 'clay_strips') # 1 - BOTTOM - LEFT - pie.operator("paint.brush_select", - text=" Inflate/Deflate", icon_value=brush_icons["inflate"]).sculpt_tool = 'INFLATE' + draw_brush_operator(pie, 'Inflate/Deflate', 'inflate') # 3 - BOTTOM - RIGHT - pie.menu(PIE_MT_Sculptthree.bl_idname, - text=" Grab Brushes", icon_value=brush_icons["grab"]) + pie.menu( + PIE_MT_sculpt_brush_select_grab.bl_idname, + text=" Grab Brushes", + icon_value=brush_icons["grab"], + ) -# Pie Sculpt 2 -class PIE_MT_Sculpttwo(Menu): - bl_idname = "PIE_MT_sculpttwo" - bl_label = "Pie Sculpt 2" +# Sculpt Pie 2 +class PIE_MT_sculpt_brush_select_misc(Menu): + bl_idname = "PIE_MT_sculpt_brush_select_misc" + bl_label = "More Brushes" def draw(self, context): global brush_icons layout = self.layout layout.scale_y = 1.5 - layout.operator("paint.brush_select", text=' Smooth', - icon_value=brush_icons["smooth"]).sculpt_tool = 'SMOOTH' - layout.operator("paint.brush_select", text=' Flatten', - icon_value=brush_icons["flatten"]).sculpt_tool = 'FLATTEN' - layout.operator("paint.brush_select", text=' Scrape/Peaks', - icon_value=brush_icons["scrape"]).sculpt_tool = 'SCRAPE' - layout.operator("paint.brush_select", text=' Fill/Deepen', - icon_value=brush_icons["fill"]).sculpt_tool = 'FILL' - layout.operator("paint.brush_select", text=' Pinch/Magnify', - icon_value=brush_icons["pinch"]).sculpt_tool = 'PINCH' - layout.operator("paint.brush_select", text=' Layer', - icon_value=brush_icons["layer"]).sculpt_tool = 'LAYER' - layout.operator("paint.brush_select", text=' Mask', - icon_value=brush_icons["mask"]).sculpt_tool = 'MASK' + # 4 - LEFT + draw_brush_operator(layout, 'Smooth', 'smooth') + # 6 - RIGHT + draw_brush_operator(layout, 'Flatten/Contrast', 'flatten') + # 2 - BOTTOM + draw_brush_operator(layout, 'Scrape/Fill', 'scrape') + # 8 - TOP + draw_brush_operator(layout, 'Fill/Deepen', 'fill') + # 7 - TOP - LEFT + draw_brush_operator(layout, 'Pinch/Magnify', 'pinch') + # 9 - TOP - RIGHT + draw_brush_operator(layout, 'Layer', 'layer') + # 1 - BOTTOM - LEFT + draw_brush_operator(layout, 'Mask', 'mask') + # 3 - BOTTOM - RIGHT -# Pie Sculpt Three -class PIE_MT_Sculptthree(Menu): - bl_idname = "PIE_MT_sculptthree" - bl_label = "Pie Sculpt 3" +# Sculpt Pie Three +class PIE_MT_sculpt_brush_select_grab(Menu): + bl_idname = "PIE_MT_sculpt_brush_select_grab" + bl_label = "Grab Brushes" def draw(self, context): global brush_icons layout = self.layout layout.scale_y = 1.5 - layout.operator("paint.brush_select", - text=' Grab', icon_value=brush_icons["grab"]).sculpt_tool = 'GRAB' - layout.operator("paint.brush_select", - text=' Nudge', icon_value=brush_icons["nudge"]).sculpt_tool = 'NUDGE' - layout.operator("paint.brush_select", - text=' Thumb', icon_value=brush_icons["thumb"]).sculpt_tool = 'THUMB' - layout.operator("paint.brush_select", - text=' Snakehook', icon_value=brush_icons["snake_hook"]).sculpt_tool = 'SNAKE_HOOK' - layout.operator("paint.brush_select", - text=' Rotate', icon_value=brush_icons["rotate"]).sculpt_tool = 'ROTATE' + # 4 - LEFT + draw_brush_operator(layout, 'Grab', 'grab') + # 6 - RIGHT + draw_brush_operator(layout, 'Nudge', 'nudge') + # 2 - BOTTOM + draw_brush_operator(layout, 'Thumb', 'thumb') + # 8 - TOP + draw_brush_operator(layout, 'Snake Hook', 'snake_hook') + # 7 - TOP - LEFT + draw_brush_operator(layout, 'Twist', 'rotate') + + +def draw_brush_operator(layout, brush_name: str, brush_icon: str): + """Draw a brush select operator in the provided UI element with the pre-4.3 icons. + brush_name must match the name of the Brush Asset. + brush_icon must match the name of a file in this add-on's icons folder. + """ + if 'asset_activate' in dir(bpy.ops.brush): + # 4.3 + op = layout.operator( + 'brush.asset_activate', + text=" " + brush_name, + icon_value=brush_icons[brush_icon], + ) + op.asset_library_type = 'ESSENTIALS' + op.relative_asset_identifier = ( + os.path.join("brushes", "essentials_brushes.blend", "Brush", brush_name) + ) + else: + # Pre-4.3 + op = layout.operator( + "paint.brush_select", + text=" " + brush_name, + icon_value=brush_icons[brush_icon], + ) + op.sculpt_tool = brush_icon.upper() brush_icons = {} @@ -121,16 +122,12 @@ brush_icons = {} def create_icons(): global brush_icons - icons_directory = bpy.utils.system_resource('DATAFILES', path="icons") - brushes = ( - "crease", "blob", "smooth", "draw", "clay", "clay_strips", "inflate", "grab", - "nudge", "thumb", "snake_hook", "rotate", "flatten", "scrape", "fill", "pinch", - "layer", "mask", - ) - for brush in brushes: - filename = os.path.join(icons_directory, f"brush.sculpt.{brush}.dat") - icon_value = bpy.app.icons.new_triangles_from_file(filename) - brush_icons[brush] = icon_value + icons_directory = Path(__file__).parent / "icons" + + for icon_path in icons_directory.iterdir(): + icon_value = bpy.app.icons.new_triangles_from_file(icon_path.as_posix()) + brush_name = icon_path.stem.split(".")[-1] + brush_icons[brush_name] = icon_value def release_icons(): @@ -139,44 +136,23 @@ def release_icons(): bpy.app.icons.release(value) -classes = ( - PIE_MT_SculptPie, - PIE_MT_Sculpttwo, - PIE_MT_Sculptthree, - PIE_OT_SculptSculptDraw, +registry = ( + PIE_MT_sculpt_brush_select, + PIE_MT_sculpt_brush_select_misc, + PIE_MT_sculpt_brush_select_grab, ) -addon_keymaps = [] - def register(): create_icons() - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Sculpt Pie Menu - km = wm.keyconfigs.addon.keymaps.new(name='Sculpt') - kmi = km.keymap_items.new('wm.call_menu_pie', 'W', 'PRESS') - kmi.properties.name = "PIE_MT_sculpt" - addon_keymaps.append((km, kmi)) + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_sculpt_brush_select'}, + hotkey_kwargs={'type': "W", 'value': "PRESS"}, + key_cat="Sculpt", + ) def unregister(): release_icons() - - for cls in classes: - bpy.utils.unregister_class(cls) - - wm = bpy.context.window_manager - kc = wm.keyconfigs.addon - if kc: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() diff --git a/source/pie_select_menu.py b/source/pie_select_menu.py index 4ac4400..9e819be 100644 --- a/source/pie_select_menu.py +++ b/source/pie_select_menu.py @@ -2,29 +2,15 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'A'", - "description": "Object/Edit mode Selection Menu", - "author": "pitiwazou, meta-androcto", - "version": (0, 1, 1), - "blender": (2, 80, 0), - "location": "3D View", - "warning": "", - "doc_url": "", - "category": "Select Pie" -} - import bpy -from bpy.types import ( - Menu, - Operator -) +from bpy.types import Menu, Operator +from .hotkeys import register_hotkey # Pie Selection Object Mode - A class PIE_MT_SelectionsMore(Menu): bl_idname = "PIE_MT_selectionsmore" - bl_label = "Pie Selections Object Mode" + bl_label = "Selection Pie" def draw(self, context): layout = self.layout @@ -55,12 +41,13 @@ class PIE_MT_SelectionsMore(Menu): props.extend = True props.direction = 'CHILD' + # Pie Selection Object Mode - A class PIE_MT_SelectionsOM(Menu): bl_idname = "PIE_MT_selectionsom" - bl_label = "Pie Selections Object Mode" + bl_label = "Selection Pie" def draw(self, context): layout = self.layout @@ -70,9 +57,13 @@ class PIE_MT_SelectionsOM(Menu): # 6 - RIGHT pie.operator("object.select_by_type", text="Select By Type") # 2 - BOTTOM - pie.operator("object.select_all", text="Invert Selection", icon='ZOOM_PREVIOUS').action = 'INVERT' + pie.operator( + "object.select_all", text="Invert Selection", icon='ZOOM_PREVIOUS' + ).action = 'INVERT' # 8 - TOP - pie.operator("object.select_all", text="Select All Toggle", icon='NONE').action = 'TOGGLE' + pie.operator( + "object.select_all", text="Select All Toggle", icon='NONE' + ).action = 'TOGGLE' # 7 - TOP - LEFT pie.operator("view3d.select_circle", text="Circle Select") # 9 - TOP - RIGHT @@ -122,7 +113,9 @@ class PIE_MT_SelectAllBySelection(Menu): box.operator("class.vertexop", text="Vertex", icon='VERTEXSEL') box.operator("class.edgeop", text="Edge", icon='EDGESEL') box.operator("class.faceop", text="Face", icon='FACESEL') - box.operator("verts.edgesfacesop", text="Vertex/Edges/Faces", icon='OBJECT_DATAMODE') + box.operator( + "verts.edgesfacesop", text="Vertex/Edges/Faces", icon='OBJECT_DATAMODE' + ) # Edit Selection Modes @@ -198,12 +191,18 @@ class PIE_MT_SelectLoopSelection(Menu): layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("mesh.loop_multi_select", text="Select Loop", icon='NONE').ring = False - layout.operator("mesh.loop_multi_select", text="Select Ring", icon='NONE').ring = True - layout.operator("mesh.loop_to_region", text="Select Loop Inner Region", icon='NONE') + layout.operator( + "mesh.loop_multi_select", text="Select Loop", icon='NONE' + ).ring = False + layout.operator( + "mesh.loop_multi_select", text="Select Ring", icon='NONE' + ).ring = True + layout.operator( + "mesh.loop_to_region", text="Select Loop Inner Region", icon='NONE' + ) -classes = ( +registry = ( PIE_MT_SelectionsOM, PIE_MT_SelectionsEM, PIE_MT_SelectAllBySelection, @@ -212,42 +211,20 @@ classes = ( PIE_OT_classvertexop, PIE_OT_classedgeop, PIE_OT_classfaceop, - PIE_OT_vertsedgesfacesop + PIE_OT_vertsedgesfacesop, ) -addon_keymaps = [] - def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Selection Object Mode - km = wm.keyconfigs.addon.keymaps.new(name='Object Mode') - kmi = km.keymap_items.new('wm.call_menu_pie', 'A', 'PRESS') - kmi.properties.name = "PIE_MT_selectionsom" - addon_keymaps.append((km, kmi)) - - # Selection Edit Mode - km = wm.keyconfigs.addon.keymaps.new(name='Mesh') - kmi = km.keymap_items.new('wm.call_menu_pie', 'A', 'PRESS') - kmi.properties.name = "PIE_MT_selectionsem" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_selectionsom'}, + hotkey_kwargs={'type': "A", 'value': "PRESS"}, + key_cat="Object Mode", + ) + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_selectionsem'}, + hotkey_kwargs={'type': "A", 'value': "PRESS"}, + key_cat="Mesh", + ) diff --git a/source/pie_shading_menu.py b/source/pie_shading_menu.py index 66a169c..b79b264 100644 --- a/source/pie_shading_menu.py +++ b/source/pie_shading_menu.py @@ -2,26 +2,15 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Z'", - "description": "Viewport Shading Menus", - "author": "pitiwazou, meta-androcto", - "version": (0, 1, 1), - "blender": (2, 80, 0), - "location": "3D View", - "warning": "", - "doc_url": "", - "category": "Shading Pie" -} - import bpy from bpy.types import Menu +from .hotkeys import register_hotkey -# Pie Shading - Z +# Shading Pie - Z class PIE_MT_ShadingView(Menu): bl_idname = "PIE_MT_shadingview" - bl_label = "Pie Shading" + bl_label = "Shading Pie" def draw(self, context): layout = self.layout @@ -38,37 +27,15 @@ class PIE_MT_ShadingView(Menu): pie.operator("OBJECT_OT_shade_flat") -classes = ( +registry = ( PIE_MT_ShadingView, ) -addon_keymaps = [] - def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Shading - km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D') - kmi = km.keymap_items.new('wm.call_menu_pie', 'Z', 'PRESS') - kmi.properties.name = "PIE_MT_shadingview" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_shadingview'}, + hotkey_kwargs={'type': "Z", 'value': "PRESS"}, + key_cat="3D View", + ) diff --git a/source/pie_views_numpad_menu.py b/source/pie_views_numpad_menu.py index 387e62a..b586488 100644 --- a/source/pie_views_numpad_menu.py +++ b/source/pie_views_numpad_menu.py @@ -2,23 +2,13 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -bl_info = { - "name": "Hotkey: 'Alt Q'", - "description": "Viewport Numpad Menus", - "author": "pitiwazou, meta-androcto", - "version": (0, 1, 1), - "blender": (2, 80, 0), - "location": "Alt Q key", - "warning": "", - "doc_url": "", - "category": "View Numpad Pie" -} import bpy from bpy.types import ( Menu, Operator, ) +from .hotkeys import register_hotkey # Lock Camera Transforms @@ -59,7 +49,7 @@ class PIE_OT_LockTransforms(Operator): # Pie views numpad - Q class PIE_MT_ViewNumpad(Menu): bl_idname = "PIE_MT_viewnumpad" - bl_label = "Pie Views Menu" + bl_label = "Views Pie" def draw(self, context): layout = self.layout @@ -73,7 +63,9 @@ class PIE_MT_ViewNumpad(Menu): # 6 - RIGHT pie.operator("view3d.view_axis", text="Right", icon='TRIA_RIGHT').type = 'RIGHT' # 2 - BOTTOM - pie.operator("view3d.view_axis", text="Bottom", icon='TRIA_DOWN').type = 'BOTTOM' + pie.operator("view3d.view_axis", text="Bottom", icon='TRIA_DOWN').type = ( + 'BOTTOM' + ) # 8 - TOP pie.operator("view3d.view_axis", text="Top", icon='TRIA_UP').type = 'TOP' # 7 - TOP - LEFT @@ -89,14 +81,19 @@ class PIE_MT_ViewNumpad(Menu): row = box.row(align=True) if context.space_data.lock_camera is False: - row.operator("wm.context_toggle", text="Lock Cam To View", - icon='UNLOCKED').data_path = "space_data.lock_camera" + row.operator( + "wm.context_toggle", text="Lock Cam To View", icon='UNLOCKED' + ).data_path = "space_data.lock_camera" elif context.space_data.lock_camera is True: - row.operator("wm.context_toggle", text="Lock Cam to View", - icon='LOCKED').data_path = "space_data.lock_camera" + row.operator( + "wm.context_toggle", text="Lock Cam to View", icon='LOCKED' + ).data_path = "space_data.lock_camera" - icon_locked = 'LOCKED' if ob and ob.lock_rotation[0] is False else \ - 'UNLOCKED' if ob and ob.lock_rotation[0] is True else 'LOCKED' + icon_locked = ( + 'LOCKED' + if ob and ob.lock_rotation[0] is False + else 'UNLOCKED' if ob and ob.lock_rotation[0] is True else 'LOCKED' + ) row = box.row(align=True) row.operator("object.locktransforms", text="Lock Transforms", icon=icon_locked) @@ -119,38 +116,16 @@ class PIE_MT_ViewNumpad(Menu): row.operator("screen.screen_full_area", text="Toggle Full") -classes = ( +registry = ( PIE_MT_ViewNumpad, PIE_OT_LockTransforms, ) -addon_keymaps = [] - def register(): - for cls in classes: - bpy.utils.register_class(cls) - - wm = bpy.context.window_manager - if wm.keyconfigs.addon: - # Views numpad - km = wm.keyconfigs.addon.keymaps.new(name='3D View Generic', space_type='VIEW_3D') - kmi = km.keymap_items.new('wm.call_menu_pie', 'Q', 'PRESS', alt=True) - kmi.properties.name = "PIE_MT_viewnumpad" - 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: - for km, kmi in addon_keymaps: - km.keymap_items.remove(kmi) - addon_keymaps.clear() - - -if __name__ == "__main__": - register() + register_hotkey( + 'wm.call_menu_pie', + op_kwargs={'name': 'PIE_MT_viewnumpad'}, + hotkey_kwargs={'type': "Q", 'value': "PRESS", 'alt': True}, + key_cat="3D View", + ) diff --git a/source/prefs.py b/source/prefs.py new file mode 100644 index 0000000..6c93a71 --- /dev/null +++ b/source/prefs.py @@ -0,0 +1,15 @@ + +from bpy.types import AddonPreferences +from .hotkeys import draw_hotkey_list + +class PIEToolsPreferences(AddonPreferences): + bl_idname = __package__ + + keymap_items = {} + + def draw(self, context): + draw_hotkey_list(self.layout.column(), context) + +registry = [ + PIEToolsPreferences, +]