#ifndef MENUS_H__ #define MENUS_H__ /*************************************************************************************** * @file Menus.h * * @brief Defines constants and functions for working with menus. * @copyright * Copyright 2023 Tom Hicks * Licensed under the MIT license see the LICENSE file for details. ***************************************************************************************/ #include "Colors.h" namespace SBF { class MenuStyle; class MenuItem; } // namespace SBF // End forward declarations #include #include #include #include /** \addtogroup Menus * @{ */ namespace SBF { class MenuStyleBuilder { public: MenuStyleBuilder(); MenuStyleBuilder& SetScreenWidth(int screen_width); MenuStyleBuilder& SetRandomItemName(const std::string& name); MenuStyleBuilder& SetRandomItemId(int id); MenuStyleBuilder& SetRandomItemColor(uint8_t color); MenuStyleBuilder& SetCancelItemName(const std::string& name); MenuStyleBuilder& SetCancelItemId(int id); MenuStyleBuilder& SetCancelItemColor(uint8_t color); MenuStyleBuilder& SetIdLabelSeparator(const std::string& separator); MenuStyleBuilder& SetLabelValueSeparator(const std::string& separator); MenuStyleBuilder& SetMenuItemSeparator(const std::string& separator); MenuStyleBuilder& SetShowRandom(bool show_random); MenuStyleBuilder& SetShowCancel(bool show_cancel); MenuStyleBuilder& SetUseColors(bool use_colors); MenuStyle Build(); }; class MenuStyle { public: MenuStyle(); void Adjust(std::vector menu_items, bool ignore_value = true); friend std::ostream& operator<<(std::ostream& os, const MenuStyle& style); bool operator==(const MenuStyle& other); bool operator!=(const MenuStyle& other); int id_width; int label_width; int value_width; int screen_width; std::string random_item_name; int random_item_id; uint8_t random_item_color; std::string cancel_item_name; int cancel_item_id; uint8_t cancel_item_color; std::string id_label_separator; std::string label_value_separator; std::string menu_item_spacer; bool show_random; bool show_cancel; bool use_colors; }; class MenuItem { public: MenuItem(); MenuItem(std::string label, int id); MenuItem(std::string label, int id, int value); MenuItem(std::string label, int id, uint8_t color); friend std::ostream& operator<<(std::ostream& os, const MenuItem& item); bool operator==(const MenuItem& other); bool operator!=(const MenuItem& other); std::string label; int id; int value; uint8_t color; bool is_visible; bool include_in_random; }; // TODO: Make a menu class to hold GetRandomMenuItemId, the various BuildMenu* methods, and possibly PrintMenu. int GetRandomMenuItemId(std::vector items); std::vector BuildMenu(std::vector labels); std::vector BuildMenuWithValues(std::vector> items); std::vector BuildMenuWithValues(std::vector labels, std::vector values); std::vector BuildMenuWithColors(std::vector> items); std::vector BuildMenuWithColors(std::vector labels, std::vector colors); std::ostream& PrintMenu(std::ostream& os, std::vector items, MenuStyle style); std::string GetTitle(MenuItem item, MenuStyle style); std::string GetTitleWithoutValue(MenuItem item, MenuStyle style); std::ostream& PrintWithMaybeColor(std::ostream& os, const std::string& text, uint8_t text_color = kColorDefaultForeground, bool use_colors = false); int ChooseStringId(std::vector labels, MenuStyle style, const std::string& prompt); bool ChooseYesOrNo(std::string prompt); int GetChoice(int min, int max); int GetChoice(); int GetMenuChoice(std::vector menu_items, MenuStyle style); std::string GetString(std::string prompt); int ChooseStringIdWithValues(std::vector labels, std::vector values, MenuStyle style, const std::string& prompt); int ChooseMenuItemId(std::vector menu_items, MenuStyle style, const std::string& prompt, bool ignore_value); int ChooseStringIdWithColors(std::vector labels, std::vector colors, MenuStyle style, const std::string& prompt); void WaitForKeypress(); /// Clears the screen if not a debug build. inline void MaybeClearScreen() { #if !defined(DEBUG) cout << "\033[1;1H\033[2J"; #endif } } // End namespace SBF /** @}*/ #endif // !defined MENUS_H__