2021-11-19 17:55:07 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Linq;
|
2021-12-07 22:06:14 +00:00
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.Http;
|
2021-11-19 17:55:07 +00:00
|
|
|
|
using System.Numerics;
|
2021-12-07 22:06:14 +00:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Dalamud;
|
2021-11-19 17:55:07 +00:00
|
|
|
|
using Dalamud.Interface;
|
|
|
|
|
using Dalamud.Interface.Colors;
|
2021-12-13 09:04:11 +00:00
|
|
|
|
using Dalamud.Logging;
|
2021-11-19 17:55:07 +00:00
|
|
|
|
using ImGuiNET;
|
|
|
|
|
using Lumina.Excel.GeneratedSheets;
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
|
|
|
|
namespace Glamaholic.Ui {
|
|
|
|
|
internal class MainInterface {
|
2021-11-23 00:58:39 +00:00
|
|
|
|
internal const int IconSize = 48;
|
|
|
|
|
|
2021-11-19 17:55:07 +00:00
|
|
|
|
private static readonly PlateSlot[] LeftSide = {
|
|
|
|
|
PlateSlot.MainHand,
|
|
|
|
|
PlateSlot.Head,
|
|
|
|
|
PlateSlot.Body,
|
|
|
|
|
PlateSlot.Hands,
|
|
|
|
|
PlateSlot.Legs,
|
|
|
|
|
PlateSlot.Feet,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private static readonly PlateSlot[] RightSide = {
|
|
|
|
|
PlateSlot.OffHand,
|
|
|
|
|
PlateSlot.Ears,
|
|
|
|
|
PlateSlot.Neck,
|
|
|
|
|
PlateSlot.Wrists,
|
|
|
|
|
PlateSlot.RightRing,
|
|
|
|
|
PlateSlot.LeftRing,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private PluginUi Ui { get; }
|
|
|
|
|
private List<Item> Items { get; }
|
|
|
|
|
private List<Item> FilteredItems { get; set; }
|
2021-12-07 22:06:14 +00:00
|
|
|
|
private Dictionary<string, byte> Stains { get; }
|
2021-11-19 17:55:07 +00:00
|
|
|
|
|
2021-12-13 09:03:01 +00:00
|
|
|
|
private FilterInfo? PlateFilter { get; set; }
|
|
|
|
|
|
2021-11-19 17:55:07 +00:00
|
|
|
|
private bool _visible;
|
|
|
|
|
private int _dragging = -1;
|
|
|
|
|
private int _selectedPlate = -1;
|
|
|
|
|
private bool _scrollToSelected;
|
|
|
|
|
private string _plateFilter = string.Empty;
|
|
|
|
|
private bool _showRename;
|
|
|
|
|
private string _renameInput = string.Empty;
|
|
|
|
|
private bool _deleteConfirm;
|
|
|
|
|
private bool _editing;
|
|
|
|
|
private SavedPlate? _editingPlate;
|
|
|
|
|
private string _itemFilter = string.Empty;
|
|
|
|
|
private string _dyeFilter = string.Empty;
|
2021-12-07 22:06:14 +00:00
|
|
|
|
private volatile bool _ecImporting;
|
2021-12-09 09:07:58 +00:00
|
|
|
|
private readonly Dictionary<string, Stopwatch> _timedMessages = new();
|
2021-12-13 09:33:15 +00:00
|
|
|
|
private string _tagInput = string.Empty;
|
2021-11-19 17:55:07 +00:00
|
|
|
|
|
|
|
|
|
internal MainInterface(PluginUi ui) {
|
|
|
|
|
this.Ui = ui;
|
|
|
|
|
|
|
|
|
|
// get all equippable items that aren't soul crystals
|
2021-12-09 22:44:22 +00:00
|
|
|
|
this.Items = this.Ui.Plugin.DataManager.GetExcelSheet<Item>(ClientLanguage.English)!
|
2021-11-19 17:55:07 +00:00
|
|
|
|
.Where(row => row.EquipSlotCategory.Row is not 0 && row.EquipSlotCategory.Value!.SoulCrystal == 0)
|
|
|
|
|
.ToList();
|
|
|
|
|
this.FilteredItems = this.Items;
|
2021-12-07 22:06:14 +00:00
|
|
|
|
|
|
|
|
|
this.Stains = this.Ui.Plugin.DataManager.GetExcelSheet<Stain>(ClientLanguage.English)!
|
|
|
|
|
.Where(row => row.RowId != 0)
|
|
|
|
|
.Where(row => !string.IsNullOrWhiteSpace(row.Name.RawString))
|
|
|
|
|
.ToDictionary(row => row.Name.RawString, row => (byte) row.RowId);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void Open() {
|
|
|
|
|
this._visible = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void Toggle() {
|
|
|
|
|
this._visible ^= true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void Draw() {
|
|
|
|
|
this.HandleTimers();
|
|
|
|
|
|
|
|
|
|
if (!this._visible) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.SetNextWindowSize(new Vector2(415, 650), ImGuiCond.FirstUseEver);
|
|
|
|
|
|
|
|
|
|
if (!ImGui.Begin(this.Ui.Plugin.Name, ref this._visible, ImGuiWindowFlags.MenuBar)) {
|
|
|
|
|
ImGui.End();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.DrawInner();
|
|
|
|
|
|
|
|
|
|
ImGui.End();
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-13 09:04:11 +00:00
|
|
|
|
private static bool IsValidEorzeaCollectionUrl(string urlString) {
|
|
|
|
|
if (!Uri.TryCreate(urlString, UriKind.Absolute, out var url)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return url.Host == "ffxiv.eorzeacollection.com" && url.AbsolutePath.StartsWith("/glamour/");
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-19 17:55:07 +00:00
|
|
|
|
private void DrawMenuBar() {
|
|
|
|
|
if (!ImGui.BeginMenuBar()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui.BeginMenu("Plates")) {
|
|
|
|
|
if (ImGui.MenuItem("New")) {
|
2021-11-21 06:38:36 +00:00
|
|
|
|
this.Ui.Plugin.Config.AddPlate(new SavedPlate("Untitled Plate"));
|
2021-11-19 17:55:07 +00:00
|
|
|
|
this.Ui.Plugin.SaveConfig();
|
|
|
|
|
this.SwitchPlate(this.Ui.Plugin.Config.Plates.Count - 1, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui.BeginMenu("Import")) {
|
2021-12-13 09:04:11 +00:00
|
|
|
|
if (ImGui.MenuItem("Clipboard")) {
|
2021-12-13 10:35:23 +00:00
|
|
|
|
var json = Util.GetClipboardText();
|
2021-11-19 17:55:07 +00:00
|
|
|
|
try {
|
2021-12-13 09:04:11 +00:00
|
|
|
|
var plate = JsonConvert.DeserializeObject<SharedPlate>(json);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
if (plate != null) {
|
2021-12-13 09:04:11 +00:00
|
|
|
|
this.Ui.Plugin.Config.AddPlate(plate.ToPlate());
|
2021-11-19 17:55:07 +00:00
|
|
|
|
this.Ui.Plugin.SaveConfig();
|
2021-12-13 09:04:11 +00:00
|
|
|
|
this.Ui.SwitchPlate(this.Ui.Plugin.Config.Plates.Count - 1);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
2021-12-13 09:04:11 +00:00
|
|
|
|
PluginLog.LogWarning(ex, "Failed to import glamour plate");
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-13 10:35:23 +00:00
|
|
|
|
var validUrl = IsValidEorzeaCollectionUrl(Util.GetClipboardText());
|
2021-12-13 09:04:11 +00:00
|
|
|
|
if (ImGui.MenuItem("Copied Eorzea Collection URL", validUrl) && !this._ecImporting) {
|
2021-12-13 10:35:23 +00:00
|
|
|
|
this.ImportEorzeaCollection(Util.GetClipboardText());
|
2021-12-13 10:00:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-07 22:06:14 +00:00
|
|
|
|
ImGui.EndMenu();
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-19 17:55:07 +00:00
|
|
|
|
ImGui.EndMenu();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var anyChanged = false;
|
|
|
|
|
if (ImGui.BeginMenu("Settings")) {
|
|
|
|
|
anyChanged |= ImGui.MenuItem("Show plate editor menu", null, ref this.Ui.Plugin.Config.ShowEditorMenu);
|
|
|
|
|
anyChanged |= ImGui.MenuItem("Show examine window menu", null, ref this.Ui.Plugin.Config.ShowExamineMenu);
|
2021-11-23 18:41:58 +00:00
|
|
|
|
anyChanged |= ImGui.MenuItem("Show try on menu", null, ref this.Ui.Plugin.Config.ShowTryOnMenu);
|
2021-11-22 22:50:08 +00:00
|
|
|
|
ImGui.Separator();
|
|
|
|
|
anyChanged |= ImGui.MenuItem("Show Ko-fi button", null, ref this.Ui.Plugin.Config.ShowKofiButton);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
|
|
|
|
|
ImGui.EndMenu();
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-23 04:18:52 +00:00
|
|
|
|
if (ImGui.BeginMenu("Help")) {
|
|
|
|
|
foreach (var (title, content) in this.Ui.Help) {
|
|
|
|
|
if (!ImGui.BeginMenu(title)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.PushTextWrapPos(ImGui.CalcTextSize("0").X * 60f * ImGuiHelpers.GlobalScale);
|
|
|
|
|
ImGui.TextUnformatted(content);
|
|
|
|
|
ImGui.PopTextWrapPos();
|
|
|
|
|
|
|
|
|
|
ImGui.EndMenu();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndMenu();
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-22 22:50:08 +00:00
|
|
|
|
if (this.Ui.Plugin.Config.ShowKofiButton) {
|
|
|
|
|
const string kofiText = "Support on Ko-fi";
|
|
|
|
|
var kofiTextSize = ImGui.CalcTextSize(kofiText);
|
|
|
|
|
ImGui.GetWindowDrawList().AddRectFilled(
|
|
|
|
|
ImGui.GetCursorScreenPos(),
|
|
|
|
|
ImGui.GetCursorScreenPos() + kofiTextSize + ImGui.GetStyle().ItemInnerSpacing * 2,
|
|
|
|
|
0xFF5B5EFF
|
|
|
|
|
);
|
|
|
|
|
ImGui.PushStyleColor(ImGuiCol.Text, 0xFFFFFFFF);
|
|
|
|
|
ImGui.PushStyleColor(ImGuiCol.HeaderHovered, 0x00000000);
|
|
|
|
|
if (ImGui.MenuItem(kofiText)) {
|
|
|
|
|
Process.Start(new ProcessStartInfo("https://ko-fi.com/ascclemens") {
|
|
|
|
|
UseShellExecute = true,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.PopStyleColor(2);
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-19 17:55:07 +00:00
|
|
|
|
if (anyChanged) {
|
|
|
|
|
this.Ui.Plugin.SaveConfig();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndMenuBar();
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-13 09:04:11 +00:00
|
|
|
|
private void ImportEorzeaCollection(string url) {
|
|
|
|
|
if (!IsValidEorzeaCollectionUrl(url)) {
|
2021-12-07 22:06:14 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this._ecImporting = true;
|
|
|
|
|
|
|
|
|
|
Task.Run(async () => {
|
|
|
|
|
var items = new Dictionary<PlateSlot, SavedGlamourItem>();
|
|
|
|
|
|
|
|
|
|
var client = new HttpClient();
|
2021-12-13 09:04:11 +00:00
|
|
|
|
var resp = await client.GetAsync(url);
|
2021-12-07 22:06:14 +00:00
|
|
|
|
var html = await resp.Content.ReadAsStringAsync();
|
|
|
|
|
|
|
|
|
|
var titleParts = html.Split("<title>");
|
|
|
|
|
var glamName = titleParts.Length > 1
|
2021-12-09 05:59:51 +00:00
|
|
|
|
? WebUtility.HtmlDecode(titleParts[1].Split('<')[0].Split('|')[0].Trim())
|
2021-12-07 22:06:14 +00:00
|
|
|
|
: "Eorzea Collection plate";
|
|
|
|
|
|
|
|
|
|
var parts = html.Split("c-gear-slot-item-name");
|
|
|
|
|
foreach (var part in parts) {
|
|
|
|
|
var nameParts = part.Split('>');
|
|
|
|
|
if (nameParts.Length < 2) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var rawName = nameParts[1].Split('<')[0].Trim();
|
|
|
|
|
var name = WebUtility.HtmlDecode(rawName);
|
|
|
|
|
if (string.IsNullOrWhiteSpace(name)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-12-09 06:19:31 +00:00
|
|
|
|
|
2021-12-07 22:06:14 +00:00
|
|
|
|
var item = this.Items.Find(item => item.Name == name);
|
|
|
|
|
if (item == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var slot = Util.GetSlot(item);
|
|
|
|
|
if (slot is PlateSlot.RightRing && items.ContainsKey(PlateSlot.RightRing)) {
|
|
|
|
|
slot = PlateSlot.LeftRing;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (slot == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var stainId = this.GetStainIdFromPart(part);
|
|
|
|
|
items[slot.Value] = new SavedGlamourItem {
|
|
|
|
|
ItemId = item.RowId,
|
|
|
|
|
StainId = stainId,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this._ecImporting = false;
|
|
|
|
|
|
|
|
|
|
var plate = new SavedPlate(glamName) {
|
|
|
|
|
Items = items,
|
|
|
|
|
};
|
|
|
|
|
this.Ui.Plugin.Config.AddPlate(plate);
|
|
|
|
|
this.Ui.Plugin.SaveConfig();
|
|
|
|
|
this.SwitchPlate(this.Ui.Plugin.Config.Plates.Count - 1, true);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private byte GetStainIdFromPart(string part) {
|
|
|
|
|
var stainParts = part.Split('⬤');
|
|
|
|
|
if (stainParts.Length <= 1) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var stainSubParts = stainParts[1].Split('>');
|
|
|
|
|
if (stainSubParts.Length <= 1) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var rawStainName = stainSubParts[1].Split('<')[0].Trim();
|
|
|
|
|
var stainName = WebUtility.HtmlDecode(rawStainName);
|
|
|
|
|
this.Stains.TryGetValue(stainName, out var stainId);
|
|
|
|
|
return stainId;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-19 17:55:07 +00:00
|
|
|
|
private void DrawPlateList() {
|
|
|
|
|
if (!ImGui.BeginChild("plate list", new Vector2(205 * ImGuiHelpers.GlobalScale, 0), true)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.SetNextItemWidth(-1);
|
2021-12-13 09:03:01 +00:00
|
|
|
|
if (ImGui.InputText("##plate-filter", ref this._plateFilter, 512, ImGuiInputTextFlags.AutoSelectAll)) {
|
|
|
|
|
this.PlateFilter = this._plateFilter.Length == 0
|
|
|
|
|
? null
|
|
|
|
|
: new FilterInfo(this.Ui.Plugin.DataManager, this._plateFilter);
|
|
|
|
|
}
|
2021-11-19 17:55:07 +00:00
|
|
|
|
|
|
|
|
|
(int src, int dst)? drag = null;
|
|
|
|
|
if (ImGui.BeginChild("plate list actual", Vector2.Zero, false, ImGuiWindowFlags.HorizontalScrollbar)) {
|
|
|
|
|
for (var i = 0; i < this.Ui.Plugin.Config.Plates.Count; i++) {
|
|
|
|
|
var plate = this.Ui.Plugin.Config.Plates[i];
|
|
|
|
|
|
2021-12-13 09:03:01 +00:00
|
|
|
|
if (this.PlateFilter != null && !this.PlateFilter.Matches(plate)) {
|
2021-11-19 17:55:07 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int? switchTo = null;
|
|
|
|
|
if (ImGui.Selectable($"{plate.Name}##{i}", this._selectedPlate == i)) {
|
|
|
|
|
switchTo = i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this._scrollToSelected && this._selectedPlate == i) {
|
|
|
|
|
this._scrollToSelected = false;
|
|
|
|
|
ImGui.SetScrollHereY(1f);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right)) {
|
|
|
|
|
switchTo = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui.IsItemHovered()) {
|
|
|
|
|
ImGui.PushFont(UiBuilder.IconFont);
|
|
|
|
|
var deleteWidth = ImGui.CalcTextSize(FontAwesomeIcon.Times.ToIconString()).X;
|
|
|
|
|
ImGui.SameLine(ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemInnerSpacing.X * 2 - deleteWidth);
|
|
|
|
|
ImGui.TextUnformatted(FontAwesomeIcon.Times.ToIconString());
|
|
|
|
|
ImGui.PopFont();
|
|
|
|
|
|
|
|
|
|
var mouseDown = ImGui.IsMouseDown(ImGuiMouseButton.Left);
|
|
|
|
|
var mouseClicked = ImGui.IsMouseReleased(ImGuiMouseButton.Left);
|
|
|
|
|
if (ImGui.IsItemHovered() || mouseDown) {
|
|
|
|
|
if (mouseClicked) {
|
|
|
|
|
switchTo = null;
|
|
|
|
|
|
|
|
|
|
if (this._deleteConfirm) {
|
|
|
|
|
this._deleteConfirm = false;
|
|
|
|
|
if (this._selectedPlate == i) {
|
|
|
|
|
switchTo = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.Ui.Plugin.Config.Plates.RemoveAt(i);
|
|
|
|
|
this.Ui.Plugin.SaveConfig();
|
|
|
|
|
} else {
|
|
|
|
|
this._deleteConfirm = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
this._deleteConfirm = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this._deleteConfirm) {
|
|
|
|
|
ImGui.BeginTooltip();
|
|
|
|
|
ImGui.TextUnformatted("Click delete again to confirm.");
|
|
|
|
|
ImGui.EndTooltip();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (switchTo != null) {
|
|
|
|
|
this.SwitchPlate(switchTo.Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// handle dragging
|
|
|
|
|
if (this._plateFilter.Length == 0 && ImGui.IsItemActive() || this._dragging == i) {
|
|
|
|
|
this._dragging = i;
|
|
|
|
|
var step = 0;
|
|
|
|
|
if (ImGui.GetIO().MouseDelta.Y < 0 && ImGui.GetMousePos().Y < ImGui.GetItemRectMin().Y) {
|
|
|
|
|
step = -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui.GetIO().MouseDelta.Y > 0 && ImGui.GetMousePos().Y > ImGui.GetItemRectMax().Y) {
|
|
|
|
|
step = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (step != 0) {
|
|
|
|
|
drag = (i, i + step);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ImGui.IsMouseDown(ImGuiMouseButton.Left) && this._dragging != -1) {
|
|
|
|
|
this._dragging = -1;
|
|
|
|
|
this.Ui.Plugin.SaveConfig();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (drag != null && drag.Value.dst < this.Ui.Plugin.Config.Plates.Count && drag.Value.dst >= 0) {
|
|
|
|
|
this._dragging = drag.Value.dst;
|
|
|
|
|
// ReSharper disable once SwapViaDeconstruction
|
|
|
|
|
var temp = this.Ui.Plugin.Config.Plates[drag.Value.src];
|
|
|
|
|
this.Ui.Plugin.Config.Plates[drag.Value.src] = this.Ui.Plugin.Config.Plates[drag.Value.dst];
|
|
|
|
|
this.Ui.Plugin.Config.Plates[drag.Value.dst] = temp;
|
|
|
|
|
|
|
|
|
|
// do not SwitchPlate, because this is technically not a switch
|
|
|
|
|
if (this._selectedPlate == drag.Value.dst) {
|
|
|
|
|
var step = drag.Value.dst - drag.Value.src;
|
|
|
|
|
this._selectedPlate = drag.Value.dst - step;
|
|
|
|
|
} else if (this._selectedPlate == drag.Value.src) {
|
|
|
|
|
this._selectedPlate = drag.Value.dst;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndChild();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndChild();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawDyePopup(string dyePopup, SavedGlamourItem mirage) {
|
|
|
|
|
if (!ImGui.BeginPopup(dyePopup)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.PushItemWidth(-1);
|
|
|
|
|
ImGui.InputText("##dye-filter", ref this._dyeFilter, 512);
|
|
|
|
|
|
|
|
|
|
if (ImGui.IsWindowAppearing()) {
|
|
|
|
|
ImGui.SetKeyboardFocusHere();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui.BeginChild("dye picker", new Vector2(250, 350), false, ImGuiWindowFlags.HorizontalScrollbar)) {
|
|
|
|
|
if (ImGui.Selectable("None", mirage.StainId == 0)) {
|
|
|
|
|
mirage.StainId = 0;
|
|
|
|
|
ImGui.CloseCurrentPopup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var filter = this._dyeFilter.ToLowerInvariant();
|
|
|
|
|
|
|
|
|
|
foreach (var stain in this.Ui.Plugin.DataManager.GetExcelSheet<Stain>()!) {
|
|
|
|
|
if (stain.RowId == 0 || stain.Shade == 0) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (filter.Length > 0 && !stain.Name.RawString.ToLowerInvariant().Contains(filter)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui.Selectable($"{stain.Name}##{stain.RowId}", mirage.StainId == stain.RowId)) {
|
|
|
|
|
mirage.StainId = (byte) stain.RowId;
|
|
|
|
|
ImGui.CloseCurrentPopup();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndChild();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndPopup();
|
|
|
|
|
}
|
2021-11-21 07:17:58 +00:00
|
|
|
|
|
2021-11-19 17:55:07 +00:00
|
|
|
|
private unsafe void DrawItemPopup(string itemPopup, SavedPlate plate, PlateSlot slot) {
|
|
|
|
|
if (!ImGui.BeginPopup(itemPopup)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.SetNextItemWidth(-1);
|
|
|
|
|
if (ImGui.InputText("##item-filter", ref this._itemFilter, 512, ImGuiInputTextFlags.AutoSelectAll)) {
|
|
|
|
|
this.FilterItems(slot);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui.IsWindowAppearing()) {
|
|
|
|
|
ImGui.SetKeyboardFocusHere();
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
if (GameFunctions.DresserContents.Count > 0) {
|
|
|
|
|
if (ImGui.Checkbox("Only show items in the armoire/dresser", ref this.Ui.Plugin.Config.ItemFilterShowObtainedOnly)) {
|
|
|
|
|
this.Ui.Plugin.SaveConfig();
|
|
|
|
|
this.FilterItems(slot);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.Separator();
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-19 17:55:07 +00:00
|
|
|
|
if (ImGui.BeginChild("item search", new Vector2(250, 450), false, ImGuiWindowFlags.HorizontalScrollbar)) {
|
2021-11-21 08:22:37 +00:00
|
|
|
|
uint? id;
|
2021-11-19 17:55:07 +00:00
|
|
|
|
if (plate.Items.TryGetValue(slot, out var slotMirage)) {
|
|
|
|
|
id = slotMirage.ItemId;
|
2021-11-21 08:22:37 +00:00
|
|
|
|
} else {
|
|
|
|
|
id = null;
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
if (ImGui.Selectable("##none-keep", id == null)) {
|
2021-11-19 17:55:07 +00:00
|
|
|
|
plate.Items.Remove(slot);
|
|
|
|
|
ImGui.CloseCurrentPopup();
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
ImGui.SameLine();
|
|
|
|
|
Util.TextIcon(FontAwesomeIcon.Box);
|
|
|
|
|
ImGui.SameLine();
|
|
|
|
|
ImGui.TextUnformatted("None (keep existing)");
|
|
|
|
|
|
|
|
|
|
if (ImGui.Selectable("##none-remove)", id == 0)) {
|
2021-11-21 08:22:37 +00:00
|
|
|
|
plate.Items[slot] = new SavedGlamourItem();
|
|
|
|
|
ImGui.CloseCurrentPopup();
|
|
|
|
|
}
|
2021-12-13 09:04:11 +00:00
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
ImGui.SameLine();
|
|
|
|
|
Util.TextIcon(FontAwesomeIcon.Box);
|
|
|
|
|
ImGui.SameLine();
|
|
|
|
|
ImGui.TextUnformatted("None (remove existing)");
|
2021-11-21 08:22:37 +00:00
|
|
|
|
|
2021-11-19 17:55:07 +00:00
|
|
|
|
var clipper = new ImGuiListClipperPtr(ImGuiNative.ImGuiListClipper_ImGuiListClipper());
|
|
|
|
|
|
|
|
|
|
clipper.Begin(this.FilteredItems.Count);
|
|
|
|
|
while (clipper.Step()) {
|
|
|
|
|
for (var i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
|
|
|
|
|
var item = this.FilteredItems[i];
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
if (ImGui.Selectable($"##{item.RowId}", item.RowId == id)) {
|
2021-11-19 17:55:07 +00:00
|
|
|
|
if (!plate.Items.ContainsKey(slot)) {
|
|
|
|
|
plate.Items[slot] = new SavedGlamourItem();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
plate.Items[slot].ItemId = item.RowId;
|
|
|
|
|
if (!item.IsDyeable) {
|
|
|
|
|
plate.Items[slot].StainId = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.CloseCurrentPopup();
|
|
|
|
|
}
|
2021-11-23 00:58:39 +00:00
|
|
|
|
|
2021-11-23 04:23:56 +00:00
|
|
|
|
if (Util.IsItemMiddleOrCtrlClicked()) {
|
2021-11-23 00:58:39 +00:00
|
|
|
|
this.Ui.AlternativeFinders.Add(new AlternativeFinder(this.Ui, item));
|
|
|
|
|
}
|
2021-12-09 09:07:58 +00:00
|
|
|
|
|
|
|
|
|
ImGui.SameLine();
|
|
|
|
|
|
|
|
|
|
var has = GameFunctions.DresserContents.Any(saved => saved.ItemId % Util.HqItemOffset == item.RowId) || this.Ui.Plugin.Functions.IsInArmoire(item.RowId);
|
|
|
|
|
|
|
|
|
|
if (!has) {
|
|
|
|
|
ImGui.PushStyleColor(ImGuiCol.Text, ImGui.GetStyle().Colors[(int) ImGuiCol.TextDisabled]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Util.TextIcon(FontAwesomeIcon.Box);
|
|
|
|
|
|
|
|
|
|
if (!has) {
|
|
|
|
|
ImGui.PopStyleColor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.SameLine();
|
|
|
|
|
|
|
|
|
|
ImGui.TextUnformatted($"{item.Name}");
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndChild();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndPopup();
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
private unsafe void DrawIcon(PlateSlot slot, SavedPlate plate, int iconSize, int paddingSize) {
|
2021-11-19 17:55:07 +00:00
|
|
|
|
var drawCursor = ImGui.GetCursorScreenPos();
|
|
|
|
|
var tooltip = slot.Name();
|
|
|
|
|
ImGui.BeginGroup();
|
|
|
|
|
|
|
|
|
|
plate.Items.TryGetValue(slot, out var mirage);
|
|
|
|
|
|
|
|
|
|
var borderColour = *ImGui.GetStyleColorVec4(ImGuiCol.Border);
|
|
|
|
|
|
|
|
|
|
// check for item
|
2021-12-09 09:07:58 +00:00
|
|
|
|
if (mirage != null && mirage.ItemId != 0 && GameFunctions.DresserContents.Count > 0) {
|
2021-11-23 21:09:52 +00:00
|
|
|
|
var has = GameFunctions.DresserContents.Any(saved => saved.ItemId % Util.HqItemOffset == mirage.ItemId) || this.Ui.Plugin.Functions.IsInArmoire(mirage.ItemId);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
if (!has) {
|
|
|
|
|
borderColour = ImGuiColors.DalamudYellow;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.GetWindowDrawList().AddRect(drawCursor, drawCursor + new Vector2(iconSize + paddingSize), ImGui.ColorConvertFloat4ToU32(borderColour));
|
|
|
|
|
|
|
|
|
|
var cursorBefore = ImGui.GetCursorPos();
|
|
|
|
|
ImGui.InvisibleButton($"preview {slot}", new Vector2(iconSize + paddingSize));
|
|
|
|
|
var cursorAfter = ImGui.GetCursorPos();
|
|
|
|
|
|
2021-11-21 08:22:37 +00:00
|
|
|
|
if (mirage != null && mirage.ItemId != 0) {
|
2021-11-19 17:55:07 +00:00
|
|
|
|
var item = this.Ui.Plugin.DataManager.GetExcelSheet<Item>()!.GetRow(mirage.ItemId);
|
|
|
|
|
if (item != null) {
|
|
|
|
|
var icon = this.Ui.GetIcon(item.Icon);
|
|
|
|
|
if (icon != null) {
|
|
|
|
|
ImGui.SetCursorPos(cursorBefore + new Vector2(paddingSize / 2f));
|
|
|
|
|
ImGui.Image(icon.ImGuiHandle, new Vector2(iconSize));
|
|
|
|
|
ImGui.SetCursorPos(cursorAfter);
|
|
|
|
|
|
|
|
|
|
var stain = this.Ui.Plugin.DataManager.GetExcelSheet<Stain>()!.GetRow(mirage.StainId);
|
|
|
|
|
var circleCentre = drawCursor + new Vector2(iconSize, 4 + paddingSize / 2f);
|
|
|
|
|
if (mirage.StainId != 0 && stain != null) {
|
|
|
|
|
var colour = stain.Color;
|
|
|
|
|
var abgr = 0xFF000000;
|
|
|
|
|
abgr |= (colour & 0xFF) << 16;
|
|
|
|
|
abgr |= ((colour >> 8) & 0xFF) << 8;
|
|
|
|
|
abgr |= (colour >> 16) & 0xFF;
|
|
|
|
|
ImGui.GetWindowDrawList().AddCircleFilled(circleCentre, 4, abgr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item.IsDyeable) {
|
|
|
|
|
ImGui.GetWindowDrawList().AddCircle(circleCentre, 5, 0xFF000000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var stainName = mirage.StainId == 0 || stain == null
|
|
|
|
|
? ""
|
|
|
|
|
: $" ({stain.Name})";
|
|
|
|
|
tooltip += $"\n{item.Name}{stainName}";
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-21 08:22:37 +00:00
|
|
|
|
} else if (mirage != null) {
|
|
|
|
|
// remove
|
|
|
|
|
ImGui.GetWindowDrawList().AddLine(
|
|
|
|
|
drawCursor + new Vector2(paddingSize / 2f),
|
|
|
|
|
drawCursor + new Vector2(paddingSize / 2f) + new Vector2(iconSize),
|
|
|
|
|
ImGui.ColorConvertFloat4ToU32(ImGui.GetStyle().Colors[(int) ImGuiCol.Text])
|
|
|
|
|
);
|
2021-11-22 22:50:08 +00:00
|
|
|
|
|
2021-11-21 08:22:37 +00:00
|
|
|
|
ImGui.GetWindowDrawList().AddLine(
|
|
|
|
|
drawCursor + new Vector2(paddingSize / 2f) + new Vector2(iconSize, 0),
|
|
|
|
|
drawCursor + new Vector2(paddingSize / 2f) + new Vector2(0, iconSize),
|
|
|
|
|
ImGui.ColorConvertFloat4ToU32(ImGui.GetStyle().Colors[(int) ImGuiCol.Text])
|
|
|
|
|
);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndGroup();
|
|
|
|
|
|
|
|
|
|
// fix spacing
|
|
|
|
|
ImGui.SetCursorPos(cursorAfter);
|
|
|
|
|
|
|
|
|
|
if (ImGui.IsItemHovered()) {
|
|
|
|
|
ImGui.BeginTooltip();
|
|
|
|
|
ImGui.TextUnformatted(tooltip);
|
|
|
|
|
ImGui.EndTooltip();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var itemPopup = $"plate item edit {slot}";
|
|
|
|
|
var dyePopup = $"plate item dye {slot}";
|
|
|
|
|
if (this._editing && ImGui.IsItemClicked(ImGuiMouseButton.Left)) {
|
|
|
|
|
ImGui.OpenPopup(itemPopup);
|
|
|
|
|
this.FilterItems(slot);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this._editing && ImGui.IsItemClicked(ImGuiMouseButton.Right) && mirage != null) {
|
|
|
|
|
var dyeable = this.Ui.Plugin.DataManager.GetExcelSheet<Item>()!.GetRow(mirage.ItemId)?.IsDyeable ?? false;
|
|
|
|
|
if (dyeable) {
|
|
|
|
|
ImGui.OpenPopup(dyePopup);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-23 04:23:56 +00:00
|
|
|
|
if (mirage != null && mirage.ItemId != 0 && Util.IsItemMiddleOrCtrlClicked()) {
|
2021-11-23 00:58:39 +00:00
|
|
|
|
var item = this.Ui.Plugin.DataManager.GetExcelSheet<Item>()!.GetRow(mirage.ItemId);
|
|
|
|
|
if (item != null) {
|
|
|
|
|
this.Ui.AlternativeFinders.Add(new AlternativeFinder(this.Ui, item));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-19 17:55:07 +00:00
|
|
|
|
this.DrawItemPopup(itemPopup, plate, slot);
|
|
|
|
|
|
|
|
|
|
if (mirage != null) {
|
|
|
|
|
this.DrawDyePopup(dyePopup, mirage);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
private void DrawPlatePreview(SavedPlate plate) {
|
2021-11-19 17:55:07 +00:00
|
|
|
|
const int paddingSize = 12;
|
|
|
|
|
|
|
|
|
|
if (!ImGui.BeginTable("plate item preview", 2, ImGuiTableFlags.SizingFixedFit)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var (left, right) in LeftSide.Zip(RightSide)) {
|
|
|
|
|
ImGui.TableNextColumn();
|
2021-12-09 09:07:58 +00:00
|
|
|
|
this.DrawIcon(left, plate, IconSize, paddingSize);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
ImGui.TableNextColumn();
|
2021-12-09 09:07:58 +00:00
|
|
|
|
this.DrawIcon(right, plate, IconSize, paddingSize);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndTable();
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-21 07:17:58 +00:00
|
|
|
|
private void DrawPlateButtons(SavedPlate plate) {
|
2021-11-19 17:55:07 +00:00
|
|
|
|
if (this._editing || !ImGui.BeginTable("plate buttons", 5, ImGuiTableFlags.SizingFixedFit)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.TableNextColumn();
|
|
|
|
|
if (Util.IconButton(FontAwesomeIcon.Check, tooltip: "Apply")) {
|
2021-12-09 09:07:58 +00:00
|
|
|
|
if (!Util.IsEditingPlate(this.Ui.Plugin.GameGui)) {
|
|
|
|
|
this.AddTimedMessage("The in-game plate editor must be open.");
|
2021-12-20 01:48:28 +00:00
|
|
|
|
} else {
|
|
|
|
|
this.Ui.Plugin.Functions.LoadPlate(plate);
|
2021-12-09 09:07:58 +00:00
|
|
|
|
}
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.TableNextColumn();
|
|
|
|
|
if (Util.IconButton(FontAwesomeIcon.Search, tooltip: "Try on")) {
|
2021-11-21 07:17:58 +00:00
|
|
|
|
this.Ui.TryOn(plate.Items.Values);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.TableNextColumn();
|
|
|
|
|
if (Util.IconButton(FontAwesomeIcon.Font, tooltip: "Rename")) {
|
|
|
|
|
this._showRename ^= true;
|
|
|
|
|
this._renameInput = plate.Name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.TableNextColumn();
|
|
|
|
|
if (Util.IconButton(FontAwesomeIcon.PencilAlt, tooltip: "Edit")) {
|
|
|
|
|
this._editing = true;
|
|
|
|
|
this._editingPlate = plate.Clone();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.TableNextColumn();
|
|
|
|
|
if (Util.IconButton(FontAwesomeIcon.ShareAltSquare, tooltip: "Share")) {
|
2021-12-13 09:04:11 +00:00
|
|
|
|
ImGui.SetClipboardText(JsonConvert.SerializeObject(new SharedPlate(plate)));
|
2021-12-09 09:07:58 +00:00
|
|
|
|
this.AddTimedMessage("Copied to clipboard.");
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndTable();
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-13 09:33:15 +00:00
|
|
|
|
private void DrawPlateTags(SavedPlate plate) {
|
|
|
|
|
if (this._editing) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ImGui.CollapsingHeader($"Tags ({plate.Tags.Count})###plate-tags")) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-12-13 10:00:14 +00:00
|
|
|
|
|
2021-12-13 09:33:15 +00:00
|
|
|
|
ImGui.SetNextItemWidth(-1);
|
|
|
|
|
if (ImGui.InputTextWithHint("##tag-input", "Input a tag and press Enter", ref this._tagInput, 128, ImGuiInputTextFlags.EnterReturnsTrue)) {
|
2021-12-13 10:28:21 +00:00
|
|
|
|
if (!string.IsNullOrWhiteSpace(this._tagInput)) {
|
|
|
|
|
var tag = this._tagInput.Trim();
|
2021-12-13 10:00:14 +00:00
|
|
|
|
|
2021-12-13 10:28:21 +00:00
|
|
|
|
if (!plate.Tags.Contains(tag)) {
|
|
|
|
|
plate.Tags.Add(tag);
|
|
|
|
|
plate.Tags.Sort();
|
|
|
|
|
this.Ui.Plugin.SaveConfig();
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-13 10:29:03 +00:00
|
|
|
|
|
|
|
|
|
this._tagInput = string.Empty;
|
2021-12-13 09:33:15 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ImGui.BeginChild("tag-list")) {
|
|
|
|
|
var toRemove = -1;
|
|
|
|
|
for (var i = 0; i < plate.Tags.Count; i++) {
|
|
|
|
|
var tag = plate.Tags[i];
|
|
|
|
|
|
2021-12-14 09:30:00 +00:00
|
|
|
|
if (Util.IconButton(FontAwesomeIcon.Times, $"remove-tag-{i}")) {
|
2021-12-13 09:33:15 +00:00
|
|
|
|
toRemove = i;
|
|
|
|
|
}
|
2021-12-13 10:00:14 +00:00
|
|
|
|
|
2021-12-13 09:33:15 +00:00
|
|
|
|
ImGui.SameLine();
|
|
|
|
|
ImGui.TextUnformatted(tag);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (toRemove > -1) {
|
|
|
|
|
plate.Tags.RemoveAt(toRemove);
|
|
|
|
|
this.Ui.Plugin.SaveConfig();
|
|
|
|
|
}
|
2021-12-13 10:00:14 +00:00
|
|
|
|
|
2021-12-13 09:33:15 +00:00
|
|
|
|
ImGui.EndChild();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
private void DrawPlateDetail() {
|
2021-11-19 17:55:07 +00:00
|
|
|
|
if (!ImGui.BeginChild("plate detail")) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this._selectedPlate > -1 && this._selectedPlate < this.Ui.Plugin.Config.Plates.Count) {
|
|
|
|
|
var plate = this._editingPlate ?? this.Ui.Plugin.Config.Plates[this._selectedPlate];
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
this.DrawPlatePreview(plate);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
|
|
|
|
|
var renameWasVisible = this._showRename;
|
|
|
|
|
|
|
|
|
|
this.DrawPlateButtons(plate);
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
foreach (var (msg, _) in this._timedMessages) {
|
|
|
|
|
Util.TextUnformattedWrapped(msg);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this._showRename && Util.DrawTextInput("plate-rename", ref this._renameInput, flags: ImGuiInputTextFlags.AutoSelectAll)) {
|
|
|
|
|
plate.Name = this._renameInput;
|
|
|
|
|
this.Ui.Plugin.SaveConfig();
|
|
|
|
|
this._showRename = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this._showRename && !renameWasVisible) {
|
|
|
|
|
ImGui.SetKeyboardFocusHere();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this._editing) {
|
|
|
|
|
Util.TextUnformattedWrapped("Click an item to edit it. Right-click to dye.");
|
|
|
|
|
|
|
|
|
|
if (ImGui.Button("Save") && this._editingPlate != null) {
|
|
|
|
|
this.Ui.Plugin.Config.Plates[this._selectedPlate] = this._editingPlate;
|
|
|
|
|
this.Ui.Plugin.SaveConfig();
|
|
|
|
|
this.ResetEditing();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.SameLine();
|
|
|
|
|
|
|
|
|
|
if (ImGui.Button("Cancel")) {
|
|
|
|
|
this.ResetEditing();
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-13 09:33:15 +00:00
|
|
|
|
|
|
|
|
|
this.DrawPlateTags(plate);
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImGui.EndChild();
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
private void DrawWarnings() {
|
|
|
|
|
var warnings = new List<string>();
|
2021-11-19 17:55:07 +00:00
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
if (!this.Ui.Plugin.Functions.ArmoireLoaded) {
|
|
|
|
|
warnings.Add("The Armoire is not loaded. Open it once to enable glamours from the Armoire.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GameFunctions.DresserContents.Count == 0) {
|
|
|
|
|
warnings.Add("Glamour Dresser is empty or has not been opened. Glamaholic will not know which items you have.");
|
|
|
|
|
}
|
2021-11-19 17:55:07 +00:00
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
if (warnings.Count == 0) {
|
|
|
|
|
return;
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
2021-12-13 09:04:11 +00:00
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
ImGui.PushStyleColor(ImGuiCol.Text, ImGuiColors.DalamudYellow);
|
|
|
|
|
var header = ImGui.CollapsingHeader($"Warnings ({warnings.Count})###warnings");
|
|
|
|
|
ImGui.PopStyleColor();
|
2021-12-13 09:04:11 +00:00
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
if (!header) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < warnings.Count; i++) {
|
|
|
|
|
if (i != 0) {
|
|
|
|
|
ImGui.Separator();
|
|
|
|
|
}
|
2021-12-13 09:04:11 +00:00
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
Util.TextUnformattedWrapped(warnings[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DrawInner() {
|
|
|
|
|
this.DrawMenuBar();
|
|
|
|
|
|
|
|
|
|
this.DrawWarnings();
|
2021-11-19 17:55:07 +00:00
|
|
|
|
|
|
|
|
|
this.DrawPlateList();
|
|
|
|
|
|
|
|
|
|
ImGui.SameLine();
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
this.DrawPlateDetail();
|
2021-11-19 17:55:07 +00:00
|
|
|
|
|
|
|
|
|
ImGui.End();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void HandleTimers() {
|
2021-12-09 09:07:58 +00:00
|
|
|
|
var keys = this._timedMessages.Keys.ToArray();
|
|
|
|
|
foreach (var key in keys) {
|
|
|
|
|
if (this._timedMessages[key].Elapsed > TimeSpan.FromSeconds(5)) {
|
|
|
|
|
this._timedMessages.Remove(key);
|
|
|
|
|
}
|
2021-11-19 17:55:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-09 09:07:58 +00:00
|
|
|
|
private void AddTimedMessage(string message) {
|
|
|
|
|
var timer = new Stopwatch();
|
|
|
|
|
timer.Start();
|
|
|
|
|
this._timedMessages[message] = timer;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-19 17:55:07 +00:00
|
|
|
|
internal void SwitchPlate(int idx, bool scrollTo = false) {
|
|
|
|
|
this._selectedPlate = idx;
|
|
|
|
|
this._scrollToSelected = scrollTo;
|
|
|
|
|
this._renameInput = string.Empty;
|
|
|
|
|
this._showRename = false;
|
|
|
|
|
this._deleteConfirm = false;
|
2021-12-09 09:07:58 +00:00
|
|
|
|
this._timedMessages.Clear();
|
2021-11-19 17:55:07 +00:00
|
|
|
|
this.ResetEditing();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ResetEditing() {
|
|
|
|
|
this._editing = false;
|
|
|
|
|
this._editingPlate = null;
|
|
|
|
|
this._itemFilter = string.Empty;
|
|
|
|
|
this._dyeFilter = string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void FilterItems(PlateSlot slot) {
|
|
|
|
|
var filter = this._itemFilter.ToLowerInvariant();
|
2021-12-09 09:07:58 +00:00
|
|
|
|
|
|
|
|
|
IEnumerable<Item> items;
|
|
|
|
|
if (GameFunctions.DresserContents.Count > 0 && this.Ui.Plugin.Config.ItemFilterShowObtainedOnly) {
|
|
|
|
|
var sheet = this.Ui.Plugin.DataManager.GetExcelSheet<Item>()!;
|
|
|
|
|
items = GameFunctions.DresserContents
|
|
|
|
|
.Select(item => sheet.GetRow(item.ItemId))
|
|
|
|
|
.Where(item => item != null)
|
|
|
|
|
.Cast<Item>();
|
|
|
|
|
} else {
|
|
|
|
|
items = this.Items;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.FilteredItems = items
|
2021-11-23 04:23:37 +00:00
|
|
|
|
.Where(item => !Util.IsItemSkipped(item))
|
2021-11-19 17:55:07 +00:00
|
|
|
|
.Where(item => Util.MatchesSlot(item.EquipSlotCategory.Value!, slot))
|
|
|
|
|
.Where(item => this._itemFilter.Length == 0 || item.Name.RawString.ToLowerInvariant().Contains(filter))
|
|
|
|
|
.ToList();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|