operator draw function working again. needed to add layout to the operator to give...
[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, "global_pivot")
187         col.prop(view, "zoom_to_mouse")
188         col.prop(view, "rotate_around_selection")
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         col.label(text="Window Draw Method:")
415         col.row().prop(system, "window_draw_method", expand=True)
416         col.label(text="Textures:")
417         col.prop(system, "gl_texture_limit", text="Limit Size")
418         col.prop(system, "texture_time_out", text="Time Out")
419         col.prop(system, "texture_collection_rate", text="Collection Rate")
420
421         col.separator()
422         col.separator()
423         col.separator()
424
425         col.label(text="Sequencer:")
426         col.prop(system, "prefetch_frames")
427         col.prop(system, "memory_cache_limit")
428
429         column = split.column()
430
431         column.label(text="Solid OpenGL lights:")
432
433         split = column.split(percentage=0.1)
434         split.label()
435         split.label(text="Colors:")
436         split.label(text="Direction:")
437
438
439         split = column.split(percentage=0.1)
440
441         if lamp0.enabled == True:
442             split.prop(lamp0, "enabled", text="", icon='OUTLINER_OB_LAMP')
443         else:
444             split.prop(lamp0, "enabled", text="", icon='LAMP_DATA')
445
446         col = split.column()
447         col.active = lamp0.enabled
448         row = col.row()
449         row.label(text="Diffuse:")
450         row.prop(lamp0, "diffuse_color", text="")
451         row = col.row()
452         row.label(text="Specular:")
453         row.prop(lamp0, "specular_color", text="")
454
455         col = split.column()
456         col.active = lamp0.enabled
457         col.prop(lamp0, "direction", text="")
458
459
460         split = column.split(percentage=0.1)
461
462         if lamp1.enabled == True:
463             split.prop(lamp1, "enabled", text="", icon='OUTLINER_OB_LAMP')
464         else:
465             split.prop(lamp1, "enabled", text="", icon='LAMP_DATA')
466
467         col = split.column()
468         col.active = lamp1.enabled
469         row = col.row()
470         row.label(text="Diffuse:")
471         row.prop(lamp1, "diffuse_color", text="")
472         row = col.row()
473         row.label(text="Specular:")
474         row.prop(lamp1, "specular_color", text="")
475
476         col = split.column()
477         col.active = lamp1.enabled
478         col.prop(lamp1, "direction", text="")
479
480
481         split = column.split(percentage=0.1)
482
483         if lamp2.enabled == True:
484             split.prop(lamp2, "enabled", text="", icon='OUTLINER_OB_LAMP')
485         else:
486             split.prop(lamp2, "enabled", text="", icon='LAMP_DATA')
487
488         col = split.column()
489         col.active = lamp2.enabled
490         row = col.row()
491         row.label(text="Diffuse:")
492         row.prop(lamp2, "diffuse_color", text="")
493         row = col.row()
494         row.label(text="Specular:")
495         row.prop(lamp2, "specular_color", text="")
496
497         col = split.column()
498         col.active = lamp2.enabled
499         col.prop(lamp2, "direction", text="")
500
501
502         column.separator()
503         column.separator()
504         column.separator()
505
506         col = column.column()
507
508         col.prop(system, "use_weight_color_range", text="Custom Weight Paint Range")
509         sub = col.column()
510         sub.active = system.use_weight_color_range
511         sub.template_color_ramp(system, "weight_color_range", expand=True)
512
513
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
1336     def draw_kmi(self, kc, km, kmi, layout, level):
1337         layout.set_context_pointer("keyitem", kmi)
1338
1339         col = self.indented_layout(layout, level)
1340
1341         col.enabled = km.user_defined
1342
1343         if km.user_defined:
1344             col = col.column(align=True)
1345             box = col.box()
1346         else:
1347             box = col.column()
1348
1349         split = box.split(percentage=0.4)
1350
1351         # header bar
1352         row = split.row()
1353         row.prop(kmi, "expanded", text="", no_bg=True)
1354         row.prop(kmi, "active", text="", no_bg=True)
1355
1356         if km.modal:
1357             row.prop(kmi, "propvalue", text="")
1358         else:
1359             row.label(text=kmi.name)
1360
1361         row = split.row()
1362         row.prop(kmi, "map_type", text="")
1363         if kmi.map_type == 'KEYBOARD':
1364             row.prop(kmi, "type", text="", full_event=True)
1365         elif kmi.map_type == 'MOUSE':
1366             row.prop(kmi, "type", text="", full_event=True)
1367         elif kmi.map_type == 'TWEAK':
1368             subrow = row.row()
1369             subrow.prop(kmi, "type", text="")
1370             subrow.prop(kmi, "value", text="")
1371         elif kmi.map_type == 'TIMER':
1372             row.prop(kmi, "type", text="")
1373         else:
1374             row.label()
1375
1376         row.operator("wm.keyitem_restore", text="", icon='BACK')
1377         row.operator("wm.keyitem_remove", text="", icon='X')
1378
1379         # Expanded, additional event settings
1380         if kmi.expanded:
1381             box = col.box()
1382
1383             if kmi.map_type not in ('TEXTINPUT', 'TIMER'):
1384                 split = box.split(percentage=0.4)
1385                 sub = split.row()
1386
1387                 if km.modal:
1388                     sub.prop(kmi, "propvalue", text="")
1389                 else:
1390                     sub.prop(kmi, "idname", text="")
1391
1392                 sub = split.column()
1393                 subrow = sub.row(align=True)
1394
1395                 if kmi.map_type == 'KEYBOARD':
1396                     subrow.prop(kmi, "type", text="", event=True)
1397                     subrow.prop(kmi, "value", text="")
1398                 elif kmi.map_type == 'MOUSE':
1399                     subrow.prop(kmi, "type", text="")
1400                     subrow.prop(kmi, "value", text="")
1401
1402                 subrow = sub.row()
1403                 subrow.scale_x = 0.75
1404                 subrow.prop(kmi, "any")
1405                 subrow.prop(kmi, "shift")
1406                 subrow.prop(kmi, "ctrl")
1407                 subrow.prop(kmi, "alt")
1408                 subrow.prop(kmi, "oskey", text="Cmd")
1409                 subrow.prop(kmi, "key_modifier", text="", event=True)
1410
1411             # Operator properties
1412             props = kmi.properties
1413             if props is not None:
1414                 box.separator()
1415                 flow = box.column_flow(columns=2)
1416                 for pname in dir(props):
1417                     if not props.is_property_hidden(pname):
1418                         flow.prop(props, pname)
1419
1420             # Modal key maps attached to this operator
1421             if not km.modal:
1422                 kmm = kc.find_keymap_modal(kmi.idname)
1423                 if kmm:
1424                     self.draw_km(kc, kmm, None, layout, level + 1)
1425
1426     def draw_input_prefs(self, inputs, layout):
1427         # General settings
1428         row = layout.row()
1429         col = row.column()
1430
1431         sub = col.column()
1432         sub.label(text="Mouse:")
1433         sub1 = sub.column()
1434         sub1.enabled = (inputs.select_mouse == 'RIGHT')
1435         sub1.prop(inputs, "emulate_3_button_mouse")
1436         sub.prop(inputs, "continuous_mouse")
1437
1438         sub.label(text="Select With:")
1439         sub.row().prop(inputs, "select_mouse", expand=True)
1440
1441         sub = col.column()
1442         sub.label(text="Double Click:")
1443         sub.prop(inputs, "double_click_time", text="Speed")
1444
1445         sub.separator()
1446
1447         sub.prop(inputs, "emulate_numpad")
1448
1449         sub.separator()
1450
1451         sub.label(text="Orbit Style:")
1452         sub.row().prop(inputs, "view_rotation", expand=True)
1453
1454         sub.label(text="Zoom Style:")
1455         sub.row().prop(inputs, "viewport_zoom_style", expand=True)
1456         if inputs.viewport_zoom_style == 'DOLLY':
1457             sub.row().prop(inputs, "zoom_axis", expand=True)
1458             sub.prop(inputs, "invert_zoom_direction")
1459
1460         #sub.prop(inputs, "use_middle_mouse_paste")
1461
1462         #col.separator()
1463
1464         #sub = col.column()
1465         #sub.label(text="Mouse Wheel:")
1466         #sub.prop(view, "wheel_scroll_lines", text="Scroll Lines")
1467
1468         col.separator()
1469
1470         sub = col.column()
1471         sub.label(text="NDOF Device:")
1472         sub.prop(inputs, "ndof_pan_speed", text="Pan Speed")
1473         sub.prop(inputs, "ndof_rotate_speed", text="Orbit Speed")
1474
1475         row.separator()
1476
1477     def draw_filtered(self, kc, layout):
1478         filter = kc.filter.lower()
1479
1480         for km in kc.keymaps:
1481             filtered_items = [kmi for kmi in km.items if filter in kmi.name.lower()]
1482
1483             if len(filtered_items) != 0:
1484                 km = km.active()
1485
1486                 col = layout.column()
1487                 col.set_context_pointer("keymap", km)
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     def draw_hierarchy(self, defkc, layout):
1503         for entry in KM_HIERARCHY:
1504             self.draw_entry(defkc, entry, layout)
1505
1506     def draw(self, context):
1507         layout = self.layout
1508
1509         userpref = context.user_preferences
1510         wm = context.manager
1511
1512         inputs = userpref.inputs
1513
1514         split = layout.split(percentage=0.25)
1515
1516         # Input settings
1517         self.draw_input_prefs(inputs, split)
1518
1519         # Keymap Settings
1520         col = split.column()
1521         # kc = wm.active_keyconfig
1522         kc = wm.default_keyconfig
1523
1524         sub = col.column()
1525
1526         subsplit = sub.split()
1527         subcol = subsplit.column()
1528         subcol.prop_object(wm, "active_keyconfig", wm, "keyconfigs", text="Configuration:")
1529
1530         subcol = subsplit.column()
1531         subcol.prop(kc, "filter", icon="VIEWZOOM")
1532
1533         col.separator()
1534
1535         if kc.filter != "":
1536             self.draw_filtered(kc, col)
1537         else:
1538             self.draw_hierarchy(kc, col)
1539
1540 bpy.types.register(USERPREF_HT_header)
1541 bpy.types.register(USERPREF_PT_tabs)
1542 bpy.types.register(USERPREF_PT_interface)
1543 bpy.types.register(USERPREF_PT_theme)
1544 bpy.types.register(USERPREF_PT_edit)
1545 bpy.types.register(USERPREF_PT_system)
1546 bpy.types.register(USERPREF_PT_file)
1547 bpy.types.register(USERPREF_PT_input)
1548
1549 from bpy.props import *
1550
1551 class WM_OT_keyconfig_test(bpy.types.Operator):
1552     "Test keyconfig for conflicts."
1553     bl_idname = "wm.keyconfig_test"
1554     bl_label = "Test Key Configuration for Conflicts"
1555     
1556     def testEntry(self, kc, entry, src = None, parent = None):
1557         result = False
1558         def kmistr(kmi):
1559             if km.modal:
1560                 s = ["kmi = km.add_modal_item(\'%s\', \'%s\', \'%s\'" % (kmi.propvalue, kmi.type, kmi.value)]
1561             else:
1562                 s = ["kmi = km.add_item(\'%s\', \'%s\', \'%s\'" % (kmi.idname, kmi.type, kmi.value)]
1563
1564             if kmi.any:
1565                 s.append(", any=True")
1566             else:
1567                 if kmi.shift:
1568                     s.append(", shift=True")
1569                 if kmi.ctrl:
1570                     s.append(", ctrl=True")
1571                 if kmi.alt:
1572                     s.append(", alt=True")
1573                 if kmi.oskey:
1574                     s.append(", oskey=True")
1575             if kmi.key_modifier and kmi.key_modifier != 'NONE':
1576                 s.append(", key_modifier=\'%s\'" % kmi.key_modifier)
1577             
1578             s.append(")\n")
1579             
1580             props = kmi.properties
1581
1582             if props is not None:
1583                 for pname in dir(props):
1584                     if props.is_property_set(pname) and not props.is_property_hidden(pname):
1585                         value = eval("props.%s" % pname)
1586                         value = _string_value(value)
1587                         if value != "":
1588                             s.append("kmi.properties.%s = %s\n" % (pname, value))
1589                             
1590             return "".join(s).strip()
1591                         
1592         idname, spaceid, regionid, children = entry
1593
1594         km = kc.find_keymap(idname, space_type = spaceid, region_type = regionid)
1595         
1596         if km:
1597             km = km.active()
1598     
1599             if src:
1600                 for item in km.items:
1601                     if src.compare(item):
1602                         print("===========")
1603                         print(parent.name)
1604                         print(kmistr(src))
1605                         print(km.name)
1606                         print(kmistr(item))
1607                         result = True
1608                 
1609                 for child in children:
1610                     if self.testEntry(kc, child, src, parent):
1611                         result = True
1612             else:
1613                 for i in range(len(km.items)):
1614                     src = km.items[i]
1615                     
1616                     for child in children:
1617                         if self.testEntry(kc, child, src, km):
1618                             result = True
1619
1620                     for j in range(len(km.items) - i - 1):
1621                         item = km.items[j + i + 1]
1622                         if src.compare(item):
1623                             print("===========")
1624                             print(km.name)
1625                             print(kmistr(src))
1626                             print(kmistr(item))
1627                             result = True
1628     
1629                 for child in children:
1630                     if self.testEntry(kc, child):
1631                         result = True
1632         
1633         return result
1634     
1635     def testConfig(self, kc):
1636         result = False
1637         for entry in KM_HIERARCHY:
1638             if self.testEntry(kc, entry):
1639                 result = True
1640         return result
1641         
1642     def execute(self, context):
1643         wm = context.manager
1644         kc = wm.default_keyconfig
1645         
1646         if self.testConfig(kc):
1647             print("CONFLICT")
1648        
1649         return {'FINISHED'}
1650
1651 def _string_value(value):
1652     result = ""
1653     if isinstance(value, str):
1654         if value != "":
1655             result = "\'%s\'" % value
1656     elif isinstance(value, bool):
1657         if value:
1658             result = "True"
1659         else:
1660             result = "False"
1661     elif isinstance(value, float):
1662         result = "%.10f" % value
1663     elif isinstance(value, int):
1664         result = "%d" % value
1665     elif getattr(value, '__len__', False):
1666         if len(value):
1667             result = "["
1668             for i in range(0, len(value)):
1669                 result += _string_value(value[i])
1670                 if i != len(value)-1:
1671                     result += ", "
1672             result += "]"
1673     else:
1674         print("Export key configuration: can't write ", value)
1675
1676     return result
1677     
1678 class WM_OT_keyconfig_export(bpy.types.Operator):
1679     "Export key configuration to a python script."
1680     bl_idname = "wm.keyconfig_export"
1681     bl_label = "Export Key Configuration..."
1682
1683     path = bpy.props.StringProperty(name="File Path", description="File path to write file to.")
1684
1685     def execute(self, context):
1686         if not self.properties.path:
1687             raise Exception("File path not set.")
1688
1689         f = open(self.properties.path, "w")
1690         if not f:
1691             raise Exception("Could not open file.")
1692
1693         wm = context.manager
1694         kc = wm.active_keyconfig
1695
1696         f.write('# Configuration %s\n' % kc.name)
1697
1698         f.write("wm = bpy.data.windowmanagers[0]\n")
1699         f.write("kc = wm.add_keyconfig(\'%s\')\n\n" % kc.name)
1700
1701         for km in kc.keymaps:
1702             km = km.active()
1703             f.write("# Map %s\n" % km.name)
1704             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))
1705             for kmi in km.items:
1706                 if km.modal:
1707                     f.write("kmi = km.add_modal_item(\'%s\', \'%s\', \'%s\'" % (kmi.propvalue, kmi.type, kmi.value))
1708                 else:
1709                     f.write("kmi = km.add_item(\'%s\', \'%s\', \'%s\'" % (kmi.idname, kmi.type, kmi.value))
1710                 if kmi.any:
1711                     f.write(", any=True")
1712                 else:
1713                     if kmi.shift:
1714                         f.write(", shift=True")
1715                     if kmi.ctrl:
1716                         f.write(", ctrl=True")
1717                     if kmi.alt:
1718                         f.write(", alt=True")
1719                     if kmi.oskey:
1720                         f.write(", oskey=True")
1721                 if kmi.key_modifier and kmi.key_modifier != 'NONE':
1722                     f.write(", key_modifier=\'%s\'" % kmi.key_modifier)
1723                 f.write(")\n")
1724
1725                 props = kmi.properties
1726
1727                 if props is not None:
1728                     for pname in dir(props):
1729                         if props.is_property_set(pname) and not props.is_property_hidden(pname):
1730                             value = eval("props.%s" % pname)
1731                             value = _string_value(value)
1732                             if value != "":
1733                                 f.write("kmi.properties.%s = %s\n" % (pname, value))
1734
1735             f.write("\n")
1736
1737         f.close()
1738
1739         return {'FINISHED'}
1740
1741     def invoke(self, context, event):
1742         wm = context.manager
1743         wm.add_fileselect(self)
1744         return {'RUNNING_MODAL'}
1745
1746
1747 class WM_OT_keymap_edit(bpy.types.Operator):
1748     "Edit key map."
1749     bl_idname = "wm.keymap_edit"
1750     bl_label = "Edit Key Map"
1751
1752     def execute(self, context):
1753         wm = context.manager
1754         km = context.keymap
1755         km.copy_to_user()
1756         return {'FINISHED'}
1757
1758
1759 class WM_OT_keymap_restore(bpy.types.Operator):
1760     "Restore key map(s)."
1761     bl_idname = "wm.keymap_restore"
1762     bl_label = "Restore Key Map(s)"
1763
1764     all = BoolProperty(attr="all", name="All Keymaps", description="Restore all keymaps to default.")
1765
1766     def execute(self, context):
1767         wm = context.manager
1768
1769         if self.properties.all:
1770             for km in wm.default_keyconfig.keymaps:
1771                 km.restore_to_default()
1772         else:
1773             km = context.keymap
1774             km.restore_to_default()
1775
1776         return {'FINISHED'}
1777
1778 class WM_OT_keyitem_restore(bpy.types.Operator):
1779     "Restore key map item."
1780     bl_idname = "wm.keyitem_restore"
1781     bl_label = "Restore Key Map Item"
1782
1783     def poll(self, context):
1784         kmi = context.keyitem
1785         km = context.keymap
1786         return km and kmi and kmi.id != 0
1787
1788     def execute(self, context):
1789         wm = context.manager
1790         kmi = context.keyitem
1791         km = context.keymap
1792
1793         km.restore_item_to_default(kmi)
1794
1795         return {'FINISHED'}
1796     
1797 class WM_OT_keyitem_add(bpy.types.Operator):
1798     "Add key map item."
1799     bl_idname = "wm.keyitem_add"
1800     bl_label = "Add Key Map Item"
1801
1802     def execute(self, context):
1803         wm = context.manager
1804         km = context.keymap
1805         if km.modal:
1806             km.add_modal_item("", 'A', 'PRESS') # kmi
1807         else:
1808             km.add_item("", 'A', 'PRESS') # kmi
1809         return {'FINISHED'}
1810
1811
1812 class WM_OT_keyitem_remove(bpy.types.Operator):
1813     "Remove key map item."
1814     bl_idname = "wm.keyitem_remove"
1815     bl_label = "Remove Key Map Item"
1816
1817     def execute(self, context):
1818         wm = context.manager
1819         kmi = context.keyitem
1820         km = context.keymap
1821         km.remove_item(kmi)
1822         return {'FINISHED'}
1823
1824 bpy.types.register(WM_OT_keyconfig_export)
1825 bpy.types.register(WM_OT_keyconfig_test)
1826 bpy.types.register(WM_OT_keymap_edit)
1827 bpy.types.register(WM_OT_keymap_restore)
1828 bpy.types.register(WM_OT_keyitem_add)
1829 bpy.types.register(WM_OT_keyitem_remove)
1830 bpy.types.register(WM_OT_keyitem_restore)