Add mini quest window
authorLiza Carvelli <liza@carvel.li>
Fri, 9 Aug 2024 22:57:09 +0000 (00:57 +0200)
committerLiza Carvelli <liza@carvel.li>
Fri, 9 Aug 2024 22:57:09 +0000 (00:57 +0200)
Questionable/Controller/CommandHandler.cs
Questionable/Windows/QuestComponents/ActiveQuestComponent.cs
Questionable/Windows/QuestComponents/QuickAccessButtonsComponent.cs
Questionable/Windows/QuestWindow.cs

index 322e6ccd1e49dc439180a8b1b77118d8024b7fa1..52f7fa4db03d773093ff1e03fa3fd552f24f837f 100644 (file)
@@ -17,7 +17,6 @@ internal sealed class CommandHandler : IDisposable
     private readonly IChatGui _chatGui;
     private readonly QuestController _questController;
     private readonly MovementController _movementController;
-    private readonly QuickAccessButtonsComponent _quickAccessButtonsComponent;
     private readonly QuestRegistry _questRegistry;
     private readonly ConfigWindow _configWindow;
     private readonly DebugOverlay _debugOverlay;
@@ -31,7 +30,6 @@ internal sealed class CommandHandler : IDisposable
         IChatGui chatGui,
         QuestController questController,
         MovementController movementController,
-        QuickAccessButtonsComponent quickAccessButtonsComponent,
         QuestRegistry questRegistry,
         ConfigWindow configWindow,
         DebugOverlay debugOverlay,
@@ -44,7 +42,6 @@ internal sealed class CommandHandler : IDisposable
         _chatGui = chatGui;
         _questController = questController;
         _movementController = movementController;
-        _quickAccessButtonsComponent = quickAccessButtonsComponent;
         _questRegistry = questRegistry;
         _configWindow = configWindow;
         _debugOverlay = debugOverlay;
@@ -87,7 +84,7 @@ internal sealed class CommandHandler : IDisposable
                 break;
 
             case "reload":
-                _quickAccessButtonsComponent.Reload();
+                _questWindow.Reload();
                 break;
 
             case "do":
index bd5802ae9c8a7a73ff73cdca8dbe7cbc4202c254..ce669a7bd894ee69848bf1f83dc75e4416eb9c9e 100644 (file)
@@ -56,7 +56,9 @@ internal sealed class ActiveQuestComponent
         _chatGui = chatGui;
     }
 
-    public void Draw()
+    public event EventHandler? Reload;
+
+    public void Draw(bool isMinimized)
     {
         var currentQuestDetails = _questController.CurrentQuestDetails;
         QuestController.QuestProgress? currentQuest = currentQuestDetails?.Progress;
@@ -64,7 +66,7 @@ internal sealed class ActiveQuestComponent
         if (currentQuest != null)
         {
             DrawQuestNames(currentQuest, currentQuestType);
-            var questWork = DrawQuestWork(currentQuest);
+            var questWork = DrawQuestWork(currentQuest, isMinimized);
 
             if (_combatController.IsRunning)
                 ImGui.TextColored(ImGuiColors.DalamudOrange, "In Combat");
@@ -77,28 +79,32 @@ internal sealed class ActiveQuestComponent
 
             QuestSequence? currentSequence = currentQuest.Quest.FindSequence(currentQuest.Sequence);
             QuestStep? currentStep = currentSequence?.FindStep(currentQuest.Step);
-            bool colored = currentStep is
-                { InteractionType: EInteractionType.Instruction or EInteractionType.WaitForManualProgress };
-            if (colored)
-                ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudOrange);
-            ImGui.TextUnformatted(currentStep?.Comment ??
-                                  currentSequence?.Comment ?? currentQuest.Quest.Root.Comment ?? string.Empty);
-            if (colored)
-                ImGui.PopStyleColor();
-
-            //var nextStep = _questController.GetNextStep();
-            //ImGui.BeginDisabled(nextStep.Step == null);
-            ImGui.Text(_questController.ToStatString());
-            //ImGui.EndDisabled();
+            if (!isMinimized)
+            {
+                bool colored = currentStep is
+                    { InteractionType: EInteractionType.Instruction or EInteractionType.WaitForManualProgress };
+                if (colored)
+                    ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudOrange);
+                ImGui.TextUnformatted(currentStep?.Comment ??
+                                      currentSequence?.Comment ?? currentQuest.Quest.Root.Comment ?? string.Empty);
+                if (colored)
+                    ImGui.PopStyleColor();
+
+                //var nextStep = _questController.GetNextStep();
+                //ImGui.BeginDisabled(nextStep.Step == null);
+                ImGui.Text(_questController.ToStatString());
+                //ImGui.EndDisabled();
+            }
 
