├── .gitignore ├── CHANGELOG.md ├── README.md └── __init__.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | *.py[cod] -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # changelog 2 | 3 | 1.3.0 - 2021-10-30: 4 | 5 | - fix: bad mode in for snap selection to cursor / cursor to selected for Grease Pencil 6 | - code: converted to multifile addons and added Changelog 7 | - code: transfered 2.79 version to another repo 8 | 9 | 1.2.1 - 2020-12-20: 10 | 11 | - fix: keymap unregister 12 | 13 | 1.2.0 - 2020-12-16: 14 | 15 | - new shortcut: jump prev/next marker with `shift+alt+mouse4/5` (in every editor) 16 | 17 | 1.1.1 - 2020-11-28: 18 | 19 | - feat: added cursor to selected and selection to cursor for grease pencil 20 | - fix: Bug in keymap register that could affect other addon's keymap 21 | - better UI for infos in addon prefs 22 | - readme: changelog formating updated 23 | 24 | 1.0.0 - 13-09-2019: 25 | 26 | - invert preference work only on the focus/view all shortcut 27 | - fixed bug with keyframe jumping 28 | - new shortcut : move origin point 29 | 30 | 0.0.9 - 02-06-2019: 31 | 32 | - full change of keymap setting: 33 | - inverting default shortchut to a more logical setup (prev = going back, next = going to). 34 | - suppressing all preferences that overcomplicated the addon, letting only the possibility to invert everything (maybe delete even this one later). 35 | 36 | 0.0.8 - 19-02-2019: 37 | 38 | - 2.8 version 39 | 40 | 0.0.7 - 05-06-2018: 41 | 42 | - Added Alt combo to jump keyframe 43 | 44 | 0.0.5 - 22-04-2018: 45 | 46 | - Fix bad keymap unregister 47 | - Added modifiers functions: 48 | - Shift combo : cursor to selection and selection to cursor 49 | - Ctrl combo : access alternative view tweak 50 | 51 | 0.0.3 - 14-04-2018: 52 | 53 | - By default shortcuts are now completely consistent (view_selected and view all everywhere) 54 | - added addon preferences to invert buttons and customize shortcut in 3D view. 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MyKeyMouse 2 | Blender keymapper addon - Map shortcuts on mouse button 4 and 5 for mouse with additional buttons. 3 | 4 | **[Download latest](https://github.com/Pullusb/MyKeyMouse/archive/refs/heads/master.zip)** (right click, save Target as) 5 | 6 | For older blender 2.7 version go [here](https://github.com/Pullusb/SB_blender_addons_old_2_7) 7 | 8 | If you want to support me, you can buy things on my [gumroad](https://pullusb.gumroad.com) or [blender market](https://blendermarket.com/creators/pullup) pages (other mean to support [here](http://www.samuelbernou.fr/donate)). 9 | 10 | -------- 11 | 12 | ### Description 13 | 14 | Add '*view selection*' and '*view all*' shortcuts on mouse. 15 | 16 | Keymapp a list of shortcut for almost all editor where: 17 | - *mouse button 4* (often used as 'previous' action) is used to "get back", fit all elements in view. (like *home* button) 18 | - *mouse button 5* (often used as 'next' action) is used to "go to", focus on selected items. (like *numpad period* button) 19 | 20 | In the addons preferences you can choose to invert (button 4 to focus and button 5 to view all) : 21 | 22 | It does NOT affect any original shortcut on keyboard. 23 |
24 | Usual location of button 4 and 5 on a mouse with basic extra buttons (this may vary a lot on different device) 25 | 26 | ![mouse with additional buttons 4 and 5](https://github.com/Pullusb/images_repo/blob/master/Mouse_button-4-5_zoom.png) 27 | 28 | 29 | ### Why ? 30 | The location of *home* key and *numpad period* are far from both hands and force you to quit temporarily your rest positions, tending to break the workflow fluidity. 31 |
32 | 33 | ### Other added keymaps 34 | 35 | - *Ctrl + mouse button 5* Toggle isolate selection (*numpad slash* button) 36 |
37 | 38 | - *Shift + mouse button 4* Snap 3D cursor to selection 39 | - *Shift + mouse button 5* Snap selection to 3D cursor 40 |
41 | 42 | - *Alt + mouse button 4* Jump to previous keyframe 43 | - *Alt + mouse button 5* Jump to next keyframe 44 |
45 | 46 | - *Alt + Shift + mouse button 4* Jump to previous Marker 47 | - *Alt + Shift + mouse button 5* Jump to next Marker 48 |
49 | 50 | - *Ctrl + Shift + alt + mouse mouse button 4* Origin to geometry 51 | - *Ctrl + Shift + alt + mouse mouse button 5* Origin to cursor 52 |
53 | 54 | 58 | 59 | Thanks to [Vincent Lamy for the base idea](https://www.nothing-is-3d.com/article22/blender-utiliser-les-boutons-lateraux-de-la-souris) 60 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- 1 | bl_info = { 2 | "name": "MyKeyMouse", 3 | "description": "Add 'view selected' and 'view all' actions to mouse buttons 4 and 5", 4 | "author": "Samuel Bernou", 5 | "version": (1, 3, 0), 6 | "blender": (2, 80, 0), 7 | "location": "Mouse button 4 (usually 'previous') and 5 (usually 'next') on almost all editors", 8 | "warning": "", 9 | "doc_url": "https://github.com/Pullusb/MyKeyMouse", 10 | "category": "Object" } 11 | 12 | import bpy 13 | import os 14 | 15 | #keymap focus view selected (numpad_period) to mouse button 4 on all related editors 16 | #keymap view all (home key) to mouse button 5 on all related editors 17 | 18 | #customisation 19 | #3D view only : 20 | # Button 4 can view center pick on mouse instead (really a mouse related shortcut) 21 | # Button 5 can do local view instead (already have shit+C accessible for view all) 22 | 23 | 24 | addon_keymaps = [] 25 | def register_keymaps(): 26 | preferences = bpy.context.preferences 27 | addon_prefs = preferences.addons[__name__].preferences 28 | 29 | #mouse 4 and 5 often correspond to previous and next on mouse device 30 | key_prev = "BUTTON4MOUSE"#prev 31 | key_next = "BUTTON5MOUSE"#next 32 | 33 | if addon_prefs.mkmouse_invert_focus == True: 34 | key_focus = "BUTTON4MOUSE" 35 | key_home = "BUTTON5MOUSE" 36 | else:#default 37 | key_focus = "BUTTON5MOUSE" 38 | key_home = "BUTTON4MOUSE" 39 | 40 | shortcuts_items = [ 41 | 42 | ##button 4 - focus selection 43 | ["3D View", "VIEW_3D", "view3d.view_selected", key_focus], 44 | ["Graph Editor", "GRAPH_EDITOR", "graph.view_selected", key_focus], 45 | ["Dopesheet", 'DOPESHEET_EDITOR', "action.view_selected", key_focus], 46 | ["Sequencer", 'SEQUENCE_EDITOR', "sequencer.view_selected", key_focus], 47 | ["Node Editor", "NODE_EDITOR", "node.view_selected", key_focus], 48 | ["NLA Editor", "NLA_EDITOR", "nla.view_selected", key_focus], 49 | ["Clip Editor", "CLIP_EDITOR", "clip.view_selected", key_focus], 50 | ["Image", "IMAGE_EDITOR", "image.view_selected", key_focus], 51 | ["Outliner", "OUTLINER", "outliner.show_active", key_focus], 52 | 53 | ##button 5 - view all 54 | ["3D View", "VIEW_3D", "view3d.view_all", key_home], 55 | ["Graph Editor", "GRAPH_EDITOR", "graph.view_all", key_home], 56 | ["Image", "IMAGE_EDITOR", "image.view_all", key_home], 57 | ["Node Editor", "NODE_EDITOR", "node.view_all", key_home], 58 | ["Dopesheet", "DOPESHEET_EDITOR", "action.view_all", key_home], 59 | ["NLA Editor", "NLA_EDITOR", "nla.view_all", key_home], 60 | ["Sequencer", "SEQUENCE_EDITOR", "sequencer.view_all", key_home], 61 | ["SequencerPreview", "SEQUENCE_EDITOR", "sequencer.view_all_preview", key_home], 62 | ["Clip Editor", "CLIP_EDITOR", "clip.view_all", key_home], 63 | ["Clip Graph Editor", "CLIP_EDITOR", "clip.graph_view_all", key_home], 64 | ["Clip Dopesheet Editor", "CLIP_EDITOR", "clip.dopesheet_view_all", key_home], 65 | 66 | #not exists anymore in 2.8 67 | # ["Timeline", "TIMELINE", "time.view_all", key_home], 68 | #["Logic Editor", "LOGIC_EDITOR", "logic.view_all", key_home], 69 | 70 | ] 71 | 72 | shortcuts_items.append(["3D View", "VIEW_3D", "view3d.localview", key_next, True, False, False]) 73 | 74 | # Snapping utility with shift (cursor to selection and selection to selected) 75 | shortcuts_items.append(["3D View", "VIEW_3D", "view3d.snap_cursor_to_selected", key_prev, False, True, False]) 76 | shortcuts_items.append(["3D View", "VIEW_3D", "view3d.snap_selected_to_cursor", key_next, False, True, False]) 77 | 78 | # Same with GPencil (that have a different operator) 79 | shortcuts_items.append(["Grease Pencil Stroke Edit Mode", "EMPTY", "gpencil.snap_cursor_to_selected", key_prev, False, True, False]) 80 | shortcuts_items.append(["Grease Pencil Stroke Edit Mode", "EMPTY", "gpencil.snap_to_cursor", key_next, False, True, False]) 81 | 82 | 83 | ## 2.79 : 3D view > keymap view center pick on mouse (Alt+F) Changed to 'alt + MMB' to match early 2.8 settings 84 | #if LooseVersion(str(bpy.app.version)) < LooseVersion('(2, 80, 0)'):#only set for 2.79 85 | # shortcuts_items.append(["3D View", "VIEW_3D", "view3d.view_center_pick", "MIDDLEMOUSE", False, False, True]) 86 | 87 | ## appending all keymap from above list 88 | addon = bpy.context.window_manager.keyconfigs.addon 89 | for item in shortcuts_items: 90 | #print(item)# printing items for debug 91 | km = addon.keymaps.new(name = item[0], space_type = item[1]) 92 | if len(item) > 4:#contain modifiers keys 93 | kmi = km.keymap_items.new(item[2], type = item[3], value = "PRESS", ctrl=item[4], shift=item[5],alt=item[6]) 94 | else: 95 | kmi = km.keymap_items.new(item[2], type = item[3], value = "PRESS") 96 | 97 | # print(item[2],'-->', kmi) 98 | addon_keymaps.append((km, kmi)) 99 | 100 | # Moving origin point utility, cursor/geometry. (hold properties) 101 | km = addon.keymaps.new(name = "3D View", space_type = "VIEW_3D") 102 | kmi = km.keymap_items.new("object.origin_set", type = key_next, value = "PRESS", ctrl = True, shift = True, alt = True) 103 | kmi.properties.type = 'ORIGIN_CURSOR' 104 | addon_keymaps.append((km, kmi)) 105 | 106 | kmi = km.keymap_items.new("object.origin_set", type = key_prev, value = "PRESS", ctrl = True, shift = True, alt = True) 107 | kmi.properties.type = 'ORIGIN_GEOMETRY' 108 | addon_keymaps.append((km, kmi)) 109 | 110 | # Combo keyframe jump with alt special case (hold properties). Button BUTTON6MOUSE et 7 not working with logitech software... 111 | km = addon.keymaps.new(name = "Window", space_type = "EMPTY") 112 | kmi = km.keymap_items.new("screen.keyframe_jump", type = key_prev, value = "PRESS", alt = True) 113 | kmi.properties.next = False 114 | addon_keymaps.append((km, kmi)) 115 | 116 | kmi = km.keymap_items.new("screen.keyframe_jump", type = key_next, value = "PRESS", alt = True) 117 | kmi.properties.next = True 118 | addon_keymaps.append((km, kmi)) 119 | 120 | ## jump to marker 121 | kmi = km.keymap_items.new("screen.marker_jump", type = key_prev, value = "PRESS", alt = True, shift = True) 122 | kmi.properties.next = False 123 | addon_keymaps.append((km, kmi)) 124 | 125 | kmi = km.keymap_items.new("screen.marker_jump", type = key_next, value = "PRESS", alt = True, shift = True) 126 | kmi.properties.next = True 127 | addon_keymaps.append((km, kmi)) 128 | 129 | ###---user pref 130 | 131 | class My_key_mouse_addon_pref(bpy.types.AddonPreferences): 132 | bl_idname = __name__ 133 | 134 | mkmouse_invert_focus : bpy.props.BoolProperty( 135 | name="Invert (prev button = view selected, next button = view all. (Save prefs and restart Blender to apply changes)", 136 | default=False, 137 | ) 138 | ''' 139 | mkmouse_viewport_local_view : bpy.props.BoolProperty( 140 | name="Use local view (instead of view all)", 141 | default=False, 142 | )#"Use local view (like numpad slash) instead of view all (else combine ctrl)" 143 | mkmouse_viewport_center_on_mouse : bpy.props.BoolProperty( 144 | name="Use centering view on mouse (instead of view selected)", 145 | default=False, 146 | )#"Use centering view on mouse (like Alt+F) instead of view selected (else combine ctrl)" 147 | ''' 148 | 149 | def draw(self, context): 150 | layout = self.layout 151 | box = layout.box() 152 | 153 | box.label( 154 | text="Focus control (all editor) :") 155 | box.label( 156 | text="mouse Prev button = view all") 157 | box.label( 158 | text="mouse Next button = view selected") 159 | # box.label(text="Customization ") 160 | box.prop(self, "mkmouse_invert_focus") 161 | 162 | 163 | box = layout.box() 164 | box.label(text="Only in 3D viewport:") 165 | box.label(text="Ctrl + mouse Next button = Use local view (like numpad slash)") 166 | #box.label(text="Ctrl + mouse Prev button = Unnassigned") 167 | # layout.separator() 168 | box.label(text="Cursor Snapping:") 169 | box.label(text="Shift + mouse Prev button = 3D cursor to selection") 170 | box.label(text="Shift + mouse Next button = selection to 3D cursor") 171 | # layout.separator() 172 | box.label(text="Origin change:") 173 | box.label(text="Ctrl + Shift + alt + mouse Prev button = Origin to geometry") 174 | box.label(text="Ctrl + Shift + alt + mouse Next button = Origin to cursor") 175 | 176 | # layout.label(text="Alt + middle mouse button = centering view on mouse (default shortcut in 2.8) as with Alt+F ") 177 | 178 | box = layout.box() 179 | box.label(text="Timeline related (all editor):") 180 | box.label(text="Alt + mouse Prev button = jump to prev keyframe") 181 | box.label(text="Alt + mouse Next button = jump to next keyframe") 182 | 183 | box.label(text="Alt + Shift + mouse Prev button = jump to prev marker") 184 | box.label(text="Alt + Shift + mouse Next button = jump to next marker") 185 | 186 | ''' 187 | layout.label( 188 | text="Options to swap calls in 3D viewport (accessible with 'ctrl' modifier):") 189 | layout.prop(self, "mkmouse_viewport_center_on_mouse") 190 | layout.prop(self, "mkmouse_viewport_local_view") 191 | ''' 192 | 193 | def unregister_keymaps(): 194 | # wm = bpy.context.window_manager 195 | for km, kmi in addon_keymaps: 196 | km.keymap_items.remove(kmi) 197 | addon_keymaps.clear() 198 | 199 | 200 | ## note : register via bpy.utils.register_module(__name__) Fails ! 201 | ## addons prefs isn't loaded when keymap_register try to access it. 202 | 203 | def register(): 204 | if bpy.app.background: 205 | return 206 | bpy.utils.register_class(My_key_mouse_addon_pref) 207 | register_keymaps() 208 | 209 | def unregister(): 210 | if bpy.app.background: 211 | return 212 | unregister_keymaps() 213 | bpy.utils.unregister_class(My_key_mouse_addon_pref) 214 | 215 | if __name__ == "__main__": 216 | register() 217 | --------------------------------------------------------------------------------