Disable anti-aliasing initialization, was causing GL_SELECT issues
[blender.git] / release / scripts / ui / space_userpref.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21
22 KM_HIERARCHY = [
23                     ('Window', 'EMPTY', 'WINDOW', []), # file save, window change, exit
24                     ('Screen', 'EMPTY', 'WINDOW', [    # full screen, undo, screenshot
25                         ('Screen Editing', 'EMPTY', 'WINDOW', []),    # resizing, action corners
26                         ]),
27
28                     ('View2D', 'EMPTY', 'WINDOW', []),    # view 2d navigation (per region)
29                     ('View2D Buttons List', 'EMPTY', 'WINDOW', []), # view 2d with buttons navigation
30                     ('Header', 'EMPTY', 'WINDOW', []),    # header stuff (per region)
31                     ('Grease Pencil', 'EMPTY', 'WINDOW', []), # grease pencil stuff (per region)
32
33                     ('3D View', 'VIEW_3D', 'WINDOW', [ # view 3d navigation and generic stuff (select, transform)
34                         ('Object Mode', 'EMPTY', 'WINDOW', []),
35                         ('Mesh', 'EMPTY', 'WINDOW', []),
36                         ('Curve', 'EMPTY', 'WINDOW', []),
37                         ('Armature', 'EMPTY', 'WINDOW', []),
38                         ('Metaball', 'EMPTY', 'WINDOW', []),
39                         ('Lattice', 'EMPTY', 'WINDOW', []),
40                         ('Font', 'EMPTY', 'WINDOW', []),
41
42                         ('Pose', 'EMPTY', 'WINDOW', []),
43
44                         ('Vertex Paint', 'EMPTY', 'WINDOW', []),
45                         ('Weight Paint', 'EMPTY', 'WINDOW', []),
46                         ('Face Mask', 'EMPTY', 'WINDOW', []),
47                         ('Image Paint', 'EMPTY', 'WINDOW', []), # image and view3d
48                         ('Sculpt', 'EMPTY', 'WINDOW', []),
49
50                         ('Armature Sketch', 'EMPTY', 'WINDOW', []),
51                         ('Particle', 'EMPTY', 'WINDOW', []),
52
53                         ('Object Non-modal', 'EMPTY', 'WINDOW', []), # mode change
54
55                         ('3D View Generic', 'VIEW_3D', 'WINDOW', [])    # toolbar and properties
56                         ]),
57
58                     ('Frames', 'EMPTY', 'WINDOW', []),    # frame navigation (per region)
59                     ('Markers', 'EMPTY', 'WINDOW', []),    # markers (per region)
60                     ('Animation', 'EMPTY', 'WINDOW', []),    # frame change on click, preview range (per region)
61                     ('Animation Channels', 'EMPTY', 'WINDOW', []),
62                     ('Graph Editor', 'GRAPH_EDITOR', 'WINDOW', [
63                         ('Graph Editor Generic', 'GRAPH_EDITOR', 'WINDOW', [])
64                         ]),
65                     ('Dopesheet', 'DOPESHEET_EDITOR', 'WINDOW', []),
66                     ('NLA Editor', 'NLA_EDITOR', 'WINDOW', [
67                         ('NLA Channels', 'NLA_EDITOR', 'WINDOW', []),
68                         ('NLA Generic', 'NLA_EDITOR', 'WINDOW', [])
69                         ]),
70
71                     ('Image', 'IMAGE_EDITOR', 'WINDOW', [
72                         ('UV Editor', 'EMPTY', 'WINDOW', []), # image (reverse order, UVEdit before Image
73                         ('Image Paint', 'EMPTY', 'WINDOW', []), # image and view3d
74                         ('Image Generic', 'IMAGE_EDITOR', 'WINDOW', [])
75                         ]),
76
77                     ('Timeline', 'TIMELINE', 'WINDOW', []),
78                     ('Outliner', 'OUTLINER', 'WINDOW', []),
79
80                     ('Node Editor', 'NODE_EDITOR', 'WINDOW', [
81                         ('Node Generic', 'NODE_EDITOR', 'WINDOW', [])
82                         ]),
83                     ('Sequencer', 'SEQUENCE_EDITOR', 'WINDOW', []),
84                     ('Logic Editor', 'LOGIC_EDITOR', 'WINDOW', []),
85
86                     ('File Browser', 'FILE_BROWSER', 'WINDOW', [
87                         ('File Browser Main', 'FILE_BROWSER', 'WINDOW', []),
88                         ('File Browser Buttons', 'FILE_BROWSER', 'WINDOW', [])
89                         ]),
90
91                     ('Property Editor', 'PROPERTIES', 'WINDOW', []), # align context menu
92
93                     ('Script', 'SCRIPTS_WINDOW', 'WINDOW', []),
94                     ('Text', 'TEXT_EDITOR', 'WINDOW', []),
95                     ('Console', 'CONSOLE', 'WINDOW', []),
96
97                     ('View3D Gesture Circle', 'EMPTY', 'WINDOW', []),
98                     ('Gesture Border', 'EMPTY', 'WINDOW', []),
99                     ('Standard Modal Map', 'EMPTY', 'WINDOW', []),
100                     ('Transform Modal Map', 'EMPTY', 'WINDOW', []),
101                     ('View3D Fly Modal', 'EMPTY', 'WINDOW', []),
102                     ('View3D Rotate Modal', 'EMPTY', 'WINDOW', []),
103                     ('View3D Move Modal', 'EMPTY', 'WINDOW', []),
104                     ('View3D Zoom Modal', 'EMPTY', 'WINDOW', []),
105                 ]
106
107
108 class USERPREF_HT_header(bpy.types.Header):
109     bl_space_type = 'USER_PREFERENCES'
110
111     def draw(self, context):
112         layout = self.layout
113         layout.template_header(menus=False)
114
115         userpref = context.user_preferences
116
117         layout.operator_context = 'EXEC_AREA'
118         layout.operator("wm.save_homefile", text="Save As Default")
119
120         if userpref.active_section == 'INPUT':
121             layout.operator_context = 'INVOKE_DEFAULT'
122             layout.operator("wm.keyconfig_export", "Export Key Configuration...").path = "keymap.py"
123
124
125 class USERPREF_PT_tabs(bpy.types.Panel):
126     bl_label = ""
127     bl_space_type = 'USER_PREFERENCES'
128     bl_region_type = 'WINDOW'
129     bl_show_header = False
130
131     def draw(self, context):
132         layout = self.layout
133
134         userpref = context.user_preferences
135
136         layout.prop(userpref, "active_section", expand=True)
137
138
139 class USERPREF_PT_interface(bpy.types.Panel):
140     bl_space_type = 'USER_PREFERENCES'
141     bl_label = "Interface"
142     bl_region_type = 'WINDOW'
143     bl_show_header = False
144
145     def poll(self, context):
146         userpref = context.user_preferences
147         return (userpref.active_section == 'INTERFACE')
148
149     def draw(self, context):
150         layout = self.layout
151
152         userpref = context.user_preferences
153         view = userpref.view
154
155         row = layout.row()
156
157
158         col = row.column()
159         col.label(text="Display:")
160         col.prop(view, "tooltips")
161         col.prop(view, "display_object_info", text="Object Info")
162         col.prop(view, "use_large_cursors")
163         col.prop(view, "show_view_name", text="View Name")
164         col.prop(view, "show_playback_fps", text="Playback FPS")
165         col.prop(view, "global_scene")
166         col.prop(view, "pin_floating_panels")
167         col.prop(view, "object_origin_size")
168
169         col.separator()
170         col.separator()
171         col.separator()
172
173         col.prop(view, "show_mini_axis", text="Display Mini Axis")
174         sub = col.column()
175         sub.enabled = view.show_mini_axis
176         sub.prop(view, "mini_axis_size", text="Size")
177         sub.prop(view, "mini_axis_brightness", text="Brightness")
178
179
180         row.separator()
181         row.separator()
182
183         col = row.column()
184         col.label(text="View Manipulation:")
185         col.prop(view, "auto_depth")
186         col.prop(view, "zoom_to_mouse")
187         col.prop(view, "rotate_around_selection")
188         col.prop(view, "global_pivot")
189
190         col.separator()
191
192         col.prop(view, "auto_perspective")
193         col.prop(view, "smooth_view")
194         col.prop(view, "rotation_angle")
195
196         row.separator()
197         row.separator()
198
199         col = row.column()
200         #Toolbox doesn't exist yet
201         #col.label(text="Toolbox:")
202         #col.prop(view, "use_column_layout")
203         #col.label(text="Open Toolbox Delay:")
204         #col.prop(view, "open_left_mouse_delay", text="Hold LMB")
205         #col.prop(view, "open_right_mouse_delay", text="Hold RMB")
206         col.prop(view, "use_manipulator")
207         sub = col.column()
208         sub.enabled = view.use_manipulator
209         sub.prop(view, "manipulator_size", text="Size")
210         sub.prop(view, "manipulator_handle_size", text="Handle Size")
211         sub.prop(view, "manipulator_hotspot", text="Hotspot")
212
213         col.separator()
214         col.separator()
215         col.separator()
216
217         col.label(text="Menus:")
218         col.prop(view, "open_mouse_over")
219         col.label(text="Menu Open Delay:")
220         col.prop(view, "open_toplevel_delay", text="Top Level")
221         col.prop(view, "open_sublevel_delay", text="Sub Level")
222
223
224 class USERPREF_PT_edit(bpy.types.Panel):
225     bl_space_type = 'USER_PREFERENCES'
226     bl_label = "Edit"
227     bl_region_type = 'WINDOW'
228     bl_show_header = False
229
230     def poll(self, context):
231         userpref = context.user_preferences
232         return (userpref.active_section == 'EDITING')
233
234     def draw(self, context):
235         layout = self.layout
236
237         userpref = context.user_preferences
238         edit = userpref.edit
239
240
241         row = layout.row()
242
243
244         col = row.column()
245         col.label(text="Link Materials To:")
246         col.row().prop(edit, "material_link", expand=True)
247
248         col.separator()
249         col.separator()
250         col.separator()
251
252         col.label(text="New Objects:")
253         col.prop(edit, "enter_edit_mode")
254         col.label(text="Align To:")
255         col.row().prop(edit, "object_align", expand=True)
256
257         col.separator()
258         col.separator()
259         col.separator()
260
261         col.label(text="Undo:")
262         col.prop(edit, "global_undo")
263         col.prop(edit, "undo_steps", text="Steps")
264         col.prop(edit, "undo_memory_limit", text="Memory Limit")
265
266
267         row.separator()
268         row.separator()
269
270
271         col = row.column()
272         col.label(text="Snap:")
273         col.prop(edit, "snap_translate", text="Translate")
274         col.prop(edit, "snap_rotate", text="Rotate")
275         col.prop(edit, "snap_scale", text="Scale")
276         col.separator()
277         col.separator()
278         col.separator()
279         col.label(text="Grease Pencil:")
280         col.prop(edit, "grease_pencil_manhattan_distance", text="Manhattan Distance")
281         col.prop(edit, "grease_pencil_euclidean_distance", text="Euclidean Distance")
282         #col.prop(edit, "grease_pencil_simplify_stroke", text="Simplify Stroke")
283         col.prop(edit, "grease_pencil_eraser_radius", text="Eraser Radius")
284         col.prop(edit, "grease_pencil_smooth_stroke", text="Smooth Stroke")
285
286
287         row.separator()
288         row.separator()
289
290
291         col = row.column()
292         col.label(text="Keyframing:")
293         col.prop(edit, "use_visual_keying")
294         col.prop(edit, "keyframe_insert_needed", text="Only Insert Needed")
295
296         col.separator()
297
298         col.label(text="New F-Curve Defaults:")
299         col.prop(edit, "new_interpolation_type", text="Interpolation")
300         col.prop(edit, "insertkey_xyz_to_rgb", text="XYZ to RGB")
301
302         col.separator()
303
304         col.prop(edit, "auto_keying_enable", text="Auto Keyframing:")
305
306         sub = col.column()
307
308         sub.active = edit.auto_keying_enable
309         sub.prop(edit, "auto_keyframe_insert_keyingset", text="Only Insert for Keying Set")
310         sub.prop(edit, "auto_keyframe_insert_available", text="Only Insert Available")
311
312         col.separator()
313         col.separator()
314         col.separator()
315
316         col.label(text="Transform:")
317         col.prop(edit, "drag_immediately")
318
319
320         row.separator()
321         row.separator()
322
323
324         col = row.column()
325         col.label(text="Duplicate Data:")
326         col.prop(edit, "duplicate_mesh", text="Mesh")
327         col.prop(edit, "duplicate_surface", text="Surface")
328         col.prop(edit, "duplicate_curve", text="Curve")
329         col.prop(edit, "duplicate_text", text="Text")
330         col.prop(edit, "duplicate_metaball", text="Metaball")
331         col.prop(edit, "duplicate_armature", text="Armature")
332         col.prop(edit, "duplicate_lamp", text="Lamp")
333         col.prop(edit, "duplicate_material", text="Material")
334         col.prop(edit, "duplicate_texture", text="Texture")
335         col.prop(edit, "duplicate_fcurve", text="F-Curve")
336         col.prop(edit, "duplicate_action", text="Action")
337         col.prop(edit, "duplicate_particle", text="Particle")
338
339
340 class USERPREF_PT_system(bpy.types.Panel):
341     bl_space_type = 'USER_PREFERENCES'
342     bl_label = "System"
343     bl_region_type = 'WINDOW'
344     bl_show_header = False
345
346     def poll(self, context):
347         userpref = context.user_preferences
348         return (userpref.active_section == 'SYSTEM')
349
350     def draw(self, context):
351         layout = self.layout
352
353         userpref = context.user_preferences
354         system = userpref.system
355         lamp0 = system.solid_lights[0]
356         lamp1 = system.solid_lights[1]
357         lamp2 = system.solid_lights[2]
358
359         split = layout.split()
360
361         column = split.column()
362         colsplit = column.split(percentage=0.85)
363
364         col = colsplit.column()
365         col.label(text="General:")
366         col.prop(system, "dpi")
367         col.prop(system, "frame_server_port")
368         col.prop(system, "scrollback", text="Console Scrollback")
369         col.prop(system, "auto_run_python_scripts")
370
371         col.separator()
372         col.separator()
373         col.separator()
374
375         col.label(text="Sound:")
376         col.row().prop(system, "audio_device", expand=True)
377         sub = col.column()
378         sub.active = system.audio_device != 'NONE'
379         #sub.prop(system, "enable_all_codecs")
380         sub.prop(system, "game_sound")
381         sub.prop(system, "audio_channels", text="Channels")
382         sub.prop(system, "audio_mixing_buffer", text="Mixing Buffer")
383         sub.prop(system, "audio_sample_rate", text="Sample Rate")
384         sub.prop(system, "audio_sample_format", text="Sample Format")
385
386         col.separator()
387         col.separator()
388         col.separator()
389
390
391
392         #column = split.column()
393         #colsplit = column.split(percentage=0.85)
394
395         # No translation in 2.5 yet
396         #col.prop(system, "language")
397         #col.label(text="Translate:")
398         #col.prop(system, "translate_tooltips", text="Tooltips")
399         #col.prop(system, "translate_buttons", text="Labels")
400         #col.prop(system, "translate_toolbox", text="Toolbox")
401
402         #col.separator()
403
404         #col.prop(system, "use_textured_fonts")
405
406         column = split.column()
407         colsplit = column.split(percentage=0.85)
408
409         col = colsplit.column()
410         col.label(text="OpenGL:")
411         col.prop(system, "clip_alpha", slider=True)
412         col.prop(system, "use_mipmaps")
413         col.prop(system, "use_vbos")
414         #Anti-aliasing is disabled as it breaks broder/lasso select
415         #col.prop(system, "use_antialiasing")
416         col.label(text="Window Draw Method:")
417         col.row().prop(system, "window_draw_method", expand=True)
418         col.label(text="Textures:")
419         col.prop(system, "gl_texture_limit", text="Limit Size")
420         col.prop(system, "texture_time_out", text="Time Out")
421         col.prop(system, "texture_collection_rate", text="Collection Rate")
422
423         col.separator()
424         col.separator()
425         col.separator()
426
427         col.label(text="Sequencer:")
428         col.prop(system, "prefetch_frames")
429         col.prop(system, "memory_cache_limit")
430
431         column = split.column()
432
433         column.label(text="Solid OpenGL lights:")
434
435         split = column.split(percentage=0.1)
436         split.label()
437         split.label(text="Colors:")
438         split.label(text="Direction:")
439
440
441         split = column.split(percentage=0.1)
442
443         if lamp0.enabled == True:
444             split.prop(lamp0, "enabled", text="", icon='OUTLINER_OB_LAMP')
445         else:
446             split.prop(lamp0, "enabled", text="", icon='LAMP_DATA')
447
448         col = split.column()
449         col.active = lamp0.enabled
450         row = col.row()
451         row.label(text="Diffuse:")
452         row.prop(lamp0, "diffuse_color", text="")
453         row = col.row()
454         row.label(text="Specular:")
455         row.prop(lamp0, "specular_color", text="")
456
457         col = split.column()
458         col.active = lamp0.enabled
459         col.prop(lamp0, "direction", text="")
460
461
462         split = column.split(percentage=0.1)
463
464         if lamp1.enabled == True:
465             split.prop(lamp1, "enabled", text="", icon='OUTLINER_OB_LAMP')
466         else:
467             split.prop(lamp1, "enabled", text="", icon='LAMP_DATA')
468
469         col = split.column()
470         col.active = lamp1.enabled
471         row = col.row()
472         row.label(text="Diffuse:")
473         row.prop(lamp1, "diffuse_color", text="")
474         row = col.row()
475         row.label(text="Specular:")
476         row.prop(lamp1, "specular_color", text="")
477
478         col = split.column()
479         col.active = lamp1.enabled
480         col.prop(lamp1, "direction", text="")
481
482
483         split = column.split(percentage=0.1)
484
485         if lamp2.enabled == True:
486             split.prop(lamp2, "enabled", text="", icon='OUTLINER_OB_LAMP')
487         else:
488             split.prop(lamp2, "enabled", text="", icon='LAMP_DATA')
489
490         col = split.column()
491         col.active = lamp2.enabled
492         row = col.row()
493         row.label(text="Diffuse:")
494         row.prop(lamp2, "diffuse_color", text="")
495         row = col.row()
496         row.label(text="Specular:")
497         row.prop(lamp2, "specular_color", text="")
498
499         col = split.column()
500         col.active = lamp2.enabled
501         col.prop(lamp2, "direction", text="")
502
503
504         column.separator()
505         column.separator()
506         column.separator()
507
508         col = column.column()
509
510         col.prop(system, "use_weight_color_range", text="Custom Weight Paint Range")
511         sub = col.column()
512         sub.active = system.use_weight_color_range
513         sub.template_color_ramp(system, "weight_color_range", expand=True)
514
515
516 class USERPREF_PT_theme(bpy.types.Panel):
517     bl_space_type = 'USER_PREFERENCES'
518     bl_label = "Themes"
519     bl_region_type = 'WINDOW'
520     bl_show_header = False
521
522     def poll(self, context):
523         userpref = context.user_preferences
524         return (userpref.active_section == 'THEMES')
525
526     def draw(self, context):
527         layout = self.layout
528
529         theme = context.user_preferences.themes[0]
530
531         split = layout.split(percentage=0.33)
532         split.prop(theme, "active_theme", text="")
533
534         layout.separator()
535
536         split = layout.split()
537
538         if theme.active_theme == 'VIEW_3D':
539             v3d = theme.view_3d
540
541             col = split.column()
542             col.prop(v3d, "back")
543             col.prop(v3d, "button")
544             col.prop(v3d, "button_title")
545             col.prop(v3d, "button_text")
546             col.prop(v3d, "header")
547
548             col = split.column()
549             col.prop(v3d, "grid")
550             col.prop(v3d, "wire")
551             col.prop(v3d, "lamp", slider=True)
552             col.prop(v3d, "editmesh_active", slider=True)
553
554             col = split.column()
555             col.prop(v3d, "object_selected")
556             col.prop(v3d, "object_active")
557             col.prop(v3d, "object_grouped")
558             col.prop(v3d, "object_grouped_active")
559             col.prop(v3d, "transform")
560
561             col = split.column()
562             col.prop(v3d, "vertex")
563             col.prop(v3d, "face", slider=True)
564             col.prop(v3d, "normal")
565             col.prop(v3d, "bone_solid")
566             col.prop(v3d, "bone_pose")
567             #col.prop(v3d, "edge") Doesn't seem to work
568
569         elif theme.active_theme == 'USER_INTERFACE':
570             ui = theme.user_interface.wcol_regular
571             layout.label(text="Regular:")
572
573             row = layout.row()
574             sub = row.column()
575             sub.prop(ui, "outline")
576             sub.prop(ui, "item", slider=True)
577             sub = row.column()
578             sub.prop(ui, "inner", slider=True)
579             sub.prop(ui, "inner_sel", slider=True)
580             sub = row.column()
581             sub.prop(ui, "text")
582             sub.prop(ui, "text_sel")
583             sub = row.column()
584             sub.prop(ui, "shaded")
585             subsub = sub.column(align=True)
586             subsub.active = ui.shaded
587             subsub.prop(ui, "shadetop")
588             subsub.prop(ui, "shadedown")
589
590             layout.separator()
591
592             ui = theme.user_interface.wcol_tool
593             layout.label(text="Tool:")
594
595             row = layout.row()
596             sub = row.column()
597             sub.prop(ui, "outline")
598             sub.prop(ui, "item", slider=True)
599             sub = row.column()
600             sub.prop(ui, "inner", slider=True)
601             sub.prop(ui, "inner_sel", slider=True)
602             sub = row.column()
603             sub.prop(ui, "text")
604             sub.prop(ui, "text_sel")
605             sub = row.column()
606             sub.prop(ui, "shaded")
607             subsub = sub.column(align=True)
608             subsub.active = ui.shaded
609             subsub.prop(ui, "shadetop")
610             subsub.prop(ui, "shadedown")
611
612             ui = theme.user_interface.wcol_radio
613             layout.label(text="Radio Buttons:")
614
615             row = layout.row()
616             sub = row.column()
617             sub.prop(ui, "outline")
618             sub.prop(ui, "item", slider=True)
619             sub = row.column()
620             sub.prop(ui, "inner", slider=True)
621             sub.prop(ui, "inner_sel", slider=True)
622             sub = row.column()
623             sub.prop(ui, "text")
624             sub.prop(ui, "text_sel")
625             sub = row.column()
626             sub.prop(ui, "shaded")
627             subsub = sub.column(align=True)
628             subsub.active = ui.shaded
629             subsub.prop(ui, "shadetop")
630             subsub.prop(ui, "shadedown")
631
632             ui = theme.user_interface.wcol_text
633             layout.label(text="Text:")
634
635             row = layout.row()
636             sub = row.column()
637             sub.prop(ui, "outline")
638             sub.prop(ui, "item", slider=True)
639             sub = row.column()
640             sub.prop(ui, "inner", slider=True)
641             sub.prop(ui, "inner_sel", slider=True)
642             sub = row.column()
643             sub.prop(ui, "text")
644             sub.prop(ui, "text_sel")
645             sub = row.column()
646             sub.prop(ui, "shaded")
647             subsub = sub.column(align=True)
648             subsub.active = ui.shaded
649             subsub.prop(ui, "shadetop")
650             subsub.prop(ui, "shadedown")
651
652             ui = theme.user_interface.wcol_option
653             layout.label(text="Option:")
654
655             row = layout.row()
656             sub = row.column()
657             sub.prop(ui, "outline")
658             sub.prop(ui, "item", slider=True)
659             sub = row.column()
660             sub.prop(ui, "inner", slider=True)
661             sub.prop(ui, "inner_sel", slider=True)
662             sub = row.column()
663             sub.prop(ui, "text")
664             sub.prop(ui, "text_sel")
665             sub = row.column()
666             sub.prop(ui, "shaded")
667             subsub = sub.column(align=True)
668             subsub.active = ui.shaded
669             subsub.prop(ui, "shadetop")
670             subsub.prop(ui, "shadedown")
671
672             ui = theme.user_interface.wcol_toggle
673             layout.label(text="Toggle:")
674
675             row = layout.row()
676             sub = row.column()
677             sub.prop(ui, "outline")
678             sub.prop(ui, "item", slider=True)
679             sub = row.column()
680             sub.prop(ui, "inner", slider=True)
681             sub.prop(ui, "inner_sel", slider=True)
682             sub = row.column()
683             sub.prop(ui, "text")
684             sub.prop(ui, "text_sel")
685             sub = row.column()
686             sub.prop(ui, "shaded")
687             subsub = sub.column(align=True)
688             subsub.active = ui.shaded
689             subsub.prop(ui, "shadetop")
690             subsub.prop(ui, "shadedown")
691
692             ui = theme.user_interface.wcol_num
693             layout.label(text="Number Field:")
694
695             row = layout.row()
696             sub = row.column()
697             sub.prop(ui, "outline")
698             sub.prop(ui, "item", slider=True)
699             sub = row.column()
700             sub.prop(ui, "inner", slider=True)
701             sub.prop(ui, "inner_sel", slider=True)
702             sub = row.column()
703             sub.prop(ui, "text")
704             sub.prop(ui, "text_sel")
705             sub = row.column()
706             sub.prop(ui, "shaded")
707             subsub = sub.column(align=True)
708             subsub.active = ui.shaded
709             subsub.prop(ui, "shadetop")
710             subsub.prop(ui, "shadedown")
711
712             ui = theme.user_interface.wcol_numslider
713             layout.label(text="Value Slider:")
714
715             row = layout.row()
716             sub = row.column()
717             sub.prop(ui, "outline")
718             sub.prop(ui, "item", slider=True)
719             sub = row.column()
720             sub.prop(ui, "inner", slider=True)
721             sub.prop(ui, "inner_sel", slider=True)
722             sub = row.column()
723             sub.prop(ui, "text")
724             sub.prop(ui, "text_sel")
725             sub = row.column()
726             sub.prop(ui, "shaded")
727             subsub = sub.column(align=True)
728             subsub.active = ui.shaded
729             subsub.prop(ui, "shadetop")
730             subsub.prop(ui, "shadedown")
731
732             ui = theme.user_interface.wcol_box
733             layout.label(text="Box:")
734
735             row = layout.row()
736             sub = row.column()
737             sub.prop(ui, "outline")
738             sub.prop(ui, "item", slider=True)
739             sub = row.column()
740             sub.prop(ui, "inner", slider=True)
741             sub.prop(ui, "inner_sel", slider=True)
742             sub = row.column()
743             sub.prop(ui, "text")
744             sub.prop(ui, "text_sel")
745             sub = row.column()
746             sub.prop(ui, "shaded")
747             subsub = sub.column(align=True)
748             subsub.active = ui.shaded
749             subsub.prop(ui, "shadetop")
750             subsub.prop(ui, "shadedown")
751
752             ui = theme.user_interface.wcol_menu
753             layout.label(text="Menu:")
754
755             row = layout.row()
756             sub = row.column()
757             sub.prop(ui, "outline")
758             sub.prop(ui, "item", slider=True)
759             sub = row.column()
760             sub.prop(ui, "inner", slider=True)
761             sub.prop(ui, "inner_sel", slider=True)
762             sub = row.column()
763             sub.prop(ui, "text")
764             sub.prop(ui, "text_sel")
765             sub = row.column()
766             sub.prop(ui, "shaded")
767             subsub = sub.column(align=True)
768             subsub.active = ui.shaded
769             subsub.prop(ui, "shadetop")
770             subsub.prop(ui, "shadedown")
771
772             ui = theme.user_interface.wcol_pulldown
773             layout.label(text="Pulldown:")
774
775             row = layout.row()
776             sub = row.column()
777             sub.prop(ui, "outline")
778             sub.prop(ui, "item", slider=True)
779             sub = row.column()
780             sub.prop(ui, "inner", slider=True)
781             sub.prop(ui, "inner_sel", slider=True)
782             sub = row.column()
783             sub.prop(ui, "text")
784             sub.prop(ui, "text_sel")
785             sub = row.column()
786             sub.prop(ui, "shaded")
787             subsub = sub.column(align=True)
788             subsub.active = ui.shaded
789             subsub.prop(ui, "shadetop")
790             subsub.prop(ui, "shadedown")
791
792             ui = theme.user_interface.wcol_menu_back
793             layout.label(text="Menu Back:")
794
795             row = layout.row()
796             sub = row.column()
797             sub.prop(ui, "outline")
798             sub.prop(ui, "item", slider=True)
799             sub = row.column()
800             sub.prop(ui, "inner", slider=True)
801             sub.prop(ui, "inner_sel", slider=True)
802             sub = row.column()
803             sub.prop(ui, "text")
804             sub.prop(ui, "text_sel")
805             sub = row.column()
806             sub.prop(ui, "shaded")
807             subsub = sub.column(align=True)
808             subsub.active = ui.shaded
809             subsub.prop(ui, "shadetop")
810             subsub.prop(ui, "shadedown")
811
812             ui = theme.user_interface.wcol_menu_item
813             layout.label(text="Menu Item:")
814
815             row = layout.row()
816             sub = row.column()
817             sub.prop(ui, "outline")
818             sub.prop(ui, "item", slider=True)
819             sub = row.column()
820             sub.prop(ui, "inner", slider=True)
821             sub.prop(ui, "inner_sel", slider=True)
822             sub = row.column()
823             sub.prop(ui, "text")
824             sub.prop(ui, "text_sel")
825             sub = row.column()
826             sub.prop(ui, "shaded")
827             subsub = sub.column(align=True)
828             subsub.active = ui.shaded
829             subsub.prop(ui, "shadetop")
830             subsub.prop(ui, "shadedown")
831
832             ui = theme.user_interface.wcol_scroll
833             layout.label(text="Scroll Bar:")
834
835             row = layout.row()
836             sub = row.column()
837             sub.prop(ui, "outline")
838             sub.prop(ui, "item", slider=True)
839             sub = row.column()
840             sub.prop(ui, "inner", slider=True)
841             sub.prop(ui, "inner_sel", slider=True)
842             sub = row.column()
843             sub.prop(ui, "text")
844             sub.prop(ui, "text_sel")
845             sub = row.column()
846             sub.prop(ui, "shaded")
847             subsub = sub.column(align=True)
848             subsub.active = ui.shaded
849             subsub.prop(ui, "shadetop")
850             subsub.prop(ui, "shadedown")
851
852             ui = theme.user_interface.wcol_list_item
853             layout.label(text="List Item:")
854
855             row = layout.row()
856             sub = row.column()
857             sub.prop(ui, "outline")
858             sub.prop(ui, "item", slider=True)
859             sub = row.column()
860             sub.prop(ui, "inner", slider=True)
861             sub.prop(ui, "inner_sel", slider=True)
862             sub = row.column()
863             sub.prop(ui, "text")
864             sub.prop(ui, "text_sel")
865             sub = row.column()
866             sub.prop(ui, "shaded")
867             subsub = sub.column(align=True)
868             subsub.active = ui.shaded
869             subsub.prop(ui, "shadetop")
870             subsub.prop(ui, "shadedown")
871
872             ui = theme.user_interface.wcol_state
873             layout.label(text="State:")
874
875             row = layout.row()
876             sub = row.column()
877             sub.prop(ui, "inner_anim")
878             sub.prop(ui, "inner_anim_sel")
879             sub = row.column()
880             sub.prop(ui, "inner_driven")
881             sub.prop(ui, "inner_driven_sel")
882             sub = row.column()
883             sub.prop(ui, "inner_key")
884             sub.prop(ui, "inner_key_sel")
885             sub = row.column()
886             sub.prop(ui, "blend")
887
888             ui = theme.user_interface
889             layout.separator()
890
891             sub = layout.row()
892             sub.prop(ui, "icon_file")
893
894             layout.separator()
895             layout.separator()
896
897
898         elif theme.active_theme == 'GRAPH_EDITOR':
899             graph = theme.graph_editor
900
901             col = split.column()
902             col.prop(graph, "back")
903             col.prop(graph, "button")
904             col.prop(graph, "button_title")
905             col.prop(graph, "button_text")
906
907             col = split.column()
908             col.prop(graph, "header")
909             col.prop(graph, "grid")
910             col.prop(graph, "list")
911             col.prop(graph, "channel_group")
912
913             col = split.column()
914             col.prop(graph, "active_channels_group")
915             col.prop(graph, "dopesheet_channel")
916             col.prop(graph, "dopesheet_subchannel")
917             col.prop(graph, "vertex")
918
919             col = split.column()
920             col.prop(graph, "current_frame")
921             col.prop(graph, "handle_vertex")
922             col.prop(graph, "handle_vertex_select")
923             col.separator()
924             col.prop(graph, "handle_vertex_size")
925
926         elif theme.active_theme == 'FILE_BROWSER':
927             file_browse = theme.file_browser
928
929             col = split.column()
930             col.prop(file_browse, "back")
931             col.prop(file_browse, "text")
932             col.prop(file_browse, "text_hi")
933
934             col = split.column()
935             col.prop(file_browse, "header")
936             col.prop(file_browse, "list")
937
938             col = split.column()
939             col.prop(file_browse, "selected_file")
940             col.prop(file_browse, "tiles")
941
942             col = split.column()
943             col.prop(file_browse, "active_file")
944             col.prop(file_browse, "active_file_text")
945
946         elif theme.active_theme == 'NLA_EDITOR':
947             nla = theme.nla_editor
948
949             col = split.column()
950             col.prop(nla, "back")
951             col.prop(nla, "button")
952             col.prop(nla, "button_title")
953
954             col = split.column()
955             col.prop(nla, "button_text")
956             col.prop(nla, "text")
957             col.prop(nla, "header")
958
959             col = split.column()
960             col.prop(nla, "grid")
961             col.prop(nla, "bars")
962             col.prop(nla, "bars_selected")
963
964             col = split.column()
965             col.prop(nla, "strips")
966             col.prop(nla, "strips_selected")
967             col.prop(nla, "current_frame")
968
969         elif theme.active_theme == 'DOPESHEET_EDITOR':
970             dope = theme.dopesheet_editor
971
972             col = split.column()
973             col.prop(dope, "back")
974             col.prop(dope, "list")
975             col.prop(dope, "text")
976             col.prop(dope, "header")
977
978             col = split.column()
979             col.prop(dope, "grid")
980             col.prop(dope, "channels")
981             col.prop(dope, "channels_selected")
982             col.prop(dope, "channel_group")
983
984             col = split.column()
985             col.prop(dope, "active_channels_group")
986             col.prop(dope, "long_key")
987             col.prop(dope, "long_key_selected")
988
989             col = split.column()
990             col.prop(dope, "current_frame")
991             col.prop(dope, "dopesheet_channel")
992             col.prop(dope, "dopesheet_subchannel")
993
994         elif theme.active_theme == 'IMAGE_EDITOR':
995             image = theme.image_editor
996
997             col = split.column()
998             col.prop(image, "back")
999             col.prop(image, "button")
1000
1001             col = split.column()
1002             col.prop(image, "button_title")
1003             col.prop(image, "button_text")
1004
1005             col = split.column()
1006             col.prop(image, "header")
1007
1008             col = split.column()
1009             col.prop(image, "editmesh_active", slider=True)
1010
1011         elif theme.active_theme == 'SEQUENCE_EDITOR':
1012             seq = theme.sequence_editor
1013
1014             col = split.column()
1015             col.prop(seq, "back")
1016             col.prop(seq, "button")
1017             col.prop(seq, "button_title")
1018             col.prop(seq, "button_text")
1019             col.prop(seq, "text")
1020
1021             col = split.column()
1022             col.prop(seq, "header")
1023             col.prop(seq, "grid")
1024             col.prop(seq, "movie_strip")
1025             col.prop(seq, "image_strip")
1026             col.prop(seq, "scene_strip")
1027
1028             col = split.column()
1029             col.prop(seq, "audio_strip")
1030             col.prop(seq, "effect_strip")
1031             col.prop(seq, "plugin_strip")
1032             col.prop(seq, "transition_strip")
1033
1034             col = split.column()
1035             col.prop(seq, "meta_strip")
1036             col.prop(seq, "current_frame")
1037             col.prop(seq, "keyframe")
1038             col.prop(seq, "draw_action")
1039
1040         elif theme.active_theme == 'PROPERTIES':
1041             prop = theme.properties
1042
1043             col = split.column()
1044             col.prop(prop, "back")
1045
1046             col = split.column()
1047             col.prop(prop, "title")
1048
1049             col = split.column()
1050             col.prop(prop, "text")
1051
1052             col = split.column()
1053             col.prop(prop, "header")
1054
1055         elif theme.active_theme == 'TEXT_EDITOR':
1056             text = theme.text_editor
1057
1058             col = split.column()
1059             col.prop(text, "back")
1060             col.prop(text, "button")
1061             col.prop(text, "button_title")
1062             col.prop(text, "button_text")
1063
1064             col = split.column()
1065             col.prop(text, "text")
1066             col.prop(text, "text_hi")
1067             col.prop(text, "header")
1068             col.prop(text, "line_numbers_background")
1069
1070             col = split.column()
1071             col.prop(text, "selected_text")
1072             col.prop(text, "cursor")
1073             col.prop(text, "syntax_builtin")
1074             col.prop(text, "syntax_special")
1075
1076             col = split.column()
1077             col.prop(text, "syntax_comment")
1078             col.prop(text, "syntax_string")
1079             col.prop(text, "syntax_numbers")
1080
1081         elif theme.active_theme == 'TIMELINE':
1082             time = theme.timeline
1083
1084             col = split.column()
1085             col.prop(time, "back")
1086             col.prop(time, "text")
1087
1088             col = split.column()
1089             col.prop(time, "header")
1090
1091             col = split.column()
1092             col.prop(time, "grid")
1093
1094             col = split.column()
1095             col.prop(time, "current_frame")
1096
1097         elif theme.active_theme == 'NODE_EDITOR':
1098             node = theme.node_editor
1099
1100             col = split.column()
1101             col.prop(node, "back")
1102             col.prop(node, "button")
1103             col.prop(node, "button_title")
1104             col.prop(node, "button_text")
1105
1106             col = split.column()
1107             col.prop(node, "text")
1108             col.prop(node, "text_hi")
1109             col.prop(node, "header")
1110             col.prop(node, "wires")
1111
1112             col = split.column()
1113             col.prop(node, "wire_select")
1114             col.prop(node, "selected_text")
1115             col.prop(node, "node_backdrop", slider=True)
1116             col.prop(node, "in_out_node")
1117
1118             col = split.column()
1119             col.prop(node, "converter_node")
1120             col.prop(node, "operator_node")
1121             col.prop(node, "group_node")
1122
1123         elif theme.active_theme == 'LOGIC_EDITOR':
1124             logic = theme.logic_editor
1125
1126             col = split.column()
1127             col.prop(logic, "back")
1128             col.prop(logic, "button")
1129
1130             col = split.column()
1131             col.prop(logic, "button_title")
1132             col.prop(logic, "button_text")
1133
1134             col = split.column()
1135             col.prop(logic, "text")
1136             col.prop(logic, "header")
1137
1138             col = split.column()
1139             col.prop(logic, "panel")
1140
1141         elif theme.active_theme == 'OUTLINER':
1142             out = theme.outliner
1143
1144             col = split.column()
1145             col.prop(out, "back")
1146
1147             col = split.column()
1148             col.prop(out, "text")
1149
1150             col = split.column()
1151             col.prop(out, "text_hi")
1152
1153             col = split.column()
1154             col.prop(out, "header")
1155
1156         elif theme.active_theme == 'INFO':
1157             info = theme.info
1158
1159             col = split.column()
1160             col.prop(info, "back")
1161
1162             col = split.column()
1163             col.prop(info, "header")
1164
1165             col = split.column()
1166             col.prop(info, "header_text")
1167
1168             col = split.column()
1169
1170         elif theme.active_theme == 'USER_PREFERENCES':
1171             prefs = theme.user_preferences
1172
1173             col = split.column()
1174             col.prop(prefs, "back")
1175
1176             col = split.column()
1177             col.prop(prefs, "text")
1178
1179             col = split.column()
1180             col.prop(prefs, "header")
1181
1182             col = split.column()
1183             col.prop(prefs, "header_text")
1184
1185
1186 class USERPREF_PT_file(bpy.types.Panel):
1187     bl_space_type = 'USER_PREFERENCES'
1188     bl_label = "Files"
1189     bl_region_type = 'WINDOW'
1190     bl_show_header = False
1191
1192     def poll(self, context):
1193         userpref = context.user_preferences
1194         return (userpref.active_section == 'FILES')
1195
1196     def draw(self, context):
1197         layout = self.layout
1198
1199         userpref = context.user_preferences
1200         paths = userpref.filepaths
1201
1202         split = layout.split(percentage=0.7)
1203
1204         col = split.column()
1205         col.label(text="File Paths:")
1206
1207         colsplit = col.split(percentage=0.95)
1208         col1 = colsplit.split(percentage=0.3)
1209
1210         sub = col1.column()
1211         sub.label(text="Fonts:")
1212         sub.label(text="Textures:")
1213         sub.label(text="Texture Plugins:")
1214         sub.label(text="Sequence Plugins:")
1215         sub.label(text="Render Output:")
1216         sub.label(text="Scripts:")
1217         sub.label(text="Sounds:")
1218         sub.label(text="Temp:")
1219         sub.label(text="Animation Player:")
1220
1221         sub = col1.column()
1222         sub.prop(paths, "fonts_directory", text="")
1223         sub.prop(paths, "textures_directory", text="")
1224         sub.prop(paths, "texture_plugin_directory", text="")
1225         sub.prop(paths, "sequence_plugin_directory", text="")
1226         sub.prop(paths, "render_output_directory", text="")
1227         sub.prop(paths, "python_scripts_directory", text="")
1228         sub.prop(paths, "sounds_directory", text="")
1229         sub.prop(paths, "temporary_directory", text="")
1230         subsplit = sub.split(percentage=0.3)
1231         subsplit.prop(paths, "animation_player_preset", text="")
1232         subsplit.prop(paths, "animation_player", text="")
1233
1234         col = split.column()
1235         col.label(text="Save & Load:")
1236         col.prop(paths, "use_relative_paths")
1237         col.prop(paths, "compress_file")
1238         col.prop(paths, "load_ui")
1239         col.prop(paths, "filter_file_extensions")
1240         col.prop(paths, "hide_dot_files_datablocks")
1241
1242         col.separator()
1243         col.separator()
1244
1245         col.label(text="Auto Save:")
1246         col.prop(paths, "save_version")
1247         col.prop(paths, "recent_files")
1248         col.prop(paths, "save_preview_images")
1249         col.prop(paths, "auto_save_temporary_files")
1250         sub = col.column()
1251         sub.enabled = paths.auto_save_temporary_files
1252         sub.prop(paths, "auto_save_time", text="Timer (mins)")
1253
1254
1255 class USERPREF_PT_input(bpy.types.Panel):
1256     bl_space_type = 'USER_PREFERENCES'
1257     bl_label = "Input"
1258     bl_region_type = 'WINDOW'
1259     bl_show_header = False
1260
1261     def poll(self, context):
1262         userpref = context.user_preferences
1263         return (userpref.active_section == 'INPUT')
1264
1265     def draw_entry(self, kc, entry, col, level=0):
1266         idname, spaceid, regionid, children = entry
1267
1268         km = kc.find_keymap(idname, space_type=spaceid, region_type=regionid)
1269
1270         if km:
1271             self.draw_km(kc, km, children, col, level)
1272
1273     def indented_layout(self, layout, level):
1274         indentpx = 16
1275         if level == 0:
1276             level = 0.0001   # Tweak so that a percentage of 0 won't split by half
1277         indent = level * indentpx / bpy.context.region.width
1278
1279         split = layout.split(percentage=indent)
1280         col = split.column()
1281         col = split.column()
1282         return col
1283
1284     def draw_km(self, kc, km, children, layout, level):
1285         km = km.active()
1286
1287         layout.set_context_pointer("keymap", km)
1288
1289         col = self.indented_layout(layout, level)
1290
1291         row = col.row()
1292         row.prop(km, "children_expanded", text="", no_bg=True)
1293         row.label(text=km.name)
1294
1295         row.label()
1296         row.label()
1297
1298         if km.user_defined:
1299             row.operator("wm.keymap_restore", text="Restore")
1300         else:
1301             row.operator("wm.keymap_edit", text="Edit")
1302
1303         if km.children_expanded:
1304             if children:
1305                 # Put the Parent key map's entries in a 'global' sub-category
1306                 # equal in hierarchy to the other children categories
1307                 subcol = self.indented_layout(col, level + 1)
1308                 subrow = subcol.row()
1309                 subrow.prop(km, "items_expanded", text="", no_bg=True)
1310                 subrow.label(text="%s (Global)" % km.name)
1311             else:
1312                 km.items_expanded = True
1313
1314             # Key Map items
1315             if km.items_expanded:
1316                 for kmi in km.items:
1317                     self.draw_kmi(kc, km, kmi, col, level + 1)
1318
1319                 # "Add New" at end of keymap item list
1320                 col = self.indented_layout(col, level + 1)
1321                 subcol = col.split(percentage=0.2).column()
1322                 subcol.active = km.user_defined
1323                 subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
1324
1325             col.separator()
1326
1327             # Child key maps
1328             if children:
1329                 subcol = col.column()
1330                 row = subcol.row()
1331
1332                 for entry in children:
1333                     self.draw_entry(kc, entry, col, level + 1)
1334
1335     def draw_kmi(self, kc, km, kmi, layout, level):
1336         layout.set_context_pointer("keyitem", kmi)
1337
1338         col = self.indented_layout(layout, level)
1339
1340         col.enabled = km.user_defined
1341
1342         if km.user_defined:
1343             col = col.column(align=True)
1344             box = col.box()
1345         else:
1346             box = col.column()
1347
1348         split = box.split(percentage=0.4)
1349
1350         # header bar
1351         row = split.row()
1352         row.prop(kmi, "expanded", text="", no_bg=True)
1353         row.prop(kmi, "active", text="", no_bg=True)
1354
1355         if km.modal:
1356             row.prop(kmi, "propvalue", text="")
1357         else:
1358             row.label(text=kmi.name)
1359
1360         row = split.row()
1361         row.prop(kmi, "map_type", text="")
1362         if kmi.map_type == 'KEYBOARD':
1363             row.prop(kmi, "type", text="", full_event=True)
1364         elif kmi.map_type == 'MOUSE':
1365             row.prop(kmi, "type", text="", full_event=True)
1366         elif kmi.map_type == 'TWEAK':
1367             subrow = row.row()
1368             subrow.prop(kmi, "type", text="")
1369             subrow.prop(kmi, "value", text="")
1370         elif kmi.map_type == 'TIMER':
1371             row.prop(kmi, "type", text="")
1372         else:
1373             row.label()
1374
1375         row.operator("wm.keyitem_restore", text="", icon='BACK')
1376         row.operator("wm.keyitem_remove", text="", icon='X')
1377
1378         # Expanded, additional event settings
1379         if kmi.expanded:
1380             box = col.box()
1381
1382             if kmi.map_type not in ('TEXTINPUT', 'TIMER'):
1383                 split = box.split(percentage=0.4)
1384                 sub = split.row()
1385
1386                 if km.modal:
1387                     sub.prop(kmi, "propvalue", text="")
1388                 else:
1389                     sub.prop(kmi, "idname", text="")
1390
1391                 sub = split.column()
1392                 subrow = sub.row(align=True)
1393
1394                 if kmi.map_type == 'KEYBOARD':
1395                     subrow.prop(kmi, "type", text="", event=True)
1396                     subrow.prop(kmi, "value", text="")
1397                 elif kmi.map_type == 'MOUSE':
1398                     subrow.prop(kmi, "type", text="")
1399                     subrow.prop(kmi, "value", text="")
1400
1401                 subrow = sub.row()
1402                 subrow.scale_x = 0.75
1403                 subrow.prop(kmi, "any")
1404                 subrow.prop(kmi, "shift")
1405                 subrow.prop(kmi, "ctrl")
1406                 subrow.prop(kmi, "alt")
1407                 subrow.prop(kmi, "oskey", text="Cmd")
1408                 subrow.prop(kmi, "key_modifier", text="", event=True)
1409
1410             # Operator properties
1411             props = kmi.properties
1412             if props is not None:
1413                 box.separator()
1414                 flow = box.column_flow(columns=2)
1415                 for pname in dir(props):
1416                     if not props.is_property_hidden(pname):
1417                         flow.prop(props, pname)
1418
1419             # Modal key maps attached to this operator
1420             if not km.modal:
1421                 kmm = kc.find_keymap_modal(kmi.idname)
1422                 if kmm:
1423                     self.draw_km(kc, kmm, None, layout, level + 1)
1424
1425     def draw_input_prefs(self, inputs, layout):
1426         # General settings
1427         row = layout.row()
1428         col = row.column()
1429
1430         sub = col.column()
1431         sub.label(text="Mouse:")
1432         sub1 = sub.column()
1433         sub1.enabled = (inputs.select_mouse == 'RIGHT')
1434         sub1.prop(inputs, "emulate_3_button_mouse")
1435         sub.prop(inputs, "continuous_mouse")
1436
1437         sub.label(text="Select With:")
1438         sub.row().prop(inputs, "select_mouse", expand=True)
1439
1440         sub = col.column()
1441         sub.label(text="Double Click:")
1442         sub.prop(inputs, "double_click_time", text="Speed")
1443
1444         sub.separator()
1445
1446         sub.prop(inputs, "emulate_numpad")
1447
1448         sub.separator()
1449
1450         sub.label(text="Orbit Style:")
1451         sub.row().prop(inputs, "view_rotation", expand=True)
1452
1453         sub.label(text="Zoom Style:")
1454         sub.row().prop(inputs, "viewport_zoom_style", expand=True)
1455         if inputs.viewport_zoom_style == 'DOLLY':
1456             sub.row().prop(inputs, "zoom_axis", expand=True)
1457             sub.prop(inputs, "invert_zoom_direction")
1458
1459         #sub.prop(inputs, "use_middle_mouse_paste")
1460
1461         #col.separator()
1462
1463         #sub = col.column()
1464         #sub.label(text="Mouse Wheel:")
1465         #sub.prop(view, "wheel_scroll_lines", text="Scroll Lines")
1466
1467         col.separator()
1468
1469         sub = col.column()
1470         sub.label(text="NDOF Device:")
1471         sub.prop(inputs, "ndof_pan_speed", text="Pan Speed")
1472         sub.prop(inputs, "ndof_rotate_speed", text="Orbit Speed")
1473
1474         row.separator()
1475
1476     def draw_filtered(self, kc, layout):
1477         filter = kc.filter.lower()
1478
1479         for km in kc.keymaps:
1480             km = km.active()
1481
1482             filtered_items = [kmi for kmi in km.items if filter in kmi.name.lower()]
1483
1484             if len(filtered_items) != 0:
1485                 layout.set_context_pointer("keymap", km)
1486                 col = layout.column()
1487
1488                 row = col.row()
1489                 row.label(text=km.name, icon="DOT")
1490
1491                 row.label()
1492                 row.label()
1493
1494                 if km.user_defined:
1495                     row.operator("wm.keymap_restore", text="Restore")
1496                 else:
1497                     row.operator("wm.keymap_edit", text="Edit")
1498
1499                 for kmi in filtered_items:
1500                     self.draw_kmi(kc, km, kmi, col, 1)
1501
1502                 # "Add New" at end of keymap item list
1503                 col = self.indented_layout(layout, 1)
1504                 subcol = col.split(percentage=0.2).column()
1505                 subcol.active = km.user_defined
1506                 subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
1507
1508     def draw_hierarchy(self, defkc, layout):
1509         for entry in KM_HIERARCHY:
1510             self.draw_entry(defkc, entry, layout)
1511
1512     def draw(self, context):
1513         layout = self.layout
1514
1515         userpref = context.user_preferences
1516         wm = context.manager
1517
1518         inputs = userpref.inputs
1519
1520         split = layout.split(percentage=0.25)
1521
1522         # Input settings
1523         self.draw_input_prefs(inputs, split)
1524
1525         # Keymap Settings
1526         col = split.column()
1527         # kc = wm.active_keyconfig
1528         kc = wm.default_keyconfig
1529
1530         sub = col.column()
1531
1532         subsplit = sub.split()
1533         subcol = subsplit.column()
1534         subcol.prop_object(wm, "active_keyconfig", wm, "keyconfigs", text="Configuration:")
1535
1536         subcol = subsplit.column()
1537         subcol.prop(kc, "filter", icon="VIEWZOOM")
1538
1539         col.separator()
1540
1541         if kc.filter != "":
1542             self.draw_filtered(kc, col)
1543         else:
1544             self.draw_hierarchy(kc, col)
1545
1546 bpy.types.register(USERPREF_HT_header)
1547 bpy.types.register(USERPREF_PT_tabs)
1548 bpy.types.register(USERPREF_PT_interface)
1549 bpy.types.register(USERPREF_PT_theme)
1550 bpy.types.register(USERPREF_PT_edit)
1551 bpy.types.register(USERPREF_PT_system)
1552 bpy.types.register(USERPREF_PT_file)
1553 bpy.types.register(USERPREF_PT_input)
1554
1555 from bpy.props import *
1556
1557
1558 class WM_OT_keyconfig_test(bpy.types.Operator):
1559     "Test keyconfig for conflicts."
1560     bl_idname = "wm.keyconfig_test"
1561     bl_label = "Test Key Configuration for Conflicts"
1562
1563     def testEntry(self, kc, entry, src=None, parent=None):
1564         result = False
1565
1566         def kmistr(kmi):
1567             if km.modal:
1568                 s = ["kmi = km.add_modal_item(\'%s\', \'%s\', \'%s\'" % (kmi.propvalue, kmi.type, kmi.value)]
1569             else:
1570                 s = ["kmi = km.add_item(\'%s\', \'%s\', \'%s\'" % (kmi.idname, kmi.type, kmi.value)]
1571
1572             if kmi.any:
1573                 s.append(", any=True")
1574             else:
1575                 if kmi.shift:
1576                     s.append(", shift=True")
1577                 if kmi.ctrl:
1578                     s.append(", ctrl=True")
1579                 if kmi.alt:
1580                     s.append(", alt=True")
1581                 if kmi.oskey:
1582                     s.append(", oskey=True")
1583             if kmi.key_modifier and kmi.key_modifier != 'NONE':
1584                 s.append(", key_modifier=\'%s\'" % kmi.key_modifier)
1585
1586             s.append(")\n")
1587
1588             props = kmi.properties
1589
1590             if props is not None:
1591                 for pname in dir(props):
1592                     if props.is_property_set(pname) and not props.is_property_hidden(pname):
1593                         value = eval("props.%s" % pname)
1594                         value = _string_value(value)
1595                         if value != "":
1596                             s.append("kmi.properties.%s = %s\n" % (pname, value))
1597
1598             return "".join(s).strip()
1599
1600         idname, spaceid, regionid, children = entry
1601
1602         km = kc.find_keymap(idname, space_type=spaceid, region_type=regionid)
1603
1604         if km:
1605             km = km.active()
1606
1607             if src:
1608                 for item in km.items:
1609                     if src.compare(item):
1610                         print("===========")
1611                         print(parent.name)
1612                         print(kmistr(src))
1613                         print(km.name)
1614                         print(kmistr(item))
1615                         result = True
1616
1617                 for child in children:
1618                     if self.testEntry(kc, child, src, parent):
1619                         result = True
1620             else:
1621                 for i in range(len(km.items)):
1622                     src = km.items[i]
1623
1624                     for child in children:
1625                         if self.testEntry(kc, child, src, km):
1626                             result = True
1627
1628                     for j in range(len(km.items) - i - 1):
1629                         item = km.items[j + i + 1]
1630                         if src.compare(item):
1631                             print("===========")
1632                             print(km.name)
1633                             print(kmistr(src))
1634                             print(kmistr(item))
1635                             result = True
1636
1637                 for child in children:
1638                     if self.testEntry(kc, child):
1639                         result = True
1640
1641         return result
1642
1643     def testConfig(self, kc):
1644         result = False
1645         for entry in KM_HIERARCHY:
1646             if self.testEntry(kc, entry):
1647                 result = True
1648         return result
1649
1650     def execute(self, context):
1651         wm = context.manager
1652         kc = wm.default_keyconfig
1653
1654         if self.testConfig(kc):
1655             print("CONFLICT")
1656
1657         return {'FINISHED'}
1658
1659
1660 def _string_value(value):
1661     result = ""
1662     if isinstance(value, str):
1663         if value != "":
1664             result = "\'%s\'" % value
1665     elif isinstance(value, bool):
1666         if value:
1667             result = "True"
1668         else:
1669             result = "False"
1670     elif isinstance(value, float):
1671         result = "%.10f" % value
1672     elif isinstance(value, int):
1673         result = "%d" % value
1674     elif getattr(value, '__len__', False):
1675         if len(value):
1676             result = "["
1677             for i in range(0, len(value)):
1678                 result += _string_value(value[i])
1679                 if i != len(value)-1:
1680                     result += ", "
1681             result += "]"
1682     else:
1683         print("Export key configuration: can't write ", value)
1684
1685     return result
1686
1687
1688 class WM_OT_keyconfig_export(bpy.types.Operator):
1689     "Export key configuration to a python script."
1690     bl_idname = "wm.keyconfig_export"
1691     bl_label = "Export Key Configuration..."
1692
1693     path = bpy.props.StringProperty(name="File Path", description="File path to write file to.")
1694
1695     def execute(self, context):
1696         if not self.properties.path:
1697             raise Exception("File path not set.")
1698
1699         f = open(self.properties.path, "w")
1700         if not f:
1701             raise Exception("Could not open file.")
1702
1703         wm = context.manager
1704         kc = wm.active_keyconfig
1705
1706         f.write('# Configuration %s\n' % kc.name)
1707
1708         f.write("wm = bpy.data.windowmanagers[0]\n")
1709         f.write("kc = wm.add_keyconfig(\'%s\')\n\n" % kc.name)
1710
1711         for km in kc.keymaps:
1712             km = km.active()
1713             f.write("# Map %s\n" % km.name)
1714             f.write("km = kc.add_keymap(\'%s\', space_type=\'%s\', region_type=\'%s\', modal=%s)\n\n" % (km.name, km.space_type, km.region_type, km.modal))
1715             for kmi in km.items:
1716                 if km.modal:
1717                     f.write("kmi = km.add_modal_item(\'%s\', \'%s\', \'%s\'" % (kmi.propvalue, kmi.type, kmi.value))
1718                 else:
1719                     f.write("kmi = km.add_item(\'%s\', \'%s\', \'%s\'" % (kmi.idname, kmi.type, kmi.value))
1720                 if kmi.any:
1721                     f.write(", any=True")
1722                 else:
1723                     if kmi.shift:
1724                         f.write(", shift=True")
1725                     if kmi.ctrl:
1726                         f.write(", ctrl=True")
1727                     if kmi.alt:
1728                         f.write(", alt=True")
1729                     if kmi.oskey:
1730                         f.write(", oskey=True")
1731                 if kmi.key_modifier and kmi.key_modifier != 'NONE':
1732                     f.write(", key_modifier=\'%s\'" % kmi.key_modifier)
1733                 f.write(")\n")
1734
1735                 props = kmi.properties
1736
1737                 if props is not None:
1738                     for pname in dir(props):
1739                         if props.is_property_set(pname) and not props.is_property_hidden(pname):
1740                             value = eval("props.%s" % pname)
1741                             value = _string_value(value)
1742                             if value != "":
1743                                 f.write("kmi.properties.%s = %s\n" % (pname, value))
1744
1745             f.write("\n")
1746
1747         f.close()
1748
1749         return {'FINISHED'}
1750
1751     def invoke(self, context, event):
1752         wm = context.manager
1753         wm.add_fileselect(self)
1754         return {'RUNNING_MODAL'}
1755
1756
1757 class WM_OT_keymap_edit(bpy.types.Operator):
1758     "Edit key map."
1759     bl_idname = "wm.keymap_edit"
1760     bl_label = "Edit Key Map"
1761
1762     def execute(self, context):
1763         wm = context.manager
1764         km = context.keymap
1765         km.copy_to_user()
1766         return {'FINISHED'}
1767
1768
1769 class WM_OT_keymap_restore(bpy.types.Operator):
1770     "Restore key map(s)."
1771     bl_idname = "wm.keymap_restore"
1772     bl_label = "Restore Key Map(s)"
1773
1774     all = BoolProperty(attr="all", name="All Keymaps", description="Restore all keymaps to default.")
1775
1776     def execute(self, context):
1777         wm = context.manager
1778
1779         if self.properties.all:
1780             for km in wm.default_keyconfig.keymaps:
1781                 km.restore_to_default()
1782         else:
1783             km = context.keymap
1784             km.restore_to_default()
1785
1786         return {'FINISHED'}
1787
1788
1789 class WM_OT_keyitem_restore(bpy.types.Operator):
1790     "Restore key map item."
1791     bl_idname = "wm.keyitem_restore"
1792     bl_label = "Restore Key Map Item"
1793
1794     def poll(self, context):
1795         kmi = context.keyitem
1796         km = context.keymap
1797         return km and kmi and kmi.id != 0
1798
1799     def execute(self, context):
1800         wm = context.manager
1801         kmi = context.keyitem
1802         km = context.keymap
1803
1804         km.restore_item_to_default(kmi)
1805
1806         return {'FINISHED'}
1807
1808
1809 class WM_OT_keyitem_add(bpy.types.Operator):
1810     "Add key map item."
1811     bl_idname = "wm.keyitem_add"
1812     bl_label = "Add Key Map Item"
1813
1814     def execute(self, context):
1815         wm = context.manager
1816         km = context.keymap
1817         kc = wm.default_keyconfig
1818
1819         if km.modal:
1820             km.add_modal_item("", 'A', 'PRESS') # kmi
1821         else:
1822             km.add_item("none", 'A', 'PRESS') # kmi
1823
1824         # clear filter and expand keymap so we can see the newly added item
1825         if kc.filter != '':
1826             kc.filter = ''
1827             km.items_expanded = True
1828             km.children_expanded = True
1829
1830         return {'FINISHED'}
1831
1832
1833 class WM_OT_keyitem_remove(bpy.types.Operator):
1834     "Remove key map item."
1835     bl_idname = "wm.keyitem_remove"
1836     bl_label = "Remove Key Map Item"
1837
1838     def execute(self, context):
1839         wm = context.manager
1840         kmi = context.keyitem
1841         km = context.keymap
1842         km.remove_item(kmi)
1843         return {'FINISHED'}
1844
1845 bpy.types.register(WM_OT_keyconfig_export)
1846 bpy.types.register(WM_OT_keyconfig_test)
1847 bpy.types.register(WM_OT_keymap_edit)
1848 bpy.types.register(WM_OT_keymap_restore)
1849 bpy.types.register(WM_OT_keyitem_add)
1850 bpy.types.register(WM_OT_keyitem_remove)
1851 bpy.types.register(WM_OT_keyitem_restore)