diff options
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/WM_keymap.h | 13 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_keymap.c | 160 |
2 files changed, 138 insertions, 35 deletions
diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h index fdde28c6bf1..987cbb4234c 100644 --- a/source/blender/windowmanager/WM_keymap.h +++ b/source/blender/windowmanager/WM_keymap.h @@ -68,7 +68,7 @@ wmKeyMapItem *WM_keymap_add_menu_pie(struct wmKeyMap *keymap, const char *idname int val, int modifier, int keymodifier); bool WM_keymap_remove_item(struct wmKeyMap *keymap, struct wmKeyMapItem *kmi); -int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, const int len); +int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, const int len, const bool compact); wmKeyMap *WM_keymap_list_find(ListBase *lb, const char *idname, int spaceid, int regionid); wmKeyMap *WM_keymap_find(struct wmKeyConfig *keyconf, const char *idname, int spaceid, int regionid); @@ -82,6 +82,12 @@ int WM_keymap_item_compare(struct wmKeyMapItem *k1, struct wmKeyMapItem *k2); /* Modal Keymap */ +int WM_modalkeymap_operator_items_to_string(struct wmOperatorType *ot, const int propvalue, + char *str, const int len, const bool compact); +char *WM_modalkeymap_operator_items_to_string_buf( + struct wmOperatorType *ot, const int propvalue, + char **str, int *available_len, const int max_len, const bool compact); + wmKeyMap *WM_modalkeymap_add(struct wmKeyConfig *keyconf, const char *idname, struct EnumPropertyItem *items); wmKeyMap *WM_modalkeymap_get(struct wmKeyConfig *keyconf, const char *idname); wmKeyMapItem *WM_modalkeymap_add_item(struct wmKeyMap *km, int type, int val, int modifier, int keymodifier, int value); @@ -98,7 +104,10 @@ int WM_keymap_map_type_get(struct wmKeyMapItem *kmi); /* Key Event */ -const char *WM_key_event_string(short type); +const char *WM_key_event_string(const short type, const bool compact); +int WM_keymap_item_raw_to_string( + const short shift, const short ctrl, const short alt, const short oskey, const short keymodifier, + const short type, char *str, const int len, const bool compact); int WM_key_event_operator_id( const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, const bool is_hotkey, diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 45177903cce..6d1ce43c6e6 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -42,6 +42,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_math.h" #include "BKE_context.h" #include "BKE_idprop.h" @@ -820,12 +821,11 @@ wmKeyMapItem *WM_modalkeymap_add_item_str(wmKeyMap *km, int type, int val, int m return kmi; } -wmKeyMapItem *WM_modalkeymap_find_propvalue(wmKeyMap *km, const int propvalue) +static wmKeyMapItem *wm_modalkeymap_find_propvalue_iter(wmKeyMap *km, wmKeyMapItem *kmi, const int propvalue) { - if (km->flag & KEYMAP_MODAL) { - wmKeyMapItem *kmi; - for (kmi = km->items.first; kmi; kmi = kmi->next) { + kmi = kmi ? kmi->next : km->items.first; + for (; kmi; kmi = kmi->next) { if (kmi->propvalue == propvalue) { return kmi; } @@ -838,6 +838,11 @@ wmKeyMapItem *WM_modalkeymap_find_propvalue(wmKeyMap *km, const int propvalue) return NULL; } +wmKeyMapItem *WM_modalkeymap_find_propvalue(wmKeyMap *km, const int propvalue) +{ + return wm_modalkeymap_find_propvalue_iter(km, NULL, propvalue); +} + void WM_modalkeymap_assign(wmKeyMap *km, const char *opname) { wmOperatorType *ot = WM_operatortype_find(opname, 0); @@ -881,50 +886,139 @@ static void wm_user_modal_keymap_set_items(wmWindowManager *wm, wmKeyMap *km) /* ***************** get string from key events **************** */ -const char *WM_key_event_string(short type) +const char *WM_key_event_string(const short type, const bool compact) { const char *name = NULL; - if (RNA_enum_name(event_type_items, (int)type, &name)) - return name; - + /* We first try enum items' description (abused as shortname here), and fall back to usual name if empty. */ + if ((compact && RNA_enum_description(event_type_items, (int)type, &name) && name[0]) || + RNA_enum_name(event_type_items, (int)type, &name)) + { + return IFACE_(name); + } + return ""; } -int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, const int len) +/* TODO: also support (some) value, like e.g. double-click? */ +int WM_keymap_item_raw_to_string(const short shift, const short ctrl, const short alt, const short oskey, + const short keymodifier, const short type, + char *str, const int len, const bool compact) { +#define ADD_SEP if (p != buf) *p++ = ' '; (void)0 + char buf[128]; char *p = buf; - buf[0] = 0; + buf[0] = '\0'; - if (kmi->shift == KM_ANY && - kmi->ctrl == KM_ANY && - kmi->alt == KM_ANY && - kmi->oskey == KM_ANY) + /* TODO: support order (KM_SHIFT vs. KM_SHIFT2) ? */ + if (shift == KM_ANY && + ctrl == KM_ANY && + alt == KM_ANY && + oskey == KM_ANY) { - p += BLI_strcpy_rlen(p, "Any "); + /* make it implicit in case of compact result expected. */ + if (!compact) { + ADD_SEP; + p += BLI_strcpy_rlen(p, IFACE_("Any")); + } } else { - if (kmi->shift) - p += BLI_strcpy_rlen(p, "Shift "); + if (shift) { + ADD_SEP; + p += BLI_strcpy_rlen(p, IFACE_("Shift")); + } - if (kmi->ctrl) - p += BLI_strcpy_rlen(p, "Ctrl "); + if (ctrl) { + ADD_SEP; + p += BLI_strcpy_rlen(p, IFACE_("Ctrl")); + } - if (kmi->alt) - p += BLI_strcpy_rlen(p, "Alt "); + if (alt) { + ADD_SEP; + p += BLI_strcpy_rlen(p, IFACE_("Alt")); + } - if (kmi->oskey) - p += BLI_strcpy_rlen(p, "Cmd "); + if (oskey) { + ADD_SEP; + p += BLI_strcpy_rlen(p, IFACE_("Cmd")); + } } - - if (kmi->keymodifier) { - p += BLI_strcpy_rlen(p, WM_key_event_string(kmi->keymodifier)); - p += BLI_strcpy_rlen(p, " "); + + if (keymodifier) { + ADD_SEP; + p += BLI_strcpy_rlen(p, WM_key_event_string(keymodifier, compact)); + } + + if (type) { + ADD_SEP; + p += BLI_strcpy_rlen(p, WM_key_event_string(type, compact)); + } + + /* We assume size of buf is enough to always store any possible shortcut, but let's add a debug check about it! */ + BLI_assert(p - buf < sizeof(buf)); + + /* We need utf8 here, otherwise we may 'cut' some unicode chars like arrows... */ + return BLI_strncpy_utf8_rlen(str, buf, len); + +#undef ADD_SEP +} + +int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, const int len, const bool compact) +{ + return WM_keymap_item_raw_to_string(kmi->shift, kmi->ctrl, kmi->alt, kmi->oskey, + kmi->keymodifier, kmi->type, str, len, compact); +} + +int WM_modalkeymap_operator_items_to_string( + wmOperatorType *ot, const int propvalue, char *str, const int len, const bool compact) +{ + wmKeyMap *km = ot->modalkeymap; + int totlen = 0; + bool add_sep = false; + + if (km) { + wmKeyMapItem *kmi; + + /* Find all shortcuts related to that propvalue! */ + for (kmi = WM_modalkeymap_find_propvalue(km, propvalue); + kmi && totlen < (len - 2); + kmi = wm_modalkeymap_find_propvalue_iter(km, kmi, propvalue)) + { + if (add_sep) { + str[totlen++] = '/'; + str[totlen] = '\0'; + } + else { + add_sep = true; + } + totlen += WM_keymap_item_to_string(kmi, &str[totlen], len - totlen, compact); + } + } + + return totlen; +} + +char *WM_modalkeymap_operator_items_to_string_buf( + wmOperatorType *ot, const int propvalue, char **str, int *available_len, const int max_len, const bool compact) +{ + char *ret = *str; + + if (*available_len > 1) { + int used_len = WM_modalkeymap_operator_items_to_string( + ot, propvalue, ret, min_ii(*available_len, max_len), compact) + 1; + + *available_len -= used_len; + *str += used_len; + if (*available_len == 0) { + (*str)--; /* So that *str keeps pointing on a valid char, we'll stay on it anyway. */ + } + } + else { + *ret = '\0'; } - p += BLI_strcpy_rlen(p, WM_key_event_string(kmi->type)); - return BLI_strncpy_rlen(str, buf, len); + return ret; } static wmKeyMapItem *wm_keymap_item_find_handlers( @@ -947,7 +1041,7 @@ static wmKeyMapItem *wm_keymap_item_find_handlers( if (kmi->flag & KMI_INACTIVE) continue; - if (STREQ(kmi->idname, opname) && WM_key_event_string(kmi->type)[0]) { + if (STREQ(kmi->idname, opname) && WM_key_event_string(kmi->type, false)[0]) { if (is_hotkey) { if (!ISHOTKEY(kmi->type)) continue; @@ -984,7 +1078,7 @@ static wmKeyMapItem *wm_keymap_item_find_handlers( if (IDP_EqualsProperties_ex(properties, properties_default, is_strict)) { char kmi_str[128]; - WM_keymap_item_to_string(kmi, kmi_str, sizeof(kmi_str)); + WM_keymap_item_to_string(kmi, kmi_str, sizeof(kmi_str), false); /* Note gievn properties could come from other things than menu entry... */ printf("%s: Some set values in menu entry match default op values, " "this might not be desired!\n", opname); @@ -1134,7 +1228,7 @@ static wmKeyMapItem *wm_keymap_item_find( kmi = wm_keymap_item_find_props(C, opname, opcontext, properties_default, is_strict, is_hotkey, &km); if (kmi) { char kmi_str[128]; - WM_keymap_item_to_string(kmi, kmi_str, sizeof(kmi_str)); + WM_keymap_item_to_string(kmi, kmi_str, sizeof(kmi_str), false); printf("%s: Some set values in keymap entry match default op values, " "this might not be desired!\n", opname); printf("\tkm: '%s', kmi: '%s'\n", km->idname, kmi_str); @@ -1165,7 +1259,7 @@ char *WM_key_event_operator_string( wmKeyMapItem *kmi = wm_keymap_item_find(C, opname, opcontext, properties, false, is_strict, NULL); if (kmi) { - WM_keymap_item_to_string(kmi, str, len); + WM_keymap_item_to_string(kmi, str, len, false); return str; } |