UI: Collapse XYZ Operations in Status Bar #120148

Merged
Harley Acheson merged 12 commits from Harley/blender:StatusBarXYZ into main 2024-04-22 20:03:23 +02:00
3 changed files with 98 additions and 25 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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;