diff --git a/soh/soh/Enhancements/Presets/Presets.cpp b/soh/soh/Enhancements/Presets/Presets.cpp index e611a028a..a6ffbcf96 100644 --- a/soh/soh/Enhancements/Presets/Presets.cpp +++ b/soh/soh/Enhancements/Presets/Presets.cpp @@ -86,11 +86,11 @@ void applyPreset(std::string presetName, std::vector includeSecti if (i == PRESET_SECTION_TRACKERS) { ItemTracker_LoadFromPreset(info.presetValues["blocks"][blockInfo[i].names[1]]["windows"]); if (info.presetValues["blocks"][blockInfo[i].names[1]]["windows"].contains("Check Tracker")) { - CheckTracker::CheckTracker_LoadFromPreset( + CheckTracker::LoadFromPreset( info.presetValues["blocks"][blockInfo[i].names[1]]["windows"]["Check Tracker"]); } if (info.presetValues["blocks"][blockInfo[i].names[1]]["windows"].contains("Entrance Tracker")) { - EntranceTracker_LoadFromPreset( + EntranceTracker::LoadFromPreset( info.presetValues["blocks"][blockInfo[i].names[1]]["windows"]["Entrance Tracker"]); } } diff --git a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp index 1cf9b44a8..c0e07b3c8 100644 --- a/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp +++ b/soh/soh/Enhancements/randomizer/3drando/spoiler_log.cpp @@ -89,8 +89,8 @@ static void WriteShuffledEntrance(std::string sphereString, Entrance* entrance) int16_t destinationIndex = -1; int16_t replacementIndex = entrance->GetReplacement()->GetIndex(); int16_t replacementDestinationIndex = -1; - std::string name = GetEntranceData(originalIndex)->source; - std::string text = GetEntranceData(replacementIndex)->destination; + std::string name = EntranceTracker::GetEntranceData(originalIndex)->source; + std::string text = EntranceTracker::GetEntranceData(replacementIndex)->destination; // Track the reverse destination, useful for savewarp handling if (entrance->GetReverse() != nullptr) { diff --git a/soh/soh/Enhancements/randomizer/Messages/EntranceHints.cpp b/soh/soh/Enhancements/randomizer/Messages/EntranceHints.cpp index cabfc1432..9367d7f1d 100644 --- a/soh/soh/Enhancements/randomizer/Messages/EntranceHints.cpp +++ b/soh/soh/Enhancements/randomizer/Messages/EntranceHints.cpp @@ -154,7 +154,7 @@ void BuildEntranceHintMessage(uint16_t* textId, bool* loadFromMessageTable) { if (entranceCtx->entranceOverrides[i].index == entrance) { s16 overrideIndex = entranceCtx->entranceOverrides[i].override; Entrance_SetEntranceDiscovered(entrance, false); - auto data = GetEntranceData(overrideIndex); + auto data = EntranceTracker::GetEntranceData(overrideIndex); CustomMessage msg = CustomMessage("[[name]]"); msg.Replace("[[name]]", data->destination); msg.SetTextBoxType(TEXTBOX_TYPE_WOODEN); diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp index a1a8e2926..13ac143ff 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.cpp @@ -41,10 +41,6 @@ extern std::vector dungeonRewardMedallions; extern std::vector songItems; extern std::vector equipmentItems; -namespace SohGui { -extern std::shared_ptr mSohMenu; -} - using json = nlohmann::json; using namespace UIWidgets; @@ -177,11 +173,9 @@ std::unordered_map checkNameOverrides; bool ShouldShowCheck(RandomizerCheck rc); bool UpdateFilters(); -void BeginFloatWindows(std::string UniqueName, bool& open, ImGuiWindowFlags flags = 0); bool CompareChecks(RandomizerCheck, RandomizerCheck); bool CheckByArea(RandomizerCheckArea); void DrawLocation(RandomizerCheck); -void EndFloatWindows(); void LoadSettings(); void RainbowTick(); void UpdateAreas(RandomizerCheckArea area); @@ -232,18 +226,17 @@ SceneID DungeonSceneLookupByArea(RandomizerCheckArea area) { } } -Color_RGBA8 Color_Bg_Default = { 0, 0, 0, 255 }; // Black -Color_RGBA8 Color_Main_Default = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Area_Incomplete_Extra_Default = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Area_Complete_Extra_Default = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Unchecked_Extra_Default = { 255, 255, 255, 255 }; // White -Color_RGBA8 Color_Skipped_Main_Default = { 160, 160, 160, 255 }; // Grey -Color_RGBA8 Color_Skipped_Extra_Default = { 160, 160, 160, 255 }; // Grey -Color_RGBA8 Color_Seen_Extra_Default = { 255, 255, 255, 255 }; // TODO -Color_RGBA8 Color_Hinted_Extra_Default = { 255, 255, 255, 255 }; // TODO -Color_RGBA8 Color_Collected_Extra_Default = { 242, 101, 34, 255 }; // Orange -Color_RGBA8 Color_Scummed_Extra_Default = { 0, 174, 239, 255 }; // Blue -Color_RGBA8 Color_Saved_Extra_Default = { 0, 185, 0, 255 }; // Green +const Color_RGBA8 Color_Main_Default = { 255, 255, 255, 255 }; // White +const Color_RGBA8 Color_Area_Incomplete_Extra_Default = { 255, 255, 255, 255 }; // White +const Color_RGBA8 Color_Area_Complete_Extra_Default = { 255, 255, 255, 255 }; // White +const Color_RGBA8 Color_Unchecked_Extra_Default = { 255, 255, 255, 255 }; // White +const Color_RGBA8 Color_Skipped_Main_Default = { 160, 160, 160, 255 }; // Grey +const Color_RGBA8 Color_Skipped_Extra_Default = { 160, 160, 160, 255 }; // Grey +const Color_RGBA8 Color_Seen_Extra_Default = { 255, 255, 255, 255 }; // TODO +const Color_RGBA8 Color_Hinted_Extra_Default = { 255, 255, 255, 255 }; // TODO +const Color_RGBA8 Color_Collected_Extra_Default = { 242, 101, 34, 255 }; // Orange +const Color_RGBA8 Color_Scummed_Extra_Default = { 0, 174, 239, 255 }; // Blue +const Color_RGBA8 Color_Saved_Extra_Default = { 0, 185, 0, 255 }; // Green Color_RGBA8 Color_Background = { 0, 0, 0, 255 }; @@ -266,8 +259,6 @@ Color_RGBA8 Color_Scummed_Extra = { 0, 174, 239, 255 }; // Blue Color_RGBA8 Color_Saved_Main = { 255, 255, 255, 255 }; // White Color_RGBA8 Color_Saved_Extra = { 0, 185, 0, 255 }; // Green -std::vector buttons = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L, - BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; static ImGuiTextFilter checkSearch; static bool recalculateAvailable = false; static RandomizerRegion availableChecksStartingRegion = RR_ROOT; @@ -455,8 +446,8 @@ RandomizerCheckArea AreaFromEntranceGroup[] = { RandomizerCheckArea GetCheckArea() { auto scene = static_cast(gPlayState->sceneNum); bool grottoScene = (scene == SCENE_GROTTOS || scene == SCENE_FAIRYS_FOUNTAIN); - const EntranceData* ent = - GetEntranceData(grottoScene ? ENTRANCE_GROTTO_EXIT_START + GetCurrentGrottoId() : gSaveContext.entranceIndex); + const EntranceData* ent = EntranceTracker::GetEntranceData( + grottoScene ? ENTRANCE_GROTTO_EXIT_START + EntranceTracker::GetCurrentGrottoId() : gSaveContext.entranceIndex); RandomizerCheckArea area = RCAREA_INVALID; if (ent != nullptr && !IsAreaScene(scene) && ent->type != ENTRANCE_TYPE_DUNGEON) { if (ent->source == "Desert Colossus" || ent->destination == "Desert Colossus") { @@ -466,7 +457,7 @@ RandomizerCheckArea GetCheckArea() { } } if (area == RCAREA_INVALID) { - if (grottoScene && (GetCurrentGrottoId() == -1) && + if (grottoScene && (EntranceTracker::GetCurrentGrottoId() == -1) && (OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_SHUFFLE_GROTTO_ENTRANCES) == RO_GENERIC_OFF)) { area = previousArea; } else { @@ -1021,242 +1012,243 @@ void CheckTrackerWindow::DrawElement() { } else { ImGui::SetNextWindowSize(ImVec2(400, 540), ImGuiCond_FirstUseEver); } - BeginFloatWindows("Check Tracker", mIsVisible, ImGuiWindowFlags_NoScrollbar); + if (Trackers::BeginFloatWindows( + "Check Tracker", mIsVisible, Color_Background, + static_cast(CVarGetInteger(CVAR_TRACKER_CHECK("WindowType"), TRACKER_WINDOW_WINDOW)), + CVarGetInteger(CVAR_TRACKER_CHECK("Draggable"), 1), ImGuiWindowFlags_NoScrollbar)) { + if (!GameInteractor::IsSaveLoaded() || !initialized) { + ImGui::Text("Waiting for file load..."); // TODO Language + Trackers::EndFloatWindows(); + return; + } - if (!GameInteractor::IsSaveLoaded() || !initialized) { - ImGui::Text("Waiting for file load..."); // TODO Language - EndFloatWindows(); - return; - } + if (recalculateAvailable) { + recalculateAvailable = false; + InternalRecalculateAvailableChecks(availableChecksStartingRegion); + availableChecksStartingRegion = RR_ROOT; + } - if (gPlayState->nextEntranceIndex != previousEntrance) { - previousEntrance = gPlayState->nextEntranceIndex; - recalculateAvailable = true; - } - - if (recalculateAvailable) { - recalculateAvailable = false; - InternalRecalculateAvailableChecks(availableChecksStartingRegion); - availableChecksStartingRegion = RR_ROOT; - } - - // Quick Options + // Quick Options #ifdef __WIIU__ - float headerHeight = 40.0f; + float headerHeight = 40.0f; #else - float headerHeight = 20.0f; + float headerHeight = 20.0f; #endif - if (!ImGui::BeginTable("Check Tracker", 1, 0)) { - EndFloatWindows(); - return; - } + if (!ImGui::BeginTable("Check Tracker", 1, 0)) { + Trackers::EndFloatWindows(); + return; + } - ImGui::SetWindowFontScale(CVarGetFloat(CVAR_TRACKER_CHECK("FontSize"), 1.0f)); + ImGui::SetWindowFontScale(CVarGetFloat(CVAR_TRACKER_CHECK("FontSize"), 1.0f)); - ImGui::TableNextRow(0, 0); - ImGui::TableNextColumn(); - if (CVarGetInteger(CVAR_TRACKER_CHECK("HiddenItemsToggleVisible"), 1) && - UIWidgets::CVarCheckbox( - "Show Hidden Items", CVAR_TRACKER_CHECK("ShowHidden"), - UIWidgets::CheckboxOptions( - { { .tooltip = "When active, items will show hidden checks by default when updated to this state." } }) - .Color(THEME_COLOR))) { - doAreaScroll = true; - showHidden = CVarGetInteger(CVAR_TRACKER_CHECK("ShowHidden"), 0); - RecalculateAllAreaTotals(); - } - if (enableAvailableChecks && CVarGetInteger(CVAR_TRACKER_CHECK("AvailableChecksToggleVisible"), 1)) { - if (UIWidgets::CVarCheckbox( - "Only Show Available Checks", CVAR_TRACKER_CHECK("OnlyShowAvailable"), - UIWidgets::CheckboxOptions({ { .tooltip = "When active, unavailable checks will be hidden." } }) + ImGui::TableNextRow(0, 0); + ImGui::TableNextColumn(); + if (CVarGetInteger(CVAR_TRACKER_CHECK("HiddenItemsToggleVisible"), 1) && + UIWidgets::CVarCheckbox( + "Show Hidden Items", CVAR_TRACKER_CHECK("ShowHidden"), + UIWidgets::CheckboxOptions( + { { .tooltip = + "When active, items will show hidden checks by default when updated to this state." } }) .Color(THEME_COLOR))) { doAreaScroll = true; + showHidden = CVarGetInteger(CVAR_TRACKER_CHECK("ShowHidden"), 0); RecalculateAllAreaTotals(); } - } - if (CVarGetInteger(CVAR_TRACKER_CHECK("ExpandCollapseButtonsVisible"), 0)) { - if (UIWidgets::Button( - "Expand All", - UIWidgets::ButtonOptions().Color(THEME_COLOR).Size({ ImGui::GetContentRegionAvail().x / 2 - 6, 0 }))) { - optCollapseAll = false; - optExpandAll = true; - doAreaScroll = true; - } - ImGui::SameLine(); - if (UIWidgets::Button( - "Collapse All", - UIWidgets::ButtonOptions().Color(THEME_COLOR).Size({ ImGui::GetContentRegionAvail().x - 6, 0 }))) { - optExpandAll = false; - optCollapseAll = true; - } - } - UIWidgets::PushStyleCombobox(THEME_COLOR); - if (CVarGetInteger(CVAR_TRACKER_CHECK("SearchInputVisible"), 1)) { - if (checkSearch.Draw("", ImGui::GetContentRegionAvail().x - 6)) { - UpdateFilters(); - } - std::string checkSearchText = ""; - checkSearchText = checkSearch.InputBuf; - checkSearchText.erase(std::remove(checkSearchText.begin(), checkSearchText.end(), ' '), checkSearchText.end()); - if (checkSearchText.length() < 1) { - ImGui::SameLine(20.0f); - ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.4f), "Search..."); - } - } - UIWidgets::PopStyleCombobox(); - - if (CVarGetInteger(CVAR_TRACKER_CHECK("CheckTotalsVisible"), 1)) { - std::ostringstream totalChecksSS; - totalChecksSS << ""; - if (enableAvailableChecks) { - totalChecksSS << totalChecksAvailable << " Available / "; - } - totalChecksSS << totalChecksGotten << " Checked / " << totalChecks << " Total"; - ImGui::Text("%s", totalChecksSS.str().c_str()); - } - - bool headerPresent = - CVarGetInteger(CVAR_TRACKER_CHECK("HiddenItemsToggleVisible"), 1) || - (enableAvailableChecks && CVarGetInteger(CVAR_TRACKER_CHECK("AvailableChecksToggleVisible"), 1)) || - CVarGetInteger(CVAR_TRACKER_CHECK("ExpandCollapseButtonsVisible"), 0) || - CVarGetInteger(CVAR_TRACKER_CHECK("SearchInputVisible"), 1) || - CVarGetInteger(CVAR_TRACKER_CHECK("CheckTotalsVisible"), 1); - if (headerPresent) { - ImGui::Separator(); - } - - // Checks Section Lead-in - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - if (!ImGui::BeginTable("CheckTracker##Checks", 1, ImGuiTableFlags_ScrollY)) { - ImGui::EndTable(); - EndFloatWindows(); - return; - } - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - - // Prep for loop - RainbowTick(); - bool doDraw = false; - bool thisAreaFullyChecked = false; - bool mqSpoilers = CVarGetInteger(CVAR_TRACKER_CHECK("MQSpoilers"), 0); - bool hideIncomplete = CVarGetInteger(CVAR_TRACKER_CHECK("AreaIncomplete.Hide"), 0); - bool hideComplete = CVarGetInteger(CVAR_TRACKER_CHECK("AreaComplete.Hide"), 0); - bool collapseLogic; - bool doingCollapseOrExpand = optExpandAll || optCollapseAll; - bool isThisAreaSpoiled; - RandomizerCheckArea lastArea = RCAREA_INVALID; - Color_RGBA8 mainColor; - Color_RGBA8 extraColor; - std::string stemp; - - bool shouldHideFilteredAreas = CVarGetInteger(CVAR_TRACKER_CHECK("HideFilteredAreas"), 1); - - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0f, 3.0f)); - for (auto& [rcArea, checks] : checksByArea) { - RandomizerCheckArea thisArea = currentArea; - - thisAreaFullyChecked = (areaChecksGotten[rcArea] == areaCheckTotals[rcArea]); - // Last Area needs to be cleaned up - if (lastArea != RCAREA_INVALID && doDraw) { - UIWidgets::PaddedSeparator(); - } - lastArea = rcArea; - if (previousShowHidden != showHidden) { - previousShowHidden = showHidden; - doAreaScroll = true; - } - if ((shouldHideFilteredAreas && filterAreasHidden[rcArea]) || - (!showHidden && ((hideComplete && thisAreaFullyChecked) || (hideIncomplete && !thisAreaFullyChecked))) || - (enableAvailableChecks && onlyShowAvailable && areaChecksAvailable[rcArea] == 0)) { - doDraw = false; - } else { - // Get the colour for the area - if (thisAreaFullyChecked) { - mainColor = Color_Area_Complete_Main; - extraColor = Color_Area_Complete_Extra; - } else { - mainColor = Color_Area_Incomplete_Main; - extraColor = Color_Area_Incomplete_Extra; + if (enableAvailableChecks && CVarGetInteger(CVAR_TRACKER_CHECK("AvailableChecksToggleVisible"), 1)) { + if (UIWidgets::CVarCheckbox( + "Only Show Available Checks", CVAR_TRACKER_CHECK("OnlyShowAvailable"), + UIWidgets::CheckboxOptions({ { .tooltip = "When active, unavailable checks will be hidden." } }) + .Color(THEME_COLOR))) { + doAreaScroll = true; + RecalculateAllAreaTotals(); } - - // Draw the area - collapseLogic = !thisAreaFullyChecked; - if (doingCollapseOrExpand) { - if (optExpandAll) { - collapseLogic = true; - } else if (optCollapseAll) { - collapseLogic = false; - } + } + if (CVarGetInteger(CVAR_TRACKER_CHECK("ExpandCollapseButtonsVisible"), 0)) { + if (UIWidgets::Button("Expand All", UIWidgets::ButtonOptions() + .Color(THEME_COLOR) + .Size({ ImGui::GetContentRegionAvail().x / 2 - 6, 0 }))) { + optCollapseAll = false; + optExpandAll = true; + doAreaScroll = true; } - stemp = RandomizerCheckObjects::GetRCAreaName(rcArea) + "##TreeNode"; - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(mainColor.r / 255.0f, mainColor.g / 255.0f, - mainColor.b / 255.0f, mainColor.a / 255.0f)); - if (doingCollapseOrExpand) { - ImGui::SetNextItemOpen(collapseLogic, ImGuiCond_Always); - } else { - ImGui::SetNextItemOpen(!thisAreaFullyChecked, ImGuiCond_Once); - } - doDraw = ImGui::TreeNodeEx(stemp.c_str(), ImGuiTreeNodeFlags_NoTreePushOnOpen); - ImGui::PopStyleColor(); ImGui::SameLine(); - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(extraColor.r / 255.0f, extraColor.g / 255.0f, - extraColor.b / 255.0f, extraColor.a / 255.0f)); + if (UIWidgets::Button( + "Collapse All", + UIWidgets::ButtonOptions().Color(THEME_COLOR).Size({ ImGui::GetContentRegionAvail().x - 6, 0 }))) { + optExpandAll = false; + optCollapseAll = true; + } + } + UIWidgets::PushStyleCombobox(THEME_COLOR); + if (CVarGetInteger(CVAR_TRACKER_CHECK("SearchInputVisible"), 1)) { + if (checkSearch.Draw("", ImGui::GetContentRegionAvail().x - 6)) { + UpdateFilters(); + } + std::string checkSearchText = ""; + checkSearchText = checkSearch.InputBuf; + checkSearchText.erase(std::remove(checkSearchText.begin(), checkSearchText.end(), ' '), + checkSearchText.end()); + if (checkSearchText.length() < 1) { + ImGui::SameLine(20.0f); + ImGui::TextColored(ImVec4(1.0f, 1.0f, 1.0f, 0.4f), "Search..."); + } + } + UIWidgets::PopStyleCombobox(); - isThisAreaSpoiled = IsAreaSpoiled(rcArea) || mqSpoilers; + if (CVarGetInteger(CVAR_TRACKER_CHECK("CheckTotalsVisible"), 1)) { + std::ostringstream totalChecksSS; + totalChecksSS << ""; + if (enableAvailableChecks) { + totalChecksSS << totalChecksAvailable << " Available / "; + } + totalChecksSS << totalChecksGotten << " Checked / " << totalChecks << " Total"; + ImGui::Text("%s", totalChecksSS.str().c_str()); + } - if (isThisAreaSpoiled) { - std::ostringstream areaTotalsSS; - std::ostringstream areaTotalsTooltipSS; + bool headerPresent = + CVarGetInteger(CVAR_TRACKER_CHECK("HiddenItemsToggleVisible"), 1) || + (enableAvailableChecks && CVarGetInteger(CVAR_TRACKER_CHECK("AvailableChecksToggleVisible"), 1)) || + CVarGetInteger(CVAR_TRACKER_CHECK("ExpandCollapseButtonsVisible"), 0) || + CVarGetInteger(CVAR_TRACKER_CHECK("SearchInputVisible"), 1) || + CVarGetInteger(CVAR_TRACKER_CHECK("CheckTotalsVisible"), 1); + if (headerPresent) { + ImGui::Separator(); + } - areaTotalsSS << "("; - if (enableAvailableChecks) { - areaTotalsSS << static_cast(areaChecksAvailable[rcArea]) << " / "; - areaTotalsTooltipSS << "Available / "; + // Checks Section Lead-in + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (!ImGui::BeginTable("CheckTracker##Checks", 1, ImGuiTableFlags_ScrollY)) { + ImGui::EndTable(); + Trackers::EndFloatWindows(); + return; + } + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + // Prep for loop + RainbowTick(); + bool doDraw = false; + bool thisAreaFullyChecked = false; + bool mqSpoilers = CVarGetInteger(CVAR_TRACKER_CHECK("MQSpoilers"), 0); + bool hideIncomplete = CVarGetInteger(CVAR_TRACKER_CHECK("AreaIncomplete.Hide"), 0); + bool hideComplete = CVarGetInteger(CVAR_TRACKER_CHECK("AreaComplete.Hide"), 0); + bool collapseLogic; + bool doingCollapseOrExpand = optExpandAll || optCollapseAll; + bool isThisAreaSpoiled; + RandomizerCheckArea lastArea = RCAREA_INVALID; + Color_RGBA8 mainColor; + Color_RGBA8 extraColor; + std::string stemp; + + bool shouldHideFilteredAreas = CVarGetInteger(CVAR_TRACKER_CHECK("HideFilteredAreas"), 1); + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4.0f, 3.0f)); + for (auto& [rcArea, checks] : checksByArea) { + RandomizerCheckArea thisArea = currentArea; + + thisAreaFullyChecked = (areaChecksGotten[rcArea] == areaCheckTotals[rcArea]); + // Last Area needs to be cleaned up + if (lastArea != RCAREA_INVALID && doDraw) { + UIWidgets::PaddedSeparator(); + } + lastArea = rcArea; + if (previousShowHidden != showHidden) { + previousShowHidden = showHidden; + doAreaScroll = true; + } + if ((shouldHideFilteredAreas && filterAreasHidden[rcArea]) || + (!showHidden && + ((hideComplete && thisAreaFullyChecked) || (hideIncomplete && !thisAreaFullyChecked))) || + (enableAvailableChecks && onlyShowAvailable && areaChecksAvailable[rcArea] == 0)) { + doDraw = false; + } else { + // Get the colour for the area + if (thisAreaFullyChecked) { + mainColor = Color_Area_Complete_Main; + extraColor = Color_Area_Complete_Extra; + } else { + mainColor = Color_Area_Incomplete_Main; + extraColor = Color_Area_Incomplete_Extra; } - areaTotalsSS << static_cast(areaChecksGotten[rcArea]) << " / " - << static_cast(areaCheckTotals[rcArea]) << ")"; - areaTotalsTooltipSS << "Checked / Total"; - if (showVOrMQ && RandomizerCheckObjects::AreaIsDungeon(rcArea)) { - if (OTRGlobals::Instance->gRandoContext->GetDungeons() - ->GetDungeonFromScene(DungeonSceneLookupByArea(rcArea)) - ->IsMQ()) { - areaTotalsSS << " - MQ"; - } else { - areaTotalsSS << " - Vanilla"; + // Draw the area + collapseLogic = !thisAreaFullyChecked; + if (doingCollapseOrExpand) { + if (optExpandAll) { + collapseLogic = true; + } else if (optCollapseAll) { + collapseLogic = false; } } + stemp = RandomizerCheckObjects::GetRCAreaName(rcArea) + "##TreeNode"; + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(mainColor.r / 255.0f, mainColor.g / 255.0f, + mainColor.b / 255.0f, mainColor.a / 255.0f)); + if (doingCollapseOrExpand) { + ImGui::SetNextItemOpen(collapseLogic, ImGuiCond_Always); + } else { + ImGui::SetNextItemOpen(!thisAreaFullyChecked, ImGuiCond_Once); + } + doDraw = ImGui::TreeNodeEx(stemp.c_str(), ImGuiTreeNodeFlags_NoTreePushOnOpen); + ImGui::PopStyleColor(); + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(extraColor.r / 255.0f, extraColor.g / 255.0f, + extraColor.b / 255.0f, extraColor.a / 255.0f)); - ImGui::Text("%s", areaTotalsSS.str().c_str()); - UIWidgets::Tooltip(areaTotalsTooltipSS.str().c_str()); - } else { - ImGui::Text("???"); - } + isThisAreaSpoiled = IsAreaSpoiled(rcArea) || mqSpoilers; - ImGui::PopStyleColor(); + if (isThisAreaSpoiled) { + std::ostringstream areaTotalsSS; + std::ostringstream areaTotalsTooltipSS; - // Keep areas loaded between transitions - if (thisArea == rcArea && doAreaScroll) { - ImGui::SetScrollHereY(0.0f); - doAreaScroll = false; - } - for (auto rc : checks) { - if (doDraw && isThisAreaSpoiled && !filterChecksHidden[rc]) { - DrawLocation(rc); + areaTotalsSS << "("; + if (enableAvailableChecks) { + areaTotalsSS << static_cast(areaChecksAvailable[rcArea]) << " / "; + areaTotalsTooltipSS << "Available / "; + } + areaTotalsSS << static_cast(areaChecksGotten[rcArea]) << " / " + << static_cast(areaCheckTotals[rcArea]) << ")"; + areaTotalsTooltipSS << "Checked / Total"; + + if (showVOrMQ && RandomizerCheckObjects::AreaIsDungeon(rcArea)) { + if (OTRGlobals::Instance->gRandoContext->GetDungeons() + ->GetDungeonFromScene(DungeonSceneLookupByArea(rcArea)) + ->IsMQ()) { + areaTotalsSS << " - MQ"; + } else { + areaTotalsSS << " - Vanilla"; + } + } + + ImGui::Text("%s", areaTotalsSS.str().c_str()); + UIWidgets::Tooltip(areaTotalsTooltipSS.str().c_str()); + } else { + ImGui::Text("???"); + } + + ImGui::PopStyleColor(); + + // Keep areas loaded between transitions + if (thisArea == rcArea && doAreaScroll) { + ImGui::SetScrollHereY(0.0f); + doAreaScroll = false; + } + for (auto rc : checks) { + if (doDraw && isThisAreaSpoiled && !filterChecksHidden[rc]) { + DrawLocation(rc); + } } } } - } - ImGui::PopStyleVar(); + ImGui::PopStyleVar(); - ImGui::EndTable(); // Checks Lead-out - ImGui::EndTable(); // Quick Options Lead-out - EndFloatWindows(); - if (doingCollapseOrExpand) { - optCollapseAll = false; - optExpandAll = false; + ImGui::EndTable(); // Checks Lead-out + ImGui::EndTable(); // Quick Options Lead-out + Trackers::EndFloatWindows(); + if (doingCollapseOrExpand) { + optCollapseAll = false; + optExpandAll = false; + } } } @@ -1297,41 +1289,6 @@ bool ShouldShowCheck(RandomizerCheck check) { (checkSearch.Filters.Size == 0 || checkSearch.PassFilter(search.c_str()))); } -// Windowing stuff -void BeginFloatWindows(std::string UniqueName, bool& open, ImGuiWindowFlags flags) { - ImGuiWindowFlags windowFlags = flags; - - if (windowFlags == 0) { - windowFlags |= ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_NoFocusOnAppearing; - } - - if (CVarGetInteger(CVAR_TRACKER_CHECK("WindowType"), TRACKER_WINDOW_WINDOW) == TRACKER_WINDOW_FLOATING) { - ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID); - windowFlags |= ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoTitleBar | - ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar; - - if (!CVarGetInteger(CVAR_TRACKER_CHECK("Draggable"), 1)) { - windowFlags |= ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove; - } - } - auto maybeParent = ImGui::GetCurrentWindow(); - ImGuiWindow* window = ImGui::FindWindowByName(UniqueName.c_str()); - if (window != NULL && window->DockTabIsVisible && window->ParentWindow != NULL && - std::string(window->ParentWindow->Name).compare(0, strlen("Main - Deck"), "Main - Deck") == 0) { - Color_Background.a = 255; - } - ImGui::PushStyleColor(ImGuiCol_WindowBg, VecFromRGBA8(Color_Background)); - ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f); - ImGui::Begin(UniqueName.c_str(), &open, windowFlags); -} -void EndFloatWindows() { - ImGui::PopStyleVar(); - ImGui::PopStyleColor(); - ImGui::PopStyleColor(); - ImGui::End(); -} - void LoadSettings() { // If in randomzer, then get the setting and check if in general we should be showing the settings // If in vanilla, _try_ to show items that at least are needed for 100% @@ -2014,9 +1971,9 @@ void RainbowTick() { } void ImGuiDrawTwoColorPickerSection(const char* text, const char* cvarMainName, const char* cvarExtraName, - Color_RGBA8& main_color, Color_RGBA8& extra_color, Color_RGBA8& main_default_color, - Color_RGBA8& extra_default_color, const char* cvarHideName, const char* tooltip, - UIWidgets::Colors theme) { + Color_RGBA8& main_color, Color_RGBA8& extra_color, + const Color_RGBA8& main_default_color, const Color_RGBA8& extra_default_color, + const char* cvarHideName, const char* tooltip, UIWidgets::Colors theme) { Color_RGBA8 cvarMainColor = CVarGetColor(cvarMainName, main_default_color); Color_RGBA8 cvarExtraColor = CVarGetColor(cvarExtraName, extra_default_color); main_color = cvarMainColor; @@ -2124,7 +2081,7 @@ void RecalculateAvailableChecks(RandomizerRegion startingRegion /* = RR_ROOT */) availableChecksStartingRegion = startingRegion; } -void CheckTracker_LoadFromPreset(nlohmann::json info) { +void LoadFromPreset(nlohmann::json info) { presetLoaded = true; presetPos = { info["pos"]["x"], info["pos"]["y"] }; presetSize = { info["size"]["width"], info["size"]["height"] }; @@ -2139,19 +2096,6 @@ void CheckTrackerWindow::Draw() { SyncVisibilityConsoleVariable(); } -static std::map windowType = { { TRACKER_WINDOW_FLOATING, "Floating" }, - { TRACKER_WINDOW_WINDOW, "Window" } }; -static std::map displayType = { { 0, "Always" }, { 1, "Combo Button Hold" } }; -static std::map buttonStrings = { - { TRACKER_COMBO_BUTTON_A, "A Button" }, { TRACKER_COMBO_BUTTON_B, "B Button" }, - { TRACKER_COMBO_BUTTON_C_UP, "C-Up" }, { TRACKER_COMBO_BUTTON_C_DOWN, "C-Down" }, - { TRACKER_COMBO_BUTTON_C_LEFT, "C-Left" }, { TRACKER_COMBO_BUTTON_C_RIGHT, "C-Right" }, - { TRACKER_COMBO_BUTTON_L, "L Button" }, { TRACKER_COMBO_BUTTON_Z, "Z Button" }, - { TRACKER_COMBO_BUTTON_R, "R Button" }, { TRACKER_COMBO_BUTTON_START, "Start" }, - { TRACKER_COMBO_BUTTON_D_UP, "D-Up" }, { TRACKER_COMBO_BUTTON_D_DOWN, "D-Down" }, - { TRACKER_COMBO_BUTTON_D_LEFT, "D-Left" }, { TRACKER_COMBO_BUTTON_D_RIGHT, "D-Right" } -}; - void CheckTrackerSettingsWindow::DrawElement() { ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, { 8.0f, 8.0f }); if (ImGui::BeginTable("CheckTrackerSettingsTable", 2, ImGuiTableFlags_BordersH | ImGuiTableFlags_BordersV)) { @@ -2160,9 +2104,9 @@ void CheckTrackerSettingsWindow::DrawElement() { ImGui::TableHeadersRow(); ImGui::TableNextRow(); ImGui::TableNextColumn(); - SohGui::mSohMenu->MenuDrawItem(backgroundColorWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::GetSohMenu()->MenuDrawItem(backgroundColorWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); - SohGui::mSohMenu->MenuDrawItem(windowTypeWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::GetSohMenu()->MenuDrawItem(windowTypeWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); UIWidgets::CVarSliderFloat("Font Size", CVAR_TRACKER_CHECK("FontSize"), UIWidgets::FloatSliderOptions() @@ -2179,7 +2123,7 @@ void CheckTrackerSettingsWindow::DrawElement() { UIWidgets::CheckboxOptions().Color(THEME_COLOR)); UIWidgets::CVarCheckbox("Only Enable While Paused", CVAR_TRACKER_CHECK("ShowOnlyPaused"), UIWidgets::CheckboxOptions().Color(THEME_COLOR)); - UIWidgets::CVarCombobox("Display Mode", CVAR_TRACKER_CHECK("DisplayType"), displayType, + UIWidgets::CVarCombobox("Display Mode", CVAR_TRACKER_CHECK("DisplayType"), showMode, UIWidgets::ComboboxOptions() .LabelPosition(UIWidgets::LabelPositions::Far) .ComponentAlignment(UIWidgets::ComponentAlignments::Right) @@ -2202,17 +2146,17 @@ void CheckTrackerSettingsWindow::DrawElement() { } } ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); - SohGui::mSohMenu->MenuDrawItem(dungeonSpoilerWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::GetSohMenu()->MenuDrawItem(dungeonSpoilerWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); ImGui::EndDisabled(); - SohGui::mSohMenu->MenuDrawItem(hideUnshuffledShopWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::GetSohMenu()->MenuDrawItem(hideUnshuffledShopWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); - SohGui::mSohMenu->MenuDrawItem(showGSWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::GetSohMenu()->MenuDrawItem(showGSWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); - SohGui::mSohMenu->MenuDrawItem(showLogicWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::GetSohMenu()->MenuDrawItem(showLogicWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); - SohGui::mSohMenu->MenuDrawItem(checkAvailabilityWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + SohGui::GetSohMenu()->MenuDrawItem(checkAvailabilityWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); ImGui::EndDisabled(); // Filtering settings @@ -2302,14 +2246,13 @@ void CheckTrackerWindow::UpdateElement() { } void RegisterCheckTrackerWidgets() { - backgroundColorWidget = { .name = "Background Color##CheckTrackerBgColor", - .type = WidgetType::WIDGET_CVAR_COLOR_PICKER }; + backgroundColorWidget = { .name = "Background Color##CheckTracker", .type = WidgetType::WIDGET_CVAR_COLOR_PICKER }; backgroundColorWidget.CVar(CVAR_TRACKER_CHECK("BgColor")) .Options( ColorPickerOptions().Color(THEME_COLOR).DefaultValue(Color_Bg_Default).UseAlpha().ShowReset().ShowRandom()); - SohGui::mSohMenu->AddSearchWidget({ backgroundColorWidget, "Randomizer", "Check Tracker", "General Settings" }); + SohGui::GetSohMenu()->AddSearchWidget({ backgroundColorWidget, "Randomizer", "Check Tracker", "General Settings" }); - windowTypeWidget = { .name = "Window Type", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + windowTypeWidget = { .name = "Window Type##CheckTracker", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; windowTypeWidget.CVar(CVAR_TRACKER_CHECK("WindowType")) .Options(ComboboxOptions() .DefaultIndex(TRACKER_WINDOW_WINDOW) @@ -2317,7 +2260,7 @@ void RegisterCheckTrackerWidgets() { .LabelPosition(LabelPositions::Far) .Color(THEME_COLOR) .ComboMap(windowType)); - SohGui::mSohMenu->AddSearchWidget({ windowTypeWidget, "Randomizer", "Check Tracker", "General Settings" }); + SohGui::GetSohMenu()->AddSearchWidget({ windowTypeWidget, "Randomizer", "Check Tracker", "General Settings" }); dungeonSpoilerWidget = { .name = "Vanilla/MQ Dungeon Spoilers", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; dungeonSpoilerWidget.CVar(CVAR_TRACKER_CHECK("MQSpoilers")) @@ -2325,7 +2268,7 @@ void RegisterCheckTrackerWidgets() { .Color(THEME_COLOR) .Tooltip("If enabled, Vanilla/MQ dungeons will show on the tracker immediately. " "Otherwise, Vanilla/MQ dungeon locations must be unlocked.")); - SohGui::mSohMenu->AddSearchWidget({ dungeonSpoilerWidget, "Randomizer", "Check Tracker", "General Settings" }); + SohGui::GetSohMenu()->AddSearchWidget({ dungeonSpoilerWidget, "Randomizer", "Check Tracker", "General Settings" }); hideUnshuffledShopWidget = { .name = "Hide Unshuffled Shop Item Checks", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; hideUnshuffledShopWidget.CVar(CVAR_TRACKER_CHECK("HideUnshuffledShopChecks")) @@ -2337,7 +2280,8 @@ void RegisterCheckTrackerWidgets() { hideShopUnshuffledChecks = CVarGetInteger(CVAR_TRACKER_CHECK("HideUnshuffledShopChecks"), 0); UpdateFilters(); }); - SohGui::mSohMenu->AddSearchWidget({ hideUnshuffledShopWidget, "Randomizer", "Check Tracker", "General Settings" }); + SohGui::GetSohMenu()->AddSearchWidget( + { hideUnshuffledShopWidget, "Randomizer", "Check Tracker", "General Settings" }); showGSWidget = { .name = "Always Show Gold Skulltulas", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; showGSWidget.CVar(CVAR_TRACKER_CHECK("AlwaysShowGSLocs")) @@ -2348,14 +2292,14 @@ void RegisterCheckTrackerWidgets() { alwaysShowGS = !alwaysShowGS; UpdateFilters(); }); - SohGui::mSohMenu->AddSearchWidget({ showGSWidget, "Randomizer", "Check Tracker", "General Settings" }); + SohGui::GetSohMenu()->AddSearchWidget({ showGSWidget, "Randomizer", "Check Tracker", "General Settings" }); showLogicWidget = { .name = "Show Logic", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; showLogicWidget.CVar(CVAR_TRACKER_CHECK("ShowLogic")) .Options(CheckboxOptions() .Color(THEME_COLOR) .Tooltip("If enabled, will show a check's logic when hovering over it.")); - SohGui::mSohMenu->AddSearchWidget({ showLogicWidget, "Randomizer", "Check Tracker", "General Settings" }); + SohGui::GetSohMenu()->AddSearchWidget({ showLogicWidget, "Randomizer", "Check Tracker", "General Settings" }); checkAvailabilityWidget = { .name = "Enable Available Checks", .type = WidgetType::WIDGET_CVAR_CHECKBOX }; checkAvailabilityWidget.CVar(CVAR_TRACKER_CHECK("EnableAvailableChecks")) diff --git a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h index 85def7e3b..9a7a146d9 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_check_tracker.h @@ -63,5 +63,5 @@ void UpdateAllAreas(); void RecalculateAllAreaTotals(); void SpoilAreaFromCheck(RandomizerCheck rc); void RecalculateAvailableChecks(RandomizerRegion startingRegion = RR_ROOT); -void CheckTracker_LoadFromPreset(nlohmann::json info); +void LoadFromPreset(nlohmann::json info); } // namespace CheckTracker diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp index 2891e7755..3277370ba 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.cpp @@ -5,6 +5,7 @@ #include #include +#include #include extern "C" { @@ -22,10 +23,13 @@ extern PlayState* gPlayState; #include "soh/Enhancements/game-interactor/GameInteractor.h" #include "entrance.h" +using namespace UIWidgets; + #define COLOR_ORANGE IM_COL32(230, 159, 0, 255) #define COLOR_GREEN IM_COL32(0, 158, 115, 255) #define COLOR_GRAY IM_COL32(155, 155, 155, 255) +namespace EntranceTracker { EntranceOverride srcListSortedByArea[ENTRANCE_OVERRIDES_MAX_COUNT] = { 0 }; EntranceOverride destListSortedByArea[ENTRANCE_OVERRIDES_MAX_COUNT] = { 0 }; EntranceOverride srcListSortedByType[ENTRANCE_OVERRIDES_MAX_COUNT] = { 0 }; @@ -38,6 +42,10 @@ static s16 lastEntranceIndex = -1; static s16 currentGrottoId = -1; static s16 lastSceneOrEntranceDetected = -1; +Color_RGBA8 Color_Background = { 0, 0, 0, 255 }; +static WidgetInfo backgroundColorWidget; +static WidgetInfo windowTypeWidget; + static bool presetLoaded = false; static ImVec2 presetPos; static ImVec2 presetSize; @@ -478,7 +486,7 @@ const EntranceData* GetEntranceData(s16 index) { return nullptr; } -void EntranceTracker_LoadFromPreset(nlohmann::json info) { +void LoadFromPreset(nlohmann::json info) { presetLoaded = true; presetPos = { info["pos"]["x"], info["pos"]["y"] }; presetSize = { info["size"]["width"], info["size"]["height"] }; @@ -703,9 +711,39 @@ void InitEntranceTrackingData() { void EntranceTrackerSettingsWindow::DrawElement() { ImGui::TextWrapped("The entrance tracker will only track shuffled entrances"); - UIWidgets::Spacer(0); + Spacer(0); ImGui::TableNextColumn(); + SohGui::GetSohMenu()->MenuDrawItem(backgroundColorWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + + SohGui::GetSohMenu()->MenuDrawItem(windowTypeWidget, ImGui::GetContentRegionAvail().x, THEME_COLOR); + + if (CVarGetInteger(CVAR_TRACKER_ENTRANCE("WindowType"), TRACKER_WINDOW_WINDOW) == TRACKER_WINDOW_FLOATING) { + CVarCheckbox("Enable Dragging", CVAR_TRACKER_ENTRANCE("Draggable"), CheckboxOptions().Color(THEME_COLOR)); + CVarCheckbox("Only Enable While Paused", CVAR_TRACKER_ENTRANCE("ShowOnlyPaused"), + CheckboxOptions().Color(THEME_COLOR)); + CVarCombobox("Display Mode", CVAR_TRACKER_ENTRANCE("DisplayType"), showMode, + ComboboxOptions() + .LabelPosition(LabelPositions::Far) + .ComponentAlignment(ComponentAlignments::Right) + .Color(THEME_COLOR) + .DefaultIndex(0)); + if (CVarGetInteger(CVAR_TRACKER_ENTRANCE("DisplayType"), TRACKER_DISPLAY_ALWAYS) == + TRACKER_DISPLAY_COMBO_BUTTON) { + CVarCombobox("Combo Button 1", CVAR_TRACKER_ENTRANCE("ComboButton1"), buttonStrings, + ComboboxOptions() + .LabelPosition(LabelPositions::Far) + .ComponentAlignment(ComponentAlignments::Right) + .Color(THEME_COLOR) + .DefaultIndex(TRACKER_COMBO_BUTTON_L)); + CVarCombobox("Combo Button 2", CVAR_TRACKER_ENTRANCE("ComboButton2"), buttonStrings, + ComboboxOptions() + .LabelPosition(LabelPositions::Far) + .ComponentAlignment(ComponentAlignments::Right) + .Color(THEME_COLOR) + .DefaultIndex(TRACKER_COMBO_BUTTON_L)); + } + } if (ImGui::BeginTable("entranceTrackerSubSettings", 2, ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_SizingStretchProp)) { @@ -715,64 +753,55 @@ void EntranceTrackerSettingsWindow::DrawElement() { ImGui::TableNextColumn(); ImGui::Text("Sort By"); - UIWidgets::CVarRadioButton("To", CVAR_TRACKER_ENTRANCE("SortBy"), 0, - UIWidgets::RadioButtonsOptions() - .Color(THEME_COLOR) - .Tooltip("Sort entrances by the original source entrance")); - UIWidgets::CVarRadioButton( + CVarRadioButton( + "To", CVAR_TRACKER_ENTRANCE("SortBy"), 0, + RadioButtonsOptions().Color(THEME_COLOR).Tooltip("Sort entrances by the original source entrance")); + CVarRadioButton( "From", CVAR_TRACKER_ENTRANCE("SortBy"), 1, - UIWidgets::RadioButtonsOptions().Color(THEME_COLOR).Tooltip("Sort entrances by the overrided destination")); + RadioButtonsOptions().Color(THEME_COLOR).Tooltip("Sort entrances by the overrided destination")); ImGui::Text("List Items"); - UIWidgets::CVarCheckbox( - "Auto scroll", CVAR_TRACKER_ENTRANCE("AutoScroll"), - UIWidgets::CheckboxOptions() - .Tooltip("Automatically scroll to the first available entrance in the current scene") - .Color(THEME_COLOR)); + CVarCheckbox("Auto scroll", CVAR_TRACKER_ENTRANCE("AutoScroll"), + CheckboxOptions() + .Tooltip("Automatically scroll to the first available entrance in the current scene") + .Color(THEME_COLOR)); ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); - UIWidgets::CVarCheckbox("Highlight previous", CVAR_TRACKER_ENTRANCE("HighlightPrevious"), - UIWidgets::CheckboxOptions() - .Tooltip("Highlight the previous entrance that Link came from") - .Color(THEME_COLOR)); - UIWidgets::CVarCheckbox("Highlight available", CVAR_TRACKER_ENTRANCE("HighlightAvailable"), - UIWidgets::CheckboxOptions() - .Tooltip("Highlight available entrances in the current scene") - .Color(THEME_COLOR)); + CVarCheckbox( + "Highlight previous", CVAR_TRACKER_ENTRANCE("HighlightPrevious"), + CheckboxOptions().Tooltip("Highlight the previous entrance that Link came from").Color(THEME_COLOR)); + CVarCheckbox( + "Highlight available", CVAR_TRACKER_ENTRANCE("HighlightAvailable"), + CheckboxOptions().Tooltip("Highlight available entrances in the current scene").Color(THEME_COLOR)); ImGui::EndDisabled(); - UIWidgets::CVarCheckbox("Hide undiscovered", CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), - UIWidgets::CheckboxOptions() - .Tooltip("Collapse undiscovered entrances towards the bottom of each group") - .Color(THEME_COLOR)); + CVarCheckbox("Hide undiscovered", CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), + CheckboxOptions() + .Tooltip("Collapse undiscovered entrances towards the bottom of each group") + .Color(THEME_COLOR)); bool disableHideReverseEntrances = OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == RO_GENERIC_ON; static const char* disableHideReverseEntrancesText = "This option is disabled because \"Decouple Entrances\" is enabled."; - UIWidgets::CVarCheckbox("Hide reverse", CVAR_TRACKER_ENTRANCE("HideReverseEntrances"), - UIWidgets::CheckboxOptions({ { .disabled = disableHideReverseEntrances, - .disabledTooltip = disableHideReverseEntrancesText } }) - .Tooltip("Hide reverse entrance transitions when Decouple Entrances is off") - .DefaultValue(true) - .Color(THEME_COLOR)); + CVarCheckbox("Hide reverse", CVAR_TRACKER_ENTRANCE("HideReverseEntrances"), + CheckboxOptions({ { .disabled = disableHideReverseEntrances, + .disabledTooltip = disableHideReverseEntrancesText } }) + .Tooltip("Hide reverse entrance transitions when Decouple Entrances is off") + .DefaultValue(true) + .Color(THEME_COLOR)); ImGui::TableNextColumn(); ImGui::Text("Group By"); - UIWidgets::CVarRadioButton( - "Area", CVAR_TRACKER_ENTRANCE("GroupBy"), 0, - UIWidgets::RadioButtonsOptions().Color(THEME_COLOR).Tooltip("Group entrances by their area")); - UIWidgets::CVarRadioButton( - "Type", CVAR_TRACKER_ENTRANCE("GroupBy"), 1, - UIWidgets::RadioButtonsOptions().Color(THEME_COLOR).Tooltip("Group entrances by their entrance type")); + CVarRadioButton("Area", CVAR_TRACKER_ENTRANCE("GroupBy"), 0, + RadioButtonsOptions().Color(THEME_COLOR).Tooltip("Group entrances by their area")); + CVarRadioButton("Type", CVAR_TRACKER_ENTRANCE("GroupBy"), 1, + RadioButtonsOptions().Color(THEME_COLOR).Tooltip("Group entrances by their entrance type")); ImGui::Text("Spoiler Reveal"); ImGui::BeginDisabled(CVarGetInteger(CVAR_SETTING("DisableChanges"), 0)); - UIWidgets::CVarCheckbox( - "Show Source", CVAR_TRACKER_ENTRANCE("ShowFrom"), - UIWidgets::CheckboxOptions().Tooltip("Reveal the source for undiscovered entrances").Color(THEME_COLOR)); - UIWidgets::CVarCheckbox("Show Destination", CVAR_TRACKER_ENTRANCE("ShowTo"), - UIWidgets::CheckboxOptions() - .Tooltip("Reveal the destination for undiscovered entrances") - .Color(THEME_COLOR)); + CVarCheckbox("Show Source", CVAR_TRACKER_ENTRANCE("ShowFrom"), + CheckboxOptions().Tooltip("Reveal the source for undiscovered entrances").Color(THEME_COLOR)); + CVarCheckbox("Show Destination", CVAR_TRACKER_ENTRANCE("ShowTo"), + CheckboxOptions().Tooltip("Reveal the destination for undiscovered entrances").Color(THEME_COLOR)); ImGui::EndDisabled(); ImGui::EndTable(); } @@ -796,6 +825,29 @@ void EntranceTrackerWindow::Draw() { } void EntranceTrackerWindow::DrawElement() { + Color_Background = CVarGetColor(CVAR_TRACKER_ENTRANCE("BgColor.Value"), Color_Bg_Default); + if (CVarGetInteger(CVAR_TRACKER_ENTRANCE("WindowType"), TRACKER_WINDOW_WINDOW) == TRACKER_WINDOW_FLOATING) { + if (CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowOnlyPaused"), 0) && + (gPlayState == nullptr || gPlayState->pauseCtx.state == 0)) { + return; + } + + if (CVarGetInteger(CVAR_TRACKER_ENTRANCE("DisplayType"), TRACKER_DISPLAY_ALWAYS) == + TRACKER_DISPLAY_COMBO_BUTTON) { + int comboButton1Mask = + buttons[CVarGetInteger(CVAR_TRACKER_ENTRANCE("ComboButton1"), TRACKER_COMBO_BUTTON_L)]; + int comboButton2Mask = + buttons[CVarGetInteger(CVAR_TRACKER_ENTRANCE("ComboButton2"), TRACKER_COMBO_BUTTON_R)]; + OSContPad* trackerButtonsPressed = + std::dynamic_pointer_cast(Ship::Context::GetInstance()->GetControlDeck())->GetPads(); + bool comboButtonsHeld = trackerButtonsPressed != nullptr && + trackerButtonsPressed[0].button & comboButton1Mask && + trackerButtonsPressed[0].button & comboButton2Mask; + if (!comboButtonsHeld) { + return; + } + } + } if (presetLoaded) { ImGui::SetNextWindowSize(presetSize); ImGui::SetNextWindowPos(presetPos); @@ -803,214 +855,220 @@ void EntranceTrackerWindow::DrawElement() { } else { ImGui::SetNextWindowSize(ImVec2(600, 375), ImGuiCond_FirstUseEver); } - - if (!ImGui::Begin("Entrance Tracker", &mIsVisible, ImGuiWindowFlags_NoFocusOnAppearing)) { - ImGui::End(); - return; - } - - static ImGuiTextFilter locationSearch; - - uint8_t nextTreeState = 0; - if (UIWidgets::Button("Collapse All", UIWidgets::ButtonOptions({ { .tooltip = "Collapse all entrance groups" } }) - .Color(THEME_COLOR) - .Size(UIWidgets::Sizes::Inline))) { - nextTreeState = 1; - } - ImGui::SameLine(); - if (UIWidgets::Button("Expand All", UIWidgets::ButtonOptions({ { .tooltip = "Expand all entrance groups" } }) - .Color(THEME_COLOR) - .Size(UIWidgets::Sizes::Inline))) { - nextTreeState = 2; - } - ImGui::SameLine(); - if (UIWidgets::Button("Clear", UIWidgets::ButtonOptions({ { .tooltip = "Clear the search field" } }) - .Color(THEME_COLOR) - .Size(UIWidgets::Sizes::Inline))) { - locationSearch.Clear(); - } - - UIWidgets::PushStyleCombobox(THEME_COLOR); - if (locationSearch.Draw()) { - nextTreeState = 2; - } - UIWidgets::PopStyleCombobox(); - - uint8_t destToggle = CVarGetInteger(CVAR_TRACKER_ENTRANCE("SortBy"), 0); - uint8_t groupToggle = CVarGetInteger(CVAR_TRACKER_ENTRANCE("GroupBy"), 0); - - // Combine destToggle and groupToggle to get a range of 0-3 - uint8_t groupType = destToggle + (groupToggle * 2); - size_t groupCount = groupToggle ? (size_t)ENTRANCE_TYPE_COUNT : (size_t)SPOILER_ENTRANCE_GROUP_COUNT; - auto groupNames = groupToggle ? groupTypeNames : spoilerEntranceGroupNames; - - EntranceOverride* entranceList; - - switch (groupType) { - case ENTRANCE_SOURCE_AREA: - entranceList = srcListSortedByArea; - break; - case ENTRANCE_DESTINATION_AREA: - entranceList = destListSortedByArea; - break; - case ENTRANCE_SOURCE_TYPE: - entranceList = srcListSortedByType; - break; - case ENTRANCE_DESTINATION_TYPE: - entranceList = destListSortedByType; - break; - } - - // Begin tracker list - ImGui::BeginChild("ChildEntranceTrackerLocations", ImVec2(0, -8)); - bool showTo = CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowTo"), 0); - bool showFrom = CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowFrom"), 0); - bool collapseUndiscovered = CVarGetInteger(CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), 0); - bool highlightPrevious = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightPrevious"), 0); - bool highlightAvailable = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightAvailable"), 0); - bool hideReverse = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HideReverseEntrances"), 1); - bool autoScrollArea = CVarGetInteger(CVAR_TRACKER_ENTRANCE("AutoScroll"), 0); - for (size_t i = 0; i < groupCount; i++) { - std::string groupName = groupNames[i]; - - uint16_t entranceCount = gEntranceTrackingData.GroupEntranceCounts[groupType][i]; - uint16_t startIndex = gEntranceTrackingData.GroupOffsets[groupType][i]; - - bool doAreaScroll = false; - int undiscovered = 0; - std::vector displayEntrances = {}; - - // Loop over entrances first for filtering - for (size_t entranceIdx = 0; entranceIdx < entranceCount; entranceIdx++) { - size_t trueIdx = entranceIdx + startIndex; - - EntranceOverride entrance = entranceList[trueIdx]; - - const EntranceData* original = GetEntranceData(entrance.index); - const EntranceData* override = GetEntranceData(entrance.override); - - // If entrance is a dungeon, grotto, or interior entrance, the transition into that area has oneExit set, - // which means we can filter the return transitions as redundant if entrances are not decoupled, as this is - // redundant information. Also checks a setting, enabled by default, for hiding them. If all of these - // conditions are met, we skip adding this entrance to any lists. However, if entrances are decoupled, then - // all transitions need to be displayed, so we proceed with the filtering - if ((original->type == ENTRANCE_TYPE_DUNGEON || original->type == ENTRANCE_TYPE_GROTTO || - original->type == ENTRANCE_TYPE_INTERIOR) && - (original->oneExit != 1 && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == RO_GENERIC_OFF) && - hideReverse == 1) { - continue; - } - - // RANDOTODO: Only show blue warps if bluewarp shuffle is on - if (original->metaTag.ends_with("bw") || override->metaTag.ends_with("bw")) { - continue; - } - - bool isDiscovered = IsEntranceDiscovered(entrance.index); - - bool showOverride = (!destToggle ? showTo : showFrom) || isDiscovered; - bool showOriginal = (!destToggle ? showFrom : showTo) || isDiscovered; - - const char* origSrcAreaName = spoilerEntranceGroupNames[original->srcGroup].c_str(); - const char* origTypeName = groupTypeNames[original->type].c_str(); - const char* rplcSrcAreaName = spoilerEntranceGroupNames[override->srcGroup].c_str(); - const char* rplcTypeName = groupTypeNames[override->type].c_str(); - - const char* origSrcName = showOriginal ? original->source.c_str() : ""; - const char* rplcDstName = showOverride ? override->destination.c_str() : ""; - - // Filter for entrances by group name, type, source/destination names, and meta tags - if ((!locationSearch.IsActive() && (showOriginal || showOverride || !collapseUndiscovered)) || - ((showOriginal && - (locationSearch.PassFilter(origSrcName) || locationSearch.PassFilter(origSrcAreaName) || - locationSearch.PassFilter(origTypeName) || locationSearch.PassFilter(original->metaTag.c_str()))) || - (showOverride && - (locationSearch.PassFilter(rplcDstName) || locationSearch.PassFilter(rplcSrcAreaName) || - locationSearch.PassFilter(rplcTypeName) || locationSearch.PassFilter(override->metaTag.c_str()))))) { - - // Detect if a scroll should happen and remember the scene for that scroll - if (!doAreaScroll && - (lastSceneOrEntranceDetected != LinkIsInArea(original) && LinkIsInArea(original) != -1)) { - lastSceneOrEntranceDetected = LinkIsInArea(original); - doAreaScroll = true; - } - - displayEntrances.push_back(entrance); - } else if (!isDiscovered) { - undiscovered++; - } + if (Trackers::BeginFloatWindows( + "Entrance Tracker", mIsVisible, Color_Background, + static_cast(CVarGetInteger(CVAR_TRACKER_ENTRANCE("WindowType"), TRACKER_WINDOW_WINDOW)), + CVarGetInteger(CVAR_TRACKER_ENTRANCE("Draggable"), 1), ImGuiWindowFlags_NoScrollbar)) { + if (!GameInteractor::IsSaveLoaded()) { + ImGui::Text("Waiting for file load..."); // TODO Language + Trackers::EndFloatWindows(); + return; } - // Then display the entrances in groups - if (displayEntrances.size() != 0 || (!locationSearch.IsActive() && undiscovered > 0)) { - // Handle opening/closing trees based on auto scroll or collapse/expand buttons - if (nextTreeState == 1) { - ImGui::SetNextItemOpen(false, ImGuiCond_None); - } else { - ImGui::SetNextItemOpen(true, nextTreeState == 0 && !doAreaScroll ? ImGuiCond_Once : ImGuiCond_None); - } + static ImGuiTextFilter locationSearch; - if (ImGui::TreeNode(groupName.c_str())) { - for (auto entrance : displayEntrances) { - const EntranceData* original = GetEntranceData(entrance.index); - const EntranceData* override = GetEntranceData(entrance.override); + uint8_t nextTreeState = 0; + if (Button("Collapse All", ButtonOptions({ { .tooltip = "Collapse all entrance groups" } }) + .Color(THEME_COLOR) + .Size(Sizes::Inline))) { + nextTreeState = 1; + } + ImGui::SameLine(); + if (Button("Expand All", ButtonOptions({ { .tooltip = "Expand all entrance groups" } }) + .Color(THEME_COLOR) + .Size(Sizes::Inline))) { + nextTreeState = 2; + } + ImGui::SameLine(); + if (Button("Clear", + ButtonOptions({ { .tooltip = "Clear the search field" } }).Color(THEME_COLOR).Size(Sizes::Inline))) { + locationSearch.Clear(); + } - bool isDiscovered = IsEntranceDiscovered(entrance.index); + PushStyleCombobox(THEME_COLOR); + if (locationSearch.Draw()) { + nextTreeState = 2; + } + PopStyleCombobox(); - bool showOverride = (!destToggle ? showTo : showFrom) || isDiscovered; - bool showOriginal = (!destToggle ? showFrom : showTo) || isDiscovered; + uint8_t destToggle = CVarGetInteger(CVAR_TRACKER_ENTRANCE("SortBy"), 0); + uint8_t groupToggle = CVarGetInteger(CVAR_TRACKER_ENTRANCE("GroupBy"), 0); - const char* unknown = "???"; + // Combine destToggle and groupToggle to get a range of 0-3 + uint8_t groupType = destToggle + (groupToggle * 2); + size_t groupCount = groupToggle ? (size_t)ENTRANCE_TYPE_COUNT : (size_t)SPOILER_ENTRANCE_GROUP_COUNT; + auto groupNames = groupToggle ? groupTypeNames : spoilerEntranceGroupNames; - const char* origSrcName = showOriginal ? original->source.c_str() : unknown; - const char* rplcDstName = showOverride ? override->destination.c_str() : unknown; + EntranceOverride* entranceList; - uint32_t color = isDiscovered ? IM_COL32_WHITE : COLOR_GRAY; + switch (groupType) { + case ENTRANCE_SOURCE_AREA: + entranceList = srcListSortedByArea; + break; + case ENTRANCE_DESTINATION_AREA: + entranceList = destListSortedByArea; + break; + case ENTRANCE_SOURCE_TYPE: + entranceList = srcListSortedByType; + break; + case ENTRANCE_DESTINATION_TYPE: + entranceList = destListSortedByType; + break; + } - // Handle highlighting and auto scroll - if ((original->index == lastEntranceIndex || - (override->reverseIndex == lastEntranceIndex && - OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == - RO_GENERIC_OFF)) && - highlightPrevious) { - color = COLOR_ORANGE; - } else if (LinkIsInArea(original) != -1) { - if (highlightAvailable) { - color = COLOR_GREEN; - } + // Begin tracker list + ImGui::BeginChild("ChildEntranceTrackerLocations", ImVec2(0, -8)); + bool showTo = CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowTo"), 0); + bool showFrom = CVarGetInteger(CVAR_TRACKER_ENTRANCE("ShowFrom"), 0); + bool collapseUndiscovered = CVarGetInteger(CVAR_TRACKER_ENTRANCE("CollapseUndiscovered"), 0); + bool highlightPrevious = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightPrevious"), 0); + bool highlightAvailable = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HighlightAvailable"), 0); + bool hideReverse = CVarGetInteger(CVAR_TRACKER_ENTRANCE("HideReverseEntrances"), 1); + bool autoScrollArea = CVarGetInteger(CVAR_TRACKER_ENTRANCE("AutoScroll"), 0); + for (size_t i = 0; i < groupCount; i++) { + std::string groupName = groupNames[i]; - if (doAreaScroll) { - doAreaScroll = false; - if (autoScrollArea) { - ImGui::SetScrollHereY(0.0f); - } - } + uint16_t entranceCount = gEntranceTrackingData.GroupEntranceCounts[groupType][i]; + uint16_t startIndex = gEntranceTrackingData.GroupOffsets[groupType][i]; + + bool doAreaScroll = false; + int undiscovered = 0; + std::vector displayEntrances = {}; + + // Loop over entrances first for filtering + for (size_t entranceIdx = 0; entranceIdx < entranceCount; entranceIdx++) { + size_t trueIdx = entranceIdx + startIndex; + + EntranceOverride entrance = entranceList[trueIdx]; + + const EntranceData* original = GetEntranceData(entrance.index); + const EntranceData* override = GetEntranceData(entrance.override); + + // If entrance is a dungeon, grotto, or interior entrance, the transition into that area has oneExit + // set, which means we can filter the return transitions as redundant if entrances are not decoupled, as + // this is redundant information. Also checks a setting, enabled by default, for hiding them. If all of + // these conditions are met, we skip adding this entrance to any lists. However, if entrances are + // decoupled, then all transitions need to be displayed, so we proceed with the filtering + if ((original->type == ENTRANCE_TYPE_DUNGEON || original->type == ENTRANCE_TYPE_GROTTO || + original->type == ENTRANCE_TYPE_INTERIOR) && + (original->oneExit != 1 && OTRGlobals::Instance->gRandomizer->GetRandoSettingValue( + RSK_DECOUPLED_ENTRANCES) == RO_GENERIC_OFF) && + hideReverse == 1) { + continue; + } + + // RANDOTODO: Only show blue warps if bluewarp shuffle is on + if (original->metaTag.ends_with("bw") || override->metaTag.ends_with("bw")) { + continue; + } + + bool isDiscovered = IsEntranceDiscovered(entrance.index); + + bool showOverride = (!destToggle ? showTo : showFrom) || isDiscovered; + bool showOriginal = (!destToggle ? showFrom : showTo) || isDiscovered; + + const char* origSrcAreaName = spoilerEntranceGroupNames[original->srcGroup].c_str(); + const char* origTypeName = groupTypeNames[original->type].c_str(); + const char* rplcSrcAreaName = spoilerEntranceGroupNames[override->srcGroup].c_str(); + const char* rplcTypeName = groupTypeNames[override->type].c_str(); + + const char* origSrcName = showOriginal ? original->source.c_str() : ""; + const char* rplcDstName = showOverride ? override->destination.c_str() : ""; + + // Filter for entrances by group name, type, source/destination names, and meta tags + if ((!locationSearch.IsActive() && (showOriginal || showOverride || !collapseUndiscovered)) || + ((showOriginal && + (locationSearch.PassFilter(origSrcName) || locationSearch.PassFilter(origSrcAreaName) || + locationSearch.PassFilter(origTypeName) || + locationSearch.PassFilter(original->metaTag.c_str()))) || + (showOverride && + (locationSearch.PassFilter(rplcDstName) || locationSearch.PassFilter(rplcSrcAreaName) || + locationSearch.PassFilter(rplcTypeName) || + locationSearch.PassFilter(override->metaTag.c_str()))))) { + + // Detect if a scroll should happen and remember the scene for that scroll + if (!doAreaScroll && + (lastSceneOrEntranceDetected != LinkIsInArea(original) && LinkIsInArea(original) != -1)) { + lastSceneOrEntranceDetected = LinkIsInArea(original); + doAreaScroll = true; } - ImGui::PushStyleColor(ImGuiCol_Text, color); + displayEntrances.push_back(entrance); + } else if (!isDiscovered) { + undiscovered++; + } + } - // Use a non-breaking space to keep the arrow from wrapping to a newline by itself - ImGui::TextWrapped("%s\u00A0-> %s", origSrcName, rplcDstName); - - ImGui::PopStyleColor(); + // Then display the entrances in groups + if (displayEntrances.size() != 0 || (!locationSearch.IsActive() && undiscovered > 0)) { + // Handle opening/closing trees based on auto scroll or collapse/expand buttons + if (nextTreeState == 1) { + ImGui::SetNextItemOpen(false, ImGuiCond_None); + } else { + ImGui::SetNextItemOpen(true, nextTreeState == 0 && !doAreaScroll ? ImGuiCond_Once : ImGuiCond_None); } - // Write collapsed undiscovered info - if (!locationSearch.IsActive() && undiscovered > 0) { - UIWidgets::Spacer(0); - ImGui::PushStyleColor(ImGuiCol_Text, COLOR_GRAY); - ImGui::TextWrapped("%d Undiscovered", undiscovered); - ImGui::PopStyleColor(); - } + if (ImGui::TreeNode(groupName.c_str())) { + for (auto entrance : displayEntrances) { + const EntranceData* original = GetEntranceData(entrance.index); + const EntranceData* override = GetEntranceData(entrance.override); - UIWidgets::Spacer(0); - ImGui::TreePop(); + bool isDiscovered = IsEntranceDiscovered(entrance.index); + + bool showOverride = (!destToggle ? showTo : showFrom) || isDiscovered; + bool showOriginal = (!destToggle ? showFrom : showTo) || isDiscovered; + + const char* unknown = "???"; + + const char* origSrcName = showOriginal ? original->source.c_str() : unknown; + const char* rplcDstName = showOverride ? override->destination.c_str() : unknown; + + uint32_t color = isDiscovered ? IM_COL32_WHITE : COLOR_GRAY; + + // Handle highlighting and auto scroll + if ((original->index == lastEntranceIndex || + (override->reverseIndex == lastEntranceIndex && + OTRGlobals::Instance->gRandomizer->GetRandoSettingValue(RSK_DECOUPLED_ENTRANCES) == + RO_GENERIC_OFF)) && + highlightPrevious) { + color = COLOR_ORANGE; + } else if (LinkIsInArea(original) != -1) { + if (highlightAvailable) { + color = COLOR_GREEN; + } + + if (doAreaScroll) { + doAreaScroll = false; + if (autoScrollArea) { + ImGui::SetScrollHereY(0.0f); + } + } + } + + ImGui::PushStyleColor(ImGuiCol_Text, color); + + // Use a non-breaking space to keep the arrow from wrapping to a newline by itself + ImGui::TextWrapped("%s\u00A0-> %s", origSrcName, rplcDstName); + + ImGui::PopStyleColor(); + } + + // Write collapsed undiscovered info + if (!locationSearch.IsActive() && undiscovered > 0) { + Spacer(0); + ImGui::PushStyleColor(ImGuiCol_Text, COLOR_GRAY); + ImGui::TextWrapped("%d Undiscovered", undiscovered); + ImGui::PopStyleColor(); + } + + Spacer(0); + ImGui::TreePop(); + } } } + ImGui::EndChild(); + Trackers::EndFloatWindows(); } - ImGui::EndChild(); - ImGui::End(); } void EntranceTrackerWindow::InitElement() { @@ -1020,3 +1078,66 @@ void EntranceTrackerWindow::InitElement() { GameInteractor::Instance->RegisterGameHook( [](int32_t fileNum) { ClearEntranceTrackingData(); }); } + +void RegisterCheckTrackerWidgets() { + backgroundColorWidget = { .name = "Background Color##EntranceTracker", + .type = WidgetType::WIDGET_CVAR_COLOR_PICKER }; + backgroundColorWidget.CVar(CVAR_TRACKER_ENTRANCE("BgColor")) + .Options( + ColorPickerOptions().Color(THEME_COLOR).DefaultValue(Color_Bg_Default).UseAlpha().ShowReset().ShowRandom()); + SohGui::GetSohMenu()->AddSearchWidget( + { backgroundColorWidget, "Randomizer", "Entrance Tracker", "General Settings" }); + + windowTypeWidget = { .name = "Window Type##EntranceTracker", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + windowTypeWidget.CVar(CVAR_TRACKER_ENTRANCE("WindowType")) + .Options(ComboboxOptions() + .DefaultIndex(TRACKER_WINDOW_WINDOW) + .ComponentAlignment(ComponentAlignments::Right) + .LabelPosition(LabelPositions::Far) + .Color(THEME_COLOR) + .ComboMap(windowType)); + SohGui::GetSohMenu()->AddSearchWidget({ windowTypeWidget, "Randomizer", "Entrance Tracker", "General Settings" }); +} + +static RegisterMenuInitFunc menuInitFunc(RegisterCheckTrackerWidgets); +} // namespace EntranceTracker + +namespace Trackers { +// Windowing stuff +bool BeginFloatWindows(std::string UniqueName, bool& open, Color_RGBA8& bgCol, TrackerWindowType windowType, + bool draggable, ImGuiWindowFlags flags) { + ImGuiWindowFlags windowFlags = flags; + + if (windowFlags == 0) { + windowFlags |= ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_NoFocusOnAppearing; + } + + if (windowType == TRACKER_WINDOW_FLOATING) { + ImGui::SetNextWindowViewport(ImGui::GetMainViewport()->ID); + windowFlags |= ImGuiWindowFlags_NoDocking | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoTitleBar | + ImGuiWindowFlags_NoScrollWithMouse | ImGuiWindowFlags_NoScrollbar; + + if (!draggable) { + windowFlags |= ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove; + } + } + auto maybeParent = ImGui::GetCurrentWindow(); + ImGuiWindow* window = ImGui::FindWindowByName(UniqueName.c_str()); + ImVec4 bgColVec = VecFromRGBA8(bgCol); + if (window != NULL && window->DockTabIsVisible && window->ParentWindow != NULL && + std::string(window->ParentWindow->Name).compare(0, strlen("Main - Deck"), "Main - Deck") == 0) { + bgColVec.w = 1.0f; + } + ImGui::PushStyleColor(ImGuiCol_WindowBg, bgColVec); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f); + return ImGui::Begin(UniqueName.c_str(), &open, windowFlags); +} + +void EndFloatWindows() { + ImGui::PopStyleVar(); + ImGui::PopStyleColor(); + ImGui::PopStyleColor(); + ImGui::End(); +} // namespace Trackers +} // namespace Trackers diff --git a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h index 31592cd08..036630e90 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h +++ b/soh/soh/Enhancements/randomizer/randomizer_entrance_tracker.h @@ -5,6 +5,7 @@ #include #include +#include "randomizerTypes.h" typedef enum { // ENTRANCE_GROUP_NO_GROUP, @@ -75,7 +76,22 @@ typedef struct { uint16_t GroupOffsets[TRACKER_GROUP_TYPE_COUNT][SPOILER_ENTRANCE_GROUP_COUNT]; } EntranceTrackingData; -extern EntranceTrackingData gEntranceTrackingData; +static std::map windowType = { { TRACKER_WINDOW_FLOATING, "Floating" }, + { TRACKER_WINDOW_WINDOW, "Window" } }; +static std::map showMode = { { 0, "Always" }, { 1, "Combo Button Hold" } }; +static std::map buttonStrings = { + { TRACKER_COMBO_BUTTON_A, "A Button" }, { TRACKER_COMBO_BUTTON_B, "B Button" }, + { TRACKER_COMBO_BUTTON_C_UP, "C-Up" }, { TRACKER_COMBO_BUTTON_C_DOWN, "C-Down" }, + { TRACKER_COMBO_BUTTON_C_LEFT, "C-Left" }, { TRACKER_COMBO_BUTTON_C_RIGHT, "C-Right" }, + { TRACKER_COMBO_BUTTON_L, "L Button" }, { TRACKER_COMBO_BUTTON_Z, "Z Button" }, + { TRACKER_COMBO_BUTTON_R, "R Button" }, { TRACKER_COMBO_BUTTON_START, "Start" }, + { TRACKER_COMBO_BUTTON_D_UP, "D-Up" }, { TRACKER_COMBO_BUTTON_D_DOWN, "D-Down" }, + { TRACKER_COMBO_BUTTON_D_LEFT, "D-Left" }, { TRACKER_COMBO_BUTTON_D_RIGHT, "D-Right" } +}; + +static const Color_RGBA8 Color_Bg_Default = { 0, 0, 0, 255 }; // Black +static std::vector buttons = { BTN_A, BTN_B, BTN_CUP, BTN_CDOWN, BTN_CLEFT, BTN_CRIGHT, BTN_L, + BTN_Z, BTN_R, BTN_START, BTN_DUP, BTN_DDOWN, BTN_DLEFT, BTN_DRIGHT }; #define SINGLE_SCENE_INFO(scene) \ { \ @@ -84,6 +100,9 @@ extern EntranceTrackingData gEntranceTrackingData; #define SCENE_NO_SPAWN(scene) \ { scene, -1 } +namespace EntranceTracker { +extern EntranceTrackingData gEntranceTrackingData; + void SetCurrentGrottoIDForTracker(int16_t entranceIndex); void SetLastEntranceOverrideForTracker(int16_t entranceIndex); void ClearEntranceTrackingData(); @@ -91,7 +110,7 @@ void InitEntranceTrackingData(); s16 GetLastEntranceOverride(); s16 GetCurrentGrottoId(); const EntranceData* GetEntranceData(s16); -void EntranceTracker_LoadFromPreset(nlohmann::json info); +void LoadFromPreset(nlohmann::json info); class EntranceTrackerSettingsWindow final : public Ship::GuiWindow { public: @@ -112,3 +131,10 @@ class EntranceTrackerWindow final : public Ship::GuiWindow { void DrawElement() override; void UpdateElement() override{}; }; +} // namespace EntranceTracker + +namespace Trackers { +bool BeginFloatWindows(std::string UniqueName, bool& open, Color_RGBA8& bgCol, TrackerWindowType windowType, + bool draggable, ImGuiWindowFlags flags = 0); +void EndFloatWindows(); +} // namespace Trackers diff --git a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp index 2edbfede3..1dabde263 100644 --- a/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp +++ b/soh/soh/Enhancements/randomizer/randomizer_item_tracker.cpp @@ -2016,23 +2016,6 @@ static std::map itemTrackerTriforcePieceTrackOptions = { { TRIFORCE_PIECE_COLLECTED_REQUIRED, "Collected / Required" }, { TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX, "Collected / Required / Max" }, }; -static std::map windowTypes = { - { TRACKER_WINDOW_FLOATING, "Floating" }, - { TRACKER_WINDOW_WINDOW, "Window" }, -}; -static std::map displayModes = { - { TRACKER_DISPLAY_ALWAYS, "Always" }, - { TRACKER_DISPLAY_COMBO_BUTTON, "Combo Button Hold" }, -}; -static std::map buttons = { - { TRACKER_COMBO_BUTTON_A, "A" }, { TRACKER_COMBO_BUTTON_B, "B" }, - { TRACKER_COMBO_BUTTON_C_UP, "C-Up" }, { TRACKER_COMBO_BUTTON_C_DOWN, "C-Down" }, - { TRACKER_COMBO_BUTTON_C_LEFT, "C-Left" }, { TRACKER_COMBO_BUTTON_C_RIGHT, "C-Right" }, - { TRACKER_COMBO_BUTTON_L, "L" }, { TRACKER_COMBO_BUTTON_Z, "Z" }, - { TRACKER_COMBO_BUTTON_R, "R" }, { TRACKER_COMBO_BUTTON_START, "Start" }, - { TRACKER_COMBO_BUTTON_D_UP, "D-Up" }, { TRACKER_COMBO_BUTTON_D_DOWN, "D-Down" }, - { TRACKER_COMBO_BUTTON_D_LEFT, "D-Left" }, { TRACKER_COMBO_BUTTON_D_RIGHT, "D-Right" }, -}; static std::map displayTypes = { { SECTION_DISPLAY_HIDDEN, "Hidden" }, { SECTION_DISPLAY_MAIN_WINDOW, "Main Window" }, @@ -2068,7 +2051,7 @@ void ItemTrackerSettingsWindow::DrawElement() { CheckboxOptions().Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Display Mode", CVAR_TRACKER_ITEM("DisplayType.Main"), displayModes, + if (CVarCombobox("Display Mode", CVAR_TRACKER_ITEM("DisplayType.Main"), showMode, ComboboxOptions() .DefaultIndex(TRACKER_DISPLAY_ALWAYS) .ComponentAlignment(ComponentAlignments::Right) @@ -2078,7 +2061,7 @@ void ItemTrackerSettingsWindow::DrawElement() { } if (CVarGetInteger(CVAR_TRACKER_ITEM("DisplayType.Main"), TRACKER_DISPLAY_ALWAYS) == TRACKER_DISPLAY_COMBO_BUTTON) { - if (CVarCombobox("Combo Button 1", CVAR_TRACKER_ITEM("ComboButton1"), buttons, + if (CVarCombobox("Combo Button 1", CVAR_TRACKER_ITEM("ComboButton1"), buttonStrings, ComboboxOptions() .DefaultIndex(TRACKER_COMBO_BUTTON_L) .ComponentAlignment(ComponentAlignments::Right) @@ -2086,7 +2069,7 @@ void ItemTrackerSettingsWindow::DrawElement() { .Color(THEME_COLOR))) { shouldUpdateVectors = true; } - if (CVarCombobox("Combo Button 2", CVAR_TRACKER_ITEM("ComboButton2"), buttons, + if (CVarCombobox("Combo Button 2", CVAR_TRACKER_ITEM("ComboButton2"), buttonStrings, ComboboxOptions() .DefaultIndex(TRACKER_COMBO_BUTTON_R) .ComponentAlignment(ComponentAlignments::Right) @@ -2223,20 +2206,20 @@ void ItemTrackerWindow::InitElement() { } void RegisterItemTrackerWidgets() { - backgroundColor = { .name = "Background Color##gItemTrackerBgColor", .type = WidgetType::WIDGET_CVAR_COLOR_PICKER }; + backgroundColor = { .name = "Background Color##ItemTracker", .type = WidgetType::WIDGET_CVAR_COLOR_PICKER }; backgroundColor.CVar(CVAR_TRACKER_ITEM("BgColor")) .Options( ColorPickerOptions().Color(THEME_COLOR).DefaultValue({ 0, 0, 0, 0 }).UseAlpha().ShowReset().ShowRandom()); SohGui::mSohMenu->AddSearchWidget({ backgroundColor, "Randomizer", "Item Tracker", "General Settings" }); - windowTypeWidget = { .name = "Window Type", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; + windowTypeWidget = { .name = "Window Type##ItemTracker", .type = WidgetType::WIDGET_CVAR_COMBOBOX }; windowTypeWidget.CVar(CVAR_TRACKER_ITEM("WindowType")) .Options(ComboboxOptions() .DefaultIndex(TRACKER_WINDOW_FLOATING) .ComponentAlignment(ComponentAlignments::Right) .LabelPosition(LabelPositions::Far) .Color(THEME_COLOR) - .ComboMap(windowTypes)) + .ComboMap(windowType)) .Callback([](WidgetInfo& info) { shouldUpdateVectors = true; }); SohGui::mSohMenu->AddSearchWidget({ windowTypeWidget, "Randomizer", "Item Tracker", "General Settings" }); enableDraggingWidget; diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index b544b31b1..7535a8739 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2429,11 +2429,11 @@ extern "C" void Randomizer_ShowRandomizerMenu() { } extern "C" void EntranceTracker_SetCurrentGrottoID(s16 entranceIndex) { - SetCurrentGrottoIDForTracker(entranceIndex); + EntranceTracker::SetCurrentGrottoIDForTracker(entranceIndex); } extern "C" void EntranceTracker_SetLastEntranceOverride(s16 entranceIndex) { - SetLastEntranceOverrideForTracker(entranceIndex); + EntranceTracker::SetLastEntranceOverrideForTracker(entranceIndex); } extern "C" void Gfx_RegisterBlendedTexture(const char* name, u8* mask, u8* replacement) { diff --git a/soh/soh/SohGui/SohGui.cpp b/soh/soh/SohGui/SohGui.cpp index de0b8be09..183038d43 100644 --- a/soh/soh/SohGui/SohGui.cpp +++ b/soh/soh/SohGui/SohGui.cpp @@ -19,7 +19,6 @@ #ifdef __SWITCH__ #include #endif -#include "SohMenu.h" #include "include/global.h" #include "include/z64audio.h" #include "soh/SaveManager.h" @@ -67,8 +66,6 @@ std::string GetWindowButtonText(const char* text, bool menuOpen) { // MARK: - Delegates -std::shared_ptr mSohMenuBar; - std::shared_ptr mConsoleWindow; std::shared_ptr mStatsWindow; std::shared_ptr mGfxDebuggerWindow; @@ -89,8 +86,8 @@ std::shared_ptr mMessageViewerWindow; std::shared_ptr mGameplayStatsWindow; std::shared_ptr mCheckTrackerSettingsWindow; std::shared_ptr mCheckTrackerWindow; -std::shared_ptr mEntranceTrackerSettingsWindow; -std::shared_ptr mEntranceTrackerWindow; +std::shared_ptr mEntranceTrackerSettingsWindow; +std::shared_ptr mEntranceTrackerWindow; std::shared_ptr mItemTrackerSettingsWindow; std::shared_ptr mItemTrackerWindow; std::shared_ptr mTimeSplitWindow; @@ -104,6 +101,10 @@ UIWidgets::Colors GetMenuThemeColor() { return mSohMenu->GetMenuThemeColor(); } +std::shared_ptr GetSohMenu() { + return mSohMenu; +} + void SetupMenu() { auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui(); mSohMenu = std::make_shared(CVAR_WINDOW("Menu"), "Port Menu"); @@ -177,10 +178,10 @@ void SetupGuiElements() { mCheckTrackerSettingsWindow = std::make_shared( CVAR_WINDOW("CheckTrackerSettings"), "Check Tracker Settings", ImVec2(600, 375)); gui->AddGuiWindow(mCheckTrackerSettingsWindow); - mEntranceTrackerWindow = - std::make_shared(CVAR_WINDOW("EntranceTracker"), "Entrance Tracker", ImVec2(500, 750)); + mEntranceTrackerWindow = std::make_shared( + CVAR_WINDOW("EntranceTracker"), "Entrance Tracker", ImVec2(500, 750)); gui->AddGuiWindow(mEntranceTrackerWindow); - mEntranceTrackerSettingsWindow = std::make_shared( + mEntranceTrackerSettingsWindow = std::make_shared( CVAR_WINDOW("EntranceTrackerSettings"), "Entrance Tracker Settings", ImVec2(600, 375)); gui->AddGuiWindow(mEntranceTrackerSettingsWindow); mItemTrackerWindow = @@ -229,7 +230,6 @@ void Destroy() { mStatsWindow = nullptr; mConsoleWindow = nullptr; mGfxDebuggerWindow = nullptr; - mSohMenuBar = nullptr; mInputViewer = nullptr; mInputViewerSettings = nullptr; mTimeSplitWindow = nullptr; diff --git a/soh/soh/SohGui/SohGui.hpp b/soh/soh/SohGui/SohGui.hpp index 2af5ef0fd..bc2d5fec6 100644 --- a/soh/soh/SohGui/SohGui.hpp +++ b/soh/soh/SohGui/SohGui.hpp @@ -9,7 +9,7 @@ #define SohGui_hpp #include -#include "SohMenuBar.h" +#include "SohMenu.h" #include "soh/Enhancements/audio/AudioEditor.h" #include "soh/Enhancements/controls/InputViewer.h" #include "soh/Enhancements/cosmetics/CosmeticsEditor.h" @@ -44,6 +44,7 @@ bool DismissPopup(std::string title); void ShowRandomizerSettingsMenu(); void ShowEscMenu(); UIWidgets::Colors GetMenuThemeColor(); +std::shared_ptr GetSohMenu(); } // namespace SohGui #define THEME_COLOR SohGui::GetMenuThemeColor() diff --git a/soh/soh/SohGui/SohMenuBar.cpp b/soh/soh/SohGui/SohMenuBar.cpp deleted file mode 100644 index ea5d522b0..000000000 --- a/soh/soh/SohGui/SohMenuBar.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "SohMenuBar.h" -#include -#include "regex" -#include -#include -#include "UIWidgets.hpp" -#include "include/z64audio.h" -#include -#include "soh/OTRGlobals.h" -#include "soh/SaveManager.h" -#include "z64.h" -#include "soh/cvar_prefixes.h" -#include "macros.h" -#include "functions.h" -#include "variables.h" -#include "soh/Enhancements/game-interactor/GameInteractor.h" -#include "soh/Enhancements/Presets/Presets.h" -#include "soh/Enhancements/mods.h" -#include "soh/Notification/Notification.h" -#include "soh/Enhancements/cosmetics/authenticGfxPatches.h" -#include "soh/Network/CrowdControl/CrowdControl.h" -#include "soh/Network/Sail/Sail.h" -#include "soh/Enhancements/audio/AudioEditor.h" -#include "soh/Enhancements/controls/InputViewer.h" -#include "soh/Enhancements/cosmetics/CosmeticsEditor.h" -#include "soh/Enhancements/debugger/actorViewer.h" -#include "soh/Enhancements/debugger/colViewer.h" -#include "soh/Enhancements/debugger/debugSaveEditor.h" -#include "soh/Enhancements/debugger/hookDebugger.h" -#include "soh/Enhancements/debugger/dlViewer.h" -#include "soh/Enhancements/debugger/valueViewer.h" -#include "soh/Enhancements/gameplaystatswindow.h" -#include "soh/Enhancements/debugger/MessageViewer.h" -#include "soh/Enhancements/randomizer/randomizer_check_tracker.h" -#include "soh/Enhancements/randomizer/randomizer_entrance_tracker.h" -#include "soh/Enhancements/randomizer/randomizer_item_tracker.h" -#include "soh/Enhancements/enemyrandomizer.h" -#include "soh/Enhancements/timesplits/TimeSplits.h" -#include "soh/Enhancements/randomizer/Plandomizer.h" -#include "soh/Enhancements/TimeDisplay/TimeDisplay.h" - -// FA icons are kind of wonky, if they worked how I expected them to the "+ 2.0f" wouldn't be needed, but -// they don't work how I expect them to so I added that because it looked good when I eyeballed it -#define FA_ICON_BUTTON_FRAME_PADDING_X(icon) (((optionsButtonSize.x - ImGui::CalcTextSize(icon).x) / 2) + 2.0f) - -extern bool isBetaQuestEnabled; - -extern "C" PlayState* gPlayState; - -std::string GetWindowButtonText(const char* text, bool menuOpen) { - char buttonText[100] = ""; - if (menuOpen) { - strcat(buttonText, ICON_FA_CHEVRON_RIGHT " "); - } - strcat(buttonText, text); - if (!menuOpen) { - strcat(buttonText, " "); - } - return buttonText; -} - -static std::unordered_map windowBackendNames = { - { Ship::WindowBackend::FAST3D_DXGI_DX11, "DirectX" }, - { Ship::WindowBackend::FAST3D_SDL_OPENGL, "OpenGL" }, - { Ship::WindowBackend::FAST3D_SDL_METAL, "Metal" }, -}; - -static const char* filters[3] = { -#ifdef __WIIU__ - "", -#else - "Three-Point", -#endif - "Linear", "None" -}; - -extern "C" SaveContext gSaveContext; - -namespace SohGui { - -std::unordered_map availableWindowBackendsMap; -Ship::WindowBackend configWindowBackend; - -void DrawSettingsMenu() { -} - -void SohMenuBar::InitElement() { -} - -void SohMenuBar::DrawElement() { - if (ImGui::BeginMenuBar()) { - static ImVec2 sWindowPadding(8.0f, 8.0f); - - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, sWindowPadding); - - DrawSettingsMenu(); - - ImGui::SetCursorPosY(0.0f); - - ImGui::PopStyleVar(1); - ImGui::EndMenuBar(); - } -} -} // namespace SohGui diff --git a/soh/soh/SohGui/SohMenuBar.h b/soh/soh/SohGui/SohMenuBar.h deleted file mode 100644 index 56d0c1c6a..000000000 --- a/soh/soh/SohGui/SohMenuBar.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace SohGui { -class SohMenuBar : public Ship::GuiMenuBar { - public: - using Ship::GuiMenuBar::GuiMenuBar; - - protected: - void DrawElement() override; - void InitElement() override; - void UpdateElement() override{}; -}; -} // namespace SohGui \ No newline at end of file diff --git a/soh/soh/SohGui/UIWidgets.hpp b/soh/soh/SohGui/UIWidgets.hpp index 2cbc1d5ff..927b2d271 100644 --- a/soh/soh/SohGui/UIWidgets.hpp +++ b/soh/soh/SohGui/UIWidgets.hpp @@ -681,13 +681,14 @@ void Separator(bool padTop = true, bool padBottom = true, float extraVerticalTop float CalcComboWidth(const char* preview_value, ImGuiComboFlags flags); template -bool Combobox(const char* label, T* value, const std::map& comboMap, +bool Combobox(std::string label, T* value, const std::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); + std::string trueLabel = label.substr(0, label.find("#")); + ImGui::PushID(label.c_str()); ImGui::BeginGroup(); ImGui::BeginDisabled(options.disabled); PushStyleCombobox(options.color); @@ -706,7 +707,7 @@ bool Combobox(const char* label, T* value, const std::map& combo ImGui::AlignTextToFramePadding(); if (options.labelPosition != LabelPositions::None) { if (options.alignment == ComponentAlignments::Right) { - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); if (options.labelPosition == LabelPositions::Above) { ImGui::NewLine(); ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); @@ -717,7 +718,7 @@ bool Combobox(const char* label, T* value, const std::map& combo } } else if (options.alignment == ComponentAlignments::Left) { if (options.labelPosition == LabelPositions::Above) { - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); } } } @@ -741,11 +742,11 @@ bool Combobox(const char* label, T* value, const std::map& combo if (options.alignment == ComponentAlignments::Left) { if (options.labelPosition == LabelPositions::Near) { ImGui::SameLine(); - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); } 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); + ImGui::Text("%s", trueLabel.c_str()); } } } @@ -763,13 +764,14 @@ bool Combobox(const char* label, T* value, const std::map& combo } template -bool Combobox(const char* label, T* value, const std::vector& comboVector, +bool Combobox(std::string 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); + std::string trueLabel = label.substr(0, label.find("#")); + ImGui::PushID(label.c_str()); ImGui::BeginGroup(); ImGui::BeginDisabled(options.disabled); PushStyleCombobox(options.color); @@ -788,7 +790,7 @@ bool Combobox(const char* label, T* value, const std::vector& combo ImGui::AlignTextToFramePadding(); if (options.labelPosition != LabelPositions::None) { if (options.alignment == ComponentAlignments::Right) { - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); if (options.labelPosition == LabelPositions::Above) { ImGui::NewLine(); ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); @@ -799,7 +801,7 @@ bool Combobox(const char* label, T* value, const std::vector& combo } } else if (options.alignment == ComponentAlignments::Left) { if (options.labelPosition == LabelPositions::Above) { - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); } } } @@ -824,11 +826,11 @@ bool Combobox(const char* label, T* value, const std::vector& combo if (options.alignment == ComponentAlignments::Left) { if (options.labelPosition == LabelPositions::Near) { ImGui::SameLine(); - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); } 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); + ImGui::Text("%s", trueLabel.c_str()); } } } @@ -847,13 +849,14 @@ bool Combobox(const char* label, T* value, const std::vector& combo } template -bool Combobox(const char* label, T* value, const std::vector& comboVector, +bool Combobox(std::string 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); + std::string trueLabel = label.substr(0, label.find("#")); + ImGui::PushID(label.c_str()); ImGui::BeginGroup(); ImGui::BeginDisabled(options.disabled); PushStyleCombobox(options.color); @@ -872,7 +875,7 @@ bool Combobox(const char* label, T* value, const std::vector& combo ImGui::AlignTextToFramePadding(); if (options.labelPosition != LabelPositions::None) { if (options.alignment == ComponentAlignments::Right) { - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); if (options.labelPosition == LabelPositions::Above) { ImGui::NewLine(); ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); @@ -883,7 +886,7 @@ bool Combobox(const char* label, T* value, const std::vector& combo } } else if (options.alignment == ComponentAlignments::Left) { if (options.labelPosition == LabelPositions::Above) { - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); } } } @@ -908,12 +911,12 @@ bool Combobox(const char* label, T* value, const std::vector& combo if (options.alignment == ComponentAlignments::Left) { if (options.labelPosition == LabelPositions::Near) { ImGui::SameLine(); - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); } 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); + ImGui::Text("%s", trueLabel.c_str()); } } } @@ -932,7 +935,7 @@ bool Combobox(const char* label, T* value, const std::vector& combo } template -bool Combobox(const char* label, T* value, const char* (&comboArray)[N], const ComboboxOptions& options = {}) { +bool Combobox(std::string label, T* value, const char* (&comboArray)[N], const ComboboxOptions& options = {}) { bool dirty = false; size_t currentValueIndex = static_cast(*value); if (currentValueIndex >= N) { @@ -940,7 +943,8 @@ bool Combobox(const char* label, T* value, const char* (&comboArray)[N], const C } std::string invisibleLabelStr = "##" + std::string(label); const char* invisibleLabel = invisibleLabelStr.c_str(); - ImGui::PushID(label); + std::string trueLabel = label.substr(0, label.find("#")); + ImGui::PushID(label.c_str()); ImGui::BeginGroup(); ImGui::BeginDisabled(options.disabled); PushStyleCombobox(options.color); @@ -959,7 +963,7 @@ bool Combobox(const char* label, T* value, const char* (&comboArray)[N], const C ImGui::AlignTextToFramePadding(); if (options.labelPosition != LabelPositions::None) { if (options.alignment == ComponentAlignments::Right) { - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); if (options.labelPosition == LabelPositions::Above) { ImGui::NewLine(); ImGui::SameLine(ImGui::GetContentRegionAvail().x - comboWidth); @@ -970,7 +974,7 @@ bool Combobox(const char* label, T* value, const char* (&comboArray)[N], const C } } else if (options.alignment == ComponentAlignments::Left) { if (options.labelPosition == LabelPositions::Above) { - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); } } } @@ -995,11 +999,11 @@ bool Combobox(const char* label, T* value, const char* (&comboArray)[N], const C if (options.alignment == ComponentAlignments::Left) { if (options.labelPosition == LabelPositions::Near) { ImGui::SameLine(); - ImGui::Text("%s", label); + ImGui::Text("%s", trueLabel.c_str()); } 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); + ImGui::Text("%s", trueLabel.c_str()); } } }