mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-12 18:27:24 +01:00
Add Reapply Automation with prior functionality and rework header buttons for performance.
This commit is contained in:
parent
8dde1689f7
commit
05d261d4a3
11 changed files with 612 additions and 364 deletions
|
|
@ -124,7 +124,7 @@ public partial class GlamourerIpc
|
|||
if (_objects.TryGetValue(id, out var data))
|
||||
foreach (var obj in data.Objects)
|
||||
{
|
||||
_autoDesignApplier.ReapplyAutomation(obj, state.Identifier, state);
|
||||
_autoDesignApplier.ReapplyAutomation(obj, state.Identifier, state, true);
|
||||
_stateManager.ReapplyState(obj, StateSource.IpcManual);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -215,7 +215,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
_state.ReapplyState(actor, StateSource.Fixed);
|
||||
}
|
||||
|
||||
public void ReapplyAutomation(Actor actor, ActorIdentifier identifier, ActorState state)
|
||||
public void ReapplyAutomation(Actor actor, ActorIdentifier identifier, ActorState state, bool reset)
|
||||
{
|
||||
if (!_config.EnableAutoDesigns)
|
||||
return;
|
||||
|
|
@ -223,6 +223,7 @@ public sealed class AutoDesignApplier : IDisposable
|
|||
if (!GetPlayerSet(identifier, out var set))
|
||||
return;
|
||||
|
||||
if (reset)
|
||||
_state.ResetState(state, StateSource.Game);
|
||||
Reduce(actor, state, set, false, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ public enum QdbButtons
|
|||
RevertAdvanced = 0x08,
|
||||
RevertEquip = 0x10,
|
||||
RevertCustomize = 0x20,
|
||||
ReapplyAutomation = 0x40,
|
||||
}
|
||||
|
||||
public sealed class DesignQuickBar : Window, IDisposable
|
||||
|
|
@ -118,6 +119,7 @@ public sealed class DesignQuickBar : Window, IDisposable
|
|||
DrawRevertCustomizeButton(buttonSize);
|
||||
DrawRevertAdvancedCustomization(buttonSize);
|
||||
DrawRevertAutomationButton(buttonSize);
|
||||
DrawReapplyAutomationButton(buttonSize);
|
||||
}
|
||||
|
||||
private ActorIdentifier _playerIdentifier;
|
||||
|
|
@ -249,7 +251,47 @@ public sealed class DesignQuickBar : Window, IDisposable
|
|||
|
||||
foreach (var actor in data.Objects)
|
||||
{
|
||||
_autoDesignApplier.ReapplyAutomation(actor, id, state!);
|
||||
_autoDesignApplier.ReapplyAutomation(actor, id, state!, true);
|
||||
_stateManager.ReapplyState(actor, StateSource.Manual);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawReapplyAutomationButton(Vector2 buttonSize)
|
||||
{
|
||||
if (!_config.EnableAutoDesigns)
|
||||
return;
|
||||
|
||||
if (!_config.QdbButtons.HasFlag(QdbButtons.ReapplyAutomation))
|
||||
return;
|
||||
|
||||
var available = 0;
|
||||
var tooltip = string.Empty;
|
||||
|
||||
if (_playerIdentifier.IsValid && _playerState is { IsLocked: false } && _playerData.Valid)
|
||||
{
|
||||
available |= 1;
|
||||
tooltip = "Left-Click: Reapply the player character's current automation on top of their current state.";
|
||||
}
|
||||
|
||||
if (_targetIdentifier.IsValid && _targetState is { IsLocked: false } && _targetData.Valid)
|
||||
{
|
||||
if (available != 0)
|
||||
tooltip += '\n';
|
||||
available |= 2;
|
||||
tooltip += $"Right-Click: Reapply {_targetIdentifier}'s current automation on top of their current state.";
|
||||
}
|
||||
|
||||
if (available == 0)
|
||||
tooltip = "Neither player character nor target are available, have state modified by Glamourer, or their state is locked.";
|
||||
|
||||
var (clicked, id, data, state) = ResolveTarget(FontAwesomeIcon.Repeat, buttonSize, tooltip, available);
|
||||
ImGui.SameLine();
|
||||
if (!clicked)
|
||||
return;
|
||||
|
||||
foreach (var actor in data.Objects)
|
||||
{
|
||||
_autoDesignApplier.ReapplyAutomation(actor, id, state!, false);
|
||||
_stateManager.ReapplyState(actor, StateSource.Manual);
|
||||
}
|
||||
}
|
||||
|
|
@ -385,8 +427,14 @@ public sealed class DesignQuickBar : Window, IDisposable
|
|||
_numButtons = 0;
|
||||
if (_config.QdbButtons.HasFlag(QdbButtons.RevertAll))
|
||||
++_numButtons;
|
||||
if (_config.EnableAutoDesigns && _config.QdbButtons.HasFlag(QdbButtons.RevertAutomation))
|
||||
if (_config.EnableAutoDesigns)
|
||||
{
|
||||
if (_config.QdbButtons.HasFlag(QdbButtons.RevertAutomation))
|
||||
++_numButtons;
|
||||
if (_config.QdbButtons.HasFlag(QdbButtons.ReapplyAutomation))
|
||||
++_numButtons;
|
||||
}
|
||||
|
||||
if ((_config.UseAdvancedParameters || _config.UseAdvancedDyes) && _config.QdbButtons.HasFlag(QdbButtons.RevertAdvanced))
|
||||
++_numButtons;
|
||||
if (_config.QdbButtons.HasFlag(QdbButtons.RevertCustomize))
|
||||
|
|
|
|||
|
|
@ -55,12 +55,12 @@ public class MainWindow : Window, IDisposable
|
|||
public readonly NpcTab Npcs;
|
||||
public readonly MessagesTab Messages;
|
||||
|
||||
public TabType SelectTab = TabType.None;
|
||||
public TabType SelectTab;
|
||||
|
||||
public MainWindow(DalamudPluginInterface pi, Configuration config, SettingsTab settings, ActorTab actors, DesignTab designs,
|
||||
DebugTab debugTab, AutomationTab automation, UnlocksTab unlocks, TabSelected @event, MessagesTab messages, DesignQuickBar quickBar,
|
||||
NpcTab npcs, MainWindowPosition position)
|
||||
: base(GetLabel())
|
||||
: base("GlamourerMainWindow")
|
||||
{
|
||||
pi.UiBuilder.DisableGposeUiHide = true;
|
||||
SizeConstraints = new WindowSizeConstraints()
|
||||
|
|
@ -102,6 +102,7 @@ public class MainWindow : Window, IDisposable
|
|||
? Flags | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize
|
||||
: Flags & ~(ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoResize);
|
||||
_position.IsOpen = IsOpen;
|
||||
WindowName = GetLabel();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
|
@ -177,8 +178,12 @@ public class MainWindow : Window, IDisposable
|
|||
IsOpen = true;
|
||||
}
|
||||
|
||||
private static string GetLabel()
|
||||
=> Glamourer.Version.Length == 0
|
||||
? "Glamourer###GlamourerMainWindow"
|
||||
: $"Glamourer v{Glamourer.Version}###GlamourerMainWindow";
|
||||
private string GetLabel()
|
||||
=> (Glamourer.Version.Length == 0, _config.Ephemeral.IncognitoMode) switch
|
||||
{
|
||||
(true, true) => "Glamourer (Incognito Mode)###GlamourerMainWindow",
|
||||
(true, false) => "Glamourer###GlamourerMainWindow",
|
||||
(false, false) => $"Glamourer v{Glamourer.Version}###GlamourerMainWindow",
|
||||
(false, true) => $"Glamourer v{Glamourer.Version} (Incognito Mode)###GlamourerMainWindow",
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,22 +21,68 @@ using Penumbra.GameData.Enums;
|
|||
|
||||
namespace Glamourer.Gui.Tabs.ActorTab;
|
||||
|
||||
public class ActorPanel(
|
||||
ActorSelector _selector,
|
||||
StateManager _stateManager,
|
||||
CustomizationDrawer _customizationDrawer,
|
||||
EquipmentDrawer _equipmentDrawer,
|
||||
AutoDesignApplier _autoDesignApplier,
|
||||
Configuration _config,
|
||||
DesignConverter _converter,
|
||||
ObjectManager _objects,
|
||||
DesignManager _designManager,
|
||||
ImportService _importService,
|
||||
ICondition _conditions,
|
||||
DictModelChara _modelChara,
|
||||
CustomizeParameterDrawer _parameterDrawer,
|
||||
AdvancedDyePopup _advancedDyes)
|
||||
public class ActorPanel
|
||||
{
|
||||
private readonly ActorSelector _selector;
|
||||
private readonly StateManager _stateManager;
|
||||
private readonly CustomizationDrawer _customizationDrawer;
|
||||
private readonly EquipmentDrawer _equipmentDrawer;
|
||||
private readonly AutoDesignApplier _autoDesignApplier;
|
||||
private readonly Configuration _config;
|
||||
private readonly DesignConverter _converter;
|
||||
private readonly ObjectManager _objects;
|
||||
private readonly DesignManager _designManager;
|
||||
private readonly ImportService _importService;
|
||||
private readonly ICondition _conditions;
|
||||
private readonly DictModelChara _modelChara;
|
||||
private readonly CustomizeParameterDrawer _parameterDrawer;
|
||||
private readonly AdvancedDyePopup _advancedDyes;
|
||||
private readonly HeaderDrawer.Button[] _leftButtons;
|
||||
private readonly HeaderDrawer.Button[] _rightButtons;
|
||||
|
||||
public ActorPanel(ActorSelector selector,
|
||||
StateManager stateManager,
|
||||
CustomizationDrawer customizationDrawer,
|
||||
EquipmentDrawer equipmentDrawer,
|
||||
AutoDesignApplier autoDesignApplier,
|
||||
Configuration config,
|
||||
DesignConverter converter,
|
||||
ObjectManager objects,
|
||||
DesignManager designManager,
|
||||
ImportService importService,
|
||||
ICondition conditions,
|
||||
DictModelChara modelChara,
|
||||
CustomizeParameterDrawer parameterDrawer,
|
||||
AdvancedDyePopup advancedDyes)
|
||||
{
|
||||
_selector = selector;
|
||||
_stateManager = stateManager;
|
||||
_customizationDrawer = customizationDrawer;
|
||||
_equipmentDrawer = equipmentDrawer;
|
||||
_autoDesignApplier = autoDesignApplier;
|
||||
_config = config;
|
||||
_converter = converter;
|
||||
_objects = objects;
|
||||
_designManager = designManager;
|
||||
_importService = importService;
|
||||
_conditions = conditions;
|
||||
_modelChara = modelChara;
|
||||
_parameterDrawer = parameterDrawer;
|
||||
_advancedDyes = advancedDyes;
|
||||
_leftButtons =
|
||||
[
|
||||
new SetFromClipboardButton(this),
|
||||
new ExportToClipboardButton(this),
|
||||
new SaveAsDesignButton(this),
|
||||
];
|
||||
_rightButtons =
|
||||
[
|
||||
new LockedButton(this),
|
||||
new HeaderDrawer.IncognitoButton(_config.Ephemeral),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
private ActorIdentifier _identifier;
|
||||
private string _actorName = string.Empty;
|
||||
private Actor _actor = Actor.Null;
|
||||
|
|
@ -81,9 +127,7 @@ public class ActorPanel(
|
|||
{
|
||||
var textColor = !_identifier.IsValid ? ImGui.GetColorU32(ImGuiCol.Text) :
|
||||
_data.Valid ? ColorId.ActorAvailable.Value() : ColorId.ActorUnavailable.Value();
|
||||
HeaderDrawer.Draw(_actorName, textColor, ImGui.GetColorU32(ImGuiCol.FrameBg),
|
||||
3, SetFromClipboardButton(), ExportToClipboardButton(), SaveAsDesignButton(), LockedButton(),
|
||||
HeaderDrawer.Button.IncognitoButton(_selector.IncognitoMode, v => _selector.IncognitoMode = v));
|
||||
HeaderDrawer.Draw(_actorName, textColor, ImGui.GetColorU32(ImGuiCol.FrameBg), _leftButtons, _rightButtons);
|
||||
|
||||
SaveDesignDrawPopup();
|
||||
}
|
||||
|
|
@ -269,59 +313,9 @@ public class ActorPanel(
|
|||
_stateManager.TurnHuman(_state, StateSource.Manual);
|
||||
}
|
||||
|
||||
private HeaderDrawer.Button SetFromClipboardButton()
|
||||
=> new()
|
||||
{
|
||||
Description =
|
||||
"Try to apply a design from your clipboard.\nHold Control to only apply gear.\nHold Shift to only apply customizations.",
|
||||
Icon = FontAwesomeIcon.Clipboard,
|
||||
OnClick = SetFromClipboard,
|
||||
Visible = _state != null,
|
||||
Disabled = _state?.IsLocked ?? true,
|
||||
};
|
||||
|
||||
private HeaderDrawer.Button ExportToClipboardButton()
|
||||
=> new()
|
||||
{
|
||||
Description =
|
||||
"Copy the current design to your clipboard.\nHold Control to disable applying of customizations for the copied design.\nHold Shift to disable applying of gear for the copied design.",
|
||||
Icon = FontAwesomeIcon.Copy,
|
||||
OnClick = ExportToClipboard,
|
||||
Visible = _state?.ModelData.ModelId == 0,
|
||||
};
|
||||
|
||||
private HeaderDrawer.Button SaveAsDesignButton()
|
||||
=> new()
|
||||
{
|
||||
Description =
|
||||
"Save the current state as a design.\nHold Control to disable applying of customizations for the saved design.\nHold Shift to disable applying of gear for the saved design.",
|
||||
Icon = FontAwesomeIcon.Save,
|
||||
OnClick = SaveDesignOpen,
|
||||
Visible = _state?.ModelData.ModelId == 0,
|
||||
};
|
||||
|
||||
private HeaderDrawer.Button LockedButton()
|
||||
=> new()
|
||||
{
|
||||
Description = "The current state of this actor is locked by external tools.",
|
||||
Icon = FontAwesomeIcon.Lock,
|
||||
OnClick = () => { },
|
||||
Disabled = true,
|
||||
Visible = _state?.IsLocked ?? false,
|
||||
TextColor = ColorId.ActorUnavailable.Value(),
|
||||
BorderColor = ColorId.ActorUnavailable.Value(),
|
||||
};
|
||||
|
||||
private string _newName = string.Empty;
|
||||
private DesignBase? _newDesign;
|
||||
|
||||
private void SaveDesignOpen()
|
||||
{
|
||||
ImGui.OpenPopup("Save as Design");
|
||||
_newName = _state!.Identifier.ToName();
|
||||
_newDesign = _converter.Convert(_state, ApplicationRules.FromModifiers(_state));
|
||||
}
|
||||
|
||||
private void SaveDesignDrawPopup()
|
||||
{
|
||||
if (!ImGuiUtil.OpenNameField("Save as Design", ref _newName))
|
||||
|
|
@ -333,37 +327,6 @@ public class ActorPanel(
|
|||
_newName = string.Empty;
|
||||
}
|
||||
|
||||
private void SetFromClipboard()
|
||||
{
|
||||
try
|
||||
{
|
||||
var (applyGear, applyCustomize) = UiHelpers.ConvertKeysToBool();
|
||||
var text = ImGui.GetClipboardText();
|
||||
var design = _converter.FromBase64(text, applyCustomize, applyGear, out _)
|
||||
?? throw new Exception("The clipboard did not contain valid data.");
|
||||
_stateManager.ApplyDesign(_state!, design, ApplySettings.ManualWithLinks);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Glamourer.Messager.NotificationMessage(ex, $"Could not apply clipboard to {_identifier}.",
|
||||
$"Could not apply clipboard to design {_identifier.Incognito(null)}", NotificationType.Error, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExportToClipboard()
|
||||
{
|
||||
try
|
||||
{
|
||||
var text = _converter.ShareBase64(_state!, ApplicationRules.FromModifiers(_state!));
|
||||
ImGui.SetClipboardText(text);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Glamourer.Messager.NotificationMessage(ex, $"Could not copy {_identifier} data to clipboard.",
|
||||
$"Could not copy data from design {_identifier.Incognito(null)} to clipboard", NotificationType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void RevertButtons()
|
||||
{
|
||||
if (ImGuiUtil.DrawDisabledButton("Revert to Game", Vector2.Zero, "Revert the character to its actual state in the game.",
|
||||
|
|
@ -371,18 +334,29 @@ public class ActorPanel(
|
|||
_stateManager.ResetState(_state!, StateSource.Manual);
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGuiUtil.DrawDisabledButton("Reapply State", Vector2.Zero, "Try to reapply the configured state if something went wrong.",
|
||||
_state!.IsLocked))
|
||||
|
||||
if (ImGuiUtil.DrawDisabledButton("Reapply Automation", Vector2.Zero,
|
||||
"Reapply the current automation state for the character on top of its current state..",
|
||||
!_config.EnableAutoDesigns || _state!.IsLocked))
|
||||
{
|
||||
_autoDesignApplier.ReapplyAutomation(_actor, _identifier, _state!, false);
|
||||
_stateManager.ReapplyState(_actor, StateSource.Manual);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGuiUtil.DrawDisabledButton("Reapply Automation", Vector2.Zero,
|
||||
if (ImGuiUtil.DrawDisabledButton("Revert to Automation", Vector2.Zero,
|
||||
"Try to revert the character to the state it would have using automated designs.",
|
||||
!_config.EnableAutoDesigns || _state!.IsLocked))
|
||||
{
|
||||
_autoDesignApplier.ReapplyAutomation(_actor, _identifier, _state!);
|
||||
_autoDesignApplier.ReapplyAutomation(_actor, _identifier, _state!, true);
|
||||
_stateManager.ReapplyState(_actor, StateSource.Manual);
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
if (ImGuiUtil.DrawDisabledButton("Reapply", Vector2.Zero,
|
||||
"Try to reapply the configured state if something went wrong. Should generally not be necessary.",
|
||||
_state!.IsLocked))
|
||||
_stateManager.ReapplyState(_actor, StateSource.Manual);
|
||||
}
|
||||
|
||||
private void DrawApplyToSelf()
|
||||
|
|
@ -414,4 +388,107 @@ public class ActorPanel(
|
|||
_stateManager.ApplyDesign(state, _converter.Convert(_state!, ApplicationRules.FromModifiers(_state!)),
|
||||
ApplySettings.Manual);
|
||||
}
|
||||
|
||||
|
||||
private sealed class SetFromClipboardButton(ActorPanel panel)
|
||||
: HeaderDrawer.Button
|
||||
{
|
||||
protected override string Description
|
||||
=> "Try to apply a design from your clipboard.\nHold Control to only apply gear.\nHold Shift to only apply customizations.";
|
||||
|
||||
protected override FontAwesomeIcon Icon
|
||||
=> FontAwesomeIcon.Clipboard;
|
||||
|
||||
public override bool Visible
|
||||
=> panel._state != null;
|
||||
|
||||
protected override bool Disabled
|
||||
=> panel._state?.IsLocked ?? true;
|
||||
|
||||
protected override void OnClick()
|
||||
{
|
||||
try
|
||||
{
|
||||
var (applyGear, applyCustomize) = UiHelpers.ConvertKeysToBool();
|
||||
var text = ImGui.GetClipboardText();
|
||||
var design = panel._converter.FromBase64(text, applyCustomize, applyGear, out _)
|
||||
?? throw new Exception("The clipboard did not contain valid data.");
|
||||
panel._stateManager.ApplyDesign(panel._state!, design, ApplySettings.ManualWithLinks);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Glamourer.Messager.NotificationMessage(ex, $"Could not apply clipboard to {panel._identifier}.",
|
||||
$"Could not apply clipboard to design {panel._identifier.Incognito(null)}", NotificationType.Error, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ExportToClipboardButton(ActorPanel panel) : HeaderDrawer.Button
|
||||
{
|
||||
protected override string Description
|
||||
=> "Copy the current design to your clipboard.\nHold Control to disable applying of customizations for the copied design.\nHold Shift to disable applying of gear for the copied design.";
|
||||
|
||||
protected override FontAwesomeIcon Icon
|
||||
=> FontAwesomeIcon.Copy;
|
||||
|
||||
public override bool Visible
|
||||
=> panel._state?.ModelData.ModelId == 0;
|
||||
|
||||
protected override void OnClick()
|
||||
{
|
||||
try
|
||||
{
|
||||
var text = panel._converter.ShareBase64(panel._state!, ApplicationRules.FromModifiers(panel._state!));
|
||||
ImGui.SetClipboardText(text);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Glamourer.Messager.NotificationMessage(ex, $"Could not copy {panel._identifier} data to clipboard.",
|
||||
$"Could not copy data from design {panel._identifier.Incognito(null)} to clipboard", NotificationType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class SaveAsDesignButton(ActorPanel panel) : HeaderDrawer.Button
|
||||
{
|
||||
protected override string Description
|
||||
=> "Save the current state as a design.\nHold Control to disable applying of customizations for the saved design.\nHold Shift to disable applying of gear for the saved design.";
|
||||
|
||||
protected override FontAwesomeIcon Icon
|
||||
=> FontAwesomeIcon.Save;
|
||||
|
||||
public override bool Visible
|
||||
=> panel._state?.ModelData.ModelId == 0;
|
||||
|
||||
protected override void OnClick()
|
||||
{
|
||||
ImGui.OpenPopup("Save as Design");
|
||||
panel._newName = panel._state!.Identifier.ToName();
|
||||
panel._newDesign = panel._converter.Convert(panel._state, ApplicationRules.FromModifiers(panel._state));
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class LockedButton(ActorPanel panel) : HeaderDrawer.Button
|
||||
{
|
||||
protected override string Description
|
||||
=> "The current state of this actor is locked by external tools.";
|
||||
|
||||
protected override FontAwesomeIcon Icon
|
||||
=> FontAwesomeIcon.Lock;
|
||||
|
||||
public override bool Visible
|
||||
=> panel._state?.IsLocked ?? false;
|
||||
|
||||
protected override bool Disabled
|
||||
=> true;
|
||||
|
||||
protected override uint BorderColor
|
||||
=> ColorId.ActorUnavailable.Value();
|
||||
|
||||
protected override uint TextColor
|
||||
=> ColorId.ActorUnavailable.Value();
|
||||
|
||||
protected override void OnClick()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ public class SetPanel(
|
|||
RandomRestrictionDrawer _randomDrawer)
|
||||
{
|
||||
private readonly JobGroupCombo _jobGroupCombo = new(_manager, _jobs, Glamourer.Log);
|
||||
|
||||
private readonly HeaderDrawer.Button[] _rightButtons = [new HeaderDrawer.IncognitoButton(_config.Ephemeral)];
|
||||
private string? _tempName;
|
||||
private int _dragIndex = -1;
|
||||
|
||||
|
|
@ -47,8 +47,7 @@ public class SetPanel(
|
|||
}
|
||||
|
||||
private void DrawHeader()
|
||||
=> HeaderDrawer.Draw(_selector.SelectionName, 0, ImGui.GetColorU32(ImGuiCol.FrameBg), 0,
|
||||
HeaderDrawer.Button.IncognitoButton(_selector.IncognitoMode, v => _selector.IncognitoMode = v));
|
||||
=> HeaderDrawer.Draw(_selector.SelectionName, 0, ImGui.GetColorU32(ImGuiCol.FrameBg), [], _rightButtons);
|
||||
|
||||
private void DrawPanel()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,79 +15,79 @@ using OtterGui;
|
|||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.GameData.Enums;
|
||||
using System;
|
||||
using static Glamourer.Gui.Tabs.HeaderDrawer;
|
||||
|
||||
namespace Glamourer.Gui.Tabs.DesignTab;
|
||||
|
||||
public class DesignPanel(
|
||||
DesignFileSystemSelector _selector,
|
||||
CustomizationDrawer _customizationDrawer,
|
||||
DesignManager _manager,
|
||||
ObjectManager _objects,
|
||||
StateManager _state,
|
||||
EquipmentDrawer _equipmentDrawer,
|
||||
ModAssociationsTab _modAssociations,
|
||||
Configuration _config,
|
||||
DesignDetailTab _designDetails,
|
||||
DesignConverter _converter,
|
||||
ImportService _importService,
|
||||
MultiDesignPanel _multiDesignPanel,
|
||||
CustomizeParameterDrawer _parameterDrawer,
|
||||
DesignLinkDrawer _designLinkDrawer,
|
||||
MaterialDrawer _materials)
|
||||
public class DesignPanel
|
||||
{
|
||||
private readonly FileDialogManager _fileDialog = new();
|
||||
private readonly DesignFileSystemSelector _selector;
|
||||
private readonly CustomizationDrawer _customizationDrawer;
|
||||
private readonly DesignManager _manager;
|
||||
private readonly ObjectManager _objects;
|
||||
private readonly StateManager _state;
|
||||
private readonly EquipmentDrawer _equipmentDrawer;
|
||||
private readonly ModAssociationsTab _modAssociations;
|
||||
private readonly Configuration _config;
|
||||
private readonly DesignDetailTab _designDetails;
|
||||
private readonly ImportService _importService;
|
||||
private readonly DesignConverter _converter;
|
||||
private readonly MultiDesignPanel _multiDesignPanel;
|
||||
private readonly CustomizeParameterDrawer _parameterDrawer;
|
||||
private readonly DesignLinkDrawer _designLinkDrawer;
|
||||
private readonly MaterialDrawer _materials;
|
||||
private readonly Button[] _leftButtons;
|
||||
private readonly Button[] _rightButtons;
|
||||
|
||||
private HeaderDrawer.Button LockButton()
|
||||
=> _selector.Selected == null
|
||||
? HeaderDrawer.Button.Invisible
|
||||
: _selector.Selected.WriteProtected()
|
||||
? new HeaderDrawer.Button
|
||||
|
||||
public DesignPanel(DesignFileSystemSelector selector,
|
||||
CustomizationDrawer customizationDrawer,
|
||||
DesignManager manager,
|
||||
ObjectManager objects,
|
||||
StateManager state,
|
||||
EquipmentDrawer equipmentDrawer,
|
||||
ModAssociationsTab modAssociations,
|
||||
Configuration config,
|
||||
DesignDetailTab designDetails,
|
||||
DesignConverter converter,
|
||||
ImportService importService,
|
||||
MultiDesignPanel multiDesignPanel,
|
||||
CustomizeParameterDrawer parameterDrawer,
|
||||
DesignLinkDrawer designLinkDrawer,
|
||||
MaterialDrawer materials)
|
||||
{
|
||||
Description = "Make this design editable.",
|
||||
Icon = FontAwesomeIcon.Lock,
|
||||
OnClick = () => _manager.SetWriteProtection(_selector.Selected!, false),
|
||||
_selector = selector;
|
||||
_customizationDrawer = customizationDrawer;
|
||||
_manager = manager;
|
||||
_objects = objects;
|
||||
_state = state;
|
||||
_equipmentDrawer = equipmentDrawer;
|
||||
_modAssociations = modAssociations;
|
||||
_config = config;
|
||||
_designDetails = designDetails;
|
||||
_importService = importService;
|
||||
_converter = converter;
|
||||
_multiDesignPanel = multiDesignPanel;
|
||||
_parameterDrawer = parameterDrawer;
|
||||
_designLinkDrawer = designLinkDrawer;
|
||||
_materials = materials;
|
||||
_leftButtons =
|
||||
[
|
||||
new SetFromClipboardButton(this),
|
||||
new UndoButton(this),
|
||||
new ExportToClipboardButton(this),
|
||||
];
|
||||
_rightButtons =
|
||||
[
|
||||
new LockButton(this),
|
||||
new IncognitoButton(_config.Ephemeral),
|
||||
];
|
||||
}
|
||||
: new HeaderDrawer.Button
|
||||
{
|
||||
Description = "Write-protect this design.",
|
||||
Icon = FontAwesomeIcon.LockOpen,
|
||||
OnClick = () => _manager.SetWriteProtection(_selector.Selected!, true),
|
||||
};
|
||||
|
||||
private HeaderDrawer.Button SetFromClipboardButton()
|
||||
=> new()
|
||||
{
|
||||
Description =
|
||||
"Try to apply a design from your clipboard over this design.\nHold Control to only apply gear.\nHold Shift to only apply customizations.",
|
||||
Icon = FontAwesomeIcon.Clipboard,
|
||||
OnClick = SetFromClipboard,
|
||||
Visible = _selector.Selected != null,
|
||||
Disabled = _selector.Selected?.WriteProtected() ?? true,
|
||||
};
|
||||
|
||||
private HeaderDrawer.Button UndoButton()
|
||||
=> new()
|
||||
{
|
||||
Description = "Undo the last change if you accidentally overwrote your design with a different one.",
|
||||
Icon = FontAwesomeIcon.Undo,
|
||||
OnClick = UndoOverwrite,
|
||||
Visible = _selector.Selected != null,
|
||||
Disabled = !_manager.CanUndo(_selector.Selected),
|
||||
};
|
||||
|
||||
private HeaderDrawer.Button ExportToClipboardButton()
|
||||
=> new()
|
||||
{
|
||||
Description = "Copy the current design to your clipboard.",
|
||||
Icon = FontAwesomeIcon.Copy,
|
||||
OnClick = ExportToClipboard,
|
||||
Visible = _selector.Selected != null,
|
||||
};
|
||||
|
||||
private void DrawHeader()
|
||||
=> HeaderDrawer.Draw(SelectionName, 0, ImGui.GetColorU32(ImGuiCol.FrameBg),
|
||||
3, SetFromClipboardButton(), UndoButton(), ExportToClipboardButton(), LockButton(),
|
||||
HeaderDrawer.Button.IncognitoButton(_selector.IncognitoMode, v => _selector.IncognitoMode = v));
|
||||
=> HeaderDrawer.Draw(SelectionName, 0, ImGui.GetColorU32(ImGuiCol.FrameBg), _leftButtons, _rightButtons);
|
||||
|
||||
private string SelectionName
|
||||
=> _selector.Selected == null ? "No Selection" : _selector.IncognitoMode ? _selector.Selected.Incognito : _selector.Selected.Name.Text;
|
||||
|
|
@ -397,49 +397,6 @@ public class DesignPanel(
|
|||
DrawSaveToDat();
|
||||
}
|
||||
|
||||
private void SetFromClipboard()
|
||||
{
|
||||
try
|
||||
{
|
||||
var text = ImGui.GetClipboardText();
|
||||
var (applyEquip, applyCustomize) = UiHelpers.ConvertKeysToBool();
|
||||
var design = _converter.FromBase64(text, applyCustomize, applyEquip, out _)
|
||||
?? throw new Exception("The clipboard did not contain valid data.");
|
||||
_manager.ApplyDesign(_selector.Selected!, design);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Glamourer.Messager.NotificationMessage(ex, $"Could not apply clipboard to {_selector.Selected!.Name}.",
|
||||
$"Could not apply clipboard to design {_selector.Selected!.Identifier}", NotificationType.Error, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void UndoOverwrite()
|
||||
{
|
||||
try
|
||||
{
|
||||
_manager.UndoDesignChange(_selector.Selected!);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Glamourer.Messager.NotificationMessage(ex, $"Could not undo last changes to {_selector.Selected!.Name}.", NotificationType.Error,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExportToClipboard()
|
||||
{
|
||||
try
|
||||
{
|
||||
var text = _converter.ShareBase64(_selector.Selected!);
|
||||
ImGui.SetClipboardText(text);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Glamourer.Messager.NotificationMessage(ex, $"Could not copy {_selector.Selected!.Name} data to clipboard.",
|
||||
$"Could not copy data from design {_selector.Selected!.Identifier} to clipboard", NotificationType.Error, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawApplyToSelf()
|
||||
{
|
||||
|
|
@ -497,4 +454,111 @@ public class DesignPanel(
|
|||
|
||||
private static unsafe string GetUserPath()
|
||||
=> Framework.Instance()->UserPath;
|
||||
|
||||
|
||||
private sealed class LockButton(DesignPanel panel) : Button
|
||||
{
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class UndoButton(DesignPanel panel) : Button
|
||||
{
|
||||
public override bool Visible
|
||||
=> panel._selector.Selected != null;
|
||||
|
||||
protected override bool Disabled
|
||||
=> !panel._manager.CanUndo(panel._selector.Selected);
|
||||
|
||||
protected override string Description
|
||||
=> "Undo the last change if you accidentally overwrote your design with a different one.";
|
||||
|
||||
protected override FontAwesomeIcon Icon
|
||||
=> FontAwesomeIcon.Undo;
|
||||
|
||||
protected override void OnClick()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,76 +8,77 @@ namespace Glamourer.Gui.Tabs;
|
|||
|
||||
public static class HeaderDrawer
|
||||
{
|
||||
public struct Button
|
||||
public abstract class Button
|
||||
{
|
||||
public static readonly Button Invisible = new()
|
||||
{
|
||||
Visible = false,
|
||||
Width = 0,
|
||||
};
|
||||
protected abstract void OnClick();
|
||||
|
||||
public Action? OnClick;
|
||||
public string Description = string.Empty;
|
||||
public float Width;
|
||||
public uint BorderColor;
|
||||
public uint TextColor;
|
||||
public FontAwesomeIcon Icon;
|
||||
public bool Disabled;
|
||||
public bool Visible;
|
||||
protected virtual string Description
|
||||
=> string.Empty;
|
||||
|
||||
public Button()
|
||||
{
|
||||
Visible = true;
|
||||
Width = ImGui.GetFrameHeightWithSpacing();
|
||||
BorderColor = ColorId.HeaderButtons.Value();
|
||||
TextColor = ColorId.HeaderButtons.Value();
|
||||
Disabled = false;
|
||||
}
|
||||
protected virtual uint BorderColor
|
||||
=> ColorId.HeaderButtons.Value();
|
||||
|
||||
public readonly void Draw()
|
||||
protected virtual uint TextColor
|
||||
=> ColorId.HeaderButtons.Value();
|
||||
|
||||
protected virtual FontAwesomeIcon Icon
|
||||
=> FontAwesomeIcon.None;
|
||||
|
||||
protected virtual bool Disabled
|
||||
=> false;
|
||||
|
||||
public virtual bool Visible
|
||||
=> true;
|
||||
|
||||
public void Draw(float width)
|
||||
{
|
||||
if (!Visible)
|
||||
return;
|
||||
|
||||
using var color = ImRaii.PushColor(ImGuiCol.Border, BorderColor)
|
||||
.Push(ImGuiCol.Text, TextColor, TextColor != 0);
|
||||
if (ImGuiUtil.DrawDisabledButton(Icon.ToIconString(), new Vector2(Width, ImGui.GetFrameHeight()), string.Empty, Disabled, true))
|
||||
OnClick?.Invoke();
|
||||
if (ImGuiUtil.DrawDisabledButton(Icon.ToIconString(), new Vector2(width, ImGui.GetFrameHeight()), string.Empty, Disabled, true))
|
||||
OnClick();
|
||||
color.Pop();
|
||||
ImGuiUtil.HoverTooltip(Description);
|
||||
}
|
||||
|
||||
public static Button IncognitoButton(bool current, Action<bool> setter)
|
||||
=> current
|
||||
? new Button
|
||||
{
|
||||
Description = "Toggle incognito mode off.",
|
||||
Icon = FontAwesomeIcon.EyeSlash,
|
||||
OnClick = () => setter(false),
|
||||
}
|
||||
: new Button
|
||||
{
|
||||
Description = "Toggle incognito mode on.",
|
||||
Icon = FontAwesomeIcon.Eye,
|
||||
OnClick = () => setter(true),
|
||||
};
|
||||
}
|
||||
|
||||
public static void Draw(string text, uint textColor, uint frameColor, int leftButtons, params Button[] buttons)
|
||||
public sealed class IncognitoButton(EphemeralConfig config) : Button
|
||||
{
|
||||
protected override string Description
|
||||
=> config.IncognitoMode
|
||||
? "Toggle incognito mode off."
|
||||
: "Toggle incognito mode on.";
|
||||
|
||||
protected override FontAwesomeIcon Icon
|
||||
=> config.IncognitoMode
|
||||
? FontAwesomeIcon.EyeSlash
|
||||
: FontAwesomeIcon.Eye;
|
||||
|
||||
protected override void OnClick()
|
||||
{
|
||||
config.IncognitoMode = !config.IncognitoMode;
|
||||
config.Save();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Draw(string text, uint textColor, uint frameColor, Button[] leftButtons, Button[] rightButtons)
|
||||
{
|
||||
var width = ImGui.GetFrameHeightWithSpacing();
|
||||
using var style = ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, Vector2.Zero)
|
||||
.Push(ImGuiStyleVar.FrameRounding, 0)
|
||||
.Push(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale);
|
||||
|
||||
var leftButtonSize = 0f;
|
||||
foreach (var button in buttons.Take(leftButtons).Where(b => b.Visible))
|
||||
foreach (var button in leftButtons.Where(b => b.Visible))
|
||||
{
|
||||
button.Draw();
|
||||
button.Draw(width);
|
||||
ImGui.SameLine();
|
||||
leftButtonSize += button.Width;
|
||||
leftButtonSize += width;
|
||||
}
|
||||
|
||||
var rightButtonSize = buttons.Length > leftButtons ? buttons.Skip(leftButtons).Where(b => b.Visible).Select(b => b.Width).Sum() : 0f;
|
||||
var rightButtonSize = rightButtons.Count(b => b.Visible) * width;
|
||||
var midSize = ImGui.GetContentRegionAvail().X - rightButtonSize - ImGuiHelpers.GlobalScale;
|
||||
|
||||
style.Pop();
|
||||
|
|
@ -89,10 +90,10 @@ public static class HeaderDrawer
|
|||
style.Pop();
|
||||
style.Push(ImGuiStyleVar.FrameBorderSize, ImGuiHelpers.GlobalScale);
|
||||
|
||||
foreach (var button in buttons.Skip(leftButtons).Where(b => b.Visible))
|
||||
foreach (var button in rightButtons.Where(b => b.Visible))
|
||||
{
|
||||
ImGui.SameLine();
|
||||
button.Draw();
|
||||
button.Draw(width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,23 +12,57 @@ using OtterGui;
|
|||
using OtterGui.Classes;
|
||||
using OtterGui.Raii;
|
||||
using Penumbra.GameData.Enums;
|
||||
using static Glamourer.Gui.Tabs.HeaderDrawer;
|
||||
|
||||
namespace Glamourer.Gui.Tabs.NpcTab;
|
||||
|
||||
public class NpcPanel(
|
||||
NpcSelector _selector,
|
||||
LocalNpcAppearanceData _favorites,
|
||||
CustomizationDrawer _customizeDrawer,
|
||||
EquipmentDrawer _equipDrawer,
|
||||
DesignConverter _converter,
|
||||
DesignManager _designManager,
|
||||
StateManager _state,
|
||||
ObjectManager _objects,
|
||||
DesignColors _colors)
|
||||
public class NpcPanel
|
||||
{
|
||||
private readonly DesignColorCombo _colorCombo = new(_colors, true);
|
||||
private readonly DesignColorCombo _colorCombo;
|
||||
private string _newName = string.Empty;
|
||||
private DesignBase? _newDesign;
|
||||
private readonly NpcSelector _selector;
|
||||
private readonly LocalNpcAppearanceData _favorites;
|
||||
private readonly CustomizationDrawer _customizeDrawer;
|
||||
private readonly EquipmentDrawer _equipDrawer;
|
||||
private readonly DesignConverter _converter;
|
||||
private readonly DesignManager _designManager;
|
||||
private readonly StateManager _state;
|
||||
private readonly ObjectManager _objects;
|
||||
private readonly DesignColors _colors;
|
||||
private readonly Button[] _leftButtons;
|
||||
private readonly Button[] _rightButtons;
|
||||
|
||||
public NpcPanel(NpcSelector selector,
|
||||
LocalNpcAppearanceData favorites,
|
||||
CustomizationDrawer customizeDrawer,
|
||||
EquipmentDrawer equipDrawer,
|
||||
DesignConverter converter,
|
||||
DesignManager designManager,
|
||||
StateManager state,
|
||||
ObjectManager objects,
|
||||
DesignColors colors)
|
||||
{
|
||||
_selector = selector;
|
||||
_favorites = favorites;
|
||||
_customizeDrawer = customizeDrawer;
|
||||
_equipDrawer = equipDrawer;
|
||||
_converter = converter;
|
||||
_designManager = designManager;
|
||||
_state = state;
|
||||
_objects = objects;
|
||||
_colors = colors;
|
||||
_colorCombo = new DesignColorCombo(colors, true);
|
||||
_leftButtons =
|
||||
[
|
||||
new ExportToClipboardButton(this),
|
||||
new SaveAsDesignButton(this),
|
||||
];
|
||||
_rightButtons =
|
||||
[
|
||||
new FavoriteButton(this),
|
||||
];
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
|
|
@ -41,67 +75,30 @@ public class NpcPanel(
|
|||
private void DrawHeader()
|
||||
{
|
||||
HeaderDrawer.Draw(_selector.HasSelection ? _selector.Selection.Name : "No Selection", ColorId.NormalDesign.Value(),
|
||||
ImGui.GetColorU32(ImGuiCol.FrameBg), 2, ExportToClipboardButton(), SaveAsDesignButton(), FavoriteButton());
|
||||
ImGui.GetColorU32(ImGuiCol.FrameBg), _leftButtons, _rightButtons);
|
||||
SaveDesignDrawPopup();
|
||||
}
|
||||
|
||||
private HeaderDrawer.Button FavoriteButton()
|
||||
private sealed class FavoriteButton(NpcPanel panel) : Button
|
||||
{
|
||||
var (desc, color) = _favorites.IsFavorite(_selector.Selection)
|
||||
? ("Remove this NPC appearance from your favorites.", ColorId.FavoriteStarOn.Value())
|
||||
: ("Add this NPC Appearance to your favorites.", 0x80000000);
|
||||
return new HeaderDrawer.Button
|
||||
{
|
||||
Icon = FontAwesomeIcon.Star,
|
||||
OnClick = () => _favorites.ToggleFavorite(_selector.Selection),
|
||||
Visible = _selector.HasSelection,
|
||||
Description = desc,
|
||||
TextColor = color,
|
||||
};
|
||||
}
|
||||
protected override string Description
|
||||
=> panel._favorites.IsFavorite(panel._selector.Selection)
|
||||
? "Remove this NPC appearance from your favorites."
|
||||
: "Add this NPC Appearance to your favorites.";
|
||||
|
||||
private HeaderDrawer.Button ExportToClipboardButton()
|
||||
=> new()
|
||||
{
|
||||
Description =
|
||||
"Copy the current NPCs appearance to your clipboard.\nHold Control to disable applying of customizations for the copied design.\nHold Shift to disable applying of gear for the copied design.",
|
||||
Icon = FontAwesomeIcon.Copy,
|
||||
OnClick = ExportToClipboard,
|
||||
Visible = _selector.HasSelection,
|
||||
};
|
||||
protected override uint TextColor
|
||||
=> panel._favorites.IsFavorite(panel._selector.Selection)
|
||||
? ColorId.FavoriteStarOn.Value()
|
||||
: 0x80000000;
|
||||
|
||||
private HeaderDrawer.Button SaveAsDesignButton()
|
||||
=> new()
|
||||
{
|
||||
Description =
|
||||
"Save this NPCs appearance as a design.\nHold Control to disable applying of customizations for the saved design.\nHold Shift to disable applying of gear for the saved design.",
|
||||
Icon = FontAwesomeIcon.Save,
|
||||
OnClick = SaveDesignOpen,
|
||||
Visible = _selector.HasSelection,
|
||||
};
|
||||
protected override FontAwesomeIcon Icon
|
||||
=> FontAwesomeIcon.Star;
|
||||
|
||||
private void ExportToClipboard()
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = ToDesignData();
|
||||
var text = _converter.ShareBase64(data, new StateMaterialManager(), ApplicationRules.NpcFromModifiers());
|
||||
ImGui.SetClipboardText(text);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Glamourer.Messager.NotificationMessage(ex, $"Could not copy {_selector.Selection.Name}'s data to clipboard.",
|
||||
$"Could not copy data from NPC appearance {_selector.Selection.Kind} {_selector.Selection.Id.Id} to clipboard",
|
||||
NotificationType.Error);
|
||||
}
|
||||
}
|
||||
public override bool Visible
|
||||
=> panel._selector.HasSelection;
|
||||
|
||||
private void SaveDesignOpen()
|
||||
{
|
||||
ImGui.OpenPopup("Save as Design");
|
||||
_newName = _selector.Selection.Name;
|
||||
var data = ToDesignData();
|
||||
_newDesign = _converter.Convert(data, new StateMaterialManager(), ApplicationRules.NpcFromModifiers());
|
||||
protected override void OnClick()
|
||||
=> panel._favorites.ToggleFavorite(panel._selector.Selection);
|
||||
}
|
||||
|
||||
private void SaveDesignDrawPopup()
|
||||
|
|
@ -289,4 +286,52 @@ public class NpcPanel(
|
|||
ImGuiUtil.HoverTooltip("Click to copy to clipboard.");
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ExportToClipboardButton(NpcPanel panel) : Button
|
||||
{
|
||||
protected override string Description
|
||||
=> "Copy the current NPCs appearance to your clipboard.\nHold Control to disable applying of customizations for the copied design.\nHold Shift to disable applying of gear for the copied design.";
|
||||
|
||||
protected override FontAwesomeIcon Icon
|
||||
=> FontAwesomeIcon.Copy;
|
||||
|
||||
public override bool Visible
|
||||
=> panel._selector.HasSelection;
|
||||
|
||||
protected override void OnClick()
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = panel.ToDesignData();
|
||||
var text = panel._converter.ShareBase64(data, new StateMaterialManager(), ApplicationRules.NpcFromModifiers());
|
||||
ImGui.SetClipboardText(text);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Glamourer.Messager.NotificationMessage(ex, $"Could not copy {panel._selector.Selection.Name}'s data to clipboard.",
|
||||
$"Could not copy data from NPC appearance {panel._selector.Selection.Kind} {panel._selector.Selection.Id.Id} to clipboard",
|
||||
NotificationType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class SaveAsDesignButton(NpcPanel panel) : Button
|
||||
{
|
||||
protected override string Description
|
||||
=> "Save this NPCs appearance as a design.\nHold Control to disable applying of customizations for the saved design.\nHold Shift to disable applying of gear for the saved design.";
|
||||
|
||||
protected override FontAwesomeIcon Icon
|
||||
=> FontAwesomeIcon.Save;
|
||||
|
||||
public override bool Visible
|
||||
=> panel._selector.HasSelection;
|
||||
|
||||
protected override void OnClick()
|
||||
{
|
||||
ImGui.OpenPopup("Save as Design");
|
||||
panel._newName = panel._selector.Selection.Name;
|
||||
var data = panel.ToDesignData();
|
||||
panel._newDesign = panel._converter.Convert(data, new StateMaterialManager(), ApplicationRules.NpcFromModifiers());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ public class SettingsTab(
|
|||
{
|
||||
var showAuto = config.EnableAutoDesigns;
|
||||
var showAdvanced = config.UseAdvancedParameters || config.UseAdvancedDyes;
|
||||
var numColumns = 6 - (showAuto ? 0 : 1) - (showAdvanced ? 0 : 1);
|
||||
var numColumns = 7 - (showAuto ? 0 : 2) - (showAdvanced ? 0 : 1);
|
||||
ImGui.NewLine();
|
||||
ImGui.TextUnformatted("Show the Following Buttons in the Quick Design Bar:");
|
||||
ImGui.Dummy(Vector2.Zero);
|
||||
|
|
@ -225,8 +225,9 @@ public class SettingsTab(
|
|||
(" Apply Design ", true, QdbButtons.ApplyDesign),
|
||||
(" Revert All ", true, QdbButtons.RevertAll),
|
||||
(" Revert to Auto ", showAuto, QdbButtons.RevertAutomation),
|
||||
(" Reapply Auto ", showAuto, QdbButtons.ReapplyAutomation),
|
||||
(" Revert Equip ", true, QdbButtons.RevertEquip),
|
||||
(" Revert Customization ", true, QdbButtons.RevertCustomize),
|
||||
(" Revert Customize ", true, QdbButtons.RevertCustomize),
|
||||
(" Revert Advanced ", showAdvanced, QdbButtons.RevertAdvanced),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,8 @@ public class CommandService : IDisposable
|
|||
"apply" => Apply(argument),
|
||||
"reapply" => ReapplyState(argument),
|
||||
"revert" => Revert(argument),
|
||||
"reapplyautomation" => ReapplyAutomation(argument),
|
||||
"reapplyautomation" => ReapplyAutomation(argument, "reapplyautomation", false),
|
||||
"reverttoautomation" => ReapplyAutomation(argument, "reverttoautomation", true),
|
||||
"automation" => SetAutomation(argument),
|
||||
"copy" => CopyState(argument),
|
||||
"save" => SaveState(argument),
|
||||
|
|
@ -143,6 +144,8 @@ public class CommandService : IDisposable
|
|||
_chat.Print(new SeStringBuilder().AddCommand("revert", "Reverts a given character to its game state. Use without arguments for help.")
|
||||
.BuiltString);
|
||||
_chat.Print(new SeStringBuilder().AddCommand("reapplyautomation",
|
||||
"Reapplies the current automation state on top of the characters current state.. Use without arguments for help.").BuiltString);
|
||||
_chat.Print(new SeStringBuilder().AddCommand("reverttoautomation",
|
||||
"Reverts a given character to its supposed state using automated designs. Use without arguments for help.").BuiltString);
|
||||
_chat.Print(new SeStringBuilder()
|
||||
.AddCommand("copy", "Copy the current state of a character to clipboard. Use without arguments for help.").BuiltString);
|
||||
|
|
@ -296,11 +299,11 @@ public class CommandService : IDisposable
|
|||
return true;
|
||||
}
|
||||
|
||||
private bool ReapplyAutomation(string argument)
|
||||
private bool ReapplyAutomation(string argument, string command, bool revert)
|
||||
{
|
||||
if (argument.Length == 0)
|
||||
{
|
||||
_chat.Print(new SeStringBuilder().AddText("Use with /glamour reapplyautomation ").AddGreen("[Character Identifier]").BuiltString);
|
||||
_chat.Print(new SeStringBuilder().AddText($"Use with /glamour {command} ").AddGreen("[Character Identifier]").BuiltString);
|
||||
PlayerIdentifierHelp(false, true);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -318,7 +321,7 @@ public class CommandService : IDisposable
|
|||
{
|
||||
if (_stateManager.GetOrCreate(identifier, actor, out var state))
|
||||
{
|
||||
_autoDesignApplier.ReapplyAutomation(actor, identifier, state);
|
||||
_autoDesignApplier.ReapplyAutomation(actor, identifier, state, revert);
|
||||
_stateManager.ReapplyState(actor, StateSource.Manual);
|
||||
}
|
||||
}
|
||||
|
|
@ -474,7 +477,10 @@ public class CommandService : IDisposable
|
|||
_chat.Print(new SeStringBuilder()
|
||||
.AddText(" 》 Clipboard as a single word will try to apply a design string currently in your clipboard.").BuiltString);
|
||||
_chat.Print(new SeStringBuilder()
|
||||
.AddText(" 》 ").AddYellow("Random").AddText(" supports many restrictions, see the Restriction Builder when adding a Random design to Automations for valid strings.").BuiltString);
|
||||
.AddText(" 》 ").AddYellow("Random")
|
||||
.AddText(
|
||||
" supports many restrictions, see the Restriction Builder when adding a Random design to Automations for valid strings.")
|
||||
.BuiltString);
|
||||
_chat.Print(new SeStringBuilder()
|
||||
.AddText(" 》 ").AddBlue("<Enable Mods>").AddText(" is optional and can be omitted (together with the ;), ").AddBlue("true")
|
||||
.AddText(" or ").AddBlue("false").AddText(".").BuiltString);
|
||||
|
|
@ -677,6 +683,7 @@ public class CommandService : IDisposable
|
|||
_chat.Print(new SeStringBuilder().AddText("No design matched your restrictions.").BuiltString);
|
||||
return false;
|
||||
}
|
||||
|
||||
_chat.Print($"Chose random design {((Design)design).Name}.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue