Keymap: expose tool keymaps in the preferences

Currently some modes share tool keymaps, we might want to disable
this since it's confusing editing one thing in multiple places.

However this should be resolved in the tool definitions.
This commit is contained in:
Campbell Barton 2018-10-03 15:48:37 +10:00
parent e44dfbbba5
commit 1c3411ac89
5 changed files with 116 additions and 44 deletions

View File

@ -437,8 +437,8 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
reports, check_ctxt_rna, settings)
# And parse keymaps!
from bpy_extras.keyconfig_utils import KM_HIERARCHY
walk_keymap_hierarchy(KM_HIERARCHY, "KM_HIERARCHY")
from bpy_extras.keyconfig_utils import km_hierarchy
walk_keymap_hierarchy(km_hierarchy(), "KM_HIERARCHY")
##### Python source code #####

View File

@ -18,12 +18,36 @@
# <pep8 compliant>
def _km_expand_from_toolsystem(space_type, context_mode):
def _fn():
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
for cls in ToolSelectPanelHelper.__subclasses__():
if cls.bl_space_type == space_type:
return cls.keymap_ui_hierarchy(context_mode)
raise Exception("keymap not found")
return _fn
def _km_hierarchy_iter_recursive(items):
for sub in items:
if callable(sub):
yield from sub()
else:
yield (*sub[:3], list(_km_hierarchy_iter_recursive(sub[3])))
def km_hierarchy():
return list(_km_hierarchy_iter_recursive(_km_hierarchy))
# bpy.type.KeyMap: (km.name, km.space_type, km.region_type, [...])
# ('Script', 'EMPTY', 'WINDOW', []),
KM_HIERARCHY = [
# Access via 'km_hierarchy'.
_km_hierarchy = [
('Window', 'EMPTY', 'WINDOW', []), # file save, window change, exit
('Screen', 'EMPTY', 'WINDOW', [ # full screen, undo, screenshot
('Screen Editing', 'EMPTY', 'WINDOW', []), # re-sizing, action corners
@ -36,24 +60,51 @@ KM_HIERARCHY = [
('User Interface', 'EMPTY', 'WINDOW', []),
('3D View', 'VIEW_3D', 'WINDOW', [ # view 3d navigation and generic stuff (select, transform)
('Object Mode', 'EMPTY', 'WINDOW', []),
('Mesh', 'EMPTY', 'WINDOW', []),
('Curve', 'EMPTY', 'WINDOW', []),
('Armature', 'EMPTY', 'WINDOW', []),
('Metaball', 'EMPTY', 'WINDOW', []),
('Lattice', 'EMPTY', 'WINDOW', []),
('Font', 'EMPTY', 'WINDOW', []),
('Object Mode', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'OBJECT'),
]),
('Mesh', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'EDIT_MESH'),
]),
('Curve', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'EDIT_CURVE'),
]),
('Armature', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'EDIT_ARMATURE'),
]),
('Metaball', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'EDIT_METABALL'),
]),
('Lattice', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'EDIT_LATTICE'),
]),
('Font', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'EDIT_TEXT'),
]),
('Pose', 'EMPTY', 'WINDOW', []),
('Pose', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'POSE'),
]),
('Vertex Paint', 'EMPTY', 'WINDOW', []),
('Weight Paint', 'EMPTY', 'WINDOW', []),
('Vertex Paint', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'PAINT_VERTEX'),
]),
('Weight Paint', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'PAINT_WEIGHT'),
]),
('Weight Paint Vertex Selection', 'EMPTY', 'WINDOW', []),
('Face Mask', 'EMPTY', 'WINDOW', []),
('Image Paint', 'EMPTY', 'WINDOW', []), # image and view3d
('Sculpt', 'EMPTY', 'WINDOW', []),
# image and view3d
('Image Paint', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'PAINT_TEXTURE'),
]),
('Sculpt', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'SCULPT'),
]),
('Particle', 'EMPTY', 'WINDOW', []),
('Particle', 'EMPTY', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', 'PARTICLE'),
]),
('Knife Tool Modal Map', 'EMPTY', 'WINDOW', []),
('Custom Normals Modal Map', 'EMPTY', 'WINDOW', []),
@ -69,7 +120,10 @@ KM_HIERARCHY = [
('View3D Zoom Modal', 'EMPTY', 'WINDOW', []),
('View3D Dolly Modal', 'EMPTY', 'WINDOW', []),
('3D View Generic', 'VIEW_3D', 'WINDOW', []), # toolbar and properties
# toolbar and properties
('3D View Generic', 'VIEW_3D', 'WINDOW', [
_km_expand_from_toolsystem('VIEW_3D', None),
]),
]),
('Graph Editor', 'GRAPH_EDITOR', 'WINDOW', [
@ -88,7 +142,9 @@ KM_HIERARCHY = [
('UV Editor', 'EMPTY', 'WINDOW', []), # image (reverse order, UVEdit before Image)
('Image Paint', 'EMPTY', 'WINDOW', []), # image and view3d
('UV Sculpt', 'EMPTY', 'WINDOW', []),
('Image Generic', 'IMAGE_EDITOR', 'WINDOW', []),
('Image Generic', 'IMAGE_EDITOR', 'WINDOW', [
_km_expand_from_toolsystem('IMAGE_EDITOR', None),
]),
]),
('Outliner', 'OUTLINER', 'WINDOW', []),
@ -410,7 +466,7 @@ def keyconfig_test(kc):
# Function body
result = False
for entry in KM_HIERARCHY:
for entry in km_hierarchy():
if testEntry(kc, entry):
result = True
return result

View File

@ -356,7 +356,7 @@ def draw_filtered(display_keymaps, filter_type, filter_text, layout):
def draw_hierarchy(display_keymaps, layout):
from bpy_extras import keyconfig_utils
for entry in keyconfig_utils.KM_HIERARCHY:
for entry in keyconfig_utils.km_hierarchy():
draw_entry(display_keymaps, entry, layout)

View File

@ -302,25 +302,32 @@ class ToolSelectPanelHelper:
return context.button_operator.name
@classmethod
def _km_action_simple(cls, kc, context_mode, text, keymap_fn):
if context_mode is None:
context_mode = "All"
km_idname = f"{cls.keymap_prefix:s} {context_mode:s}, {text:s}"
def _km_action_simple(cls, kc, context_descr, text, keymap_fn):
km_idname = f"{cls.keymap_prefix:s} {context_descr:s}, {text:s}"
km = kc.keymaps.get(km_idname)
if km is None:
km = kc.keymaps.new(km_idname, space_type=cls.bl_space_type, region_type='WINDOW')
keymap_fn[0](km)
keymap_fn[0] = km
# Special internal function, gives use items that contain keymaps.
@staticmethod
def _tools_flatten_with_keymap(tools):
for item_parent in tools:
if item_parent is None:
continue
for item in item_parent if (type(item_parent) is tuple) else (item_parent,):
# skip None or generator function
if item is None or _item_is_fn(item):
continue
if item.keymap is not None:
yield item
@classmethod
def register(cls):
wm = bpy.context.window_manager
# XXX, should we be manipulating the user-keyconfig on load?
# Perhaps this should only add when keymap items don't already exist.
#
# This needs some careful consideration.
kc = wm.keyconfigs.user
# Write into defaults, users may modify in preferences.
kc = wm.keyconfigs.default
# Track which tool-group was last used for non-active groups.
# Blender stores the active tool-group index.
@ -333,17 +340,26 @@ class ToolSelectPanelHelper:
return
for context_mode, tools in cls.tools_all():
for item_parent in tools:
if item_parent is None:
continue
for item in item_parent if (type(item_parent) is tuple) else (item_parent,):
# skip None or generator function
if item is None or _item_is_fn(item):
continue
keymap_data = item.keymap
if keymap_data is not None and callable(keymap_data[0]):
text = item.text
cls._km_action_simple(kc, context_mode, text, keymap_data)
if context_mode is None:
context_descr = "All"
else:
context_descr = context_mode.replace("_", " ").title()
for item in cls._tools_flatten_with_keymap(tools):
keymap_data = item.keymap
if callable(keymap_data[0]):
text = item.text
cls._km_action_simple(kc, context_descr, text, keymap_data)
@classmethod
def keymap_ui_hierarchy(cls, context_mode):
# See: bpy_extras.keyconfig_utils
for context_mode_test, tools in cls.tools_all():
if context_mode_test == context_mode:
for item in cls._tools_flatten_with_keymap(tools):
km = item.keymap[0]
# print((km.name, cls.bl_space_type, 'WINDOW', []))
yield (km.name, cls.bl_space_type, 'WINDOW', [])
# -------------------------------------------------------------------------
# Layout Generators

View File

@ -27,12 +27,12 @@ from bpy_extras import keyconfig_utils
def check_maps():
maps = {}
def fill_maps(ls):
for km_name, km_space_type, km_region_type, km_sub in ls:
def fill_maps(seq):
for km_name, km_space_type, km_region_type, km_sub in seq:
maps[km_name] = (km_space_type, km_region_type)
fill_maps(km_sub)
fill_maps(keyconfig_utils.KM_HIERARCHY)
fill_maps(keyconfig_utils.km_hierarchy())
import bpy
keyconf = bpy.context.window_manager.keyconfigs.active