Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/intern/wm_event_system.c
| Show First 20 Lines • Show All 2,817 Lines • ▼ Show 20 Lines | else if (handler_base->poll == NULL || handler_base->poll(CTX_wm_region(C), event)) { | ||||
| /* Modal+blocking handler_base. */ | /* Modal+blocking handler_base. */ | ||||
| if (handler_base->flag & WM_HANDLER_BLOCKING) { | if (handler_base->flag & WM_HANDLER_BLOCKING) { | ||||
| action |= WM_HANDLER_BREAK; | action |= WM_HANDLER_BREAK; | ||||
| } | } | ||||
| /* Handle all types here. */ | /* Handle all types here. */ | ||||
| if (handler_base->type == WM_HANDLER_TYPE_KEYMAP) { | if (handler_base->type == WM_HANDLER_TYPE_KEYMAP) { | ||||
| wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base; | wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base; | ||||
| wmKeyMap *keymap = WM_event_get_keymap_from_handler(wm, handler); | wmEventHandler_KeymapResult km_result; | ||||
| action |= wm_handlers_do_keymap_with_keymap_handler( | WM_event_get_keymaps_from_handler(wm, handler, &km_result); | ||||
| int action_iter = WM_HANDLER_CONTINUE; | |||||
| for (int km_index = 0; km_index < km_result.keymaps_len; km_index++) { | |||||
| wmKeyMap *keymap = km_result.keymaps[km_index]; | |||||
| action_iter |= wm_handlers_do_keymap_with_keymap_handler( | |||||
| C, event, handlers, handler, keymap, do_debug_handler); | C, event, handlers, handler, keymap, do_debug_handler); | ||||
| if (action_iter & WM_HANDLER_BREAK) { | |||||
| break; | |||||
| } | |||||
| } | |||||
| action |= action_iter; | |||||
| /* Clear the tool-tip whenever a key binding is handled, without this tool-tips | /* Clear the tool-tip whenever a key binding is handled, without this tool-tips | ||||
| * are kept when a modal operators starts (annoying but otherwise harmless). */ | * are kept when a modal operators starts (annoying but otherwise harmless). */ | ||||
| if (action & WM_HANDLER_BREAK) { | if (action & WM_HANDLER_BREAK) { | ||||
| /* Window may be gone after file read. */ | /* Window may be gone after file read. */ | ||||
| if (CTX_wm_window(C) != NULL) { | if (CTX_wm_window(C) != NULL) { | ||||
| WM_tooltip_clear(C, CTX_wm_window(C)); | WM_tooltip_clear(C, CTX_wm_window(C)); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 897 Lines • ▼ Show 20 Lines | |||||
| * This runs before #WM_event_get_keymap_from_toolsystem, | * This runs before #WM_event_get_keymap_from_toolsystem, | ||||
| * allowing both the fallback-tool and active-tool to be activated | * allowing both the fallback-tool and active-tool to be activated | ||||
| * providing the key-map is configured so the keys don't conflict. | * providing the key-map is configured so the keys don't conflict. | ||||
| * For example one mouse button can run the active-tool, another button for the fallback-tool. | * For example one mouse button can run the active-tool, another button for the fallback-tool. | ||||
| * See T72567. | * See T72567. | ||||
| * | * | ||||
| * Follow #wmEventHandler_KeymapDynamicFn signature. | * Follow #wmEventHandler_KeymapDynamicFn signature. | ||||
| */ | */ | ||||
| wmKeyMap *WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm, | void WM_event_get_keymap_from_toolsystem_fallback(wmWindowManager *wm, | ||||
| wmEventHandler_Keymap *handler) | wmEventHandler_Keymap *handler, | ||||
| wmEventHandler_KeymapResult *km_result) | |||||
| { | { | ||||
| memset(km_result, 0x0, sizeof(*km_result)); | |||||
| const char *keymap_id_list[ARRAY_SIZE(km_result->keymaps)]; | |||||
| int keymap_id_list_len = 0; | |||||
| ScrArea *area = handler->dynamic.user_data; | ScrArea *area = handler->dynamic.user_data; | ||||
| handler->keymap_tool = NULL; | handler->keymap_tool = NULL; | ||||
| bToolRef_Runtime *tref_rt = area->runtime.tool ? area->runtime.tool->runtime : NULL; | bToolRef_Runtime *tref_rt = area->runtime.tool ? area->runtime.tool->runtime : NULL; | ||||
| if (tref_rt && tref_rt->keymap_fallback[0]) { | |||||
| const char *keymap_id = NULL; | |||||
| if (tref_rt && tref_rt->keymap[0]) { | |||||
| keymap_id_list[keymap_id_list_len++] = tref_rt->keymap; | |||||
| } | |||||
| bool is_gizmo_visible = false; | |||||
| bool is_gizmo_highlight = false; | |||||
| if (tref_rt && tref_rt->keymap_fallback[0]) { | |||||
| bool add_keymap = false; | |||||
| /* Support for the gizmo owning the tool keymap. */ | /* Support for the gizmo owning the tool keymap. */ | ||||
| if (tref_rt->gizmo_group[0] != '\0' && tref_rt->keymap_fallback[0] != '\0') { | |||||
| if (tref_rt->flag & TOOLREF_FLAG_FALLBACK_KEYMAP) { | |||||
| add_keymap = true; | |||||
| } | |||||
| if (tref_rt->gizmo_group[0] != '\0') { | |||||
| wmGizmoMap *gzmap = NULL; | wmGizmoMap *gzmap = NULL; | ||||
| wmGizmoGroup *gzgroup = NULL; | wmGizmoGroup *gzgroup = NULL; | ||||
| LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { | LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { | ||||
| if (region->gizmo_map != NULL) { | if (region->gizmo_map != NULL) { | ||||
| gzmap = region->gizmo_map; | gzmap = region->gizmo_map; | ||||
| gzgroup = WM_gizmomap_group_find(gzmap, tref_rt->gizmo_group); | gzgroup = WM_gizmomap_group_find(gzmap, tref_rt->gizmo_group); | ||||
| if (gzgroup != NULL) { | if (gzgroup != NULL) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (gzgroup != NULL) { | if (gzgroup != NULL) { | ||||
| if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP) { | if (gzgroup->type->flag & WM_GIZMOGROUPTYPE_TOOL_FALLBACK_KEYMAP) { | ||||
| /* If all are hidden, don't override. */ | /* If all are hidden, don't override. */ | ||||
| if (gzgroup->use_fallback_keymap) { | if (gzgroup->use_fallback_keymap) { | ||||
| is_gizmo_visible = true; | |||||
| wmGizmo *highlight = wm_gizmomap_highlight_get(gzmap); | wmGizmo *highlight = wm_gizmomap_highlight_get(gzmap); | ||||
| if (highlight == NULL) { | if (highlight) { | ||||
| keymap_id = tref_rt->keymap_fallback; | is_gizmo_highlight = true; | ||||
| } | |||||
| add_keymap = true; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (add_keymap) { | |||||
| keymap_id_list[keymap_id_list_len++] = tref_rt->keymap_fallback; | |||||
| } | |||||
| } | |||||
| if (is_gizmo_visible && !is_gizmo_highlight) { | |||||
| if (keymap_id_list_len == 2) { | |||||
| SWAP(const char *, keymap_id_list[0], keymap_id_list[1]); | |||||
| } | |||||
| } | } | ||||
| if (keymap_id && keymap_id[0]) { | for (int i = 0; i < keymap_id_list_len; i++) { | ||||
| const char *keymap_id = keymap_id_list[i]; | |||||
| BLI_assert(keymap_id && keymap_id[0]); | |||||
| wmKeyMap *km = WM_keymap_list_find_spaceid_or_empty( | wmKeyMap *km = WM_keymap_list_find_spaceid_or_empty( | ||||
| &wm->userconf->keymaps, keymap_id, area->spacetype, RGN_TYPE_WINDOW); | &wm->userconf->keymaps, keymap_id, area->spacetype, RGN_TYPE_WINDOW); | ||||
| /* We shouldn't use keymaps from unrelated spaces. */ | /* We shouldn't use keymaps from unrelated spaces. */ | ||||
| if (km != NULL) { | if (km == NULL) { | ||||
| handler->keymap_tool = area->runtime.tool; | printf("Keymap: '%s' not found for tool '%s'\n", keymap_id, area->runtime.tool->idname); | ||||
| return km; | continue; | ||||
| } | |||||
| printf( | |||||
| "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname); | |||||
| } | } | ||||
| handler->keymap_tool = area->runtime.tool; | |||||
| km_result->keymaps[km_result->keymaps_len++] = km; | |||||
| } | } | ||||
| return NULL; | |||||
| } | } | ||||
| wmKeyMap *WM_event_get_keymap_from_toolsystem(wmWindowManager *wm, wmEventHandler_Keymap *handler) | void WM_event_get_keymap_from_toolsystem(wmWindowManager *wm, | ||||
| wmEventHandler_Keymap *handler, | |||||
| wmEventHandler_KeymapResult *km_result) | |||||
| { | { | ||||
| memset(km_result, 0x0, sizeof(*km_result)); | |||||
| ScrArea *area = handler->dynamic.user_data; | ScrArea *area = handler->dynamic.user_data; | ||||
| handler->keymap_tool = NULL; | handler->keymap_tool = NULL; | ||||
| bToolRef_Runtime *tref_rt = area->runtime.tool ? area->runtime.tool->runtime : NULL; | bToolRef_Runtime *tref_rt = area->runtime.tool ? area->runtime.tool->runtime : NULL; | ||||
| if (tref_rt && tref_rt->keymap[0]) { | if (tref_rt && tref_rt->keymap[0]) { | ||||
| const char *keymap_id = tref_rt->keymap; | const char *keymap_id = tref_rt->keymap; | ||||
| { | { | ||||
| wmKeyMap *km = WM_keymap_list_find_spaceid_or_empty( | wmKeyMap *km = WM_keymap_list_find_spaceid_or_empty( | ||||
| &wm->userconf->keymaps, keymap_id, area->spacetype, RGN_TYPE_WINDOW); | &wm->userconf->keymaps, keymap_id, area->spacetype, RGN_TYPE_WINDOW); | ||||
| /* We shouldn't use keymaps from unrelated spaces. */ | /* We shouldn't use keymaps from unrelated spaces. */ | ||||
| if (km != NULL) { | if (km != NULL) { | ||||
| handler->keymap_tool = area->runtime.tool; | handler->keymap_tool = area->runtime.tool; | ||||
| return km; | km_result->keymaps[km_result->keymaps_len++] = km; | ||||
| } | } | ||||
| else { | |||||
| printf( | printf( | ||||
| "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname); | "Keymap: '%s' not found for tool '%s'\n", tref_rt->keymap, area->runtime.tool->idname); | ||||
| } | } | ||||
| } | } | ||||
| return NULL; | } | ||||
| } | } | ||||
| struct wmEventHandler_Keymap *WM_event_add_keymap_handler_dynamic( | struct wmEventHandler_Keymap *WM_event_add_keymap_handler_dynamic( | ||||
| ListBase *handlers, wmEventHandler_KeymapDynamicFn *keymap_fn, void *user_data) | ListBase *handlers, wmEventHandler_KeymapDynamicFn *keymap_fn, void *user_data) | ||||
| { | { | ||||
| if (!keymap_fn) { | if (!keymap_fn) { | ||||
| CLOG_WARN(WM_LOG_HANDLERS, "called with NULL keymap_fn"); | CLOG_WARN(WM_LOG_HANDLERS, "called with NULL keymap_fn"); | ||||
| return NULL; | return NULL; | ||||
| ▲ Show 20 Lines • Show All 1,117 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Event / Keymap Matching API | /** \name Event / Keymap Matching API | ||||
| * \{ */ | * \{ */ | ||||
| wmKeyMap *WM_event_get_keymap_from_handler(wmWindowManager *wm, wmEventHandler_Keymap *handler) | void WM_event_get_keymaps_from_handler(wmWindowManager *wm, | ||||
| wmEventHandler_Keymap *handler, | |||||
| wmEventHandler_KeymapResult *km_result) | |||||
| { | { | ||||
| wmKeyMap *keymap; | |||||
| if (handler->dynamic.keymap_fn != NULL) { | if (handler->dynamic.keymap_fn != NULL) { | ||||
| keymap = handler->dynamic.keymap_fn(wm, handler); | handler->dynamic.keymap_fn(wm, handler, km_result); | ||||
| BLI_assert(handler->keymap == NULL); | BLI_assert(handler->keymap == NULL); | ||||
| } | } | ||||
| else { | else { | ||||
| keymap = WM_keymap_active(wm, handler->keymap); | memset(km_result, 0x0, sizeof(*km_result)); | ||||
| wmKeyMap *keymap = WM_keymap_active(wm, handler->keymap); | |||||
| BLI_assert(keymap != NULL); | BLI_assert(keymap != NULL); | ||||
| if (keymap != NULL) { | |||||
| km_result->keymaps[km_result->keymaps_len++] = keymap; | |||||
| } | |||||
| } | } | ||||
| return keymap; | |||||
| } | } | ||||
| wmKeyMapItem *WM_event_match_keymap_item(bContext *C, wmKeyMap *keymap, const wmEvent *event) | wmKeyMapItem *WM_event_match_keymap_item(bContext *C, wmKeyMap *keymap, const wmEvent *event) | ||||
| { | { | ||||
| LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) { | LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) { | ||||
| if (wm_eventmatch(event, kmi)) { | if (wm_eventmatch(event, kmi)) { | ||||
| wmOperatorType *ot = WM_operatortype_find(kmi->idname, 0); | wmOperatorType *ot = WM_operatortype_find(kmi->idname, 0); | ||||
| if (WM_operator_poll_context(C, ot, WM_OP_INVOKE_DEFAULT)) { | if (WM_operator_poll_context(C, ot, WM_OP_INVOKE_DEFAULT)) { | ||||
| Show All 12 Lines | wmKeyMapItem *WM_event_match_keymap_item_from_handlers(bContext *C, | ||||
| LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) { | LISTBASE_FOREACH (wmEventHandler *, handler_base, handlers) { | ||||
| /* During this loop, UI handlers for nested menus can tag multiple handlers free. */ | /* During this loop, UI handlers for nested menus can tag multiple handlers free. */ | ||||
| if (handler_base->flag & WM_HANDLER_DO_FREE) { | if (handler_base->flag & WM_HANDLER_DO_FREE) { | ||||
| /* Pass. */ | /* Pass. */ | ||||
| } | } | ||||
| else if (handler_base->poll == NULL || handler_base->poll(CTX_wm_region(C), event)) { | else if (handler_base->poll == NULL || handler_base->poll(CTX_wm_region(C), event)) { | ||||
| if (handler_base->type == WM_HANDLER_TYPE_KEYMAP) { | if (handler_base->type == WM_HANDLER_TYPE_KEYMAP) { | ||||
| wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base; | wmEventHandler_Keymap *handler = (wmEventHandler_Keymap *)handler_base; | ||||
| wmKeyMap *keymap = WM_event_get_keymap_from_handler(wm, handler); | wmEventHandler_KeymapResult km_result; | ||||
| if (keymap && WM_keymap_poll(C, keymap)) { | WM_event_get_keymaps_from_handler(wm, handler, &km_result); | ||||
| for (int km_index = 0; km_index < km_result.keymaps_len; km_index++) { | |||||
| wmKeyMap *keymap = km_result.keymaps[km_index]; | |||||
| if (WM_keymap_poll(C, keymap)) { | |||||
| wmKeyMapItem *kmi = WM_event_match_keymap_item(C, keymap, event); | wmKeyMapItem *kmi = WM_event_match_keymap_item(C, keymap, event); | ||||
| if (kmi != NULL) { | if (kmi != NULL) { | ||||
| return kmi; | return kmi; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Cursor Keymap Status | /** \name Cursor Keymap Status | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 305 Lines • Show Last 20 Lines | |||||