More reshaping

This commit is contained in:
jpirnay
2026-04-09 21:50:32 +02:00
parent 68f175eced
commit 14dcd8be0f
11 changed files with 144 additions and 59 deletions
+2 -2
View File
@@ -45,9 +45,9 @@ class ButtonNavigator final {
[[nodiscard]] static int nextIndex(int currentIndex, const std::vector<bool>& selectable);
[[nodiscard]] static int previousIndex(int currentIndex, const std::vector<bool>& selectable);
[[nodiscard]] static int nextIndex(int currentIndex, int totalItems,
const std::function<bool(int index)>& isSelectable);
const std::function<bool(int index)>& isSelectable);
[[nodiscard]] static int previousIndex(int currentIndex, int totalItems,
const std::function<bool(int index)>& isSelectable);
const std::function<bool(int index)>& isSelectable);
[[nodiscard]] int nextIndex(int currentIndex) const;
[[nodiscard]] int previousIndex(int currentIndex) const;
+48
View File
@@ -0,0 +1,48 @@
#pragma once
#include <I18n.h>
#include <functional>
#include <type_traits>
#include <vector>
// Generic helper for constructing separator rows in menu item vectors.
// The item type must have an `action`, an `isSeparator`, and either a `labelId` or `nameId` member.
template <typename ItemType>
inline ItemType makeSeparatorMenuItem(StrId labelId) {
ItemType item{};
if constexpr (std::is_member_object_pointer_v<decltype(&ItemType::action)>) {
item.action = static_cast<decltype(item.action)>(0);
}
if constexpr (std::is_member_object_pointer_v<decltype(&ItemType::labelId)>) {
item.labelId = labelId;
} else if constexpr (std::is_member_object_pointer_v<decltype(&ItemType::nameId)>) {
item.nameId = labelId;
} else {
static_assert(sizeof(ItemType) == 0,
"makeSeparatorMenuItem requires ItemType with labelId or nameId member");
}
item.isSeparator = true;
return item;
}
// Generic helper for creating a selectable predicate for menu lists.
// The item type must have an `isSeparator` member.
template <typename ItemType>
inline std::function<bool(int)> makeSelectablePredicate(const std::vector<ItemType>& items) {
return
[&items](int index) { return index >= 0 && index < static_cast<int>(items.size()) && !items[index].isSeparator; };
}
template <typename ItemType>
inline std::function<bool(int)> makeSelectablePredicate(const std::vector<ItemType>& items, int indexOffset,
bool firstIndexSelectable) {
return [&items, indexOffset, firstIndexSelectable](int index) {
if (firstIndexSelectable && index == 0) {
return true;
}
const int itemIndex = index - indexOffset;
return itemIndex >= 0 && itemIndex < static_cast<int>(items.size()) && !items[itemIndex].isSeparator;
};
}