diff --git a/Glamourer/Automation/AutoDesignManager.cs b/Glamourer/Automation/AutoDesignManager.cs index c1e361d..1b95f73 100644 --- a/Glamourer/Automation/AutoDesignManager.cs +++ b/Glamourer/Automation/AutoDesignManager.cs @@ -28,6 +28,7 @@ public class AutoDesignManager : ISavable, IReadOnlyList, IDispos private readonly AutomationChanged _event; private readonly DesignChanged _designEvent; private readonly RandomDesignGenerator _randomDesigns; + private readonly QuickSelectedDesign _quickSelectedDesign; private readonly List _data = []; private readonly Dictionary _enabled = []; @@ -36,15 +37,17 @@ public class AutoDesignManager : ISavable, IReadOnlyList, IDispos => _enabled; public AutoDesignManager(JobService jobs, ActorManager actors, SaveService saveService, DesignManager designs, AutomationChanged @event, - FixedDesignMigrator migrator, DesignFileSystem fileSystem, DesignChanged designEvent, RandomDesignGenerator randomDesigns) + FixedDesignMigrator migrator, DesignFileSystem fileSystem, DesignChanged designEvent, RandomDesignGenerator randomDesigns, + QuickSelectedDesign quickSelectedDesign) { - _jobs = jobs; - _actors = actors; - _saveService = saveService; - _designs = designs; - _event = @event; - _designEvent = designEvent; - _randomDesigns = randomDesigns; + _jobs = jobs; + _actors = actors; + _saveService = saveService; + _designs = designs; + _event = @event; + _designEvent = designEvent; + _randomDesigns = randomDesigns; + _quickSelectedDesign = quickSelectedDesign; _designEvent.Subscribe(OnDesignChange, DesignChanged.Priority.AutoDesignManager); Load(); migrator.ConsumeMigratedData(_actors, fileSystem, this); @@ -486,6 +489,10 @@ public class AutoDesignManager : ISavable, IReadOnlyList, IDispos { design = new RandomDesign(_randomDesigns); } + else if (designIdentifier is QuickSelectedDesign.SerializedName) + { + design = _quickSelectedDesign; + } else { if (designIdentifier.Length == 0) diff --git a/Glamourer/Designs/Special/QuickSelectedDesign.cs b/Glamourer/Designs/Special/QuickSelectedDesign.cs new file mode 100644 index 0000000..dd0f00f --- /dev/null +++ b/Glamourer/Designs/Special/QuickSelectedDesign.cs @@ -0,0 +1,52 @@ +using Glamourer.Automation; +using Glamourer.Gui; +using Glamourer.Interop.Material; +using Glamourer.State; +using Newtonsoft.Json.Linq; +using OtterGui.Services; + +namespace Glamourer.Designs.Special; + +public class QuickSelectedDesign(QuickDesignCombo combo) : IDesignStandIn, IService +{ + public const string SerializedName = "//QuickSelection"; + public const string ResolvedName = "Quick Design Bar Selection"; + + public bool Equals(IDesignStandIn? other) + => other is QuickSelectedDesign; + + public string ResolveName(bool incognito) + => ResolvedName; + + public Design? CurrentDesign + => combo.Design as Design; + + public ref readonly DesignData GetDesignData(in DesignData baseRef) + { + if (combo.Design != null) + return ref combo.Design.GetDesignData(baseRef); + + return ref baseRef; + } + + public IReadOnlyList<(uint, MaterialValueDesign)> GetMaterialData() + => combo.Design?.GetMaterialData() ?? []; + + public string SerializeName() + => SerializedName; + + public StateSource AssociatedSource() + => StateSource.Manual; + + public IEnumerable<(IDesignStandIn Design, ApplicationType Flags)> AllLinks + => combo.Design?.AllLinks ?? []; + + public void AddData(JObject jObj) + { } + + public void ParseData(JObject jObj) + { } + + public bool ChangeData(object data) + => false; +} diff --git a/Glamourer/EphemeralConfig.cs b/Glamourer/EphemeralConfig.cs index 8497538..027685f 100644 --- a/Glamourer/EphemeralConfig.cs +++ b/Glamourer/EphemeralConfig.cs @@ -9,15 +9,16 @@ namespace Glamourer; public class EphemeralConfig : ISavable { - public int Version { get; set; } = Configuration.Constants.CurrentVersion; - public bool IncognitoMode { get; set; } = false; - public bool UnlockDetailMode { get; set; } = true; - public bool ShowDesignQuickBar { get; set; } = false; - public bool LockDesignQuickBar { get; set; } = false; - public bool LockMainWindow { get; set; } = false; - public MainWindow.TabType SelectedTab { get; set; } = MainWindow.TabType.Settings; - public Guid SelectedDesign { get; set; } = Guid.Empty; - public int LastSeenVersion { get; set; } = GlamourerChangelog.LastChangelogVersion; + public int Version { get; set; } = Configuration.Constants.CurrentVersion; + public bool IncognitoMode { get; set; } = false; + public bool UnlockDetailMode { get; set; } = true; + public bool ShowDesignQuickBar { get; set; } = false; + public bool LockDesignQuickBar { get; set; } = false; + public bool LockMainWindow { get; set; } = false; + public MainWindow.TabType SelectedTab { get; set; } = MainWindow.TabType.Settings; + public Guid SelectedDesign { get; set; } = Guid.Empty; + public Guid SelectedQuickDesign { get; set; } = Guid.Empty; + public int LastSeenVersion { get; set; } = GlamourerChangelog.LastChangelogVersion; [JsonIgnore] diff --git a/Glamourer/Gui/DesignCombo.cs b/Glamourer/Gui/DesignCombo.cs index a4bfadb..1875b81 100644 --- a/Glamourer/Gui/DesignCombo.cs +++ b/Glamourer/Gui/DesignCombo.cs @@ -14,9 +14,9 @@ namespace Glamourer.Gui; public abstract class DesignComboBase : FilterComboCache>, IDisposable { - private readonly EphemeralConfig _config; - private readonly DesignChanged _designChanged; - private readonly DesignColors _designColors; + protected readonly EphemeralConfig Config; + protected readonly DesignChanged DesignChanged; + protected readonly DesignColors DesignColors; protected readonly TabSelected TabSelected; protected float InnerWidth; private IDesignStandIn? _currentDesign; @@ -25,19 +25,19 @@ public abstract class DesignComboBase : FilterComboCache _config.IncognitoMode; + => Config.IncognitoMode; void IDisposable.Dispose() { - _designChanged.Unsubscribe(OnDesignChange); + DesignChanged.Unsubscribe(OnDesignChange); GC.SuppressFinalize(this); } @@ -45,42 +45,47 @@ public abstract class DesignComboBase : FilterComboCache 0 && realDesign.Name != path) { - var start = ImGui.GetItemRectMin(); - var pos = start.X + ImGui.CalcTextSize(realDesign.Name).X; - var maxSize = ImGui.GetWindowPos().X + ImGui.GetWindowContentRegionMax().X; - var remainingSpace = maxSize - pos; - var requiredSize = ImGui.CalcTextSize(path).X + ImGui.GetStyle().ItemInnerSpacing.X; - var offset = remainingSpace - requiredSize; - if (ImGui.GetScrollMaxY() == 0) - offset -= ImGui.GetStyle().ItemInnerSpacing.X; - - if (offset < ImGui.GetStyle().ItemSpacing.X) - ImGuiUtil.HoverTooltip(path); - else - ImGui.GetWindowDrawList().AddText(start with { X = pos + offset }, - ImGui.GetColorU32(ImGuiCol.TextDisabled), path); + using var color = ImRaii.PushColor(ImGuiCol.Text, DesignColors.GetColor(realDesign)); + ret = base.DrawSelectable(globalIdx, selected); + DrawPath(path, realDesign); + return ret; } + case QuickSelectedDesign quickDesign: + { + ret = base.DrawSelectable(globalIdx, selected); + DrawResolvedDesign(quickDesign); + return ret; + } + default: return base.DrawSelectable(globalIdx, selected); } + } + + private static void DrawPath(string path, Design realDesign) + { + if (path.Length <= 0 || realDesign.Name == path) + return; + + DrawRightAligned(realDesign.Name, path, ImGui.GetColorU32(ImGuiCol.TextDisabled)); + } + + private void DrawResolvedDesign(QuickSelectedDesign quickDesign) + { + var linkedDesign = quickDesign.CurrentDesign; + if (linkedDesign != null) + DrawRightAligned(quickDesign.ResolveName(false), linkedDesign.Name.Text, DesignColors.GetColor(linkedDesign)); else - { - ret = base.DrawSelectable(globalIdx, selected); - } - - - return ret; + DrawRightAligned(quickDesign.ResolveName(false), "[Nothing]", DesignColors.MissingColor); } protected override int UpdateCurrentSelected(int currentSelected) { CurrentSelectionIdx = Items.IndexOf(p => _currentDesign == p.Item1); - CurrentSelection = CurrentSelectionIdx >= 0 ? Items[CurrentSelectionIdx] : null; + UpdateSelection(CurrentSelectionIdx >= 0 ? Items[CurrentSelectionIdx] : null); return CurrentSelectionIdx; } @@ -90,7 +95,7 @@ public abstract class DesignComboBase : FilterComboCache ReferenceEquals(s.Item1, CurrentSelection?.Item1)); if (CurrentSelectionIdx >= 0) { - CurrentSelection = Items[CurrentSelectionIdx]; + UpdateSelection(Items[CurrentSelectionIdx]); } else if (Items.Count > 0) { CurrentSelectionIdx = 0; - CurrentSelection = Items[0]; + UpdateSelection(Items[0]); } else { - CurrentSelection = null; + UpdateSelection(null); } if (!priorState) @@ -151,6 +158,47 @@ public abstract class DesignComboBase : FilterComboCache new Tuple(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty)) .OrderBy(d => d.Item2), ]) - => AllowMouseWheel = MouseWheelType.Unmodified; + { + if (config.SelectedQuickDesign != Guid.Empty) + { + CurrentSelectionIdx = Items.IndexOf(t => t.Item1 is Design d && d.Identifier == config.SelectedQuickDesign); + if (CurrentSelectionIdx >= 0) + CurrentSelection = Items[CurrentSelectionIdx]; + else if (Items.Count > 0) + CurrentSelectionIdx = 0; + } + + AllowMouseWheel = MouseWheelType.Unmodified; + SelectionChanged += OnSelectionChange; + } + + private void OnSelectionChange(Tuple? old, Tuple? @new) + { + if (old == null) + { + if (@new?.Item1 is not Design d) + return; + + Config.SelectedQuickDesign = d.Identifier; + Config.Save(); + } + else if (@new?.Item1 is not Design d) + { + Config.SelectedQuickDesign = Guid.Empty; + Config.Save(); + } + else if (!old.Item1.Equals(@new.Item1)) + { + Config.SelectedQuickDesign = d.Identifier; + Config.Save(); + } + } } public sealed class LinkDesignCombo( @@ -253,11 +335,13 @@ public sealed class SpecialDesignCombo( DesignChanged designChanged, AutoDesignManager autoDesignManager, EphemeralConfig config, - RandomDesignGenerator rng) + RandomDesignGenerator rng, + QuickSelectedDesign quickSelectedDesign) : DesignComboBase(() => designs.Designs .Select(d => new Tuple(d, fileSystem.FindLeaf(d, out var l) ? l.FullName() : string.Empty)) .OrderBy(d => d.Item2) .Prepend(new Tuple(new RandomDesign(rng), string.Empty)) + .Prepend(new Tuple(quickSelectedDesign, string.Empty)) .Prepend(new Tuple(new RevertDesign(), string.Empty)) .ToList(), log, designChanged, tabSelected, config, designColors) { diff --git a/OtterGui b/OtterGui index 9d68a48..d71f854 160000 --- a/OtterGui +++ b/OtterGui @@ -1 +1 @@ -Subproject commit 9d68a487610266058fbec853efed9a35c9df6fbe +Subproject commit d71f8540a2c2efb4f2cb96e4706bb056397daf0a