Blender  V3.3
wm_keymap_utils.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
9 #include <string.h>
10 
11 #include "DNA_object_types.h"
12 #include "DNA_space_types.h"
13 #include "DNA_userdef_types.h"
15 
16 #include "BLI_listbase.h"
17 #include "BLI_utildefines.h"
18 
19 #include "BKE_context.h"
20 
21 #include "RNA_access.h"
22 
23 #include "WM_api.h"
24 #include "WM_types.h"
25 
26 /* menu wrapper for WM_keymap_add_item */
27 
28 /* -------------------------------------------------------------------- */
33  const char *idname,
35 {
36  wmKeyMapItem *kmi = WM_keymap_add_item(keymap, "WM_OT_call_menu", params);
37  RNA_string_set(kmi->ptr, "name", idname);
38  return kmi;
39 }
40 
42  const char *idname,
44 {
45  wmKeyMapItem *kmi = WM_keymap_add_item(keymap, "WM_OT_call_menu_pie", params);
46  RNA_string_set(kmi->ptr, "name", idname);
47  return kmi;
48 }
49 
51  const char *idname,
53 {
54  wmKeyMapItem *kmi = WM_keymap_add_item(keymap, "WM_OT_call_panel", params);
55  RNA_string_set(kmi->ptr, "name", idname);
56  /* TODO: we might want to disable this. */
57  RNA_boolean_set(kmi->ptr, "keep_open", false);
58  return kmi;
59 }
60 
62  const char *idname,
64 {
65  wmKeyMapItem *kmi = WM_keymap_add_item(keymap, "WM_OT_tool_set_by_id", params);
66  RNA_string_set(kmi->ptr, "name", idname);
67  return kmi;
68 }
69 
72 /* -------------------------------------------------------------------- */
77 {
79  const char *km_id = NULL;
80  if (sl->spacetype == SPACE_VIEW3D) {
81  const enum eContextObjectMode mode = CTX_data_mode_enum(C);
82  switch (mode) {
83  case CTX_MODE_EDIT_MESH:
84  km_id = "Mesh";
85  break;
87  km_id = "Curve";
88  break;
90  km_id = "Curves";
91  break;
93  km_id = "Curve";
94  break;
95  case CTX_MODE_EDIT_TEXT:
96  km_id = "Font";
97  break;
99  km_id = "Armature";
100  break;
102  km_id = "Metaball";
103  break;
105  km_id = "Lattice";
106  break;
107  case CTX_MODE_POSE:
108  km_id = "Pose";
109  break;
110  case CTX_MODE_SCULPT:
111  km_id = "Sculpt";
112  break;
114  km_id = "Weight Paint";
115  break;
117  km_id = "Vertex Paint";
118  break;
120  km_id = "Image Paint";
121  break;
122  case CTX_MODE_PARTICLE:
123  km_id = "Particle";
124  break;
125  case CTX_MODE_OBJECT:
126  km_id = "Object Mode";
127  break;
129  km_id = "Grease Pencil Stroke Paint Mode";
130  break;
132  km_id = "Grease Pencil Stroke Edit Mode";
133  break;
135  km_id = "Grease Pencil Stroke Sculpt Mode";
136  break;
138  km_id = "Grease Pencil Stroke Weight Mode";
139  break;
141  km_id = "Grease Pencil Stroke Vertex Mode";
142  break;
144  km_id = "Curves Sculpt";
145  break;
146  }
147  }
148  else if (sl->spacetype == SPACE_IMAGE) {
149  const SpaceImage *sima = (SpaceImage *)sl;
150  const eSpaceImage_Mode mode = sima->mode;
151  switch (mode) {
152  case SI_MODE_VIEW:
153  km_id = "Image";
154  break;
155  case SI_MODE_PAINT:
156  km_id = "Image Paint";
157  break;
158  case SI_MODE_MASK:
159  km_id = "Mask Editing";
160  break;
161  case SI_MODE_UV:
162  km_id = "UV Editor";
163  break;
164  }
165  }
166  else {
167  return NULL;
168  }
169 
170  wmKeyMap *km = WM_keymap_find_all(CTX_wm_manager(C), km_id, 0, 0);
171  BLI_assert(km);
172  return km;
173 }
174 
175 wmKeyMap *WM_keymap_guess_opname(const bContext *C, const char *opname)
176 {
177  /* Op types purposely skipped for now:
178  * BRUSH_OT
179  * BOID_OT
180  * BUTTONS_OT
181  * CONSTRAINT_OT
182  * PAINT_OT
183  * ED_OT
184  * FLUID_OT
185  * TEXTURE_OT
186  * UI_OT
187  * WORLD_OT
188  */
189 
190  wmKeyMap *km = NULL;
193 
194  /* Window */
195  if (STRPREFIX(opname, "WM_OT") || STRPREFIX(opname, "ED_OT_undo")) {
196  if (STREQ(opname, "WM_OT_tool_set_by_id")) {
198  }
199 
200  if (km == NULL) {
201  km = WM_keymap_find_all(wm, "Window", 0, 0);
202  }
203  }
204  /* Screen & Render */
205  else if (STRPREFIX(opname, "SCREEN_OT") || STRPREFIX(opname, "RENDER_OT") ||
206  STRPREFIX(opname, "SOUND_OT") || STRPREFIX(opname, "SCENE_OT")) {
207  km = WM_keymap_find_all(wm, "Screen", 0, 0);
208  }
209  /* Grease Pencil */
210  else if (STRPREFIX(opname, "GPENCIL_OT")) {
211  km = WM_keymap_find_all(wm, "Grease Pencil", 0, 0);
212  }
213  /* Markers */
214  else if (STRPREFIX(opname, "MARKER_OT")) {
215  km = WM_keymap_find_all(wm, "Markers", 0, 0);
216  }
217  /* Import/Export */
218  else if (STRPREFIX(opname, "IMPORT_") || STRPREFIX(opname, "EXPORT_")) {
219  km = WM_keymap_find_all(wm, "Window", 0, 0);
220  }
221 
222  /* 3D View */
223  else if (STRPREFIX(opname, "VIEW3D_OT")) {
224  km = WM_keymap_find_all(wm, "3D View", sl->spacetype, 0);
225  }
226  else if (STRPREFIX(opname, "OBJECT_OT")) {
227  /* exception, this needs to work outside object mode too */
228  if (STRPREFIX(opname, "OBJECT_OT_mode_set")) {
229  km = WM_keymap_find_all(wm, "Object Non-modal", 0, 0);
230  }
231  else {
232  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
233  }
234  }
235  /* Object mode related */
236  else if (STRPREFIX(opname, "GROUP_OT") || STRPREFIX(opname, "MATERIAL_OT") ||
237  STRPREFIX(opname, "PTCACHE_OT") || STRPREFIX(opname, "RIGIDBODY_OT")) {
238  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
239  }
240 
241  /* Editing Modes */
242  else if (STRPREFIX(opname, "MESH_OT")) {
243  km = WM_keymap_find_all(wm, "Mesh", 0, 0);
244 
245  /* some mesh operators are active in object mode too, like add-prim */
246  if (km && !WM_keymap_poll((bContext *)C, km)) {
247  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
248  }
249  }
250  else if (STRPREFIX(opname, "CURVE_OT") || STRPREFIX(opname, "SURFACE_OT")) {
251  km = WM_keymap_find_all(wm, "Curve", 0, 0);
252 
253  /* some curve operators are active in object mode too, like add-prim */
254  if (km && !WM_keymap_poll((bContext *)C, km)) {
255  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
256  }
257  }
258  else if (STRPREFIX(opname, "ARMATURE_OT") || STRPREFIX(opname, "SKETCH_OT")) {
259  km = WM_keymap_find_all(wm, "Armature", 0, 0);
260  }
261  else if (STRPREFIX(opname, "POSE_OT") || STRPREFIX(opname, "POSELIB_OT")) {
262  km = WM_keymap_find_all(wm, "Pose", 0, 0);
263  }
264  else if (STRPREFIX(opname, "SCULPT_OT")) {
265  switch (CTX_data_mode_enum(C)) {
266  case CTX_MODE_SCULPT:
267  km = WM_keymap_find_all(wm, "Sculpt", 0, 0);
268  break;
269  default:
270  break;
271  }
272  }
273  else if (STRPREFIX(opname, "CURVES_OT")) {
274  km = WM_keymap_find_all(wm, "Curves", 0, 0);
275  }
276  else if (STRPREFIX(opname, "SCULPT_CURVES_OT")) {
277  km = WM_keymap_find_all(wm, "Sculpt Curves", 0, 0);
278  }
279  else if (STRPREFIX(opname, "MBALL_OT")) {
280  km = WM_keymap_find_all(wm, "Metaball", 0, 0);
281 
282  /* some mball operators are active in object mode too, like add-prim */
283  if (km && !WM_keymap_poll((bContext *)C, km)) {
284  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
285  }
286  }
287  else if (STRPREFIX(opname, "LATTICE_OT")) {
288  km = WM_keymap_find_all(wm, "Lattice", 0, 0);
289  }
290  else if (STRPREFIX(opname, "PARTICLE_OT")) {
291  km = WM_keymap_find_all(wm, "Particle", 0, 0);
292  }
293  else if (STRPREFIX(opname, "FONT_OT")) {
294  km = WM_keymap_find_all(wm, "Font", 0, 0);
295  }
296  /* Paint Face Mask */
297  else if (STRPREFIX(opname, "PAINT_OT_face_select")) {
298  km = WM_keymap_find_all(wm, "Paint Face Mask (Weight, Vertex, Texture)", 0, 0);
299  }
300  else if (STRPREFIX(opname, "PAINT_OT")) {
301  /* check for relevant mode */
302  switch (CTX_data_mode_enum(C)) {
304  km = WM_keymap_find_all(wm, "Weight Paint", 0, 0);
305  break;
307  km = WM_keymap_find_all(wm, "Vertex Paint", 0, 0);
308  break;
310  km = WM_keymap_find_all(wm, "Image Paint", 0, 0);
311  break;
312  case CTX_MODE_SCULPT:
313  km = WM_keymap_find_all(wm, "Sculpt", 0, 0);
314  break;
315  default:
316  break;
317  }
318  }
319  /* General 2D View, not bound to a specific spacetype. */
320  else if (STRPREFIX(opname, "VIEW2D_OT")) {
321  km = WM_keymap_find_all(wm, "View2D", 0, 0);
322  }
323  /* Image Editor */
324  else if (STRPREFIX(opname, "IMAGE_OT")) {
325  km = WM_keymap_find_all(wm, "Image", sl->spacetype, 0);
326  }
327  /* Clip Editor */
328  else if (STRPREFIX(opname, "CLIP_OT")) {
329  km = WM_keymap_find_all(wm, "Clip", sl->spacetype, 0);
330  }
331  else if (STRPREFIX(opname, "MASK_OT")) {
332  km = WM_keymap_find_all(wm, "Mask Editing", 0, 0);
333  }
334  /* UV Editor */
335  else if (STRPREFIX(opname, "UV_OT")) {
336  /* Hack to allow using UV unwrapping ops from 3DView/editmode.
337  * Mesh keymap is probably not ideal, but best place I could find to put those. */
338  if (sl->spacetype == SPACE_VIEW3D) {
339  km = WM_keymap_find_all(wm, "Mesh", 0, 0);
340  if (km && !WM_keymap_poll((bContext *)C, km)) {
341  km = NULL;
342  }
343  }
344  if (!km) {
345  km = WM_keymap_find_all(wm, "UV Editor", 0, 0);
346  }
347  }
348  /* Node Editor */
349  else if (STRPREFIX(opname, "NODE_OT")) {
350  km = WM_keymap_find_all(wm, "Node Editor", sl->spacetype, 0);
351  }
352  /* Animation Editor Channels */
353  else if (STRPREFIX(opname, "ANIM_OT_channels")) {
354  km = WM_keymap_find_all(wm, "Animation Channels", 0, 0);
355  }
356  /* Animation Generic - after channels */
357  else if (STRPREFIX(opname, "ANIM_OT")) {
358  if (sl->spacetype == SPACE_VIEW3D) {
359  switch (CTX_data_mode_enum(C)) {
360  case CTX_MODE_OBJECT:
361  km = WM_keymap_find_all(wm, "Object Mode", 0, 0);
362  break;
363  case CTX_MODE_POSE:
364  km = WM_keymap_find_all(wm, "Pose", 0, 0);
365  break;
366  default:
367  break;
368  }
369  if (km && !WM_keymap_poll((bContext *)C, km)) {
370  km = NULL;
371  }
372  }
373 
374  if (!km) {
375  km = WM_keymap_find_all(wm, "Animation", 0, 0);
376  }
377  }
378  /* Graph Editor */
379  else if (STRPREFIX(opname, "GRAPH_OT")) {
380  km = WM_keymap_find_all(wm, "Graph Editor", sl->spacetype, 0);
381  }
382  /* Dopesheet Editor */
383  else if (STRPREFIX(opname, "ACTION_OT")) {
384  km = WM_keymap_find_all(wm, "Dopesheet", sl->spacetype, 0);
385  }
386  /* NLA Editor */
387  else if (STRPREFIX(opname, "NLA_OT")) {
388  km = WM_keymap_find_all(wm, "NLA Editor", sl->spacetype, 0);
389  }
390  /* Script */
391  else if (STRPREFIX(opname, "SCRIPT_OT")) {
392  km = WM_keymap_find_all(wm, "Script", sl->spacetype, 0);
393  }
394  /* Text */
395  else if (STRPREFIX(opname, "TEXT_OT")) {
396  km = WM_keymap_find_all(wm, "Text", sl->spacetype, 0);
397  }
398  /* Sequencer */
399  else if (STRPREFIX(opname, "SEQUENCER_OT")) {
400  km = WM_keymap_find_all(wm, "Sequencer", sl->spacetype, 0);
401  }
402  /* Console */
403  else if (STRPREFIX(opname, "CONSOLE_OT")) {
404  km = WM_keymap_find_all(wm, "Console", sl->spacetype, 0);
405  }
406  /* Console */
407  else if (STRPREFIX(opname, "INFO_OT")) {
408  km = WM_keymap_find_all(wm, "Info", sl->spacetype, 0);
409  }
410  /* File browser */
411  else if (STRPREFIX(opname, "FILE_OT")) {
412  km = WM_keymap_find_all(wm, "File Browser", sl->spacetype, 0);
413  }
414  /* Logic Editor */
415  else if (STRPREFIX(opname, "LOGIC_OT")) {
416  km = WM_keymap_find_all(wm, "Logic Editor", sl->spacetype, 0);
417  }
418  /* Outliner */
419  else if (STRPREFIX(opname, "OUTLINER_OT")) {
420  km = WM_keymap_find_all(wm, "Outliner", sl->spacetype, 0);
421  }
422  /* Transform */
423  else if (STRPREFIX(opname, "TRANSFORM_OT")) {
424  /* check for relevant editor */
425  switch (sl->spacetype) {
426  case SPACE_VIEW3D:
427  km = WM_keymap_find_all(wm, "3D View", sl->spacetype, 0);
428  break;
429  case SPACE_GRAPH:
430  km = WM_keymap_find_all(wm, "Graph Editor", sl->spacetype, 0);
431  break;
432  case SPACE_ACTION:
433  km = WM_keymap_find_all(wm, "Dopesheet", sl->spacetype, 0);
434  break;
435  case SPACE_NLA:
436  km = WM_keymap_find_all(wm, "NLA Editor", sl->spacetype, 0);
437  break;
438  case SPACE_IMAGE:
439  km = WM_keymap_find_all(wm, "UV Editor", 0, 0);
440  break;
441  case SPACE_NODE:
442  km = WM_keymap_find_all(wm, "Node Editor", sl->spacetype, 0);
443  break;
444  case SPACE_SEQ:
445  km = WM_keymap_find_all(wm, "Sequencer", sl->spacetype, 0);
446  break;
447  }
448  }
449 
450  return km;
451 }
452 
453 static bool wm_keymap_item_uses_modifier(const wmKeyMapItem *kmi, const int event_modifier)
454 {
455  if (kmi->ctrl != KM_ANY) {
456  if ((kmi->ctrl == KM_NOTHING) != ((event_modifier & KM_CTRL) == 0)) {
457  return false;
458  }
459  }
460 
461  if (kmi->alt != KM_ANY) {
462  if ((kmi->alt == KM_NOTHING) != ((event_modifier & KM_ALT) == 0)) {
463  return false;
464  }
465  }
466 
467  if (kmi->shift != KM_ANY) {
468  if ((kmi->shift == KM_NOTHING) != ((event_modifier & KM_SHIFT) == 0)) {
469  return false;
470  }
471  }
472 
473  if (kmi->oskey != KM_ANY) {
474  if ((kmi->oskey == KM_NOTHING) != ((event_modifier & KM_OSKEY) == 0)) {
475  return false;
476  }
477  }
478  return true;
479 }
480 
481 bool WM_keymap_uses_event_modifier(const wmKeyMap *keymap, const int event_modifier)
482 {
483  LISTBASE_FOREACH (const wmKeyMapItem *, kmi, &keymap->items) {
484  if ((kmi->flag & KMI_INACTIVE) == 0) {
485  if (wm_keymap_item_uses_modifier(kmi, event_modifier)) {
486  return true;
487  }
488  }
489  }
490  return false;
491 }
492 
494 {
495 }
496 
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
eContextObjectMode
Definition: BKE_context.h:103
@ CTX_MODE_EDIT_GPENCIL
Definition: BKE_context.h:120
@ CTX_MODE_EDIT_CURVE
Definition: BKE_context.h:105
@ CTX_MODE_PAINT_TEXTURE
Definition: BKE_context.h:116
@ CTX_MODE_EDIT_SURFACE
Definition: BKE_context.h:106
@ CTX_MODE_WEIGHT_GPENCIL
Definition: BKE_context.h:122
@ CTX_MODE_PARTICLE
Definition: BKE_context.h:117
@ CTX_MODE_SCULPT
Definition: BKE_context.h:113
@ CTX_MODE_VERTEX_GPENCIL
Definition: BKE_context.h:123
@ CTX_MODE_OBJECT
Definition: BKE_context.h:118
@ CTX_MODE_EDIT_MESH
Definition: BKE_context.h:104
@ CTX_MODE_SCULPT_CURVES
Definition: BKE_context.h:124
@ CTX_MODE_EDIT_TEXT
Definition: BKE_context.h:107
@ CTX_MODE_EDIT_CURVES
Definition: BKE_context.h:111
@ CTX_MODE_EDIT_ARMATURE
Definition: BKE_context.h:108
@ CTX_MODE_SCULPT_GPENCIL
Definition: BKE_context.h:121
@ CTX_MODE_EDIT_LATTICE
Definition: BKE_context.h:110
@ CTX_MODE_PAINT_GPENCIL
Definition: BKE_context.h:119
@ CTX_MODE_PAINT_VERTEX
Definition: BKE_context.h:115
@ CTX_MODE_EDIT_METABALL
Definition: BKE_context.h:109
@ CTX_MODE_PAINT_WEIGHT
Definition: BKE_context.h:114
@ CTX_MODE_POSE
Definition: BKE_context.h:112
struct SpaceLink * CTX_wm_space_data(const bContext *C)
Definition: context.c:743
enum eContextObjectMode CTX_data_mode_enum(const bContext *C)
Definition: context.c:1228
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
#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
#define C
Definition: RandGen.cpp:25
@ KM_NOTHING
Definition: WM_types.h:266
@ KM_ANY
Definition: WM_types.h:265
@ KM_CTRL
Definition: WM_types.h:239
@ KM_ALT
Definition: WM_types.h:240
@ KM_OSKEY
Definition: WM_types.h:242
@ KM_SHIFT
Definition: WM_types.h:238
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void RNA_string_set(PointerRNA *ptr, const char *name, const char *value)
Definition: rna_access.c:5155
void RNA_boolean_set(PointerRNA *ptr, const char *name, bool value)
Definition: rna_access.c:4874
struct PointerRNA * ptr
wmKeyMap * WM_keymap_find_all(wmWindowManager *wm, const char *idname, int spaceid, int regionid)
Definition: wm_keymap.c:866
bool WM_keymap_poll(bContext *C, wmKeyMap *keymap)
Definition: wm_keymap.c:432
wmKeyMapItem * WM_keymap_add_item(wmKeyMap *keymap, const char *idname, const KeyMapItem_Params *params)
Definition: wm_keymap.c:505
void WM_keymap_fix_linking(void)
wmKeyMapItem * WM_keymap_add_menu(wmKeyMap *keymap, const char *idname, const KeyMapItem_Params *params)
wmKeyMapItem * WM_keymap_add_tool(wmKeyMap *keymap, const char *idname, const KeyMapItem_Params *params)
wmKeyMap * WM_keymap_guess_from_context(const bContext *C)
wmKeyMapItem * WM_keymap_add_panel(wmKeyMap *keymap, const char *idname, const KeyMapItem_Params *params)
bool WM_keymap_uses_event_modifier(const wmKeyMap *keymap, const int event_modifier)
wmKeyMap * WM_keymap_guess_opname(const bContext *C, const char *opname)
wmKeyMapItem * WM_keymap_add_menu_pie(wmKeyMap *keymap, const char *idname, const KeyMapItem_Params *params)
static bool wm_keymap_item_uses_modifier(const wmKeyMapItem *kmi, const int event_modifier)