diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2017-04-08 12:06:44 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2017-04-08 12:09:11 +0300 |
commit | 1cd54ec225d9fd66bfed51b18bd5605f49ec1b07 (patch) | |
tree | dbbf065791e07f49739f1d5801d178190f11da78 /release/scripts/modules/bpy_extras | |
parent | 867d31130769b45c6f1b71ef619f247634ae890c (diff) |
Add helpers in bpy_extras.keyconfig_utils for addons to (un)register their keymaps.
Doing this in a fully 'clean' way is far from obvious, especially
unregister, you often end up leaving nasty 'orphanned' keymap items
referring to unregistered operators...
Diffstat (limited to 'release/scripts/modules/bpy_extras')
-rw-r--r-- | release/scripts/modules/bpy_extras/keyconfig_utils.py | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/release/scripts/modules/bpy_extras/keyconfig_utils.py b/release/scripts/modules/bpy_extras/keyconfig_utils.py index 6ecdd0c5e13..3203bc41b76 100644 --- a/release/scripts/modules/bpy_extras/keyconfig_utils.py +++ b/release/scripts/modules/bpy_extras/keyconfig_utils.py @@ -141,6 +141,78 @@ KM_HIERARCHY = [ # ----------------------------------------------------------------------------- +# Add-on helpers to properly (un)register their own keymaps. + +# Example of keymaps_description: +keymaps_description_doc = """ +keymaps_description is a tuple (((keymap_description), (tuple of keymap_item_descriptions))). +keymap_description is a tuple (name, space_type, region_type, is_modal). +keymap_item_description is a tuple ({kw_args_for_keymap_new}, (tuple of properties)). +kw_args_for_keymap_new is a mapping which keywords match parameters of keymap.new() function. +tuple of properties is a tuple of pairs (prop_name, prop_value) (properties being those of called operator). + +Example: + +KEYMAPS = ( + # First, keymap identifiers (last bool is True for modal km). + (('Sequencer', 'SEQUENCE_EDITOR', 'WINDOW', False), ( + # Then a tuple of keymap items, defined by a dict of kwargs for the km new func, and a tuple of tuples (name, val) + # for ops properties, if needing non-default values. + ({"idname": export_strips.SEQExportStrip.bl_idname, "type": 'P', "value": 'PRESS', "shift": True, "ctrl": True}, + ()), + )), +) +""" + + +def addon_keymap_register(wm, keymaps_description): + """ + Register a set of keymaps for addons. + + """ + keymaps_description_doc + kconf = wm.keyconfigs.addon + if not kconf: + return # happens in background mode... + for km_info, km_items in keymaps_description: + km_name, km_sptype, km_regtype, km_ismodal = km_info + kmap = [k for k in kconf.keymaps + if k.name == km_name and k.region_type == km_regtype and + k.space_type == km_sptype and k.is_modal == km_ismodal] + if kmap: + kmap = kmap[0] + else: + kmap = kconf.keymaps.new(km_name, region_type=km_regtype, space_type=km_sptype, modal=km_ismodal) + for kmi_kwargs, props in km_items: + kmi = kmap.keymap_items.new(**kmi_kwargs) + kmi.active = True + for prop, val in props: + setattr(kmi.properties, prop, val) + + +def addon_keymap_unregister(wm, keymaps_description): + """ + Unregister a set of keymaps for addons. + + """ + keymaps_description_doc + # NOTE: We must also clean up user keyconfig, else, if user has customized one of add-on's shortcut, this + # customization remains in memory, and comes back when re-enabling the addon, causing a segfault... :/ + kconfs = wm.keyconfigs + for kconf in (kconfs.user, kconfs.addon): + for km_info, km_items in keymaps_description: + km_name, km_sptype, km_regtype, km_ismodal = km_info + kmaps = (k for k in kconf.keymaps + if k.name == km_name and k.region_type == km_regtype and + k.space_type == km_sptype and k.is_modal == km_ismodal) + for kmap in kmaps: + for kmi_kwargs, props in km_items: + idname = kmi_kwargs["idname"] + for kmi in kmap.keymap_items: + if kmi.idname == idname: + kmap.keymap_items.remove(kmi) + # NOTE: We won't remove addons keymaps themselves, other addons might also use them! + + +# ----------------------------------------------------------------------------- # Utility functions def km_exists_in(km, export_keymaps): |