Blender V5.0
interface_template_event.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "BLI_string_ref.hh"
10
11#include "BLT_translation.hh"
12
13#include "WM_keymap.hh"
14
16#include "interface_intern.hh"
17
19
21 const EnumPropertyItem *item)
22{
23 if (item == nullptr) {
24 return nullptr;
25 }
26
27 for (wmKeyMapItem *kmi = static_cast<wmKeyMapItem *>(keymap->items.first); kmi; kmi = kmi->next)
28 {
29 if (kmi->propvalue == item->value) {
30 return kmi;
31 }
32 }
33
34 return nullptr;
35}
36
37static bool keymap_item_can_collapse(const wmKeyMapItem *kmi_a, const wmKeyMapItem *kmi_b)
38{
39 return (kmi_a->shift == kmi_b->shift && kmi_a->ctrl == kmi_b->ctrl && kmi_a->alt == kmi_b->alt &&
40 kmi_a->oskey == kmi_b->oskey && kmi_a->hyper == kmi_b->hyper);
41}
42
44 const wmKeyMap *keymap,
45 const EnumPropertyItem *item)
46{
47 const wmKeyMapItem *kmi = keymap_item_from_enum_item(keymap, item);
48 if (kmi == nullptr) {
49 return 0;
50 }
51
52 if ((kmi->val == KM_RELEASE) && ISKEYBOARD(kmi->type)) {
53 /* Assume release events just disable something which was toggled on. */
54 return 1;
55 }
56
57 /* Try to merge some known triplet items to save horizontal space. */
58 const EnumPropertyItem *item_y = (item[1].identifier) ? item + 1 : nullptr;
59 const EnumPropertyItem *item_z = (item_y && item[2].identifier) ? item + 2 : nullptr;
60 const wmKeyMapItem *kmi_y = keymap_item_from_enum_item(keymap, item_y);
61 const wmKeyMapItem *kmi_z = keymap_item_from_enum_item(keymap, item_z);
62
63 if (kmi_y && kmi_z && keymap_item_can_collapse(kmi, kmi_y) &&
64 keymap_item_can_collapse(kmi_y, kmi_z))
65 {
66 const char *xyz_label = nullptr;
67
68 if (STREQ(item->identifier, "AXIS_X") && STREQ(item_y->identifier, "AXIS_Y") &&
69 STREQ(item_z->identifier, "AXIS_Z"))
70 {
71 xyz_label = IFACE_("Axis");
72 }
73 else if (STREQ(item->identifier, "PLANE_X") && STREQ(item_y->identifier, "PLANE_Y") &&
74 STREQ(item_z->identifier, "PLANE_Z"))
75 {
76 xyz_label = IFACE_("Plane");
77 }
78
79 if (STREQ(item->identifier, "PROPORTIONAL_SIZE_UP") &&
80 STREQ(item_y->identifier, "PROPORTIONAL_SIZE_DOWN") &&
81 STREQ(item_z->identifier, "PROPORTIONAL_SIZE"))
82 {
83 xyz_label = IFACE_("Proportional Size");
84 }
85
86 if (xyz_label) {
87 int icon_mod[KM_MOD_NUM] = {0};
88#ifdef WITH_HEADLESS
89 int icon = 0;
90#else
91 int icon = UI_icon_from_keymap_item(kmi, icon_mod);
92#endif
93 for (int j = 0; j < ARRAY_SIZE(icon_mod) && icon_mod[j]; j++) {
94 layout->label("", icon_mod[j]);
95 const float offset = ui_event_icon_offset(icon_mod[j]);
96 if (offset != 0.0f) {
97 layout->separator(offset);
98 }
99 }
100 layout->label("", icon);
101 layout->separator(ui_event_icon_offset(icon));
102
103#ifndef WITH_HEADLESS
104 icon = UI_icon_from_keymap_item(kmi_y, icon_mod);
105#endif
106 layout->label("", icon);
107 layout->separator(ui_event_icon_offset(icon));
108
109#ifndef WITH_HEADLESS
110 icon = UI_icon_from_keymap_item(kmi_z, icon_mod);
111#endif
112 layout->label("", icon);
113 layout->separator(ui_event_icon_offset(icon));
114 layout->separator(0.2f);
115 layout->label(xyz_label, ICON_NONE);
116 layout->separator(0.6f);
117 return 3;
118 }
119 }
120
121 /* Try to merge some known paired items to save horizontal space. */
122 if (kmi_y && keymap_item_can_collapse(kmi, kmi_y)) {
123 const char *ab_label = nullptr;
124
125 if (STREQ(item->identifier, "PROPORTIONAL_SIZE_UP") &&
126 STREQ(item_y->identifier, "PROPORTIONAL_SIZE_DOWN"))
127 {
128 ab_label = IFACE_("Proportional Size");
129 }
130
131 if (ab_label) {
132 int icon_mod[KM_MOD_NUM] = {0};
133#ifdef WITH_HEADLESS
134 int icon = 0;
135#else
136 int icon = UI_icon_from_keymap_item(kmi, icon_mod);
137#endif
138 for (int j = 0; j < ARRAY_SIZE(icon_mod) && icon_mod[j]; j++) {
139 layout->label("", icon_mod[j]);
140 const float offset = ui_event_icon_offset(icon_mod[j]);
141 if (offset != 0.0f) {
142 layout->separator(offset);
143 }
144 }
145 layout->label("", icon);
146 layout->separator(ui_event_icon_offset(icon));
147
148#ifndef WITH_HEADLESS
149 icon = UI_icon_from_keymap_item(kmi_y, icon_mod);
150#endif
151 layout->label("", icon);
152 layout->separator(ui_event_icon_offset(icon));
153 layout->separator(0.2f);
154 layout->label(ab_label, ICON_NONE);
155 layout->separator(0.6f);
156 return 2;
157 }
158 }
159
160 /* Single item without merging. */
161 return uiTemplateEventFromKeymapItem(layout, item->name, kmi, false) ? 1 : 0;
162}
163
165 const StringRefNull text,
166 const wmKeyMapItem *kmi,
167 bool text_fallback)
168{
169 bool ok = false;
170
171 int icon_mod[KM_MOD_NUM];
172#ifdef WITH_HEADLESS
173 int icon = 0;
174#else
175 const int icon = UI_icon_from_keymap_item(kmi, icon_mod);
176#endif
177 if (icon != 0) {
178 for (int j = 0; j < ARRAY_SIZE(icon_mod) && icon_mod[j]; j++) {
179 layout->label("", icon_mod[j]);
180 const float offset = ui_event_icon_offset(icon_mod[j]);
181 if (offset != 0.0f) {
182 layout->separator(offset);
183 }
184 }
185
186 /* Icon and text separately is closer together with aligned layout. */
187
188 layout->label("", icon);
189 if (icon >= ICON_MOUSE_LMB && icon <= ICON_MOUSE_MMB_SCROLL) {
190 /* Negative space after narrow mice icons. */
191 layout->separator(-0.68f);
192 }
193
194 const float offset = ui_event_icon_offset(icon);
195 if (offset != 0.0f) {
196 layout->separator(offset);
197 }
198
199 layout->separator(0.2f);
200 layout->label(CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, text.c_str()), ICON_NONE);
201 layout->separator(0.6f);
202 ok = true;
203 }
204 else if (text_fallback) {
205 const char *event_text = WM_key_event_string(kmi->type, true);
206 layout->label(event_text, ICON_NONE);
207 layout->label(CTX_IFACE_(BLT_I18NCONTEXT_ID_WINDOWMANAGER, text.c_str()), ICON_NONE);
208 layout->separator(0.6f);
209 ok = true;
210 }
211 return ok;
212}
#define ARRAY_SIZE(arr)
#define STREQ(a, b)
#define BLT_I18NCONTEXT_ID_WINDOWMANAGER
#define CTX_IFACE_(context, msgid)
#define IFACE_(msgid)
int UI_icon_from_keymap_item(const wmKeyMapItem *kmi, int r_icon_mod[KM_MOD_NUM])
@ KM_RELEASE
Definition WM_types.hh:312
#define KM_MOD_NUM
Definition WM_types.hh:297
constexpr const char * c_str() const
float ui_event_icon_offset(const int icon_id)
static const wmKeyMapItem * keymap_item_from_enum_item(const wmKeyMap *keymap, const EnumPropertyItem *item)
bool uiTemplateEventFromKeymapItem(uiLayout *layout, const StringRefNull text, const wmKeyMapItem *kmi, bool text_fallback)
static bool keymap_item_can_collapse(const wmKeyMapItem *kmi_a, const wmKeyMapItem *kmi_b)
int uiTemplateStatusBarModalItem(uiLayout *layout, const wmKeyMap *keymap, const EnumPropertyItem *item)
const char * identifier
Definition RNA_types.hh:657
const char * name
Definition RNA_types.hh:661
void * first
void label(blender::StringRef name, int icon)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
struct wmKeyMapItem * next
#define ISKEYBOARD(event_type)
const char * WM_key_event_string(const short type, const bool compact)