-            DrawQuestButtons(currentQuest, currentStep, questWork);
+            DrawQuestButtons(currentQuest, currentStep, questWork, isMinimized);
 
             DrawSimulationControls();
         }
         else
         {
             ImGui.Text("No active quest");
-            ImGui.TextColored(ImGuiColors.DalamudGrey, $"{_questRegistry.Count} quests loaded");
+            if (!isMinimized)
+                ImGui.TextColored(ImGuiColors.DalamudGrey, $"{_questRegistry.Count} quests loaded");
 
             if (ImGuiComponents.IconButton(FontAwesomeIcon.Stop))
             {
@@ -157,11 +163,16 @@ internal sealed class ActiveQuestComponent
         }
     }
 
-    private QuestProgressInfo? DrawQuestWork(QuestController.QuestProgress currentQuest)
+    private QuestProgressInfo? DrawQuestWork(QuestController.QuestProgress currentQuest, bool isMinimized)
     {
         var questWork = _questFunctions.GetQuestProgressInfo(currentQuest.Quest.Id);
+
         if (questWork != null)
         {
+            if (isMinimized)
+                return questWork;
+
+
             Vector4 color;
             unsafe
             {
@@ -203,7 +214,7 @@ internal sealed class ActiveQuestComponent
     }
 
     private void DrawQuestButtons(QuestController.QuestProgress currentQuest, QuestStep? currentStep,
-        QuestProgressInfo? questProgressInfo)
+        QuestProgressInfo? questProgressInfo, bool isMinimized)
     {
         ImGui.BeginDisabled(_questController.IsRunning);
         if (ImGuiComponents.IconButton(FontAwesomeIcon.Play))
@@ -215,11 +226,14 @@ internal sealed class ActiveQuestComponent
             _questController.ExecuteNextStep(QuestController.EAutomationType.Automatic);
         }
 
-        ImGui.SameLine();
-
-        if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.StepForward, "Step"))
+        if (!isMinimized)
         {
-            _questController.ExecuteNextStep(QuestController.EAutomationType.Manual);
+            ImGui.SameLine();
+
+            if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.StepForward, "Step"))
+            {
+                _questController.ExecuteNextStep(QuestController.EAutomationType.Manual);
+            }
         }
 
         ImGui.EndDisabled();
@@ -232,39 +246,48 @@ internal sealed class ActiveQuestComponent
             _gatheringController.Stop("Manual");
         }
 
-        bool lastStep = currentStep ==
-                        currentQuest.Quest.FindSequence(currentQuest.Sequence)?.Steps.LastOrDefault();
-        bool colored = currentStep != null
-                       && !lastStep
-                       && currentStep.InteractionType == EInteractionType.Instruction
-                       && _questController.HasCurrentTaskMatching<WaitAtEnd.WaitNextStepOrSequence>(out _);
-
-        ImGui.BeginDisabled(lastStep);
-        if (colored)
-            ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.ParsedGreen);
-        if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.ArrowCircleRight, "Skip"))
+        if (isMinimized)
         {
-            _movementController.Stop();
-            _questController.Skip(currentQuest.Quest.Id, currentQuest.Sequence);
+            ImGui.SameLine();
+            if (ImGuiComponents.IconButton(FontAwesomeIcon.RedoAlt))
+                Reload?.Invoke(this, EventArgs.Empty);
         }
+        else
+        {
+            bool lastStep = currentStep ==
+                            currentQuest.Quest.FindSequence(currentQuest.Sequence)?.Steps.LastOrDefault();
+            bool colored = currentStep != null
+                           && !lastStep
+                           && currentStep.InteractionType == EInteractionType.Instruction
+                           && _questController.HasCurrentTaskMatching<WaitAtEnd.WaitNextStepOrSequence>(out _);
+
+            ImGui.BeginDisabled(lastStep);
+            if (colored)
+                ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.ParsedGreen);
+            if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.ArrowCircleRight, "Skip"))
+            {
+                _movementController.Stop();
+                _questController.Skip(currentQuest.Quest.Id, currentQuest.Sequence);
+            }
 
-        if (colored)
-            ImGui.PopStyleColor();
-        ImGui.EndDisabled();
+            if (colored)
+                ImGui.PopStyleColor();
+            ImGui.EndDisabled();
 
-        if (_commandManager.Commands.TryGetValue("/questinfo", out var commandInfo))
-        {
-            ImGui.SameLine();
-            if (ImGuiComponents.IconButton(FontAwesomeIcon.Atlas))
-                _commandManager.DispatchCommand("/questinfo",
-                    currentQuest.Quest.Id.ToString() ?? string.Empty, commandInfo);
-        }
+            if (_commandManager.Commands.TryGetValue("/questinfo", out var commandInfo))
+            {
+                ImGui.SameLine();
+                if (ImGuiComponents.IconButton(FontAwesomeIcon.Atlas))
+                    _commandManager.DispatchCommand("/questinfo",
+                        currentQuest.Quest.Id.ToString() ?? string.Empty, commandInfo);
+            }
 
-        bool autoAcceptNextQuest = _configuration.General.AutoAcceptNextQuest;
-        if (ImGui.Checkbox("Automatically accept next quest", ref autoAcceptNextQuest))
-        {
-            _configuration.General.AutoAcceptNextQuest = autoAcceptNextQuest;
-            _pluginInterface.SavePluginConfig(_configuration);
+            bool autoAcceptNextQuest = _configuration.General.AutoAcceptNextQuest;
+            if (ImGui.Checkbox("Automatically accept next quest", ref autoAcceptNextQuest))
+            {
+                _configuration.General.AutoAcceptNextQuest = autoAcceptNextQuest;
+                _pluginInterface.SavePluginConfig(_configuration);
+            }
         }
     }
 
index c189686164d8532b41da73f82557c2ef30d324b5..6704b5945fd9aa8ae8b99fd386813432b91b19f0 100644 (file)
@@ -18,9 +18,7 @@ namespace Questionable.Windows.QuestComponents;
 
 internal sealed class QuickAccessButtonsComponent
 {
-    private readonly QuestController _questController;
     private readonly MovementController _movementController;
-    private readonly GameUiController _gameUiController;
     private readonly GameFunctions _gameFunctions;
     private readonly ChatFunctions _chatFunctions;
     private readonly QuestRegistry _questRegistry;
@@ -29,12 +27,10 @@ internal sealed class QuickAccessButtonsComponent
     private readonly JournalProgressWindow _journalProgressWindow;
     private readonly IClientState _clientState;
     private readonly ICondition _condition;
-    private readonly IFramework _framework;
     private readonly ICommandManager _commandManager;
 
-    public QuickAccessButtonsComponent(QuestController questController,
+    public QuickAccessButtonsComponent(
         MovementController movementController,
-        GameUiController gameUiController,
         GameFunctions gameFunctions,
         ChatFunctions chatFunctions,
         QuestRegistry questRegistry,
@@ -43,12 +39,9 @@ internal sealed class QuickAccessButtonsComponent
         JournalProgressWindow journalProgressWindow,
         IClientState clientState,
         ICondition condition,
-        IFramework framework,
         ICommandManager commandManager)
     {
-        _questController = questController;
         _movementController = movementController;
-        _gameUiController = gameUiController;
         _gameFunctions = gameFunctions;
         _chatFunctions = chatFunctions;
         _questRegistry = questRegistry;
@@ -57,10 +50,11 @@ internal sealed class QuickAccessButtonsComponent
         _journalProgressWindow = journalProgressWindow;
         _clientState = clientState;
         _condition = condition;
-        _framework = framework;
         _commandManager = commandManager;
     }
 
+    public event EventHandler? Reload;
+
     public unsafe void Draw()
     {
         var map = AgentMap.Instance();
@@ -89,8 +83,8 @@ internal sealed class QuickAccessButtonsComponent
                 ImGui.SetTooltip("Hold CTRL to enable this button.\nRebuilding the navmesh will take some time.");
         }
 
-        if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.RedoAlt,"Reload Data"))
-            Reload();
+        if (ImGuiComponents.IconButtonWithText(FontAwesomeIcon.RedoAlt, "Reload Data"))
+            Reload?.Invoke(this, EventArgs.Empty);
 
         ImGui.SameLine();
         if (ImGuiComponents.IconButton(FontAwesomeIcon.ChartColumn))
@@ -105,13 +99,6 @@ internal sealed class QuickAccessButtonsComponent
         }
     }
 
