1
0
mirror of https://github.com/OpenTTD/OpenTTD synced 2026-01-31 08:04:36 +01:00

Codechange: Create API for special hotkeys used to select items from list.

This commit is contained in:
Rito12
2026-01-24 18:44:23 +01:00
committed by rubidium42
parent d17f662490
commit 7b5bfe2ac6

View File

@@ -62,7 +62,64 @@ bool IsQuitKey(uint16_t keycode);
void LoadHotkeysFromConfig();
void SaveHotkeysToConfig();
void HandleGlobalHotkeys(char32_t key, uint16_t keycode);
static constexpr int SPECIAL_HOTKEY_BIT = 30; ///< Bit which denotes that hotkey isn't bound to UI button.
/**
* Checks if hotkey index is special or not.
* @param hotkey Hotkey index to check.
* @return True iff the index is for special hotkey.
*/
inline bool IsSpecialHotkey(const int &hotkey)
{
return HasBit(hotkey, SPECIAL_HOTKEY_BIT);
}
/**
* Indexes for special hotkeys to navigate in lists.
* Values have to have SPECIAL_HOTKEY_BIT set.
*/
enum class SpecialListHotkeys : int {
PreviousItem = 1 << SPECIAL_HOTKEY_BIT, ///< Hotkey to select previous item in the list.
NextItem, ///< Hotkey to select next item in the list.
FirstItem, ///< Hotkey to select first item in the list.
LastItem, ///< Hotkey to select last item in the list.
};
/**
* Gets the first index in the list for given hotkey and the step to look for another if first is invalid.
* @tparam ItemType The type of items stored in the list.
* @tparam ListType The type of the list. For example: std::vector<ItemType>, std::list<ItemType>.
* @param hotkey The special hotkey to get the index and step for.
* @param list The list containing items.
* @param current_item The item that is currently chosen, used for next and previous hotkeys.
* @return Tuple containing index as first element and step as second. The step for backward direction has positive value, use `% list.size()` to remain in bounds.
*/
template<class ItemType, class ListType>
std::tuple<size_t, size_t> GetListIndexStep(SpecialListHotkeys hotkey, const ListType &list, const ItemType &current_item)
{
/* Don't use -1, because how % is implemented for negative numbers. */
size_t step_back = list.size() - 1;
auto get_relative_index_step = [list, current_item](size_t step) -> std::tuple<size_t, size_t> {
size_t index = std::distance(list.begin(), std::ranges::find(list, current_item));
return {(index + step) % list.size(), step};
};
switch (hotkey) {
default: NOT_REACHED();
case SpecialListHotkeys::FirstItem:
return {0, 1};
case SpecialListHotkeys::LastItem:
return {list.size() - 1, step_back};
case SpecialListHotkeys::PreviousItem:
return get_relative_index_step(step_back);
case SpecialListHotkeys::NextItem:
return get_relative_index_step(1);
}
}
#endif /* HOTKEYS_H */