Entrance Tracker Display Options (#6193)

Add all window display options to Entrance Tracker.
Apply hidden label filtering to combobox labels.
Remove tracker prefixes from check and entrance tracker preset load functions.
Remove all references to the menu bar, and the menubar source and header files.
This commit is contained in:
Malkierian 2026-01-28 20:24:43 -07:00 committed by GitHub
parent 473a77bbb2
commit 8176e57144
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 679 additions and 721 deletions

View file

@ -86,11 +86,11 @@ void applyPreset(std::string presetName, std::vector<PresetSection> 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"]);
}
}

View file

@ -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) {

View file

@ -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);

View file

@ -41,10 +41,6 @@ extern std::vector<ItemTrackerItem> dungeonRewardMedallions;
extern std::vector<ItemTrackerItem> songItems;
extern std::vector<ItemTrackerItem> equipmentItems;
namespace SohGui {
extern std::shared_ptr<SohMenu> mSohMenu;
}
using json = nlohmann::json;
using namespace UIWidgets;
@ -177,11 +173,9 @@ std::unordered_map<RandomizerCheck, std::string> 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<uint32_t> 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<SceneID>(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<TrackerWindowType>(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<uint16_t>(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<uint16_t>(areaChecksGotten[rcArea]) << " / "
<< static_cast<uint16_t>(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<uint16_t>(areaChecksAvailable[rcArea]) << " / ";
areaTotalsTooltipSS << "Available / ";
}
areaTotalsSS << static_cast<uint16_t>(areaChecksGotten[rcArea]) << " / "
<< static_cast<uint16_t>(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<int32_t, const char*> windowType = { { TRACKER_WINDOW_FLOATING, "Floating" },
{ TRACKER_WINDOW_WINDOW, "Window" } };
static std::map<int32_t, const char*> displayType = { { 0, "Always" }, { 1, "Combo Button Hold" } };
static std::map<int32_t, const char*> 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"))

View file

@ -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

View file

@ -5,6 +5,7 @@
#include <string>
#include <vector>
#include <libultraship/controller/controldeck/ControlDeck.h>
#include <libultraship/libultraship.h>
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<LUS::ControlDeck>(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<EntranceOverride> 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<TrackerWindowType>(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<EntranceOverride> 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<GameInteractor::OnExitGame>(
[](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

View file

@ -5,6 +5,7 @@
#include <cstdint>
#include <libultraship/libultraship.h>
#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<int32_t, const char*> windowType = { { TRACKER_WINDOW_FLOATING, "Floating" },
{ TRACKER_WINDOW_WINDOW, "Window" } };
static std::map<int32_t, const char*> showMode = { { 0, "Always" }, { 1, "Combo Button Hold" } };
static std::map<int32_t, const char*> 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<uint32_t> 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

View file

@ -2016,23 +2016,6 @@ static std::map<int32_t, const char*> itemTrackerTriforcePieceTrackOptions = {
{ TRIFORCE_PIECE_COLLECTED_REQUIRED, "Collected / Required" },
{ TRIFORCE_PIECE_COLLECTED_REQUIRED_MAX, "Collected / Required / Max" },
};
static std::map<int32_t, const char*> windowTypes = {
{ TRACKER_WINDOW_FLOATING, "Floating" },
{ TRACKER_WINDOW_WINDOW, "Window" },
};
static std::map<int32_t, const char*> displayModes = {
{ TRACKER_DISPLAY_ALWAYS, "Always" },
{ TRACKER_DISPLAY_COMBO_BUTTON, "Combo Button Hold" },
};
static std::map<int32_t, const char*> 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<int32_t, const char*> 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;

View file

@ -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) {

View file

@ -19,7 +19,6 @@
#ifdef __SWITCH__
#include <port/switch/SwitchImpl.h>
#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<SohMenuBar> mSohMenuBar;
std::shared_ptr<Ship::GuiWindow> mConsoleWindow;
std::shared_ptr<SohStatsWindow> mStatsWindow;
std::shared_ptr<Ship::GuiWindow> mGfxDebuggerWindow;
@ -89,8 +86,8 @@ std::shared_ptr<MessageViewer> mMessageViewerWindow;
std::shared_ptr<GameplayStatsWindow> mGameplayStatsWindow;
std::shared_ptr<CheckTracker::CheckTrackerSettingsWindow> mCheckTrackerSettingsWindow;
std::shared_ptr<CheckTracker::CheckTrackerWindow> mCheckTrackerWindow;
std::shared_ptr<EntranceTrackerSettingsWindow> mEntranceTrackerSettingsWindow;
std::shared_ptr<EntranceTrackerWindow> mEntranceTrackerWindow;
std::shared_ptr<EntranceTracker::EntranceTrackerSettingsWindow> mEntranceTrackerSettingsWindow;
std::shared_ptr<EntranceTracker::EntranceTrackerWindow> mEntranceTrackerWindow;
std::shared_ptr<ItemTrackerSettingsWindow> mItemTrackerSettingsWindow;
std::shared_ptr<ItemTrackerWindow> mItemTrackerWindow;
std::shared_ptr<TimeSplitWindow> mTimeSplitWindow;
@ -104,6 +101,10 @@ UIWidgets::Colors GetMenuThemeColor() {
return mSohMenu->GetMenuThemeColor();
}
std::shared_ptr<SohMenu> GetSohMenu() {
return mSohMenu;
}
void SetupMenu() {
auto gui = Ship::Context::GetInstance()->GetWindow()->GetGui();
mSohMenu = std::make_shared<SohMenu>(CVAR_WINDOW("Menu"), "Port Menu");
@ -177,10 +178,10 @@ void SetupGuiElements() {
mCheckTrackerSettingsWindow = std::make_shared<CheckTracker::CheckTrackerSettingsWindow>(
CVAR_WINDOW("CheckTrackerSettings"), "Check Tracker Settings", ImVec2(600, 375));
gui->AddGuiWindow(mCheckTrackerSettingsWindow);
mEntranceTrackerWindow =
std::make_shared<EntranceTrackerWindow>(CVAR_WINDOW("EntranceTracker"), "Entrance Tracker", ImVec2(500, 750));
mEntranceTrackerWindow = std::make_shared<EntranceTracker::EntranceTrackerWindow>(
CVAR_WINDOW("EntranceTracker"), "Entrance Tracker", ImVec2(500, 750));
gui->AddGuiWindow(mEntranceTrackerWindow);
mEntranceTrackerSettingsWindow = std::make_shared<EntranceTrackerSettingsWindow>(
mEntranceTrackerSettingsWindow = std::make_shared<EntranceTracker::EntranceTrackerSettingsWindow>(
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;

View file

@ -9,7 +9,7 @@
#define SohGui_hpp
#include <stdio.h>
#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<SohMenu> GetSohMenu();
} // namespace SohGui
#define THEME_COLOR SohGui::GetMenuThemeColor()

View file

@ -1,104 +0,0 @@
#include "SohMenuBar.h"
#include <imgui.h>
#include "regex"
#include <libultraship/bridge/consolevariablebridge.h>
#include <libultraship/libultraship.h>
#include "UIWidgets.hpp"
#include "include/z64audio.h"
#include <fast/backends/gfx_rendering_api.h>
#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<Ship::WindowBackend, const char*> 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<Ship::WindowBackend, const char*> 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

View file

@ -1,17 +0,0 @@
#pragma once
#include <libultraship/libultraship.h>
#include <ship/window/gui/GuiMenuBar.h>
#include <ship/window/gui/GuiElement.h>
namespace SohGui {
class SohMenuBar : public Ship::GuiMenuBar {
public:
using Ship::GuiMenuBar::GuiMenuBar;
protected:
void DrawElement() override;
void InitElement() override;
void UpdateElement() override{};
};
} // namespace SohGui

View file

@ -681,13 +681,14 @@ void Separator(bool padTop = true, bool padBottom = true, float extraVerticalTop
float CalcComboWidth(const char* preview_value, ImGuiComboFlags flags);
template <typename T>
bool Combobox(const char* label, T* value, const std::map<T, const char*>& comboMap,
bool Combobox(std::string label, T* value, const std::map<T, const char*>& 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<T, const char*>& 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<T, const char*>& 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<T, const char*>& 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<T, const char*>& combo
}
template <typename T = size_t>
bool Combobox(const char* label, T* value, const std::vector<const char*>& comboVector,
bool Combobox(std::string label, T* value, const std::vector<const char*>& comboVector,
const ComboboxOptions& options = {}) {
bool dirty = false;
size_t currentValueIndex = static_cast<size_t>(*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<const char*>& 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<const char*>& 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<const char*>& 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<const char*>& combo
}
template <typename T = size_t>
bool Combobox(const char* label, T* value, const std::vector<std::string>& comboVector,
bool Combobox(std::string label, T* value, const std::vector<std::string>& comboVector,
const ComboboxOptions& options = {}) {
bool dirty = false;
size_t currentValueIndex = static_cast<size_t>(*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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& combo
}
template <typename T = size_t, size_t N>
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<size_t>(*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());
}
}
}