diff --git a/include/ui/game_screen.hpp b/include/ui/game_screen.hpp index a6dd4920..bbb5ffa8 100644 --- a/include/ui/game_screen.hpp +++ b/include/ui/game_screen.hpp @@ -157,6 +157,8 @@ private: bool chatWindowLocked = true; ImVec2 chatWindowPos_ = ImVec2(0.0f, 0.0f); bool chatWindowPosInit_ = false; + ImVec2 questTrackerPos_ = ImVec2(-1.0f, -1.0f); // <0 = use default + bool questTrackerPosInit_ = false; bool showEscapeMenu = false; bool showEscapeSettingsNotice = false; bool showSettingsWindow = false; diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index bf02b2b4..68069c3d 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -16518,6 +16518,10 @@ void GameScreen::saveSettings() { out << "extended_zoom=" << (pendingExtendedZoom ? 1 : 0) << "\n"; out << "fov=" << pendingFov << "\n"; + // Quest tracker position + out << "quest_tracker_x=" << questTrackerPos_.x << "\n"; + out << "quest_tracker_y=" << questTrackerPos_.y << "\n"; + // Chat out << "chat_active_tab=" << activeChatTab_ << "\n"; out << "chat_timestamps=" << (chatShowTimestamps_ ? 1 : 0) << "\n"; @@ -16662,6 +16666,15 @@ void GameScreen::loadSettings() { if (auto* camera = renderer->getCamera()) camera->setFov(pendingFov); } } + // Quest tracker position + else if (key == "quest_tracker_x") { + questTrackerPos_.x = std::stof(val); + questTrackerPosInit_ = true; + } + else if (key == "quest_tracker_y") { + questTrackerPos_.y = std::stof(val); + questTrackerPosInit_ = true; + } // Chat else if (key == "chat_active_tab") activeChatTab_ = std::clamp(std::stoi(val), 0, 3); else if (key == "chat_timestamps") chatShowTimestamps_ = (std::stoi(val) != 0); @@ -20018,16 +20031,20 @@ void GameScreen::renderObjectiveTracker(game::GameHandler& gameHandler) { ImVec2 display = ImGui::GetIO().DisplaySize; float screenW = display.x > 0.0f ? display.x : 1280.0f; + float screenH = display.y > 0.0f ? display.y : 720.0f; float trackerW = 220.0f; - float trackerX = screenW - trackerW - 12.0f; - float trackerY = 230.0f; // below minimap + + // Default position: top-right, below minimap + if (!questTrackerPosInit_ || questTrackerPos_.x < 0.0f) { + questTrackerPos_ = ImVec2(screenW - trackerW - 12.0f, 230.0f); + questTrackerPosInit_ = true; + } ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | - ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | - ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | - ImGuiWindowFlags_NoFocusOnAppearing; + ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_AlwaysAutoResize | + ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoFocusOnAppearing; - ImGui::SetNextWindowPos(ImVec2(trackerX, trackerY), ImGuiCond_Always); + ImGui::SetNextWindowPos(questTrackerPos_, ImGuiCond_Always); ImGui::SetNextWindowSize(ImVec2(trackerW, 0.0f), ImGuiCond_Always); ImGui::SetNextWindowBgAlpha(0.5f); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 4.0f); @@ -20087,6 +20104,17 @@ void GameScreen::renderObjectiveTracker(game::GameHandler& gameHandler) { ImGui::Dummy(ImVec2(0.0f, 2.0f)); } + + // Track drag — save new position when the window is moved + ImVec2 newPos = ImGui::GetWindowPos(); + if (std::abs(newPos.x - questTrackerPos_.x) > 0.5f || + std::abs(newPos.y - questTrackerPos_.y) > 0.5f) { + // Clamp to screen bounds + newPos.x = std::clamp(newPos.x, 0.0f, screenW - trackerW); + newPos.y = std::clamp(newPos.y, 0.0f, screenH - 40.0f); + questTrackerPos_ = newPos; + saveSettings(); + } } ImGui::End(); ImGui::PopStyleVar(2);