Merge branch 'master' into blender2.8
[blender.git] / source / blender / windowmanager / intern / wm_keymap_utils.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * ***** END GPL LICENSE BLOCK *****
19  */
20
21 /** \file blender/windowmanager/intern/wm_keymap_utils.c
22  *  \ingroup wm
23  *
24  * Utilities to help define keymaps.
25  */
26
27 #include <string.h>
28
29 #include "DNA_object_types.h"
30 #include "DNA_space_types.h"
31 #include "DNA_userdef_types.h"
32 #include "DNA_windowmanager_types.h"
33
34 #include "BLI_utildefines.h"
35
36 #include "BKE_context.h"
37
38 #include "RNA_access.h"
39
40 #include "WM_api.h"
41 #include "WM_types.h"
42
43 /* menu wrapper for WM_keymap_add_item */
44
45 /* -------------------------------------------------------------------- */
46 /** \name Wrappers for #WM_keymap_add_item
47  * \{ */
48
49 /* menu wrapper for WM_keymap_add_item */
50 wmKeyMapItem *WM_keymap_add_menu(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
51 {
52         wmKeyMapItem *kmi = WM_keymap_add_item(keymap, "WM_OT_call_menu", type, val, modifier, keymodifier);
53         RNA_string_set(kmi->ptr, "name", idname);
54         return kmi;
55 }
56
57 wmKeyMapItem *WM_keymap_add_menu_pie(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
58 {
59         wmKeyMapItem *kmi = WM_keymap_add_item(keymap, "WM_OT_call_menu_pie", type, val, modifier, keymodifier);
60         RNA_string_set(kmi->ptr, "name", idname);
61         return kmi;
62 }
63
64 wmKeyMapItem *WM_keymap_add_panel(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
65 {
66         wmKeyMapItem *kmi = WM_keymap_add_item(keymap, "WM_OT_call_panel", type, val, modifier, keymodifier);
67         RNA_string_set(kmi->ptr, "name", idname);
68         /* TODO: we might want to disable this. */
69         RNA_boolean_set(kmi->ptr, "keep_open", false);
70         return kmi;
71 }
72
73 /* tool wrapper for WM_keymap_add_item */
74 wmKeyMapItem *WM_keymap_add_tool(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
75 {
76         wmKeyMapItem *kmi = WM_keymap_add_item(keymap, "WM_OT_tool_set_by_name", type, val, modifier, keymodifier);
77         RNA_string_set(kmi->ptr, "name", idname);
78         return kmi;
79 }
80
81 /** Useful for mapping numbers to an enum. */
82 void WM_keymap_add_context_enum_set_items(
83         wmKeyMap *keymap, const EnumPropertyItem *items, const char *data_path,
84         int type_start, int val, int modifier, int keymodifier)
85 {
86         for (int i = 0, type_offset = 0; items[i].identifier; i++) {
87                 if (items[i].identifier[0] == '\0') {
88                         continue;
89                 }
90                 wmKeyMapItem *kmi = WM_keymap_add_item(
91                         keymap, "WM_OT_context_set_enum",
92                         type_start + type_offset, val, modifier, keymodifier);
93                 RNA_string_set(kmi->ptr, "data_path", data_path);
94                 RNA_string_set(kmi->ptr, "value", items[i].identifier);
95                 type_offset += 1;
96         }
97 }
98
99 /** \} */
100
101 /* -------------------------------------------------------------------- */
102 /** \name Introspection
103  * \{ */
104
105 /* Guess an appropriate keymap from the operator name */
106 /* Needs to be kept up to date with Keymap and Operator naming */
107 wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
108 {
109         /* Op types purposely skipped  for now:
110          *     BRUSH_OT
111          *     BOID_OT
112          *     BUTTONS_OT
113          *     CONSTRAINT_OT
114          *     PAINT_OT
115          *     ED_OT
116          *     FLUID_OT
117          *     TEXTURE_OT
118          *     UI_OT
119          *     VIEW2D_OT
120          *     WORLD_OT
121          */
122
123         wmKeyMap *km = NULL;
124         SpaceLink *sl = CTX_wm_space_data(C);
125
126         /* Window */
127         if (STRPREFIX(opname, "WM_OT")) {
128                 km = WM_keymap_find_all(C, "Window", 0, 0);
129         }
130         /* Screen & Render */
131         else if (STRPREFIX(opname, "SCREEN_OT") ||
132                  STRPREFIX(opname, "RENDER_OT") ||
133                  STRPREFIX(opname, "SOUND_OT") ||
134                  STRPREFIX(opname, "SCENE_OT"))
135         {
136                 km = WM_keymap_find_all(C, "Screen", 0, 0);
137         }
138         /* Grease Pencil */
139         else if (STRPREFIX(opname, "GPENCIL_OT")) {
140                 km = WM_keymap_find_all(C, "Grease Pencil", 0, 0);
141         }
142         /* Markers */
143         else if (STRPREFIX(opname, "MARKER_OT")) {
144                 km = WM_keymap_find_all(C, "Markers", 0, 0);
145         }
146         /* Import/Export*/
147         else if (STRPREFIX(opname, "IMPORT_") ||
148                  STRPREFIX(opname, "EXPORT_"))
149         {
150                 km = WM_keymap_find_all(C, "Window", 0, 0);
151         }
152
153
154         /* 3D View */
155         else if (STRPREFIX(opname, "VIEW3D_OT")) {
156                 km = WM_keymap_find_all(C, "3D View", sl->spacetype, 0);
157         }
158         else if (STRPREFIX(opname, "OBJECT_OT")) {
159                 /* exception, this needs to work outside object mode too */
160                 if (STRPREFIX(opname, "OBJECT_OT_mode_set"))
161                         km = WM_keymap_find_all(C, "Object Non-modal", 0, 0);
162                 else
163                         km = WM_keymap_find_all(C, "Object Mode", 0, 0);
164         }
165         /* Object mode related */
166         else if (STRPREFIX(opname, "GROUP_OT") ||
167                  STRPREFIX(opname, "MATERIAL_OT") ||
168                  STRPREFIX(opname, "PTCACHE_OT") ||
169                  STRPREFIX(opname, "RIGIDBODY_OT"))
170         {
171                 km = WM_keymap_find_all(C, "Object Mode", 0, 0);
172         }
173
174         /* Editing Modes */
175         else if (STRPREFIX(opname, "MESH_OT")) {
176                 km = WM_keymap_find_all(C, "Mesh", 0, 0);
177
178                 /* some mesh operators are active in object mode too, like add-prim */
179                 if (km && !WM_keymap_poll((bContext *)C, km)) {
180                         km = WM_keymap_find_all(C, "Object Mode", 0, 0);
181                 }
182         }
183         else if (STRPREFIX(opname, "CURVE_OT") ||
184                  STRPREFIX(opname, "SURFACE_OT"))
185         {
186                 km = WM_keymap_find_all(C, "Curve", 0, 0);
187
188                 /* some curve operators are active in object mode too, like add-prim */
189                 if (km && !WM_keymap_poll((bContext *)C, km)) {
190                         km = WM_keymap_find_all(C, "Object Mode", 0, 0);
191                 }
192         }
193         else if (STRPREFIX(opname, "ARMATURE_OT") ||
194                  STRPREFIX(opname, "SKETCH_OT"))
195         {
196                 km = WM_keymap_find_all(C, "Armature", 0, 0);
197         }
198         else if (STRPREFIX(opname, "POSE_OT") ||
199                  STRPREFIX(opname, "POSELIB_OT"))
200         {
201                 km = WM_keymap_find_all(C, "Pose", 0, 0);
202         }
203         else if (STRPREFIX(opname, "SCULPT_OT")) {
204                 switch (CTX_data_mode_enum(C)) {
205                         case OB_MODE_SCULPT:
206                                 km = WM_keymap_find_all(C, "Sculpt", 0, 0);
207                                 break;
208                         case OB_MODE_EDIT:
209                                 km = WM_keymap_find_all(C, "UV Sculpt", 0, 0);
210                                 break;
211                 }
212         }
213         else if (STRPREFIX(opname, "MBALL_OT")) {
214                 km = WM_keymap_find_all(C, "Metaball", 0, 0);
215
216                 /* some mball operators are active in object mode too, like add-prim */
217                 if (km && !WM_keymap_poll((bContext *)C, km)) {
218                         km = WM_keymap_find_all(C, "Object Mode", 0, 0);
219                 }
220         }
221         else if (STRPREFIX(opname, "LATTICE_OT")) {
222                 km = WM_keymap_find_all(C, "Lattice", 0, 0);
223         }
224         else if (STRPREFIX(opname, "PARTICLE_OT")) {
225                 km = WM_keymap_find_all(C, "Particle", 0, 0);
226         }
227         else if (STRPREFIX(opname, "FONT_OT")) {
228                 km = WM_keymap_find_all(C, "Font", 0, 0);
229         }
230         /* Paint Face Mask */
231         else if (STRPREFIX(opname, "PAINT_OT_face_select")) {
232                 km = WM_keymap_find_all(C, "Face Mask", 0, 0);
233         }
234         else if (STRPREFIX(opname, "PAINT_OT")) {
235                 /* check for relevant mode */
236                 switch (CTX_data_mode_enum(C)) {
237                         case OB_MODE_WEIGHT_PAINT:
238                                 km = WM_keymap_find_all(C, "Weight Paint", 0, 0);
239                                 break;
240                         case OB_MODE_VERTEX_PAINT:
241                                 km = WM_keymap_find_all(C, "Vertex Paint", 0, 0);
242                                 break;
243                         case OB_MODE_TEXTURE_PAINT:
244                                 km = WM_keymap_find_all(C, "Image Paint", 0, 0);
245                                 break;
246                 }
247         }
248         /* Image Editor */
249         else if (STRPREFIX(opname, "IMAGE_OT")) {
250                 km = WM_keymap_find_all(C, "Image", sl->spacetype, 0);
251         }
252         /* Clip Editor */
253         else if (STRPREFIX(opname, "CLIP_OT")) {
254                 km = WM_keymap_find_all(C, "Clip", sl->spacetype, 0);
255         }
256         else if (STRPREFIX(opname, "MASK_OT")) {
257                 km = WM_keymap_find_all(C, "Mask Editing", 0, 0);
258         }
259         /* UV Editor */
260         else if (STRPREFIX(opname, "UV_OT")) {
261                 /* Hack to allow using UV unwrapping ops from 3DView/editmode.
262                  * Mesh keymap is probably not ideal, but best place I could find to put those. */
263                 if (sl->spacetype == SPACE_VIEW3D) {
264                         km = WM_keymap_find_all(C, "Mesh", 0, 0);
265                         if (km && !WM_keymap_poll((bContext *)C, km)) {
266                                 km = NULL;
267                         }
268                 }
269                 if (!km) {
270                         km = WM_keymap_find_all(C, "UV Editor", 0, 0);
271                 }
272         }
273         /* Node Editor */
274         else if (STRPREFIX(opname, "NODE_OT")) {
275                 km = WM_keymap_find_all(C, "Node Editor", sl->spacetype, 0);
276         }
277         /* Animation Editor Channels */
278         else if (STRPREFIX(opname, "ANIM_OT_channels")) {
279                 km = WM_keymap_find_all(C, "Animation Channels", 0, 0);
280         }
281         /* Animation Generic - after channels */
282         else if (STRPREFIX(opname, "ANIM_OT")) {
283                 km = WM_keymap_find_all(C, "Animation", 0, 0);
284         }
285         /* Graph Editor */
286         else if (STRPREFIX(opname, "GRAPH_OT")) {
287                 km = WM_keymap_find_all(C, "Graph Editor", sl->spacetype, 0);
288         }
289         /* Dopesheet Editor */
290         else if (STRPREFIX(opname, "ACTION_OT")) {
291                 km = WM_keymap_find_all(C, "Dopesheet", sl->spacetype, 0);
292         }
293         /* NLA Editor */
294         else if (STRPREFIX(opname, "NLA_OT")) {
295                 km = WM_keymap_find_all(C, "NLA Editor", sl->spacetype, 0);
296         }
297         /* Script */
298         else if (STRPREFIX(opname, "SCRIPT_OT")) {
299                 km = WM_keymap_find_all(C, "Script", sl->spacetype, 0);
300         }
301         /* Text */
302         else if (STRPREFIX(opname, "TEXT_OT")) {
303                 km = WM_keymap_find_all(C, "Text", sl->spacetype, 0);
304         }
305         /* Sequencer */
306         else if (STRPREFIX(opname, "SEQUENCER_OT")) {
307                 km = WM_keymap_find_all(C, "Sequencer", sl->spacetype, 0);
308         }
309         /* Console */
310         else if (STRPREFIX(opname, "CONSOLE_OT")) {
311                 km = WM_keymap_find_all(C, "Console", sl->spacetype, 0);
312         }
313         /* Console */
314         else if (STRPREFIX(opname, "INFO_OT")) {
315                 km = WM_keymap_find_all(C, "Info", sl->spacetype, 0);
316         }
317         /* File browser */
318         else if (STRPREFIX(opname, "FILE_OT")) {
319                 km = WM_keymap_find_all(C, "File Browser", sl->spacetype, 0);
320         }
321         /* Logic Editor */
322         else if (STRPREFIX(opname, "LOGIC_OT")) {
323                 km = WM_keymap_find_all(C, "Logic Editor", sl->spacetype, 0);
324         }
325         /* Outliner */
326         else if (STRPREFIX(opname, "OUTLINER_OT")) {
327                 km = WM_keymap_find_all(C, "Outliner", sl->spacetype, 0);
328         }
329         /* Transform */
330         else if (STRPREFIX(opname, "TRANSFORM_OT")) {
331                 /* check for relevant editor */
332                 switch (sl->spacetype) {
333                         case SPACE_VIEW3D:
334                                 km = WM_keymap_find_all(C, "3D View", sl->spacetype, 0);
335                                 break;
336                         case SPACE_IPO:
337                                 km = WM_keymap_find_all(C, "Graph Editor", sl->spacetype, 0);
338                                 break;
339                         case SPACE_ACTION:
340                                 km = WM_keymap_find_all(C, "Dopesheet", sl->spacetype, 0);
341                                 break;
342                         case SPACE_NLA:
343                                 km = WM_keymap_find_all(C, "NLA Editor", sl->spacetype, 0);
344                                 break;
345                         case SPACE_IMAGE:
346                                 km = WM_keymap_find_all(C, "UV Editor", 0, 0);
347                                 break;
348                         case SPACE_NODE:
349                                 km = WM_keymap_find_all(C, "Node Editor", sl->spacetype, 0);
350                                 break;
351                         case SPACE_SEQ:
352                                 km = WM_keymap_find_all(C, "Sequencer", sl->spacetype, 0);
353                                 break;
354                 }
355         }
356
357         return km;
358 }
359
360 /** \} */