UI: Collapse XYZ Operations in Status Bar #120148
@ -2545,6 +2545,12 @@ bool uiTemplateEventFromKeymapItem(uiLayout *layout,
|
||||
const wmKeyMapItem *kmi,
|
||||
bool text_fallback);
|
||||
|
||||
/* Draw keymap item for status bar. Returns number of items consumed,
|
||||
* as X/Y/Z items may get merged to use less space. */
|
||||
int uiTemplateStatusBarModalItem(uiLayout *layout,
|
||||
const wmKeyMap *keymap,
|
||||
const EnumPropertyItem *item);
|
||||
|
||||
void uiTemplateComponentMenu(uiLayout *layout,
|
||||
PointerRNA *ptr,
|
||||
const char *propname,
|
||||
|
@ -6519,6 +6519,89 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr)
|
||||
/** \name Event Icon Template
|
||||
* \{ */
|
||||
|
||||
static const wmKeyMapItem *keymap_item_from_enum_item(const wmKeyMap *keymap,
|
||||
const EnumPropertyItem *item)
|
||||
{
|
||||
if (item == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (wmKeyMapItem *kmi = static_cast<wmKeyMapItem *>(keymap->items.first); kmi; kmi = kmi->next)
|
||||
{
|
||||
if (kmi->val == KM_RELEASE) {
|
||||
/* Assume release events just disable something which was toggled on. */
|
||||
continue;
|
||||
}
|
||||
if (kmi->propvalue == item->value) {
|
||||
return kmi;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static bool keymap_item_can_collapse(const wmKeyMapItem *kmi_a, const wmKeyMapItem *kmi_b)
|
||||
{
|
||||
return (kmi_a->shift == kmi_b->shift && kmi_a->ctrl == kmi_b->ctrl && kmi_a->alt == kmi_b->alt &&
|
||||
kmi_a->oskey == kmi_b->oskey);
|
||||
}
|
||||
|
||||
int uiTemplateStatusBarModalItem(uiLayout *layout,
|
||||
const wmKeyMap *keymap,
|
||||
const EnumPropertyItem *item)
|
||||
{
|
||||
const wmKeyMapItem *kmi = keymap_item_from_enum_item(keymap, item);
|
||||
if (kmi == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to merge some known XYZ items to save horizontal space. */
|
||||
const EnumPropertyItem *item_y = (item[1].identifier) ? item + 1 : nullptr;
|
||||
const EnumPropertyItem *item_z = (item_y && item[2].identifier) ? item + 2 : nullptr;
|
||||
const wmKeyMapItem *kmi_y = keymap_item_from_enum_item(keymap, item_y);
|
||||
const wmKeyMapItem *kmi_z = keymap_item_from_enum_item(keymap, item_z);
|
||||
|
||||
if (kmi_y && kmi_z && keymap_item_can_collapse(kmi, kmi_y) &&
|
||||
keymap_item_can_collapse(kmi_y, kmi_z))
|
||||
{
|
||||
const char *xyz_label = nullptr;
|
||||
|
||||
if (STREQ(item->identifier, "AXIS_X") && STREQ(item_y->identifier, "AXIS_Y") &&
|
||||
STREQ(item_z->identifier, "AXIS_Z"))
|
||||
{
|
||||
xyz_label = IFACE_("Axis");
|
||||
}
|
||||
else if (STREQ(item->identifier, "PLANE_X") && STREQ(item_y->identifier, "PLANE_Y") &&
|
||||
STREQ(item_z->identifier, "PLANE_Z"))
|
||||
{
|
||||
xyz_label = IFACE_("Plane");
|
||||
}
|
||||
|
||||
if (xyz_label) {
|
||||
int icon_mod[4];
|
||||
int icon = UI_icon_from_keymap_item(kmi, icon_mod);
|
||||
for (int j = 0; j < ARRAY_SIZE(icon_mod) && icon_mod[j]; j++) {
|
||||
uiItemL(layout, "", icon_mod[j]);
|
||||
}
|
||||
uiItemL(layout, "", icon);
|
||||
|
||||
icon = UI_icon_from_keymap_item(kmi_y, icon_mod);
|
||||
uiItemL(layout, "", icon);
|
||||
|
||||
icon = UI_icon_from_keymap_item(kmi_z, icon_mod);
|
||||
uiItemL(layout, "", icon);
|
||||
|
||||
uiItemS_ex(layout, 0.6f);
|
||||
uiItemL(layout, xyz_label, ICON_NONE);
|
||||
uiItemS_ex(layout, 0.7f);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Single item without merging. */
|
||||
return uiTemplateEventFromKeymapItem(layout, item->name, kmi, false) ? 1 : 0;
|
||||
}
|
||||
|
||||
bool uiTemplateEventFromKeymapItem(uiLayout *layout,
|
||||
const char *text,
|
||||
const wmKeyMapItem *kmi,
|
||||
|
@ -6388,32 +6388,16 @@ bool WM_window_modal_keymap_status_draw(bContext *C, wmWindow *win, uiLayout *la
|
||||
continue;
|
||||
}
|
||||
|
||||
bool show_text = true;
|
||||
|
||||
{
|
||||
/* WARNING: O(n^2). */
|
||||
wmKeyMapItem *kmi = nullptr;
|
||||
for (kmi = static_cast<wmKeyMapItem *>(keymap->items.first); kmi; kmi = kmi->next) {
|
||||
if (kmi->propvalue == items[i].value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (kmi != nullptr) {
|
||||
if (kmi->val == KM_RELEASE) {
|
||||
/* Assume release events just disable something which was toggled on. */
|
||||
continue;
|
||||
}
|
||||
if (uiTemplateEventFromKeymapItem(row, items[i].name, kmi, false)) {
|
||||
show_text = false;
|
||||
}
|
||||
}
|
||||
const int num_items_used = uiTemplateStatusBarModalItem(row, keymap, items + i);
|
||||
if (num_items_used > 0) {
|
||||
/* Skip items in case consecutive items were merged. */
|
||||
i += num_items_used - 1;
|
||||
}
|
||||
if (show_text) {
|
||||
if (std::optional<std::string> str = WM_modalkeymap_operator_items_to_string(
|
||||
op->type, items[i].value, true))
|
||||
{
|
||||
uiItemL(row, fmt::format("{}: {}", *str, items[i].name).c_str(), ICON_NONE);
|
||||
}
|
||||
else if (std::optional<std::string> str = WM_modalkeymap_operator_items_to_string(
|
||||
op->type, items[i].value, true))
|
||||
{
|
||||
/* Show text instead */
|
||||
uiItemL(row, fmt::format("{}: {}", *str, items[i].name).c_str(), ICON_NONE);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user