diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs b/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs index ca6974a..2eb220a 100644 --- a/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs +++ b/Glamourer/Gui/Tabs/DesignTab/DesignFileSystemSelector.cs @@ -18,7 +18,7 @@ using Luna; namespace Glamourer.Gui.Tabs.DesignTab; -public sealed class DesignFileSystemSelector : FileSystemSelector +public sealed class DesignFileSystemSelector : FileSystemSelector, IPanel { private readonly DesignManager _designManager; private readonly DesignChanged _event; @@ -399,4 +399,7 @@ public sealed class DesignFileSystemSelector : FileSystemSelector Id + => "DesignSelector"u8; } diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignHeader.cs b/Glamourer/Gui/Tabs/DesignTab/DesignHeader.cs new file mode 100644 index 0000000..b8baa4d --- /dev/null +++ b/Glamourer/Gui/Tabs/DesignTab/DesignHeader.cs @@ -0,0 +1,21 @@ +using Luna; + +namespace Glamourer.Gui.Tabs.DesignTab; + +public sealed class DesignHeader : SplitButtonHeader +{ + public DesignHeader(DesignSelection selection, IncognitoButton incognito) + { + RightButtons.AddButton(incognito, 50); + RightButtons.AddButton(new LockedButton(selection), 100); + } + + private sealed class LockedButton(DesignSelection selection) : BaseIconButton + { + public override bool IsVisible + => selection.Design is not null; + + public override AwesomeIcon Icon + => selection.Design!.WriteProtected() ? LunaStyle.LockedIcon : LunaStyle.UnlockedIcon; + } +} diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs b/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs index 7da344b..082cb71 100644 --- a/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs +++ b/Glamourer/Gui/Tabs/DesignTab/DesignPanel.cs @@ -24,10 +24,10 @@ using static Glamourer.Gui.Tabs.HeaderDrawer; namespace Glamourer.Gui.Tabs.DesignTab; -public class DesignPanel +public class DesignPanel : IPanel { private readonly FileDialogManager _fileDialog = new(); - private readonly DesignFileSystemSelector _selector; + private readonly DesignSelection _selection; private readonly CustomizationDrawer _customizationDrawer; private readonly DesignManager _manager; private readonly ActorObjectManager _objects; @@ -47,8 +47,7 @@ public class DesignPanel private readonly Button[] _rightButtons; - public DesignPanel(DesignFileSystemSelector selector, - CustomizationDrawer customizationDrawer, + public DesignPanel(CustomizationDrawer customizationDrawer, DesignManager manager, ActorObjectManager objects, StateManager state, @@ -62,9 +61,8 @@ public class DesignPanel CustomizeParameterDrawer parameterDrawer, DesignLinkDrawer designLinkDrawer, MaterialDrawer materials, - EditorHistory history) + EditorHistory history, DesignSelection selection) { - _selector = selector; _customizationDrawer = customizationDrawer; _manager = manager; _objects = objects; @@ -80,6 +78,7 @@ public class DesignPanel _designLinkDrawer = designLinkDrawer; _materials = materials; _history = history; + _selection = selection; _leftButtons = [ new SetFromClipboardButton(this), @@ -99,7 +98,7 @@ public class DesignPanel => HeaderDrawer.Draw(SelectionName, 0, ImGuiColor.FrameBackground.Get().Color, _leftButtons, _rightButtons); private string SelectionName - => _selector.Selected == null ? "No Selection" : _config.Ephemeral.IncognitoMode ? _selector.Selected.Incognito : _selector.Selected.Name.Text; + => _selection.Design == null ? "No Selection" : _config.Ephemeral.IncognitoMode ? _selection.Design.Incognito : _selection.Design.Name.Text; private void DrawEquipment() { @@ -109,22 +108,22 @@ public class DesignPanel _equipmentDrawer.Prepare(); - var usedAllStain = _equipmentDrawer.DrawAllStain(out var newAllStain, _selector.Selected!.WriteProtected()); + var usedAllStain = _equipmentDrawer.DrawAllStain(out var newAllStain, _selection.Design!.WriteProtected()); foreach (var slot in EquipSlotExtensions.EqdpSlots) { - var data = EquipDrawData.FromDesign(_manager, _selector.Selected!, slot); + var data = EquipDrawData.FromDesign(_manager, _selection.Design!, slot); _equipmentDrawer.DrawEquip(data); if (usedAllStain) - _manager.ChangeStains(_selector.Selected, slot, newAllStain); + _manager.ChangeStains(_selection.Design, slot, newAllStain); } - var mainhand = EquipDrawData.FromDesign(_manager, _selector.Selected!, EquipSlot.MainHand); - var offhand = EquipDrawData.FromDesign(_manager, _selector.Selected!, EquipSlot.OffHand); + var mainhand = EquipDrawData.FromDesign(_manager, _selection.Design!, EquipSlot.MainHand); + var offhand = EquipDrawData.FromDesign(_manager, _selection.Design!, EquipSlot.OffHand); _equipmentDrawer.DrawWeapons(mainhand, offhand, true); foreach (var slot in BonusExtensions.AllFlags) { - var data = BonusDrawData.FromDesign(_manager, _selector.Selected!, slot); + var data = BonusDrawData.FromDesign(_manager, _selection.Design!, slot); _equipmentDrawer.DrawBonusItem(data); } @@ -138,28 +137,28 @@ public class DesignPanel { using (var _ = ImRaii.Group()) { - EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromDesign(MetaIndex.HatState, _manager, _selector.Selected!)); - EquipmentDrawer.DrawMetaToggle(ToggleDrawData.CrestFromDesign(CrestFlag.Head, _manager, _selector.Selected!)); + EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromDesign(MetaIndex.HatState, _manager, _selection.Design!)); + EquipmentDrawer.DrawMetaToggle(ToggleDrawData.CrestFromDesign(CrestFlag.Head, _manager, _selection.Design!)); } Im.Line.Same(); using (var _ = ImRaii.Group()) { - EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromDesign(MetaIndex.VisorState, _manager, _selector.Selected!)); - EquipmentDrawer.DrawMetaToggle(ToggleDrawData.CrestFromDesign(CrestFlag.Body, _manager, _selector.Selected!)); + EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromDesign(MetaIndex.VisorState, _manager, _selection.Design!)); + EquipmentDrawer.DrawMetaToggle(ToggleDrawData.CrestFromDesign(CrestFlag.Body, _manager, _selection.Design!)); } Im.Line.Same(); using (var _ = ImRaii.Group()) { - EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromDesign(MetaIndex.WeaponState, _manager, _selector.Selected!)); - EquipmentDrawer.DrawMetaToggle(ToggleDrawData.CrestFromDesign(CrestFlag.OffHand, _manager, _selector.Selected!)); + EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromDesign(MetaIndex.WeaponState, _manager, _selection.Design!)); + EquipmentDrawer.DrawMetaToggle(ToggleDrawData.CrestFromDesign(CrestFlag.OffHand, _manager, _selection.Design!)); } Im.Line.Same(); using (var _ = ImRaii.Group()) { - EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromDesign(MetaIndex.EarState, _manager, _selector.Selected!)); + EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromDesign(MetaIndex.EarState, _manager, _selection.Design!)); } } @@ -169,25 +168,25 @@ public class DesignPanel return; var expand = _config.AutoExpandDesignPanel.HasFlag(DesignPanelFlag.Customization); - using var h = Im.Tree.HeaderId(_selector.Selected!.DesignData.ModelId is 0 + using var h = Im.Tree.HeaderId(_selection.Design!.DesignData.ModelId is 0 ? "Customization" - : $"Customization (Model Id #{_selector.Selected!.DesignData.ModelId})###Customization", + : $"Customization (Model Id #{_selection.Design!.DesignData.ModelId})###Customization", expand ? TreeNodeFlags.DefaultOpen : TreeNodeFlags.None); if (!h) return; - if (_customizationDrawer.Draw(_selector.Selected!.DesignData.Customize, _selector.Selected.Application.Customize, - _selector.Selected!.WriteProtected(), false)) + if (_customizationDrawer.Draw(_selection.Design!.DesignData.Customize, _selection.Design.Application.Customize, + _selection.Design!.WriteProtected(), false)) foreach (var idx in CustomizeIndex.Values) { var flag = idx.ToFlag(); var newValue = _customizationDrawer.ChangeApply.HasFlag(flag); - _manager.ChangeApplyCustomize(_selector.Selected, idx, newValue); + _manager.ChangeApplyCustomize(_selection.Design, idx, newValue); if (_customizationDrawer.Changed.HasFlag(flag)) - _manager.ChangeCustomize(_selector.Selected, idx, _customizationDrawer.Customize[idx]); + _manager.ChangeCustomize(_selection.Design, idx, _customizationDrawer.Customize[idx]); } - EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromDesign(MetaIndex.Wetness, _manager, _selector.Selected!)); + EquipmentDrawer.DrawMetaToggle(ToggleDrawData.FromDesign(MetaIndex.Wetness, _manager, _selection.Design!)); Im.Dummy(new Vector2(Im.Style.TextHeight / 2)); } @@ -197,7 +196,7 @@ public class DesignPanel if (!h) return; - _parameterDrawer.Draw(_manager, _selector.Selected!); + _parameterDrawer.Draw(_manager, _selection.Design!); } private void DrawMaterialValues() @@ -206,52 +205,52 @@ public class DesignPanel if (!h) return; - _materials.Draw(_selector.Selected!); + _materials.Draw(_selection.Design!); } private void DrawCustomizeApplication() { using var id = ImUtf8.PushId("Customizations"u8); - var set = _selector.Selected!.CustomizeSet; + var set = _selection.Design!.CustomizeSet; var available = set.SettingAvailable | CustomizeFlag.Clan | CustomizeFlag.Gender | CustomizeFlag.BodyType; - var flags = _selector.Selected!.ApplyCustomizeExcludingBodyType == 0 ? 0 : - (_selector.Selected!.ApplyCustomize & available) == available ? 3 : 1; + var flags = _selection.Design!.ApplyCustomizeExcludingBodyType == 0 ? 0 : + (_selection.Design!.ApplyCustomize & available) == available ? 3 : 1; if (ImGui.CheckboxFlags("Apply All Customizations", ref flags, 3)) { var newFlags = flags == 3; - _manager.ChangeApplyCustomize(_selector.Selected!, CustomizeIndex.Clan, newFlags); - _manager.ChangeApplyCustomize(_selector.Selected!, CustomizeIndex.Gender, newFlags); + _manager.ChangeApplyCustomize(_selection.Design!, CustomizeIndex.Clan, newFlags); + _manager.ChangeApplyCustomize(_selection.Design!, CustomizeIndex.Gender, newFlags); foreach (var index in CustomizationExtensions.AllBasic) - _manager.ChangeApplyCustomize(_selector.Selected!, index, newFlags); + _manager.ChangeApplyCustomize(_selection.Design!, index, newFlags); } - var applyClan = _selector.Selected!.DoApplyCustomize(CustomizeIndex.Clan); + var applyClan = _selection.Design!.DoApplyCustomize(CustomizeIndex.Clan); if (ImUtf8.Checkbox($"Apply {CustomizeIndex.Clan.ToNameU8()}", ref applyClan)) - _manager.ChangeApplyCustomize(_selector.Selected!, CustomizeIndex.Clan, applyClan); + _manager.ChangeApplyCustomize(_selection.Design!, CustomizeIndex.Clan, applyClan); - var applyGender = _selector.Selected!.DoApplyCustomize(CustomizeIndex.Gender); + var applyGender = _selection.Design!.DoApplyCustomize(CustomizeIndex.Gender); if (ImUtf8.Checkbox($"Apply {CustomizeIndex.Gender.ToNameU8()}", ref applyGender)) - _manager.ChangeApplyCustomize(_selector.Selected!, CustomizeIndex.Gender, applyGender); + _manager.ChangeApplyCustomize(_selection.Design!, CustomizeIndex.Gender, applyGender); foreach (var index in CustomizationExtensions.All.Where(set.IsAvailable)) { - var apply = _selector.Selected!.DoApplyCustomize(index); + var apply = _selection.Design!.DoApplyCustomize(index); if (ImUtf8.Checkbox($"Apply {set.Option(index)}", ref apply)) - _manager.ChangeApplyCustomize(_selector.Selected!, index, apply); + _manager.ChangeApplyCustomize(_selection.Design!, index, apply); } } private void DrawCrestApplication() { using var id = ImUtf8.PushId("Crests"u8); - var flags = (uint)_selector.Selected!.Application.Crest; + var flags = (uint)_selection.Design!.Application.Crest; var bigChange = ImGui.CheckboxFlags("Apply All Crests", ref flags, (uint)CrestExtensions.AllRelevant); foreach (var flag in CrestExtensions.AllRelevantSet) { - var apply = bigChange ? ((CrestFlag)flags & flag) == flag : _selector.Selected!.DoApplyCrest(flag); + var apply = bigChange ? ((CrestFlag)flags & flag) == flag : _selection.Design!.DoApplyCrest(flag); if (ImUtf8.Checkbox($"Apply {flag.ToLabel()} Crest", ref apply) || bigChange) - _manager.ChangeApplyCrest(_selector.Selected!, flag, apply); + _manager.ChangeApplyCrest(_selection.Design!, flag, apply); } } @@ -261,7 +260,7 @@ public class DesignPanel if (!h) return; - using var disabled = Im.Disabled(_selector.Selected!.WriteProtected()); + using var disabled = Im.Disabled(_selection.Design!.WriteProtected()); DrawAllButtons(); @@ -279,22 +278,22 @@ public class DesignPanel { void ApplyEquip(string label, EquipFlag allFlags, bool stain, IEnumerable slots) { - var flags = (uint)(allFlags & _selector.Selected!.Application.Equip); + var flags = (uint)(allFlags & _selection.Design!.Application.Equip); using var id = ImUtf8.PushId(label); var bigChange = ImGui.CheckboxFlags($"Apply All {label}", ref flags, (uint)allFlags); if (stain) foreach (var slot in slots) { - var apply = bigChange ? ((EquipFlag)flags).HasFlag(slot.ToStainFlag()) : _selector.Selected!.DoApplyStain(slot); + var apply = bigChange ? ((EquipFlag)flags).HasFlag(slot.ToStainFlag()) : _selection.Design!.DoApplyStain(slot); if (ImUtf8.Checkbox($"Apply {slot.ToName()} Dye", ref apply) || bigChange) - _manager.ChangeApplyStains(_selector.Selected!, slot, apply); + _manager.ChangeApplyStains(_selection.Design!, slot, apply); } else foreach (var slot in slots) { - var apply = bigChange ? ((EquipFlag)flags).HasFlag(slot.ToFlag()) : _selector.Selected!.DoApplyEquip(slot); + var apply = bigChange ? ((EquipFlag)flags).HasFlag(slot.ToFlag()) : _selection.Design!.DoApplyEquip(slot); if (ImUtf8.Checkbox($"Apply {slot.ToName()}", ref apply) || bigChange) - _manager.ChangeApplyItem(_selector.Selected!, slot, apply); + _manager.ChangeApplyItem(_selection.Design!, slot, apply); } } @@ -379,8 +378,8 @@ public class DesignPanel size, !enabled)) { - _manager.ChangeApplyMulti(_selector.Selected!, true, true, true, false, true, true, false, true); - _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.Wetness, false); + _manager.ChangeApplyMulti(_selection.Design!, true, true, true, false, true, true, false, true); + _manager.ChangeApplyMeta(_selection.Design!, MetaIndex.Wetness, false); } if (!enabled) @@ -390,7 +389,7 @@ public class DesignPanel if (ImUtf8.ButtonEx("Disable Advanced"u8, "Disable all advanced dyes and customizations but keep everything else as is."u8, size, !enabled)) - _manager.ChangeApplyMulti(_selector.Selected!, null, null, null, false, null, null, false, null); + _manager.ChangeApplyMulti(_selection.Design!, null, null, null, false, null, null, false, null); if (!enabled) ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"Hold {_config.DeleteDesignModifier} while clicking."); @@ -398,18 +397,18 @@ public class DesignPanel if (equip is null && customize is null) return; - _manager.ChangeApplyMulti(_selector.Selected!, equip, customize, equip, customize.HasValue && !customize.Value ? false : null, null, + _manager.ChangeApplyMulti(_selection.Design!, equip, customize, equip, customize.HasValue && !customize.Value ? false : null, null, equip, equip, equip); if (equip.HasValue) { - _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.HatState, equip.Value); - _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.VisorState, equip.Value); - _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.WeaponState, equip.Value); - _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.EarState, equip.Value); + _manager.ChangeApplyMeta(_selection.Design!, MetaIndex.HatState, equip.Value); + _manager.ChangeApplyMeta(_selection.Design!, MetaIndex.VisorState, equip.Value); + _manager.ChangeApplyMeta(_selection.Design!, MetaIndex.WeaponState, equip.Value); + _manager.ChangeApplyMeta(_selection.Design!, MetaIndex.EarState, equip.Value); } if (customize.HasValue) - _manager.ChangeApplyMeta(_selector.Selected!, MetaIndex.Wetness, customize.Value); + _manager.ChangeApplyMeta(_selection.Design!, MetaIndex.Wetness, customize.Value); } private static readonly IReadOnlyList MetaLabels = @@ -425,14 +424,14 @@ public class DesignPanel { using var id = ImUtf8.PushId("Meta"); const uint all = (uint)MetaExtensions.All; - var flags = (uint)_selector.Selected!.Application.Meta; + var flags = (uint)_selection.Design!.Application.Meta; var bigChange = ImGui.CheckboxFlags("Apply All Meta Changes", ref flags, all); foreach (var (index, label) in MetaExtensions.AllRelevant.Zip(MetaLabels)) { - var apply = bigChange ? ((MetaFlag)flags).HasFlag(index.ToFlag()) : _selector.Selected!.DoApplyMeta(index); + var apply = bigChange ? ((MetaFlag)flags).HasFlag(index.ToFlag()) : _selection.Design!.DoApplyMeta(index); if (ImUtf8.Checkbox(label, ref apply) || bigChange) - _manager.ChangeApplyMeta(_selector.Selected!, index, apply); + _manager.ChangeApplyMeta(_selection.Design!, index, apply); } } @@ -444,13 +443,13 @@ public class DesignPanel private void DrawBonusSlotApplication() { using var id = ImUtf8.PushId("Bonus"u8); - var flags = _selector.Selected!.Application.BonusItem; + var flags = _selection.Design!.Application.BonusItem; var bigChange = BonusExtensions.AllFlags.Count > 1 && ImUtf8.Checkbox("Apply All Bonus Slots"u8, ref flags, BonusExtensions.All); foreach (var (index, label) in BonusExtensions.AllFlags.Zip(BonusSlotLabels)) { - var apply = bigChange ? flags.HasFlag(index) : _selector.Selected!.DoApplyBonusItem(index); + var apply = bigChange ? flags.HasFlag(index) : _selection.Design!.DoApplyBonusItem(index); if (ImUtf8.Checkbox(label, ref apply) || bigChange) - _manager.ChangeApplyBonusItem(_selector.Selected!, index, apply); + _manager.ChangeApplyBonusItem(_selection.Design!, index, apply); } } @@ -458,20 +457,23 @@ public class DesignPanel private void DrawParameterApplication() { using var id = Im.Id.Push("Parameter"u8); - var flags = (ulong)_selector.Selected!.Application.Parameters; + var flags = (ulong)_selection.Design!.Application.Parameters; var bigChange = Im.Checkbox("Apply All Customize Parameters"u8, ref flags, (ulong)CustomizeParameterExtensions.All); foreach (var flag in CustomizeParameterExtensions.AllFlags) { - var apply = bigChange ? ((CustomizeParameterFlag)flags).HasFlag(flag) : _selector.Selected!.DoApplyParameter(flag); + var apply = bigChange ? ((CustomizeParameterFlag)flags).HasFlag(flag) : _selection.Design!.DoApplyParameter(flag); if (Im.Checkbox($"Apply {flag.ToNameU8()}", ref apply) || bigChange) - _manager.ChangeApplyParameter(_selector.Selected!, flag, apply); + _manager.ChangeApplyParameter(_selection.Design!, flag, apply); } } + public ReadOnlySpan Id + => "Designs"u8; + public void Draw() { using var group = ImUtf8.Group(); - if (_selector.SelectedPaths.Count > 1) + if (_selection.DesignPaths.Count > 1) { _multiDesignPanel.Draw(); } @@ -480,22 +482,22 @@ public class DesignPanel DrawHeader(); DrawPanel(); - if (_selector.Selected == null || _selector.Selected.WriteProtected()) + if (_selection.Design == null || _selection.Design.WriteProtected()) return; if (_importService.CreateDatTarget(out var dat)) { - _manager.ChangeCustomize(_selector.Selected!, CustomizeIndex.Clan, dat.Customize[CustomizeIndex.Clan]); - _manager.ChangeCustomize(_selector.Selected!, CustomizeIndex.Gender, dat.Customize[CustomizeIndex.Gender]); + _manager.ChangeCustomize(_selection.Design!, CustomizeIndex.Clan, dat.Customize[CustomizeIndex.Clan]); + _manager.ChangeCustomize(_selection.Design!, CustomizeIndex.Gender, dat.Customize[CustomizeIndex.Gender]); foreach (var idx in CustomizationExtensions.AllBasic) - _manager.ChangeCustomize(_selector.Selected!, idx, dat.Customize[idx]); + _manager.ChangeCustomize(_selection.Design!, idx, dat.Customize[idx]); Glamourer.Messager.NotificationMessage( - $"Applied games .dat file {dat.Description} customizations to {_selector.Selected.Name}.", NotificationType.Success, false); + $"Applied games .dat file {dat.Description} customizations to {_selection.Design.Name}.", NotificationType.Success, false); } else if (_importService.CreateCharaTarget(out var designBase, out var name)) { - _manager.ApplyDesign(_selector.Selected!, designBase); - Glamourer.Messager.NotificationMessage($"Applied Anamnesis .chara file {name} to {_selector.Selected.Name}.", + _manager.ApplyDesign(_selection.Design!, designBase); + Glamourer.Messager.NotificationMessage($"Applied Anamnesis .chara file {name} to {_selection.Design.Name}.", NotificationType.Success, false); } } @@ -506,12 +508,12 @@ public class DesignPanel private void DrawPanel() { using var table = Im.Table.Begin("##Panel"u8, 1, TableFlags.BordersOuter | TableFlags.ScrollY, Im.ContentRegion.Available); - if (!table || _selector.Selected is null) + if (!table || _selection.Design is null) return; ImGui.TableSetupScrollFreeze(0, 1); ImGui.TableNextColumn(); - if (_selector.Selected is null) + if (_selection.Design is null) return; Im.Dummy(Vector2.Zero); @@ -550,8 +552,8 @@ public class DesignPanel if (_state.GetOrCreate(id, data.Objects[0], out var state)) { - using var _ = _selector.Selected!.TemporarilyRestrictApplication(ApplicationCollection.FromKeys()); - _state.ApplyDesign(state, _selector.Selected!, ApplySettings.ManualWithLinks with { IsFinal = true }); + using var _ = _selection.Design!.TemporarilyRestrictApplication(ApplicationCollection.FromKeys()); + _state.ApplyDesign(state, _selection.Design!, ApplySettings.ManualWithLinks with { IsFinal = true }); } } @@ -568,14 +570,14 @@ public class DesignPanel if (_state.GetOrCreate(id, data.Objects[0], out var state)) { - using var _ = _selector.Selected!.TemporarilyRestrictApplication(ApplicationCollection.FromKeys()); - _state.ApplyDesign(state, _selector.Selected!, ApplySettings.ManualWithLinks with { IsFinal = true }); + using var _ = _selection.Design!.TemporarilyRestrictApplication(ApplicationCollection.FromKeys()); + _state.ApplyDesign(state, _selection.Design!, ApplySettings.ManualWithLinks with { IsFinal = true }); } } private void DrawSaveToDat() { - var verified = _importService.Verify(_selector.Selected!.DesignData.Customize, out _); + var verified = _importService.Verify(_selection.Design!.DesignData.Customize, out _); var tt = verified ? "Export the currently configured customizations of this design to a character creation data file." : "The current design contains customizations that can not be applied during character creation."; @@ -585,8 +587,8 @@ public class DesignPanel if (ImGuiUtil.DrawDisabledButton("Export to Dat", Vector2.Zero, tt, !verified)) _fileDialog.SaveFileDialog("Save File...", ".dat", "FFXIV_CHARA_01.dat", ".dat", (v, path) => { - if (v && _selector.Selected != null) - _importService.SaveDesignAsDat(path, _selector.Selected!.DesignData.Customize, _selector.Selected!.Name); + if (v && _selection.Design != null) + _importService.SaveDesignAsDat(path, _selection.Design!.DesignData.Customize, _selection.Design!.Name); }, startPath); _fileDialog.Draw(); @@ -595,163 +597,163 @@ public class DesignPanel private static unsafe string GetUserPath() => Framework.Instance()->UserPathString; +} - private sealed class LockButton(DesignPanel panel) : Button +private sealed class LockButton(DesignPanel panel) : Button +{ + public override bool Visible + => panel._selection.Design != null; + + protected override string Description + => panel._selection.Design!.WriteProtected() + ? "Make this design editable." + : "Write-protect this design."; + + protected override FontAwesomeIcon Icon + => panel._selection.Design!.WriteProtected() + ? FontAwesomeIcon.Lock + : FontAwesomeIcon.LockOpen; + + protected override void OnClick() + => panel._manager.SetWriteProtection(panel._selection.Design!, !panel._selection.Design!.WriteProtected()); +} + +private sealed class SetFromClipboardButton(DesignPanel panel) : Button +{ + public override bool Visible + => panel._selection.Design != null; + + protected override bool Disabled + => panel._selection.Design?.WriteProtected() ?? true; + + protected override string Description + => "Try to apply a design from your clipboard over this design.\nHold Control to only apply gear.\nHold Shift to only apply customizations."; + + protected override FontAwesomeIcon Icon + => FontAwesomeIcon.Clipboard; + + protected override void OnClick() { - public override bool Visible - => panel._selector.Selected != null; - - protected override string Description - => panel._selector.Selected!.WriteProtected() - ? "Make this design editable." - : "Write-protect this design."; - - protected override FontAwesomeIcon Icon - => panel._selector.Selected!.WriteProtected() - ? FontAwesomeIcon.Lock - : FontAwesomeIcon.LockOpen; - - protected override void OnClick() - => panel._manager.SetWriteProtection(panel._selector.Selected!, !panel._selector.Selected!.WriteProtected()); - } - - private sealed class SetFromClipboardButton(DesignPanel panel) : Button - { - public override bool Visible - => panel._selector.Selected != null; - - protected override bool Disabled - => panel._selector.Selected?.WriteProtected() ?? true; - - protected override string Description - => "Try to apply a design from your clipboard over this design.\nHold Control to only apply gear.\nHold Shift to only apply customizations."; - - protected override FontAwesomeIcon Icon - => FontAwesomeIcon.Clipboard; - - protected override void OnClick() + try { - try - { - var text = ImGui.GetClipboardText(); - var (applyEquip, applyCustomize) = UiHelpers.ConvertKeysToBool(); - var design = panel._converter.FromBase64(text, applyCustomize, applyEquip, out _) - ?? throw new Exception("The clipboard did not contain valid data."); - panel._manager.ApplyDesign(panel._selector.Selected!, design); - } - catch (Exception ex) - { - Glamourer.Messager.NotificationMessage(ex, $"Could not apply clipboard to {panel._selector.Selected!.Name}.", - $"Could not apply clipboard to design {panel._selector.Selected!.Identifier}", NotificationType.Error, false); - } + var text = ImGui.GetClipboardText(); + var (applyEquip, applyCustomize) = UiHelpers.ConvertKeysToBool(); + var design = panel._converter.FromBase64(text, applyCustomize, applyEquip, out _) + ?? throw new Exception("The clipboard did not contain valid data."); + panel._manager.ApplyDesign(panel._selection.Design!, design); } - } - - private sealed class DesignUndoButton(DesignPanel panel) : Button - { - public override bool Visible - => panel._selector.Selected != null; - - protected override bool Disabled - => !panel._manager.CanUndo(panel._selector.Selected) || (panel._selector.Selected?.WriteProtected() ?? true); - - protected override string Description - => "Undo the last time you applied an entire design onto this design, if you accidentally overwrote your design with a different one."; - - protected override FontAwesomeIcon Icon - => FontAwesomeIcon.SyncAlt; - - protected override void OnClick() + catch (Exception ex) { - try - { - panel._manager.UndoDesignChange(panel._selector.Selected!); - } - catch (Exception ex) - { - Glamourer.Messager.NotificationMessage(ex, $"Could not undo last changes to {panel._selector.Selected!.Name}.", - NotificationType.Error, - false); - } + Glamourer.Messager.NotificationMessage(ex, $"Could not apply clipboard to {panel._selection.Design!.Name}.", + $"Could not apply clipboard to design {panel._selection.Design!.Identifier}", NotificationType.Error, false); } } - - private sealed class ExportToClipboardButton(DesignPanel panel) : Button - { - public override bool Visible - => panel._selector.Selected != null; - - protected override string Description - => "Copy the current design to your clipboard."; - - protected override FontAwesomeIcon Icon - => FontAwesomeIcon.Copy; - - protected override void OnClick() - { - try - { - var text = panel._converter.ShareBase64(panel._selector.Selected!); - ImGui.SetClipboardText(text); - } - catch (Exception ex) - { - Glamourer.Messager.NotificationMessage(ex, $"Could not copy {panel._selector.Selected!.Name} data to clipboard.", - $"Could not copy data from design {panel._selector.Selected!.Identifier} to clipboard", NotificationType.Error, false); - } - } - } - - private sealed class ApplyCharacterButton(DesignPanel panel) : Button - { - public override bool Visible - => panel._selector.Selected != null && panel._objects.Player.Valid; - - protected override string Description - => "Overwrite this design with your character's current state."; - - protected override bool Disabled - => panel._selector.Selected?.WriteProtected() ?? true; - - protected override FontAwesomeIcon Icon - => FontAwesomeIcon.UserEdit; - - protected override void OnClick() - { - try - { - var (player, actor) = panel._objects.PlayerData; - if (!player.IsValid || !actor.Valid || !panel._state.GetOrCreate(player, actor.Objects[0], out var state)) - throw new Exception("No player state available."); - - var design = panel._converter.Convert(state, ApplicationRules.FromModifiers(state)) - ?? throw new Exception("The clipboard did not contain valid data."); - panel._selector.Selected!.GetMaterialDataRef().Clear(); - panel._manager.ApplyDesign(panel._selector.Selected!, design); - } - catch (Exception ex) - { - Glamourer.Messager.NotificationMessage(ex, $"Could not apply player state to {panel._selector.Selected!.Name}.", - $"Could not apply player state to design {panel._selector.Selected!.Identifier}", NotificationType.Error, false); - } - } - } - - private sealed class UndoButton(DesignPanel panel) : Button - { - protected override string Description - => "Undo the last change."; - - protected override FontAwesomeIcon Icon - => FontAwesomeIcon.Undo; - - public override bool Visible - => panel._selector.Selected != null; - - protected override bool Disabled - => (panel._selector.Selected?.WriteProtected() ?? true) || !panel._history.CanUndo(panel._selector.Selected); - - protected override void OnClick() - => panel._history.Undo(panel._selector.Selected!); - } } + +private sealed class DesignUndoButton(DesignPanel panel) : Button +{ + public override bool Visible + => panel._selection.Design != null; + + protected override bool Disabled + => !panel._manager.CanUndo(panel._selection.Design) || (panel._selection.Design?.WriteProtected() ?? true); + + protected override string Description + => "Undo the last time you applied an entire design onto this design, if you accidentally overwrote your design with a different one."; + + protected override FontAwesomeIcon Icon + => FontAwesomeIcon.SyncAlt; + + protected override void OnClick() + { + try + { + panel._manager.UndoDesignChange(panel._selection.Design!); + } + catch (Exception ex) + { + Glamourer.Messager.NotificationMessage(ex, $"Could not undo last changes to {panel._selection.Design!.Name}.", + NotificationType.Error, + false); + } + } +} + +private sealed class ExportToClipboardButton(DesignPanel panel) : Button +{ + public override bool Visible + => panel._selection.Design != null; + + protected override string Description + => "Copy the current design to your clipboard."; + + protected override FontAwesomeIcon Icon + => FontAwesomeIcon.Copy; + + protected override void OnClick() + { + try + { + var text = panel._converter.ShareBase64(panel._selection.Design!); + ImGui.SetClipboardText(text); + } + catch (Exception ex) + { + Glamourer.Messager.NotificationMessage(ex, $"Could not copy {panel._selection.Design!.Name} data to clipboard.", + $"Could not copy data from design {panel._selection.Design!.Identifier} to clipboard", NotificationType.Error, false); + } + } +} + +private sealed class ApplyCharacterButton(DesignPanel panel) : Button +{ + public override bool Visible + => panel._selection.Design != null && panel._objects.Player.Valid; + + protected override string Description + => "Overwrite this design with your character's current state."; + + protected override bool Disabled + => panel._selection.Design?.WriteProtected() ?? true; + + protected override FontAwesomeIcon Icon + => FontAwesomeIcon.UserEdit; + + protected override void OnClick() + { + try + { + var (player, actor) = panel._objects.PlayerData; + if (!player.IsValid || !actor.Valid || !panel._state.GetOrCreate(player, actor.Objects[0], out var state)) + throw new Exception("No player state available."); + + var design = panel._converter.Convert(state, ApplicationRules.FromModifiers(state)) + ?? throw new Exception("The clipboard did not contain valid data."); + panel._selection.Design!.GetMaterialDataRef().Clear(); + panel._manager.ApplyDesign(panel._selection.Design!, design); + } + catch (Exception ex) + { + Glamourer.Messager.NotificationMessage(ex, $"Could not apply player state to {panel._selection.Design!.Name}.", + $"Could not apply player state to design {panel._selection.Design!.Identifier}", NotificationType.Error, false); + } + } +} + +private sealed class UndoButton(DesignPanel panel) : Button +{ + protected override string Description + => "Undo the last change."; + + protected override FontAwesomeIcon Icon + => FontAwesomeIcon.Undo; + + public override bool Visible + => panel._selection.Design != null; + + protected override bool Disabled + => (panel._selection.Design?.WriteProtected() ?? true) || !panel._history.CanUndo(panel._selection.Design); + + protected override void OnClick() + => panel._history.Undo(panel._selection.Design!); +} \ No newline at end of file diff --git a/Glamourer/Gui/Tabs/DesignTab/DesignSelection.cs b/Glamourer/Gui/Tabs/DesignTab/DesignSelection.cs new file mode 100644 index 0000000..f070208 --- /dev/null +++ b/Glamourer/Gui/Tabs/DesignTab/DesignSelection.cs @@ -0,0 +1,12 @@ +using Glamourer.Designs; +using Luna; + +namespace Glamourer.Gui.Tabs.DesignTab; + +public sealed class DesignSelection : IUiService, IDisposable +{ + public Design? Design { get; private set; } + + public void Dispose() + { } +} diff --git a/Glamourer/Gui/Tabs/DesignTab/ModCombo.cs b/Glamourer/Gui/Tabs/DesignTab/ModCombo.cs index a0b805e..96bdb2e 100644 --- a/Glamourer/Gui/Tabs/DesignTab/ModCombo.cs +++ b/Glamourer/Gui/Tabs/DesignTab/ModCombo.cs @@ -1,95 +1,107 @@ -using Dalamud.Interface.Utility; -using Glamourer.Interop.Penumbra; -using Dalamud.Bindings.ImGui; +using Glamourer.Interop.Penumbra; using ImSharp; -using OtterGui.Classes; -using OtterGui.Log; -using OtterGui.Raii; -using OtterGui.Text; -using OtterGui.Widgets; -using MouseWheelType = OtterGui.Widgets.MouseWheelType; namespace Glamourer.Gui.Tabs.DesignTab; -public sealed class ModCombo : FilterComboCache<(Mod Mod, ModSettings Settings, int Count)> +public sealed class ModCombo(PenumbraService penumbra, DesignSelection selection) : ImSharp.FilterComboBase(new ModFilter()) { - public ModCombo(PenumbraService penumbra, Logger log, DesignFileSystemSelector selector) - : base(() => penumbra.GetMods(selector.Selected?.FilteredItemNames.ToArray() ?? []), MouseWheelType.None, log) - => SearchByParts = false; - - protected override string ToString((Mod Mod, ModSettings Settings, int Count) obj) - => obj.Mod.Name; - - protected override bool IsVisible(int globalIndex, LowerString filter) - => filter.IsContained(Items[globalIndex].Mod.Name) || filter.IsContained(Items[globalIndex].Mod.DirectoryName); - - protected override bool DrawSelectable(int globalIdx, bool selected) + public readonly struct CacheItem(in Mod mod, in ModSettings settings, int count) { - using var id = ImUtf8.PushId(globalIdx); - var (mod, settings, count) = Items[globalIdx]; - bool ret; - var color = settings.Enabled + public readonly StringPair Name = new(mod.Name); + public readonly StringPair Directory = new(mod.DirectoryName); + public readonly ModSettings Settings = settings; + public readonly int Count = count; + + public readonly Vector4 Color = settings.Enabled ? count > 0 - ? ColorId.ContainsItemsEnabled.Value() - : ImGuiColor.Text.Get() + ? ColorId.ContainsItemsEnabled.Value().ToVector() + : Im.Style[ImGuiColor.Text] : count > 0 - ? ColorId.ContainsItemsDisabled.Value() - : ImGuiColor.TextDisabled.Get(); - using (ImGuiColor.Text.Push(color)) + ? ColorId.ContainsItemsDisabled.Value().ToVector() + : Im.Style[ImGuiColor.TextDisabled]; + + public readonly bool DifferingNames = string.Equals(mod.Name, mod.DirectoryName, StringComparison.CurrentCultureIgnoreCase); + } + + protected override float ItemHeight + => Im.Style.TextHeightWithSpacing; + + protected override IEnumerable GetItems() + => penumbra.GetMods(selection.Design?.FilteredItemNames.ToArray() ?? []).Select(t => new CacheItem(t.Mod, t.Settings, t.Count)); + + protected override bool DrawItem(in CacheItem item, int globalIndex, bool selected) + { + bool ret; + using (ImGuiColor.Text.Push(item.Color)) { - ret = ImUtf8.Selectable(mod.Name, selected); + ret = Im.Selectable(item.Name.Utf8, selected); } - if (ImGui.IsItemHovered()) - { - using var style = ImRaii.PushStyle(ImGuiStyleVar.PopupBorderSize, 2 * Im.Style.GlobalScale); - using var tt = ImUtf8.Tooltip(); - var namesDifferent = mod.Name != mod.DirectoryName; - Im.Dummy(new Vector2(300 * Im.Style.GlobalScale, 0)); - using (ImUtf8.Group()) - { - if (namesDifferent) - ImUtf8.Text("Directory Name"u8); - ImUtf8.Text("Enabled"u8); - ImUtf8.Text("Priority"u8); - ImUtf8.Text("Affected Design Items"u8); - DrawSettingsLeft(settings); - } - - ImGui.SameLine(Math.Max(ImGui.GetItemRectSize().X + 3 * Im.Style.ItemSpacing.X, 150 * Im.Style.GlobalScale)); - using (ImUtf8.Group()) - { - if (namesDifferent) - ImUtf8.Text(mod.DirectoryName); - ImUtf8.Text($"{settings.Enabled}"); - ImUtf8.Text($"{settings.Priority}"); - ImUtf8.Text($"{count}"); - DrawSettingsRight(settings); - } - } + if (Im.Item.Hovered()) + DrawTooltip(item); return ret; } - public static void DrawSettingsLeft(ModSettings settings) + private static void DrawTooltip(in CacheItem item) + { + using var style = ImStyleSingle.PopupBorderThickness.Push(2 * Im.Style.GlobalScale); + using var tt = Im.Tooltip.Begin(); + + Im.Dummy(new Vector2(300 * Im.Style.GlobalScale, 0)); + using (Im.Group()) + { + if (item.DifferingNames) + Im.Text("Directory Name"u8); + Im.Text("Enabled"u8); + Im.Text("Priority"u8); + Im.Text("Affected Design Items"u8); + DrawSettingsLeft(item.Settings); + } + + Im.Line.Same(Math.Max(Im.Item.Size.X + 3 * Im.Style.ItemSpacing.X, 150 * Im.Style.GlobalScale)); + using (Im.Group()) + { + if (item.DifferingNames) + Im.Text(item.Directory.Utf8); + Im.Text($"{item.Settings.Enabled}"); + Im.Text($"{item.Settings.Priority}"); + Im.Text($"{item.Count}"); + DrawSettingsRight(item.Settings); + } + } + + private static void DrawSettingsLeft(in ModSettings settings) { foreach (var setting in settings.Settings) { - ImUtf8.Text(setting.Key); + Im.Text(setting.Key); for (var i = 1; i < setting.Value.Count; ++i) Im.Line.New(); } } - public static void DrawSettingsRight(ModSettings settings) + private static void DrawSettingsRight(in ModSettings settings) { foreach (var setting in settings.Settings) { if (setting.Value.Count == 0) - ImUtf8.Text(""u8); + Im.Text(""u8); else foreach (var option in setting.Value) - ImUtf8.Text(option); + Im.Text(option); } } + + protected override bool IsSelected(CacheItem item, int globalIndex) + => throw new NotImplementedException(); + + private sealed class ModFilter : TextFilterBase + { + public override bool WouldBeVisible(in CacheItem item, int globalIndex) + => base.WouldBeVisible(in item, globalIndex) || WouldBeVisible(item.Directory.Utf16); + + protected override string ToFilterString(in CacheItem item, int globalIndex) + => item.Name.Utf16; + } } diff --git a/Glamourer/Gui/Tabs/DesignTab/MultiDesignPanel.cs b/Glamourer/Gui/Tabs/DesignTab/MultiDesignPanel.cs index c7ca7c6..06588fc 100644 --- a/Glamourer/Gui/Tabs/DesignTab/MultiDesignPanel.cs +++ b/Glamourer/Gui/Tabs/DesignTab/MultiDesignPanel.cs @@ -1,13 +1,7 @@ -using Dalamud.Interface; -using Dalamud.Interface.Utility; -using Glamourer.Designs; +using Glamourer.Designs; using Glamourer.Interop.Material; -using Dalamud.Bindings.ImGui; using ImSharp; -using OtterGui.Extensions; -using OtterGui.Raii; -using OtterGui.Text; -using static Glamourer.Gui.Tabs.HeaderDrawer; +using Luna; namespace Glamourer.Gui.Tabs.DesignTab; @@ -17,9 +11,6 @@ public class MultiDesignPanel( DesignColors colors, Configuration config) { - private readonly Button[] _leftButtons = []; - private readonly Button[] _rightButtons = []; //[new IncognitoButton(config)]; - private readonly DesignColorCombo _colorCombo = new(colors, true); public void Draw() @@ -27,13 +18,8 @@ public class MultiDesignPanel( if (selector.SelectedPaths.Count == 0) return; - HeaderDrawer.Draw(string.Empty, 0, ImGuiColor.FrameBackground.Get().Color, _leftButtons, _rightButtons); - using var child = ImUtf8.Child("##MultiPanel"u8, default, true); - if (!child) - return; - - var width = ImGuiHelpers.ScaledVector2(145, 0); - var treeNodePos = ImGui.GetCursorPos(); + var width = ImEx.ScaledVectorX(145); + var treeNodePos = Im.Cursor.Position; _numDesigns = DrawDesignList(); DrawCounts(treeNodePos); var offset = DrawMultiTagger(width); @@ -49,18 +35,17 @@ public class MultiDesignPanel( private void DrawCounts(Vector2 treeNodePos) { - var startPos = ImGui.GetCursorPos(); + var startPos = Im.Cursor.Position; var numFolders = selector.SelectedPaths.Count - _numDesigns; - var text = (_numDesigns, numFolders) switch + Im.Cursor.Position = treeNodePos; + ImEx.TextRightAligned((_numDesigns, numFolders) switch { - (0, 0) => string.Empty, // should not happen - (> 0, 0) => $"{_numDesigns} Designs", - (0, > 0) => $"{numFolders} Folders", - _ => $"{_numDesigns} Designs, {numFolders} Folders", - }; - ImGui.SetCursorPos(treeNodePos); - ImUtf8.TextRightAligned(text); - ImGui.SetCursorPos(startPos); + (0, 0) => StringU8.Empty, // should not happen + ( > 0, 0) => $"{_numDesigns} Designs", + (0, > 0) => $"{numFolders} Folders", + _ => $"{_numDesigns} Designs, {numFolders} Folders", + }); + Im.Cursor.Position = startPos; } private void ResetCounts() @@ -127,14 +112,14 @@ public class MultiDesignPanel( { using var id = Im.Id.Push(i++); var (icon, text) = path is DesignFileSystem.Leaf l - ? (FontAwesomeIcon.FileCircleMinus, l.Value.Name.Text) - : (FontAwesomeIcon.FolderMinus, string.Empty); - ImGui.TableNextColumn(); - if (ImUtf8.IconButton(icon, "Remove from selection."u8, sizeType)) + ? (LunaStyle.RemoveFileIcon, l.Value.Name.Text) + : (LunaStyle.RemoveFolderIcon, string.Empty); + table.NextColumn(); + if (ImEx.Icon.Button(icon, "Remove from selection."u8, sizeType)) selector.RemovePathFromMultiSelection(path); - ImUtf8.DrawFrameColumn(text); - ImUtf8.DrawFrameColumn(fullName); + table.DrawFrameColumn(text); + table.DrawFrameColumn(fullName); if (CountLeaves(path)) ++numDesigns; @@ -159,36 +144,32 @@ public class MultiDesignPanel( private float DrawMultiTagger(Vector2 width) { - ImUtf8.TextFrameAligned("Multi Tagger:"u8); + ImEx.TextFrameAligned("Multi Tagger:"u8); Im.Line.Same(); - var offset = ImGui.GetItemRectSize().X + Im.Style.WindowPadding.X; - ImGui.SetNextItemWidth(Im.ContentRegion.Available.X - 2 * (width.X + Im.Style.ItemSpacing.X)); - ImUtf8.InputText("##tag"u8, ref _tag, "Tag Name..."u8); + var offset = Im.Item.Size.X + Im.Style.WindowPadding.X; + Im.Item.SetNextWidth(Im.ContentRegion.Available.X - 2 * (width.X + Im.Style.ItemSpacing.X)); + Im.Input.Text("##tag"u8, ref _tag, "Tag Name..."u8); UpdateTagCache(); - var label = _addDesigns.Count > 0 - ? $"Add to {_addDesigns.Count} Designs" - : "Add"; - var tooltip = _addDesigns.Count == 0 - ? _tag.Length == 0 - ? "No tag specified." - : $"All designs selected already contain the tag \"{_tag}\"." - : $"Add the tag \"{_tag}\" to {_addDesigns.Count} designs as a local tag:\n\n\t{string.Join("\n\t", _addDesigns.Select(m => m.Name.Text))}"; Im.Line.Same(); - if (ImUtf8.ButtonEx(label, tooltip, width, _addDesigns.Count == 0)) + if (ImEx.Button(_addDesigns.Count > 0 + ? $"Add to {_addDesigns.Count} Designs" + : "Add"u8, width, _addDesigns.Count is 0 + ? _tag.Length is 0 + ? "No tag specified."u8 + : $"All designs selected already contain the tag \"{_tag}\"." + : $"Add the tag \"{_tag}\" to {_addDesigns.Count} designs as a local tag:\n\n\t{StringU8.Join("\n\t"u8, _addDesigns.Select(m => m.Name.Text))}", _addDesigns.Count is 0)) foreach (var design in _addDesigns) editor.AddTag(design, _tag); - label = _removeDesigns.Count > 0 - ? $"Remove from {_removeDesigns.Count} Designs" - : "Remove"; - tooltip = _removeDesigns.Count == 0 - ? _tag.Length == 0 - ? "No tag specified." - : $"No selected design contains the tag \"{_tag}\" locally." - : $"Remove the local tag \"{_tag}\" from {_removeDesigns.Count} designs:\n\n\t{string.Join("\n\t", _removeDesigns.Select(m => m.Item1.Name.Text))}"; Im.Line.Same(); - if (ImUtf8.ButtonEx(label, tooltip, width, _removeDesigns.Count == 0)) + if (ImEx.Button(_removeDesigns.Count > 0 + ? $"Remove from {_removeDesigns.Count} Designs" + : "Remove", width, _removeDesigns.Count is 0 + ? _tag.Length is 0 + ? "No tag specified."u8 + : $"No selected design contains the tag \"{_tag}\" locally." + : $"Remove the local tag \"{_tag}\" from {_removeDesigns.Count} designs:\n\n\t{string.Join("\n\t", _removeDesigns.Select(m => m.Item1.Name.Text))}", _removeDesigns.Count is 0)) foreach (var (design, index) in _removeDesigns) editor.RemoveTag(design, index); Im.Separator(); @@ -197,24 +178,22 @@ public class MultiDesignPanel( private void DrawMultiQuickDesignBar(float offset) { - ImUtf8.TextFrameAligned("Multi QDB:"u8); - ImGui.SameLine(offset, Im.Style.ItemSpacing.X); + ImEx.TextFrameAligned("Multi QDB:"u8); + Im.Line.Same(offset, Im.Style.ItemSpacing.X); var buttonWidth = new Vector2((Im.ContentRegion.Available.X - Im.Style.ItemSpacing.X) / 2, 0); var diff = _numDesigns - _numQuickDesignEnabled; - var tt = diff == 0 - ? $"All {_numDesigns} selected designs are already displayed in the quick design bar." - : $"Display all {_numDesigns} selected designs in the quick design bar. Changes {diff} designs."; - if (ImUtf8.ButtonEx("Display Selected Designs in QDB"u8, tt, buttonWidth, diff == 0)) + if (ImEx.Button("Display Selected Designs in QDB"u8, buttonWidth, diff is 0 + ? $"All {_numDesigns} selected designs are already displayed in the quick design bar." + : $"Display all {_numDesigns} selected designs in the quick design bar. Changes {diff} designs.", diff is 0)) { foreach (var design in selector.SelectedPaths.OfType()) editor.SetQuickDesign(design.Value, true); } Im.Line.Same(); - tt = _numQuickDesignEnabled == 0 - ? $"All {_numDesigns} selected designs are already hidden in the quick design bar." - : $"Hide all {_numDesigns} selected designs in the quick design bar. Changes {_numQuickDesignEnabled} designs."; - if (ImUtf8.ButtonEx("Hide Selected Designs in QDB"u8, tt, buttonWidth, _numQuickDesignEnabled == 0)) + if (ImEx.Button("Hide Selected Designs in QDB"u8, buttonWidth, _numQuickDesignEnabled is 0 + ? $"All {_numDesigns} selected designs are already hidden in the quick design bar." + : $"Hide all {_numDesigns} selected designs in the quick design bar. Changes {_numQuickDesignEnabled} designs.", _numQuickDesignEnabled is 0)) { foreach (var design in selector.SelectedPaths.OfType()) editor.SetQuickDesign(design.Value, false); @@ -225,22 +204,20 @@ public class MultiDesignPanel( private void DrawMultiLock(float offset) { - ImUtf8.TextFrameAligned("Multi Lock:"u8); - ImGui.SameLine(offset, Im.Style.ItemSpacing.X); + ImEx.TextFrameAligned("Multi Lock:"u8); + Im.Line.Same(offset, Im.Style.ItemSpacing.X); var buttonWidth = new Vector2((Im.ContentRegion.Available.X - Im.Style.ItemSpacing.X) / 2, 0); var diff = _numDesigns - _numDesignsLocked; - var tt = diff == 0 - ? $"All {_numDesigns} selected designs are already write protected." - : $"Write-protect all {_numDesigns} designs. Changes {diff} designs."; - if (ImUtf8.ButtonEx("Turn Write-Protected"u8, tt, buttonWidth, diff == 0)) + if (ImEx.Button("Turn Write-Protected"u8, buttonWidth, diff is 0 + ? $"All {_numDesigns} selected designs are already write protected." + : $"Write-protect all {_numDesigns} designs. Changes {diff} designs.", diff is 0)) foreach (var design in selector.SelectedPaths.OfType()) editor.SetWriteProtection(design.Value, true); Im.Line.Same(); - tt = _numDesignsLocked == 0 - ? $"None of the {_numDesigns} selected designs are write-protected." - : $"Remove the write protection of the {_numDesigns} selected designs. Changes {_numDesignsLocked} designs."; - if (ImUtf8.ButtonEx("Remove Write-Protection"u8, tt, buttonWidth, _numDesignsLocked == 0)) + if (ImEx.Button("Remove Write-Protection"u8, buttonWidth, _numDesignsLocked is 0 + ? $"None of the {_numDesigns} selected designs are write-protected." + : $"Remove the write protection of the {_numDesigns} selected designs. Changes {_numDesignsLocked} designs.", _numDesignsLocked is 0)) foreach (var design in selector.SelectedPaths.OfType()) editor.SetWriteProtection(design.Value, false); Im.Separator(); @@ -248,22 +225,20 @@ public class MultiDesignPanel( private void DrawMultiResetSettings(float offset) { - ImUtf8.TextFrameAligned("Settings:"u8); - ImGui.SameLine(offset, Im.Style.ItemSpacing.X); + ImEx.TextFrameAligned("Settings:"u8); + Im.Line.Same(offset, Im.Style.ItemSpacing.X); var buttonWidth = new Vector2((Im.ContentRegion.Available.X - Im.Style.ItemSpacing.X) / 2, 0); var diff = _numDesigns - _numDesignsResetSettings; - var tt = diff == 0 - ? $"All {_numDesigns} selected designs already reset temporary settings." - : $"Make all {_numDesigns} selected designs reset temporary settings. Changes {diff} designs."; - if (ImUtf8.ButtonEx("Set Reset Temp. Settings"u8, tt, buttonWidth, diff == 0)) + if (ImEx.Button("Set Reset Temp. Settings"u8, buttonWidth, diff is 0 + ? $"All {_numDesigns} selected designs already reset temporary settings." + : $"Make all {_numDesigns} selected designs reset temporary settings. Changes {diff} designs.", diff is 0)) foreach (var design in selector.SelectedPaths.OfType()) editor.ChangeResetTemporarySettings(design.Value, true); Im.Line.Same(); - tt = _numDesignsResetSettings == 0 - ? $"None of the {_numDesigns} selected designs reset temporary settings." - : $"Stop all {_numDesigns} selected designs from resetting temporary settings. Changes {_numDesignsResetSettings} designs."; - if (ImUtf8.ButtonEx("Remove Reset Temp. Settings"u8, tt, buttonWidth, _numDesignsResetSettings == 0)) + if (ImEx.Button("Remove Reset Temp. Settings"u8, buttonWidth, _numDesignsResetSettings is 0 + ? $"None of the {_numDesigns} selected designs reset temporary settings." + : $"Stop all {_numDesigns} selected designs from resetting temporary settings. Changes {_numDesignsResetSettings} designs.", _numDesignsResetSettings is 0)) foreach (var design in selector.SelectedPaths.OfType()) editor.ChangeResetTemporarySettings(design.Value, false); Im.Separator(); @@ -271,22 +246,20 @@ public class MultiDesignPanel( private void DrawMultiResetDyes(float offset) { - ImUtf8.TextFrameAligned("Adv. Dyes:"u8); - ImGui.SameLine(offset, Im.Style.ItemSpacing.X); + ImEx.TextFrameAligned("Adv. Dyes:"u8); + Im.Line.Same(offset, Im.Style.ItemSpacing.X); var buttonWidth = new Vector2((Im.ContentRegion.Available.X - Im.Style.ItemSpacing.X) / 2, 0); var diff = _numDesigns - _numDesignsResetDyes; - var tt = diff == 0 - ? $"All {_numDesigns} selected designs already reset advanced dyes." - : $"Make all {_numDesigns} selected designs reset advanced dyes. Changes {diff} designs."; - if (ImUtf8.ButtonEx("Set Reset Dyes"u8, tt, buttonWidth, diff == 0)) + if (ImEx.Button("Set Reset Dyes"u8, buttonWidth, diff is 0 + ? $"All {_numDesigns} selected designs already reset advanced dyes." + : $"Make all {_numDesigns} selected designs reset advanced dyes. Changes {diff} designs.", diff is 0)) foreach (var design in selector.SelectedPaths.OfType()) editor.ChangeResetAdvancedDyes(design.Value, true); Im.Line.Same(); - tt = _numDesignsLocked == 0 - ? $"None of the {_numDesigns} selected designs reset advanced dyes." - : $"Stop all {_numDesigns} selected designs from resetting advanced dyes. Changes {_numDesignsResetDyes} designs."; - if (ImUtf8.ButtonEx("Remove Reset Dyes"u8, tt, buttonWidth, _numDesignsResetDyes == 0)) + if (ImEx.Button("Remove Reset Dyes"u8, buttonWidth, _numDesignsLocked is 0 + ? $"None of the {_numDesigns} selected designs reset advanced dyes." + : $"Stop all {_numDesigns} selected designs from resetting advanced dyes. Changes {_numDesignsResetDyes} designs.", _numDesignsResetDyes is 0)) foreach (var design in selector.SelectedPaths.OfType()) editor.ChangeResetAdvancedDyes(design.Value, false); Im.Separator(); @@ -294,22 +267,20 @@ public class MultiDesignPanel( private void DrawMultiForceRedraw(float offset) { - ImUtf8.TextFrameAligned("Redrawing:"u8); - ImGui.SameLine(offset, Im.Style.ItemSpacing.X); + ImEx.TextFrameAligned("Redrawing:"u8); + Im.Line.Same(offset, Im.Style.ItemSpacing.X); var buttonWidth = new Vector2((Im.ContentRegion.Available.X - Im.Style.ItemSpacing.X) / 2, 0); var diff = _numDesigns - _numDesignsForcedRedraw; - var tt = diff == 0 - ? $"All {_numDesigns} selected designs already force redraws." - : $"Make all {_numDesigns} designs force redraws. Changes {diff} designs."; - if (ImUtf8.ButtonEx("Force Redraws"u8, tt, buttonWidth, diff == 0)) + if (ImEx.Button("Force Redraws"u8, buttonWidth, diff is 0 + ? $"All {_numDesigns} selected designs already force redraws." + : $"Make all {_numDesigns} designs force redraws. Changes {diff} designs.", diff is 0)) foreach (var design in selector.SelectedPaths.OfType()) editor.ChangeForcedRedraw(design.Value, true); Im.Line.Same(); - tt = _numDesignsLocked == 0 - ? $"None of the {_numDesigns} selected designs force redraws." - : $"Stop all {_numDesigns} selected designs from forcing redraws. Changes {_numDesignsForcedRedraw} designs."; - if (ImUtf8.ButtonEx("Remove Forced Redraws"u8, tt, buttonWidth, _numDesignsForcedRedraw == 0)) + if (ImEx.Button("Remove Forced Redraws"u8, buttonWidth, _numDesignsLocked is 0 + ? $"None of the {_numDesigns} selected designs force redraws." + : $"Stop all {_numDesigns} selected designs from forcing redraws. Changes {_numDesignsForcedRedraw} designs.", _numDesignsForcedRedraw is 0)) foreach (var design in selector.SelectedPaths.OfType()) editor.ChangeForcedRedraw(design.Value, false); Im.Separator(); @@ -319,39 +290,35 @@ public class MultiDesignPanel( private void DrawMultiColor(Vector2 width, float offset) { - ImUtf8.TextFrameAligned("Multi Colors:"u8); - ImGui.SameLine(offset, Im.Style.ItemSpacing.X); + ImEx.TextFrameAligned("Multi Colors:"u8); + Im.Line.Same(offset, Im.Style.ItemSpacing.X); if (_colorCombo.Draw("##color"u8, _colorComboSelection, "Select a design color."u8, Im.ContentRegion.Available.X - 2 * (width.X + Im.Style.ItemSpacing.X), out var newSelection)) _colorComboSelection = newSelection; UpdateColorCache(); - var label = _addDesigns.Count > 0 - ? $"Set for {_addDesigns.Count} Designs" - : "Set"; - var tooltip = _addDesigns.Count is 0 - ? _colorComboSelection switch - { - null => "No color specified.", - DesignColors.AutomaticName => "Use the other button to set to automatic.", - _ => $"All designs selected are already set to the color \"{_colorComboSelection}\".", - } - : $"Set the color of {_addDesigns.Count} designs to \"{_colorComboSelection}\"\n\n\t{string.Join("\n\t", _addDesigns.Select(m => m.Name.Text))}"; Im.Line.Same(); - if (ImEx.Button(label, width, tooltip, _addDesigns.Count is 0)) + if (ImEx.Button(_addDesigns.Count > 0 + ? $"Set for {_addDesigns.Count} Designs" + : "Set"u8, width, _addDesigns.Count is 0 + ? _colorComboSelection switch + { + null => "No color specified."u8, + DesignColors.AutomaticName => "Use the other button to set to automatic."u8, + _ => $"All designs selected are already set to the color \"{_colorComboSelection}\".", + } + : $"Set the color of {_addDesigns.Count} designs to \"{_colorComboSelection}\"\n\n\t{StringU8.Join("\n\t"u8, _addDesigns.Select(m => m.Name.Text))}", _addDesigns.Count is 0)) { foreach (var design in _addDesigns) editor.ChangeColor(design, _colorComboSelection!); } - label = _removeDesigns.Count > 0 - ? $"Unset {_removeDesigns.Count} Designs" - : "Unset"; - tooltip = _removeDesigns.Count == 0 - ? "No selected design is set to a non-automatic color." - : $"Set {_removeDesigns.Count} designs to use automatic color again:\n\n\t{string.Join("\n\t", _removeDesigns.Select(m => m.Item1.Name.Text))}"; Im.Line.Same(); - if (ImEx.Button(label, width, tooltip, _removeDesigns.Count is 0)) + if (ImEx.Button(_removeDesigns.Count > 0 + ? $"Unset {_removeDesigns.Count} Designs" + : "Unset"u8, width, _removeDesigns.Count is 0 + ? "No selected design is set to a non-automatic color."u8 + : $"Set {_removeDesigns.Count} designs to use automatic color again:\n\n\t{StringU8.Join("\n\t"u8, _removeDesigns.Select(m => m.Item1.Name.Text))}", _removeDesigns.Count is 0)) { foreach (var (design, _) in _removeDesigns) editor.ChangeColor(design, string.Empty); @@ -362,13 +329,12 @@ public class MultiDesignPanel( private void DrawAdvancedButtons(float offset) { - ImUtf8.TextFrameAligned("Delete Adv."u8); - ImGui.SameLine(offset, Im.Style.ItemSpacing.X); + ImEx.TextFrameAligned("Delete Adv."u8); + Im.Line.Same(offset, Im.Style.ItemSpacing.X); var enabled = config.DeleteDesignModifier.IsActive(); - var tt = _numDesignsWithAdvancedDyes is 0 - ? "No selected designs contain any advanced dyes." - : $"Delete {_numAdvancedDyes} advanced dyes from {_numDesignsWithAdvancedDyes} of the selected designs."; - if (ImUtf8.ButtonEx("Delete All Advanced Dyes"u8, tt, new Vector2(Im.ContentRegion.Available.X, 0), + if (ImEx.Button("Delete All Advanced Dyes"u8, Im.ContentRegion.Available with { Y = 0 }, _numDesignsWithAdvancedDyes is 0 + ? "No selected designs contain any advanced dyes."u8 + : $"Delete {_numAdvancedDyes} advanced dyes from {_numDesignsWithAdvancedDyes} of the selected designs.", !enabled || _numDesignsWithAdvancedDyes is 0)) foreach (var design in selector.SelectedPaths.OfType()) @@ -378,93 +344,94 @@ public class MultiDesignPanel( } if (!enabled && _numDesignsWithAdvancedDyes is not 0) - ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking to delete."); + Im.Tooltip.OnHover(HoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking to delete."); Im.Separator(); } private void DrawApplicationButtons(float offset) { - ImUtf8.TextFrameAligned("Application"u8); - ImGui.SameLine(offset, Im.Style.ItemSpacing.X); + ImEx.TextFrameAligned("Application"u8); + Im.Line.Same(offset, Im.Style.ItemSpacing.X); var width = new Vector2((Im.ContentRegion.Available.X - Im.Style.ItemSpacing.X) / 2, 0); var enabled = config.DeleteDesignModifier.IsActive(); bool? equip = null; bool? customize = null; - var group = ImUtf8.Group(); - if (ImUtf8.ButtonEx("Disable Everything"u8, - _numDesigns > 0 - ? $"Disable application of everything, including any existing advanced dyes, advanced customizations, crests and wetness for all {_numDesigns} designs." - : "No designs selected.", width, !enabled)) + using (Im.Group()) { - equip = false; - customize = false; - } - - if (!enabled) - ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); - - Im.Line.Same(); - if (ImUtf8.ButtonEx("Enable Everything"u8, - _numDesigns > 0 - ? $"Enable application of everything, including any existing advanced dyes, advanced customizations, crests and wetness for all {_numDesigns} designs." - : "No designs selected.", width, !enabled)) - { - equip = true; - customize = true; - } - - if (!enabled) - ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); - - if (ImUtf8.ButtonEx("Equipment Only"u8, - _numDesigns > 0 - ? $"Enable application of anything related to gear, disable anything that is not related to gear for all {_numDesigns} designs." - : "No designs selected.", width, !enabled)) - { - equip = true; - customize = false; - } - - if (!enabled) - ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); - - Im.Line.Same(); - if (ImUtf8.ButtonEx("Customization Only"u8, - _numDesigns > 0 - ? $"Enable application of anything related to customization, disable anything that is not related to customization for all {_numDesigns} designs." - : "No designs selected.", width, !enabled)) - { - equip = false; - customize = true; - } - - if (!enabled) - ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); - - if (ImUtf8.ButtonEx("Default Application"u8, - _numDesigns > 0 - ? $"Set the application rules to the default values as if the {_numDesigns} were newly created,without any advanced features or wetness." - : "No designs selected.", width, !enabled)) - foreach (var design in selector.SelectedPaths.OfType().Select(l => l.Value)) + if (ImEx.Button("Disable Everything"u8, width, + _numDesigns > 0 + ? $"Disable application of everything, including any existing advanced dyes, advanced customizations, crests and wetness for all {_numDesigns} designs." + : "No designs selected."u8, !enabled)) { - editor.ChangeApplyMulti(design, true, true, true, false, true, true, false, true); - editor.ChangeApplyMeta(design, MetaIndex.Wetness, false); + equip = false; + customize = false; } - if (!enabled) - ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); + if (!enabled) + Im.Tooltip.OnHover(HoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); - Im.Line.Same(); - if (ImUtf8.ButtonEx("Disable Advanced"u8, _numDesigns > 0 - ? $"Disable all advanced dyes and customizations but keep everything else as is for all {_numDesigns} designs." - : "No designs selected.", width, !enabled)) - foreach (var design in selector.SelectedPaths.OfType().Select(l => l.Value)) - editor.ChangeApplyMulti(design, null, null, null, false, null, null, false, null); + Im.Line.Same(); + if (ImEx.Button("Enable Everything"u8, width, + _numDesigns > 0 + ? $"Enable application of everything, including any existing advanced dyes, advanced customizations, crests and wetness for all {_numDesigns} designs." + : "No designs selected."u8, !enabled)) + { + equip = true; + customize = true; + } - if (!enabled) - ImUtf8.HoverTooltip(ImGuiHoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); + if (!enabled) + Im.Tooltip.OnHover(HoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); + + if (ImEx.Button("Equipment Only"u8, width, + _numDesigns > 0 + ? $"Enable application of anything related to gear, disable anything that is not related to gear for all {_numDesigns} designs." + : "No designs selected."u8, !enabled)) + { + equip = true; + customize = false; + } + + if (!enabled) + Im.Tooltip.OnHover(HoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); + + Im.Line.Same(); + if (ImEx.Button("Customization Only"u8, width, + _numDesigns > 0 + ? $"Enable application of anything related to customization, disable anything that is not related to customization for all {_numDesigns} designs." + : "No designs selected."u8, !enabled)) + { + equip = false; + customize = true; + } + + if (!enabled) + Im.Tooltip.OnHover(HoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); + + if (ImEx.Button("Default Application"u8, width, + _numDesigns > 0 + ? $"Set the application rules to the default values as if the {_numDesigns} were newly created,without any advanced features or wetness." + : "No designs selected."u8, !enabled)) + foreach (var design in selector.SelectedPaths.OfType().Select(l => l.Value)) + { + editor.ChangeApplyMulti(design, true, true, true, false, true, true, false, true); + editor.ChangeApplyMeta(design, MetaIndex.Wetness, false); + } + + if (!enabled) + Im.Tooltip.OnHover(HoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); + + Im.Line.Same(); + if (ImEx.Button("Disable Advanced"u8, width, _numDesigns > 0 + ? $"Disable all advanced dyes and customizations but keep everything else as is for all {_numDesigns} designs." + : "No designs selected."u8, !enabled)) + foreach (var design in selector.SelectedPaths.OfType().Select(l => l.Value)) + editor.ChangeApplyMulti(design, null, null, null, false, null, null, false, null); + + if (!enabled) + Im.Tooltip.OnHover(HoveredFlags.AllowWhenDisabled, $"Hold {config.DeleteDesignModifier} while clicking."); + } - group.Dispose(); Im.Separator(); if (equip is null && customize is null) return; @@ -489,7 +456,7 @@ public class MultiDesignPanel( { _addDesigns.Clear(); _removeDesigns.Clear(); - if (_tag.Length == 0) + if (_tag.Length is 0) return; foreach (var leaf in selector.SelectedPaths.OfType()) diff --git a/Luna b/Luna index e80bdf5..0ee15af 160000 --- a/Luna +++ b/Luna @@ -1 +1 @@ -Subproject commit e80bdf5c10c6c30efccdff7d1adcb4a638eba4df +Subproject commit 0ee15af5c45b6c72df25b972e48b9a57347c25a5