Blender  V2.93
wm_keymap_utils.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
23 #include <string.h>
24 
25 #include "DNA_object_types.h"
26 #include "DNA_space_types.h"
27 #include "DNA_userdef_types.h"
29 
30 #include "BLI_listbase.h"
31 #include "BLI_utildefines.h"
32 
33 #include "BKE_context.h"
34 
35 #include "RNA_access.h"
36 
37 #include "WM_api.h"
38 #include "WM_types.h"
39 
40 /* menu wrapper for WM_keymap_add_item */
41 
42 /* -------------------------------------------------------------------- */
46 /* menu wrapper for WM_keymap_add_item */
48  wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
49 {
51  keymap, "WM_OT_call_menu", type, val, modifier, keymodifier);
52  RNA_string_set(kmi->ptr, "name", idname);
53  return kmi;
54 }
55 
57  wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
58 {
60  keymap, "WM_OT_call_menu_pie", type, val, modifier, keymodifier);
61  RNA_string_set(kmi->ptr, "name", idname);
62  return kmi;
63 }
64 
66  wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
67 {
69  keymap, "WM_OT_call_panel", type, val, modifier, keymodifier);
70  RNA_string_set(kmi->ptr, "name", idname);
71  /* TODO: we might want to disable this. */
72  RNA_boolean_set(kmi->ptr, "keep_open", false);
73  return kmi;
74 }
75 
76 /* tool wrapper for WM_keymap_add_item */
78  wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
79 {
81  keymap, "WM_OT_tool_set_by_id", type, val, modifier, keymodifier);
82  RNA_string_set(kmi->ptr, "name", idname);
83  return kmi;
84 }
85 
88  const EnumPropertyItem *items,
89  const char *data_path,
90  int type_start,
91  int val,
92  int modifier,
93  int keymodifier)
94 {
95  for (int i = 0, type_offset = 0; items[i].identifier; i++) {
96  if (items[i].identifier[0] == '\0') {
97  continue;
98  }
100  keymap, "WM_OT_context_set_enum", type_start + type_offset, val, modifier, keymodifier);
101  RNA_string_set(kmi->ptr, "data_path", data_path);
102  RNA_string_set(kmi->ptr, "value", items[i].identifier);
103  type_offset += 1;
104  }
105 }
106 
109 /* -------------------------------------------------------------------- */
114 {
116  const char *km_id = NULL;
117  if (sl->spacetype == SPACE_VIEW3D) {
118  const enum eContextObjectMode mode = CTX_data_mode_enum(C);
119  switch (mode) {
120  case CTX_MODE_EDIT_MESH:
121  km_id = "Mesh";
122  break;
123  case CTX_MODE_EDIT_CURVE:
124  km_id = "Curve";
125  break;
127  km_id = "Curve";
128  break;
129  case CTX_MODE_EDIT_TEXT:
130  km_id = "Font";
131  break;
133  km_id = "Armature";
134  break;
136  km_id = "Metaball";
137  break;
139  km_id = "Lattice";
140  break;
141  case CTX_MODE_POSE:
142  km_id = "Pose";
143  break;
144  case CTX_MODE_SCULPT:
145  km_id = "Sculpt";
146  break;
148  km_id = "Weight Paint";
149  break;
151  km_id = "Vertex Paint";
152  break;
154  km_id = "Image Paint";
155  break;
156  case CTX_MODE_PARTICLE:
157  km_id = "Particle";
158  break;
159  case CTX_MODE_OBJECT:
160  km_id = "Object Mode";
161  break;
163  km_id = "Grease Pencil Stroke Paint Mode";
164  break;
166  km_id = "Grease Pencil Stroke Edit Mode";
167  break;
169  km_id = "Grease Pencil Stroke Sculpt Mode";
170  break;
172  km_id = "Grease Pencil Stroke Weight Mode";
173  break;
175  km_id = "Grease Pencil Stroke Vertex Mode";
176  break;
177  }
178  }
179  else if (sl->spacetype == SPACE_IMAGE) {
180  const SpaceImage *sima = (SpaceImage *)sl;
181  const eSpaceImage_Mode mode = sima->mode;
182  switch (mode) {
183  case SI_MODE_VIEW:
184  km_id = "Image";
185  break;
186  case SI_MODE_PAINT:
187  km_id = "Image Paint";
188  break;
189  case SI_MODE_MASK:
190  km_id = "Mask Editing";
191  break;
192  case SI_MODE_UV:
193  km_id = "UV Editor";
194  break;
195  }
196  }
197  else {
198  return NULL;
199  }
200 
201  wmKeyMap *km = WM_keymap_find_all(CTX_wm_manager(C), km_id, 0, 0);
202  BLI_assert(km);
203  return km;
204 }
205 
206 /* Guess an appropriate keymap from the operator name */
207 /* Needs to be kept up to date with Keymap and Operator naming */
208 wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
209 {
210  /* Op types purposely skipped for now:
211  * BRUSH_OT
212  * BOID_OT
213  * BUTTONS_OT
214  * CONSTRAINT_OT
215  * PAINT_OT
216  * ED_OT
217  * FLUID_OT
218  * TEXTURE_OT
219  * UI_OT
220  * WORLD_OT
221  */
222 
223  wmKeyMap *km = NULL;
226 
227  /* Window */
228  if (STRPREFIX(opname, "WM_OT") || STRPREFIX(opname, "ED_OT_undo")) {
229  if (STREQ(opname, "WM_OT_tool_set_by_id")) {
231  }
232 
233  if (km == NULL) {
234  km = WM_keymap_find_all(wm, "Window", 0, 0);
235  }
236  }
237  /* Screen & Render */
238  else if (STRPREFIX(opname, "SCREEN_OT") || STRPREFIX(opname, "RENDER_OT") ||
239  STRPREFIX(opname, "SOUND_OT") || STRPREFIX(opname, "SCENE_OT")) {
240  km = WM_keymap_find_all(wm, "Screen", 0, 0);
241  }
242  /* Grease Pencil */
243  else if (STRPREFIX(opname, "GPENCIL_OT")) {
244  km = WM_keymap_find_all(wm, "Grease Pencil", 0, 0);
245  }
246  /* Markers */
247  else if (STRPREFIX(opname, "MARKER_OT")) {
248  km = WM_keymap_find_all(wm, "Markers", 0, 0);
249  }
250  /* Import/Export*/
251  else if (STRPREFIX(opname, "IMPORT_") || STRPREFIX(opname, "EXPORT_")) {
252  km = WM_keymap_find_all(wm, "Window", 0, 0);
253  }
254 
255  /* 3D View */
256  else if (STRPREFIX(opname, "VIEW3D_OT")) {
257  km = WM_keymap_find_all(wm, "3D View", sl->spacetype, 0);
258  }
259  else if (STRPREFIX(opname, "OBJECT_OT")) {
260  /* exception, this needs to work outside object mode too */
261  if (STRPREFIX(opname, "OBJECT_OT_mode_set")) {
262  km = WM_keymap_find_all(wm, "Object Non-modal", 0, 0);
263  }
264  else {
265  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
266  }
267  }
268  /* Object mode related */
269  else if (STRPREFIX(opname, "GROUP_OT") || STRPREFIX(opname, "MATERIAL_OT") ||
270  STRPREFIX(opname, "PTCACHE_OT") || STRPREFIX(opname, "RIGIDBODY_OT")) {
271  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
272  }
273 
274  /* Editing Modes */
275  else if (STRPREFIX(opname, "MESH_OT")) {
276  km = WM_keymap_find_all(wm, "Mesh", 0, 0);
277 
278  /* some mesh operators are active in object mode too, like add-prim */
279  if (km && !WM_keymap_poll((bContext *)C, km)) {
280  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
281  }
282  }
283  else if (STRPREFIX(opname, "CURVE_OT") || STRPREFIX(opname, "SURFACE_OT")) {
284  km = WM_keymap_find_all(wm, "Curve", 0, 0);
285 
286  /* some curve operators are active in object mode too, like add-prim */
287  if (km && !WM_keymap_poll((bContext *)C, km)) {
288  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
289  }
290  }
291  else if (STRPREFIX(opname, "ARMATURE_OT") || STRPREFIX(opname, "SKETCH_OT")) {
292  km = WM_keymap_find_all(wm, "Armature", 0, 0);
293  }
294  else if (STRPREFIX(opname, "POSE_OT") || STRPREFIX(opname, "POSELIB_OT")) {
295  km = WM_keymap_find_all(wm, "Pose", 0, 0);
296  }
297  else if (STRPREFIX(opname, "SCULPT_OT")) {
298  switch (CTX_data_mode_enum(C)) {
299  case CTX_MODE_SCULPT:
300  km = WM_keymap_find_all(wm, "Sculpt", 0, 0);
301  break;
302  default:
303  break;
304  }
305  }
306  else if (STRPREFIX(opname, "MBALL_OT")) {
307  km = WM_keymap_find_all(wm, "Metaball", 0, 0);
308 
309  /* some mball operators are active in object mode too, like add-prim */
310  if (km && !WM_keymap_poll((bContext *)C, km)) {
311  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
312  }
313  }
314  else if (STRPREFIX(opname, "LATTICE_OT")) {
315  km = WM_keymap_find_all(wm, "Lattice", 0, 0);
316  }
317  else if (STRPREFIX(opname, "PARTICLE_OT")) {
318  km = WM_keymap_find_all(wm, "Particle", 0, 0);
319  }
320  else if (STRPREFIX(opname, "FONT_OT")) {
321  km = WM_keymap_find_all(wm, "Font", 0, 0);
322  }
323  /* Paint Face Mask */
324  else if (STRPREFIX(opname, "PAINT_OT_face_select")) {
325  km = WM_keymap_find_all(wm, "Paint Face Mask (Weight, Vertex, Texture)", 0, 0);
326  }
327  else if (STRPREFIX(opname, "PAINT_OT")) {
328  /* check for relevant mode */
329  switch (CTX_data_mode_enum(C)) {
331  km = WM_keymap_find_all(wm, "Weight Paint", 0, 0);
332  break;
334  km = WM_keymap_find_all(wm, "Vertex Paint", 0, 0);
335  break;
337  km = WM_keymap_find_all(wm, "Image Paint", 0, 0);
338  break;
339  case CTX_MODE_SCULPT:
340  km = WM_keymap_find_all(wm, "Sculpt", 0, 0);
341  break;
342  default:
343  break;
344  }
345  }
346  /* General 2D View, not bound to a specific spacetype. */
347  else if (STRPREFIX(opname, "VIEW2D_OT")) {
348  km = WM_keymap_find_all(wm, "View2D", 0, 0);
349  }
350  /* Image Editor */
351  else if (STRPREFIX(opname, "IMAGE_OT")) {
352  km = WM_keymap_find_all(wm, "Image", sl->spacetype, 0);
353  }
354  /* Clip Editor */
355  else if (STRPREFIX(opname, "CLIP_OT")) {
356  km = WM_keymap_find_all(wm, "Clip", sl->spacetype, 0);
357  }
358  else if (STRPREFIX(opname, "MASK_OT")) {
359  km = WM_keymap_find_all(wm, "Mask Editing", 0, 0);
360  }
361  /* UV Editor */
362  else if (STRPREFIX(opname, "UV_OT")) {
363  /* Hack to allow using UV unwrapping ops from 3DView/editmode.
364  * Mesh keymap is probably not ideal, but best place I could find to put those. */
365  if (sl->spacetype == SPACE_VIEW3D) {
366  km = WM_keymap_find_all(wm, "Mesh", 0, 0);
367  if (km && !WM_keymap_poll((bContext *)C, km)) {
368  km = NULL;
369  }
370  }
371  if (!km) {
372  km = WM_keymap_find_all(wm, "UV Editor", 0, 0);
373  }
374  }
375  /* Node Editor */
376  else if (STRPREFIX(opname, "NODE_OT")) {
377  km = WM_keymap_find_all(wm, "Node Editor", sl->spacetype, 0);
378  }
379  /* Animation Editor Channels */
380  else if (STRPREFIX(opname, "ANIM_OT_channels")) {
381  km = WM_keymap_find_all(wm, "Animation Channels", 0, 0);
382  }
383  /* Animation Generic - after channels */
384  else if (STRPREFIX(opname, "ANIM_OT")) {
385  if (sl->spacetype == SPACE_VIEW3D) {
386  switch (CTX_data_mode_enum(C)) {
387  case CTX_MODE_OBJECT:
388  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
389  break;
390  case CTX_MODE_POSE:
391  km = WM_keymap_find_all(wm, "Pose", 0, 0);
392  break;
393  default:
394  break;
395  }
396  if (km && !WM_keymap_poll((bContext *)C, km)) {
397  km = NULL;
398  }
399  }
400 
401  if (!km) {
402  km = WM_keymap_find_all(wm, "Animation", 0, 0);
403  }
404  }
405  /* Graph Editor */
406  else if (STRPREFIX(opname, "GRAPH_OT")) {
407  km = WM_keymap_find_all(wm, "Graph Editor", sl->spacetype, 0);
408  }
409  /* Dopesheet Editor */
410  else if (STRPREFIX(opname, "ACTION_OT")) {
411  km = WM_keymap_find_all(wm, "Dopesheet", sl->spacetype, 0);
412  }
413  /* NLA Editor */
414  else if (STRPREFIX(opname, "NLA_OT")) {
415  km = WM_keymap_find_all(wm, "NLA Editor", sl->spacetype, 0);
416  }
417  /* Script */
418  else if (STRPREFIX(opname, "SCRIPT_OT")) {
419  km = WM_keymap_find_all(wm, "Script", sl->spacetype, 0);
420  }
421  /* Text */
422  else if (STRPREFIX(opname, "TEXT_OT")) {
423  km = WM_keymap_find_all(wm, "Text", sl->spacetype, 0);
424  }
425  /* Sequencer */
426  else if (STRPREFIX(opname, "SEQUENCER_OT")) {
427  km = WM_keymap_find_all(wm, "Sequencer", sl->spacetype, 0);
428  }
429  /* Console */
430  else if (STRPREFIX(opname, "CONSOLE_OT")) {
431  km = WM_keymap_find_all(wm, "Console", sl->spacetype, 0);
432  }
433  /* Console */
434  else if (STRPREFIX(opname, "INFO_OT")) {
435  km = WM_keymap_find_all(wm, "Info", sl->spacetype, 0);
436  }
437  /* File browser */
438  else if (STRPREFIX(opname, "FILE_OT")) {
439  km = WM_keymap_find_all(wm, "File Browser", sl->spacetype, 0);
440  }
441  /* Logic Editor */
442  else if (STRPREFIX(opname, "LOGIC_OT")) {
443  km = WM_keymap_find_all(wm, "Logic Editor", sl->spacetype, 0);
444  }
445  /* Outliner */
446  else if (STRPREFIX(opname, "OUTLINER_OT")) {
447  km = WM_keymap_find_all(wm, "Outliner", sl->spacetype, 0);
448  }
449  /* Transform */
450  else if (STRPREFIX(opname, "TRANSFORM_OT")) {
451  /* check for relevant editor */
452  switch (sl->spacetype) {
453  case SPACE_VIEW3D:
454  km = WM_keymap_find_all(wm, "3D View", sl->spacetype, 0);
455  break;
456  case SPACE_GRAPH:
457  km = WM_keymap_find_all(wm, "Graph Editor", sl->spacetype, 0);
458  break;
459  case SPACE_ACTION:
460  km = WM_keymap_find_all(wm, "Dopesheet", sl->spacetype, 0);
461  break;
462  case SPACE_NLA:
463  km = WM_keymap_find_all(wm, "NLA Editor", sl->spacetype, 0);
464  break;
465  case SPACE_IMAGE:
466  km = WM_keymap_find_all(wm, "UV Editor", 0, 0);
467  break;
468  case SPACE_NODE:
469  km = WM_keymap_find_all(wm, "Node Editor", sl->spacetype, 0);
470  break;
471  case SPACE_SEQ:
472  km = WM_keymap_find_all(wm, "Sequencer", sl->spacetype, 0);
473  break;
474  }
475  }
476 
477  return km;
478 }
479 
480 static bool wm_keymap_item_uses_modifier(const wmKeyMapItem *kmi, const int event_modifier)
481 {
482  if (kmi->ctrl != KM_ANY) {
483  if ((kmi->ctrl == KM_NOTHING) != ((event_modifier & KM_CTRL) == 0)) {
484  return false;
485  }
486  }
487 
488  if (kmi->alt != KM_ANY) {
489  if ((kmi->alt == KM_NOTHING) != ((event_modifier & KM_ALT) == 0)) {
490  return false;
491  }
492  }
493 
494  if (kmi->shift != KM_ANY) {
495  if ((kmi->shift == KM_NOTHING) != ((event_modifier & KM_SHIFT) == 0)) {
496  return false;
497  }
498  }
499 
500  if (kmi->oskey != KM_ANY) {
501  if ((kmi->oskey == KM_NOTHING) != ((event_modifier & KM_OSKEY) == 0)) {
502  return false;
503  }
504  }
505  return true;
506 }
507 
508 bool WM_keymap_uses_event_modifier(const wmKeyMap *keymap, const int event_modifier)
509 {
510  LISTBASE_FOREACH (const wmKeyMapItem *, kmi, &keymap->items) {
511  if ((kmi->flag & KMI_INACTIVE) == 0) {
512  if (wm_keymap_item_uses_modifier(kmi, event_modifier)) {
513  return true;
514  }
515  }
516  }
517  return false;
518 }
519 
521 {
522 }
523 
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
eContextObjectMode
Definition: BKE_context.h:114
@ CTX_MODE_EDIT_GPENCIL
Definition: BKE_context.h:130
@ CTX_MODE_EDIT_CURVE
Definition: BKE_context.h:116
@ CTX_MODE_PAINT_TEXTURE
Definition: BKE_context.h:126
@ CTX_MODE_EDIT_SURFACE
Definition: BKE_context.h:117
@ CTX_MODE_WEIGHT_GPENCIL
Definition: BKE_context.h:132
@ CTX_MODE_PARTICLE
Definition: BKE_context.h:127
@ CTX_MODE_SCULPT
Definition: BKE_context.h:123
@ CTX_MODE_VERTEX_GPENCIL
Definition: BKE_context.h:133
@ CTX_MODE_OBJECT
Definition: BKE_context.h:128
@ CTX_MODE_EDIT_MESH
Definition: BKE_context.h:115
@ CTX_MODE_EDIT_TEXT
Definition: BKE_context.h:118
@ CTX_MODE_EDIT_ARMATURE
Definition: BKE_context.h:119
@ CTX_MODE_SCULPT_GPENCIL
Definition: BKE_context.h:131
@ CTX_MODE_EDIT_LATTICE
Definition: BKE_context.h:121
@ CTX_MODE_PAINT_GPENCIL
Definition: BKE_context.h:129
@ CTX_MODE_PAINT_VERTEX
Definition: BKE_context.h:125
@ CTX_MODE_EDIT_METABALL
Definition: BKE_context.h:120
@ CTX_MODE_PAINT_WEIGHT
Definition: BKE_context.h:124
@ CTX_MODE_POSE
Definition: BKE_context.h:122
struct SpaceLink * CTX_wm_space_data(const bContext *C)
Definition: context.c:719
enum eContextObjectMode CTX_data_mode_enum(const bContext *C)
Definition: context.c:1174
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
#define STRPREFIX(a, b)
#define STREQ(a, b)
Object is a sort of wrapper for general info.
@ SPACE_ACTION
@ SPACE_NODE
@ SPACE_NLA
@ SPACE_SEQ
@ SPACE_IMAGE
@ SPACE_GRAPH
@ SPACE_VIEW3D
eSpaceImage_Mode
@ SI_MODE_PAINT
@ SI_MODE_VIEW
@ SI_MODE_MASK
@ SI_MODE_UV
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
#define C
Definition: RandGen.cpp:39
#define KM_SHIFT
Definition: WM_types.h:221
#define KM_ANY
Definition: WM_types.h:240
#define KM_NOTHING
Definition: WM_types.h:241
#define KM_CTRL
Definition: WM_types.h:222
#define KM_ALT
Definition: WM_types.h:223
#define KM_OSKEY
Definition: WM_types.h:224
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:6550
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:6272
const char * identifier
Definition: RNA_types.h:446
struct PointerRNA * ptr
wmKeyMap * WM_keymap_find_all(wmWindowManager *wm, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:866
wmKeyMapItem * WM_keymap_add_item(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
Definition: wm_keymap.c:506
bool WM_keymap_poll(bContext *C, wmKeyMap *keymap)
Definition: wm_keymap.c:451
wmKeyMapItem * WM_keymap_add_menu_pie(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
wmKeyMapItem * WM_keymap_add_menu(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
void WM_keymap_fix_linking(void)
wmKeyMapItem * WM_keymap_add_panel(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
wmKeyMap * WM_keymap_guess_from_context(const bContext *C)
wmKeyMapItem * WM_keymap_add_tool(wmKeyMap *keymap, const char *idname, int type, int val, int modifier, int keymodifier)
bool WM_keymap_uses_event_modifier(const wmKeyMap *keymap, const int event_modifier)
wmKeyMap * WM_keymap_guess_opname(const bContext *C, const char *opname)
void WM_keymap_add_context_enum_set_items(wmKeyMap *keymap, const EnumPropertyItem *items, const char *data_path, int type_start, int val, int modifier, int keymodifier)
static bool wm_keymap_item_uses_modifier(const wmKeyMapItem *kmi, const int event_modifier)