-    public void Reload()
-    {
-        _questController.Reload();
-        _framework.RunOnTick(() => _gameUiController.HandleCurrentDialogueChoices(),
-            TimeSpan.FromMilliseconds(200));
-    }
-
     private bool DrawValidationIssuesButton()
     {
         int errorCount = _questRegistry.ValidationErrorCount;
index dab69b8b3d31c8b372a2221274e7cce6d23e34b4..5f7531e1fb2aece5591c0123ec478df2ef06c906 100644 (file)
@@ -1,5 +1,6 @@
 using System;
 using System.Numerics;
+using Dalamud.Interface;
 using Dalamud.Plugin;
 using Dalamud.Plugin.Services;
 using ImGuiNET;
@@ -24,6 +25,9 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
     private readonly CreationUtilsComponent _creationUtilsComponent;
     private readonly QuickAccessButtonsComponent _quickAccessButtonsComponent;
     private readonly RemainingTasksComponent _remainingTasksComponent;
+    private readonly IFramework _framework;
+    private readonly GameUiController _gameUiController;
+    private readonly TitleBarButton _minimizeButton;
 
     public QuestWindow(IDalamudPluginInterface pluginInterface,
         QuestController questController,
@@ -34,8 +38,11 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
         ARealmRebornComponent aRealmRebornComponent,
         CreationUtilsComponent creationUtilsComponent,
         QuickAccessButtonsComponent quickAccessButtonsComponent,
-        RemainingTasksComponent remainingTasksComponent)
-        : base($"Questionable v{PluginVersion.ToString(2)}###Questionable", ImGuiWindowFlags.AlwaysAutoResize)
+        RemainingTasksComponent remainingTasksComponent,
+        IFramework framework,
+        GameUiController gameUiController)
+        : base($"Questionable v{PluginVersion.ToString(2)}###Questionable",
+            ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoCollapse)
     {
         _pluginInterface = pluginInterface;
         _questController = questController;
@@ -47,6 +54,8 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
         _creationUtilsComponent = creationUtilsComponent;
         _quickAccessButtonsComponent = quickAccessButtonsComponent;
         _remainingTasksComponent = remainingTasksComponent;
+        _framework = framework;
+        _gameUiController = gameUiController;
 
 #if DEBUG
         IsOpen = true;
@@ -57,9 +66,27 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
             MaximumSize = default
         };
         RespectCloseHotkey = false;
+
+        _minimizeButton = new TitleBarButton
+        {
+            Icon = FontAwesomeIcon.Minus,
+            Priority = int.MinValue,
+            IconOffset = new Vector2(1.5f, 1),
+            Click = _ =>
+            {
+                IsMinimized = !IsMinimized;
+                _minimizeButton!.Icon = IsMinimized ? FontAwesomeIcon.WindowMaximize : FontAwesomeIcon.Minus;
+            },
+            AvailableClickthrough = true,
+        };
+        TitleBarButtons.Insert(0, _minimizeButton);
+
+        _activeQuestComponent.Reload += OnReload;
+        _quickAccessButtonsComponent.Reload += OnReload;
     }
 
     public WindowConfig WindowConfig => _configuration.DebugWindowConfig;
+    public bool IsMinimized { get; set; }
 
     public void SaveWindowConfig() => _pluginInterface.SavePluginConfig(_configuration);
 
@@ -82,19 +109,31 @@ internal sealed class QuestWindow : LWindow, IPersistableWindowConfig
 
     public override void Draw()
     {
-        _activeQuestComponent.Draw();
-        ImGui.Separator();
-
-        if (_aRealmRebornComponent.ShouldDraw)
+        _activeQuestComponent.Draw(IsMinimized);
+        if (!IsMinimized)
         {
-            _aRealmRebornComponent.Draw();
             ImGui.Separator();
+
+            if (_aRealmRebornComponent.ShouldDraw)
+            {
+                _aRealmRebornComponent.Draw();
+                ImGui.Separator();
+            }
+
+            _creationUtilsComponent.Draw();
+            ImGui.Separator();
+
+            _quickAccessButtonsComponent.Draw();
+            _remainingTasksComponent.Draw();
         }
+    }
 
-        _creationUtilsComponent.Draw();
-        ImGui.Separator();
+    private void OnReload(object? sender, EventArgs e) => Reload();
 
-        _quickAccessButtonsComponent.Draw();
-        _remainingTasksComponent.Draw();
+    internal void Reload()
+    {
+        _questController.Reload();
+        _framework.RunOnTick(() => _gameUiController.HandleCurrentDialogueChoices(),
+            TimeSpan.FromMilliseconds(200));
     }
 }