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