From 7b5bfe2ac6ffdc525b39114464dbbcc4f4ce6f94 Mon Sep 17 00:00:00 2001 From: Rito12 Date: Sat, 24 Jan 2026 18:44:23 +0100 Subject: [PATCH] Codechange: Create API for special hotkeys used to select items from list. --- src/hotkeys.h | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/src/hotkeys.h b/src/hotkeys.h index 48cddd2205..75b31b641b 100644 --- a/src/hotkeys.h +++ b/src/hotkeys.h @@ -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, std::list. + * @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 +std::tuple GetListIndexStep(SpecialListHotkeys hotkey, const ListType &list, const ItemType ¤t_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 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 */