From f37c3aa2286dca72584cf3f2b3d89d0a9f5433e8 Mon Sep 17 00:00:00 2001 From: Archez Date: Thu, 3 Apr 2025 23:33:35 -0400 Subject: [PATCH] clang-format .hpp files (#5307) * Add hpp files to clang-format script * clang-format hpp files --- run-clang-format.ps1 | 2 +- run-clang-format.sh | 6 +- .../randomizer/3drando/custom_messages.hpp | 50 +- .../Enhancements/randomizer/3drando/fill.hpp | 86 +- .../Enhancements/randomizer/3drando/hints.hpp | 62 +- .../Enhancements/randomizer/3drando/menu.hpp | 3 +- .../randomizer/3drando/playthrough.hpp | 8 +- .../randomizer/3drando/pool_functions.hpp | 31 +- .../randomizer/3drando/rando_main.hpp | 3 +- .../randomizer/3drando/random.hpp | 30 +- .../Enhancements/randomizer/3drando/shops.hpp | 16 +- .../Enhancements/randomizer/3drando/text.hpp | 54 +- soh/soh/ShipInit.hpp | 24 +- soh/soh/SohGui/SohGui.hpp | 17 +- soh/soh/SohGui/UIWidgets.hpp | 1714 +++++++++-------- 15 files changed, 1048 insertions(+), 1058 deletions(-) diff --git a/run-clang-format.ps1 b/run-clang-format.ps1 index ba91db620..39905f9ed 100644 --- a/run-clang-format.ps1 +++ b/run-clang-format.ps1 @@ -37,7 +37,7 @@ if (-not (Test-Path $clangFormatFilePath) -or ($currentVersion -ne $requiredVers $basePath = (Resolve-Path .).Path $files = Get-ChildItem -Path $basePath\soh -Recurse -File ` | Where-Object { ($_.Extension -eq '.c' -or $_.Extension -eq '.cpp' -or ` - ($_.Extension -eq '.h' -and ` + (($_.Extension -eq '.h' -or $_.Extension -eq '.hpp') -and ` (-not ($_.FullName -like "*\soh\src\*" -or $_.FullName -like "*\soh\include\*")))) -and ` (-not ($_.FullName -like "*\soh\assets\*")) } diff --git a/run-clang-format.sh b/run-clang-format.sh index b3a8ae040..20129e63d 100755 --- a/run-clang-format.sh +++ b/run-clang-format.sh @@ -10,8 +10,8 @@ # -name "*.c" -o -name "*.cpp" # find all .c and .cpp files # -# -name "*.h" ! -path "soh/src/**.h" ! -path "soh/include/**.h" -# find all .h files that aren't in soh/src or soh/include +# ( -name "*.h" -o -name "*.hpp" ) ! -path "soh/src/**.h" ! -path "soh/include/**.h" +# find all .h and .hpp files that aren't in soh/src or soh/include # this is because zret decomp only runs clang-format on c files # https://github.com/zeldaret/mm/blob/b7e5468ca16315a7e322055eff3d97fe980bbc25/format.py#L182 # @@ -26,4 +26,4 @@ # and pass it as an argument to clang-format # verbose to print files being formatted and X out of Y status -find soh -type f \( -name "*.c" -o -name "*.cpp" -o \( -name "*.h" ! -path "soh/src/**.h" ! -path "soh/include/**.h" \) \) ! -path "soh/assets/*" -print0 | xargs -0 clang-format-14 -i --verbose +find soh -type f \( -name "*.c" -o -name "*.cpp" -o \( \( -name "*.h" -o -name "*.hpp" \) ! -path "soh/src/*" ! -path "soh/include/*" \) \) ! -path "soh/assets/*" -print0 | xargs -0 clang-format-14 -i --verbose diff --git a/soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp b/soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp index 4daacf51a..71a0e66b0 100644 --- a/soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/custom_messages.hpp @@ -6,28 +6,28 @@ #include "text.hpp" namespace CustomMessages { - std::string MESSAGE_END(); - std::string WAIT_FOR_INPUT(); - std::string HORIZONTAL_SPACE(uint8_t x); - std::string GO_TO(uint16_t x); - std::string INSTANT_TEXT_ON(); - std::string INSTANT_TEXT_OFF(); - std::string SHOP_MESSAGE_BOX(); - std::string EVENT_TRIGGER(); - std::string DELAY_FRAMES(uint8_t x); - std::string CLOSE_AFTER(uint8_t x); - std::string PLAYER_NAME(); - std::string PLAY_OCARINA(); - std::string ITEM_OBTAINED(uint8_t x); - std::string SET_SPEED(uint8_t x); - std::string SKULLTULAS_DESTROYED(); - std::string CURRENT_TIME(); - std::string UNSKIPPABLE(); - std::string TWO_WAY_CHOICE(); - std::string NEWLINE(); - std::string COLOR(std::string x); - std::string CENTER_TEXT(); - std::string IF_NOT_MQ(); - std::string MQ_ELSE(); - std::string MQ_END(); -} +std::string MESSAGE_END(); +std::string WAIT_FOR_INPUT(); +std::string HORIZONTAL_SPACE(uint8_t x); +std::string GO_TO(uint16_t x); +std::string INSTANT_TEXT_ON(); +std::string INSTANT_TEXT_OFF(); +std::string SHOP_MESSAGE_BOX(); +std::string EVENT_TRIGGER(); +std::string DELAY_FRAMES(uint8_t x); +std::string CLOSE_AFTER(uint8_t x); +std::string PLAYER_NAME(); +std::string PLAY_OCARINA(); +std::string ITEM_OBTAINED(uint8_t x); +std::string SET_SPEED(uint8_t x); +std::string SKULLTULAS_DESTROYED(); +std::string CURRENT_TIME(); +std::string UNSKIPPABLE(); +std::string TWO_WAY_CHOICE(); +std::string NEWLINE(); +std::string COLOR(std::string x); +std::string CENTER_TEXT(); +std::string IF_NOT_MQ(); +std::string MQ_ELSE(); +std::string MQ_END(); +} // namespace CustomMessages diff --git a/soh/soh/Enhancements/randomizer/3drando/fill.hpp b/soh/soh/Enhancements/randomizer/3drando/fill.hpp index bb013cc13..f2028e05d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/fill.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/fill.hpp @@ -7,52 +7,52 @@ #include #include -//RANDOTODO merge into Logic once Logic is a class passed to logic funtions +// RANDOTODO merge into Logic once Logic is a class passed to logic funtions struct GetAccessibleLocationsStruct { - std::vector accessibleLocations; - std::vector regionPool; - //Variables for playthrough - int gsCount; - int maxGsCount; - std::vector buyIgnores; + std::vector accessibleLocations; + std::vector regionPool; + // Variables for playthrough + int gsCount; + int maxGsCount; + std::vector buyIgnores; - //Variables for search - std::vector newItemLocations; - bool logicUpdated; - bool resetSphere; + // Variables for search + std::vector newItemLocations; + bool logicUpdated; + bool resetSphere; - //Variables For Validating Entrences - bool haveTimeAccess; - bool foundTempleOfTime; - bool validatedStartingRegion; - bool sphereZeroComplete; - bool timePassChildDay; - bool timePassChildNight; - bool timePassAdultDay; - bool timePassAdultNight; + // Variables For Validating Entrences + bool haveTimeAccess; + bool foundTempleOfTime; + bool validatedStartingRegion; + bool sphereZeroComplete; + bool timePassChildDay; + bool timePassChildNight; + bool timePassAdultDay; + bool timePassAdultNight; - std::vector itemSphere; - std::list entranceSphere; + std::vector itemSphere; + std::list entranceSphere; - bool calculatingAvailableChecks = false; + bool calculatingAvailableChecks = false; - GetAccessibleLocationsStruct(int _maxGsCount){ - regionPool = {RR_ROOT}; - gsCount = 0; - maxGsCount = _maxGsCount; - logicUpdated = false; - resetSphere = false; - } - - void InitLoop(){ - logicUpdated = false; - for (Rando::ItemLocation* location : newItemLocations) { - location->ApplyPlacedItemEffect(); + GetAccessibleLocationsStruct(int _maxGsCount) { + regionPool = { RR_ROOT }; + gsCount = 0; + maxGsCount = _maxGsCount; + logicUpdated = false; + resetSphere = false; + } + + void InitLoop() { + logicUpdated = false; + for (Rando::ItemLocation* location : newItemLocations) { + location->ApplyPlacedItemEffect(); + } + newItemLocations.clear(); + itemSphere.clear(); + entranceSphere.clear(); } - newItemLocations.clear(); - itemSphere.clear(); - entranceSphere.clear(); - } }; void ClearProgress(); @@ -61,13 +61,15 @@ int Fill(); std::vector GetEmptyLocations(std::vector allowedLocations); -void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE, +void ProcessRegion(Region* region, GetAccessibleLocationsStruct& gals, RandomizerGet ignore = RG_NONE, bool stopOnBeatable = false, bool addToPlaythrough = false); -std::vector ReachabilitySearch(const std::vector& allowedLocations, RandomizerGet ignore=RG_NONE, bool calculatingAvailableChecks=false); +std::vector ReachabilitySearch(const std::vector& allowedLocations, + RandomizerGet ignore = RG_NONE, + bool calculatingAvailableChecks = false); void GeneratePlaythrough(); -bool CheckBeatable(RandomizerGet ignore=RG_NONE); +bool CheckBeatable(RandomizerGet ignore = RG_NONE); void ValidateEntrances(bool checkPoeCollectorAccess, bool checkOtherEntranceAccess); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/hints.hpp b/soh/soh/Enhancements/randomizer/3drando/hints.hpp index 9199c6c81..48566f47e 100644 --- a/soh/soh/Enhancements/randomizer/3drando/hints.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/hints.hpp @@ -11,29 +11,30 @@ #include "../../custom-message/CustomMessageManager.h" struct HintDistributionSetting { - std::string name; - HintType type; - uint32_t weight; - uint8_t fixed; - uint8_t copies; - std::function filter; - uint8_t dungeonLimit; + std::string name; + HintType type; + uint32_t weight; + uint8_t fixed; + uint8_t copies; + std::function filter; + uint8_t dungeonLimit; - HintDistributionSetting(std::string _name, HintType _type, uint32_t _weight, uint8_t _fixed, uint8_t _copies, - std::function _filter, uint8_t _dungeonLimit = 40); + HintDistributionSetting(std::string _name, HintType _type, uint32_t _weight, uint8_t _fixed, uint8_t _copies, + std::function _filter, uint8_t _dungeonLimit = 40); }; struct HintSetting { - uint8_t alwaysCopies; - uint8_t trialCopies; - uint8_t junkWeight; - std::vector distTable; + uint8_t alwaysCopies; + uint8_t trialCopies; + uint8_t junkWeight; + std::vector distTable; }; class HintText { -public: + public: HintText() = default; - HintText(CustomMessage clearText_, std::vector ambiguousText_ = {}, std::vector obscureText_ = {}); + HintText(CustomMessage clearText_, std::vector ambiguousText_ = {}, + std::vector obscureText_ = {}); const CustomMessage& GetClear() const; const CustomMessage& GetObscure() const; const CustomMessage& GetObscure(uint8_t selection) const; @@ -46,27 +47,28 @@ public: bool operator==(const HintText& right) const; bool operator!=(const HintText& right) const; -private: + private: CustomMessage clearText; std::vector ambiguousText = {}; std::vector obscureText = {}; }; -struct StaticHintInfo{ - HintType type; - std::vector hintKeys; - RandomizerSettingKey setting; - std::variant condition; - std::vector targetChecks; - std::vector targetItems; - std::vector hintChecks; - bool yourPocket; - int num; +struct StaticHintInfo { + HintType type; + std::vector hintKeys; + RandomizerSettingKey setting; + std::variant condition; + std::vector targetChecks; + std::vector targetItems; + std::vector hintChecks; + bool yourPocket; + int num; - StaticHintInfo() = default; - StaticHintInfo(HintType _type, std::vector _hintKeys, RandomizerSettingKey _setting, std::variant _condition, - std::vector _targetChecks, std::vector _targetItems = {}, - std::vector _hintChecks = {}, bool _yourPocket = false, int _num = 0); + StaticHintInfo() = default; + StaticHintInfo(HintType _type, std::vector _hintKeys, RandomizerSettingKey _setting, + std::variant _condition, std::vector _targetChecks, + std::vector _targetItems = {}, std::vector _hintChecks = {}, + bool _yourPocket = false, int _num = 0); }; RandomizerHintTextKey GetRandomJunkHint(); diff --git a/soh/soh/Enhancements/randomizer/3drando/menu.hpp b/soh/soh/Enhancements/randomizer/3drando/menu.hpp index e0e6e4210..b40c97c2d 100644 --- a/soh/soh/Enhancements/randomizer/3drando/menu.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/menu.hpp @@ -13,4 +13,5 @@ #define DELETE_PRESET 6 #define RESET_TO_DEFAULTS 8 -bool GenerateRandomizer(std::set excludedLocations, std::set enabledTricks, std::string seedInput); \ No newline at end of file +bool GenerateRandomizer(std::set excludedLocations, std::set enabledTricks, + std::string seedInput); \ No newline at end of file diff --git a/soh/soh/Enhancements/randomizer/3drando/playthrough.hpp b/soh/soh/Enhancements/randomizer/3drando/playthrough.hpp index 1dbbc7842..52ad6a3ee 100644 --- a/soh/soh/Enhancements/randomizer/3drando/playthrough.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/playthrough.hpp @@ -4,6 +4,8 @@ #include "../context.h" namespace Playthrough { - int Playthrough_Init(uint32_t seed, std::set excludedLocations, std::set enabledTricks); - int Playthrough_Repeat(std::set excludedLocations, std::set enabledTricks, int count = 1); -} +int Playthrough_Init(uint32_t seed, std::set excludedLocations, + std::set enabledTricks); +int Playthrough_Repeat(std::set excludedLocations, std::set enabledTricks, + int count = 1); +} // namespace Playthrough diff --git a/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp b/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp index 5a83cda5b..5edcb0fda 100644 --- a/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/pool_functions.hpp @@ -5,38 +5,35 @@ #include #include -template -static void erase_if(std::vector& vector, Predicate pred) { - vector.erase(std::remove_if(begin(vector), end(vector), pred), end(vector)); +template static void erase_if(std::vector& vector, Predicate pred) { + vector.erase(std::remove_if(begin(vector), end(vector), pred), end(vector)); } template std::vector FilterFromPool(std::vector& vector, Predicate pred, bool eraseAfterFilter = false) { - std::vector filteredPool = {}; - std::copy_if(vector.begin(), vector.end(), std::back_inserter(filteredPool), pred); + std::vector filteredPool = {}; + std::copy_if(vector.begin(), vector.end(), std::back_inserter(filteredPool), pred); - if (eraseAfterFilter) { - erase_if(vector, pred); - } + if (eraseAfterFilter) { + erase_if(vector, pred); + } - return filteredPool; + return filteredPool; } template std::vector FilterAndEraseFromPool(std::vector& vector, Predicate pred) { - return FilterFromPool(vector, pred, true); + return FilterFromPool(vector, pred, true); } -template -void AddElementsToPool(std::vector& toPool, const FromPool& fromPool) { - toPool.insert(toPool.end(), std::cbegin(fromPool), std::cend(fromPool)); +template void AddElementsToPool(std::vector& toPool, const FromPool& fromPool) { + toPool.insert(toPool.end(), std::cbegin(fromPool), std::cend(fromPool)); } -template -bool ElementInContainer(T& element, const Container& container) { - return std::find(container.begin(), container.end(), element) != container.end(); +template bool ElementInContainer(T& element, const Container& container) { + return std::find(container.begin(), container.end(), element) != container.end(); } template bool IsAnyOf(First&& first, T&&... t) { - return ((first == t) || ...); + return ((first == t) || ...); } diff --git a/soh/soh/Enhancements/randomizer/3drando/rando_main.hpp b/soh/soh/Enhancements/randomizer/3drando/rando_main.hpp index 8ac22069b..b03dd8b88 100644 --- a/soh/soh/Enhancements/randomizer/3drando/rando_main.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/rando_main.hpp @@ -3,5 +3,6 @@ #include namespace RandoMain { -void GenerateRando(std::set excludedLocations, std::set enabledTricks, std::string seedInput); +void GenerateRando(std::set excludedLocations, std::set enabledTricks, + std::string seedInput); } diff --git a/soh/soh/Enhancements/randomizer/3drando/random.hpp b/soh/soh/Enhancements/randomizer/3drando/random.hpp index 24ab78dcd..cc519d5f9 100644 --- a/soh/soh/Enhancements/randomizer/3drando/random.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/random.hpp @@ -11,9 +11,8 @@ void Random_Init(uint32_t seed); uint32_t Random(int min, int max); double RandomDouble(); -//Get a random element from a vector or array -template -T RandomElement(std::vector& vector, bool erase) { +// Get a random element from a vector or array +template T RandomElement(std::vector& vector, bool erase) { const auto idx = Random(0, vector.size()); const T selected = vector[idx]; if (erase) { @@ -21,17 +20,14 @@ T RandomElement(std::vector& vector, bool erase) { } return selected; } -template -auto& RandomElement(Container& container) { +template auto& RandomElement(Container& container) { return container[Random(0, std::size(container))]; } -template -const auto& RandomElement(const Container& container) { +template const auto& RandomElement(const Container& container) { return container[Random(0, std::size(container))]; } -template -const T RandomElementFromSet(const std::set& set) { +template const T RandomElementFromSet(const std::set& set) { if (set.size() == 1) { return *set.begin(); } @@ -44,19 +40,15 @@ const T RandomElementFromSet(const std::set& set) { return *it; } -//Shuffle items within a vector or array -//RANDOTODO There's probably a more efficient way to do what this does. -template -void Shuffle(std::vector& vector) { - for (std::size_t i = 0; i + 1 < vector.size(); i++) - { +// Shuffle items within a vector or array +// RANDOTODO There's probably a more efficient way to do what this does. +template void Shuffle(std::vector& vector) { + for (std::size_t i = 0; i + 1 < vector.size(); i++) { std::swap(vector[i], vector[Random(i, vector.size())]); } } -template -void Shuffle(std::array& arr) { - for (std::size_t i = 0; i + 1 < arr.size(); i++) - { +template void Shuffle(std::array& arr) { + for (std::size_t i = 0; i + 1 < arr.size(); i++) { std::swap(arr[i], arr[Random(i, arr.size())]); } } diff --git a/soh/soh/Enhancements/randomizer/3drando/shops.hpp b/soh/soh/Enhancements/randomizer/3drando/shops.hpp index b1f09a9a7..81c4a4358 100644 --- a/soh/soh/Enhancements/randomizer/3drando/shops.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/shops.hpp @@ -16,16 +16,10 @@ struct PriceSettingsStruct { RandomizerSettingKey tycoonWallet; RandomizerSettingKey affordable; - PriceSettingsStruct(RandomizerSettingKey _main, - RandomizerSettingKey _fixedPrice, - RandomizerSettingKey _range1, - RandomizerSettingKey _range2, - RandomizerSettingKey _noWallet, - RandomizerSettingKey _childWallet, - RandomizerSettingKey _adultWallet, - RandomizerSettingKey _giantWallet, - RandomizerSettingKey _tycoonWallet, - RandomizerSettingKey _affordable); + PriceSettingsStruct(RandomizerSettingKey _main, RandomizerSettingKey _fixedPrice, RandomizerSettingKey _range1, + RandomizerSettingKey _range2, RandomizerSettingKey _noWallet, RandomizerSettingKey _childWallet, + RandomizerSettingKey _adultWallet, RandomizerSettingKey _giantWallet, + RandomizerSettingKey _tycoonWallet, RandomizerSettingKey _affordable); }; extern void PlaceVanillaShopItems(); @@ -34,5 +28,3 @@ extern uint16_t GetRandomPrice(Rando::Location* loc, PriceSettingsStruct priceSe extern uint16_t GetCheapBalancedPrice(); extern int GetShopsanityReplaceAmount(); extern Text GetIceTrapName(uint8_t id); - - diff --git a/soh/soh/Enhancements/randomizer/3drando/text.hpp b/soh/soh/Enhancements/randomizer/3drando/text.hpp index 46c0196bb..1196ac928 100644 --- a/soh/soh/Enhancements/randomizer/3drando/text.hpp +++ b/soh/soh/Enhancements/randomizer/3drando/text.hpp @@ -7,22 +7,20 @@ #define SINGULAR 1 class Text { -public: + public: Text() = default; Text(std::string english_, std::string french_, std::string spanish_) - : english(std::move(english_)), - french(std::move(french_)), - spanish(std::move(spanish_)), - german(std::move("")) { - // german defaults to english text until a translation is provided. - german = english; - } + : english(std::move(english_)), french(std::move(french_)), spanish(std::move(spanish_)), + german(std::move("")) { + // german defaults to english text until a translation is provided. + german = english; + } Text(std::string english_, std::string french_, std::string spanish_, std::string german_) - : english(std::move(english_)), - french(std::move(french_)), - spanish(std::move(spanish_)), - german(std::move(german_)) {} - Text(std::string english_) : english(std::move(english_)), french(std::move("")), spanish(std::move("")), german(std::move("")) { + : english(std::move(english_)), french(std::move(french_)), spanish(std::move(spanish_)), + german(std::move(german_)) { + } + Text(std::string english_) + : english(std::move(english_)), french(std::move("")), spanish(std::move("")), german(std::move("")) { // default unprovided languages to english text french = spanish = german = english; } @@ -54,24 +52,24 @@ public: const std::string& GetForLanguage(uint8_t language) const { switch (language) { - case 0: //LANGUAGE_ENG: changed to resolve #include loops + case 0: // LANGUAGE_ENG: changed to resolve #include loops return GetEnglish(); - case 2: //LANGUAGE_FRA: + case 2: // LANGUAGE_FRA: return GetFrench(); - case 1: //LANGUAGE_GER: + case 1: // LANGUAGE_GER: return GetGerman(); default: return GetEnglish(); } } - Text operator+ (const Text& right) const { - return Text{english + right.GetEnglish(), french + right.GetFrench(), spanish + right.GetSpanish(), - german + right.GetGerman()}; + Text operator+(const Text& right) const { + return Text{ english + right.GetEnglish(), french + right.GetFrench(), spanish + right.GetSpanish(), + german + right.GetGerman() }; } - Text operator+ (const std::string& right) const { - return Text{english + right, french + right, spanish + right, german + right}; + Text operator+(const std::string& right) const { + return Text{ english + right, french + right, spanish + right, german + right }; } bool operator==(const Text& right) const { @@ -88,11 +86,11 @@ public: void Replace(std::string oldStr, std::string newStr) { - for (std::string* str : {&english, &french, &spanish, &german}) { + for (std::string* str : { &english, &french, &spanish, &german }) { size_t position = str->find(oldStr); while (position != std::string::npos) { - str->replace(position, oldStr.length(), newStr); - position = str->find(oldStr); + str->replace(position, oldStr.length(), newStr); + position = str->find(oldStr); } } } @@ -123,15 +121,15 @@ public: // Convert first char to upper case Text Capitalize(void) const { Text cap = *this + ""; - for (std::string* str : {&cap.english, &cap.french, &cap.spanish, &cap.german}) { + for (std::string* str : { &cap.english, &cap.french, &cap.spanish, &cap.german }) { (*str)[0] = std::toupper((*str)[0]); } return cap; } - //find the appropriate bars that separate singular from plural + // find the appropriate bars that separate singular from plural void SetForm(int form) { - for (std::string* str : {&english, &french, &spanish, &german}) { + for (std::string* str : { &english, &french, &spanish, &german }) { size_t firstBar = str->find('|'); if (firstBar != std::string::npos) { @@ -151,7 +149,7 @@ public: } } } - //remove the remaining bar + // remove the remaining bar this->Replace("|", ""); } diff --git a/soh/soh/ShipInit.hpp b/soh/soh/ShipInit.hpp index b5351cdc0..2341a1024 100644 --- a/soh/soh/ShipInit.hpp +++ b/soh/soh/ShipInit.hpp @@ -28,34 +28,34 @@ struct ShipInit { /** * @brief Register a function to execute on boot and (optionally) in other situations - * + * * @param initFunc The function to execute * @param updatePaths Strings to specify additional situations in which to execute the function - * + * * ### Examples: - * + * * #### Execute function `bar` on boot - * + * * ```cpp * static RegisterShipInitFunc foo(bar); * ``` - * + * * #### Execute function `bar` on boot and when the CVar `baz` might have changed - * + * * ```cpp * static RegisterShipInitFunc foo(bar, { "baz" }); * ``` - * + * * #### Execute function `bar` on boot and when `IS_RANDO` might have changed - * + * * ```cpp * static RegisterShipInitFunc foo(bar, { "IS_RANDO" }); * ``` - * + * * ### Additional Information: - * - * To get a better sense of when your function will be executed - * you can look for `ShipInit::Init` calls throughout the codebase + * + * To get a better sense of when your function will be executed + * you can look for `ShipInit::Init` calls throughout the codebase */ struct RegisterShipInitFunc { RegisterShipInitFunc(std::function initFunc, const std::set& updatePaths = {}) { diff --git a/soh/soh/SohGui/SohGui.hpp b/soh/soh/SohGui/SohGui.hpp index b1d278e06..d9b7bb644 100644 --- a/soh/soh/SohGui/SohGui.hpp +++ b/soh/soh/SohGui/SohGui.hpp @@ -32,14 +32,15 @@ #include "SohModals.h" namespace SohGui { - void SetupHooks(); - void SetupGuiElements(); - void Draw(); - void Destroy(); - void RegisterPopup(std::string title, std::string message, std::string button1 = "OK", std::string button2 = "", std::function button1callback = nullptr, std::function button2callback = nullptr); - void ShowRandomizerSettingsMenu(); - UIWidgets::Colors GetMenuThemeColor(); -} +void SetupHooks(); +void SetupGuiElements(); +void Draw(); +void Destroy(); +void RegisterPopup(std::string title, std::string message, std::string button1 = "OK", std::string button2 = "", + std::function button1callback = nullptr, std::function button2callback = nullptr); +void ShowRandomizerSettingsMenu(); +UIWidgets::Colors GetMenuThemeColor(); +} // namespace SohGui #define THEME_COLOR SohGui::GetMenuThemeColor() diff --git a/soh/soh/SohGui/UIWidgets.hpp b/soh/soh/SohGui/UIWidgets.hpp index ab6e75b19..2382bb7f6 100644 --- a/soh/soh/SohGui/UIWidgets.hpp +++ b/soh/soh/SohGui/UIWidgets.hpp @@ -14,903 +14,905 @@ namespace UIWidgets { - using SectionFunc = void(*)(); +using SectionFunc = void (*)(); - struct TextFilters { - static int FilterNumbers(ImGuiInputTextCallbackData* data) { - if (data->EventChar < 256 && strchr("1234567890", (char)data->EventChar)) { - return 0; - } - return 1; +struct TextFilters { + static int FilterNumbers(ImGuiInputTextCallbackData* data) { + if (data->EventChar < 256 && strchr("1234567890", (char)data->EventChar)) { + return 0; } - - static int FilterAlphaNum(ImGuiInputTextCallbackData* data) { - const char* alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789"; - if (data->EventChar < 256 && strchr(alphanum, (char)data->EventChar)) { - return 0; - } - return 1; - } - }; - - std::string WrappedText(const char* text, unsigned int charactersPerLine = 80); - std::string WrappedText(const std::string& text, unsigned int charactersPerLine = 80); - void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f, float extraVerticalBottomPadding = 0.0f); - void Tooltip(const char* text); - - typedef enum ColorPickerModifiers { - ColorPickerResetButton = 1, - ColorPickerRandomButton = 2, - ColorPickerRainbowCheck = 4, - ColorPickerLockCheck = 8, - } ColorPickerModifiers; - - // mostly in order for colors usable by the menu without custom text color - enum Colors { - Red, - DarkRed, - Orange, - Green, - DarkGreen, - LightBlue, - Blue, - DarkBlue, - Indigo, - Violet, - Purple, - Brown, - Gray, - DarkGray, - // not suitable for menu theme use - Pink, - Yellow, - Cyan, - Black, - LightGray, - White, - NoColor - }; - - enum InputTypes { - String, - Scalar - }; - - const std::unordered_map ColorValues = { - { Colors::Pink, ImVec4(0.87f, 0.3f, 0.87f, 1.0f) }, - { Colors::Red, ImVec4(0.55f, 0.0f, 0.0f, 1.0f) }, - { Colors::DarkRed, ImVec4(0.3f, 0.0f, 0.0f, 1.0f) }, - { Colors::Orange, ImVec4(0.85f, 0.55f, 0.0f, 1.0f) }, - { Colors::Yellow, ImVec4(0.95f, 0.95f, 0.0f, 1.0f) }, - { Colors::Green, ImVec4(0.0f, 0.55f, 0.0f, 1.0f) }, - { Colors::DarkGreen, ImVec4(0.0f, 0.3f, 0.0f, 1.0f) }, - { Colors::Cyan, ImVec4(0.0f, 0.9f, 0.9f, 1.0f) }, - { Colors::LightBlue, ImVec4(0.0f, 0.24f, 0.8f, 1.0f) }, - { Colors::Blue, ImVec4(0.08f, 0.03f, 0.65f, 1.0f) }, - { Colors::DarkBlue, ImVec4(0.03f, 0.0f, 0.5f, 1.0f) }, - { Colors::Indigo, ImVec4(0.35f, 0.0f, 0.87f, 1.0f) }, - { Colors::Violet, ImVec4(0.5f, 0.0f, 0.9f, 1.0f) }, - { Colors::Purple, ImVec4(0.31f, 0.0f, 0.67f, 1.0f) }, - { Colors::Brown, ImVec4(0.37f, 0.18f, 0.0f, 1.0f) }, - { Colors::LightGray, ImVec4(0.75f, 0.75f, 0.75f, 1.0f) }, - { Colors::Gray, ImVec4(0.45f, 0.45f, 0.45f, 1.0f) }, - { Colors::DarkGray, ImVec4(0.15f, 0.15f, 0.15f, 1.0f) }, - { Colors::Black, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)}, - { Colors::White, ImVec4(1.0f, 1.0f, 1.0f, 1.0f) }, - { Colors::NoColor, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)}, - }; - - namespace Sizes { - const ImVec2 Inline = ImVec2(0.0f, 0.0f); - const ImVec2 Fill = ImVec2(-1.0f, 0.0f); + return 1; } - enum LabelPositions { - Near, - Far, - Above, - None, - Within, - }; + static int FilterAlphaNum(ImGuiInputTextCallbackData* data) { + const char* alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789"; + if (data->EventChar < 256 && strchr(alphanum, (char)data->EventChar)) { + return 0; + } + return 1; + } +}; - enum ComponentAlignments { - Left, - Right, - }; +std::string WrappedText(const char* text, unsigned int charactersPerLine = 80); +std::string WrappedText(const std::string& text, unsigned int charactersPerLine = 80); +void PaddedSeparator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f, + float extraVerticalBottomPadding = 0.0f); +void Tooltip(const char* text); - struct WidgetOptions{ - const char* tooltip = ""; - bool disabled = false; - const char* disabledTooltip = ""; +typedef enum ColorPickerModifiers { + ColorPickerResetButton = 1, + ColorPickerRandomButton = 2, + ColorPickerRainbowCheck = 4, + ColorPickerLockCheck = 8, +} ColorPickerModifiers; - WidgetOptions& Tooltip(const char* tooltip_) { - tooltip = tooltip_; - return *this; - } - WidgetOptions& Disabled(bool disabled_) { - disabled = disabled_; - return *this; - } - WidgetOptions& DisabledTooltip(const char* disabledTooltip_) { - disabledTooltip = disabledTooltip_; - return *this; - } - }; +// mostly in order for colors usable by the menu without custom text color +enum Colors { + Red, + DarkRed, + Orange, + Green, + DarkGreen, + LightBlue, + Blue, + DarkBlue, + Indigo, + Violet, + Purple, + Brown, + Gray, + DarkGray, + // not suitable for menu theme use + Pink, + Yellow, + Cyan, + Black, + LightGray, + White, + NoColor +}; - struct TextOptions : WidgetOptions { - Colors color = Colors::NoColor; +enum InputTypes { String, Scalar }; - TextOptions& Color(Colors color_) { - color = color_; - return *this; - } - }; +const std::unordered_map ColorValues = { + { Colors::Pink, ImVec4(0.87f, 0.3f, 0.87f, 1.0f) }, { Colors::Red, ImVec4(0.55f, 0.0f, 0.0f, 1.0f) }, + { Colors::DarkRed, ImVec4(0.3f, 0.0f, 0.0f, 1.0f) }, { Colors::Orange, ImVec4(0.85f, 0.55f, 0.0f, 1.0f) }, + { Colors::Yellow, ImVec4(0.95f, 0.95f, 0.0f, 1.0f) }, { Colors::Green, ImVec4(0.0f, 0.55f, 0.0f, 1.0f) }, + { Colors::DarkGreen, ImVec4(0.0f, 0.3f, 0.0f, 1.0f) }, { Colors::Cyan, ImVec4(0.0f, 0.9f, 0.9f, 1.0f) }, + { Colors::LightBlue, ImVec4(0.0f, 0.24f, 0.8f, 1.0f) }, { Colors::Blue, ImVec4(0.08f, 0.03f, 0.65f, 1.0f) }, + { Colors::DarkBlue, ImVec4(0.03f, 0.0f, 0.5f, 1.0f) }, { Colors::Indigo, ImVec4(0.35f, 0.0f, 0.87f, 1.0f) }, + { Colors::Violet, ImVec4(0.5f, 0.0f, 0.9f, 1.0f) }, { Colors::Purple, ImVec4(0.31f, 0.0f, 0.67f, 1.0f) }, + { Colors::Brown, ImVec4(0.37f, 0.18f, 0.0f, 1.0f) }, { Colors::LightGray, ImVec4(0.75f, 0.75f, 0.75f, 1.0f) }, + { Colors::Gray, ImVec4(0.45f, 0.45f, 0.45f, 1.0f) }, { Colors::DarkGray, ImVec4(0.15f, 0.15f, 0.15f, 1.0f) }, + { Colors::Black, ImVec4(0.0f, 0.0f, 0.0f, 1.0f) }, { Colors::White, ImVec4(1.0f, 1.0f, 1.0f, 1.0f) }, + { Colors::NoColor, ImVec4(0.0f, 0.0f, 0.0f, 0.0f) }, +}; - struct ButtonOptions : WidgetOptions { - ImVec2 size = Sizes::Fill; - ImVec2 padding = ImVec2(10.0f, 8.0f); - Colors color = Colors::Gray; +namespace Sizes { +const ImVec2 Inline = ImVec2(0.0f, 0.0f); +const ImVec2 Fill = ImVec2(-1.0f, 0.0f); +} // namespace Sizes - ButtonOptions& Size(ImVec2 size_) { - size = size_; - return *this; - } - ButtonOptions& Padding(ImVec2 padding_) { - padding = padding_; - return *this; - } - ButtonOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - ButtonOptions& Color(Colors color_) { - color = color_; - return *this; - } - }; +enum LabelPositions { + Near, + Far, + Above, + None, + Within, +}; - struct WindowButtonOptions : WidgetOptions { - ImVec2 size = Sizes::Inline; - ImVec2 padding = ImVec2(10.0f, 8.0f); - Colors color = Colors::Gray; - bool showButton = true; - bool embedWindow = true; +enum ComponentAlignments { + Left, + Right, +}; - WindowButtonOptions& Size(ImVec2 size_) { - size = size_; - return *this; - } - WindowButtonOptions& Padding(ImVec2 padding_) { - padding = padding_; - return *this; - } - WindowButtonOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - WindowButtonOptions& Color(Colors color_) { - color = color_; - return *this; - } - WindowButtonOptions& ShowButton(bool showButton_) { - showButton = showButton_; - return *this; - } - WindowButtonOptions& EmbedWindow(bool embedWindow_) { - embedWindow = embedWindow_; - return *this; - } - }; +struct WidgetOptions { + const char* tooltip = ""; + bool disabled = false; + const char* disabledTooltip = ""; - struct CheckboxOptions : WidgetOptions { - bool defaultValue = false; // Only applicable to CVarCheckbox - ComponentAlignments alignment = ComponentAlignments::Left; - LabelPositions labelPosition = LabelPositions::Near; - Colors color = Colors::LightBlue; + WidgetOptions& Tooltip(const char* tooltip_) { + tooltip = tooltip_; + return *this; + } + WidgetOptions& Disabled(bool disabled_) { + disabled = disabled_; + return *this; + } + WidgetOptions& DisabledTooltip(const char* disabledTooltip_) { + disabledTooltip = disabledTooltip_; + return *this; + } +}; - CheckboxOptions& DefaultValue(bool defaultValue_) { - defaultValue = defaultValue_; - return *this; - } - CheckboxOptions& ComponentAlignment(ComponentAlignments alignment_) { - alignment = alignment_; - return *this; - } - CheckboxOptions& LabelPosition(LabelPositions labelPosition_) { - labelPosition = labelPosition_; - return *this; - } - CheckboxOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - CheckboxOptions& Color(Colors color_) { - color = color_; - return *this; - } - CheckboxOptions& DisabledTooltip(const char* disabledTooltip_) { - WidgetOptions::disabledTooltip = disabledTooltip_; - return *this; - } - }; +struct TextOptions : WidgetOptions { + Colors color = Colors::NoColor; - struct ComboboxOptions : WidgetOptions { - std::unordered_map comboMap = {}; - uint32_t defaultIndex = 0; // Only applicable to CVarCombobox - ComponentAlignments alignment = ComponentAlignments::Left; - LabelPositions labelPosition = LabelPositions::Above; - ImGuiComboFlags flags = 0; - Colors color = Colors::LightBlue; + TextOptions& Color(Colors color_) { + color = color_; + return *this; + } +}; - ComboboxOptions& ComboMap(std::unordered_map comboMap_) { - comboMap = comboMap_; - return *this; - } - ComboboxOptions& DefaultIndex(uint32_t defaultIndex_) { - defaultIndex = defaultIndex_; - return *this; - } - ComboboxOptions& ComponentAlignment(ComponentAlignments alignment_) { - alignment = alignment_; - return *this; - } - ComboboxOptions& LabelPosition(LabelPositions labelPosition_) { - labelPosition = labelPosition_; - return *this; - } - ComboboxOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - ComboboxOptions& Color(Colors color_) { - color = color_; - return *this; - } - }; +struct ButtonOptions : WidgetOptions { + ImVec2 size = Sizes::Fill; + ImVec2 padding = ImVec2(10.0f, 8.0f); + Colors color = Colors::Gray; - struct IntSliderOptions : WidgetOptions { - bool showButtons = true; - const char* format = "%d"; - int32_t step = 1; - int32_t min = 1; - int32_t max = 10; - int32_t defaultValue = 1; - bool clamp = true; - ComponentAlignments alignment = ComponentAlignments::Left; - LabelPositions labelPosition = LabelPositions::Above; - Colors color = Colors::Gray; - ImGuiSliderFlags flags = 0; - ImVec2 size = {0,0}; + ButtonOptions& Size(ImVec2 size_) { + size = size_; + return *this; + } + ButtonOptions& Padding(ImVec2 padding_) { + padding = padding_; + return *this; + } + ButtonOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + ButtonOptions& Color(Colors color_) { + color = color_; + return *this; + } +}; - IntSliderOptions& ShowButtons(bool showButtons_) { - showButtons = showButtons_; - return *this; - } - IntSliderOptions& Format(const char* format_) { - format = format_; - return *this; - } - IntSliderOptions& Step(int32_t step_) { - step = step_; - return *this; - } - IntSliderOptions& Min(int32_t min_) { - min = min_; - return *this; - } - IntSliderOptions& Max(int32_t max_) { - max = max_; - return *this; - } - IntSliderOptions& DefaultValue(int32_t defaultValue_) { - defaultValue = defaultValue_; - return *this; - } - IntSliderOptions& ComponentAlignment(ComponentAlignments alignment_) { - alignment = alignment_; - return *this; - } - IntSliderOptions& LabelPosition(LabelPositions labelPosition_) { - labelPosition = labelPosition_; - return *this; - } - IntSliderOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - IntSliderOptions& Color(Colors color_) { - color = color_; - return *this; - } - IntSliderOptions& Size(ImVec2 size_) { - size = size_; - return *this; - } - IntSliderOptions& Clamp(bool clamp_) { - clamp = clamp_; - return *this; - } - }; +struct WindowButtonOptions : WidgetOptions { + ImVec2 size = Sizes::Inline; + ImVec2 padding = ImVec2(10.0f, 8.0f); + Colors color = Colors::Gray; + bool showButton = true; + bool embedWindow = true; - struct FloatSliderOptions : WidgetOptions { - bool showButtons = true; - const char* format = "%f"; - float step = 0.01f; - float min = 0.01f; - float max = 10.0f; - float defaultValue = 1.0f; - bool clamp = true; - bool isPercentage = false; // Multiplies visual value by 100 - ComponentAlignments alignment = ComponentAlignments::Left; - LabelPositions labelPosition = LabelPositions::Above; - Colors color = Colors::Gray; - ImGuiSliderFlags flags = 0; - ImVec2 size = {0,0}; + WindowButtonOptions& Size(ImVec2 size_) { + size = size_; + return *this; + } + WindowButtonOptions& Padding(ImVec2 padding_) { + padding = padding_; + return *this; + } + WindowButtonOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + WindowButtonOptions& Color(Colors color_) { + color = color_; + return *this; + } + WindowButtonOptions& ShowButton(bool showButton_) { + showButton = showButton_; + return *this; + } + WindowButtonOptions& EmbedWindow(bool embedWindow_) { + embedWindow = embedWindow_; + return *this; + } +}; - FloatSliderOptions& ShowButtons(bool showButtons_) { - showButtons = showButtons_; - return *this; - } - FloatSliderOptions& Format(const char* format_) { - format = format_; - return *this; - } - FloatSliderOptions& Step(float step_) { - step = step_; - return *this; - } - FloatSliderOptions& Min(float min_) { - min = min_; - return *this; - } - FloatSliderOptions& Max(float max_) { - max = max_; - return *this; - } - FloatSliderOptions& DefaultValue(float defaultValue_) { - defaultValue = defaultValue_; - return *this; - } - FloatSliderOptions& ComponentAlignment(ComponentAlignments alignment_) { - alignment = alignment_; - return *this; - } - FloatSliderOptions& LabelPosition(LabelPositions labelPosition_) { - labelPosition = labelPosition_; - return *this; - } - FloatSliderOptions& IsPercentage(bool isPercentage_ = true) { - isPercentage = isPercentage_; - format = "%.0f%%"; - min = 0.0f; - max = 1.0f; - return *this; - } - FloatSliderOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - FloatSliderOptions& Color(Colors color_) { - color = color_; - return *this; - } - FloatSliderOptions& Size(ImVec2 size_) { - size = size_; - return *this; - } - FloatSliderOptions& Clamp(bool clamp_) { - clamp = clamp_; - return *this; - } - }; +struct CheckboxOptions : WidgetOptions { + bool defaultValue = false; // Only applicable to CVarCheckbox + ComponentAlignments alignment = ComponentAlignments::Left; + LabelPositions labelPosition = LabelPositions::Near; + Colors color = Colors::LightBlue; - struct RadioButtonsOptions : WidgetOptions { - std::unordered_map buttonMap; - Colors color = Colors::LightBlue; + CheckboxOptions& DefaultValue(bool defaultValue_) { + defaultValue = defaultValue_; + return *this; + } + CheckboxOptions& ComponentAlignment(ComponentAlignments alignment_) { + alignment = alignment_; + return *this; + } + CheckboxOptions& LabelPosition(LabelPositions labelPosition_) { + labelPosition = labelPosition_; + return *this; + } + CheckboxOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + CheckboxOptions& Color(Colors color_) { + color = color_; + return *this; + } + CheckboxOptions& DisabledTooltip(const char* disabledTooltip_) { + WidgetOptions::disabledTooltip = disabledTooltip_; + return *this; + } +}; - RadioButtonsOptions& ButtonMap(std::unordered_map buttonMap_) { - buttonMap = buttonMap_; - return *this; +struct ComboboxOptions : WidgetOptions { + std::unordered_map comboMap = {}; + uint32_t defaultIndex = 0; // Only applicable to CVarCombobox + ComponentAlignments alignment = ComponentAlignments::Left; + LabelPositions labelPosition = LabelPositions::Above; + ImGuiComboFlags flags = 0; + Colors color = Colors::LightBlue; + + ComboboxOptions& ComboMap(std::unordered_map comboMap_) { + comboMap = comboMap_; + return *this; + } + ComboboxOptions& DefaultIndex(uint32_t defaultIndex_) { + defaultIndex = defaultIndex_; + return *this; + } + ComboboxOptions& ComponentAlignment(ComponentAlignments alignment_) { + alignment = alignment_; + return *this; + } + ComboboxOptions& LabelPosition(LabelPositions labelPosition_) { + labelPosition = labelPosition_; + return *this; + } + ComboboxOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + ComboboxOptions& Color(Colors color_) { + color = color_; + return *this; + } +}; + +struct IntSliderOptions : WidgetOptions { + bool showButtons = true; + const char* format = "%d"; + int32_t step = 1; + int32_t min = 1; + int32_t max = 10; + int32_t defaultValue = 1; + bool clamp = true; + ComponentAlignments alignment = ComponentAlignments::Left; + LabelPositions labelPosition = LabelPositions::Above; + Colors color = Colors::Gray; + ImGuiSliderFlags flags = 0; + ImVec2 size = { 0, 0 }; + + IntSliderOptions& ShowButtons(bool showButtons_) { + showButtons = showButtons_; + return *this; + } + IntSliderOptions& Format(const char* format_) { + format = format_; + return *this; + } + IntSliderOptions& Step(int32_t step_) { + step = step_; + return *this; + } + IntSliderOptions& Min(int32_t min_) { + min = min_; + return *this; + } + IntSliderOptions& Max(int32_t max_) { + max = max_; + return *this; + } + IntSliderOptions& DefaultValue(int32_t defaultValue_) { + defaultValue = defaultValue_; + return *this; + } + IntSliderOptions& ComponentAlignment(ComponentAlignments alignment_) { + alignment = alignment_; + return *this; + } + IntSliderOptions& LabelPosition(LabelPositions labelPosition_) { + labelPosition = labelPosition_; + return *this; + } + IntSliderOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + IntSliderOptions& Color(Colors color_) { + color = color_; + return *this; + } + IntSliderOptions& Size(ImVec2 size_) { + size = size_; + return *this; + } + IntSliderOptions& Clamp(bool clamp_) { + clamp = clamp_; + return *this; + } +}; + +struct FloatSliderOptions : WidgetOptions { + bool showButtons = true; + const char* format = "%f"; + float step = 0.01f; + float min = 0.01f; + float max = 10.0f; + float defaultValue = 1.0f; + bool clamp = true; + bool isPercentage = false; // Multiplies visual value by 100 + ComponentAlignments alignment = ComponentAlignments::Left; + LabelPositions labelPosition = LabelPositions::Above; + Colors color = Colors::Gray; + ImGuiSliderFlags flags = 0; + ImVec2 size = { 0, 0 }; + + FloatSliderOptions& ShowButtons(bool showButtons_) { + showButtons = showButtons_; + return *this; + } + FloatSliderOptions& Format(const char* format_) { + format = format_; + return *this; + } + FloatSliderOptions& Step(float step_) { + step = step_; + return *this; + } + FloatSliderOptions& Min(float min_) { + min = min_; + return *this; + } + FloatSliderOptions& Max(float max_) { + max = max_; + return *this; + } + FloatSliderOptions& DefaultValue(float defaultValue_) { + defaultValue = defaultValue_; + return *this; + } + FloatSliderOptions& ComponentAlignment(ComponentAlignments alignment_) { + alignment = alignment_; + return *this; + } + FloatSliderOptions& LabelPosition(LabelPositions labelPosition_) { + labelPosition = labelPosition_; + return *this; + } + FloatSliderOptions& IsPercentage(bool isPercentage_ = true) { + isPercentage = isPercentage_; + format = "%.0f%%"; + min = 0.0f; + max = 1.0f; + return *this; + } + FloatSliderOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + FloatSliderOptions& Color(Colors color_) { + color = color_; + return *this; + } + FloatSliderOptions& Size(ImVec2 size_) { + size = size_; + return *this; + } + FloatSliderOptions& Clamp(bool clamp_) { + clamp = clamp_; + return *this; + } +}; + +struct RadioButtonsOptions : WidgetOptions { + std::unordered_map buttonMap; + Colors color = Colors::LightBlue; + + RadioButtonsOptions& ButtonMap(std::unordered_map buttonMap_) { + buttonMap = buttonMap_; + return *this; + } + RadioButtonsOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + RadioButtonsOptions& Color(Colors color_) { + color = color_; + return *this; + } +}; + +struct InputOptions : WidgetOptions { + ComponentAlignments alignment = ComponentAlignments::Left; + LabelPositions labelPosition = LabelPositions::Above; + Colors color = Colors::Gray; + ImVec2 size = { 0, 0 }; + std::string placeholder = ""; + InputTypes type = InputTypes::String; + std::string defaultValue = ""; + bool secret = false; + ImGuiInputFlags addedFlags = 0; + + InputOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + InputOptions& Color(Colors color_) { + color = color_; + return *this; + } + InputOptions& Size(ImVec2 size_) { + size = size_; + return *this; + } + + InputOptions& LabelPosition(LabelPositions labelPosition_) { + labelPosition = labelPosition_; + return *this; + } + + InputOptions& PlaceholderText(std::string&& placeholder_) { + placeholder = std::move(placeholder_); + return *this; + } + + InputOptions& PlaceholderText(std::string& placeholder_) { + placeholder = placeholder_; + return *this; + } + + InputOptions& InputType(InputTypes type_) { + type = type_; + return *this; + } + + InputOptions& DefaultValue(std::string defaultValue_) { + defaultValue = defaultValue_; + return *this; + } + + InputOptions& IsSecret(bool secret_ = false) { + secret = secret_; + return *this; + } +}; + +void PushStyleMenu(const ImVec4& color); +void PushStyleMenu(Colors color = Colors::LightBlue); +void PopStyleMenu(); +bool BeginMenu(const char* label, Colors color = Colors::LightBlue); + +void PushStyleMenuItem(const ImVec4& color); +void PushStyleMenuItem(Colors color = Colors::LightBlue); +void PopStyleMenuItem(); +bool MenuItem(const char* label, const char* shortcut = NULL, Colors color = Colors::LightBlue); + +void PushStyleButton(const ImVec4& color, ImVec2 padding = ImVec2(10.0f, 8.0f)); +void PushStyleButton(Colors color = Colors::Gray, ImVec2 padding = ImVec2(10.0f, 8.0f)); +void PopStyleButton(); +bool Button(const char* label, const ButtonOptions& options = {}); +bool WindowButton(const char* label, const char* cvarName, std::shared_ptr windowPtr, + const WindowButtonOptions& options = {}); + +void PushStyleCheckbox(const ImVec4& color); +void PushStyleCheckbox(Colors color = Colors::LightBlue); +void PopStyleCheckbox(); +void RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash); +bool Checkbox(const char* label, bool* v, const CheckboxOptions& options = {}); +bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions& options = {}); + +void PushStyleCombobox(const ImVec4& color); +void PushStyleCombobox(Colors color = Colors::LightBlue); +void PopStyleCombobox(); + +void PushStyleTabs(const ImVec4& color); +void PushStyleTabs(Colors color = Colors::LightBlue); +void PopStyleTabs(); + +void PushStyleInput(const ImVec4& color); +void PushStyleInput(Colors color = Colors::LightBlue); +void PopStyleInput(); + +void PushStyleHeader(const ImVec4& color); +void PushStyleHeader(Colors color = Colors::LightBlue); +void PopStyleHeader(); + +void Spacer(float height = 0.0f); +void Separator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f, + float extraVerticalBottomPadding = 0.0f); + +float CalcComboWidth(const char* preview_value, ImGuiComboFlags flags); + +template +bool Combobox(const char* label, T* value, const std::unordered_map& comboMap, + const ComboboxOptions& options = {}) { + bool dirty = false; + float startX = ImGui::GetCursorPosX(); + std::string invisibleLabelStr = "##" + std::string(label); + const char* invisibleLabel = invisibleLabelStr.c_str(); + ImGui::PushID(label); + ImGui::BeginGroup(); + ImGui::BeginDisabled(options.disabled); + PushStyleCombobox(options.color); + + const char* longest; + size_t length = 0; + for (auto& [index, string] : comboMap) { + size_t len = strlen(string); + if (len > length) { + longest = string; + length = len; } - RadioButtonsOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - RadioButtonsOptions& Color(Colors color_) { - color = color_; - return *this; - } - }; + } + float comboWidth = CalcComboWidth(longest, options.flags); - struct InputOptions : WidgetOptions { - ComponentAlignments alignment = ComponentAlignments::Left; - LabelPositions labelPosition = LabelPositions::Above; - Colors color = Colors::Gray; - ImVec2 size = {0,0}; - std::string placeholder = ""; - InputTypes type = InputTypes::String; - std::string defaultValue = ""; - bool secret = false; - ImGuiInputFlags addedFlags = 0; - - InputOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - InputOptions& Color(Colors color_) { - color = color_; - return *this; - } - InputOptions& Size(ImVec2 size_) { - size = size_; - return *this; - } - - InputOptions& LabelPosition(LabelPositions labelPosition_) { - labelPosition = labelPosition_; - return *this; - } - - InputOptions& PlaceholderText(std::string&& placeholder_) { - placeholder = std::move(placeholder_); - return *this; - } - - InputOptions& PlaceholderText(std::string& placeholder_) { - placeholder = placeholder_; - return *this; - } - - InputOptions& InputType(InputTypes type_) { - type = type_; - return *this; - } - - InputOptions& DefaultValue(std::string defaultValue_) { - defaultValue = defaultValue_; - return *this; - } - - InputOptions& IsSecret(bool secret_ = false) { - secret = secret_; - return *this; - } - }; - - void PushStyleMenu(const ImVec4& color); - void PushStyleMenu(Colors color = Colors::LightBlue); - void PopStyleMenu(); - bool BeginMenu(const char* label, Colors color = Colors::LightBlue); - - void PushStyleMenuItem(const ImVec4& color); - void PushStyleMenuItem(Colors color = Colors::LightBlue); - void PopStyleMenuItem(); - bool MenuItem(const char* label, const char* shortcut = NULL, Colors color = Colors::LightBlue); - - void PushStyleButton(const ImVec4& color, ImVec2 padding = ImVec2(10.0f, 8.0f)); - void PushStyleButton(Colors color = Colors::Gray, ImVec2 padding = ImVec2(10.0f, 8.0f)); - void PopStyleButton(); - bool Button(const char* label, const ButtonOptions& options = {}); - bool WindowButton(const char* label, const char* cvarName, std::shared_ptr windowPtr, const WindowButtonOptions& options = {}); - - void PushStyleCheckbox(const ImVec4& color); - void PushStyleCheckbox(Colors color = Colors::LightBlue); - void PopStyleCheckbox(); - void RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash); - bool Checkbox(const char* label, bool* v, const CheckboxOptions& options = {}); - bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions& options = {}); - - void PushStyleCombobox(const ImVec4& color); - void PushStyleCombobox(Colors color = Colors::LightBlue); - void PopStyleCombobox(); - - void PushStyleTabs(const ImVec4& color); - void PushStyleTabs(Colors color = Colors::LightBlue); - void PopStyleTabs(); - - void PushStyleInput(const ImVec4& color); - void PushStyleInput(Colors color = Colors::LightBlue); - void PopStyleInput(); - - void PushStyleHeader(const ImVec4& color); - void PushStyleHeader(Colors color = Colors::LightBlue); - void PopStyleHeader(); - - void Spacer(float height = 0.0f); - void Separator(bool padTop = true, bool padBottom = true, float extraVerticalTopPadding = 0.0f, - float extraVerticalBottomPadding = 0.0f); - - float CalcComboWidth(const char* preview_value, ImGuiComboFlags flags); - - template - bool Combobox(const char* label, T* value, const std::unordered_map& comboMap, const ComboboxOptions& options = {}) { - bool dirty = false; - float startX = ImGui::GetCursorPosX(); - std::string invisibleLabelStr = "##" + std::string(label); - const char* invisibleLabel = invisibleLabelStr.c_str(); - ImGui::PushID(label); - ImGui::BeginGroup(); - ImGui::BeginDisabled(options.disabled); - PushStyleCombobox(options.color); - - const char* longest; - size_t length = 0; - for (auto& [index, string] : comboMap) { - size_t len = strlen(string); - if (len > length) { - longest = string; - length = len; + ImGui::AlignTextToFramePadding(); + if (options.labelPosition != LabelPositions::None) { + if (options.alignment == ComponentAlignments::Right) { + ImGui::Text("%s", label); + if (options.labelPosition == LabelPositions::Above) { + ImGui::NewLine(); + ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); + } else if (options.labelPosition == LabelPositions::Near) { + ImGui::SameLine(); + } else if (options.labelPosition == LabelPositions::Far) { + ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); } - } - float comboWidth = CalcComboWidth(longest, options.flags); - - ImGui::AlignTextToFramePadding(); - if (options.labelPosition != LabelPositions::None) { - if (options.alignment == ComponentAlignments::Right) { + } else if (options.alignment == ComponentAlignments::Left) { + if (options.labelPosition == LabelPositions::Above) { ImGui::Text("%s", label); - if (options.labelPosition == LabelPositions::Above) { - ImGui::NewLine(); - ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); - } else if (options.labelPosition == LabelPositions::Near) { - ImGui::SameLine(); - } else if (options.labelPosition == LabelPositions::Far) { - ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); - } - } else if (options.alignment == ComponentAlignments::Left) { - if (options.labelPosition == LabelPositions::Above) { - ImGui::Text("%s", label); - } } } - - ImGui::SetNextItemWidth(comboWidth); - if (ImGui::BeginCombo(invisibleLabel, comboMap.at(*value), options.flags)) { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); - for (const auto& pair : comboMap) { - if (strlen(pair.second) > 1) { - if (ImGui::Selectable(pair.second, pair.first == *value)) { - *value = pair.first; - dirty = true; - } - } - } - ImGui::PopStyleVar(); - ImGui::EndCombo(); - } - - if (options.labelPosition != LabelPositions::None) { - if (options.alignment == ComponentAlignments::Left) { - if (options.labelPosition == LabelPositions::Near) { - ImGui::SameLine(); - ImGui::Text("%s", label); - } else if (options.labelPosition == LabelPositions::Far) { - float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 2; - ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); - ImGui::Text("%s", label); - } - } - } - PopStyleCombobox(); - ImGui::EndDisabled(); - ImGui::EndGroup(); - if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); - } - ImGui::PopID(); - return dirty; } - template - bool Combobox(const char* label, T* value, const std::vector& comboVector, const ComboboxOptions& options = {}) { - bool dirty = false; - size_t currentValueIndex = static_cast(*value); - std::string invisibleLabelStr = "##" + std::string(label); - const char* invisibleLabel = invisibleLabelStr.c_str(); - ImGui::PushID(label); - ImGui::BeginGroup(); - ImGui::BeginDisabled(options.disabled); - PushStyleCombobox(options.color); - - const char* longest; - int length = 0; - for (auto& string : comboVector) { - int len = strlen(string); - if (len > length) { - longest = string; - length = len; + ImGui::SetNextItemWidth(comboWidth); + if (ImGui::BeginCombo(invisibleLabel, comboMap.at(*value), options.flags)) { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); + for (const auto& pair : comboMap) { + if (strlen(pair.second) > 1) { + if (ImGui::Selectable(pair.second, pair.first == *value)) { + *value = pair.first; + dirty = true; + } } } - float comboWidth = CalcComboWidth(longest, options.flags); + ImGui::PopStyleVar(); + ImGui::EndCombo(); + } - ImGui::AlignTextToFramePadding(); - if (options.labelPosition != LabelPositions::None) { - if (options.alignment == ComponentAlignments::Right) { + if (options.labelPosition != LabelPositions::None) { + if (options.alignment == ComponentAlignments::Left) { + if (options.labelPosition == LabelPositions::Near) { + ImGui::SameLine(); ImGui::Text("%s", label); - if (options.labelPosition == LabelPositions::Above) { - ImGui::NewLine(); - ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); - } else if (options.labelPosition == LabelPositions::Near) { - ImGui::SameLine(); - } else if (options.labelPosition == LabelPositions::Far) { - ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); - } - } else if (options.alignment == ComponentAlignments::Left) { - if (options.labelPosition == LabelPositions::Above) { - ImGui::Text("%s", label); - } - } - } - - ImGui::SetNextItemWidth(comboWidth); - if (ImGui::BeginCombo(invisibleLabel, comboVector.at(currentValueIndex), options.flags)) { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); - for (size_t i = 0; i < comboVector.size(); ++i) { - auto newValue = static_cast(i); - if (strlen(comboVector.at(i)) > 1) { - if (ImGui::Selectable(comboVector.at(i), newValue == *value)) { - *value = newValue; - dirty = true; - } - } - } - ImGui::PopStyleVar(); - ImGui::EndCombo(); - } - - if (options.labelPosition != LabelPositions::None) { - if (options.alignment == ComponentAlignments::Left) { - if (options.labelPosition == LabelPositions::Near) { - ImGui::SameLine(); - ImGui::Text("%s", label); - } else if (options.labelPosition == LabelPositions::Far) { - float width = ImGui::CalcTextSize(comboVector.at(*value)).x + ImGui::GetStyle().FramePadding.x * 2; - ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); - ImGui::Text("%s", label); - } - } - } - - PopStyleCombobox(); - ImGui::EndDisabled(); - ImGui::EndGroup(); - if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); - } - ImGui::PopID(); - return dirty; - } - - template - bool Combobox(const char* label, T* value, const std::vector& comboVector, const ComboboxOptions& options = {}) { - bool dirty = false; - size_t currentValueIndex = static_cast(*value); - std::string invisibleLabelStr = "##" + std::string(label); - const char* invisibleLabel = invisibleLabelStr.c_str(); - ImGui::PushID(label); - ImGui::BeginGroup(); - ImGui::BeginDisabled(options.disabled); - PushStyleCombobox(options.color); - - const char* longest; - int length = 0; - for (auto& string : comboVector) { - int len = string.length(); - if (len > length) { - longest = string.c_str(); - length = len; - } - } - float comboWidth = CalcComboWidth(longest, options.flags); - - ImGui::AlignTextToFramePadding(); - if (options.labelPosition != LabelPositions::None) { - if (options.alignment == ComponentAlignments::Right) { + } else if (options.labelPosition == LabelPositions::Far) { + float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 2; + ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); ImGui::Text("%s", label); - if (options.labelPosition == LabelPositions::Above) { - ImGui::NewLine(); - ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); - } else if (options.labelPosition == LabelPositions::Near) { - ImGui::SameLine(); - } else if (options.labelPosition == LabelPositions::Far) { - ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); - } - } else if (options.alignment == ComponentAlignments::Left) { - if (options.labelPosition == LabelPositions::Above) { - ImGui::Text("%s", label); - } } } - - ImGui::SetNextItemWidth(comboWidth); - if (ImGui::BeginCombo(invisibleLabel, comboVector.at(currentValueIndex).c_str(), options.flags)) { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); - for (size_t i = 0; i < comboVector.size(); ++i) { - auto newValue = static_cast(i); - if (comboVector.at(i).length() > 1) { - if (ImGui::Selectable(comboVector.at(i).c_str(), newValue == *value)) { - *value = newValue; - dirty = true; - } - } - } - ImGui::PopStyleVar(); - ImGui::EndCombo(); - } - - if (options.labelPosition != LabelPositions::None) { - if (options.alignment == ComponentAlignments::Left) { - if (options.labelPosition == LabelPositions::Near) { - ImGui::SameLine(); - ImGui::Text("%s", label); - } else if (options.labelPosition == LabelPositions::Far) { - float width = ImGui::CalcTextSize(comboVector.at(*value).c_str()).x + ImGui::GetStyle().FramePadding.x * 2; - ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); - ImGui::Text("%s", label); - } - } - } - - PopStyleCombobox(); - ImGui::EndDisabled(); - ImGui::EndGroup(); - if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); - } - ImGui::PopID(); - return dirty; } - - template - bool Combobox(const char* label, T* value, const char* (&comboArray)[N], const ComboboxOptions& options = {}) { - bool dirty = false; - size_t currentValueIndex = static_cast(*value); - if (currentValueIndex >= N) { - currentValueIndex = 0; - } - std::string invisibleLabelStr = "##" + std::string(label); - const char* invisibleLabel = invisibleLabelStr.c_str(); - ImGui::PushID(label); - ImGui::BeginGroup(); - ImGui::BeginDisabled(options.disabled); - PushStyleCombobox(options.color); - - const char* longest; - size_t length = 0; - for (size_t i = 0; i < N; i++) { - size_t len = strlen(comboArray[i]); - if (len > length) { - longest = comboArray[i]; - length = len; - } - } - float comboWidth = CalcComboWidth(longest, options.flags); - - ImGui::AlignTextToFramePadding(); - if (options.labelPosition != LabelPositions::None) { - if (options.alignment == ComponentAlignments::Right) { - ImGui::Text("%s", label); - if (options.labelPosition == LabelPositions::Above) { - ImGui::NewLine(); - ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); - } else if (options.labelPosition == LabelPositions::Near) { - ImGui::SameLine(); - } else if (options.labelPosition == LabelPositions::Far) { - ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); - } - } else if (options.alignment == ComponentAlignments::Left) { - if (options.labelPosition == LabelPositions::Above) { - ImGui::Text("%s", label); - } - } - } - - ImGui::SetNextItemWidth(comboWidth); - if (ImGui::BeginCombo(invisibleLabel, comboArray[currentValueIndex], options.flags)) { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); - for (size_t i = 0; i < N; ++i) { - auto newValue = static_cast(i); - if (strlen(comboArray[i]) > 1) { - if (ImGui::Selectable(comboArray[i], newValue == *value)) { - *value = newValue; - dirty = true; - } - } - } - ImGui::PopStyleVar(); - ImGui::EndCombo(); - } - - if (options.labelPosition != LabelPositions::None) { - if (options.alignment == ComponentAlignments::Left) { - if (options.labelPosition == LabelPositions::Near) { - ImGui::SameLine(); - ImGui::Text("%s", label); - } else if (options.labelPosition == LabelPositions::Far) { - float width = ImGui::CalcTextSize(comboArray[*value]).x + ImGui::GetStyle().FramePadding.x * 2; - ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); - ImGui::Text("%s", label); - } - } - } - PopStyleCombobox(); - ImGui::EndDisabled(); - ImGui::EndGroup(); - if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); - } - ImGui::PopID(); - return dirty; + PopStyleCombobox(); + ImGui::EndDisabled(); + ImGui::EndGroup(); + if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && + !Ship_IsCStringEmpty(options.disabledTooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); } - - template - bool CVarCombobox(const char* label, const char* cvarName, const std::unordered_map& comboMap, const ComboboxOptions& options = {}) { - bool dirty = false; - int32_t value = CVarGetInteger(cvarName, options.defaultIndex); - if (Combobox(label, &value, comboMap, options)) { - CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - ShipInit::Init(cvarName); - dirty = true; - } - return dirty; - } - - template - bool CVarCombobox(const char* label, const char* cvarName, const std::vector& comboVector, const ComboboxOptions& options = {}) { - bool dirty = false; - int32_t value = CVarGetInteger(cvarName, options.defaultIndex); - if (Combobox(label, &value, comboVector, options)) { - CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - ShipInit::Init(cvarName); - dirty = true; - } - return dirty; - } - - template - bool CVarCombobox(const char* label, const char* cvarName, const char* (&comboArray)[N], const ComboboxOptions& options = {}) { - bool dirty = false; - int32_t value = CVarGetInteger(cvarName, options.defaultIndex); - if (Combobox(label, &value, comboArray, options)) { - CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - ShipInit::Init(cvarName); - dirty = true; - } - return dirty; - } - - void PushStyleSlider(Colors color = Colors::LightBlue); - void PopStyleSlider(); - bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& options = {}); - bool CVarSliderInt(const char* label, const char* cvarName, const IntSliderOptions& options = {}); - bool SliderFloat(const char* label, float* value, const FloatSliderOptions& options = {}); - bool CVarSliderFloat(const char* label, const char* cvarName, const FloatSliderOptions& options = {}); - bool InputString(const char* label, std::string* value, const InputOptions& options = {}); - bool CVarInputString(const char* label, const char* cvarName, const InputOptions& options = {}); - bool InputInt(const char* label, int32_t* value, const InputOptions& options = {}); - bool CVarInputInt(const char* label, const char* cvarName, const InputOptions& options = {}); - bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaultColor, bool hasAlpha = false, uint8_t modifiers = 0, UIWidgets::Colors themeColor = UIWidgets::Colors::LightBlue); - bool RadioButton(const char* label, bool active); - bool CVarRadioButton(const char* text, const char* cvarName, int32_t id, const RadioButtonsOptions& options); - bool StateButton(const char* str_id, const char* label, ImVec2 size, UIWidgets::ButtonOptions options, ImGuiButtonFlags flags = ImGuiButtonFlags_None); - void DrawFlagArray32(const std::string& name, uint32_t& flags, Colors color = Colors::LightBlue); - void DrawFlagArray16(const std::string& name, uint16_t& flags, Colors color = Colors::LightBlue); - void DrawFlagArray8(const std::string& name, uint8_t& flags, Colors color = Colors::LightBlue); - void DrawFlagArray8Mask(const std::string& name, uint8_t& flags, Colors color = Colors::LightBlue); - - void InsertHelpHoverText(const std::string& text); - void InsertHelpHoverText(const char* text); + ImGui::PopID(); + return dirty; } + +template +bool Combobox(const char* label, T* value, const std::vector& comboVector, + const ComboboxOptions& options = {}) { + bool dirty = false; + size_t currentValueIndex = static_cast(*value); + std::string invisibleLabelStr = "##" + std::string(label); + const char* invisibleLabel = invisibleLabelStr.c_str(); + ImGui::PushID(label); + ImGui::BeginGroup(); + ImGui::BeginDisabled(options.disabled); + PushStyleCombobox(options.color); + + const char* longest; + int length = 0; + for (auto& string : comboVector) { + int len = strlen(string); + if (len > length) { + longest = string; + length = len; + } + } + float comboWidth = CalcComboWidth(longest, options.flags); + + ImGui::AlignTextToFramePadding(); + if (options.labelPosition != LabelPositions::None) { + if (options.alignment == ComponentAlignments::Right) { + ImGui::Text("%s", label); + if (options.labelPosition == LabelPositions::Above) { + ImGui::NewLine(); + ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); + } else if (options.labelPosition == LabelPositions::Near) { + ImGui::SameLine(); + } else if (options.labelPosition == LabelPositions::Far) { + ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); + } + } else if (options.alignment == ComponentAlignments::Left) { + if (options.labelPosition == LabelPositions::Above) { + ImGui::Text("%s", label); + } + } + } + + ImGui::SetNextItemWidth(comboWidth); + if (ImGui::BeginCombo(invisibleLabel, comboVector.at(currentValueIndex), options.flags)) { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); + for (size_t i = 0; i < comboVector.size(); ++i) { + auto newValue = static_cast(i); + if (strlen(comboVector.at(i)) > 1) { + if (ImGui::Selectable(comboVector.at(i), newValue == *value)) { + *value = newValue; + dirty = true; + } + } + } + ImGui::PopStyleVar(); + ImGui::EndCombo(); + } + + if (options.labelPosition != LabelPositions::None) { + if (options.alignment == ComponentAlignments::Left) { + if (options.labelPosition == LabelPositions::Near) { + ImGui::SameLine(); + ImGui::Text("%s", label); + } else if (options.labelPosition == LabelPositions::Far) { + float width = ImGui::CalcTextSize(comboVector.at(*value)).x + ImGui::GetStyle().FramePadding.x * 2; + ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); + ImGui::Text("%s", label); + } + } + } + + PopStyleCombobox(); + ImGui::EndDisabled(); + ImGui::EndGroup(); + if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && + !Ship_IsCStringEmpty(options.disabledTooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); + } + ImGui::PopID(); + return dirty; +} + +template +bool Combobox(const char* label, T* value, const std::vector& comboVector, + const ComboboxOptions& options = {}) { + bool dirty = false; + size_t currentValueIndex = static_cast(*value); + std::string invisibleLabelStr = "##" + std::string(label); + const char* invisibleLabel = invisibleLabelStr.c_str(); + ImGui::PushID(label); + ImGui::BeginGroup(); + ImGui::BeginDisabled(options.disabled); + PushStyleCombobox(options.color); + + const char* longest; + int length = 0; + for (auto& string : comboVector) { + int len = string.length(); + if (len > length) { + longest = string.c_str(); + length = len; + } + } + float comboWidth = CalcComboWidth(longest, options.flags); + + ImGui::AlignTextToFramePadding(); + if (options.labelPosition != LabelPositions::None) { + if (options.alignment == ComponentAlignments::Right) { + ImGui::Text("%s", label); + if (options.labelPosition == LabelPositions::Above) { + ImGui::NewLine(); + ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); + } else if (options.labelPosition == LabelPositions::Near) { + ImGui::SameLine(); + } else if (options.labelPosition == LabelPositions::Far) { + ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); + } + } else if (options.alignment == ComponentAlignments::Left) { + if (options.labelPosition == LabelPositions::Above) { + ImGui::Text("%s", label); + } + } + } + + ImGui::SetNextItemWidth(comboWidth); + if (ImGui::BeginCombo(invisibleLabel, comboVector.at(currentValueIndex).c_str(), options.flags)) { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); + for (size_t i = 0; i < comboVector.size(); ++i) { + auto newValue = static_cast(i); + if (comboVector.at(i).length() > 1) { + if (ImGui::Selectable(comboVector.at(i).c_str(), newValue == *value)) { + *value = newValue; + dirty = true; + } + } + } + ImGui::PopStyleVar(); + ImGui::EndCombo(); + } + + if (options.labelPosition != LabelPositions::None) { + if (options.alignment == ComponentAlignments::Left) { + if (options.labelPosition == LabelPositions::Near) { + ImGui::SameLine(); + ImGui::Text("%s", label); + } else if (options.labelPosition == LabelPositions::Far) { + float width = + ImGui::CalcTextSize(comboVector.at(*value).c_str()).x + ImGui::GetStyle().FramePadding.x * 2; + ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); + ImGui::Text("%s", label); + } + } + } + + PopStyleCombobox(); + ImGui::EndDisabled(); + ImGui::EndGroup(); + if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && + !Ship_IsCStringEmpty(options.disabledTooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); + } + ImGui::PopID(); + return dirty; +} + +template +bool Combobox(const char* label, T* value, const char* (&comboArray)[N], const ComboboxOptions& options = {}) { + bool dirty = false; + size_t currentValueIndex = static_cast(*value); + if (currentValueIndex >= N) { + currentValueIndex = 0; + } + std::string invisibleLabelStr = "##" + std::string(label); + const char* invisibleLabel = invisibleLabelStr.c_str(); + ImGui::PushID(label); + ImGui::BeginGroup(); + ImGui::BeginDisabled(options.disabled); + PushStyleCombobox(options.color); + + const char* longest; + size_t length = 0; + for (size_t i = 0; i < N; i++) { + size_t len = strlen(comboArray[i]); + if (len > length) { + longest = comboArray[i]; + length = len; + } + } + float comboWidth = CalcComboWidth(longest, options.flags); + + ImGui::AlignTextToFramePadding(); + if (options.labelPosition != LabelPositions::None) { + if (options.alignment == ComponentAlignments::Right) { + ImGui::Text("%s", label); + if (options.labelPosition == LabelPositions::Above) { + ImGui::NewLine(); + ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); + } else if (options.labelPosition == LabelPositions::Near) { + ImGui::SameLine(); + } else if (options.labelPosition == LabelPositions::Far) { + ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); + } + } else if (options.alignment == ComponentAlignments::Left) { + if (options.labelPosition == LabelPositions::Above) { + ImGui::Text("%s", label); + } + } + } + + ImGui::SetNextItemWidth(comboWidth); + if (ImGui::BeginCombo(invisibleLabel, comboArray[currentValueIndex], options.flags)) { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); + for (size_t i = 0; i < N; ++i) { + auto newValue = static_cast(i); + if (strlen(comboArray[i]) > 1) { + if (ImGui::Selectable(comboArray[i], newValue == *value)) { + *value = newValue; + dirty = true; + } + } + } + ImGui::PopStyleVar(); + ImGui::EndCombo(); + } + + if (options.labelPosition != LabelPositions::None) { + if (options.alignment == ComponentAlignments::Left) { + if (options.labelPosition == LabelPositions::Near) { + ImGui::SameLine(); + ImGui::Text("%s", label); + } else if (options.labelPosition == LabelPositions::Far) { + float width = ImGui::CalcTextSize(comboArray[*value]).x + ImGui::GetStyle().FramePadding.x * 2; + ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); + ImGui::Text("%s", label); + } + } + } + PopStyleCombobox(); + ImGui::EndDisabled(); + ImGui::EndGroup(); + if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && + !Ship_IsCStringEmpty(options.disabledTooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); + } + ImGui::PopID(); + return dirty; +} + +template +bool CVarCombobox(const char* label, const char* cvarName, const std::unordered_map& comboMap, + const ComboboxOptions& options = {}) { + bool dirty = false; + int32_t value = CVarGetInteger(cvarName, options.defaultIndex); + if (Combobox(label, &value, comboMap, options)) { + CVarSetInteger(cvarName, value); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ShipInit::Init(cvarName); + dirty = true; + } + return dirty; +} + +template +bool CVarCombobox(const char* label, const char* cvarName, const std::vector& comboVector, + const ComboboxOptions& options = {}) { + bool dirty = false; + int32_t value = CVarGetInteger(cvarName, options.defaultIndex); + if (Combobox(label, &value, comboVector, options)) { + CVarSetInteger(cvarName, value); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ShipInit::Init(cvarName); + dirty = true; + } + return dirty; +} + +template +bool CVarCombobox(const char* label, const char* cvarName, const char* (&comboArray)[N], + const ComboboxOptions& options = {}) { + bool dirty = false; + int32_t value = CVarGetInteger(cvarName, options.defaultIndex); + if (Combobox(label, &value, comboArray, options)) { + CVarSetInteger(cvarName, value); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ShipInit::Init(cvarName); + dirty = true; + } + return dirty; +} + +void PushStyleSlider(Colors color = Colors::LightBlue); +void PopStyleSlider(); +bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& options = {}); +bool CVarSliderInt(const char* label, const char* cvarName, const IntSliderOptions& options = {}); +bool SliderFloat(const char* label, float* value, const FloatSliderOptions& options = {}); +bool CVarSliderFloat(const char* label, const char* cvarName, const FloatSliderOptions& options = {}); +bool InputString(const char* label, std::string* value, const InputOptions& options = {}); +bool CVarInputString(const char* label, const char* cvarName, const InputOptions& options = {}); +bool InputInt(const char* label, int32_t* value, const InputOptions& options = {}); +bool CVarInputInt(const char* label, const char* cvarName, const InputOptions& options = {}); +bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaultColor, bool hasAlpha = false, + uint8_t modifiers = 0, UIWidgets::Colors themeColor = UIWidgets::Colors::LightBlue); +bool RadioButton(const char* label, bool active); +bool CVarRadioButton(const char* text, const char* cvarName, int32_t id, const RadioButtonsOptions& options); +bool StateButton(const char* str_id, const char* label, ImVec2 size, UIWidgets::ButtonOptions options, + ImGuiButtonFlags flags = ImGuiButtonFlags_None); +void DrawFlagArray32(const std::string& name, uint32_t& flags, Colors color = Colors::LightBlue); +void DrawFlagArray16(const std::string& name, uint16_t& flags, Colors color = Colors::LightBlue); +void DrawFlagArray8(const std::string& name, uint8_t& flags, Colors color = Colors::LightBlue); +void DrawFlagArray8Mask(const std::string& name, uint8_t& flags, Colors color = Colors::LightBlue); + +void InsertHelpHoverText(const std::string& text); +void InsertHelpHoverText(const char* text); +} // namespace UIWidgets ImVec4 GetRandomValue(); Color_RGBA8 RGBA8FromVec(ImVec4 vec);