Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2018-07-08 12:57:59 +0300
committerCampbell Barton <ideasman42@gmail.com>2018-07-08 23:17:42 +0300
commitaed82dafff8f7f0f30a7b7c1c7180d13ec52b052 (patch)
tree0395b0969069c8972b607758b725d6f616940705 /source/blender
parent907dd3d34a2f876622da1b4561df939a7d5836e9 (diff)
Icons: support for drawing event icons
Use for drawing modal operator header keys.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/include/UI_icons.h52
-rw-r--r--source/blender/editors/include/UI_interface.h4
-rw-r--r--source/blender/editors/interface/CMakeLists.txt1
-rw-r--r--source/blender/editors/interface/interface_icons.c152
-rw-r--r--source/blender/editors/interface/interface_icons_event.c295
-rw-r--r--source/blender/editors/interface/interface_intern.h5
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c45
7 files changed, 546 insertions, 8 deletions
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index 68318835a00..a63855439f4 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -1032,3 +1032,55 @@ DEF_VICO(COLORSET_17_VEC)
DEF_VICO(COLORSET_18_VEC)
DEF_VICO(COLORSET_19_VEC)
DEF_VICO(COLORSET_20_VEC)
+
+/* Events */
+DEF_ICON(EVENT_A)
+DEF_ICON(EVENT_B)
+DEF_ICON(EVENT_C)
+DEF_ICON(EVENT_D)
+DEF_ICON(EVENT_E)
+DEF_ICON(EVENT_F)
+DEF_ICON(EVENT_G)
+DEF_ICON(EVENT_H)
+DEF_ICON(EVENT_I)
+DEF_ICON(EVENT_J)
+DEF_ICON(EVENT_K)
+DEF_ICON(EVENT_L)
+DEF_ICON(EVENT_M)
+DEF_ICON(EVENT_N)
+DEF_ICON(EVENT_O)
+DEF_ICON(EVENT_P)
+DEF_ICON(EVENT_Q)
+DEF_ICON(EVENT_R)
+DEF_ICON(EVENT_S)
+DEF_ICON(EVENT_T)
+DEF_ICON(EVENT_U)
+DEF_ICON(EVENT_V)
+DEF_ICON(EVENT_W)
+DEF_ICON(EVENT_X)
+DEF_ICON(EVENT_Y)
+DEF_ICON(EVENT_Z)
+DEF_ICON(EVENT_SHIFT)
+DEF_ICON(EVENT_CTRL)
+DEF_ICON(EVENT_ALT)
+DEF_ICON(EVENT_OS)
+DEF_ICON(EVENT_F1)
+DEF_ICON(EVENT_F2)
+DEF_ICON(EVENT_F3)
+DEF_ICON(EVENT_F4)
+DEF_ICON(EVENT_F5)
+DEF_ICON(EVENT_F6)
+DEF_ICON(EVENT_F7)
+DEF_ICON(EVENT_F8)
+DEF_ICON(EVENT_F9)
+DEF_ICON(EVENT_F10)
+DEF_ICON(EVENT_F11)
+DEF_ICON(EVENT_F12)
+DEF_ICON(EVENT_ESC)
+DEF_ICON(EVENT_TAB)
+DEF_ICON(EVENT_PAGEUP)
+DEF_ICON(EVENT_PAGEDOWN)
+DEF_ICON(EVENT_HOME)
+DEF_ICON(EVENT_END)
+DEF_ICON(EVENT_RETURN)
+/* add as needed. */
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 8a758d01809..4114c209894 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -76,6 +76,7 @@ struct wmEvent;
struct wmManipulator;
struct wmMsgBus;
struct wmKeyMap;
+struct wmKeyMapItem;
typedef struct uiBut uiBut;
typedef struct uiBlock uiBlock;
@@ -723,6 +724,9 @@ enum {
int UI_icon_from_id(struct ID *id);
int UI_icon_from_report_type(int type);
+int UI_icon_from_event_type(short event_type, short event_value);
+int UI_icon_from_keymap_item(const struct wmKeyMapItem *kmi, int r_icon_mod[4]);
+
uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip);
uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip);
uiBut *uiDefIconTextMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, int icon, const char *str, int x, int y, short width, short height, const char *tip);
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index ee18f956cac..cf172441be1 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -54,6 +54,7 @@ set(SRC
interface_eyedropper_driver.c
interface_handlers.c
interface_icons.c
+ interface_icons_event.c
interface_layout.c
interface_ops.c
interface_panel.c
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 92178e58a58..9c5a4392f78 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -108,6 +108,7 @@ typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
#define ICON_TYPE_BUFFER 3
#define ICON_TYPE_VECTOR 4
#define ICON_TYPE_GEOM 5
+#define ICON_TYPE_EVENT 6 /* draw keymap entries using custom renderer. */
typedef struct DrawInfo {
int type;
@@ -126,6 +127,14 @@ typedef struct DrawInfo {
struct {
int x, y, w, h;
} texture;
+ struct {
+ /* Can be packed into a single int. */
+ short event_type;
+ short event_value;
+ int icon;
+ /* Allow lookups. */
+ struct DrawInfo *next;
+ } input;
} data;
} DrawInfo;
@@ -437,6 +446,143 @@ static void init_brush_icons(void)
#undef INIT_BRUSH_ICON
}
+static DrawInfo *g_di_event_list = NULL;
+
+int UI_icon_from_event_type(short event_type, short event_value)
+{
+ if (event_type == RIGHTSHIFTKEY) {
+ event_type = LEFTSHIFTKEY;
+ }
+ else if (event_type == RIGHTCTRLKEY) {
+ event_type = LEFTCTRLKEY;
+ }
+ else if (event_type == RIGHTALTKEY) {
+ event_type = LEFTALTKEY;
+ }
+ else if (event_type == EVT_TWEAK_L) {
+ event_type = LEFTMOUSE;
+ event_value = KM_CLICK_DRAG;
+ }
+ else if (event_type == EVT_TWEAK_M) {
+ event_type = MIDDLEMOUSE;
+ event_value = KM_CLICK_DRAG;
+ }
+ else if (event_type == EVT_TWEAK_R) {
+ event_type = RIGHTMOUSE;
+ event_value = KM_CLICK_DRAG;
+ }
+
+ DrawInfo *di = g_di_event_list;
+ do {
+ if (di->data.input.event_type == event_type) {
+ return di->data.input.icon;
+ }
+ } while ((di = di->data.input.next));
+
+ if (event_type == LEFTMOUSE) {
+ return ELEM(event_value, KM_CLICK, KM_PRESS) ? ICON_MOUSE_LMB : ICON_MOUSE_LMB_DRAG;
+ }
+ else if (event_type == MIDDLEMOUSE) {
+ return ELEM(event_value, KM_CLICK, KM_PRESS) ? ICON_MOUSE_MMB : ICON_MOUSE_MMB_DRAG;
+ }
+ else if (event_type == RIGHTMOUSE) {
+ return ELEM(event_value, KM_CLICK, KM_PRESS) ? ICON_MOUSE_RMB : ICON_MOUSE_RMB_DRAG;
+ }
+
+ return ICON_NONE;
+}
+
+int UI_icon_from_keymap_item(const wmKeyMapItem *kmi, int r_icon_mod[4])
+{
+ if (r_icon_mod) {
+ memset(r_icon_mod, 0x0, sizeof(int[4]));
+ int i = 0;
+ if (!ELEM(kmi->ctrl, KM_NOTHING, KM_ANY)) {
+ r_icon_mod[i++] = ICON_EVENT_CTRL;
+ }
+ if (!ELEM(kmi->alt, KM_NOTHING, KM_ANY)) {
+ r_icon_mod[i++] = ICON_EVENT_ALT;
+ }
+ if (!ELEM(kmi->shift, KM_NOTHING, KM_ANY)) {
+ r_icon_mod[i++] = ICON_EVENT_SHIFT;
+ }
+ if (!ELEM(kmi->oskey, KM_NOTHING, KM_ANY)) {
+ r_icon_mod[i++] = ICON_EVENT_OS;
+ }
+ }
+ return UI_icon_from_event_type(kmi->type, kmi->val);
+}
+
+static void init_event_icons(void)
+{
+ DrawInfo *di_next = NULL;
+
+#define INIT_EVENT_ICON(icon_id, type, value) \
+ { \
+ DrawInfo *di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_EVENT); \
+ di->data.input.event_type = type; \
+ di->data.input.event_value = value; \
+ di->data.input.icon = icon_id; \
+ di->data.input.next = di_next; \
+ di_next = di; \
+ }
+ /* end INIT_EVENT_ICON */
+
+ const int w = 16; /* DUMMY */
+
+ INIT_EVENT_ICON(ICON_EVENT_A, AKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_B, BKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_C, CKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_D, DKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_E, EKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F, FKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_G, GKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_H, HKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_I, IKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_J, JKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_K, KKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_L, LKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_M, MKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_N, NKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_O, OKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_P, PKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_Q, QKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_R, RKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_S, SKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_T, TKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_U, UKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_V, VKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_W, WKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_X, XKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_Y, YKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_Z, ZKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_SHIFT, LEFTSHIFTKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_CTRL, LEFTCTRLKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_ALT, LEFTALTKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_OS, OSKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F1, F1KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F2, F2KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F3, F3KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F4, F4KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F5, F5KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F6, F6KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F7, F7KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F8, F8KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F9, F9KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F10, F10KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F11, F11KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_F12, F12KEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_ESC, ESCKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_TAB, TABKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_PAGEUP, PAGEUPKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_PAGEDOWN, PAGEDOWNKEY, KM_ANY);
+ INIT_EVENT_ICON(ICON_EVENT_RETURN, RETKEY, KM_ANY);
+
+ g_di_event_list = di_next;
+
+#undef INIT_EVENT_ICON
+}
+
static void icon_verify_datatoc(IconImage *iimg)
{
/* if it has own rect, things are all OK */
@@ -795,6 +941,7 @@ void UI_icons_init(int first_dyn_id)
init_iconfile_list(&iconfilelist);
init_internal_icons();
init_brush_icons();
+ init_event_icons();
#endif
}
@@ -1285,6 +1432,11 @@ static void icon_draw_size(
icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, rgb, desaturate);
GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
}
+ else if (di->type == ICON_TYPE_EVENT) {
+ const short event_type = di->data.input.event_type;
+ const short event_value = di->data.input.event_value;
+ icon_draw_rect_input(x, y, w, h, alpha, event_type, event_value);
+ }
else if (di->type == ICON_TYPE_TEXTURE) {
/* texture image use premul alpha for correct scaling */
GPU_blend_set_func(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
diff --git a/source/blender/editors/interface/interface_icons_event.c b/source/blender/editors/interface/interface_icons_event.c
new file mode 100644
index 00000000000..dc444b98b2c
--- /dev/null
+++ b/source/blender/editors/interface/interface_icons_event.c
@@ -0,0 +1,295 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/interface/interface_icons_event.c
+ * \ingroup edinterface
+ *
+ * A special set of icons to represent input devices,
+ * this is a mix of text (via fonts) and a handful of custom glyphs for special keys.
+ *
+ * Event codes are used as identifiers.
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "GPU_draw.h"
+#include "GPU_matrix.h"
+#include "GPU_batch.h"
+#include "GPU_immediate.h"
+#include "GPU_state.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
+#include "BLI_fileops_types.h"
+#include "BLI_math_vector.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_dynamicpaint_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_workspace_types.h"
+
+#include "RNA_access.h"
+#include "RNA_enum_types.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+#include "BKE_icons.h"
+#include "BKE_appdir.h"
+#include "BKE_studiolight.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_thumbs.h"
+
+#include "BIF_glutil.h"
+#include "BLF_api.h"
+
+#include "DEG_depsgraph.h"
+
+#include "DRW_engine.h"
+
+#include "ED_datafiles.h"
+#include "ED_keyframes_draw.h"
+#include "ED_render.h"
+
+#include "UI_interface.h"
+#include "UI_interface_icons.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "interface_intern.h"
+
+static void icon_draw_rect_input_small_text_ex(
+ const rctf *rect, const float color[4], const float margin[2], const char *str,
+ int font_size)
+{
+ BLF_batch_draw_flush();
+ const int font_id = BLF_default();
+ BLF_color4fv(font_id, color);
+ BLF_size(font_id, font_size * U.pixelsize, U.dpi);
+ BLF_position(font_id, rect->xmin + margin[0] * 2, rect->ymin + margin[1] * 5, 0.0f);
+ BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_batch_draw_flush();
+}
+
+static void icon_draw_rect_input_small_text(
+ const rctf *rect, const float color[4], const float margin[2], const char *str)
+{
+ icon_draw_rect_input_small_text_ex(rect, color, margin, str, 8);
+}
+
+static void icon_draw_rect_input_default_text(
+ const rctf *rect,
+ const float color[4], const float margin[2], const char *str)
+{
+ BLF_batch_draw_flush();
+ const int font_id = BLF_default();
+ BLF_color4fv(font_id, color);
+ BLF_position(font_id, (int)(rect->xmin + margin[0] * 5), (int)(rect->ymin + margin[1] * 5), 0.0f);
+ BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_batch_draw_flush();
+}
+
+static void icon_draw_rect_input_mono_text(
+ const rctf *rect,
+ const float color[4], const float margin[2], const char *str)
+{
+ BLF_batch_draw_flush();
+ const int font_id = blf_mono_font;
+ BLF_color4fv(font_id, color);
+ BLF_size(font_id, 20 * U.pixelsize, U.dpi);
+ BLF_position(font_id, (int)(rect->xmin + margin[0] * 5), (int)(rect->ymin + margin[1] * 5), 0.0f);
+ BLF_draw(font_id, str, BLF_DRAW_STR_DUMMY_MAX);
+ BLF_batch_draw_flush();
+}
+
+static void icon_draw_rect_input_line_prim(
+ const rctf *rect,
+ const float color[4],
+ const int prim,
+ const char lines[][2], int lines_len)
+{
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+ BLI_assert(ELEM(prim, GWN_PRIM_LINE_LOOP, GWN_PRIM_LINE_STRIP));
+ const uint pos_id = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor4fv(color);
+ immBegin(prim, lines_len);
+ float w_inv = BLI_rctf_size_x(rect) / 255.0f;
+ float h_inv = BLI_rctf_size_y(rect) / 255.0f;
+ for (int i = 0; i < lines_len; i++) {
+ immVertex2f(
+ pos_id,
+ round_fl_to_int(rect->xmin + ((float)lines[i][0] * w_inv)),
+ round_fl_to_int(rect->ymin + ((float)lines[i][1] * h_inv))
+ );
+ }
+ immEnd();
+ immUnbindProgram();
+ glDisable(GL_LINE_SMOOTH);
+ glDisable(GL_BLEND);
+}
+
+void icon_draw_rect_input(
+ float x, float y, int w, int h, float UNUSED(alpha),
+ short event_type, short UNUSED(event_value))
+{
+ float color[4];
+ const float margin[2] = {w / 20.0f, h / 20.0f};
+ UI_GetThemeColor4fv(TH_TEXT, color);
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(
+ false,
+ (int)x,
+ (int)y,
+ (int)(x + w),
+ (int)(y + h), 4.0f, color
+ );
+
+ const rctf rect = {
+ .xmin = x,
+ .ymin = y,
+ .xmax = x + w,
+ .ymax = y + h,
+ };
+
+ const bool simple_text = false;
+
+ if ((event_type >= AKEY) || (ZKEY <= event_type)) {
+ char str[2] = {'A' + (event_type - AKEY), '\0'};
+ icon_draw_rect_input_default_text(&rect, color, margin, str);
+ }
+ if ((event_type >= F1KEY) || (F12KEY <= event_type)) {
+ char str[3] = {'F', '1' + (event_type - F1KEY), '\0'};
+ icon_draw_rect_input_default_text(&rect, color, margin, str);
+ }
+ else if (event_type == LEFTSHIFTKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Shift");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -14.0f), (w / -14.0f));
+ icon_draw_rect_input_mono_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x87, 0xa7, 0x0});
+ }
+ }
+ else if (event_type == LEFTCTRLKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Ctrl");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -16.0f), 0.0f);
+ icon_draw_rect_input_default_text(&rect_ofs, color, margin, "^");
+ }
+ }
+ else if (event_type == LEFTALTKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Alt");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -8.0f), 0.0f);
+ icon_draw_rect_input_default_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x8c, 0xa5, 0x0});
+ }
+ }
+ else if (event_type == OSKEY) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "OS");
+ }
+ else if (event_type == DELKEY) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Del");
+ }
+ else if (event_type == TABKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Tab");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -12.0f), (w / -12.0f));
+ icon_draw_rect_input_mono_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x86, 0xb9, 0x0});
+ }
+ }
+ else if (event_type == HOMEKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Home");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -12.0f), (w / -12.0f));
+ icon_draw_rect_input_mono_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x87, 0xa4, 0x0});
+ }
+ }
+ else if (event_type == ENDKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "End");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -12.0f), (w / -12.0f));
+ icon_draw_rect_input_mono_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x87, 0xa5, 0x0});
+ }
+ }
+ else if (event_type == RETKEY) {
+ if (simple_text) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Ret");
+ }
+ else {
+ rctf rect_ofs = rect;
+ BLI_rctf_translate(&rect_ofs, (w / -8.0f), (w / -6.0f));
+ icon_draw_rect_input_mono_text(&rect_ofs, color, margin, (const char[]){0xe2, 0x8f, 0x8e, 0x0});
+ }
+ }
+ else if (event_type == ESCKEY) {
+ icon_draw_rect_input_small_text(&rect, color, margin, "Esc");
+ }
+ else if (event_type == PAGEUPKEY) {
+ icon_draw_rect_input_small_text_ex(&rect, color, margin, (const char[]){'P', 0xe2, 0x86, 0x91, 0x0}, 10);
+ }
+ else if (event_type == PAGEDOWNKEY) {
+ icon_draw_rect_input_small_text_ex(&rect, color, margin, (const char[]){'P', 0xe2, 0x86, 0x93, 0x0}, 10);
+ }
+ else if (event_type == LEFTARROWKEY) {
+ icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x90, 0x0});
+ }
+ else if (event_type == UPARROWKEY) {
+ icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x91, 0x0});
+ }
+ else if (event_type == RIGHTARROWKEY) {
+ icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x92, 0x0});
+ }
+ else if (event_type == DOWNARROWKEY) {
+ icon_draw_rect_input_default_text(&rect, color, margin, (const char[]){0xe2, 0x86, 0x93, 0x0});
+ }
+ else if (event_type == SPACEKEY) {
+ const uchar lines[] = {60, 118, 60, 60, 195, 60, 195, 118};
+ icon_draw_rect_input_line_prim(
+ &rect, color, GWN_PRIM_LINE_STRIP,
+ (const void *)lines, ARRAY_SIZE(lines) / 2);
+ }
+}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 0b76e311cc7..ffc389c6dfd 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -789,6 +789,11 @@ void uiStyleInit(void);
void ui_icon_ensure_deferred(const struct bContext *C, const int icon_id, const bool big);
int ui_id_icon_get(const struct bContext *C, struct ID *id, const bool big);
+/* interface_icons_event.c */
+void icon_draw_rect_input(
+ float x, float y, int w, int h, float alpha,
+ short event_type, short event_value);
+
/* resources.c */
void init_userdef_do_versions(struct Main *bmain);
void ui_theme_init_default(void);
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 19889f57261..4f5578e452d 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -4546,14 +4546,43 @@ bool WM_window_modal_keymap_status_draw(
if (!items[i].identifier[0]) {
continue;
}
- char buf[UI_MAX_DRAW_STR];
- int available_len = sizeof(buf);
- char *p = buf;
- WM_modalkeymap_operator_items_to_string_buf(ot, items[i].value, true, UI_MAX_SHORTCUT_STR, &available_len, &p);
- p -= 1;
- if (p > buf) {
- BLI_snprintf(p, available_len, ": %s", items[i].name);
- uiItemL(row, buf, 0);
+
+ bool show_text = true;
+
+ {
+ /* warning: O(n^2) */
+ wmKeyMapItem *kmi = NULL;
+ for (kmi = keymap->items.first; kmi; kmi = kmi->next) {
+ if (kmi->propvalue == items[i].value) {
+ break;
+ }
+ }
+ if (kmi != NULL) {
+ if (kmi->val == KM_RELEASE) {
+ /* Assume release events just disable something which was toggled on. */
+ continue;
+ }
+ int icon_mod[4];
+ int icon = UI_icon_from_keymap_item(kmi, icon_mod);
+ if (icon != 0) {
+ for (int j = 0; j < ARRAY_SIZE(icon_mod) && icon_mod[j]; j++) {
+ uiItemL(row, "", icon_mod[j]);
+ }
+ uiItemL(row, items[i].name, icon);
+ show_text = false;
+ }
+ }
+ }
+ if (show_text) {
+ char buf[UI_MAX_DRAW_STR];
+ int available_len = sizeof(buf);
+ char *p = buf;
+ WM_modalkeymap_operator_items_to_string_buf(ot, items[i].value, true, UI_MAX_SHORTCUT_STR, &available_len, &p);
+ p -= 1;
+ if (p > buf) {
+ BLI_snprintf(p, available_len, ": %s", items[i].name);
+ uiItemL(row, buf, 0);
+ }
}
}
return true;