Skip to content

Commit 6bd8abe

Browse files
Merge pull request #58 from roguesleipnir/mmb_switch2
Implemented Right Click Drag Navigation with Modifiers
2 parents 62b1bef + 53b9af2 commit 6bd8abe

3 files changed

Lines changed: 229 additions & 10 deletions

File tree

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Maps Blender's Walk/Fly Navigation to the Right Mouse Button in addition to the
77

88
It also (optionally) maps the Node Editor's Pan View and Add/Search Node Menu to the Right Mouse Button.
99

10+
It also (optionally) can remap the Middle Mouse Button 3D View controls to Right Mouse Button to match other 3D software.
11+
1012
[![Install and Use](https://img.youtube.com/vi/wIEsuaaS-Hw/0.jpg)](https://www.youtube.com/watch?v=wIEsuaaS-Hw)
1113

1214
## How to Install
@@ -47,6 +49,23 @@ Additionally, in the settings, you can change the cursor resetting behavior. By
4749

4850
You can enable/disable Node Editor mode in the Preferences.
4951

52+
#### Switching default Middle Mouse 3D View Controls to Right Mouse
53+
To match other 3D software, the Middle Mouse 3D View camera controls can also be switched to use the Right Mouse instead:
54+
- Shift + Drag RMB to Pan 3D View
55+
- Ctrl + Drag RMB to Zoom 3D View
56+
- Ctrl + Shift + Drag RMB to Dolly Zoom 3D View
57+
- Alt + Drag RMB to Rotate 3D View
58+
59+
Other controls that were switched to Middle Mouse:
60+
- Shift + Click MMB to Set 3D Cursor
61+
- Shift + Drag MMB to Transform Translate
62+
- Ctrl + Drag MMB to Lasso Selection
63+
- Shift + Ctrl + Drag MMB to Lasso Deselection
64+
65+
There is also a setting to switch the activation of Right Mouse Navigation mode and the 3D View Rotate keymapping:
66+
- Drag + RMB will now Rotate 3D View
67+
- Alt + RMB then WASD for Navigation Mode
68+
5069
## Acknowledgements and Thanks
5170

5271
Big thanks to __Biaru__ and __NathanC__ for their contributions to the code!

__init__.py

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
RMN_OT_toggle_cam_navigation,
66
)
77
from .preferences import RightMouseNavigationPreferences
8+
from bpy.app.handlers import persistent
89

910
addon_keymaps = []
1011
menumodes = [
@@ -30,7 +31,7 @@
3031
]
3132

3233

33-
def register_keymaps(menumodes, panelmodes, keyconfig):
34+
def register_keymaps(menumodes, panelmodes, keyconfig):
3435
# These Modes all call standard menus
3536
# "Object Mode", "Mesh", "Curve", "Armature", "Metaball", "Lattice",
3637
# "Font", "Pose"
@@ -60,21 +61,23 @@ def register_keymaps(menumodes, panelmodes, keyconfig):
6061
key.value = "RELEASE"
6162

6263

63-
def unregister_keymaps(menumodes, panelmodes, keyconfig):
64+
def unregister_keymaps(menumodes, panelmodes, keyconfig):
6465
# Reactivating menus
6566
# "Object Mode", "Mesh", "Curve", "Armature", "Metaball", "Lattice",
6667
# "Font", "Pose"
6768
for i in menumodes:
6869
for key in keyconfig.keymaps[i].keymap_items:
6970
if key.idname == "wm.call_menu" and key.type == "RIGHTMOUSE":
7071
key.active = True
72+
key.value = "PRESS"
7173

7274
# Reactivating panels
7375
# "Vertex Paint", "Weight Paint", "Image Paint", "Sculpt"
7476
for i in panelmodes:
7577
for key in keyconfig.keymaps[i].keymap_items:
7678
if key.idname == "wm.call_panel" and key.type == "RIGHTMOUSE":
7779
key.active = True
80+
key.value = "PRESS"
7881

7982
# Changing the Walk Modal Map back
8083
for key in keyconfig.keymaps["View3D Walk Modal"].keymap_items:
@@ -86,11 +89,22 @@ def unregister_keymaps(menumodes, panelmodes, keyconfig):
8689
key.value = "PRESS"
8790

8891

92+
def rebind_rmb(scene):
93+
# Preferences can only be checked after register
94+
addon_prefs = bpy.context.preferences.addons[__package__].preferences
95+
addon_prefs.menumodes = menumodes
96+
addon_prefs.panelmodes = panelmodes
97+
addon_prefs.rebind_3dview_keymap(bpy.context, addon_prefs.rmb_pan_rotate)
98+
addon_prefs.rebind_switch_nav_rotate(bpy.context, addon_prefs.rmb_rotate_switch)
99+
100+
89101
def register():
102+
bpy.app.handlers.load_post.append(rebind_rmb)
103+
104+
for cls in classes:
105+
bpy.utils.register_class(cls)
106+
90107
if not bpy.app.background:
91-
for cls in classes:
92-
bpy.utils.register_class(cls)
93-
94108
wm = bpy.context.window_manager
95109
addon_kc = wm.keyconfigs.addon
96110

@@ -144,9 +158,16 @@ def register():
144158

145159

146160
def unregister():
161+
bpy.app.handlers.load_post.remove(rebind_rmb)
162+
163+
addon_prefs = bpy.context.preferences.addons[__package__].preferences
164+
addon_prefs.rebind_switch_nav_rotate(bpy.context, False)
165+
addon_prefs.rebind_3dview_keymap(bpy.context, False)
166+
167+
for cls in classes:
168+
bpy.utils.unregister_class(cls)
169+
147170
if not bpy.app.background:
148-
for cls in classes:
149-
bpy.utils.unregister_class(cls)
150171

151172
wm = bpy.context.window_manager
152173

@@ -172,7 +193,7 @@ def unregister():
172193
panelmodes=panelmodes,
173194
keyconfig=user_keyconfig,
174195
)
175-
196+
176197
addon_kc = wm.keyconfigs.addon
177198
# Remove only the keymap items that this addon registered
178199
for km, kmi_orig in addon_keymaps:
@@ -183,7 +204,7 @@ def unregister():
183204
f"[Right Mouse Navigation] Could not remove keymap item {getattr(kmi_orig, 'idname', 'unknown')} from {km.name}: {e}"
184205
)
185206
addon_keymaps.clear()
186-
187-
207+
208+
188209
if __name__ == "__main__":
189210
register()

preferences.py

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
)
77
from bpy.types import AddonPreferences
88

9+
menumodes = []
10+
panelmodes = []
911

1012
def draw_cam_lock(self, context):
1113
preferences = context.preferences
@@ -64,6 +66,14 @@ def update_node_keymap(self, context):
6466
key.active = addon_prefs.enable_for_node_editors
6567

6668

69+
def update_rebind_3dview_keymap(self, context):
70+
self.rebind_3dview_keymap(context, self.rmb_pan_rotate)
71+
72+
73+
def update_rebind_switch_nav_rotate(self, context):
74+
self.rebind_switch_nav_rotate(context, self.rmb_rotate_switch)
75+
76+
6777
class RightMouseNavigationPreferences(AddonPreferences):
6878
bl_idname = __package__
6979

@@ -118,7 +128,151 @@ class RightMouseNavigationPreferences(AddonPreferences):
118128
default=False,
119129
update=cam_lock_update,
120130
)
131+
132+
rmb_pan_rotate: BoolProperty(
133+
name="Switch MMB and RMB Drag Camera Navigation",
134+
description="Switches Camera Navigation controls to Right Mouse Button.",
135+
default=False,
136+
update=update_rebind_3dview_keymap,
137+
)
121138

139+
rmb_rotate_switch: BoolProperty(
140+
name="Use Alt to enter Right Mouse Navigation with WASD",
141+
description="Switches RMB Navigation and drag Rotation controls with Alt modifier.",
142+
default=False,
143+
update=update_rebind_switch_nav_rotate,
144+
)
145+
146+
147+
def rebind_3dview_keymap(self, context, isActive):
148+
wm = context.window_manager
149+
active_kc = wm.keyconfigs.active
150+
addon_kc = wm.keyconfigs.addon
151+
152+
if (isActive):
153+
for key in active_kc.keymaps["3D View"].keymap_items:
154+
if (key.idname == "view3d.cursor3d" and key.type == "RIGHTMOUSE"):
155+
key.type = "MIDDLEMOUSE"
156+
key.value = "CLICK"
157+
key.shift = True
158+
if (key.idname == "view3d.rotate" and key.type == "MIDDLEMOUSE"):
159+
key.type = "RIGHTMOUSE"
160+
key.value = "CLICK_DRAG"
161+
key.alt = True
162+
if (key.idname == "view3d.move" and key.type == "MIDDLEMOUSE"):
163+
key.type = "RIGHTMOUSE"
164+
key.value = "CLICK_DRAG"
165+
key.shift = True
166+
if (key.idname == "view3d.zoom" and key.type == "MIDDLEMOUSE"):
167+
key.type = "RIGHTMOUSE"
168+
key.value = "CLICK_DRAG"
169+
key.ctrl = True
170+
if (key.idname == "view3d.dolly" and key.type == "MIDDLEMOUSE"):
171+
key.type = "RIGHTMOUSE"
172+
key.value = "CLICK_DRAG"
173+
key.shift = True
174+
key.ctrl = True
175+
if (key.idname == "view3d.select_lasso" and key.type == "RIGHTMOUSE" and key.ctrl == True):
176+
key.type = "MIDDLEMOUSE"
177+
key.value = "CLICK_DRAG"
178+
key.ctrl = True
179+
if (key.idname == "view3d.select_lasso" and key.type == "RIGHTMOUSE" and key.ctrl == True and key.shift == True):
180+
key.type = "MIDDLEMOUSE"
181+
key.value = "CLICK_DRAG"
182+
key.shift = True
183+
key.ctrl = True
184+
if (key.idname == "transform.translate" and key.type == "RIGHTMOUSE"):
185+
key.type = "MIDDLEMOUSE"
186+
else:
187+
for key in active_kc.keymaps["3D View"].keymap_items:
188+
if (key.idname == "view3d.cursor3d" and key.type == "MIDDLEMOUSE"):
189+
key.type = "RIGHTMOUSE"
190+
key.value = "CLICK"
191+
key.shift = True
192+
if (key.idname == "view3d.rotate" and key.type == "RIGHTMOUSE"):
193+
key.type = "MIDDLEMOUSE"
194+
key.value = "PRESS"
195+
key.alt = False
196+
if (key.idname == "view3d.move" and key.type == "RIGHTMOUSE"):
197+
key.type = "MIDDLEMOUSE"
198+
key.value = "PRESS"
199+
key.shift = True
200+
if (key.idname == "view3d.zoom" and key.type == "RIGHTMOUSE"):
201+
key.type = "MIDDLEMOUSE"
202+
key.value = "PRESS"
203+
key.ctrl = True
204+
if (key.idname == "view3d.dolly" and key.type == "RIGHTMOUSE"):
205+
key.type = "MIDDLEMOUSE"
206+
key.value = "PRESS"
207+
key.shift = True
208+
key.ctrl = True
209+
if (key.idname == "view3d.select_lasso" and key.type == "MIDDLEMOUSE" and key.ctrl == True):
210+
key.type = "RIGHTMOUSE"
211+
key.value = "CLICK_DRAG"
212+
key.ctrl = True
213+
if (key.idname == "view3d.select_lasso" and key.type == "MIDDLEMOUSE" and key.ctrl == True and key.shift == True):
214+
key.type = "RIGHTMOUSE"
215+
key.value = "CLICK_DRAG"
216+
key.shift = True
217+
key.ctrl = True
218+
if (key.idname == "transform.translate" and key.type == "MIDDLEMOUSE"):
219+
key.type = "RIGHTMOUSE"
220+
221+
222+
def rebind_switch_nav_rotate(self, context, isActive):
223+
wm = context.window_manager
224+
active_kc = wm.keyconfigs.active
225+
addon_kc = wm.keyconfigs.addon
226+
227+
if (isActive):
228+
for key in addon_kc.keymaps["3D View"].keymap_items:
229+
if (key.idname == "rmn.right_mouse_navigation"):
230+
key.type = "RIGHTMOUSE"
231+
key.value = "PRESS"
232+
key.alt = True
233+
for key in active_kc.keymaps["3D View"].keymap_items:
234+
if (key.idname == "view3d.rotate" and key.type == "RIGHTMOUSE"):
235+
key.type = "RIGHTMOUSE"
236+
key.value = "CLICK_DRAG"
237+
key.alt = False
238+
for i in menumodes:
239+
for key in active_kc.keymaps[i].keymap_items:
240+
if (
241+
key.idname == "wm.call_menu"
242+
and key.type == "RIGHTMOUSE"
243+
):
244+
key.active = True
245+
key.value = "CLICK"
246+
for i in panelmodes:
247+
for key in active_kc.keymaps[i].keymap_items:
248+
if key.idname == "wm.call_panel" and key.type == "RIGHTMOUSE" and key.active:
249+
key.active = False
250+
key.value = "CLICK"
251+
else:
252+
for key in addon_kc.keymaps["3D View"].keymap_items:
253+
if (key.idname == "rmn.right_mouse_navigation"):
254+
key.type = "RIGHTMOUSE"
255+
key.value = "PRESS"
256+
key.alt = False
257+
for key in active_kc.keymaps["3D View"].keymap_items:
258+
if (key.idname == "view3d.rotate" and key.type == "RIGHTMOUSE"):
259+
key.type = "RIGHTMOUSE"
260+
key.value = "CLICK_DRAG"
261+
key.alt = True
262+
for i in menumodes:
263+
for key in active_kc.keymaps[i].keymap_items:
264+
if (
265+
key.idname == "wm.call_menu"
266+
and key.type == "RIGHTMOUSE"
267+
):
268+
key.active = False
269+
key.value = "PRESS"
270+
for i in panelmodes:
271+
for key in active_kc.keymaps[i].keymap_items:
272+
if key.idname == "wm.call_panel" and key.type == "RIGHTMOUSE":
273+
key.active = True
274+
key.value = "PRESS"
275+
122276
def draw(self, context):
123277
layout = self.layout
124278

