4.3 Compatibility & Editable Hotkeys #1

Merged
Demeter Dzadik merged 4 commits from demeters_branch into main 2024-08-15 12:47:59 +02:00
51 changed files with 867 additions and 1113 deletions

View File

@ -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)

View File

@ -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"

183
source/hotkeys.py Normal file
View File

@ -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 = {}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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",
)

View File

@ -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",
)

View File

@ -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",
)

View File

@ -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",
)

View File

@ -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",
)

View File

@ -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",
)

View File

@ -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",
)

View File

@ -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",
)

View File

@ -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",
)

View File

@ -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",
)

View File

@ -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)
Mets marked this conversation as resolved

Extensions review tool raises flag for this line

Use of back-slash (often used for non-portable MS-Windows paths).

I'm not familiar with re module so can't help you with that much, just letting you know.

Extensions review tool raises flag for this line ``` Use of back-slash (often used for non-portable MS-Windows paths). ``` I'm not familiar with re module so can't help you with that much, just letting you know.
Review

\d is a notation in RegularExpression denoting an integer (0-9), so I think this is a false alarm.

\d is a notation in RegularExpression denoting an integer (0-9), so I think this is a false alarm.
@ -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",
)

View File

@ -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)
Mets marked this conversation as resolved Outdated

Non-portable backslashes here as well. Causes incorrect filepaths on some systems.

Use os here and let it handle that

os.path.join("brushes", "essentials_brushes.blend", "Brush")

Not sure but I THINK it should recognize blend file as a directory, I remember that being the case.

Non-portable backslashes here as well. Causes incorrect filepaths on some systems. Use `os` here and let it handle that ``` os.path.join("brushes", "essentials_brushes.blend", "Brush") ``` Not sure but I THINK it should recognize blend file as a directory, I remember that being the case.

Great point, fixed!

Great point, fixed!
)
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()

View File

@ -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",
)

View File

@ -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",
)

View File

@ -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",
)

15
source/prefs.py Normal file
View File

@ -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,
]