UI: Collapse XYZ Operations in Status Bar #120148
@ -2545,6 +2545,12 @@ bool uiTemplateEventFromKeymapItem(uiLayout *layout,
|
|||||||
const wmKeyMapItem *kmi,
|
const wmKeyMapItem *kmi,
|
||||||
bool text_fallback);
|
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,
|
void uiTemplateComponentMenu(uiLayout *layout,
|
||||||
PointerRNA *ptr,
|
PointerRNA *ptr,
|
||||||
const char *propname,
|
const char *propname,
|
||||||
|
@ -6519,6 +6519,89 @@ void uiTemplateKeymapItemProperties(uiLayout *layout, PointerRNA *ptr)
|
|||||||
/** \name Event Icon Template
|
/** \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,
|
bool uiTemplateEventFromKeymapItem(uiLayout *layout,
|
||||||
const char *text,
|
const char *text,
|
||||||
const wmKeyMapItem *kmi,
|
const wmKeyMapItem *kmi,
|
||||||
|
@ -6388,32 +6388,16 @@ bool WM_window_modal_keymap_status_draw(bContext *C, wmWindow *win, uiLayout *la
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool show_text = true;
|
const int num_items_used = uiTemplateStatusBarModalItem(row, keymap, items + i);
|
||||||
|
if (num_items_used > 0) {
|
||||||
{
|
/* Skip items in case consecutive items were merged. */
|
||||||
/* WARNING: O(n^2). */
|
i += num_items_used - 1;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (show_text) {
|
else if (std::optional<std::string> str = WM_modalkeymap_operator_items_to_string(
|
||||||
if (std::optional<std::string> str = WM_modalkeymap_operator_items_to_string(
|
op->type, items[i].value, true))
|
||||||
op->type, items[i].value, true))
|
{
|
||||||
{
|
/* Show text instead */
|
||||||
uiItemL(row, fmt::format("{}: {}", *str, items[i].name).c_str(), ICON_NONE);
|
uiItemL(row, fmt::format("{}: {}", *str, items[i].name).c_str(), ICON_NONE);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user