Fix T103267: No shortcuts shown in the Pose Assets context menu

Support displaying shortcuts for uiListDyn.custom_drag_* &
custom_activate_* operators.
This commit is contained in:
Campbell Barton 2023-01-11 19:14:35 +11:00
parent f88e788569
commit 68c6fc6d38
Notes: blender-bot 2023-02-13 13:47:12 +01:00
Referenced by issue #103267, No shortcuts shown in the Pose Assets context menu
3 changed files with 127 additions and 0 deletions

View File

@ -3130,6 +3130,20 @@ void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p);
bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src);
void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p);
/**
* A version of #WM_key_event_operator_string that's limited to UI elements.
*
* This supports showing shortcuts in context-menus (for example),
* for actions that can also be activated using shortcuts while the cursor is over the button.
* Without this those shortcuts aren't discoverable for users.
*/
const char *UI_key_event_operator_string(const struct bContext *C,
const char *opname,
IDProperty *properties,
const bool is_strict,
char *result,
const int result_len);
/* ui_interface_region_tooltip.c */
/**

View File

@ -25,8 +25,10 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_lib_id.h"
#include "BKE_report.h"
#include "BKE_screen.h"
#include "MEM_guardedalloc.h"
@ -1094,3 +1096,107 @@ void UI_butstore_update(uiBlock *block)
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Key Event from UI
* \{ */
/**
* Follow the logic from #wm_keymap_item_find_in_keymap.
*/
static bool ui_key_event_property_match(const char *opname,
IDProperty *properties,
const bool is_strict,
wmOperatorType *ui_optype,
PointerRNA *ui_opptr)
{
if (!STREQ(ui_optype->idname, opname)) {
return false;
}
bool match = false;
if (properties) {
if (ui_opptr && IDP_EqualsProperties_ex(
properties, static_cast<IDProperty *>(ui_opptr->data), is_strict)) {
match = true;
}
}
else {
match = true;
}
return match;
}
const char *UI_key_event_operator_string(const bContext *C,
const char *opname,
IDProperty *properties,
const bool is_strict,
char *result,
const int result_len)
{
/* NOTE: currently only actions on UI Lists are supported (for the asset manager).
* Other kinds of events can be supported as needed. */
ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
return nullptr;
}
/* Early exit regions which don't have UI-Lists. */
if ((region->type->keymapflag & ED_KEYMAP_UI) == 0) {
return nullptr;
}
uiBut *but = UI_region_active_but_get(region);
if (but == nullptr) {
return nullptr;
}
if (but->type != UI_BTYPE_PREVIEW_TILE) {
return nullptr;
}
short event_val = KM_NOTHING;
short event_type = KM_NOTHING;
uiBut *listbox = nullptr;
LISTBASE_FOREACH_BACKWARD (uiBut *, but_iter, &but->block->buttons) {
if ((but_iter->type == UI_BTYPE_LISTBOX) && ui_but_contains_rect(but_iter, &but->rect)) {
listbox = but_iter;
break;
}
}
if (listbox && listbox->custom_data) {
uiList *list = static_cast<uiList *>(listbox->custom_data);
uiListDyn *dyn_data = list->dyn_data;
if ((dyn_data->custom_activate_optype != nullptr) &&
ui_key_event_property_match(opname,
properties,
is_strict,
dyn_data->custom_activate_optype,
dyn_data->custom_activate_opptr)) {
event_val = KM_CLICK;
event_type = LEFTMOUSE;
}
else if ((dyn_data->custom_activate_optype != nullptr) &&
ui_key_event_property_match(opname,
properties,
is_strict,
dyn_data->custom_drag_optype,
dyn_data->custom_drag_opptr)) {
event_val = KM_CLICK_DRAG;
event_type = LEFTMOUSE;
}
}
if ((event_val != KM_NOTHING) && (event_type != KM_NOTHING)) {
WM_keymap_item_raw_to_string(
false, false, false, false, 0, event_val, event_type, false, result, result_len);
return result;
}
return nullptr;
}
/** \} */

View File

@ -25,6 +25,8 @@
#include "BLF_api.h"
#include "UI_interface.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
@ -1659,6 +1661,11 @@ char *WM_key_event_operator_string(const bContext *C,
return result;
}
/* Check UI state (non key-map actions for UI regions). */
if (UI_key_event_operator_string(C, opname, properties, is_strict, result, result_len)) {
return result;
}
return NULL;
}