feat: improve interactions with active HUD layout
Trying to preview different saved was more difficult than it needed to be since after importing a layout, the user needed to swap to another layout and then back to the original one in order to see the changes. I changed this so that if a user imports a layout to the currently active HUD slot, the plugin automatically swaps to another HUD slot and back. As a part of this also refined the general slot UI so that the active slot is indicated in the slot selection UI for saving a layout to game data.
This commit is contained in:
parent
38907f2cd8
commit
67a3b5caf3
|
@ -11,6 +11,7 @@ namespace HudSwap {
|
|||
private const int LAYOUT_SIZE = 0xb40;
|
||||
|
||||
private delegate IntPtr GetFilePointerDelegate(byte index);
|
||||
|
||||
private delegate uint SetHudLayoutDelegate(IntPtr filePtr, uint hudLayout, byte unk0, byte unk1);
|
||||
|
||||
private readonly GetFilePointerDelegate _getFilePointer;
|
||||
|
@ -73,6 +74,16 @@ namespace HudSwap {
|
|||
return this.GetDataPointer() + 0x2c58 + (slotNum * LAYOUT_SIZE);
|
||||
}
|
||||
|
||||
public HudSlot GetActiveHudSlot() {
|
||||
int slotVal = Marshal.ReadInt32(this.GetDataPointer() + 0x5958);
|
||||
|
||||
if (!Enum.IsDefined(typeof(HudSlot), slotVal)) {
|
||||
throw new IOException($"invalid hud slot in FFXIV memory of ${slotVal}");
|
||||
}
|
||||
|
||||
return (HudSlot)slotVal;
|
||||
}
|
||||
|
||||
public byte[] ReadLayout(HudSlot slot) {
|
||||
IntPtr slotPtr = this.GetLayoutPointer(slot);
|
||||
byte[] bytes = new byte[LAYOUT_SIZE];
|
||||
|
@ -87,9 +98,17 @@ namespace HudSwap {
|
|||
if (layout.Length != LAYOUT_SIZE) {
|
||||
throw new ArgumentException($"layout must be {LAYOUT_SIZE} bytes", nameof(layout));
|
||||
}
|
||||
|
||||
IntPtr slotPtr = this.GetLayoutPointer(slot);
|
||||
Marshal.Copy(layout, 0, slotPtr, LAYOUT_SIZE);
|
||||
|
||||
var currentSlot = this.GetActiveHudSlot();
|
||||
if (currentSlot == slot) {
|
||||
this.SelectSlot(currentSlot, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void WriteLayout(byte[] layout) => WriteLayout(this.GetActiveHudSlot(), layout);
|
||||
}
|
||||
|
||||
public enum HudSlot {
|
||||
|
|
|
@ -39,7 +39,10 @@ namespace HudSwap {
|
|||
|
||||
private string importName = "";
|
||||
private string renameName = "";
|
||||
private Guid selectedLayout = Guid.Empty;
|
||||
private Guid selectedLayoutId = Guid.Empty;
|
||||
|
||||
private Layout selectedLayout =>
|
||||
selectedLayoutId == Guid.Empty ? null : this.plugin.Config.Layouts2[this.selectedLayoutId];
|
||||
|
||||
private int editingConditionIndex = -1;
|
||||
private HudConditionMatch editingCondition;
|
||||
|
@ -107,8 +110,8 @@ namespace HudSwap {
|
|||
ImGui.PushItemWidth(-1);
|
||||
if (ImGui.ListBoxHeader("##saved-layouts")) {
|
||||
foreach (KeyValuePair<Guid, Layout> entry in this.plugin.Config.Layouts2) {
|
||||
if (ImGui.Selectable($"{entry.Value.Name}##{entry.Key}", this.selectedLayout == entry.Key)) {
|
||||
this.selectedLayout = entry.Key;
|
||||
if (ImGui.Selectable($"{entry.Value.Name}##{entry.Key}", this.selectedLayoutId == entry.Key)) {
|
||||
this.selectedLayoutId = entry.Key;
|
||||
this.renameName = entry.Value.Name;
|
||||
this.importName = this.renameName;
|
||||
}
|
||||
|
@ -117,27 +120,37 @@ namespace HudSwap {
|
|||
}
|
||||
ImGui.PopItemWidth();
|
||||
|
||||
ImGui.NewLine();
|
||||
|
||||
const int deleteButtonWidth = 30;
|
||||
ImGui.SameLine(ImGui.GetWindowContentRegionWidth() - deleteButtonWidth);
|
||||
ImGui.PushFont(UiBuilder.IconFont);
|
||||
if (ImGui.Button(FontAwesomeIcon.Trash.ToIconString(), new Vector2(deleteButtonWidth, ImGui.GetTextLineHeight())) &&
|
||||
this.selectedLayoutId != null) {
|
||||
this.plugin.Config.Layouts2.Remove(this.selectedLayoutId);
|
||||
this.plugin.Config.HudConditionMatches.RemoveAll(m => m.LayoutId == this.selectedLayoutId);
|
||||
this.selectedLayoutId = Guid.Empty;
|
||||
this.renameName = "";
|
||||
this.plugin.Config.Save();
|
||||
}
|
||||
ImGui.PopFont();
|
||||
|
||||
ImGui.Text("Copy onto slot...");
|
||||
Vector2 slotButtonSize = new Vector2(40, ImGui.GetTextLineHeight());
|
||||
foreach (HudSlot slot in Enum.GetValues(typeof(HudSlot))) {
|
||||
string buttonName = $"{(int)slot + 1}##copy";
|
||||
if (ImGui.Button(buttonName) && this.selectedLayout != null) {
|
||||
Layout layout = this.plugin.Config.Layouts2[this.selectedLayout];
|
||||
this.plugin.Hud.WriteLayout(slot, layout.Hud.ToArray());
|
||||
// Surround the button with parentheses if this is the current slot
|
||||
string slotText = slot == this.plugin.Hud.GetActiveHudSlot() ? $"({(int)slot + 1})" : ((int)slot + 1).ToString();
|
||||
string buttonName = $"{slotText}##copy";
|
||||
if (ImGui.Button(buttonName, slotButtonSize) && this.selectedLayout != null) {
|
||||
this.plugin.Hud.WriteLayout(slot, this.selectedLayout.Hud);
|
||||
}
|
||||
ImGui.SameLine();
|
||||
}
|
||||
|
||||
if (ImGui.Button("Delete") && this.selectedLayout != null) {
|
||||
this.plugin.Config.Layouts2.Remove(this.selectedLayout);
|
||||
this.plugin.Config.HudConditionMatches.RemoveAll(m => m.LayoutId == this.selectedLayout);
|
||||
this.selectedLayout = Guid.Empty;
|
||||
this.renameName = "";
|
||||
this.plugin.Config.Save();
|
||||
}
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGui.Button("Copy to clipboard") && this.selectedLayout != null) {
|
||||
if (this.plugin.Config.Layouts2.TryGetValue(this.selectedLayout, out Layout layout)) {
|
||||
if (ImGui.Button("Clipboard") && this.selectedLayoutId != null) {
|
||||
if (this.plugin.Config.Layouts2.TryGetValue(this.selectedLayoutId, out Layout layout)) {
|
||||
SharedLayout shared = new SharedLayout(layout);
|
||||
string json = JsonConvert.SerializeObject(shared);
|
||||
ImGui.SetClipboardText(json);
|
||||
|
@ -146,10 +159,10 @@ namespace HudSwap {
|
|||
|
||||
ImGui.InputText("##rename-input", ref this.renameName, 100);
|
||||
ImGui.SameLine();
|
||||
if (ImGui.Button("Rename") && this.renameName.Length != 0 && this.selectedLayout != null) {
|
||||
Layout layout = this.plugin.Config.Layouts2[this.selectedLayout];
|
||||
if (ImGui.Button("Rename") && this.renameName.Length != 0 && this.selectedLayoutId != null) {
|
||||
Layout layout = this.plugin.Config.Layouts2[this.selectedLayoutId];
|
||||
Layout newLayout = new Layout(this.renameName, layout.Hud, layout.Positions);
|
||||
this.plugin.Config.Layouts2[this.selectedLayout] = newLayout;
|
||||
this.plugin.Config.Layouts2[this.selectedLayoutId] = newLayout;
|
||||
this.plugin.Config.Save();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue