Node Wrangler: another update for 2.8
[blender-addons.git] / space_view3d_display_tools / fast_navigate.py
blob5d61138a0fcf35a0e640a92f54505b73e1744b2b
1 # space_view_3d_display_tools.py Copyright (C) 2014, Jordi Vall-llovera
2 # Multiple display tools for fast navigate/interact with the viewport
4 # ##### BEGIN GPL LICENSE BLOCK #####
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software Foundation,
18 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 # ##### END GPL LICENCE BLOCK #####
22 """
23 Additional links:
24 Author Site: http://www.jordiart.com
25 """
27 import bpy
28 from bpy.types import Operator
29 from bpy.props import BoolProperty
30 from collections import defaultdict
33 # Fast Navigate toggle function
34 def trigger_fast_navigate(trigger):
35 scene = bpy.context.scene.display_tools
36 scene.FastNavigateStop = False
37 trigger = not trigger
40 # Control how to display particles during fast navigate
41 def display_particles(mode, dis_particles):
42 scene = bpy.context.scene.display_tools
44 for particles in bpy.data.particles:
45 if scene.ShowParticles is False:
46 particles.display_method = 'NONE'
47 else:
48 if particles.type == 'EMITTER':
49 particles.display_method = 'DOT'
50 particles.display_percentage = 100
51 else:
52 particles.display_method = 'RENDER'
53 particles.display_percentage = dis_particles
55 return dis_particles
58 # Fast Navigate operator
59 class FastNavigate(Operator):
60 bl_idname = "view3d.fast_navigate_operator"
61 bl_label = "Fast Navigate"
62 bl_description = ("Limit the objects drawing in the 3D view for faster navigation\n"
63 "Runs in modal mode until Stop is pressed or Esc, Return, Space")
65 trigger = BoolProperty(default=False)
66 mode = BoolProperty(default=False)
67 screen_width = [0, 0]
68 store_fail = False
69 store_init_particles = {}
70 store_viewport_shade = None
71 check_particles_draw = False
72 fast_particles_draw = 0
74 def modal(self, context, event):
75 context.area.tag_redraw()
76 scene = context.scene.display_tools
78 if scene.FastNavigateStop is True:
79 self.execute(context)
80 return {'FINISHED'}
82 if context.area.type != 'VIEW_3D':
83 self.execute(context)
84 return {'FINISHED'}
86 if scene.EditActive is True:
87 self.fast_navigate_stuff(context, event)
88 return {'PASS_THROUGH'}
89 else:
90 obj = context.active_object
91 if obj:
92 if obj.mode != 'EDIT':
93 self.fast_navigate_stuff(context, event)
94 return {'PASS_THROUGH'}
95 else:
96 return {'PASS_THROUGH'}
97 else:
98 self.fast_navigate_stuff(context, event)
99 return {'PASS_THROUGH'}
101 return {'RUNNING_MODAL'}
103 def invoke(self, context, event):
104 if context.area.type != 'VIEW_3D':
105 self.report({'WARNING'},
106 "Fast Navigate: View3D not found. Operation Cancelled")
107 return {'CANCELLED'}
109 self.store_init_particles = defaultdict(list)
110 self.store_fail = False
112 context.window_manager.modal_handler_add(self)
113 trigger_fast_navigate(self.trigger)
114 scene = context.scene.display_tools
115 scene.DelayTime = scene.DelayTimeGlobal
116 self.get_screen_size(context, scene)
117 self.start_settings_store(context, store=False)
118 self.check_particles_draw = True
120 return {'RUNNING_MODAL'}
122 def execute(self, context):
123 scene = context.scene.display_tools
124 scene.FastNavigateStop = True
126 self.start_settings_store(context, store=True)
128 mess, mess_txt = ('WARNING', "Fast Navigate: Some Settings could not be restored") if \
129 self.store_fail else ('INFO', "Exited the Fast Navigate mode")
131 self.report({mess}, mess_txt)
133 return {'FINISHED'}
135 @staticmethod
136 def calc_delay(scene):
137 if scene.Delay is True:
138 if scene.DelayTime < scene.DelayTimeGlobal:
139 scene.DelayTime += 1
141 def start_settings_store(self, context, store=False):
142 try:
143 view = context.space_data
144 shade = view.viewport_shade if view.type == 'VIEW_3D' else None
145 if store is False:
146 if not shade:
147 self.store_fail = True
148 else:
149 self.store_viewport_shade = shade
150 for particle in bpy.data.particles:
151 self.store_init_particles[particle.name] = \
152 [particle.display_method, particle.display_percentage]
153 else:
154 if not shade:
155 self.store_fail = True
156 else:
157 shade = self.store_viewport_shade or 'SOLID'
158 for particle in bpy.data.particles:
159 particle.display_method = self.store_init_particles[particle.name][0]
160 particle.display_percentage = self.store_init_particles[particle.name][1]
161 except:
162 self.store_fail = True
164 def get_screen_size(self, context, scene):
165 if context.area.type == 'VIEW_3D':
166 coord_x = context.area.x + scene.ScreenStart
167 coord_max_x = context.area.width - scene.ScreenEnd
168 self.screen_width = [coord_x, coord_max_x]
170 # Do repetitive fast navigate related stuff
171 def fast_navigate_stuff(self, context, event):
172 scene = context.scene.display_tools
173 view = context.space_data
175 if scene.FastNavigateStop is True:
176 return {'FINISHED'}
178 if context.area.type != 'VIEW_3D':
179 scene.FastNavigateStop = True
180 return {'FINISHED'}
182 if event.type in {'ESC', 'RET', 'SPACE'}:
183 scene.FastNavigateStop = True
184 return {'CANCELLED'}
186 # limit the active area
187 if event.mouse_x not in range(self.screen_width[0], self.screen_width[1]):
188 return {'PASS_THROUGH'}
190 # fast navigate while orbit/panning
191 if event.type == 'MIDDLEMOUSE':
192 self.calc_delay(scene)
193 view.viewport_shade = scene.FastMode
194 self.mode = False
196 # fast navigate while transform operations
197 if event.type in {'G', 'R', 'S'}:
198 self.calc_delay(scene)
199 view.viewport_shade = scene.FastMode
200 self.mode = False
202 # fast navigate while menu popups or duplicates
203 if event.type in {'W', 'D', 'L', 'U', 'I', 'M', 'A', 'B'}:
204 self.calc_delay(scene)
205 view.viewport_shade = scene.FastMode
206 self.mode = False
208 # fast navigate while numpad navigation
209 if event.type in {'NUMPAD_PERIOD', 'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3',
210 'NUMPAD_4', 'NUMPAD_5', 'NUMPAD_6', 'NUMPAD_7',
211 'NUMPAD_8', 'NUMPAD_9'}:
212 self.calc_delay(scene)
213 view.viewport_shade = scene.FastMode
214 self.mode = False
216 # fast navigate while zooming with mousewheel too
217 if event.type in {'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
218 scene.DelayTime = scene.DelayTimeGlobal
219 view.viewport_shade = scene.FastMode
220 self.mode = False
222 if event.type == 'MOUSEMOVE':
223 if scene.Delay is True:
224 if scene.DelayTime == 0:
225 view.viewport_shade = scene.OriginalMode
226 scene.DelayTime = scene.DelayTimeGlobal
227 self.mode = True
228 else:
229 view.viewport_shade = scene.OriginalMode
230 self.mode = True
232 if scene.Delay is True:
233 scene.DelayTime -= 1
234 if scene.DelayTime == 0:
235 view.viewport_shade = scene.OriginalMode
236 scene.DelayTime = scene.DelayTimeGlobal
237 self.mode = True
239 # update particles draw (only update call when the fast draw or the percentage are changed)
240 self.check_particles_draw = not self.mode
241 dis_particles = scene.InitialParticles if self.mode else scene.ParticlesPercentageDisplay
243 if self.check_particles_draw is True:
244 self.fast_particles_draw = display_particles(self.mode, dis_particles)
245 else:
246 if self.fast_particles_draw != dis_particles:
247 self.fast_particles_draw = display_particles(self.mode, dis_particles)
250 # Fast Navigate Stop
251 def fast_navigate_stop(context):
252 scene = context.scene.display_tools
253 scene.FastNavigateStop = True
256 # Fast Navigate Stop Operator
257 class FastNavigateStop(Operator):
258 bl_idname = "view3d.fast_navigate_stop"
259 bl_label = "Stop"
260 bl_description = "Stop Fast Navigate"
262 def execute(self, context):
263 fast_navigate_stop(context)
265 return {'FINISHED'}
268 # Register
269 def register():
270 bpy.utils.register_module(__name__)
273 def unregister():
274 bpy.utils.unregister_module(__name__)
277 if __name__ == "__main__":
278 register()