@@ -150,6 +304,31 @@ def draw(self, context):
150304
row.prop(self, "disable_camera_navigation")
151305
row.prop(self, "show_cam_lock_ui")
152306

307+
row = layout.row()
308+
box = row.box()
309+
box.label(text="Right Mouse Button Pan, Zoom, and Rotate", icon="VIEW3D")
310+
box.label(text="RMB Menus will be set to Click when these options are toggled.")
311+
box.prop(self, "rmb_pan_rotate")
312+
if self.rmb_pan_rotate:
313+
if not self.rmb_rotate_switch:
314+
box.label(text="Hold RMB then WASD for Navigation Mode")
315+
box.label(text="Alt + Drag RMB to Rotate 3D View")
316+
box.label(text="Shift + Drag RMB to Pan 3D View")
317+
box.label(text="Ctrl + Drag RMB to Zoom 3D View")
318+
box.label(text="Ctrl + Shift + Drag RMB to Dolly Zoom 3D View")
319+
box.label(text="Other controls swapped")
320+
box.label(text="Shift + Click MMB to Set 3D Cursor")
321+
box.label(text="Shift + Drag MMB to Transform Translate")
322+
box.label(text="Ctrl + Drag MMB to Lasso Selection")
323+
box.label(text="Shift + Ctrl + Drag MMB to Lasso Deselection")
324+
if (self.rmb_pan_rotate):
325+
box.prop(self, "rmb_rotate_switch")
326+
if self.rmb_rotate_switch:
327+
box.label(text="Drag + RMB will now Rotate 3D View")
328+
box.label(text="Alt + RMB then WASD for Navigation Mode")
329+
elif (not self.rmb_pan_rotate and self.rmb_rotate_switch):
330+
self.rmb_rotate_switch = False
331+
153332
# Keymap Customization
154333
import rna_keymap_ui
155334

0 commit comments

Comments
 (0)