Add Reapply Automation with prior functionality and rework header buttons for performance.

This commit is contained in:
Ottermandias 2024-03-15 15:36:20 +01:00
parent 8dde1689f7
commit 05d261d4a3
11 changed files with 612 additions and 364 deletions

View file

@ -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()
{ }
}
}