diff options
| author | KiritoDv <36680385+KiritoDv@users.noreply.github.com> | 2025-05-16 02:44:40 +0000 |
|---|---|---|
| committer | github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> | 2025-05-16 02:44:40 +0000 |
| commit | b53a5dbcfa24ef2aa4860b6d9512709976686de8 (patch) | |
| tree | 441f2bb9c0bc8f955eb9289d19b13beab5c239c5 /src/port/ui | |
| parent | bdf5ca8d603ae56ac275bebf9fde58ae72484d76 (diff) | |
clang formatclang-format
Diffstat (limited to 'src/port/ui')
| -rw-r--r-- | src/port/ui/ContentBrowser.cpp | 454 | ||||
| -rw-r--r-- | src/port/ui/ContentBrowser.h | 7 | ||||
| -rw-r--r-- | src/port/ui/FreecamWindow.cpp | 29 | ||||
| -rw-r--r-- | src/port/ui/FreecamWindow.h | 3 | ||||
| -rw-r--r-- | src/port/ui/ImguiUI.cpp | 623 | ||||
| -rw-r--r-- | src/port/ui/Menu.cpp | 14 | ||||
| -rw-r--r-- | src/port/ui/Menu.h | 15 | ||||
| -rw-r--r-- | src/port/ui/MenuTypes.h | 2 | ||||
| -rw-r--r-- | src/port/ui/MultiplayerWindow.cpp | 5 | ||||
| -rw-r--r-- | src/port/ui/MultiplayerWindow.h | 3 | ||||
| -rw-r--r-- | src/port/ui/PortMenu.cpp | 104 | ||||
| -rw-r--r-- | src/port/ui/PortMenu.h | 6 | ||||
| -rw-r--r-- | src/port/ui/Properties.cpp | 136 | ||||
| -rw-r--r-- | src/port/ui/Properties.h | 8 | ||||
| -rw-r--r-- | src/port/ui/ResolutionEditor.cpp | 18 | ||||
| -rw-r--r-- | src/port/ui/ResolutionEditor.h | 2 | ||||
| -rw-r--r-- | src/port/ui/SceneExplorer.cpp | 30 | ||||
| -rw-r--r-- | src/port/ui/SceneExplorer.h | 8 | ||||
| -rw-r--r-- | src/port/ui/Tools.cpp | 220 | ||||
| -rw-r--r-- | src/port/ui/Tools.h | 7 | ||||
| -rw-r--r-- | src/port/ui/TrackProperties.cpp | 490 | ||||
| -rw-r--r-- | src/port/ui/TrackProperties.h | 7 | ||||
| -rw-r--r-- | src/port/ui/UIWidgets.cpp | 16 | ||||
| -rw-r--r-- | src/port/ui/UIWidgets.h | 1323 |
24 files changed, 1809 insertions, 1721 deletions
diff --git a/src/port/ui/ContentBrowser.cpp b/src/port/ui/ContentBrowser.cpp index 826477ea5..fc6099eae 100644 --- a/src/port/ui/ContentBrowser.cpp +++ b/src/port/ui/ContentBrowser.cpp @@ -21,268 +21,282 @@ namespace Editor { - ContentBrowserWindow::~ContentBrowserWindow() { - SPDLOG_TRACE("destruct content browser window"); - } +ContentBrowserWindow::~ContentBrowserWindow() { + SPDLOG_TRACE("destruct content browser window"); +} - void ContentBrowserWindow::DrawElement() { - if (ImGui::Button(ICON_FA_REFRESH)) { - Refresh = true; - } +void ContentBrowserWindow::DrawElement() { + if (ImGui::Button(ICON_FA_REFRESH)) { + Refresh = true; + } - // Query content in o2r and add them to Content - if (Refresh) { - Refresh = false; - RemoveCustomTracksFromTrackList(); - Tracks.clear(); - Content.clear(); - FindTracks(); - FindContent(); - return; - } + // Query content in o2r and add them to Content + if (Refresh) { + Refresh = false; + RemoveCustomTracksFromTrackList(); + Tracks.clear(); + Content.clear(); + FindTracks(); + FindContent(); + return; + } - ImGui::BeginChild("LeftPanel", ImVec2(120, 0), true, ImGuiWindowFlags_None); - - ContentBrowserWindow::FolderButton("Tracks", TrackContent); - ContentBrowserWindow::FolderButton("Actors", ActorContent); - ContentBrowserWindow::FolderButton("Objects", ObjectContent); - ContentBrowserWindow::FolderButton("Custom", CustomContent); - ImGui::EndChild(); - ImGui::SameLine(); - ImGui::BeginChild("RightPanel", ImVec2(0, 0), true, ImGuiWindowFlags_None); - if (TrackContent) { - AddTrackContent(); - } + ImGui::BeginChild("LeftPanel", ImVec2(120, 0), true, ImGuiWindowFlags_None); + + ContentBrowserWindow::FolderButton("Tracks", TrackContent); + ContentBrowserWindow::FolderButton("Actors", ActorContent); + ContentBrowserWindow::FolderButton("Objects", ObjectContent); + ContentBrowserWindow::FolderButton("Custom", CustomContent); + ImGui::EndChild(); + ImGui::SameLine(); + ImGui::BeginChild("RightPanel", ImVec2(0, 0), true, ImGuiWindowFlags_None); + if (TrackContent) { + AddTrackContent(); + } - if (ActorContent) { - AddActorContent(); - } + if (ActorContent) { + AddActorContent(); + } - if (ObjectContent) { - AddObjectContent(); - } + if (ObjectContent) { + AddObjectContent(); + } - if (CustomContent) { - AddCustomContent(); - } - ImGui::EndChild(); + if (CustomContent) { + AddCustomContent(); } + ImGui::EndChild(); +} - void ContentBrowserWindow::FolderButton(const char* label, bool& contentFlag, const ImVec2& size) { - std::string buttonText = fmt::format("{0} {1}", contentFlag ? ICON_FA_FOLDER_OPEN_O : ICON_FA_FOLDER_O, label); - if (ImGui::Button(buttonText.c_str(), size)) { - TrackContent = false; - ActorContent = false; - ObjectContent = false; - CustomContent = false; - contentFlag = !contentFlag; - } +void ContentBrowserWindow::FolderButton(const char* label, bool& contentFlag, const ImVec2& size) { + std::string buttonText = fmt::format("{0} {1}", contentFlag ? ICON_FA_FOLDER_OPEN_O : ICON_FA_FOLDER_O, label); + if (ImGui::Button(buttonText.c_str(), size)) { + TrackContent = false; + ActorContent = false; + ObjectContent = false; + CustomContent = false; + contentFlag = !contentFlag; } +} - std::unordered_map<std::string, std::function<AActor*(const FVector&)>> ActorList = { - { "Mario Sign", [](const FVector& pos) { return new AMarioSign(pos); } }, - { "Wario Sign", [](const FVector& pos) { return new AWarioSign(pos); } }, - { "Cloud", [](const FVector& pos) { return new ACloud(pos); } }, - { "Finishline", [](const FVector& pos) { return new AFinishline(pos); } }, - { "Ghostship", [](const FVector& pos) { return new AShip(pos, AShip::Skin::GHOSTSHIP); } }, - { "Ship_1", [](const FVector& pos) { return new AShip(pos, AShip::Skin::SHIP2); } }, - { "Ship_2", [](const FVector& pos) { return new AShip(pos, AShip::Skin::SHIP3); } }, - { "SpaghettiShip", [](const FVector& pos) { return new ASpaghettiShip(pos); } }, - { "Starship", [](const FVector& pos) { return new AStarship(pos); } }, - { "Train", [](const FVector& pos) { return new ATrain(ATrain::TenderStatus::HAS_TENDER, 4, 2.5f, 0); } }, - { "Boat", [](const FVector& pos) { return new ABoat((0.6666666f)/4, 0); } }, - { "Bus", [](const FVector& pos) { return new ABus(2.0f, 2.5f, &D_80164550[0][0], 0); } }, - { "Car", [](const FVector& pos) { return new ACar(2.0f, 2.5f, &D_80164550[0][0], 0); } }, - { "Truck", [](const FVector& pos) { return new ATruck(2.0f, 2.5f, &D_80164550[0][0], 0); } }, - { "Tanker Truck", [](const FVector& pos) { return new ATankerTruck(2.0f, 2.5f, &D_80164550[0][0], 0); } }, - }; - - std::unordered_map<std::string, std::function<OObject*(const FVector&)>> ObjectList = { - { "Bat", [](const FVector& pos) { return new OBat(pos, IRotator(0, 0, 0)); } }, - { "Bomb Kart", [](const FVector& pos) { return new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); } }, - // { "Boos", [](const FVector& pos) { return new OBoos(pos, &D_80164550[0][0], 0, 0, 0.8333333f); } }, - { "CheepCheep", [](const FVector& pos) { return new OCheepCheep(pos, OCheepCheep::CheepType::RACE, IPathSpan(0, 10)); } }, - { "Crab", [](const FVector& pos) { return new OCrab(FVector2D(0, 10), FVector2D(20, 10)); } }, - { "ChainChomp", [](const FVector& pos) { return new OChainChomp(); } }, - { "Flagpole", [](const FVector& pos) { return new OFlagpole(pos, 0); } }, - { "Hedgehog", [](const FVector& pos) { return new OHedgehog(pos, FVector2D(0, 10), 0); } }, - { "HotAirBalloon", [](const FVector& pos) { return new OHotAirBalloon(pos); } }, - { "Lakitu", [](const FVector& pos) { return new OLakitu(0, OLakitu::LakituType::STARTER); } }, - // { "Mole", [](const FVector& pos) { return new OMole(pos, ); } }, // <-- Needs a group - { "Chick Penguin", [](const FVector& pos) { return new OPenguin(pos, 0, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE3); } }, - { "Penguin", [](const FVector& pos) { return new OPenguin(pos, 0, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); } }, - { "Emperor Penguin", [](const FVector& pos) { return new OPenguin(pos, 0, OPenguin::PenguinType::EMPEROR, OPenguin::Behaviour::STRUT); } }, - { "Seagull", [](const FVector& pos) { return new OSeagull(pos); } }, - { "Thwomp", [](const FVector& pos) { return new OThwomp(pos.x, pos.z, 0, 1.0f, 0, 0, 2.0f); } }, - { "Trashbin", [](const FVector& pos) { return new OTrashBin(pos, IRotator(0, 0, 0), 1.0f, OTrashBin::Behaviour::MUNCHING); } }, - { "Trophy", [](const FVector& pos) { return new OTrophy(pos, OTrophy::TrophyType::GOLD_150, OTrophy::Behaviour::ROTATE2); } }, - { "Snowman", [](const FVector& pos) { return new OSnowman(pos); } }, - { "Podium", [](const FVector& pos) { return new OPodium(pos); } }, - { "Balloons", [](const FVector& pos) { return new OGrandPrixBalloons(pos); } }, - }; - - void ContentBrowserWindow::AddTrackContent() { - size_t i_track = 0; - for (auto& track : Tracks) { - if (!track.SceneFile.empty()) { // has scene file - std::string label = fmt::format("{}##{}", track.Name, i_track); - if (ImGui::Button(label.c_str())) { - SetCourseByClass(track.course); - gGamestateNext = RACING; - SetSceneFile(track.Archive, track.SceneFile); - break; - } - } else { // no scene file - std::string label = fmt::format("{} {}", ICON_FA_EXCLAMATION_TRIANGLE, track.Name); - if (ImGui::Button(label.c_str())) { - track.SceneFile = track.Dir + "/scene.json"; - SetCourseByClass(track.course); - SetSceneFile(track.Archive, track.SceneFile); - SaveLevel(); - Refresh = true; - } +std::unordered_map<std::string, std::function<AActor*(const FVector&)>> ActorList = { + { "Mario Sign", [](const FVector& pos) { return new AMarioSign(pos); } }, + { "Wario Sign", [](const FVector& pos) { return new AWarioSign(pos); } }, + { "Cloud", [](const FVector& pos) { return new ACloud(pos); } }, + { "Finishline", [](const FVector& pos) { return new AFinishline(pos); } }, + { "Ghostship", [](const FVector& pos) { return new AShip(pos, AShip::Skin::GHOSTSHIP); } }, + { "Ship_1", [](const FVector& pos) { return new AShip(pos, AShip::Skin::SHIP2); } }, + { "Ship_2", [](const FVector& pos) { return new AShip(pos, AShip::Skin::SHIP3); } }, + { "SpaghettiShip", [](const FVector& pos) { return new ASpaghettiShip(pos); } }, + { "Starship", [](const FVector& pos) { return new AStarship(pos); } }, + { "Train", [](const FVector& pos) { return new ATrain(ATrain::TenderStatus::HAS_TENDER, 4, 2.5f, 0); } }, + { "Boat", [](const FVector& pos) { return new ABoat((0.6666666f) / 4, 0); } }, + { "Bus", [](const FVector& pos) { return new ABus(2.0f, 2.5f, &D_80164550[0][0], 0); } }, + { "Car", [](const FVector& pos) { return new ACar(2.0f, 2.5f, &D_80164550[0][0], 0); } }, + { "Truck", [](const FVector& pos) { return new ATruck(2.0f, 2.5f, &D_80164550[0][0], 0); } }, + { "Tanker Truck", [](const FVector& pos) { return new ATankerTruck(2.0f, 2.5f, &D_80164550[0][0], 0); } }, +}; + +std::unordered_map<std::string, std::function<OObject*(const FVector&)>> ObjectList = { + { "Bat", [](const FVector& pos) { return new OBat(pos, IRotator(0, 0, 0)); } }, + { "Bomb Kart", [](const FVector& pos) { return new OBombKart(pos, &D_80164550[0][0], 0, 0, 0.8333333f); } }, + // { "Boos", [](const FVector& pos) { return new OBoos(pos, &D_80164550[0][0], 0, 0, 0.8333333f); } }, + { "CheepCheep", + [](const FVector& pos) { return new OCheepCheep(pos, OCheepCheep::CheepType::RACE, IPathSpan(0, 10)); } }, + { "Crab", [](const FVector& pos) { return new OCrab(FVector2D(0, 10), FVector2D(20, 10)); } }, + { "ChainChomp", [](const FVector& pos) { return new OChainChomp(); } }, + { "Flagpole", [](const FVector& pos) { return new OFlagpole(pos, 0); } }, + { "Hedgehog", [](const FVector& pos) { return new OHedgehog(pos, FVector2D(0, 10), 0); } }, + { "HotAirBalloon", [](const FVector& pos) { return new OHotAirBalloon(pos); } }, + { "Lakitu", [](const FVector& pos) { return new OLakitu(0, OLakitu::LakituType::STARTER); } }, + // { "Mole", [](const FVector& pos) { return new OMole(pos, ); } }, // <-- Needs a group + { "Chick Penguin", + [](const FVector& pos) { + return new OPenguin(pos, 0, OPenguin::PenguinType::CHICK, OPenguin::Behaviour::SLIDE3); + } }, + { "Penguin", + [](const FVector& pos) { + return new OPenguin(pos, 0, OPenguin::PenguinType::ADULT, OPenguin::Behaviour::CIRCLE); + } }, + { "Emperor Penguin", + [](const FVector& pos) { + return new OPenguin(pos, 0, OPenguin::PenguinType::EMPEROR, OPenguin::Behaviour::STRUT); + } }, + { "Seagull", [](const FVector& pos) { return new OSeagull(pos); } }, + { "Thwomp", [](const FVector& pos) { return new OThwomp(pos.x, pos.z, 0, 1.0f, 0, 0, 2.0f); } }, + { "Trashbin", + [](const FVector& pos) { return new OTrashBin(pos, IRotator(0, 0, 0), 1.0f, OTrashBin::Behaviour::MUNCHING); } }, + { "Trophy", + [](const FVector& pos) { return new OTrophy(pos, OTrophy::TrophyType::GOLD_150, OTrophy::Behaviour::ROTATE2); } }, + { "Snowman", [](const FVector& pos) { return new OSnowman(pos); } }, + { "Podium", [](const FVector& pos) { return new OPodium(pos); } }, + { "Balloons", [](const FVector& pos) { return new OGrandPrixBalloons(pos); } }, +}; + +void ContentBrowserWindow::AddTrackContent() { + size_t i_track = 0; + for (auto& track : Tracks) { + if (!track.SceneFile.empty()) { // has scene file + std::string label = fmt::format("{}##{}", track.Name, i_track); + if (ImGui::Button(label.c_str())) { + SetCourseByClass(track.course); + gGamestateNext = RACING; + SetSceneFile(track.Archive, track.SceneFile); + break; + } + } else { // no scene file + std::string label = fmt::format("{} {}", ICON_FA_EXCLAMATION_TRIANGLE, track.Name); + if (ImGui::Button(label.c_str())) { + track.SceneFile = track.Dir + "/scene.json"; + SetCourseByClass(track.course); + SetSceneFile(track.Archive, track.SceneFile); + SaveLevel(); + Refresh = true; } - - i_track += 1; } + + i_track += 1; } +} - void ContentBrowserWindow::RemoveCustomTracksFromTrackList() { - for (auto& track : Tracks) { - auto it = gWorldInstance.Courses.begin(); - while (it != gWorldInstance.Courses.end()) { - if (track.course == *it) { - delete *it; - it = gWorldInstance.Courses.erase(it); - } else { - ++it; - } +void ContentBrowserWindow::RemoveCustomTracksFromTrackList() { + for (auto& track : Tracks) { + auto it = gWorldInstance.Courses.begin(); + while (it != gWorldInstance.Courses.end()) { + if (track.course == *it) { + delete *it; + it = gWorldInstance.Courses.erase(it); + } else { + ++it; } } } +} - void ContentBrowserWindow::AddActorContent() { - FVector pos = GetPositionAheadOfCamera(300.0f); +void ContentBrowserWindow::AddActorContent() { + FVector pos = GetPositionAheadOfCamera(300.0f); - size_t i_actor = 0; - for (const auto& actor : ActorList) { - if ((i_actor != 0) && (i_actor % 10 == 0)) { - } else { - ImGui::SameLine(); - } + size_t i_actor = 0; + for (const auto& actor : ActorList) { + if ((i_actor != 0) && (i_actor % 10 == 0)) { + } else { + ImGui::SameLine(); + } - std::string label = fmt::format("{}##{}", actor.first, i_actor); - if (ImGui::Button(label.c_str())) { - gWorldInstance.AddActor(actor.second(pos)); - } - i_actor += 1; + std::string label = fmt::format("{}##{}", actor.first, i_actor); + if (ImGui::Button(label.c_str())) { + gWorldInstance.AddActor(actor.second(pos)); } + i_actor += 1; } +} - void ContentBrowserWindow::AddObjectContent() { - FVector pos = GetPositionAheadOfCamera(300.0f); +void ContentBrowserWindow::AddObjectContent() { + FVector pos = GetPositionAheadOfCamera(300.0f); - size_t i_object = 0; - for (auto& object : ObjectList) { - if ((i_object != 0) && (i_object % 10 == 0)) { - } else { - ImGui::SameLine(); - } + size_t i_object = 0; + for (auto& object : ObjectList) { + if ((i_object != 0) && (i_object % 10 == 0)) { + } else { + ImGui::SameLine(); + } - std::string label = fmt::format("{}##{}", object.first, i_object); - if (ImGui::Button(label.c_str())) { - gWorldInstance.AddObject(object.second(pos)); - } - i_object += 1; + std::string label = fmt::format("{}##{}", object.first, i_object); + if (ImGui::Button(label.c_str())) { + gWorldInstance.AddObject(object.second(pos)); } + i_object += 1; } +} - void ContentBrowserWindow::AddCustomContent() { - FVector pos = GetPositionAheadOfCamera(300.0f); - - size_t i_custom = 0; - for (const auto& file : Content) { - if ((i_custom != 0) && (i_custom % 10 == 0)) { - } else { - ImGui::SameLine(); - } +void ContentBrowserWindow::AddCustomContent() { + FVector pos = GetPositionAheadOfCamera(300.0f); - std::string label = fmt::format("{}##{}", file, i_custom); - if (ImGui::Button(label.c_str())) { - int coll; - //printf("ContentBrowser.cpp: name: %s\n", test.c_str()); - std::string name = file.substr(file.find_last_of('/') + 1); - auto actor = gWorldInstance.AddStaticMeshActor(name, FVector(pos), IRotator(0, 0, 0), FVector(1, 1, 1), "__OTR__" + file, &coll); - // This is required because ptr gets cleaned up. - actor->Model = "__OTR__" + file; + size_t i_custom = 0; + for (const auto& file : Content) { + if ((i_custom != 0) && (i_custom % 10 == 0)) { + } else { + ImGui::SameLine(); + } - } - i_custom += 1; + std::string label = fmt::format("{}##{}", file, i_custom); + if (ImGui::Button(label.c_str())) { + int coll; + // printf("ContentBrowser.cpp: name: %s\n", test.c_str()); + std::string name = file.substr(file.find_last_of('/') + 1); + auto actor = gWorldInstance.AddStaticMeshActor(name, FVector(pos), IRotator(0, 0, 0), FVector(1, 1, 1), + "__OTR__" + file, &coll); + // This is required because ptr gets cleaned up. + actor->Model = "__OTR__" + file; } + i_custom += 1; } +} - // Finds modded archives only. For discovering tracks - void ContentBrowserWindow::FindTracks() { - auto manager = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager(); - - auto ptr2 = manager->ListDirectories("tracks/*"); - if (ptr2) { - auto dirs = *ptr2; - - for (const std::string& dir : dirs) { - std::string name = dir.substr(dir.find_last_of('/') + 1); - std::string sceneFile = dir + "/scene.json"; - std::string minimapFile = dir + "/minimap.png"; - if (manager->HasFile(sceneFile)) { - auto archive = manager->GetArchiveFromFile(sceneFile); - - Course* course = new Course(); - course->LoadO2R(dir); - gWorldInstance.Courses.push_back(course); - LoadLevel(archive, course, sceneFile); - LoadMinimap(archive, course, minimapFile); - Tracks.push_back({course, sceneFile, name, dir, archive}); - } else { - const std::string file = dir + "/data_track_sections"; - - if (manager->HasFile(file)) { +// Finds modded archives only. For discovering tracks +void ContentBrowserWindow::FindTracks() { + auto manager = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager(); + + auto ptr2 = manager->ListDirectories("tracks/*"); + if (ptr2) { + auto dirs = *ptr2; + + for (const std::string& dir : dirs) { + std::string name = dir.substr(dir.find_last_of('/') + 1); + std::string sceneFile = dir + "/scene.json"; + std::string minimapFile = dir + "/minimap.png"; + if (manager->HasFile(sceneFile)) { + auto archive = manager->GetArchiveFromFile(sceneFile); + + Course* course = new Course(); + course->LoadO2R(dir); + gWorldInstance.Courses.push_back(course); + LoadLevel(archive, course, sceneFile); + LoadMinimap(archive, course, minimapFile); + Tracks.push_back({ course, sceneFile, name, dir, archive }); + } else { + const std::string file = dir + "/data_track_sections"; - Course* course = new Course(); - course->Id = (std::string("mods:") + name).c_str(); - course->Props.SetText(course->Props.Name, name.c_str(), sizeof(course->Props.Name)); - course->Props.SetText(course->Props.DebugName, name.c_str(), sizeof(course->Props.Name)); + if (manager->HasFile(file)) { - auto archive = manager->GetArchiveFromFile(file); - Tracks.push_back({course, "", name, dir, archive}); - } else { - printf("ContentBrowser.cpp: Track '%s' missing required track files. Cannot add to game\n Missing %s/data_track_sections file\n", name.c_str(), dir.c_str()); - } + Course* course = new Course(); + course->Id = (std::string("mods:") + name).c_str(); + course->Props.SetText(course->Props.Name, name.c_str(), sizeof(course->Props.Name)); + course->Props.SetText(course->Props.DebugName, name.c_str(), sizeof(course->Props.Name)); + auto archive = manager->GetArchiveFromFile(file); + Tracks.push_back({ course, "", name, dir, archive }); + } else { + printf("ContentBrowser.cpp: Track '%s' missing required track files. Cannot add to game\n Missing " + "%s/data_track_sections file\n", + name.c_str(), dir.c_str()); } } } } +} - void ContentBrowserWindow::FindContent() { - auto ptr = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->ListFiles({"hmintro/*", "*tracks/*","actors/*", "objects/*"}, {""}); - if (ptr) { - auto files = *ptr; - for (const auto& file : files) { - if (file.find("/mat_") != std::string::npos) { - continue; - } else if (file.size() >= 6 && file.substr(file.size() - 6, 5) == "_tri_" && isdigit(file.back())) { - // ends with _tri_# - continue; - } else if (file.find("_vtx_") != std::string::npos) { - // Has _vtx_ - continue; - } else if (file.find('.') != std::string::npos) { - // File has an extension - continue; - } - - Content.push_back(file); +void ContentBrowserWindow::FindContent() { + auto ptr = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->ListFiles( + { "hmintro/*", "*tracks/*", "actors/*", "objects/*" }, { "" }); + if (ptr) { + auto files = *ptr; + for (const auto& file : files) { + if (file.find("/mat_") != std::string::npos) { + continue; + } else if (file.size() >= 6 && file.substr(file.size() - 6, 5) == "_tri_" && isdigit(file.back())) { + // ends with _tri_# + continue; + } else if (file.find("_vtx_") != std::string::npos) { + // Has _vtx_ + continue; + } else if (file.find('.') != std::string::npos) { + // File has an extension + continue; } + + Content.push_back(file); } } } +} // namespace Editor diff --git a/src/port/ui/ContentBrowser.h b/src/port/ui/ContentBrowser.h index f077f7283..ee8fd0d55 100644 --- a/src/port/ui/ContentBrowser.h +++ b/src/port/ui/ContentBrowser.h @@ -5,7 +5,7 @@ namespace Editor { class ContentBrowserWindow : public Ship::GuiWindow { -public: + public: using Ship::GuiWindow::GuiWindow; ~ContentBrowserWindow(); @@ -27,7 +27,8 @@ public: bool ObjectContent = false; bool CustomContent = false; bool TrackContent = false; -protected: + + protected: void InitElement() override {}; void DrawElement() override; void UpdateElement() override {}; @@ -40,4 +41,4 @@ protected: void FindContent(); void FolderButton(const char* label, bool& contentFlag, const ImVec2& size = ImVec2(80, 32)); }; -} +} // namespace Editor diff --git a/src/port/ui/FreecamWindow.cpp b/src/port/ui/FreecamWindow.cpp index 162bc4421..a1a335250 100644 --- a/src/port/ui/FreecamWindow.cpp +++ b/src/port/ui/FreecamWindow.cpp @@ -40,7 +40,7 @@ namespace Freecam { static s32 sReadyUpBool = false; int32_t controllerType = 0; -std::unordered_map<int32_t, const char*> controlType = {{ 0, "Mouse/Keyboard" }, { 1, "Controller" }}; +std::unordered_map<int32_t, const char*> controlType = { { 0, "Mouse/Keyboard" }, { 1, "Controller" } }; uint32_t focusPlayer; @@ -51,23 +51,29 @@ bool IsPlayerValid(const char* string) { void RegisterFreecamWidgets() { mPortMenu->AddSidebarEntry("Enhancements", "Freecam", 2); WidgetPath path = { "Enhancements", "Freecam", SECTION_COLUMN_1 }; - //const float framerate = ImGui::GetIO().Framerate; - //const float deltatime = ImGui::GetIO().DeltaTime; - //ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); + // const float framerate = ImGui::GetIO().Framerate; + // const float deltatime = ImGui::GetIO().DeltaTime; + // ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(0, 0, 0, 0)); - //mPortMenu->AddWidget(path, "Controller mode is not configured yet.", WIDGET_TEXT); + // mPortMenu->AddWidget(path, "Controller mode is not configured yet.", WIDGET_TEXT); - //static int current_item = 0; + // static int current_item = 0; mPortMenu->AddWidget(path, "Human Interface Device", WIDGET_COMBOBOX) .ValuePointer(&controllerType) - .Callback([](WidgetInfo& info) { bFreecamUseController = (uint32_t)*std::get<int32_t*>(info.valuePointer); }) + .Callback([](WidgetInfo& info) { bFreecamUseController = (uint32_t) *std::get<int32_t*>(info.valuePointer); }) .Options(UIWidgets::ComboboxOptions().ComboMap(controlType)); - mPortMenu->AddWidget(path, "Keyboard: Move: W,A,S,D, Up: Space, Down: Shift\n Faster: Ctrl, Look: Right-mouse button\n Target Player Mode: F, Next: M, Previous: N", WIDGET_TEXT); - mPortMenu->AddWidget(path, "Controller: Up: A, Down: B, Faster: Z\n Target Player Mode: R, Next: Right DPad, Previous: Left DPad\n Driving Mode: L and R Buttons", WIDGET_TEXT); + mPortMenu->AddWidget(path, + "Keyboard: Move: W,A,S,D, Up: Space, Down: Shift\n Faster: Ctrl, Look: Right-mouse button\n " + "Target Player Mode: F, Next: M, Previous: N", + WIDGET_TEXT); + mPortMenu->AddWidget(path, + "Controller: Up: A, Down: B, Faster: Z\n Target Player Mode: R, Next: Right DPad, Previous: " + "Left DPad\n Driving Mode: L and R Buttons", + WIDGET_TEXT); mPortMenu->AddWidget(path, "Enable Freecam", WIDGET_CVAR_CHECKBOX) .CVar("gFreecam") - .Options(UIWidgets::CheckboxOptions({{ .tooltip = "Allows you to fly around the course"}})); + .Options(UIWidgets::CheckboxOptions({ { .tooltip = "Allows you to fly around the course" } })); mPortMenu->AddWidget(path, "Camera Damping", WIDGET_SLIDER_FLOAT) .ValuePointer(&gDampValue) @@ -86,8 +92,7 @@ void RegisterFreecamWidgets() { .Options(UIWidgets::FloatSliderOptions().Min(0.0f).Max(1.0f).Step(0.01f).Format("%.2f")); mPortMenu->AddWidget(path, "Target Player", WIDGET_TEXT); - mPortMenu->AddWidget(path, "None", WIDGET_BUTTON) - .Callback([](WidgetInfo& info) { fTargetPlayer = false; }); + mPortMenu->AddWidget(path, "None", WIDGET_BUTTON).Callback([](WidgetInfo& info) { fTargetPlayer = false; }); mPortMenu->AddWidget(path, "Player 1", WIDGET_BUTTON) .PreFunc([](WidgetInfo& info) { diff --git a/src/port/ui/FreecamWindow.h b/src/port/ui/FreecamWindow.h index 4418b8d61..7a558e71f 100644 --- a/src/port/ui/FreecamWindow.h +++ b/src/port/ui/FreecamWindow.h @@ -2,5 +2,4 @@ #include <libultraship/libultraship.h> -namespace Freecam { -} // namespace Freecam +namespace Freecam {} // namespace Freecam diff --git a/src/port/ui/ImguiUI.cpp b/src/port/ui/ImguiUI.cpp index 237e8d27f..d21587566 100644 --- a/src/port/ui/ImguiUI.cpp +++ b/src/port/ui/ImguiUI.cpp @@ -21,10 +21,10 @@ #include "PortMenu.h" extern "C" { - extern s32 gGamestateNext; - extern s32 gMenuSelection; - #include "audio/external.h" - #include "defines.h" +extern s32 gGamestateNext; +extern s32 gMenuSelection; +#include "audio/external.h" +#include "defines.h" } namespace GameUI { @@ -50,10 +50,10 @@ void SetupGuiElements() { mPortMenu = std::make_shared<PortMenu>("gOpenMenu", "Port Menu"); gui->SetMenu(mPortMenu); - //mMultiplayerWindow = gui->GetGuiWindow("Multiplayer"); - //if (mMultiplayerWindow == nullptr) { - // SPDLOG_ERROR("Could not find multiplayer window"); - //} + // mMultiplayerWindow = gui->GetGuiWindow("Multiplayer"); + // if (mMultiplayerWindow == nullptr) { + // SPDLOG_ERROR("Could not find multiplayer window"); + // } mStatsWindow = gui->GetGuiWindow("Stats"); if (mStatsWindow == nullptr) { @@ -77,7 +77,7 @@ void SetupGuiElements() { } mToolsWindow = std::make_shared<Editor::ToolsWindow>("gEditorEnabled", "Tools", ImVec2(100, 100), - (ImGuiWindowFlags_NoTitleBar)); + (ImGuiWindowFlags_NoTitleBar)); gui->AddGuiWindow(mToolsWindow); mSceneExplorerWindow = std::make_shared<Editor::SceneExplorerWindow>("gEditorEnabled", "Scene Explorer"); @@ -89,8 +89,7 @@ void SetupGuiElements() { mTrackPropertiesWindow = std::make_shared<Editor::TrackPropertiesWindow>("gEditorEnabled", "Track Properties"); gui->AddGuiWindow(mTrackPropertiesWindow); - mContentBrowserWindow = - std::make_shared<Editor::ContentBrowserWindow>("gEditorEnabled", "Content Browser"); + mContentBrowserWindow = std::make_shared<Editor::ContentBrowserWindow>("gEditorEnabled", "Content Browser"); gui->AddGuiWindow(mContentBrowserWindow); } @@ -128,294 +127,308 @@ static const char* filters[3] = { }; void DrawSettingsMenu() { -// if (UIWidgets::BeginMenu("Settings")) { -// if (UIWidgets::BeginMenu("Audio")) { -// UIWidgets::CVarSliderFloat("Master Volume", "gGameMasterVolume", 0.0f, 1.0f, 1.0f, { -// .format = "%.0f%%", -// .isPercentage = true, -// }); -// if (UIWidgets::CVarSliderFloat("Main Music Volume", "gMainMusicVolume", 0.0f, 1.0f, 1.0f, -// { -// .format = "%.0f%%", -// .isPercentage = true, -// })) { -// audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f)); -// } -// if (UIWidgets::CVarSliderFloat("Sound Effects Volume", "gSFXMusicVolume", -// 0.0f, 1.0f, 1.0f, { -// .format = "%.0f%%", -// .isPercentage = true, -// })) { -// audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f)); -// } -// if (UIWidgets::CVarSliderFloat("Environment Volume", "gEnvironmentVolume", -// 0.0f, 1.0f, 1.0f, { -// .format = "%.0f%%", -// .isPercentage = true, -// })) { -// audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f)); -// } -// -// static std::unordered_map<Ship::AudioBackend, const char*> audioBackendNames = { -// { Ship::AudioBackend::WASAPI, "Windows Audio Session API" }, -// { Ship::AudioBackend::SDL, "SDL" }, -// }; -// -// ImGui::Text("Audio API (Needs reload)"); -// auto currentAudioBackend = Ship::Context::GetInstance()->GetAudio()->GetCurrentAudioBackend(); -// -// if (Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) { -// UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); -// } -// if (ImGui::BeginCombo("##AApi", audioBackendNames[currentAudioBackend])) { -// for (uint8_t i = 0; i < -// Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size(); i++) { -// auto backend = Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->data()[i]; -// if (ImGui::Selectable(audioBackendNames[backend], backend == currentAudioBackend)) { -// Ship::Context::GetInstance()->GetAudio()->SetCurrentAudioBackend(backend); -// } -// } -// ImGui::EndCombo(); -// } -// if (Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) { -// UIWidgets::ReEnableComponent(""); -// } -// -// ImGui::EndMenu(); -// } -// -// UIWidgets::Spacer(0); -// -// if (UIWidgets::BeginMenu("Controller")) { -// UIWidgets::WindowButton("Controller Mapping", "gInputEditorWindow", GameUI::mInputEditorWindow); -// -// UIWidgets::Spacer(0); -// -//#ifndef __SWITCH__ -// UIWidgets::CVarCheckbox( -// "Menubar Controller Navigation", "gControlNav", -// { .tooltip = "Allows controller navigation of the SOH menu bar (Settings, Enhancements,...)\nCAUTION: " -// "This will disable game inputs while the menubar is visible.\n\nD-pad to move between " -// "items, A to select, and X to grab focus on the menu bar" }); -//#endif -// UIWidgets::CVarCheckbox("Show Inputs", "gInputEnabled", -// { .tooltip = "Shows currently pressed inputs on the bottom right of the screen" }); -// if (CVarGetInteger("gInputEnabled", 0)) { -// UIWidgets::CVarSliderFloat( -// "Input Scale", "gInputScale", 1.0f, 3.0f, 1.0f, -// { -// .tooltip = "Sets the on screen size of the displayed inputs from the Show Inputs setting", -// .format = "%.1fx", -// }); -// } -// -// ImGui::EndMenu(); -// } -// -// ImGui::EndMenu(); -// } -// -// ImGui::SetCursorPosY(0.0f); -// if (UIWidgets::BeginMenu("Graphics")) { -// UIWidgets::WindowButton("Resolution Editor", "gAdvancedResolutionEditorEnabled", -// GameUI::mAdvancedResolutionSettingsWindow); -// -// UIWidgets::Spacer(0); -// -// // Previously was running every frame, and nothing was setting it? Maybe a bad copy/paste? -// // Ship::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(CVarGetFloat("gInternalResolution", 1)); -// // UIWidgets::Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but -// // effective form of anti-aliasing"); -//#ifndef __WIIU__ -// if (UIWidgets::CVarSliderInt( -// "MSAA: %d", "gMSAAValue", 1, 8, 1, -// { .tooltip = -// "Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel" })) { -// Ship::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger("gMSAAValue", 1)); -// } -//#endif -// -// { // FPS Slider -// const int minFps = 30; -// static int maxFps; -// if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == -// Ship::WindowBackend::FAST3D_DXGI_DX11) { -// maxFps = 360; -// } else { -// maxFps = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); -// } -// int currentFps = 0; -//#ifdef __WIIU__ -// UIWidgets::Spacer(0); -// // only support divisors of 60 on the Wii U -// if (currentFps > 60) { -// currentFps = 60; -// } else { -// currentFps = 60 / (60 / currentFps); -// } -// -// int fpsSlider = 1; -// if (currentFps == 30) { -// ImGui::Text("FPS: Original (30)"); -// } else { -// ImGui::Text("FPS: %d", currentFps); -// if (currentFps == 30) { -// fpsSlider = 2; -// } else { // currentFps == 60 -// fpsSlider = 3; -// } -// } -// if (CVarGetInteger("gMatchRefreshRate", 0)) { -// UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); -// } -// -// if (ImGui::Button(" - ##WiiUFPS")) { -// fpsSlider--; -// } -// ImGui::SameLine(); -// ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); -// -// UIWidgets::Spacer(0); -// -// ImGui::PushItemWidth(std::min((ImGui::GetContentRegionAvail().x - 60.0f), 260.0f)); -// ImGui::SliderInt("##WiiUFPSSlider", &fpsSlider, 1, 3, "", ImGuiSliderFlags_AlwaysClamp); -// ImGui::PopItemWidth(); -// -// ImGui::SameLine(); -// ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); -// if (ImGui::Button(" + ##WiiUFPS")) { -// fpsSlider++; -// } -// -// if (CVarGetInteger("gMatchRefreshRate", 0)) { -// UIWidgets::ReEnableComponent(""); -// } -// if (fpsSlider > 3) { -// fpsSlider = 3; -// } else if (fpsSlider < 1) { -// fpsSlider = 1; -// } -// -// if (fpsSlider == 1) { -// currentFps = 20; -// } else if (fpsSlider == 2) { -// currentFps = 30; -// } else if (fpsSlider == 3) { -// currentFps = 60; -// } -// CVarSetInteger("gInterpolationFPS", currentFps); -// Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); -//#else -// bool matchingRefreshRate = -// CVarGetInteger("gMatchRefreshRate", 0) && -// Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() != Ship::WindowBackend::FAST3D_DXGI_DX11; -// UIWidgets::CVarSliderInt((currentFps == 20) ? "FPS: Original (20)" : "FPS: %d", "gInterpolationFPS", minFps, -// maxFps, 1, { .disabled = matchingRefreshRate }); -//#endif -// if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == -// Ship::WindowBackend::FAST3D_DXGI_DX11) { -// UIWidgets::Tooltip( -// "Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. " -// "This is purely " -// "visual and does not impact game logic, execution of glitches etc.\n\n" -// "A higher target FPS than your monitor's refresh rate will waste resources, and might give a worse " -// "result."); -// } else { -// UIWidgets::Tooltip( -// "Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is purely " -// "visual and does not impact game logic, execution of glitches etc."); -// } -// } // END FPS Slider -// -// if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { -// UIWidgets::Spacer(0); -// if (ImGui::Button("Match Refresh Rate")) { -// int hz = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); -// if (hz >= 30 && hz <= 360) { -// CVarSetInteger("gInterpolationFPS", hz); -// Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); -// } -// } -// } else { -// UIWidgets::PaddedEnhancementCheckbox("Match Refresh Rate", "gMatchRefreshRate", true, false); -// } -// -// UIWidgets::Tooltip("Matches interpolation value to the current game's window refresh rate"); -// -// if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { -// UIWidgets::PaddedEnhancementSliderInt( -// CVarGetInteger("gExtraLatencyThreshold", 0) == 0 ? "Jitter fix: Off" : "Jitter fix: >= %d FPS", -// "##ExtraLatencyThreshold", "gExtraLatencyThreshold", 0, 360, "", 0, true, true, false); -// UIWidgets::Tooltip("When Interpolation FPS setting is at least this threshold, add one frame of input lag " -// "(e.g. 16.6 ms for 60 FPS) in order to avoid jitter. This setting allows the CPU to " -// "work on one frame while GPU works on the previous frame.\nThis setting should be used " -// "when your computer is too slow to do CPU + GPU work in time."); -// } -// -// UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); -// -// 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" }, -// }; -// -// ImGui::Text("Renderer API (Needs reload)"); -// Ship::WindowBackend runningWindowBackend = Ship::Context::GetInstance()->GetWindow()->GetWindowBackend(); -// Ship::WindowBackend configWindowBackend; -// int configWindowBackendId = Ship::Context::GetInstance()->GetConfig()->GetInt("Window.Backend.Id", -1); -// if (Ship::Context::GetInstance()->GetWindow()->IsAvailableWindowBackend(configWindowBackendId)) { -// configWindowBackend = static_cast<Ship::WindowBackend>(configWindowBackendId); -// } else { -// configWindowBackend = runningWindowBackend; -// } -// -// if (Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) { -// UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); -// } -// if (ImGui::BeginCombo("##RApi", windowBackendNames[configWindowBackend])) { -// for (size_t i = 0; i < Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size(); -// i++) { -// auto backend = Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->data()[i]; -// if (ImGui::Selectable(windowBackendNames[backend], backend == configWindowBackend)) { -// Ship::Context::GetInstance()->GetConfig()->SetInt("Window.Backend.Id", static_cast<int>(backend)); -// Ship::Context::GetInstance()->GetConfig()->SetString("Window.Backend.Name", -// windowBackendNames[backend]); -// Ship::Context::GetInstance()->GetConfig()->Save(); -// } -// } -// ImGui::EndCombo(); -// } -// if (Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) { -// UIWidgets::ReEnableComponent(""); -// } -// -// if (Ship::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) { -// UIWidgets::PaddedEnhancementCheckbox("Enable Vsync", "gVsyncEnabled", true, false); -// } -// -// if (Ship::Context::GetInstance()->GetWindow()->SupportsWindowedFullscreen()) { -// UIWidgets::PaddedEnhancementCheckbox("Windowed fullscreen", "gSdlWindowedFullscreen", true, false); -// } -// -// if (Ship::Context::GetInstance()->GetWindow()->GetGui()->SupportsViewports()) { -// UIWidgets::PaddedEnhancementCheckbox("Allow multi-windows", "gEnableMultiViewports", true, false, false, "", -// UIWidgets::CheckboxGraphics::Cross, true); -// UIWidgets::Tooltip("Allows windows to be able to be dragged off of the main game window. Requires a reload " -// "to take effect."); -// } -// -// // If more filters are added to LUS, make sure to add them to the filters list here -// ImGui::Text("Texture Filter (Needs reload)"); -// -// UIWidgets::EnhancementCombobox("gTextureFilter", filters, 0); -// -// UIWidgets::Spacer(0); -// -// Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->DrawSettings(); -// -// ImGui::EndMenu(); -// } + // if (UIWidgets::BeginMenu("Settings")) { + // if (UIWidgets::BeginMenu("Audio")) { + // UIWidgets::CVarSliderFloat("Master Volume", "gGameMasterVolume", 0.0f, 1.0f, 1.0f, { + // .format = "%.0f%%", + // .isPercentage = true, + // }); + // if (UIWidgets::CVarSliderFloat("Main Music Volume", "gMainMusicVolume", 0.0f, 1.0f, 1.0f, + // { + // .format = "%.0f%%", + // .isPercentage = true, + // })) { + // audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f)); + // } + // if (UIWidgets::CVarSliderFloat("Sound Effects Volume", "gSFXMusicVolume", + // 0.0f, 1.0f, 1.0f, { + // .format = "%.0f%%", + // .isPercentage = true, + // })) { + // audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f)); + // } + // if (UIWidgets::CVarSliderFloat("Environment Volume", "gEnvironmentVolume", + // 0.0f, 1.0f, 1.0f, { + // .format = "%.0f%%", + // .isPercentage = true, + // })) { + // audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f)); + // } + // + // static std::unordered_map<Ship::AudioBackend, const char*> audioBackendNames = { + // { Ship::AudioBackend::WASAPI, "Windows Audio Session API" }, + // { Ship::AudioBackend::SDL, "SDL" }, + // }; + // + // ImGui::Text("Audio API (Needs reload)"); + // auto currentAudioBackend = Ship::Context::GetInstance()->GetAudio()->GetCurrentAudioBackend(); + // + // if (Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) { + // UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); + // } + // if (ImGui::BeginCombo("##AApi", audioBackendNames[currentAudioBackend])) { + // for (uint8_t i = 0; i < + // Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size(); i++) { + // auto backend = + // Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->data()[i]; if + // (ImGui::Selectable(audioBackendNames[backend], backend == currentAudioBackend)) { + // Ship::Context::GetInstance()->GetAudio()->SetCurrentAudioBackend(backend); + // } + // } + // ImGui::EndCombo(); + // } + // if (Ship::Context::GetInstance()->GetAudio()->GetAvailableAudioBackends()->size() <= 1) { + // UIWidgets::ReEnableComponent(""); + // } + // + // ImGui::EndMenu(); + // } + // + // UIWidgets::Spacer(0); + // + // if (UIWidgets::BeginMenu("Controller")) { + // UIWidgets::WindowButton("Controller Mapping", "gInputEditorWindow", GameUI::mInputEditorWindow); + // + // UIWidgets::Spacer(0); + // + // #ifndef __SWITCH__ + // UIWidgets::CVarCheckbox( + // "Menubar Controller Navigation", "gControlNav", + // { .tooltip = "Allows controller navigation of the SOH menu bar (Settings, + // Enhancements,...)\nCAUTION: " + // "This will disable game inputs while the menubar is visible.\n\nD-pad to move between + // " "items, A to select, and X to grab focus on the menu bar" }); + // #endif + // UIWidgets::CVarCheckbox("Show Inputs", "gInputEnabled", + // { .tooltip = "Shows currently pressed inputs on the bottom right of the + // screen" }); + // if (CVarGetInteger("gInputEnabled", 0)) { + // UIWidgets::CVarSliderFloat( + // "Input Scale", "gInputScale", 1.0f, 3.0f, 1.0f, + // { + // .tooltip = "Sets the on screen size of the displayed inputs from the Show Inputs setting", + // .format = "%.1fx", + // }); + // } + // + // ImGui::EndMenu(); + // } + // + // ImGui::EndMenu(); + // } + // + // ImGui::SetCursorPosY(0.0f); + // if (UIWidgets::BeginMenu("Graphics")) { + // UIWidgets::WindowButton("Resolution Editor", "gAdvancedResolutionEditorEnabled", + // GameUI::mAdvancedResolutionSettingsWindow); + // + // UIWidgets::Spacer(0); + // + // // Previously was running every frame, and nothing was setting it? Maybe a bad copy/paste? + // // Ship::Context::GetInstance()->GetWindow()->SetResolutionMultiplier(CVarGetFloat("gInternalResolution", + // 1)); + // // UIWidgets::Tooltip("Multiplies your output resolution by the value inputted, as a more intensive but + // // effective form of anti-aliasing"); + // #ifndef __WIIU__ + // if (UIWidgets::CVarSliderInt( + // "MSAA: %d", "gMSAAValue", 1, 8, 1, + // { .tooltip = + // "Activates multi-sample anti-aliasing when above 1x up to 8x for 8 samples for every pixel" + // })) { + // Ship::Context::GetInstance()->GetWindow()->SetMsaaLevel(CVarGetInteger("gMSAAValue", 1)); + // } + // #endif + // + // { // FPS Slider + // const int minFps = 30; + // static int maxFps; + // if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == + // Ship::WindowBackend::FAST3D_DXGI_DX11) { + // maxFps = 360; + // } else { + // maxFps = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); + // } + // int currentFps = 0; + // #ifdef __WIIU__ + // UIWidgets::Spacer(0); + // // only support divisors of 60 on the Wii U + // if (currentFps > 60) { + // currentFps = 60; + // } else { + // currentFps = 60 / (60 / currentFps); + // } + // + // int fpsSlider = 1; + // if (currentFps == 30) { + // ImGui::Text("FPS: Original (30)"); + // } else { + // ImGui::Text("FPS: %d", currentFps); + // if (currentFps == 30) { + // fpsSlider = 2; + // } else { // currentFps == 60 + // fpsSlider = 3; + // } + // } + // if (CVarGetInteger("gMatchRefreshRate", 0)) { + // UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); + // } + // + // if (ImGui::Button(" - ##WiiUFPS")) { + // fpsSlider--; + // } + // ImGui::SameLine(); + // ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + // + // UIWidgets::Spacer(0); + // + // ImGui::PushItemWidth(std::min((ImGui::GetContentRegionAvail().x - 60.0f), 260.0f)); + // ImGui::SliderInt("##WiiUFPSSlider", &fpsSlider, 1, 3, "", ImGuiSliderFlags_AlwaysClamp); + // ImGui::PopItemWidth(); + // + // ImGui::SameLine(); + // ImGui::SetCursorPosX(ImGui::GetCursorPosX() - 7.0f); + // if (ImGui::Button(" + ##WiiUFPS")) { + // fpsSlider++; + // } + // + // if (CVarGetInteger("gMatchRefreshRate", 0)) { + // UIWidgets::ReEnableComponent(""); + // } + // if (fpsSlider > 3) { + // fpsSlider = 3; + // } else if (fpsSlider < 1) { + // fpsSlider = 1; + // } + // + // if (fpsSlider == 1) { + // currentFps = 20; + // } else if (fpsSlider == 2) { + // currentFps = 30; + // } else if (fpsSlider == 3) { + // currentFps = 60; + // } + // CVarSetInteger("gInterpolationFPS", currentFps); + // Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + // #else + // bool matchingRefreshRate = + // CVarGetInteger("gMatchRefreshRate", 0) && + // Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() != + // Ship::WindowBackend::FAST3D_DXGI_DX11; + // UIWidgets::CVarSliderInt((currentFps == 20) ? "FPS: Original (20)" : "FPS: %d", "gInterpolationFPS", + // minFps, + // maxFps, 1, { .disabled = matchingRefreshRate }); + // #endif + // if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == + // Ship::WindowBackend::FAST3D_DXGI_DX11) { + // UIWidgets::Tooltip( + // "Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. " + // "This is purely " + // "visual and does not impact game logic, execution of glitches etc.\n\n" + // "A higher target FPS than your monitor's refresh rate will waste resources, and might give a + // worse " "result."); + // } else { + // UIWidgets::Tooltip( + // "Uses Matrix Interpolation to create extra frames, resulting in smoother graphics. This is + // purely " "visual and does not impact game logic, execution of glitches etc."); + // } + // } // END FPS Slider + // + // if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == + // Ship::WindowBackend::FAST3D_DXGI_DX11) { + // UIWidgets::Spacer(0); + // if (ImGui::Button("Match Refresh Rate")) { + // int hz = Ship::Context::GetInstance()->GetWindow()->GetCurrentRefreshRate(); + // if (hz >= 30 && hz <= 360) { + // CVarSetInteger("gInterpolationFPS", hz); + // Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + // } + // } + // } else { + // UIWidgets::PaddedEnhancementCheckbox("Match Refresh Rate", "gMatchRefreshRate", true, false); + // } + // + // UIWidgets::Tooltip("Matches interpolation value to the current game's window refresh rate"); + // + // if (Ship::Context::GetInstance()->GetWindow()->GetWindowBackend() == + // Ship::WindowBackend::FAST3D_DXGI_DX11) { + // UIWidgets::PaddedEnhancementSliderInt( + // CVarGetInteger("gExtraLatencyThreshold", 0) == 0 ? "Jitter fix: Off" : "Jitter fix: >= %d FPS", + // "##ExtraLatencyThreshold", "gExtraLatencyThreshold", 0, 360, "", 0, true, true, false); + // UIWidgets::Tooltip("When Interpolation FPS setting is at least this threshold, add one frame of input + // lag " + // "(e.g. 16.6 ms for 60 FPS) in order to avoid jitter. This setting allows the CPU to + // " "work on one frame while GPU works on the previous frame.\nThis setting should be + // used " "when your computer is too slow to do CPU + GPU work in time."); + // } + // + // UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); + // + // 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" }, + // }; + // + // ImGui::Text("Renderer API (Needs reload)"); + // Ship::WindowBackend runningWindowBackend = Ship::Context::GetInstance()->GetWindow()->GetWindowBackend(); + // Ship::WindowBackend configWindowBackend; + // int configWindowBackendId = Ship::Context::GetInstance()->GetConfig()->GetInt("Window.Backend.Id", -1); + // if (Ship::Context::GetInstance()->GetWindow()->IsAvailableWindowBackend(configWindowBackendId)) { + // configWindowBackend = static_cast<Ship::WindowBackend>(configWindowBackendId); + // } else { + // configWindowBackend = runningWindowBackend; + // } + // + // if (Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) { + // UIWidgets::DisableComponent(ImGui::GetStyle().Alpha * 0.5f); + // } + // if (ImGui::BeginCombo("##RApi", windowBackendNames[configWindowBackend])) { + // for (size_t i = 0; i < + // Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size(); + // i++) { + // auto backend = Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->data()[i]; + // if (ImGui::Selectable(windowBackendNames[backend], backend == configWindowBackend)) { + // Ship::Context::GetInstance()->GetConfig()->SetInt("Window.Backend.Id", + // static_cast<int>(backend)); + // Ship::Context::GetInstance()->GetConfig()->SetString("Window.Backend.Name", + // windowBackendNames[backend]); + // Ship::Context::GetInstance()->GetConfig()->Save(); + // } + // } + // ImGui::EndCombo(); + // } + // if (Ship::Context::GetInstance()->GetWindow()->GetAvailableWindowBackends()->size() <= 1) { + // UIWidgets::ReEnableComponent(""); + // } + // + // if (Ship::Context::GetInstance()->GetWindow()->CanDisableVerticalSync()) { + // UIWidgets::PaddedEnhancementCheckbox("Enable Vsync", "gVsyncEnabled", true, false); + // } + // + // if (Ship::Context::GetInstance()->GetWindow()->SupportsWindowedFullscreen()) { + // UIWidgets::PaddedEnhancementCheckbox("Windowed fullscreen", "gSdlWindowedFullscreen", true, false); + // } + // + // if (Ship::Context::GetInstance()->GetWindow()->GetGui()->SupportsViewports()) { + // UIWidgets::PaddedEnhancementCheckbox("Allow multi-windows", "gEnableMultiViewports", true, false, + // false, "", + // UIWidgets::CheckboxGraphics::Cross, true); + // UIWidgets::Tooltip("Allows windows to be able to be dragged off of the main game window. Requires a + // reload " + // "to take effect."); + // } + // + // // If more filters are added to LUS, make sure to add them to the filters list here + // ImGui::Text("Texture Filter (Needs reload)"); + // + // UIWidgets::EnhancementCombobox("gTextureFilter", filters, 0); + // + // UIWidgets::Spacer(0); + // + // Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGameOverlay()->DrawSettings(); + // + // ImGui::EndMenu(); + // } } void DrawMenuBarIcon() { @@ -445,13 +458,11 @@ void DrawMenuBarIcon() { } void DrawGameMenu() { - } void DrawEnhancementsMenu() { if (UIWidgets::BeginMenu("Enhancements")) { - if (UIWidgets::BeginMenu("Gameplay")) { ImGui::EndMenu(); @@ -462,7 +473,6 @@ void DrawEnhancementsMenu() { } void DrawCheatsMenu() { - } const char* debugInfoPages[6] = { @@ -470,7 +480,6 @@ const char* debugInfoPages[6] = { }; void DrawDebugMenu() { - } void GameMenuBar::DrawElement() { @@ -481,19 +490,19 @@ void GameMenuBar::DrawElement() { ImGui::SetCursorPosY(0.0f); - //DrawSettingsMenu(); + // DrawSettingsMenu(); ImGui::SetCursorPosY(0.0f); - //DrawEnhancementsMenu(); + // DrawEnhancementsMenu(); ImGui::SetCursorPosY(0.0f); - //DrawCheatsMenu(); + // DrawCheatsMenu(); ImGui::SetCursorPosY(0.0f); - //DrawDebugMenu(); + // DrawDebugMenu(); ImGui::EndMenuBar(); } diff --git a/src/port/ui/Menu.cpp b/src/port/ui/Menu.cpp index 670e304fc..01eba78ae 100644 --- a/src/port/ui/Menu.cpp +++ b/src/port/ui/Menu.cpp @@ -9,10 +9,10 @@ #include <tuple> extern "C" { - extern s32 gGamestateNext; - extern s32 gMenuSelection; - #include "audio/external.h" - #include "defines.h" +extern s32 gGamestateNext; +extern s32 gMenuSelection; +#include "audio/external.h" +#include "defines.h" } std::vector<ImVec2> windowTypeSizes = { {} }; @@ -181,8 +181,8 @@ uint32_t Menu::DrawSearchResults(std::string& menuSearchText) { for (int i = 0; i < sidebar.columnWidgets.size(); i++) { auto& column = sidebar.columnWidgets.at(i); for (auto& info : column) { - if (info.type == WIDGET_SEARCH || info.type == WIDGET_SEPARATOR || info.type == WIDGET_SEPARATOR_TEXT || - info.isHidden) { + if (info.type == WIDGET_SEARCH || info.type == WIDGET_SEPARATOR || + info.type == WIDGET_SEPARATOR_TEXT || info.isHidden) { continue; } const char* tooltip = info.options->tooltip; @@ -288,7 +288,7 @@ void Menu::MenuDrawItem(WidgetInfo& widget, uint32_t width, UIWidgets::Colors me if (UIWidgets::Combobox("Renderer API (Needs reload)", &configWindowBackend, availableWindowBackendsMap, options)) { Ship::Context::GetInstance()->GetConfig()->SetInt("Window.Backend.Id", - (int32_t)(configWindowBackend)); + (int32_t) (configWindowBackend)); Ship::Context::GetInstance()->GetConfig()->SetString("Window.Backend.Name", windowBackendsMap.at(configWindowBackend)); Ship::Context::GetInstance()->GetConfig()->Save(); diff --git a/src/port/ui/Menu.h b/src/port/ui/Menu.h index 9857737e6..429697433 100644 --- a/src/port/ui/Menu.h +++ b/src/port/ui/Menu.h @@ -19,7 +19,8 @@ class Menu : public GuiWindow { Menu(const std::string& cVar, const std::string& name, uint8_t searchSidebarIndex_ = 0, UIWidgets::Colors menuThemeIndex_ = UIWidgets::Colors::LightBlue); - virtual ~Menu() {} + virtual ~Menu() { + } void InitElement() override; void DrawElement() override; @@ -57,12 +58,12 @@ class Menu : public GuiWindow { "Searches all menus for the given text, including tooltips.")) } } } }; virtual void ProcessReset() { - gGamestateNext = MAIN_MENU_FROM_QUIT; - if (CVarGetInteger("gEnableDebugMode", 0) == true) { - gMenuSelection = START_MENU; - } else { - gMenuSelection = LOGO_INTRO_MENU; - } + gGamestateNext = MAIN_MENU_FROM_QUIT; + if (CVarGetInteger("gEnableDebugMode", 0) == true) { + gMenuSelection = START_MENU; + } else { + gMenuSelection = LOGO_INTRO_MENU; + } } private: diff --git a/src/port/ui/MenuTypes.h b/src/port/ui/MenuTypes.h index 653c6955d..cbea802c5 100644 --- a/src/port/ui/MenuTypes.h +++ b/src/port/ui/MenuTypes.h @@ -19,7 +19,7 @@ typedef enum { DISABLE_FOR_ADVANCED_RESOLUTION_ON, DISABLE_FOR_VERTICAL_RES_TOGGLE_ON, DISABLE_FOR_LOW_RES_MODE_ON, - //DISABLE_FOR_MULTIPLAYER_CONNECTED, + // DISABLE_FOR_MULTIPLAYER_CONNECTED, } DisableOption; struct WidgetInfo; diff --git a/src/port/ui/MultiplayerWindow.cpp b/src/port/ui/MultiplayerWindow.cpp index a7552bcd3..fc2516f5a 100644 --- a/src/port/ui/MultiplayerWindow.cpp +++ b/src/port/ui/MultiplayerWindow.cpp @@ -113,7 +113,7 @@ void DrawColumn2(WidgetInfo& info) { for (size_t i = 0; i < NETWORK_MAX_PLAYERS; i++) { ImGui::Text("Slot %d: char: %d, hasAuthority: %d", clients[i].slot, clients[i].character, - gPlayers[i].nHasAuthority); + gPlayers[i].nHasAuthority); } /* Stick UI to the bottom of the panel */ @@ -121,8 +121,7 @@ void DrawColumn2(WidgetInfo& info) { float windowHeight = ImGui::GetWindowHeight(); // Move the cursor to a position relative to the bottom of the window - ImGui::SetCursorPosY(windowHeight - - ImGui::GetFrameHeightWithSpacing() * 2); // Adjust Y position for two buttons + ImGui::SetCursorPosY(windowHeight - ImGui::GetFrameHeightWithSpacing() * 2); // Adjust Y position for two buttons char buttonLabel[32]; diff --git a/src/port/ui/MultiplayerWindow.h b/src/port/ui/MultiplayerWindow.h index d196c33c0..f3bf39753 100644 --- a/src/port/ui/MultiplayerWindow.h +++ b/src/port/ui/MultiplayerWindow.h @@ -2,5 +2,4 @@ #include <libultraship/libultraship.h> -namespace Multiplayer { -} // namespace Multiplayer +namespace Multiplayer {} // namespace Multiplayer diff --git a/src/port/ui/PortMenu.cpp b/src/port/ui/PortMenu.cpp index b21ddc1fa..d8411e24b 100644 --- a/src/port/ui/PortMenu.cpp +++ b/src/port/ui/PortMenu.cpp @@ -15,10 +15,10 @@ #endif extern "C" { - extern s32 gGamestateNext; - extern s32 gMenuSelection; - #include "audio/external.h" - #include "defines.h" +extern s32 gGamestateNext; +extern s32 gMenuSelection; +#include "audio/external.h" +#include "defines.h" } namespace GameUI { @@ -158,9 +158,8 @@ void PortMenu::AddSettings() { .IsPercentage()); AddWidget(path, "Main Music Volume: %.0f%%", WIDGET_CVAR_SLIDER_FLOAT) .CVar("gMainMusicVolume") - .Callback([](WidgetInfo& info) { - audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f)); - }) + .Callback( + [](WidgetInfo& info) { audio_set_player_volume(SEQ_PLAYER_LEVEL, CVarGetFloat("gMainMusicVolume", 1.0f)); }) .Options(FloatSliderOptions() .Tooltip("Adjust the background music volume.") .ShowButtons(false) @@ -168,16 +167,17 @@ void PortMenu::AddSettings() { .IsPercentage()); AddWidget(path, "Sound Effects Volume: %.0f%%", WIDGET_CVAR_SLIDER_FLOAT) .CVar("gSFXMusicVolume") - .Callback([](WidgetInfo& info) { - audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f)); - }) - .Options( - FloatSliderOptions().Tooltip("Adjust the sound effects volume.").ShowButtons(false).Format("").IsPercentage()); + .Callback( + [](WidgetInfo& info) { audio_set_player_volume(SEQ_PLAYER_SFX, CVarGetFloat("gSFXMusicVolume", 1.0f)); }) + .Options(FloatSliderOptions() + .Tooltip("Adjust the sound effects volume.") + .ShowButtons(false) + .Format("") + .IsPercentage()); AddWidget(path, "Sound Effects Volume: %.0f%%", WIDGET_CVAR_SLIDER_FLOAT) .CVar("gEnvironmentVolume") - .Callback([](WidgetInfo& info) { - audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f)); - }) + .Callback( + [](WidgetInfo& info) { audio_set_player_volume(SEQ_PLAYER_ENV, CVarGetFloat("gEnvironmentVolume", 1.0f)); }) .Options(FloatSliderOptions() .Tooltip("Adjust the environment volume.") .ShowButtons(false) @@ -332,31 +332,36 @@ void PortMenu::AddEnhancements() { AddMenuEntry("Enhancements", "gSettings.Menu.EnhancementsSidebarSection"); WidgetPath path = { "Enhancements", "General", SECTION_COLUMN_1 }; AddSidebarEntry("Enhancements", "General", 3); - //UIWidgets::WindowButton("Multiplayer", "gMultiplayerWindowEnabled", GameUI::mMultiplayerWindow, - // { .tooltip = "Shows the multiplayer window" }); - // UIWidgets::WindowButton("Freecam", "gFreecam", GameUI::mFreecamWindow, - // { .tooltip = "Allows you to fly around the course" }); + // UIWidgets::WindowButton("Multiplayer", "gMultiplayerWindowEnabled", GameUI::mMultiplayerWindow, + // { .tooltip = "Shows the multiplayer window" }); + // UIWidgets::WindowButton("Freecam", "gFreecam", GameUI::mFreecamWindow, + // { .tooltip = "Allows you to fly around the course" }); AddWidget(path, "No multiplayer feature cuts", WIDGET_CVAR_CHECKBOX) .CVar("gMultiplayerNoFeatureCuts") .Options(CheckboxOptions().Tooltip("Allows full train and jumbotron in multiplayer, etc.")); AddWidget(path, "General Improvements", WIDGET_CVAR_CHECKBOX) - .CVar("gImprovements").Options(CheckboxOptions().Tooltip("General improvements to the game experience.")); + .CVar("gImprovements") + .Options(CheckboxOptions().Tooltip("General improvements to the game experience.")); AddWidget(path, "No Level of Detail (LOD)", WIDGET_CVAR_CHECKBOX) .CVar("gDisableLod") - .Options(CheckboxOptions().Tooltip("Disable Level of Detail (LOD) to avoid models using lower poly versions at a distance")); + .Options(CheckboxOptions().Tooltip( + "Disable Level of Detail (LOD) to avoid models using lower poly versions at a distance")); AddWidget(path, "Disable Culling", WIDGET_CVAR_CHECKBOX) - .CVar("gNoCulling").Options(CheckboxOptions().Tooltip("Disable original culling of mk64")); + .CVar("gNoCulling") + .Options(CheckboxOptions().Tooltip("Disable original culling of mk64")); AddWidget(path, "Far Frustrum", WIDGET_CVAR_SLIDER_FLOAT) .CVar("gFarFrustrum") - .Options(FloatSliderOptions().Min(0.0f).Max(10000.0f).DefaultValue(10000.0f) - .Tooltip("Say how Far the Frustrum are when 'Disable Culling' are enable").Step(10.0f)); + .Options(FloatSliderOptions() + .Min(0.0f) + .Max(10000.0f) + .DefaultValue(10000.0f) + .Tooltip("Say how Far the Frustrum are when 'Disable Culling' are enable") + .Step(10.0f)); path = { "Enhancements", "Cheats", SECTION_COLUMN_1 }; AddSidebarEntry("Enhancements", "Cheats", 3); - AddWidget(path, "Moon Jump", WIDGET_CVAR_CHECKBOX) - .CVar("gEnableMoonJump"); - AddWidget(path, "Enable Custom CC", WIDGET_CVAR_CHECKBOX) - .CVar("gEnableCustomCC"); + AddWidget(path, "Moon Jump", WIDGET_CVAR_CHECKBOX).CVar("gEnableMoonJump"); + AddWidget(path, "Enable Custom CC", WIDGET_CVAR_CHECKBOX).CVar("gEnableCustomCC"); AddWidget(path, "Custom CC", WIDGET_CVAR_SLIDER_FLOAT) .CVar("gCustomCC") .Options(FloatSliderOptions().Min(0.0f).Max(1000.0f).DefaultValue(150.0f).Step(10.0f)); @@ -365,21 +370,21 @@ void PortMenu::AddEnhancements() { .Options(CheckboxOptions().Tooltip("Disable wall collision.")); AddWidget(path, "Min Height", WIDGET_CVAR_SLIDER_FLOAT) .CVar("gMinHeight") - .Options(FloatSliderOptions().Min(-50.0f).Max(50.0f).DefaultValue(0.0f) - .Tooltip("When Disable Wall Collision are enable what is the minimal height you can get.")); + .Options(FloatSliderOptions().Min(-50.0f).Max(50.0f).DefaultValue(0.0f).Tooltip( + "When Disable Wall Collision are enable what is the minimal height you can get.")); path = { "Enhancements", "HM64 Lab", SECTION_COLUMN_1 }; AddSidebarEntry("Enhancements", "HM64 Lab", 4); AddWidget(path, "Enable HM64 Labs", WIDGET_CVAR_CHECKBOX) - .CVar("gEditorEnabled") - .Callback([](WidgetInfo& info) { - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Tools")->ToggleVisibility(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Scene Explorer")->ToggleVisibility(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Content Browser")->ToggleVisibility(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Track Properties")->ToggleVisibility(); - Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Properties")->ToggleVisibility(); - }) - .Options(UIWidgets::CheckboxOptions({{ .tooltip = "Edit the universe!"}})); + .CVar("gEditorEnabled") + .Callback([](WidgetInfo& info) { + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Tools")->ToggleVisibility(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Scene Explorer")->ToggleVisibility(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Content Browser")->ToggleVisibility(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Track Properties")->ToggleVisibility(); + Ship::Context::GetInstance()->GetWindow()->GetGui()->GetGuiWindow("Properties")->ToggleVisibility(); + }) + .Options(UIWidgets::CheckboxOptions({ { .tooltip = "Edit the universe!" } })); } #ifdef __SWITCH__ @@ -400,11 +405,11 @@ void PortMenu::AddDevTools() { WidgetPath path = { "Developer", "General", SECTION_COLUMN_1 }; #ifdef __SWITCH__ AddWidget(path, "Switch CPU Profile", WIDGET_CVAR_COMBOBOX) - .CVar("gSwitchPerfMode") - .Options(ComboboxOptions() - .Tooltip("Switches the CPU profile to a different one") - .ComboMap(switchCPUProfiles) - .DefaultIndex(Ship::SwitchProfiles::STOCK)) + .CVar("gSwitchPerfMode") + .Options(ComboboxOptions() + .Tooltip("Switches the CPU profile to a different one") + .ComboMap(switchCPUProfiles) + .DefaultIndex(Ship::SwitchProfiles::STOCK)) .Callback([](WidgetInfo& info) { Ship::Switch::ApplyOverclock(); }); #endif AddWidget(path, "Popout Menu", WIDGET_CVAR_CHECKBOX) @@ -429,7 +434,8 @@ void PortMenu::AddDevTools() { AddSidebarEntry("Developer", "Stats", 1); AddWidget(path, "Popout Stats", WIDGET_WINDOW_BUTTON) .CVar("gStatsEnabled") - .Options(ButtonOptions().Tooltip("Shows the stats window, with your FPS and frametimes, and the OS you're playing on")) + .Options(ButtonOptions().Tooltip( + "Shows the stats window, with your FPS and frametimes, and the OS you're playing on")) .WindowName("Stats"); path = { "Developer", "Console", SECTION_COLUMN_1 }; @@ -445,9 +451,9 @@ PortMenu::PortMenu(const std::string& consoleVariable, const std::string& name) : Menu(consoleVariable, name, 0, UIWidgets::Colors::LightBlue) { } -//bool CheckNetworkConnected(disabledInfo& info) { -// return gNetwork.isConnected; -//} +// bool CheckNetworkConnected(disabledInfo& info) { +// return gNetwork.isConnected; +// } void PortMenu::InitElement() { Ship::Menu::InitElement(); @@ -531,4 +537,4 @@ void PortMenu::Draw() { void PortMenu::DrawElement() { Ship::Menu::DrawElement(); } -} // namespace BenGui +} // namespace GameUI diff --git a/src/port/ui/PortMenu.h b/src/port/ui/PortMenu.h index 12eb60379..1e678b6bb 100644 --- a/src/port/ui/PortMenu.h +++ b/src/port/ui/PortMenu.h @@ -6,7 +6,6 @@ #include "Menu.h" #include "Fast3D/backends/gfx_rendering_api.h" - namespace GameUI { static const std::unordered_map<int32_t, const char*> menuThemeOptions = { @@ -47,7 +46,8 @@ static const std::unordered_map<int32_t, const char*> logLevels = { class PortMenu : public Ship::Menu { public: PortMenu(const std::string& consoleVariable, const std::string& name); - ~PortMenu() {} + ~PortMenu() { + } void InitElement() override; void DrawElement() override; @@ -60,6 +60,6 @@ class PortMenu : public Ship::Menu { void AddEnhancements(); void AddDevTools(); }; -} // namespace BenGui +} // namespace GameUI #endif // PORTMENU_H diff --git a/src/port/ui/Properties.cpp b/src/port/ui/Properties.cpp index 0368231d9..86d32fd43 100644 --- a/src/port/ui/Properties.cpp +++ b/src/port/ui/Properties.cpp @@ -17,91 +17,89 @@ namespace Editor { - PropertiesWindow::~PropertiesWindow() { - SPDLOG_TRACE("destruct properties window"); +PropertiesWindow::~PropertiesWindow() { + SPDLOG_TRACE("destruct properties window"); +} + +void PropertiesWindow::DrawElement() { + GameObject* selected = gEditor.eObjectPicker.eGizmo._selected; + + if (nullptr == selected) { + return; } - void PropertiesWindow::DrawElement() { - GameObject* selected = gEditor.eObjectPicker.eGizmo._selected; + ImGui::Begin("Properties"); + + if (selected->Pos) { + ImGui::Text("Location"); + ImGui::SameLine(); + + bool positionChanged = ImGui::DragFloat3("##Location", &selected->Pos->x, 0.1f); - if (nullptr == selected) { - return; + ImGui::SameLine(); + if (ImGui::Button(ICON_FA_UNDO "##ResetPos")) { + selected->Pos->x = 0.0f; + selected->Pos->y = 0.0f; + selected->Pos->z = 0.0f; + positionChanged = true; // also counts as a change } - ImGui::Begin("Properties"); + if (positionChanged) { + gEditor.eObjectPicker.eGizmo.Pos = *selected->Pos; + } + } - if (selected->Pos) { - ImGui::Text("Location"); - ImGui::SameLine(); + if (selected->Rot) { + ImGui::Text("Rotation"); + ImGui::SameLine(); - bool positionChanged = ImGui::DragFloat3("##Location", &selected->Pos->x, 0.1f); + // Convert to temporary int values (to prevent writing 32bit values to 16bit variables) + int rot[3] = { selected->Rot->pitch, selected->Rot->yaw, selected->Rot->roll }; - ImGui::SameLine(); - if (ImGui::Button(ICON_FA_UNDO "##ResetPos")) { - selected->Pos->x = 0.0f; - selected->Pos->y = 0.0f; - selected->Pos->z = 0.0f; - positionChanged = true; // also counts as a change + if (ImGui::DragInt3("##Rotation", rot, 5.0f)) { + for (int i = 0; i < 3; i++) { + // Wrap around 0–65535 + rot[i] = (rot[i] % 65536 + 65536) % 65536; } - if (positionChanged) { - gEditor.eObjectPicker.eGizmo.Pos = *selected->Pos; - } + selected->Rot->pitch = static_cast<uint16_t>(rot[0]); + selected->Rot->yaw = static_cast<uint16_t>(rot[1]); + selected->Rot->roll = static_cast<uint16_t>(rot[2]); } - if (selected->Rot) { - ImGui::Text("Rotation"); - ImGui::SameLine(); - - // Convert to temporary int values (to prevent writing 32bit values to 16bit variables) - int rot[3] = { - selected->Rot->pitch, - selected->Rot->yaw, - selected->Rot->roll - }; - - if (ImGui::DragInt3("##Rotation", rot, 5.0f)) { - for (int i = 0; i < 3; i++) { - // Wrap around 0–65535 - rot[i] = (rot[i] % 65536 + 65536) % 65536; - } - - selected->Rot->pitch = static_cast<uint16_t>(rot[0]); - selected->Rot->yaw = static_cast<uint16_t>(rot[1]); - selected->Rot->roll = static_cast<uint16_t>(rot[2]); - } - - ImGui::SameLine(); - if (ImGui::Button(ICON_FA_UNDO "##ResetRot")) { - selected->Rot->pitch = 0; - selected->Rot->yaw = 0; - selected->Rot->roll = 0; - } + ImGui::SameLine(); + if (ImGui::Button(ICON_FA_UNDO "##ResetRot")) { + selected->Rot->pitch = 0; + selected->Rot->yaw = 0; + selected->Rot->roll = 0; } + } - if (selected->Scale) { - ImGui::Text("Scale "); - ImGui::SameLine(); + if (selected->Scale) { + ImGui::Text("Scale "); + ImGui::SameLine(); - ImGui::DragFloat3("##Scale", &selected->Scale->x, 0.1f); - ImGui::SameLine(); - if (ImGui::Button(ICON_FA_UNDO "##ResetScale")) { - selected->Scale->x = 1.0f; - selected->Scale->y = 1.0f; - selected->Scale->z = 1.0f; - } + ImGui::DragFloat3("##Scale", &selected->Scale->x, 0.1f); + ImGui::SameLine(); + if (ImGui::Button(ICON_FA_UNDO "##ResetScale")) { + selected->Scale->x = 1.0f; + selected->Scale->y = 1.0f; + selected->Scale->z = 1.0f; } + } - if (selected->Collision == GameObject::CollisionType::BOUNDING_BOX) { - ImGui::Separator(); - ImGui::Text("Editor Bounding Box Size:"); - ImGui::PushID("BoundingBoxSize"); - ImGui::DragFloat("##BoundingBoxSize", &selected->BoundingBoxSize, 0.1f); - ImGui::SameLine(); - if (ImGui::Button(ICON_FA_UNDO)) { selected->BoundingBoxSize = 2.0f; } - ImGui::PopID(); + if (selected->Collision == GameObject::CollisionType::BOUNDING_BOX) { + ImGui::Separator(); + ImGui::Text("Editor Bounding Box Size:"); + ImGui::PushID("BoundingBoxSize"); + ImGui::DragFloat("##BoundingBoxSize", &selected->BoundingBoxSize, 0.1f); + ImGui::SameLine(); + if (ImGui::Button(ICON_FA_UNDO)) { + selected->BoundingBoxSize = 2.0f; } - - ImGui::End(); + ImGui::PopID(); } -}
\ No newline at end of file + + ImGui::End(); +} +} // namespace Editor diff --git a/src/port/ui/Properties.h b/src/port/ui/Properties.h index 260f89179..f05b15531 100644 --- a/src/port/ui/Properties.h +++ b/src/port/ui/Properties.h @@ -3,15 +3,15 @@ #include <libultraship/libultraship.h> #include "port/Game.h" - namespace Editor { class PropertiesWindow : public Ship::GuiWindow { -public: + public: using Ship::GuiWindow::GuiWindow; ~PropertiesWindow(); -protected: + + protected: void InitElement() override {}; void DrawElement() override; void UpdateElement() override {}; }; -}
\ No newline at end of file +} // namespace Editor diff --git a/src/port/ui/ResolutionEditor.cpp b/src/port/ui/ResolutionEditor.cpp index ca47cb15e..63cb1e41f 100644 --- a/src/port/ui/ResolutionEditor.cpp +++ b/src/port/ui/ResolutionEditor.cpp @@ -102,8 +102,8 @@ void RegisterResolutionWidgets() { }); mPortMenu->AddWidget(path, "Internal resolution: {} x {}", WIDGET_TEXT).PreFunc([](WidgetInfo& info) { auto captured_current_dimensions = GetInterpreter()->mCurDimensions; - info.name = - fmt::format("Internal resolution: {} x {}", captured_current_dimensions.width, captured_current_dimensions.height); + info.name = fmt::format("Internal resolution: {} x {}", captured_current_dimensions.width, + captured_current_dimensions.height); }); // UIWidgets::PaddedSeparator(true, true, 3.0f, 3.0f); @@ -177,7 +177,7 @@ void RegisterResolutionWidgets() { auto gfx_current_game_window_viewport = GetInterpreter()->mGameWindowViewport; auto gfx_current_dimensions = GetInterpreter()->mCurDimensions; ImGui::Dummy({ 0, 2 }); - const float resolvedAspectRatio = (float)gfx_current_dimensions.width / gfx_current_dimensions.height; + const float resolvedAspectRatio = (float) gfx_current_dimensions.width / gfx_current_dimensions.height; ImGui::Text("Aspect ratio: %.2f:1", resolvedAspectRatio); } } @@ -314,7 +314,7 @@ void RegisterResolutionWidgets() { // if (ImGui::CollapsingHeader("Additional Settings")) { // UIWidgets::Spacer(0); // - //#if defined(__SWITCH__) || defined(__WIIU__) + // #if defined(__SWITCH__) || defined(__WIIU__) // // Disable aspect correction, stretching the framebuffer to fill the viewport. // // This option is only really needed on systems limited to 16:9 TV resolutions, such as consoles. // // The associated cvar is still functional on PC platforms if you want to use it though. @@ -326,7 +326,7 @@ void RegisterResolutionWidgets() { // ".PixelPerfectMode", 0) || // disabled_everything, // "", UIWidgets::CheckboxGraphics::Cross, false); - //#else + // #else // if (CVarGetInteger(CVAR_PREFIX_ADVANCED_RESOLUTION ".IgnoreAspectCorrection", 0)) { // // This setting is intentionally not exposed on PC platforms, // // but may be accidentally activated for varying reasons. @@ -339,7 +339,7 @@ void RegisterResolutionWidgets() { // } // UIWidgets::Spacer(2); // } - //#endif + // #endif // // // A requested addition; an alternative way of displaying the resolution field. // if (ImGui::Checkbox("Show a horizontal resolution field, instead of aspect ratio.", @@ -504,8 +504,8 @@ void UpdateResolutionVars() { // This is mostly just for UX purposes, as Fit Automatically logic is part of LUS. auto gfx_current_game_window_viewport = GetInterpreter()->mGameWindowViewport; auto gfx_current_dimensions = GetInterpreter()->mCurDimensions; - if (((float)gfx_current_game_window_viewport.width / gfx_current_game_window_viewport.height) > - ((float)gfx_current_dimensions.width / gfx_current_dimensions.height)) { + if (((float) gfx_current_game_window_viewport.width / gfx_current_game_window_viewport.height) > + ((float) gfx_current_dimensions.width / gfx_current_dimensions.height)) { // Scale to window height integerScale_maximumBounds = gfx_current_game_window_viewport.height / gfx_current_game_window_viewport.height; } else { @@ -546,4 +546,4 @@ bool IsDroppingFrames() { static RegisterMenuUpdateFunc updateFunc(UpdateResolutionVars, "Settings", "Graphics"); static RegisterMenuInitFunc initFunc(RegisterResolutionWidgets); -} // namespace BenGui +} // namespace GameUI diff --git a/src/port/ui/ResolutionEditor.h b/src/port/ui/ResolutionEditor.h index 6a1cff80b..735b1b1a7 100644 --- a/src/port/ui/ResolutionEditor.h +++ b/src/port/ui/ResolutionEditor.h @@ -9,6 +9,6 @@ namespace GameUI { bool IsDroppingFrames(); void RegisterResolutionWidgets(); void UpdateResolutionVars(); -} // namespace BenGui +} // namespace GameUI #endif // RESOLUTIONEDITOR_H diff --git a/src/port/ui/SceneExplorer.cpp b/src/port/ui/SceneExplorer.cpp index 79b9c08e0..9e084280b 100644 --- a/src/port/ui/SceneExplorer.cpp +++ b/src/port/ui/SceneExplorer.cpp @@ -16,25 +16,25 @@ namespace Editor { - SceneExplorerWindow::~SceneExplorerWindow() { - SPDLOG_TRACE("destruct scene explorer window"); - } +SceneExplorerWindow::~SceneExplorerWindow() { + SPDLOG_TRACE("destruct scene explorer window"); +} - void SceneExplorerWindow::DrawElement() { - ImGui::Text("Scene"); +void SceneExplorerWindow::DrawElement() { + ImGui::Text("Scene"); - size_t id = 0; // id for now because we don't have unique names atm - for (auto& object : gEditor.eGameObjects) { - // Convert const char* to std::string before formatting - std::string objectName = object->Name ? object->Name : "Obj"; + size_t id = 0; // id for now because we don't have unique names atm + for (auto& object : gEditor.eGameObjects) { + // Convert const char* to std::string before formatting + std::string objectName = object->Name ? object->Name : "Obj"; - // Ensure unique label using index - std::string label = fmt::format("{}##{}", objectName, id); + // Ensure unique label using index + std::string label = fmt::format("{}##{}", objectName, id); - if (ImGui::Button(label.c_str())) { - gEditor.SelectObjectFromSceneExplorer(object); - } - id += 1; + if (ImGui::Button(label.c_str())) { + gEditor.SelectObjectFromSceneExplorer(object); } + id += 1; } } +} // namespace Editor diff --git a/src/port/ui/SceneExplorer.h b/src/port/ui/SceneExplorer.h index f9e926148..eca9d1b20 100644 --- a/src/port/ui/SceneExplorer.h +++ b/src/port/ui/SceneExplorer.h @@ -3,15 +3,15 @@ #include <libultraship/libultraship.h> #include "port/Game.h" - namespace Editor { class SceneExplorerWindow : public Ship::GuiWindow { -public: + public: using Ship::GuiWindow::GuiWindow; ~SceneExplorerWindow(); -protected: + + protected: void InitElement() override {}; void DrawElement() override; void UpdateElement() override {}; }; -} +} // namespace Editor diff --git a/src/port/ui/Tools.cpp b/src/port/ui/Tools.cpp index 9bfdda26b..a41710681 100644 --- a/src/port/ui/Tools.cpp +++ b/src/port/ui/Tools.cpp @@ -20,141 +20,139 @@ extern "C" { namespace Editor { - ToolsWindow::~ToolsWindow() { - SPDLOG_TRACE("destruct tools window"); - } +ToolsWindow::~ToolsWindow() { + SPDLOG_TRACE("destruct tools window"); +} + +void ToolsWindow::InitElement() { +} + +void ToolsWindow::DrawElement() { + static bool toggleGroundSnap = CVarGetInteger("gEditorSnapToGround", 0); + static bool toggleBoundary = CVarGetInteger("gEditorBoundary", 0); + static int selectedTool = 0; // 0: Move, 1: Rotate, 2: Scale - void ToolsWindow::InitElement() { - + // Save button + if (ImGui::Button(ICON_FA_FLOPPY_O, ImVec2(50, 25))) { + SaveLevel(); } - void ToolsWindow::DrawElement() { - static bool toggleGroundSnap = CVarGetInteger("gEditorSnapToGround", 0); - static bool toggleBoundary = CVarGetInteger("gEditorBoundary", 0); - static int selectedTool = 0; // 0: Move, 1: Rotate, 2: Scale + ImGui::SameLine(); - // Save button - if (ImGui::Button(ICON_FA_FLOPPY_O, ImVec2(50, 25))) { - SaveLevel(); - } + ImVec4 defaultColor = ImGui::GetStyle().Colors[ImGuiCol_Button]; + // Function to check and highlight the selected button + auto ToolButton = [&](const char* label, int id) { + bool isSelected = (selectedTool == id); + ImGui::PushStyleColor(ImGuiCol_Button, isSelected ? ImVec4(0.4f, 0.7f, 0.9f, 1.0f) : defaultColor); - ImGui::SameLine(); - - ImVec4 defaultColor = ImGui::GetStyle().Colors[ImGuiCol_Button]; - // Function to check and highlight the selected button - auto ToolButton = [&](const char* label, int id) { - bool isSelected = (selectedTool == id); - ImGui::PushStyleColor(ImGuiCol_Button, isSelected ? ImVec4(0.4f, 0.7f, 0.9f, 1.0f) : defaultColor); - - if (ImGui::Button(label, ImVec2(50, 25))) { - selectedTool = id; // Set the selected tool - CVarSetInteger("eGizmoMode", id); - } - - ImGui::PopStyleColor(); - }; - - // Draw buttons - ToolButton(ICON_FA_ARROWS, 0); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text("Translate"); - ImGui::EndTooltip(); - } - ImGui::SameLine(); - ToolButton(ICON_FA_REPEAT, 1); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text("Rotate"); - ImGui::EndTooltip(); - } - ImGui::SameLine(); - ToolButton(ICON_FA_EXPAND, 2); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text("Scale"); - ImGui::EndTooltip(); + if (ImGui::Button(label, ImVec2(50, 25))) { + selectedTool = id; // Set the selected tool + CVarSetInteger("eGizmoMode", id); } - ImGui::SameLine(); + ImGui::PopStyleColor(); + }; + + // Draw buttons + ToolButton(ICON_FA_ARROWS, 0); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("Translate"); + ImGui::EndTooltip(); + } + ImGui::SameLine(); + ToolButton(ICON_FA_REPEAT, 1); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("Rotate"); + ImGui::EndTooltip(); + } + ImGui::SameLine(); + ToolButton(ICON_FA_EXPAND, 2); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("Scale"); + ImGui::EndTooltip(); + } - // Snap to ground - ImGui::PushStyleColor(ImGuiCol_Button, toggleGroundSnap ? ImVec4(0.4f, 0.7f, 0.9f, 1.0f) : defaultColor); + ImGui::SameLine(); - if (ImGui::Button(ICON_FA_LINK, ImVec2(50, 25))) { - toggleGroundSnap = !toggleGroundSnap; + // Snap to ground + ImGui::PushStyleColor(ImGuiCol_Button, toggleGroundSnap ? ImVec4(0.4f, 0.7f, 0.9f, 1.0f) : defaultColor); - CVarSetInteger("gEditorSnapToGround", toggleGroundSnap); - } - ImGui::PopStyleColor(); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text("Snap object to surface"); - ImGui::EndTooltip(); - } + if (ImGui::Button(ICON_FA_LINK, ImVec2(50, 25))) { + toggleGroundSnap = !toggleGroundSnap; - ImGui::SameLine(); + CVarSetInteger("gEditorSnapToGround", toggleGroundSnap); + } + ImGui::PopStyleColor(); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("Snap object to surface"); + ImGui::EndTooltip(); + } - // Boundary - ImGui::PushStyleColor(ImGuiCol_Button, toggleBoundary ? ImVec4(0.4f, 0.7f, 0.9f, 1.0f) : defaultColor); - if (ImGui::Button(toggleBoundary ? "Map Boundaries" : "Map Boundaries", ImVec2(125, 25))) { - toggleBoundary = !toggleBoundary; + ImGui::SameLine(); - CVarSetInteger("gEditorBoundary", toggleBoundary); - } - ImGui::PopStyleColor(); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text("Stops translated objects from leaving the track area."); - ImGui::Text("This helps prevent moving objects really far away off the level."); - ImGui::EndTooltip(); - } + // Boundary + ImGui::PushStyleColor(ImGuiCol_Button, toggleBoundary ? ImVec4(0.4f, 0.7f, 0.9f, 1.0f) : defaultColor); + if (ImGui::Button(toggleBoundary ? "Map Boundaries" : "Map Boundaries", ImVec2(125, 25))) { + toggleBoundary = !toggleBoundary; - ImGui::SameLine(); + CVarSetInteger("gEditorBoundary", toggleBoundary); + } + ImGui::PopStyleColor(); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("Stops translated objects from leaving the track area."); + ImGui::Text("This helps prevent moving objects really far away off the level."); + ImGui::EndTooltip(); + } - // Toggle player human/ai - bool playerToggle = (gPlayerOne->type & PLAYER_KART_AI); - ImGui::PushStyleColor(ImGuiCol_Button, defaultColor); - if (ImGui::Button(playerToggle ? ICON_FA_DESKTOP : ICON_FA_GAMEPAD, ImVec2(50, 25))) { - if (playerToggle) { - gPlayerOne->type &= ~PLAYER_KART_AI; - } else { - gPlayerOne->type |= PLAYER_KART_AI; - } + ImGui::SameLine(); + // Toggle player human/ai + bool playerToggle = (gPlayerOne->type & PLAYER_KART_AI); + ImGui::PushStyleColor(ImGuiCol_Button, defaultColor); + if (ImGui::Button(playerToggle ? ICON_FA_DESKTOP : ICON_FA_GAMEPAD, ImVec2(50, 25))) { + if (playerToggle) { + gPlayerOne->type &= ~PLAYER_KART_AI; + } else { + gPlayerOne->type |= PLAYER_KART_AI; } - ImGui::PopStyleColor(); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text("Toggle player 1's AI or human player state."); - ImGui::EndTooltip(); - } + } + ImGui::PopStyleColor(); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("Toggle player 1's AI or human player state."); + ImGui::EndTooltip(); + } - ImGui::SameLine(); + ImGui::SameLine(); - // Play/pause button - ImGui::PushStyleColor(ImGuiCol_Button, defaultColor); - if (ImGui::Button(gIsEditorPaused ? ICON_FA_PLAY : ICON_FA_PAUSE, ImVec2(50, 25))) { + // Play/pause button + ImGui::PushStyleColor(ImGuiCol_Button, defaultColor); + if (ImGui::Button(gIsEditorPaused ? ICON_FA_PLAY : ICON_FA_PAUSE, ImVec2(50, 25))) { - gIsEditorPaused = !gIsEditorPaused; - } - ImGui::PopStyleColor(); + gIsEditorPaused = !gIsEditorPaused; + } + ImGui::PopStyleColor(); - ImGui::SameLine(); + ImGui::SameLine(); - // Toggle hud - ImGui::PushStyleColor(ImGuiCol_Button, gIsHUDVisible ? ImVec4(0.4f, 0.7f, 0.9f, 1.0f) : defaultColor); - if (ImGui::Button("Toggle HUD", ImVec2(150, 25))) { + // Toggle hud + ImGui::PushStyleColor(ImGuiCol_Button, gIsHUDVisible ? ImVec4(0.4f, 0.7f, 0.9f, 1.0f) : defaultColor); + if (ImGui::Button("Toggle HUD", ImVec2(150, 25))) { - gIsHUDVisible = !gIsHUDVisible; - } - ImGui::PopStyleColor(); + gIsHUDVisible = !gIsHUDVisible; + } + ImGui::PopStyleColor(); - ImGui::SameLine(); + ImGui::SameLine(); - // Delete - if (ImGui::Button(ICON_FA_TRASH_O, ImVec2(50, 25))) { - gEditor.DeleteObject(); - } + // Delete + if (ImGui::Button(ICON_FA_TRASH_O, ImVec2(50, 25))) { + gEditor.DeleteObject(); } } +} // namespace Editor diff --git a/src/port/ui/Tools.h b/src/port/ui/Tools.h index b1afccf18..9aa67a601 100644 --- a/src/port/ui/Tools.h +++ b/src/port/ui/Tools.h @@ -4,13 +4,14 @@ namespace Editor { class ToolsWindow : public Ship::GuiWindow { -public: + public: using Ship::GuiWindow::GuiWindow; ~ToolsWindow(); -protected: + + protected: void InitElement() override; void DrawElement() override; void UpdateElement() override {}; }; -} +} // namespace Editor diff --git a/src/port/ui/TrackProperties.cpp b/src/port/ui/TrackProperties.cpp index 9f1f45198..9bf9ae060 100644 --- a/src/port/ui/TrackProperties.cpp +++ b/src/port/ui/TrackProperties.cpp @@ -23,261 +23,313 @@ extern "C" { namespace Editor { - TrackPropertiesWindow::~TrackPropertiesWindow() { - SPDLOG_TRACE("destruct track properties window"); - } +TrackPropertiesWindow::~TrackPropertiesWindow() { + SPDLOG_TRACE("destruct track properties window"); +} - void TrackPropertiesWindow::DrawElement() { - static char idBuffer[256] = "mk:mario_raceway"; - static char nameBuffer[256] = "Mario Raceway"; - static char debugNameBuffer[256] = "m circuit"; - static char lengthBuffer[256] = "567m"; - - ImGui::InputText("ID", idBuffer, IM_ARRAYSIZE(idBuffer)); - ImGui::InputText("Name", gWorldInstance.CurrentCourse->Props.Name, IM_ARRAYSIZE(nameBuffer)); - ImGui::InputText("Debug Name", gWorldInstance.CurrentCourse->Props.DebugName, IM_ARRAYSIZE(debugNameBuffer)); - ImGui::InputText("Course Length", gWorldInstance.CurrentCourse->Props.CourseLength, IM_ARRAYSIZE(lengthBuffer)); - ImGui::InputFloat("Water Level", &gWorldInstance.CurrentCourse->Props.WaterLevel); - - if (ImGui::CollapsingHeader("Camera")) { - ImGui::InputFloat("Near Perspective", &gWorldInstance.CurrentCourse->Props.NearPersp); - ImGui::InputFloat("Far Perspective", &gWorldInstance.CurrentCourse->Props.FarPersp); - if (ImGui::IsItemHovered()) { - ImGui::BeginTooltip(); - ImGui::Text("Controls the far clipping distance for perspective rendering."); - ImGui::Text("Disable culling enhancement needs to be off to see a difference."); - ImGui::EndTooltip(); - } +void TrackPropertiesWindow::DrawElement() { + static char idBuffer[256] = "mk:mario_raceway"; + static char nameBuffer[256] = "Mario Raceway"; + static char debugNameBuffer[256] = "m circuit"; + static char lengthBuffer[256] = "567m"; + + ImGui::InputText("ID", idBuffer, IM_ARRAYSIZE(idBuffer)); + ImGui::InputText("Name", gWorldInstance.CurrentCourse->Props.Name, IM_ARRAYSIZE(nameBuffer)); + ImGui::InputText("Debug Name", gWorldInstance.CurrentCourse->Props.DebugName, IM_ARRAYSIZE(debugNameBuffer)); + ImGui::InputText("Course Length", gWorldInstance.CurrentCourse->Props.CourseLength, IM_ARRAYSIZE(lengthBuffer)); + ImGui::InputFloat("Water Level", &gWorldInstance.CurrentCourse->Props.WaterLevel); + + if (ImGui::CollapsingHeader("Camera")) { + ImGui::InputFloat("Near Perspective", &gWorldInstance.CurrentCourse->Props.NearPersp); + ImGui::InputFloat("Far Perspective", &gWorldInstance.CurrentCourse->Props.FarPersp); + if (ImGui::IsItemHovered()) { + ImGui::BeginTooltip(); + ImGui::Text("Controls the far clipping distance for perspective rendering."); + ImGui::Text("Disable culling enhancement needs to be off to see a difference."); + ImGui::EndTooltip(); } + } - if (ImGui::CollapsingHeader("Environment")) { - TrackPropertiesWindow::DrawLight(); - } + if (ImGui::CollapsingHeader("Environment")) { + TrackPropertiesWindow::DrawLight(); + } - if (ImGui::CollapsingHeader("AI")) { + if (ImGui::CollapsingHeader("AI")) { - ImGui::InputFloat("AI Max Separation", &gWorldInstance.CurrentCourse->Props.AIMaximumSeparation); - ImGui::InputFloat("AI Min Separation", &gWorldInstance.CurrentCourse->Props.AIMinimumSeparation); - ImGui::InputInt("AI Steering Sensitivity", (int*)&gWorldInstance.CurrentCourse->Props.AISteeringSensitivity); + ImGui::InputFloat("AI Max Separation", &gWorldInstance.CurrentCourse->Props.AIMaximumSeparation); + ImGui::InputFloat("AI Min Separation", &gWorldInstance.CurrentCourse->Props.AIMinimumSeparation); + ImGui::InputInt("AI Steering Sensitivity", (int*) &gWorldInstance.CurrentCourse->Props.AISteeringSensitivity); - ImGui::Separator(); + ImGui::Separator(); - for (size_t i = 0; i < 32; i++) { - ImGui::InputScalar(("Element " + std::to_string(i)).c_str(), ImGuiDataType_S16, &gWorldInstance.CurrentCourse->Props.AIDistance[i]); - } + for (size_t i = 0; i < 32; i++) { + ImGui::InputScalar(("Element " + std::to_string(i)).c_str(), ImGuiDataType_S16, + &gWorldInstance.CurrentCourse->Props.AIDistance[i]); } + } - if (ImGui::CollapsingHeader("Random Junk")) { - for (size_t i = 0; i < 4; i++) { - ImGui::InputFloat(fmt::format("D_0D009418[{}]", i).c_str(), &gWorldInstance.CurrentCourse->Props.D_0D009418[i]); - } - - ImGui::Separator(); + if (ImGui::CollapsingHeader("Random Junk")) { + for (size_t i = 0; i < 4; i++) { + ImGui::InputFloat(fmt::format("D_0D009418[{}]", i).c_str(), + &gWorldInstance.CurrentCourse->Props.D_0D009418[i]); + } + ImGui::Separator(); - for (size_t i = 0; i < 4; i++) { - ImGui::InputFloat(fmt::format("D_0D009568[{}]", i).c_str(), &gWorldInstance.CurrentCourse->Props.D_0D009568[i]); - } - - ImGui::Separator(); + for (size_t i = 0; i < 4; i++) { + ImGui::InputFloat(fmt::format("D_0D009568[{}]", i).c_str(), + &gWorldInstance.CurrentCourse->Props.D_0D009568[i]); + } + ImGui::Separator(); - for (size_t i = 0; i < 4; i++) { - ImGui::InputFloat(fmt::format("D_0D0096B8[{}]", i).c_str(), &gWorldInstance.CurrentCourse->Props.D_0D0096B8[i]); - } + for (size_t i = 0; i < 4; i++) { + ImGui::InputFloat(fmt::format("D_0D0096B8[{}]", i).c_str(), + &gWorldInstance.CurrentCourse->Props.D_0D0096B8[i]); + } - ImGui::Separator(); + ImGui::Separator(); - for (size_t i = 0; i < 4; i++) { - ImGui::InputFloat(fmt::format("D_0D009808[{}]", i).c_str(), &gWorldInstance.CurrentCourse->Props.D_0D009808[i]); - } + for (size_t i = 0; i < 4; i++) { + ImGui::InputFloat(fmt::format("D_0D009808[{}]", i).c_str(), + &gWorldInstance.CurrentCourse->Props.D_0D009808[i]); } + } - float minimapColour[3]; - RGB8ToFloat((u8*)&gWorldInstance.CurrentCourse->Props.Minimap.Colour, minimapColour); - - if (ImGui::CollapsingHeader("Minimap")) { - ImGui::Text("Position"); - ImGui::SameLine(); + float minimapColour[3]; + RGB8ToFloat((u8*) &gWorldInstance.CurrentCourse->Props.Minimap.Colour, minimapColour); + if (ImGui::CollapsingHeader("Minimap")) { + ImGui::Text("Position"); + ImGui::SameLine(); - if (ImGui::DragInt2("##MinimapPosition", &gWorldInstance.CurrentCourse->Props.Minimap.Pos[0].X, 1.0f)) { - } - ImGui::Text("P2 Position"); - ImGui::SameLine(); - if (ImGui::DragInt2("##MinimapPosition2p", &gWorldInstance.CurrentCourse->Props.Minimap.Pos[1].X, 1.0f)) { - } + if (ImGui::DragInt2("##MinimapPosition", &gWorldInstance.CurrentCourse->Props.Minimap.Pos[0].X, 1.0f)) {} + ImGui::Text("P2 Position"); + ImGui::SameLine(); + if (ImGui::DragInt2("##MinimapPosition2p", &gWorldInstance.CurrentCourse->Props.Minimap.Pos[1].X, 1.0f)) {} - ImGui::Text("Player Markers"); - ImGui::SameLine(); - if (ImGui::DragInt2("##MinimapPlayers", &gWorldInstance.CurrentCourse->Props.Minimap.PlayerX, 1.0f)) { - } + ImGui::Text("Player Markers"); + ImGui::SameLine(); + if (ImGui::DragInt2("##MinimapPlayers", &gWorldInstance.CurrentCourse->Props.Minimap.PlayerX, 1.0f)) {} - ImGui::Text("Player Scale Factor"); - ImGui::SameLine(); - if (ImGui::DragFloat("##MinimapScaleFactor", &gWorldInstance.CurrentCourse->Props.Minimap.PlayerScaleFactor, 0.0001f)) { - } + ImGui::Text("Player Scale Factor"); + ImGui::SameLine(); + if (ImGui::DragFloat("##MinimapScaleFactor", &gWorldInstance.CurrentCourse->Props.Minimap.PlayerScaleFactor, + 0.0001f)) {} - ImGui::Text("Finishline"); - ImGui::SameLine(); - ImGui::DragFloat2("##MinimapFinishlineX", &gWorldInstance.CurrentCourse->Props.Minimap.FinishlineX, 1.0f); + ImGui::Text("Finishline"); + ImGui::SameLine(); + ImGui::DragFloat2("##MinimapFinishlineX", &gWorldInstance.CurrentCourse->Props.Minimap.FinishlineX, 1.0f); - ImGui::Text("Colour"); - ImGui::SameLine(); - ImGui::ColorEdit3("##MinimapColour", minimapColour, 1.0f); - } - - FloatToRGB8(minimapColour, (u8*)&gWorldInstance.CurrentCourse->Props.Minimap.Colour); - - // Convert and pass to ImGui ColorEdit3 - float topRight[3], bottomRight[3], bottomLeft[3], topLeft[3]; - float floorTopRight[3], floorBottomRight[3], floorBottomLeft[3], floorTopLeft[3]; - - // Convert RGB8 (0-255) to float (0.0f to 1.0f) - RGB8ToFloat((u8*)&gWorldInstance.CurrentCourse->Props.Skybox.TopRight, topRight); - RGB8ToFloat((u8*)&gWorldInstance.CurrentCourse->Props.Skybox.BottomRight, bottomRight); - RGB8ToFloat((u8*)&gWorldInstance.CurrentCourse->Props.Skybox.BottomLeft, bottomLeft); - RGB8ToFloat((u8*)&gWorldInstance.CurrentCourse->Props.Skybox.TopLeft, topLeft); - RGB8ToFloat((u8*)&gWorldInstance.CurrentCourse->Props.Skybox.FloorTopRight, floorTopRight); - RGB8ToFloat((u8*)&gWorldInstance.CurrentCourse->Props.Skybox.FloorBottomRight, floorBottomRight); - RGB8ToFloat((u8*)&gWorldInstance.CurrentCourse->Props.Skybox.FloorBottomLeft, floorBottomLeft); - RGB8ToFloat((u8*)&gWorldInstance.CurrentCourse->Props.Skybox.FloorTopLeft, floorTopLeft); - - if (ImGui::CollapsingHeader("Skybox")) { - ImGui::ColorEdit3("Skybox Top Right", topRight); - ImGui::ColorEdit3("Skybox Bottom Right", bottomRight); - ImGui::ColorEdit3("Skybox Bottom Left", bottomLeft); - ImGui::ColorEdit3("Skybox Top Left", topLeft); - ImGui::ColorEdit3("Skybox Floor Top Right", floorTopRight); - ImGui::ColorEdit3("Skybox Floor Bottom Right", floorBottomRight); - ImGui::ColorEdit3("Skybox Floor Bottom Left", floorBottomLeft); - ImGui::ColorEdit3("Skybox Floor Top Left", floorTopLeft); - } + ImGui::Text("Colour"); + ImGui::SameLine(); + ImGui::ColorEdit3("##MinimapColour", minimapColour, 1.0f); + } - // Convert the modified float values back to RGB8 (0-255) - FloatToRGB8(topRight, (u8*)&gWorldInstance.CurrentCourse->Props.Skybox.TopRight); - FloatToRGB8(bottomRight, (u8*)&gWorldInstance.CurrentCourse->Props.Skybox.BottomRight); - FloatToRGB8(bottomLeft, (u8*)&gWorldInstance.CurrentCourse->Props.Skybox.BottomLeft); - FloatToRGB8(topLeft, (u8*)&gWorldInstance.CurrentCourse->Props.Skybox.TopLeft); - FloatToRGB8(floorTopRight, (u8*)&gWorldInstance.CurrentCourse->Props.Skybox.FloorTopRight); - FloatToRGB8(floorBottomRight, (u8*)&gWorldInstance.CurrentCourse->Props.Skybox.FloorBottomRight); - FloatToRGB8(floorBottomLeft, (u8*)&gWorldInstance.CurrentCourse->Props.Skybox.FloorBottomLeft); - FloatToRGB8(floorTopLeft, (u8*)&gWorldInstance.CurrentCourse->Props.Skybox.FloorTopLeft); - - TrackPropertiesWindow::DrawMusic(); + FloatToRGB8(minimapColour, (u8*) &gWorldInstance.CurrentCourse->Props.Minimap.Colour); + + // Convert and pass to ImGui ColorEdit3 + float topRight[3], bottomRight[3], bottomLeft[3], topLeft[3]; + float floorTopRight[3], floorBottomRight[3], floorBottomLeft[3], floorTopLeft[3]; + + // Convert RGB8 (0-255) to float (0.0f to 1.0f) + RGB8ToFloat((u8*) &gWorldInstance.CurrentCourse->Props.Skybox.TopRight, topRight); + RGB8ToFloat((u8*) &gWorldInstance.CurrentCourse->Props.Skybox.BottomRight, bottomRight); + RGB8ToFloat((u8*) &gWorldInstance.CurrentCourse->Props.Skybox.BottomLeft, bottomLeft); + RGB8ToFloat((u8*) &gWorldInstance.CurrentCourse->Props.Skybox.TopLeft, topLeft); + RGB8ToFloat((u8*) &gWorldInstance.CurrentCourse->Props.Skybox.FloorTopRight, floorTopRight); + RGB8ToFloat((u8*) &gWorldInstance.CurrentCourse->Props.Skybox.FloorBottomRight, floorBottomRight); + RGB8ToFloat((u8*) &gWorldInstance.CurrentCourse->Props.Skybox.FloorBottomLeft, floorBottomLeft); + RGB8ToFloat((u8*) &gWorldInstance.CurrentCourse->Props.Skybox.FloorTopLeft, floorTopLeft); + + if (ImGui::CollapsingHeader("Skybox")) { + ImGui::ColorEdit3("Skybox Top Right", topRight); + ImGui::ColorEdit3("Skybox Bottom Right", bottomRight); + ImGui::ColorEdit3("Skybox Bottom Left", bottomLeft); + ImGui::ColorEdit3("Skybox Top Left", topLeft); + ImGui::ColorEdit3("Skybox Floor Top Right", floorTopRight); + ImGui::ColorEdit3("Skybox Floor Bottom Right", floorBottomRight); + ImGui::ColorEdit3("Skybox Floor Bottom Left", floorBottomLeft); + ImGui::ColorEdit3("Skybox Floor Top Left", floorTopLeft); } - void TrackPropertiesWindow::DrawMusic() { - const char* items[] = { - "None", "Title Screen", "Main Menu", "Raceways Wario Stadium", "Moo Moo Farm / Yoshi Valley", - "Choco Mountain", "Koopa Troopa Beach", "Banshee Boardwalk", "Frappe Snowland", "Bowser's Castle", - "Kalimari Desert", "Start Grid GP/VS", "Final Lap Fanfare", "Finish 1st Place", "Finish 2nd-4th Place", - "Finish 5th-8th Place", "16", "Star Jingle", "Rainbow Road", "DK Jungle", "Game Over", "Toad's Turnpike", - "Start Grid Time Attack", "VS Battle Results", "Losing Results", "Battle Arenas", "Award Ceremony Buildup", - "Award Ceremony 1st-3rd", "Staff Roll", "Award Ceremony 4th-8th" - }; - - const char* currentItem = MusicSeqToString(gWorldInstance.CurrentCourse->Props.Sequence); // Get the current selected value's string - - if (ImGui::BeginCombo("Music Sequence", currentItem)) { - for (int i = 0; i < IM_ARRAYSIZE(items); ++i) { - bool isSelected = (currentItem == items[i]); - if (ImGui::Selectable(items[i], isSelected)) { - // Update the sequence when an option is selected - gWorldInstance.CurrentCourse->Props.Sequence = static_cast<MusicSeq>(i); - play_sequence(gWorldInstance.CurrentCourse->Props.Sequence); // Call play_sequence with the updated sequence - - // Update currentItem after selection is made - currentItem = items[i]; - } - if (isSelected) { - ImGui::SetItemDefaultFocus(); - } + // Convert the modified float values back to RGB8 (0-255) + FloatToRGB8(topRight, (u8*) &gWorldInstance.CurrentCourse->Props.Skybox.TopRight); + FloatToRGB8(bottomRight, (u8*) &gWorldInstance.CurrentCourse->Props.Skybox.BottomRight); + FloatToRGB8(bottomLeft, (u8*) &gWorldInstance.CurrentCourse->Props.Skybox.BottomLeft); + FloatToRGB8(topLeft, (u8*) &gWorldInstance.CurrentCourse->Props.Skybox.TopLeft); + FloatToRGB8(floorTopRight, (u8*) &gWorldInstance.CurrentCourse->Props.Skybox.FloorTopRight); + FloatToRGB8(floorBottomRight, (u8*) &gWorldInstance.CurrentCourse->Props.Skybox.FloorBottomRight); + FloatToRGB8(floorBottomLeft, (u8*) &gWorldInstance.CurrentCourse->Props.Skybox.FloorBottomLeft); + FloatToRGB8(floorTopLeft, (u8*) &gWorldInstance.CurrentCourse->Props.Skybox.FloorTopLeft); + + TrackPropertiesWindow::DrawMusic(); +} + +void TrackPropertiesWindow::DrawMusic() { + const char* items[] = { "None", + "Title Screen", + "Main Menu", + "Raceways Wario Stadium", + "Moo Moo Farm / Yoshi Valley", + "Choco Mountain", + "Koopa Troopa Beach", + "Banshee Boardwalk", + "Frappe Snowland", + "Bowser's Castle", + "Kalimari Desert", + "Start Grid GP/VS", + "Final Lap Fanfare", + "Finish 1st Place", + "Finish 2nd-4th Place", + "Finish 5th-8th Place", + "16", + "Star Jingle", + "Rainbow Road", + "DK Jungle", + "Game Over", + "Toad's Turnpike", + "Start Grid Time Attack", + "VS Battle Results", + "Losing Results", + "Battle Arenas", + "Award Ceremony Buildup", + "Award Ceremony 1st-3rd", + "Staff Roll", + "Award Ceremony 4th-8th" }; + + const char* currentItem = + MusicSeqToString(gWorldInstance.CurrentCourse->Props.Sequence); // Get the current selected value's string + + if (ImGui::BeginCombo("Music Sequence", currentItem)) { + for (int i = 0; i < IM_ARRAYSIZE(items); ++i) { + bool isSelected = (currentItem == items[i]); + if (ImGui::Selectable(items[i], isSelected)) { + // Update the sequence when an option is selected + gWorldInstance.CurrentCourse->Props.Sequence = static_cast<MusicSeq>(i); + play_sequence( + gWorldInstance.CurrentCourse->Props.Sequence); // Call play_sequence with the updated sequence + + // Update currentItem after selection is made + currentItem = items[i]; + } + if (isSelected) { + ImGui::SetItemDefaultFocus(); } - ImGui::EndCombo(); } + ImGui::EndCombo(); } +} - // Enum to string conversion - const char* TrackPropertiesWindow::MusicSeqToString(MusicSeq seq) { - switch (seq) { - case MUSIC_SEQ_00: return "None"; - case MUSIC_SEQ_TITLE_SCREEN: return "Title Screen"; - case MUSIC_SEQ_MAIN_MENU: return "Main Menu"; - case MUSIC_SEQ_RACEWAYS_WARIO_STADIUM: return "Raceways Wario Stadium"; - case MUSIC_SEQ_MOO_MOO_FARM_YOSHI_VALLEY: return "Moo Moo Farm / Yoshi Valley"; - case MUSIC_SEQ_CHOCO_MOUNTAIN: return "Choco Mountain"; - case MUSIC_SEQ_KOOPA_TROOPA_BEACH: return "Koopa Troopa Beach"; - case MUSIC_SEQ_BANSHEE_BOARDWALK: return "Banshee Boardwalk"; - case MUSIC_SEQ_FRAPPE_SNOWLAND: return "Frappe Snowland"; - case MUSIC_SEQ_BOWSERS_CASTLE: return "Bowser's Castle"; - case MUSIC_SEQ_KALIMARI_DESERT: return "Kalimari Desert"; - case MUSIC_SEQ_START_GRID_GP_VS: return "Start Grid GP/VS"; - case MUSIC_SEQ_FINAL_LAP_FANFARE: return "Final Lap Fanfare"; - case MUSIC_SEQ_FINISH_1ST_PLACE: return "Finish 1st Place"; - case MUSIC_SEQ_FINISH_2ND_4TH_PLACE: return "Finish 2nd-4th Place"; - case MUSIC_SEQ_FINISH_5TH_8TH_PLACE: return "Finish 5th-8th Place"; - case MUSIC_SEQ_16: return "16"; - case MUSIC_SEQ_STAR_JINGLE: return "Star Jingle"; - case MUSIC_SEQ_RAINBOW_ROAD: return "Rainbow Road"; - case MUSIC_SEQ_DK_JUNGLE: return "DK Jungle"; - case MUSIC_SEQ_GAME_OVER: return "Game Over"; - case MUSIC_SEQ_TOADS_TURNPIKE: return "Toad's Turnpike"; - case MUSIC_SEQ_START_GIRD_TIME_ATTACK: return "Start Grid Time Attack"; - case MUSIC_SEQ_VS_BATTLE_RESULTS: return "VS Battle Results"; - case MUSIC_SEQ_LOSING_RESULTS: return "Losing Results"; - case MUSIC_SEQ_BATTLE_ARENAS: return "Battle Arenas"; - case MUSIC_SEQ_AWARD_CEREMONY_BUILDUP: return "Award Ceremony Buildup"; - case MUSIC_SEQ_AWARD_CEREMONY_1ST_3RD: return "Award Ceremony 1st-3rd"; - case MUSIC_SEQ_STAFF_ROLL: return "Staff Roll"; - case MUSIC_SEQ_AWARD_CEREMONY_4TH_8TH: return "Award Ceremony 4th-8th"; - default: return "None"; - } +// Enum to string conversion +const char* TrackPropertiesWindow::MusicSeqToString(MusicSeq seq) { + switch (seq) { + case MUSIC_SEQ_00: + return "None"; + case MUSIC_SEQ_TITLE_SCREEN: + return "Title Screen"; + case MUSIC_SEQ_MAIN_MENU: + return "Main Menu"; + case MUSIC_SEQ_RACEWAYS_WARIO_STADIUM: + return "Raceways Wario Stadium"; + case MUSIC_SEQ_MOO_MOO_FARM_YOSHI_VALLEY: + return "Moo Moo Farm / Yoshi Valley"; + case MUSIC_SEQ_CHOCO_MOUNTAIN: + return "Choco Mountain"; + case MUSIC_SEQ_KOOPA_TROOPA_BEACH: + return "Koopa Troopa Beach"; + case MUSIC_SEQ_BANSHEE_BOARDWALK: + return "Banshee Boardwalk"; + case MUSIC_SEQ_FRAPPE_SNOWLAND: + return "Frappe Snowland"; + case MUSIC_SEQ_BOWSERS_CASTLE: + return "Bowser's Castle"; + case MUSIC_SEQ_KALIMARI_DESERT: + return "Kalimari Desert"; + case MUSIC_SEQ_START_GRID_GP_VS: + return "Start Grid GP/VS"; + case MUSIC_SEQ_FINAL_LAP_FANFARE: + return "Final Lap Fanfare"; + case MUSIC_SEQ_FINISH_1ST_PLACE: + return "Finish 1st Place"; + case MUSIC_SEQ_FINISH_2ND_4TH_PLACE: + return "Finish 2nd-4th Place"; + case MUSIC_SEQ_FINISH_5TH_8TH_PLACE: + return "Finish 5th-8th Place"; + case MUSIC_SEQ_16: + return "16"; + case MUSIC_SEQ_STAR_JINGLE: + return "Star Jingle"; + case MUSIC_SEQ_RAINBOW_ROAD: + return "Rainbow Road"; + case MUSIC_SEQ_DK_JUNGLE: + return "DK Jungle"; + case MUSIC_SEQ_GAME_OVER: + return "Game Over"; + case MUSIC_SEQ_TOADS_TURNPIKE: + return "Toad's Turnpike"; + case MUSIC_SEQ_START_GIRD_TIME_ATTACK: + return "Start Grid Time Attack"; + case MUSIC_SEQ_VS_BATTLE_RESULTS: + return "VS Battle Results"; + case MUSIC_SEQ_LOSING_RESULTS: + return "Losing Results"; + case MUSIC_SEQ_BATTLE_ARENAS: + return "Battle Arenas"; + case MUSIC_SEQ_AWARD_CEREMONY_BUILDUP: + return "Award Ceremony Buildup"; + case MUSIC_SEQ_AWARD_CEREMONY_1ST_3RD: + return "Award Ceremony 1st-3rd"; + case MUSIC_SEQ_STAFF_ROLL: + return "Staff Roll"; + case MUSIC_SEQ_AWARD_CEREMONY_4TH_8TH: + return "Award Ceremony 4th-8th"; + default: + return "None"; } +} - void TrackPropertiesWindow::DrawLight() { - // Convert and pass to ImGui ColorEdit3 - - - for (int i = 0; i < 2; ++i) { - float ambient[3], diffuse[3], direction[3]; - - RGB8ToFloat((u8*)&D_800DC610[i].a.l.col, ambient); - RGB8ToFloat((u8*)&D_800DC610[i].l->l.col, diffuse); - RGB8ToFloat((u8*)&D_800DC610[i].l->l.dir, direction); - - // Edit the ambient RGB color - ImGui::Text("Light %d - Ambient Color", i + 1); - ImGui::ColorEdit3(("Ambient Color " + std::to_string(i)).c_str(), ambient); // Modify ambient color - - // Edit the diffuse RGB color - ImGui::Text("Light %d - Diffuse Color", i + 1); - ImGui::ColorEdit3(("Diffuse Color " + std::to_string(i)).c_str(), diffuse); // Modify diffuse color - - // Edit the direction RGB color (this could be represented as a direction vector) - ImGui::Text("Light %d - Direction", i + 1); - ImGui::ColorEdit3(("Direction Color " + std::to_string(i)).c_str(), direction); // Modify direction vector color - - FloatToRGB8(ambient, (u8*)&D_800DC610[i].a.l.col); - FloatToRGB8(ambient, (u8*)&D_800DC610[i].a.l.colc); - FloatToRGB8(diffuse, (u8*)&D_800DC610[i].l->l.col); - FloatToRGB8(diffuse, (u8*)&D_800DC610[i].l->l.colc); - FloatToRGB8(direction, (u8*)&D_800DC610[i].l->l.dir); +void TrackPropertiesWindow::DrawLight() { + // Convert and pass to ImGui ColorEdit3 - } - } + for (int i = 0; i < 2; ++i) { + float ambient[3], diffuse[3], direction[3]; - // Convert s16 color values to float (normalized to [0, 1] range) - void TrackPropertiesWindow::RGB8ToFloat(const u8* src, float* dst) { - for (int i = 0; i < 3; ++i) { - dst[i] = src[i] / 255.0f; // Normalize to the range [0.0f, 1.0f] - } + RGB8ToFloat((u8*) &D_800DC610[i].a.l.col, ambient); + RGB8ToFloat((u8*) &D_800DC610[i].l->l.col, diffuse); + RGB8ToFloat((u8*) &D_800DC610[i].l->l.dir, direction); + + // Edit the ambient RGB color + ImGui::Text("Light %d - Ambient Color", i + 1); + ImGui::ColorEdit3(("Ambient Color " + std::to_string(i)).c_str(), ambient); // Modify ambient color + + // Edit the diffuse RGB color + ImGui::Text("Light %d - Diffuse Color", i + 1); + ImGui::ColorEdit3(("Diffuse Color " + std::to_string(i)).c_str(), diffuse); // Modify diffuse color + + // Edit the direction RGB color (this could be represented as a direction vector) + ImGui::Text("Light %d - Direction", i + 1); + ImGui::ColorEdit3(("Direction Color " + std::to_string(i)).c_str(), direction); // Modify direction vector color + + FloatToRGB8(ambient, (u8*) &D_800DC610[i].a.l.col); + FloatToRGB8(ambient, (u8*) &D_800DC610[i].a.l.colc); + FloatToRGB8(diffuse, (u8*) &D_800DC610[i].l->l.col); + FloatToRGB8(diffuse, (u8*) &D_800DC610[i].l->l.colc); + FloatToRGB8(direction, (u8*) &D_800DC610[i].l->l.dir); } +} - void TrackPropertiesWindow::FloatToRGB8(const float* src, u8* dst) { - for (int i = 0; i < 3; ++i) { - dst[i] = static_cast<u8>(src[i] * 255.0f); // Scale to [0, 255] range - } +// Convert s16 color values to float (normalized to [0, 1] range) +void TrackPropertiesWindow::RGB8ToFloat(const u8* src, float* dst) { + for (int i = 0; i < 3; ++i) { + dst[i] = src[i] / 255.0f; // Normalize to the range [0.0f, 1.0f] } +} +void TrackPropertiesWindow::FloatToRGB8(const float* src, u8* dst) { + for (int i = 0; i < 3; ++i) { + dst[i] = static_cast<u8>(src[i] * 255.0f); // Scale to [0, 255] range + } } + +} // namespace Editor diff --git a/src/port/ui/TrackProperties.h b/src/port/ui/TrackProperties.h index 509ff2e70..a6788907b 100644 --- a/src/port/ui/TrackProperties.h +++ b/src/port/ui/TrackProperties.h @@ -8,11 +8,12 @@ extern "C" { namespace Editor { class TrackPropertiesWindow : public Ship::GuiWindow { -public: + public: using Ship::GuiWindow::GuiWindow; ~TrackPropertiesWindow(); -protected: + + protected: void InitElement() override {}; void DrawElement() override; void DrawMusic(); @@ -22,4 +23,4 @@ protected: void FloatToRGB8(const float* src, u8* dst); const char* MusicSeqToString(MusicSeq seq); }; -} +} // namespace Editor diff --git a/src/port/ui/UIWidgets.cpp b/src/port/ui/UIWidgets.cpp index 2495aef4e..7db2772a0 100644 --- a/src/port/ui/UIWidgets.cpp +++ b/src/port/ui/UIWidgets.cpp @@ -288,7 +288,7 @@ bool Checkbox(const char* _label, bool* value, const CheckboxOptions& options) { bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions& options) { bool dirty = false; - bool value = (bool)CVarGetInteger(cvarName, options.defaultValue); + bool value = (bool) CVarGetInteger(cvarName, options.defaultValue); if (Checkbox(label, &value, options)) { CVarSetInteger(cvarName, value); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); @@ -443,8 +443,8 @@ void ClampFloat(float* value, float min, float max, float step) { } else if (*value > max) { *value = max; } else { - int trunc = (int)std::round(*value * factor); - *value = (float)trunc / factor; + int trunc = (int) std::round(*value * factor); + *value = (float) trunc / factor; } } @@ -525,11 +525,11 @@ bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaul ImVec4 colorVec = ImVec4(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, color.a / 255.0f); bool changed = false; PushStyleCombobox(Colors::Gray); - if (ImGui::ColorEdit3(label, (float*)&colorVec, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoBorder)) { - color.r = (uint8_t)(colorVec.x * 255.0f); - color.g = (uint8_t)(colorVec.y * 255.0f); - color.b = (uint8_t)(colorVec.z * 255.0f); - color.a = (uint8_t)(colorVec.w * 255.0f); + if (ImGui::ColorEdit3(label, (float*) &colorVec, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoBorder)) { + color.r = (uint8_t) (colorVec.x * 255.0f); + color.g = (uint8_t) (colorVec.y * 255.0f); + color.b = (uint8_t) (colorVec.z * 255.0f); + color.a = (uint8_t) (colorVec.w * 255.0f); CVarSetColor(cvarName, color); Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); changed = true; diff --git a/src/port/ui/UIWidgets.h b/src/port/ui/UIWidgets.h index 079c66869..46f8110e7 100644 --- a/src/port/ui/UIWidgets.h +++ b/src/port/ui/UIWidgets.h @@ -13,699 +13,704 @@ namespace UIWidgets { - using SectionFunc = void(*)(); +using SectionFunc = void (*)(); - struct TextFilters { - static int FilterNumbers(ImGuiInputTextCallbackData* data) { - if (data->EventChar < 256 && strchr("1234567890", (char)data->EventChar)) { - return 0; - } - return 1; +struct TextFilters { + static int FilterNumbers(ImGuiInputTextCallbackData* data) { + if (data->EventChar < 256 && strchr("1234567890", (char) data->EventChar)) { + return 0; } + return 1; + } - static int FilterAlphaNum(ImGuiInputTextCallbackData* data) { - const char* alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789"; - if (data->EventChar < 256 && strchr(alphanum, (char)data->EventChar)) { - return 0; - } - return 1; - } - }; - - std::string WrappedText(const char* text, unsigned int charactersPerLine = 60); - std::string WrappedText(const std::string& text, unsigned int charactersPerLine = 60); - void Tooltip(const char* text); - - // mostly in order for colors usable by the menu without custom text color - enum Colors { - Red, - DarkRed, - Orange, - Green, - DarkGreen, - LightBlue, - Blue, - DarkBlue, - Indigo, - Violet, - Purple, - Brown, - Gray, - DarkGray, - // not suitable for menu theme use - Pink, - Yellow, - Cyan, - Black, - LightGray, - White, - NoColor - }; - - const std::unordered_map<Colors, ImVec4> ColorValues = { - { Colors::Pink, ImVec4(0.87f, 0.3f, 0.87f, 1.0f) }, - { Colors::Red, ImVec4(0.55f, 0.0f, 0.0f, 1.0f) }, - { Colors::DarkRed, ImVec4(0.3f, 0.0f, 0.0f, 1.0f) }, - { Colors::Orange, ImVec4(0.85f, 0.55f, 0.0f, 1.0f) }, - { Colors::Yellow, ImVec4(0.95f, 0.95f, 0.0f, 1.0f) }, - { Colors::Green, ImVec4(0.0f, 0.55f, 0.0f, 1.0f) }, - { Colors::DarkGreen, ImVec4(0.0f, 0.3f, 0.0f, 1.0f) }, - { Colors::Cyan, ImVec4(0.0f, 0.9f, 0.9f, 1.0f) }, - { Colors::LightBlue, ImVec4(0.0f, 0.24f, 0.8f, 1.0f) }, - { Colors::Blue, ImVec4(0.08f, 0.03f, 0.65f, 1.0f) }, - { Colors::DarkBlue, ImVec4(0.03f, 0.0f, 0.5f, 1.0f) }, - { Colors::Indigo, ImVec4(0.35f, 0.0f, 0.87f, 1.0f) }, - { Colors::Violet, ImVec4(0.5f, 0.0f, 0.9f, 1.0f) }, - { Colors::Purple, ImVec4(0.31f, 0.0f, 0.67f, 1.0f) }, - { Colors::Brown, ImVec4(0.37f, 0.18f, 0.0f, 1.0f) }, - { Colors::LightGray, ImVec4(0.75f, 0.75f, 0.75f, 1.0f) }, - { Colors::Gray, ImVec4(0.45f, 0.45f, 0.45f, 1.0f) }, - { Colors::DarkGray, ImVec4(0.15f, 0.15f, 0.15f, 1.0f) }, - { Colors::Black, ImVec4(0.0f, 0.0f, 0.0f, 1.0f)}, - { Colors::White, ImVec4(1.0f, 1.0f, 1.0f, 1.0f) }, - { Colors::NoColor, ImVec4(0.0f, 0.0f, 0.0f, 0.0f)}, - }; - - namespace Sizes { - const ImVec2 Inline = ImVec2(0.0f, 0.0f); - const ImVec2 Fill = ImVec2(-1.0f, 0.0f); - } - - enum LabelPosition { - Near, - Far, - Above, - None, - Within, - }; - - enum ComponentAlignment { - Left, - Right, - }; - - struct WidgetOptions{ - const char* tooltip = ""; - bool disabled = false; - const char* disabledTooltip = ""; - Colors color = Colors::NoColor; - - WidgetOptions& Color(Colors color_) { - color = color = color_; - return *this; - } - WidgetOptions& Tooltip(const char* tooltip_) { - tooltip = tooltip_; - return *this; + static int FilterAlphaNum(ImGuiInputTextCallbackData* data) { + const char* alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789"; + if (data->EventChar < 256 && strchr(alphanum, (char) data->EventChar)) { + return 0; } - WidgetOptions& Disabled(bool disabled_) { - disabled = disabled_; - return *this; - } - }; + return 1; + } +}; + +std::string WrappedText(const char* text, unsigned int charactersPerLine = 60); +std::string WrappedText(const std::string& text, unsigned int charactersPerLine = 60); +void Tooltip(const char* text); + +// mostly in order for colors usable by the menu without custom text color +enum Colors { + Red, + DarkRed, + Orange, + Green, + DarkGreen, + LightBlue, + Blue, + DarkBlue, + Indigo, + Violet, + Purple, + Brown, + Gray, + DarkGray, + // not suitable for menu theme use + Pink, + Yellow, + Cyan, + Black, + LightGray, + White, + NoColor +}; + +const std::unordered_map<Colors, ImVec4> ColorValues = { + { Colors::Pink, ImVec4(0.87f, 0.3f, 0.87f, 1.0f) }, { Colors::Red, ImVec4(0.55f, 0.0f, 0.0f, 1.0f) }, + { Colors::DarkRed, ImVec4(0.3f, 0.0f, 0.0f, 1.0f) }, { Colors::Orange, ImVec4(0.85f, 0.55f, 0.0f, 1.0f) }, + { Colors::Yellow, ImVec4(0.95f, 0.95f, 0.0f, 1.0f) }, { Colors::Green, ImVec4(0.0f, 0.55f, 0.0f, 1.0f) }, + { Colors::DarkGreen, ImVec4(0.0f, 0.3f, 0.0f, 1.0f) }, { Colors::Cyan, ImVec4(0.0f, 0.9f, 0.9f, 1.0f) }, + { Colors::LightBlue, ImVec4(0.0f, 0.24f, 0.8f, 1.0f) }, { Colors::Blue, ImVec4(0.08f, 0.03f, 0.65f, 1.0f) }, + { Colors::DarkBlue, ImVec4(0.03f, 0.0f, 0.5f, 1.0f) }, { Colors::Indigo, ImVec4(0.35f, 0.0f, 0.87f, 1.0f) }, + { Colors::Violet, ImVec4(0.5f, 0.0f, 0.9f, 1.0f) }, { Colors::Purple, ImVec4(0.31f, 0.0f, 0.67f, 1.0f) }, + { Colors::Brown, ImVec4(0.37f, 0.18f, 0.0f, 1.0f) }, { Colors::LightGray, ImVec4(0.75f, 0.75f, 0.75f, 1.0f) }, + { Colors::Gray, ImVec4(0.45f, 0.45f, 0.45f, 1.0f) }, { Colors::DarkGray, ImVec4(0.15f, 0.15f, 0.15f, 1.0f) }, + { Colors::Black, ImVec4(0.0f, 0.0f, 0.0f, 1.0f) }, { Colors::White, ImVec4(1.0f, 1.0f, 1.0f, 1.0f) }, + { Colors::NoColor, ImVec4(0.0f, 0.0f, 0.0f, 0.0f) }, +}; + +namespace Sizes { +const ImVec2 Inline = ImVec2(0.0f, 0.0f); +const ImVec2 Fill = ImVec2(-1.0f, 0.0f); +} // namespace Sizes + +enum LabelPosition { + Near, + Far, + Above, + None, + Within, +}; + +enum ComponentAlignment { + Left, + Right, +}; + +struct WidgetOptions { + const char* tooltip = ""; + bool disabled = false; + const char* disabledTooltip = ""; + Colors color = Colors::NoColor; + + WidgetOptions& Color(Colors color_) { + color = color = color_; + return *this; + } + WidgetOptions& Tooltip(const char* tooltip_) { + tooltip = tooltip_; + return *this; + } + WidgetOptions& Disabled(bool disabled_) { + disabled = disabled_; + return *this; + } +}; - struct ButtonOptions : WidgetOptions { - ImVec2 size = Sizes::Fill; - Colors color = Colors::Gray; +struct ButtonOptions : WidgetOptions { + ImVec2 size = Sizes::Fill; + Colors color = Colors::Gray; - ButtonOptions& Size(ImVec2 size_) { - size = size_; - return *this; - } - ButtonOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - ButtonOptions& Color(Colors color_) { - WidgetOptions::color = color = color_; - return *this; - } - }; + ButtonOptions& Size(ImVec2 size_) { + size = size_; + return *this; + } + ButtonOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + ButtonOptions& Color(Colors color_) { + WidgetOptions::color = color = color_; + return *this; + } +}; - struct CheckboxOptions : WidgetOptions { - bool defaultValue = false; // Only applicable to CVarCheckbox - ComponentAlignment alignment = ComponentAlignment::Left; - LabelPosition labelPosition = LabelPosition::Near; - Colors color = WidgetOptions::color = Colors::LightBlue; +struct CheckboxOptions : WidgetOptions { + bool defaultValue = false; // Only applicable to CVarCheckbox + ComponentAlignment alignment = ComponentAlignment::Left; + LabelPosition labelPosition = LabelPosition::Near; + Colors color = WidgetOptions::color = Colors::LightBlue; - CheckboxOptions& DefaultValue(bool defaultValue_) { - defaultValue = defaultValue_; - return *this; - } - CheckboxOptions& ComponentAlignment(ComponentAlignment alignment_) { - alignment = alignment_; - return *this; - } - CheckboxOptions& LabelPosition(LabelPosition labelPosition_) { - labelPosition = labelPosition_; - return *this; - } - CheckboxOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - CheckboxOptions& Color(Colors color_) { - WidgetOptions::color = color = color_; - return *this; - } - }; - - struct ComboboxOptions : WidgetOptions { - std::unordered_map<int32_t, const char*> comboMap = {}; - uint32_t defaultIndex = 0; // Only applicable to CVarCombobox - ComponentAlignment alignment = ComponentAlignment::Left; - LabelPosition labelPosition = LabelPosition::Above; - ImGuiComboFlags flags = 0; - Colors color = Colors::LightBlue; - - ComboboxOptions& ComboMap(std::unordered_map<int32_t, const char*> comboMap_) { - comboMap = comboMap_; - return *this; - } - ComboboxOptions& DefaultIndex(uint32_t defaultIndex_) { - defaultIndex = defaultIndex_; - return *this; - } - ComboboxOptions& ComponentAlignment(ComponentAlignment alignment_) { - alignment = alignment_; - return *this; - } - ComboboxOptions& LabelPosition(LabelPosition labelPosition_) { - labelPosition = labelPosition_; - return *this; - } - ComboboxOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - ComboboxOptions& Color(Colors color_) { - WidgetOptions::color = color = color_; - return *this; - } - }; - - struct IntSliderOptions : WidgetOptions { - bool showButtons = true; - const char* format = "%d"; - int32_t step = 1; - int32_t min = 1; - int32_t max = 10; - int32_t defaultValue = 1; - ComponentAlignment alignment = ComponentAlignment::Left; - LabelPosition labelPosition = LabelPosition::Above; - Colors color = Colors::Gray; - ImGuiSliderFlags flags = 0; - - IntSliderOptions& ShowButtons(bool showButtons_) { - showButtons = showButtons_; - return *this; - } - IntSliderOptions& Format(const char* format_) { - format = format_; - return *this; - } - IntSliderOptions& Step(int32_t step_) { - step = step_; - return *this; - } - IntSliderOptions& Min(int32_t min_) { - min = min_; - return *this; - } - IntSliderOptions& Max(int32_t max_) { - max = max_; - return *this; - } - IntSliderOptions& DefaultValue(int32_t defaultValue_) { - defaultValue = defaultValue_; - return *this; - } - IntSliderOptions& ComponentAlignment(ComponentAlignment alignment_) { - alignment = alignment_; - return *this; - } - IntSliderOptions& LabelPosition(LabelPosition labelPosition_) { - labelPosition = labelPosition_; - return *this; - } - IntSliderOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - IntSliderOptions& Color(Colors color_) { - WidgetOptions::color = color = color_; - return *this; - } - }; - - struct FloatSliderOptions : WidgetOptions { - bool showButtons = true; - const char* format = "%f"; - float step = 0.01f; - float min = 0.01f; - float max = 10.0f; - float defaultValue = 1.0f; - bool isPercentage = false; // Multiplies visual value by 100 - ComponentAlignment alignment = ComponentAlignment::Left; - LabelPosition labelPosition = LabelPosition::Above; - Colors color = Colors::Gray; - ImGuiSliderFlags flags = 0; - - FloatSliderOptions& ShowButtons(bool showButtons_) { - showButtons = showButtons_; - return *this; - } - FloatSliderOptions& Format(const char* format_) { - format = format_; - return *this; - } - FloatSliderOptions& Step(float step_) { - step = step_; - return *this; - } - FloatSliderOptions& Min(float min_) { - min = min_; - return *this; - } - FloatSliderOptions& Max(float max_) { - max = max_; - return *this; - } - FloatSliderOptions& DefaultValue(float defaultValue_) { - defaultValue = defaultValue_; - return *this; - } - FloatSliderOptions& ComponentAlignment(ComponentAlignment alignment_) { - alignment = alignment_; - return *this; - } - FloatSliderOptions& LabelPosition(LabelPosition labelPosition_) { - labelPosition = labelPosition_; - return *this; - } - FloatSliderOptions& IsPercentage(bool isPercentage_ = true) { - isPercentage = isPercentage_; - format = "%.0f"; - min = 0.0f; - max = 1.0f; - return *this; - } - FloatSliderOptions& Tooltip(const char* tooltip_) { - WidgetOptions::tooltip = tooltip_; - return *this; - } - FloatSliderOptions& Color(Colors color_) { - WidgetOptions::color = color = color_; - return *this; - } - }; - - void PushStyleMenu(const ImVec4& color); - void PushStyleMenu(Colors color = Colors::LightBlue); - void PopStyleMenu(); - bool BeginMenu(const char* label, Colors color = Colors::LightBlue); - - void PushStyleMenuItem(const ImVec4& color); - void PushStyleMenuItem(Colors color = Colors::LightBlue); - void PopStyleMenuItem(); - bool MenuItem(const char* label, const char* shortcut = NULL, Colors color = Colors::LightBlue); - - void PushStyleButton(const ImVec4& color); - void PushStyleButton(Colors color = Colors::Gray); - void PopStyleButton(); - bool Button(const char* label, const ButtonOptions& options = {}); - bool WindowButton(const char* label, const char* cvarName, std::shared_ptr<Ship::GuiWindow> windowPtr, const ButtonOptions& options = {}); - - void PushStyleCheckbox(const ImVec4& color); - void PushStyleCheckbox(Colors color = Colors::LightBlue); - void PopStyleCheckbox(); - void RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash); - bool Checkbox(const char* label, bool* v, const CheckboxOptions& options = {}); - bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions& options = {}); - - void PushStyleCombobox(const ImVec4& color); - void PushStyleCombobox(Colors color = Colors::LightBlue); - void PopStyleCombobox(); - - /*using ComboVariant = std::variant<const std::unordered_map<int32_t, const char*>&, const std::vector<const char*>&>; - - bool Combobox(const char* label, int32_t* value, ComboVariant comboSource, const ComboboxOptions& options = {}) { - bool dirty = false; - float startX = ImGui::GetCursorPosX(); - std::string invisibleLabelStr = "##" + std::string(label); - const char* invisibleLabel = invisibleLabelStr.c_str(); - ImGui::PushID(label); - ImGui::BeginGroup(); - ImGui::BeginDisabled(options.disabled); - PushStyleCombobox(options.color); - if (options.alignment == ComponentAlignment::Left) { - if (options.labelPosition == LabelPosition::Above) { - ImGui::Text("%s", label); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Near) { - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2); - } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { - ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x); - } - } else if (options.alignment == ComponentAlignment::Right) { - if (options.labelPosition == LabelPosition::Above) { - ImGui::NewLine(); - ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); - ImGui::Text("%s", label); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Near) { - ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { - float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4; - ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } + CheckboxOptions& DefaultValue(bool defaultValue_) { + defaultValue = defaultValue_; + return *this; + } + CheckboxOptions& ComponentAlignment(ComponentAlignment alignment_) { + alignment = alignment_; + return *this; + } + CheckboxOptions& LabelPosition(LabelPosition labelPosition_) { + labelPosition = labelPosition_; + return *this; + } + CheckboxOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + CheckboxOptions& Color(Colors color_) { + WidgetOptions::color = color = color_; + return *this; + } +}; + +struct ComboboxOptions : WidgetOptions { + std::unordered_map<int32_t, const char*> comboMap = {}; + uint32_t defaultIndex = 0; // Only applicable to CVarCombobox + ComponentAlignment alignment = ComponentAlignment::Left; + LabelPosition labelPosition = LabelPosition::Above; + ImGuiComboFlags flags = 0; + Colors color = Colors::LightBlue; + + ComboboxOptions& ComboMap(std::unordered_map<int32_t, const char*> comboMap_) { + comboMap = comboMap_; + return *this; + } + ComboboxOptions& DefaultIndex(uint32_t defaultIndex_) { + defaultIndex = defaultIndex_; + return *this; + } + ComboboxOptions& ComponentAlignment(ComponentAlignment alignment_) { + alignment = alignment_; + return *this; + } + ComboboxOptions& LabelPosition(LabelPosition labelPosition_) { + labelPosition = labelPosition_; + return *this; + } + ComboboxOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + ComboboxOptions& Color(Colors color_) { + WidgetOptions::color = color = color_; + return *this; + } +}; + +struct IntSliderOptions : WidgetOptions { + bool showButtons = true; + const char* format = "%d"; + int32_t step = 1; + int32_t min = 1; + int32_t max = 10; + int32_t defaultValue = 1; + ComponentAlignment alignment = ComponentAlignment::Left; + LabelPosition labelPosition = LabelPosition::Above; + Colors color = Colors::Gray; + ImGuiSliderFlags flags = 0; + + IntSliderOptions& ShowButtons(bool showButtons_) { + showButtons = showButtons_; + return *this; + } + IntSliderOptions& Format(const char* format_) { + format = format_; + return *this; + } + IntSliderOptions& Step(int32_t step_) { + step = step_; + return *this; + } + IntSliderOptions& Min(int32_t min_) { + min = min_; + return *this; + } + IntSliderOptions& Max(int32_t max_) { + max = max_; + return *this; + } + IntSliderOptions& DefaultValue(int32_t defaultValue_) { + defaultValue = defaultValue_; + return *this; + } + IntSliderOptions& ComponentAlignment(ComponentAlignment alignment_) { + alignment = alignment_; + return *this; + } + IntSliderOptions& LabelPosition(LabelPosition labelPosition_) { + labelPosition = labelPosition_; + return *this; + } + IntSliderOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + IntSliderOptions& Color(Colors color_) { + WidgetOptions::color = color = color_; + return *this; + } +}; + +struct FloatSliderOptions : WidgetOptions { + bool showButtons = true; + const char* format = "%f"; + float step = 0.01f; + float min = 0.01f; + float max = 10.0f; + float defaultValue = 1.0f; + bool isPercentage = false; // Multiplies visual value by 100 + ComponentAlignment alignment = ComponentAlignment::Left; + LabelPosition labelPosition = LabelPosition::Above; + Colors color = Colors::Gray; + ImGuiSliderFlags flags = 0; + + FloatSliderOptions& ShowButtons(bool showButtons_) { + showButtons = showButtons_; + return *this; + } + FloatSliderOptions& Format(const char* format_) { + format = format_; + return *this; + } + FloatSliderOptions& Step(float step_) { + step = step_; + return *this; + } + FloatSliderOptions& Min(float min_) { + min = min_; + return *this; + } + FloatSliderOptions& Max(float max_) { + max = max_; + return *this; + } + FloatSliderOptions& DefaultValue(float defaultValue_) { + defaultValue = defaultValue_; + return *this; + } + FloatSliderOptions& ComponentAlignment(ComponentAlignment alignment_) { + alignment = alignment_; + return *this; + } + FloatSliderOptions& LabelPosition(LabelPosition labelPosition_) { + labelPosition = labelPosition_; + return *this; + } + FloatSliderOptions& IsPercentage(bool isPercentage_ = true) { + isPercentage = isPercentage_; + format = "%.0f"; + min = 0.0f; + max = 1.0f; + return *this; + } + FloatSliderOptions& Tooltip(const char* tooltip_) { + WidgetOptions::tooltip = tooltip_; + return *this; + } + FloatSliderOptions& Color(Colors color_) { + WidgetOptions::color = color = color_; + return *this; + } +}; + +void PushStyleMenu(const ImVec4& color); +void PushStyleMenu(Colors color = Colors::LightBlue); +void PopStyleMenu(); +bool BeginMenu(const char* label, Colors color = Colors::LightBlue); + +void PushStyleMenuItem(const ImVec4& color); +void PushStyleMenuItem(Colors color = Colors::LightBlue); +void PopStyleMenuItem(); +bool MenuItem(const char* label, const char* shortcut = NULL, Colors color = Colors::LightBlue); + +void PushStyleButton(const ImVec4& color); +void PushStyleButton(Colors color = Colors::Gray); +void PopStyleButton(); +bool Button(const char* label, const ButtonOptions& options = {}); +bool WindowButton(const char* label, const char* cvarName, std::shared_ptr<Ship::GuiWindow> windowPtr, + const ButtonOptions& options = {}); + +void PushStyleCheckbox(const ImVec4& color); +void PushStyleCheckbox(Colors color = Colors::LightBlue); +void PopStyleCheckbox(); +void RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash); +bool Checkbox(const char* label, bool* v, const CheckboxOptions& options = {}); +bool CVarCheckbox(const char* label, const char* cvarName, const CheckboxOptions& options = {}); + +void PushStyleCombobox(const ImVec4& color); +void PushStyleCombobox(Colors color = Colors::LightBlue); +void PopStyleCombobox(); + +/*using ComboVariant = std::variant<const std::unordered_map<int32_t, const char*>&, const std::vector<const char*>&>; + +bool Combobox(const char* label, int32_t* value, ComboVariant comboSource, const ComboboxOptions& options = {}) { + bool dirty = false; + float startX = ImGui::GetCursorPosX(); + std::string invisibleLabelStr = "##" + std::string(label); + const char* invisibleLabel = invisibleLabelStr.c_str(); + ImGui::PushID(label); + ImGui::BeginGroup(); + ImGui::BeginDisabled(options.disabled); + PushStyleCombobox(options.color); + if (options.alignment == ComponentAlignment::Left) { + if (options.labelPosition == LabelPosition::Above) { + ImGui::Text("%s", label); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Near) { + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - +ImGui::GetStyle().ItemSpacing.x * 2); } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == +LabelPosition::None) { ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboMap.at(*value)).x + +ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x); + } + } else if (options.alignment == ComponentAlignment::Right) { + if (options.labelPosition == LabelPosition::Above) { + ImGui::NewLine(); + ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); + ImGui::Text("%s", label); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Near) { + ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { + float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4; + ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); } - if (ImGui::BeginCombo(invisibleLabel, comboMap.at(*value), options.flags)) { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); - for (const auto& pair : comboMap) { - if (strlen(pair.second) > 1) { - if (ImGui::Selectable(pair.second, pair.first == *value)) { - *value = pair.first; - dirty = true; - } + } + if (ImGui::BeginCombo(invisibleLabel, comboMap.at(*value), options.flags)) { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); + for (const auto& pair : comboMap) { + if (strlen(pair.second) > 1) { + if (ImGui::Selectable(pair.second, pair.first == *value)) { + *value = pair.first; + dirty = true; } } - ImGui::PopStyleVar(); - ImGui::EndCombo(); } - if (options.alignment == ComponentAlignment::Left) { - if (options.labelPosition == LabelPosition::Near) { - ImGui::SameLine(); - ImGui::Text("%s", label); - } else if (options.labelPosition == LabelPosition::Far) { - ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); - ImGui::Text("%s", label); - } - } else if (options.alignment == ComponentAlignment::Right) { - if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) { - ImGui::SameLine(startX); - ImGui::Text("%s", label); - } - } - PopStyleCombobox(); - ImGui::EndDisabled(); - ImGui::EndGroup(); - if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); - } - ImGui::PopID(); - return dirty; - } - - bool CVarCombobox(const char* label, const char* cvarName, ComboVariant comboSource, const ComboboxOptions& options = {}) { - bool dirty = false; - int32_t value = CVarGetInteger(cvarName, options.defaultIndex); - if (Combobox(label, &value, comboSource, options)) { - CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - ShipInit::Init(cvarName); - dirty = true; + ImGui::PopStyleVar(); + ImGui::EndCombo(); + } + if (options.alignment == ComponentAlignment::Left) { + if (options.labelPosition == LabelPosition::Near) { + ImGui::SameLine(); + ImGui::Text("%s", label); + } else if (options.labelPosition == LabelPosition::Far) { + ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); + ImGui::Text("%s", label); + } + } else if (options.alignment == ComponentAlignment::Right) { + if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) { + ImGui::SameLine(startX); + ImGui::Text("%s", label); } - return dirty; - }*/ - - template <typename T> - bool Combobox(const char* label, T* value, const std::unordered_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); - ImGui::BeginGroup(); - ImGui::BeginDisabled(options.disabled); - PushStyleCombobox(options.color); - if (options.alignment == ComponentAlignment::Left) { - if (options.labelPosition == LabelPosition::Above) { - ImGui::Text("%s", label); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Near) { - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2); - } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { - ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x); - } - } else if (options.alignment == ComponentAlignment::Right) { - if (options.labelPosition == LabelPosition::Above) { - ImGui::NewLine(); - ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); - ImGui::Text("%s", label); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Near) { - ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { - float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4; - ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } + } + PopStyleCombobox(); + ImGui::EndDisabled(); + ImGui::EndGroup(); + if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && +!Ship_IsCStringEmpty(options.disabledTooltip)) { ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); + } + ImGui::PopID(); + return dirty; +} + +bool CVarCombobox(const char* label, const char* cvarName, ComboVariant comboSource, const ComboboxOptions& options = +{}) { bool dirty = false; int32_t value = CVarGetInteger(cvarName, options.defaultIndex); if (Combobox(label, &value, +comboSource, options)) { CVarSetInteger(cvarName, value); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + ShipInit::Init(cvarName); + dirty = true; + } + return dirty; +}*/ + +template <typename T> +bool Combobox(const char* label, T* value, const std::unordered_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); + ImGui::BeginGroup(); + ImGui::BeginDisabled(options.disabled); + PushStyleCombobox(options.color); + if (options.alignment == ComponentAlignment::Left) { + if (options.labelPosition == LabelPosition::Above) { + ImGui::Text("%s", label); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Near) { + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - + ImGui::GetStyle().ItemSpacing.x * 2); + } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { + ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4 + + ImGui::GetStyle().ItemSpacing.x); + } + } else if (options.alignment == ComponentAlignment::Right) { + if (options.labelPosition == LabelPosition::Above) { + ImGui::NewLine(); + ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); + ImGui::Text("%s", label); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Near) { + ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { + float width = ImGui::CalcTextSize(comboMap.at(*value)).x + ImGui::GetStyle().FramePadding.x * 4; + ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); } - if (ImGui::BeginCombo(invisibleLabel, comboMap.at(*value), options.flags)) { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); - for (const auto& pair : comboMap) { - if (strlen(pair.second) > 1) { - if (ImGui::Selectable(pair.second, pair.first == *value)) { - *value = pair.first; - dirty = true; - } + } + if (ImGui::BeginCombo(invisibleLabel, comboMap.at(*value), options.flags)) { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); + for (const auto& pair : comboMap) { + if (strlen(pair.second) > 1) { + if (ImGui::Selectable(pair.second, pair.first == *value)) { + *value = pair.first; + dirty = true; } } - ImGui::PopStyleVar(); - ImGui::EndCombo(); } - if (options.alignment == ComponentAlignment::Left) { - if (options.labelPosition == LabelPosition::Near) { - ImGui::SameLine(); - ImGui::Text("%s", label); - } else if (options.labelPosition == LabelPosition::Far) { - ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); - ImGui::Text("%s", label); - } - } else if (options.alignment == ComponentAlignment::Right) { - if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) { - ImGui::SameLine(startX); - ImGui::Text("%s", label); - } - } - PopStyleCombobox(); - ImGui::EndDisabled(); - ImGui::EndGroup(); - if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); + ImGui::PopStyleVar(); + ImGui::EndCombo(); + } + if (options.alignment == ComponentAlignment::Left) { + if (options.labelPosition == LabelPosition::Near) { + ImGui::SameLine(); + ImGui::Text("%s", label); + } else if (options.labelPosition == LabelPosition::Far) { + ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); + ImGui::Text("%s", label); + } + } else if (options.alignment == ComponentAlignment::Right) { + if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) { + ImGui::SameLine(startX); + ImGui::Text("%s", label); } - ImGui::PopID(); - return dirty; - } - - template <typename T = size_t> - bool Combobox(const char* label, T* value, const std::vector<const char*>& comboVector, const ComboboxOptions& options = {}) { - bool dirty = false; - float startX = ImGui::GetCursorPosX(); - size_t currentValueIndex = static_cast<size_t>(*value); - std::string invisibleLabelStr = "##" + std::string(label); - const char* invisibleLabel = invisibleLabelStr.c_str(); - ImGui::PushID(label); - ImGui::BeginGroup(); - ImGui::BeginDisabled(options.disabled); - PushStyleCombobox(options.color); - if (options.alignment == ComponentAlignment::Left) { - if (options.labelPosition == LabelPosition::Above) { - ImGui::Text(label); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Near) { - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2); - } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { - ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboVector.at(currentValueIndex)).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x); - } - } else if (options.alignment == ComponentAlignment::Right) { - if (options.labelPosition == LabelPosition::Above) { - ImGui::NewLine(); - ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); - ImGui::Text(label); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Near) { - ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { - float width = ImGui::CalcTextSize(comboVector.at(currentValueIndex)).x + ImGui::GetStyle().FramePadding.x * 4; - ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } + } + PopStyleCombobox(); + ImGui::EndDisabled(); + ImGui::EndGroup(); + if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && + !Ship_IsCStringEmpty(options.disabledTooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); + } + ImGui::PopID(); + return dirty; +} + +template <typename T = size_t> +bool Combobox(const char* label, T* value, const std::vector<const char*>& comboVector, + const ComboboxOptions& options = {}) { + bool dirty = false; + float startX = ImGui::GetCursorPosX(); + size_t currentValueIndex = static_cast<size_t>(*value); + std::string invisibleLabelStr = "##" + std::string(label); + const char* invisibleLabel = invisibleLabelStr.c_str(); + ImGui::PushID(label); + ImGui::BeginGroup(); + ImGui::BeginDisabled(options.disabled); + PushStyleCombobox(options.color); + if (options.alignment == ComponentAlignment::Left) { + if (options.labelPosition == LabelPosition::Above) { + ImGui::Text(label); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Near) { + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - + ImGui::GetStyle().ItemSpacing.x * 2); + } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { + ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboVector.at(currentValueIndex)).x + + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x); + } + } else if (options.alignment == ComponentAlignment::Right) { + if (options.labelPosition == LabelPosition::Above) { + ImGui::NewLine(); + ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); + ImGui::Text(label); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Near) { + ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { + float width = + ImGui::CalcTextSize(comboVector.at(currentValueIndex)).x + ImGui::GetStyle().FramePadding.x * 4; + ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); } - if (ImGui::BeginCombo(invisibleLabel, comboVector.at(currentValueIndex), options.flags)) { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); - for (size_t i = 0; i < comboVector.size(); ++i) { - auto newValue = static_cast<T>(i); - if (strlen(comboVector.at(i)) > 1) { - if (ImGui::Selectable(comboVector.at(i), newValue == *value)) { - *value = newValue; - dirty = true; - } + } + if (ImGui::BeginCombo(invisibleLabel, comboVector.at(currentValueIndex), options.flags)) { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); + for (size_t i = 0; i < comboVector.size(); ++i) { + auto newValue = static_cast<T>(i); + if (strlen(comboVector.at(i)) > 1) { + if (ImGui::Selectable(comboVector.at(i), newValue == *value)) { + *value = newValue; + dirty = true; } } - ImGui::PopStyleVar(); - ImGui::EndCombo(); } - if (options.alignment == ComponentAlignment::Left) { - if (options.labelPosition == LabelPosition::Near) { - ImGui::SameLine(); - ImGui::Text(label); - } else if (options.labelPosition == LabelPosition::Far) { - ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); - ImGui::Text(label); - } - } else if (options.alignment == ComponentAlignment::Right) { - if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) { - ImGui::SameLine(startX); - ImGui::Text(label); - } - } - PopStyleCombobox(); - ImGui::EndDisabled(); - ImGui::EndGroup(); - if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); + ImGui::PopStyleVar(); + ImGui::EndCombo(); + } + if (options.alignment == ComponentAlignment::Left) { + if (options.labelPosition == LabelPosition::Near) { + ImGui::SameLine(); + ImGui::Text(label); + } else if (options.labelPosition == LabelPosition::Far) { + ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); + ImGui::Text(label); + } + } else if (options.alignment == ComponentAlignment::Right) { + if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) { + ImGui::SameLine(startX); + ImGui::Text(label); } - ImGui::PopID(); - return dirty; } + PopStyleCombobox(); + ImGui::EndDisabled(); + ImGui::EndGroup(); + if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && + !Ship_IsCStringEmpty(options.disabledTooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); + } + ImGui::PopID(); + return dirty; +} - template <typename T = size_t, size_t N> - bool Combobox(const char* label, T* value, const char* (&comboArray)[N], const ComboboxOptions& options = {}) { - bool dirty = false; - float startX = ImGui::GetCursorPosX(); - size_t currentValueIndex = static_cast<size_t>(*value); - if (currentValueIndex >= N) { - currentValueIndex = 0; - } - std::string invisibleLabelStr = "##" + std::string(label); - const char* invisibleLabel = invisibleLabelStr.c_str(); - ImGui::PushID(label); - ImGui::BeginGroup(); - ImGui::BeginDisabled(options.disabled); - PushStyleCombobox(options.color); - if (options.alignment == ComponentAlignment::Left) { - if (options.labelPosition == LabelPosition::Above) { - ImGui::Text("%s", label); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Near) { - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - ImGui::GetStyle().ItemSpacing.x * 2); - } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { - ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboArray[currentValueIndex]).x + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x); - } - } else if (options.alignment == ComponentAlignment::Right) { - if (options.labelPosition == LabelPosition::Above) { - ImGui::NewLine(); - ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); - ImGui::Text("%s", label); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Near) { - ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { - float width = ImGui::CalcTextSize(comboArray[currentValueIndex]).x + ImGui::GetStyle().FramePadding.x * 4; - ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); - ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); - } +template <typename T = size_t, size_t N> +bool Combobox(const char* label, T* value, const char* (&comboArray)[N], const ComboboxOptions& options = {}) { + bool dirty = false; + float startX = ImGui::GetCursorPosX(); + size_t currentValueIndex = static_cast<size_t>(*value); + if (currentValueIndex >= N) { + currentValueIndex = 0; + } + std::string invisibleLabelStr = "##" + std::string(label); + const char* invisibleLabel = invisibleLabelStr.c_str(); + ImGui::PushID(label); + ImGui::BeginGroup(); + ImGui::BeginDisabled(options.disabled); + PushStyleCombobox(options.color); + if (options.alignment == ComponentAlignment::Left) { + if (options.labelPosition == LabelPosition::Above) { + ImGui::Text("%s", label); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Near) { + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x - + ImGui::GetStyle().ItemSpacing.x * 2); + } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { + ImGui::SetNextItemWidth(ImGui::CalcTextSize(comboArray[currentValueIndex]).x + + ImGui::GetStyle().FramePadding.x * 4 + ImGui::GetStyle().ItemSpacing.x); + } + } else if (options.alignment == ComponentAlignment::Right) { + if (options.labelPosition == LabelPosition::Above) { + ImGui::NewLine(); + ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); + ImGui::Text("%s", label); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Near) { + ImGui::SameLine(ImGui::CalcTextSize(label).x + ImGui::GetStyle().ItemSpacing.x * 2); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + } else if (options.labelPosition == LabelPosition::Far || options.labelPosition == LabelPosition::None) { + float width = ImGui::CalcTextSize(comboArray[currentValueIndex]).x + ImGui::GetStyle().FramePadding.x * 4; + ImGui::SameLine(ImGui::GetContentRegionAvail().x - width); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); } - if (ImGui::BeginCombo(invisibleLabel, comboArray[currentValueIndex], options.flags)) { - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); - for (size_t i = 0; i < N; ++i) { - auto newValue = static_cast<T>(i); - if (strlen(comboArray[i]) > 1) { - if (ImGui::Selectable(comboArray[i], newValue == *value)) { - *value = newValue; - dirty = true; - } + } + if (ImGui::BeginCombo(invisibleLabel, comboArray[currentValueIndex], options.flags)) { + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(10.0f, 10.0f)); + for (size_t i = 0; i < N; ++i) { + auto newValue = static_cast<T>(i); + if (strlen(comboArray[i]) > 1) { + if (ImGui::Selectable(comboArray[i], newValue == *value)) { + *value = newValue; + dirty = true; } } - ImGui::PopStyleVar(); - ImGui::EndCombo(); - } - if (options.alignment == ComponentAlignment::Left) { - if (options.labelPosition == LabelPosition::Near) { - ImGui::SameLine(); - ImGui::Text("%s", label); - } else if (options.labelPosition == LabelPosition::Far) { - ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); - ImGui::Text("%s", label); - } - } else if (options.alignment == ComponentAlignment::Right) { - if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) { - ImGui::SameLine(startX); - ImGui::Text("%s", label); - } } - PopStyleCombobox(); - ImGui::EndDisabled(); - ImGui::EndGroup(); - if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.disabledTooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); - } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { - ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); - } - ImGui::PopID(); - return dirty; - } - - template <typename T = int32_t> - bool CVarCombobox(const char* label, const char* cvarName, const std::unordered_map<T, const char*>& comboMap, const ComboboxOptions& options = {}) { - bool dirty = false; - int32_t value = CVarGetInteger(cvarName, options.defaultIndex); - if (Combobox<T>(label, &value, comboMap, options)) { - CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - dirty = true; + ImGui::PopStyleVar(); + ImGui::EndCombo(); + } + if (options.alignment == ComponentAlignment::Left) { + if (options.labelPosition == LabelPosition::Near) { + ImGui::SameLine(); + ImGui::Text("%s", label); + } else if (options.labelPosition == LabelPosition::Far) { + ImGui::SameLine(ImGui::GetContentRegionAvail().x - ImGui::CalcTextSize(label).x); + ImGui::Text("%s", label); + } + } else if (options.alignment == ComponentAlignment::Right) { + if (options.labelPosition == LabelPosition::Near || options.labelPosition == LabelPosition::Far) { + ImGui::SameLine(startX); + ImGui::Text("%s", label); } - return dirty; } + PopStyleCombobox(); + ImGui::EndDisabled(); + ImGui::EndGroup(); + if (options.disabled && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && + !Ship_IsCStringEmpty(options.disabledTooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.disabledTooltip).c_str()); + } else if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled) && !Ship_IsCStringEmpty(options.tooltip)) { + ImGui::SetTooltip("%s", WrappedText(options.tooltip).c_str()); + } + ImGui::PopID(); + return dirty; +} + +template <typename T = int32_t> +bool CVarCombobox(const char* label, const char* cvarName, const std::unordered_map<T, const char*>& comboMap, + const ComboboxOptions& options = {}) { + bool dirty = false; + int32_t value = CVarGetInteger(cvarName, options.defaultIndex); + if (Combobox<T>(label, &value, comboMap, options)) { + CVarSetInteger(cvarName, value); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + dirty = true; + } + return dirty; +} - template <typename T = int32_t> - bool CVarCombobox(const char* label, const char* cvarName, const std::vector<const char*>& comboVector, const ComboboxOptions& options = {}) { - bool dirty = false; - int32_t value = CVarGetInteger(cvarName, options.defaultIndex); - if (Combobox<T>(label, &value, comboVector, options)) { - CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - dirty = true; - } - return dirty; +template <typename T = int32_t> +bool CVarCombobox(const char* label, const char* cvarName, const std::vector<const char*>& comboVector, + const ComboboxOptions& options = {}) { + bool dirty = false; + int32_t value = CVarGetInteger(cvarName, options.defaultIndex); + if (Combobox<T>(label, &value, comboVector, options)) { + CVarSetInteger(cvarName, value); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + dirty = true; } + return dirty; +} - template <typename T = int32_t, size_t N> - bool CVarCombobox(const char* label, const char* cvarName, const char* (&comboArray)[N], const ComboboxOptions& options = {}) { - bool dirty = false; - int32_t value = CVarGetInteger(cvarName, options.defaultIndex); - if (Combobox<T>(label, &value, comboArray, options)) { - CVarSetInteger(cvarName, value); - Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); - dirty = true; - } - return dirty; - } - - void PushStyleSlider(Colors color = Colors::LightBlue); - void PopStyleSlider(); - bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& options = {}); - bool CVarSliderInt(const char* label, const char* cvarName, const IntSliderOptions& options = {}); - bool SliderFloat(const char* label, float* value, const FloatSliderOptions& options = {}); - bool CVarSliderFloat(const char* label, const char* cvarName, const FloatSliderOptions& options = {}); - bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaultColor); - void DrawFlagArray32(const std::string& name, uint32_t& flags); - void DrawFlagArray16(const std::string& name, uint16_t& flags); - void DrawFlagArray8(const std::string& name, uint8_t& flags); - void DrawFlagArray8Mask(const std::string& name, uint8_t& flags); +template <typename T = int32_t, size_t N> +bool CVarCombobox(const char* label, const char* cvarName, const char* (&comboArray)[N], + const ComboboxOptions& options = {}) { + bool dirty = false; + int32_t value = CVarGetInteger(cvarName, options.defaultIndex); + if (Combobox<T>(label, &value, comboArray, options)) { + CVarSetInteger(cvarName, value); + Ship::Context::GetInstance()->GetWindow()->GetGui()->SaveConsoleVariablesNextFrame(); + dirty = true; + } + return dirty; } +void PushStyleSlider(Colors color = Colors::LightBlue); +void PopStyleSlider(); +bool SliderInt(const char* label, int32_t* value, const IntSliderOptions& options = {}); +bool CVarSliderInt(const char* label, const char* cvarName, const IntSliderOptions& options = {}); +bool SliderFloat(const char* label, float* value, const FloatSliderOptions& options = {}); +bool CVarSliderFloat(const char* label, const char* cvarName, const FloatSliderOptions& options = {}); +bool CVarColorPicker(const char* label, const char* cvarName, Color_RGBA8 defaultColor); +void DrawFlagArray32(const std::string& name, uint32_t& flags); +void DrawFlagArray16(const std::string& name, uint16_t& flags); +void DrawFlagArray8(const std::string& name, uint8_t& flags); +void DrawFlagArray8Mask(const std::string& name, uint8_t& flags); +} // namespace UIWidgets + #endif /* UIWidgets_hpp */ |
