Another fix for r54414 (cleaner to "import" pgettext once at top of files, also now...
[blender.git] / release / scripts / startup / bl_ui / space_userpref_keymap.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21 from bpy.types import Menu
22
23 _ = bpy.app.translations.pgettext
24
25
26 class USERPREF_MT_keyconfigs(Menu):
27     bl_label = "KeyPresets"
28     preset_subdir = "keyconfig"
29     preset_operator = "wm.keyconfig_activate"
30
31     def draw(self, context):
32         props = self.layout.operator("wm.context_set_value", text="Blender (default)")
33         props.data_path = "window_manager.keyconfigs.active"
34         props.value = "context.window_manager.keyconfigs.default"
35
36         # now draw the presets
37         Menu.draw_preset(self, context)
38
39
40 class InputKeyMapPanel:
41     bl_space_type = 'USER_PREFERENCES'
42     bl_label = "Input"
43     bl_region_type = 'WINDOW'
44     bl_options = {'HIDE_HEADER'}
45
46     def draw_entry(self, display_keymaps, entry, col, level=0):
47         idname, spaceid, regionid, children = entry
48
49         for km, kc in display_keymaps:
50             if km.name == idname and km.space_type == spaceid and km.region_type == regionid:
51                 self.draw_km(display_keymaps, kc, km, children, col, level)
52
53         '''
54         km = kc.keymaps.find(idname, space_type=spaceid, region_type=regionid)
55         if not km:
56             kc = defkc
57             km = kc.keymaps.find(idname, space_type=spaceid, region_type=regionid)
58
59         if km:
60             self.draw_km(kc, km, children, col, level)
61         '''
62
63     def indented_layout(self, layout, level):
64         indentpx = 16
65         if level == 0:
66             level = 0.0001   # Tweak so that a percentage of 0 won't split by half
67         indent = level * indentpx / bpy.context.region.width
68
69         split = layout.split(percentage=indent)
70         col = split.column()
71         col = split.column()
72         return col
73
74     def draw_km(self, display_keymaps, kc, km, children, layout, level):
75         km = km.active()
76
77         layout.context_pointer_set("keymap", km)
78
79         col = self.indented_layout(layout, level)
80
81         row = col.row()
82         row.prop(km, "show_expanded_children", text="", emboss=False)
83         row.label(text=km.name)
84
85         row.label()
86         row.label()
87
88         if km.is_modal:
89             row.label(text="", icon='LINKED')
90         if km.is_user_modified:
91             row.operator("wm.keymap_restore", text="Restore")
92         else:
93             row.label()
94
95         if km.show_expanded_children:
96             if children:
97                 # Put the Parent key map's entries in a 'global' sub-category
98                 # equal in hierarchy to the other children categories
99                 subcol = self.indented_layout(col, level + 1)
100                 subrow = subcol.row()
101                 subrow.prop(km, "show_expanded_items", text="", emboss=False)
102                 subrow.label(text=_("%s (Global)") % km.name, translate=False)
103             else:
104                 km.show_expanded_items = True
105
106             # Key Map items
107             if km.show_expanded_items:
108                 for kmi in km.keymap_items:
109                     self.draw_kmi(display_keymaps, kc, km, kmi, col, level + 1)
110
111                 # "Add New" at end of keymap item list
112                 col = self.indented_layout(col, level + 1)
113                 subcol = col.split(percentage=0.2).column()
114                 subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
115
116             col.separator()
117
118             # Child key maps
119             if children:
120                 subcol = col.column()
121                 row = subcol.row()
122
123                 for entry in children:
124                     self.draw_entry(display_keymaps, entry, col, level + 1)
125
126     def draw_kmi(self, display_keymaps, kc, km, kmi, layout, level):
127         map_type = kmi.map_type
128
129         col = self.indented_layout(layout, level)
130
131         if kmi.show_expanded:
132             col = col.column(align=True)
133             box = col.box()
134         else:
135             box = col.column()
136
137         split = box.split(percentage=0.05)
138
139         # header bar
140         row = split.row()
141         row.prop(kmi, "show_expanded", text="", emboss=False)
142
143         row = split.row()
144         row.prop(kmi, "active", text="", emboss=False)
145
146         if km.is_modal:
147             row.prop(kmi, "propvalue", text="")
148         else:
149             row.label(text=kmi.name)
150
151         row = split.row()
152         row.prop(kmi, "map_type", text="")
153         if map_type == 'KEYBOARD':
154             row.prop(kmi, "type", text="", full_event=True)
155         elif map_type == 'MOUSE':
156             row.prop(kmi, "type", text="", full_event=True)
157         elif map_type == 'NDOF':
158             row.prop(kmi, "type", text="", full_event=True)
159         elif map_type == 'TWEAK':
160             subrow = row.row()
161             subrow.prop(kmi, "type", text="")
162             subrow.prop(kmi, "value", text="")
163         elif map_type == 'TIMER':
164             row.prop(kmi, "type", text="")
165         else:
166             row.label()
167
168         if (not kmi.is_user_defined) and kmi.is_user_modified:
169             row.operator("wm.keyitem_restore", text="", icon='BACK').item_id = kmi.id
170         else:
171             row.operator("wm.keyitem_remove", text="", icon='X').item_id = kmi.id
172
173         # Expanded, additional event settings
174         if kmi.show_expanded:
175             box = col.box()
176
177             split = box.split(percentage=0.4)
178             sub = split.row()
179
180             if km.is_modal:
181                 sub.prop(kmi, "propvalue", text="")
182             else:
183                 # One day...
184                 #~ sub.prop_search(kmi, "idname", bpy.context.window_manager, "operators_all", text="")
185                 sub.prop(kmi, "idname", text="")
186
187             if map_type not in {'TEXTINPUT', 'TIMER'}:
188                 sub = split.column()
189                 subrow = sub.row(align=True)
190
191                 if map_type == 'KEYBOARD':
192                     subrow.prop(kmi, "type", text="", event=True)
193                     subrow.prop(kmi, "value", text="")
194                 elif map_type in {'MOUSE', 'NDOF'}:
195                     subrow.prop(kmi, "type", text="")
196                     subrow.prop(kmi, "value", text="")
197
198                 subrow = sub.row()
199                 subrow.scale_x = 0.75
200                 subrow.prop(kmi, "any")
201                 subrow.prop(kmi, "shift")
202                 subrow.prop(kmi, "ctrl")
203                 subrow.prop(kmi, "alt")
204                 subrow.prop(kmi, "oskey", text="Cmd")
205                 subrow.prop(kmi, "key_modifier", text="", event=True)
206
207             # Operator properties
208             box.template_keymap_item_properties(kmi)
209
210             # Modal key maps attached to this operator
211             if not km.is_modal:
212                 kmm = kc.keymaps.find_modal(kmi.idname)
213                 if kmm:
214                     self.draw_km(display_keymaps, kc, kmm, None, layout, level + 1)
215                     layout.context_pointer_set("keymap", km)
216
217     def draw_filtered(self, display_keymaps, filter_text, layout):
218         for km, kc in display_keymaps:
219             km = km.active()
220             layout.context_pointer_set("keymap", km)
221
222             filtered_items = [kmi for kmi in km.keymap_items
223                               if (filter_text in kmi.idname.lower() or
224                                   filter_text in kmi.name.lower())]
225
226             if filtered_items:
227                 col = layout.column()
228
229                 row = col.row()
230                 row.label(text=km.name, icon='DOT')
231
232                 row.label()
233                 row.label()
234
235                 if km.is_user_modified:
236                     row.operator("wm.keymap_restore", text="Restore")
237                 else:
238                     row.label()
239
240                 for kmi in filtered_items:
241                     self.draw_kmi(display_keymaps, kc, km, kmi, col, 1)
242
243                 # "Add New" at end of keymap item list
244                 col = self.indented_layout(layout, 1)
245                 subcol = col.split(percentage=0.2).column()
246                 subcol.operator("wm.keyitem_add", text="Add New", icon='ZOOMIN')
247
248     def draw_hierarchy(self, display_keymaps, layout):
249         from bpy_extras import keyconfig_utils
250         for entry in keyconfig_utils.KM_HIERARCHY:
251             self.draw_entry(display_keymaps, entry, layout)
252
253     def draw_keymaps(self, context, layout):
254         from bpy_extras import keyconfig_utils
255
256         wm = context.window_manager
257         kc = wm.keyconfigs.user
258
259         col = layout.column()
260         sub = col.column()
261
262         subsplit = sub.split()
263         subcol = subsplit.column()
264
265         row = subcol.row(align=True)
266
267         #~ row.prop_search(wm.keyconfigs, "active", wm, "keyconfigs", text="Key Config:")
268         text = bpy.path.display_name(context.window_manager.keyconfigs.active.name)
269         if not text:
270             text = "Blender (default)"
271         row.menu("USERPREF_MT_keyconfigs", text=text)
272         row.operator("wm.keyconfig_preset_add", text="", icon='ZOOMIN')
273         row.operator("wm.keyconfig_preset_add", text="", icon='ZOOMOUT').remove_active = True
274
275         #~ layout.context_pointer_set("keyconfig", wm.keyconfigs.active)
276         #~ row.operator("wm.keyconfig_remove", text="", icon='X')
277
278         row.prop(context.space_data, "filter_text", icon='VIEWZOOM')
279
280         col.separator()
281
282         display_keymaps = keyconfig_utils.keyconfig_merge(kc, kc)
283         if context.space_data.filter_text != "":
284             filter_text = context.space_data.filter_text.lower()
285             self.draw_filtered(display_keymaps, filter_text, col)
286         else:
287             self.draw_hierarchy(display_keymaps, col)
288
289
290 if __name__ == "__main__":  # only for live edit.
291     bpy.utils.register_module(__name__)