diff --git a/soh/soh/Enhancements/randomizer/option.cpp b/soh/soh/Enhancements/randomizer/option.cpp index 950fa96cf..2c0146089 100644 --- a/soh/soh/Enhancements/randomizer/option.cpp +++ b/soh/soh/Enhancements/randomizer/option.cpp @@ -140,6 +140,9 @@ bool Option::RenderImGui() const { case WidgetType::Checkbox: changed = RenderCheckbox(); break; + case WidgetType::TristateCheckbox: + changed = RenderTristateCheckbox(); + break; case WidgetType::Combobox: changed = RenderCombobox(); break; @@ -209,6 +212,26 @@ bool Option::RenderCheckbox() const { return changed; } +bool Option::RenderTristateCheckbox() const { + bool changed = false; + if (disabled) { + UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); + } + int val = CVarGetInteger(cvarName.c_str(), defaultOption); + if (CustomCheckboxTristate(name.c_str(), &val, disabled, disabledGraphic)) { + CVarSetInteger(cvarName.c_str(), val); + changed = true; + LUS::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesOnNextTick(); + } + if (!description.empty()) { + UIWidgets::InsertHelpHoverText(description.c_str()); + } + if (disabled) { + UIWidgets::ReEnableComponent(disabledText.c_str()); + } + return changed; +} + bool Option::RenderCombobox() const { bool changed = false; if (disabled) { diff --git a/soh/soh/Enhancements/randomizer/option.h b/soh/soh/Enhancements/randomizer/option.h index 8ec4a32b1..57b3dae2c 100644 --- a/soh/soh/Enhancements/randomizer/option.h +++ b/soh/soh/Enhancements/randomizer/option.h @@ -34,6 +34,7 @@ enum class OptionCategory { */ enum class WidgetType { Checkbox, /** Default for Bools, not compatible if options.size() > 2. */ + TristateCheckbox, /** Compatible with U8s, not compatible if options.size() != 3. */ Combobox, /** Default for U8s, works with U8s and Bools. */ Slider, /** Compatible with U8s. If constructed with NumOpts, consider using this. Technically can be used for Bool or non-NumOpts options but it would be a bit weird semantically. */ }; @@ -317,6 +318,7 @@ protected: private: bool RenderCheckbox() const; + bool RenderTristateCheckbox() const; bool RenderCombobox() const; bool RenderSlider() const; std::variant var; diff --git a/soh/soh/Enhancements/randomizer/settings.cpp b/soh/soh/Enhancements/randomizer/settings.cpp index 70800ae4b..75a641c12 100644 --- a/soh/soh/Enhancements/randomizer/settings.cpp +++ b/soh/soh/Enhancements/randomizer/settings.cpp @@ -135,15 +135,15 @@ void Settings::CreateOptions() { mOptions[RSK_LACS_OPTIONS] = Option::U8("LACS Reward Options", {"Standard Reward", "Greg as Reward", "Greg as Wildcard"}, OptionCategory::Setting, "gRandomizeLacsRewardOptions", "", WidgetType::Combobox, RO_LACS_STANDARD_REWARD); mOptions[RSK_KEYRINGS] = Option::U8("Key Rings", {"Off", "Random", "Count", "Selection"}, OptionCategory::Setting, "gRandomizeShuffleKeyRings", mOptionDescriptions[RSK_KEYRINGS], WidgetType::Combobox, RO_KEYRINGS_OFF); mOptions[RSK_KEYRINGS_RANDOM_COUNT] = Option::U8("Keyring Dungeon Count", {NumOpts(0, 9)}, OptionCategory::Setting, "gRandomizeShuffleKeyRingsRandomCount", "", WidgetType::Slider, 8); - mOptions[RSK_KEYRINGS_GERUDO_FORTRESS] = Option::U8("Gerudo Fortress", {"No", "Random", "Yes"}, OptionCategory::Setting "gRandomizeShuffleKeyRingsGerudoFortress", "", IMFLAG_NONE); - mOptions[RSK_KEYRINGS_FOREST_TEMPLE] = Option::U8("Forest Temple", {"No", "Random", "Yes"}, OptionCategory::Setting "gRandomizeShuffleKeyRingsForestTemple", "", IMFLAG_NONE); - mOptions[RSK_KEYRINGS_FIRE_TEMPLE] = Option::U8("Fire Temple", {"No", "Random", "Yes"}, OptionCategory::Setting "gRandomizeShuffleKeyRingsFireTemple", "", IMFLAG_NONE); - mOptions[RSK_KEYRINGS_WATER_TEMPLE] = Option::U8("Water Temple", {"No", "Random", "Yes"}, OptionCategory::Setting "gRandomizeShuffleKeyRingsWaterTemple", "", IMFLAG_NONE); - mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE] = Option::U8("Spirit Temple", {"No", "Random", "Yes"}, OptionCategory::Setting "gRandomizeShuffleKeyRingsSpiritTemple", "", IMFLAG_NONE); - mOptions[RSK_KEYRINGS_SHADOW_TEMPLE] = Option::U8("Shadow Temple", {"No", "Random", "Yes"}, OptionCategory::Setting "gRandomizeShuffleKeyRingsShadowTemple", "", IMFLAG_NONE); - mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL] = Option::U8("Bottom of the Well", {"No", "Random", "Yes"}, OptionCategory::Setting "gRandomizeShuffleKeyRingsBottomOfTheWell", "", IMFLAG_NONE); - mOptions[RSK_KEYRINGS_GTG] = Option::U8("Gerudo Training Grounds", {"No", "Random", "Yes"}, OptionCategory::Setting "gRandomizeShuffleKeyRingsGTG", "", IMFLAG_NONE); - mOptions[RSK_KEYRINGS_GANONS_CASTLE] = Option::U8("Ganon's Castle", {"No", "Random", "Yes"}, OptionCategory::Setting "gRandomizeShuffleKeyRingsGanonsCastle"); + mOptions[RSK_KEYRINGS_GERUDO_FORTRESS] = Option::U8("Gerudo Fortress", {"No", "Random", "Yes"}, OptionCategory::Setting, "gRandomizeShuffleKeyRingsGerudoFortress", "", WidgetType::TristateCheckbox, 0); + mOptions[RSK_KEYRINGS_FOREST_TEMPLE] = Option::U8("Forest Temple", {"No", "Random", "Yes"}, OptionCategory::Setting, "gRandomizeShuffleKeyRingsForestTemple", "", WidgetType::TristateCheckbox, 0); + mOptions[RSK_KEYRINGS_FIRE_TEMPLE] = Option::U8("Fire Temple", {"No", "Random", "Yes"}, OptionCategory::Setting, "gRandomizeShuffleKeyRingsFireTemple", "", WidgetType::TristateCheckbox, 0); + mOptions[RSK_KEYRINGS_WATER_TEMPLE] = Option::U8("Water Temple", {"No", "Random", "Yes"}, OptionCategory::Setting, "gRandomizeShuffleKeyRingsWaterTemple", "", WidgetType::TristateCheckbox, 0); + mOptions[RSK_KEYRINGS_SPIRIT_TEMPLE] = Option::U8("Spirit Temple", {"No", "Random", "Yes"}, OptionCategory::Setting, "gRandomizeShuffleKeyRingsSpiritTemple", "", WidgetType::TristateCheckbox, 0); + mOptions[RSK_KEYRINGS_SHADOW_TEMPLE] = Option::U8("Shadow Temple", {"No", "Random", "Yes"}, OptionCategory::Setting, "gRandomizeShuffleKeyRingsShadowTemple", "", WidgetType::TristateCheckbox, 0); + mOptions[RSK_KEYRINGS_BOTTOM_OF_THE_WELL] = Option::U8("Bottom of the Well", {"No", "Random", "Yes"}, OptionCategory::Setting, "gRandomizeShuffleKeyRingsBottomOfTheWell", "", WidgetType::TristateCheckbox, 0); + mOptions[RSK_KEYRINGS_GTG] = Option::U8("Gerudo Training Grounds", {"No", "Random", "Yes"}, OptionCategory::Setting, "gRandomizeShuffleKeyRingsGTG", "", WidgetType::TristateCheckbox, 0); + mOptions[RSK_KEYRINGS_GANONS_CASTLE] = Option::U8("Ganon's Castle", {"No", "Random", "Yes"}, OptionCategory::Setting, "gRandomizeShuffleKeyRingsGanonsCastle", "", WidgetType::TristateCheckbox, 0); mOptions[RSK_SKIP_CHILD_STEALTH] = Option::Bool("Skip Child Stealth", {"Don't Skip", "Skip"}, OptionCategory::Setting, "gRandomizeSkipChildStealth", mOptionDescriptions[RSK_SKIP_CHILD_STEALTH], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); mOptions[RSK_SKIP_CHILD_ZELDA] = Option::Bool("Skip Child Zelda", {"Don't Skip", "Skip"}, OptionCategory::Setting, "gRandomizeSkipChildZelda", mOptionDescriptions[RSK_SKIP_CHILD_ZELDA], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); mOptions[RSK_SKIP_TOWER_ESCAPE] = Option::Bool("Skip Tower Escape", {"Don't Skip", "Skip"}, OptionCategory::Setting, "gRandomizeSkipTowerEscape", mOptionDescriptions[RSK_SKIP_TOWER_ESCAPE], WidgetType::Checkbox, RO_GENERIC_DONT_SKIP); diff --git a/soh/soh/UIWidgets.hpp b/soh/soh/UIWidgets.hpp index 7dbb0fc59..621911853 100644 --- a/soh/soh/UIWidgets.hpp +++ b/soh/soh/UIWidgets.hpp @@ -69,7 +69,7 @@ namespace UIWidgets { void RenderCross(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz); bool CustomCheckbox(const char* label, bool* v, bool disabled, CheckboxGraphics disabledGraphic, bool renderCrossWhenOff = false); - bool CustomCheckboxTristate(const char* label, bool* v, bool disabled, CheckboxGraphics disabledGraphic); + bool CustomCheckboxTristate(const char* label, int* v, bool disabled, CheckboxGraphics disabledGraphic); void ReEnableComponent(const char* disabledTooltipText); void DisableComponent(const float alpha);