feat: new item search window

This commit is contained in:
goat 2020-04-14 22:21:33 +02:00
parent 8e6d2a841a
commit 6567eb7c80
2 changed files with 200 additions and 32 deletions

View file

@ -320,6 +320,17 @@ namespace Dalamud {
this.isImguiDrawPluginWindow = this.pluginWindow != null && this.pluginWindow.Draw();
}
if (this.isImguiDrawItemSearchWindow)
{
this.isImguiDrawItemSearchWindow = this.itemSearchCommandWindow != null && this.itemSearchCommandWindow.Draw();
if (this.isImguiDrawItemSearchWindow == false)
{
this.itemSearchCommandWindow?.Dispose();
this.itemSearchCommandWindow = null;
}
}
if (this.isImguiDrawCreditsWindow)
{
this.isImguiDrawCreditsWindow = this.creditsWindow != null && this.creditsWindow.Draw();
@ -519,43 +530,31 @@ namespace Dalamud {
Framework.Gui.SetBgm(ushort.Parse(arguments));
}
private ItemSearchWindow itemSearchCommandWindow;
private bool isImguiDrawItemSearchWindow;
private void OnItemLinkCommand(string command, string arguments) {
var exactSearch = false;
if (arguments.StartsWith("+"))
{
exactSearch = true;
arguments = arguments.Substring(1);
}
this.itemSearchCommandWindow = new ItemSearchWindow(this.Data, new UiBuilder(this.InterfaceManager, "ItemSearcher"));
this.itemSearchCommandWindow.OnItemChosen += (sender, item) => {
var hexData = new byte[] {
0x02, 0x13, 0x06, 0xFE, 0xFF, 0xF3, 0xF3, 0xF3, 0x03, 0x02, 0x27, 0x07, 0x03, 0xF2, 0x3A, 0x2F,
0x02, 0x01, 0x03, 0x02, 0x13, 0x06, 0xFE, 0xFF, 0xFF, 0x7B, 0x1A, 0x03, 0xEE, 0x82, 0xBB, 0x02,
0x13, 0x02, 0xEC, 0x03
};
Task.Run(async () => {
try {
dynamic results = await XivApi.Search(arguments, "Item", 1, exactSearch);
var itemId = (short) results.Results[0].ID;
var itemName = (string)results.Results[0].Name;
var endTag = new byte[] {
0x02, 0x27, 0x07, 0xCF, 0x01, 0x01, 0x01, 0xFF, 0x01, 0x03, 0x02, 0x13, 0x02, 0xEC, 0x03
};
var hexData = new byte[] {
0x02, 0x13, 0x06, 0xFE, 0xFF, 0xF3, 0xF3, 0xF3, 0x03, 0x02, 0x27, 0x07, 0x03, 0xF2, 0x3A, 0x2F,
0x02, 0x01, 0x03, 0x02, 0x13, 0x06, 0xFE, 0xFF, 0xFF, 0x7B, 0x1A, 0x03, 0xEE, 0x82, 0xBB, 0x02,
0x13, 0x02, 0xEC, 0x03
};
BitConverter.GetBytes((short) item.RowId).Reverse().ToArray().CopyTo(hexData, 14);
var endTag = new byte[] {
0x02, 0x27, 0x07, 0xCF, 0x01, 0x01, 0x01, 0xFF, 0x01, 0x03, 0x02, 0x13, 0x02, 0xEC, 0x03
};
hexData = hexData.Concat(Encoding.UTF8.GetBytes(item.Name)).Concat(endTag).ToArray();
BitConverter.GetBytes(itemId).Reverse().ToArray().CopyTo(hexData, 14);
hexData = hexData.Concat(Encoding.UTF8.GetBytes(itemName)).Concat(endTag).ToArray();
Framework.Gui.Chat.PrintChat(new XivChatEntry {
MessageBytes = hexData
});
}
catch {
Framework.Gui.Chat.PrintError(Loc.Localize("DalamudItemNotFound", "Could not find item."));
}
});
this.Framework.Gui.Chat.PrintChat(new XivChatEntry {
MessageBytes = hexData
});
};
this.isImguiDrawItemSearchWindow = true;
}
#if DEBUG

View file

@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Linq;
using System.Net.Mime;
using System.Numerics;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CheapLoc;
using Dalamud.Data;
using Dalamud.Data.LuminaExtensions;
using Dalamud.Game.ClientState.Actors.Types;
using Dalamud.Game.ClientState.Actors.Types.NonPlayer;
using ImGuiNET;
using ImGuiScene;
using Lumina.Excel.GeneratedSheets;
using Serilog;
using Item = Dalamud.Data.TransientSheet.Item;
namespace Dalamud.Interface
{
class ItemSearchWindow : IDisposable
{
private readonly DataManager data;
private readonly UiBuilder builder;
private string lastSearchText = string.Empty;
private string searchText = string.Empty;
private int lastKind = 0;
private int currentKind = 0;
private int selectedItemIndex = -1;
private TextureWrap selectedItemTex;
private CancellationTokenSource searchCancelTokenSource;
private ValueTask<List<Item>> searchTask;
private List<Item> luminaItems;
public event EventHandler<Item> OnItemChosen;
public ItemSearchWindow(DataManager data, UiBuilder builder) {
this.data = data;
this.builder = builder;
while (!data.IsDataReady)
Thread.Sleep(1);
this.luminaItems = this.data.GetExcelSheet<Item>().GetRows();
}
public bool Draw() {
ImGui.SetNextWindowSize(new Vector2(500, 500), ImGuiCond.FirstUseEver);
var isOpen = true;
if (!ImGui.Begin(Loc.Localize("DalamudItemSelectHeader", "Select an item"), ref isOpen, ImGuiWindowFlags.NoCollapse))
{
ImGui.End();
return false;
}
// Main window
ImGui.AlignTextToFramePadding();
ImGui.Text(Loc.Localize("DalamudItemSelect", "Please select an item."));
if (this.selectedItemTex != null) {
ImGui.Text(" ");
ImGui.SetCursorPosY(200f);
ImGui.SameLine();
ImGui.Image(this.selectedItemTex.ImGuiHandle, new Vector2(40, 40));
} else {
ImGui.Text(" ");
}
ImGui.Separator();
ImGui.Text("Search: ");
ImGui.SameLine();
ImGui.InputText("##searchbox", ref this.searchText, 32);
var kinds = new List<string> {Loc.Localize("DalamudItemSelectAll", "All")};
kinds.AddRange(this.data.GetExcelSheet<ItemSearchCategory>().GetRows().Where(x => !string.IsNullOrEmpty(x.Name)).Select(x => x.Name));
ImGui.Text(Loc.Localize("DalamudItemSelectCategory", "Category: "));
ImGui.SameLine();
ImGui.Combo("##kindbox", ref this.currentKind, kinds.ToArray(),
kinds.Count);
var windowSize = ImGui.GetWindowSize();
ImGui.BeginChild("scrolling", new Vector2(0, windowSize.Y - ImGui.GetCursorPosY() - 40), true, ImGuiWindowFlags.HorizontalScrollbar);
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0));
if (!string.IsNullOrEmpty(this.searchText) || this.currentKind != 0) {
if (this.lastSearchText != this.searchText || this.lastKind != this.currentKind) {
this.lastSearchText = this.searchText;
this.lastKind = this.currentKind;
this.searchCancelTokenSource?.Cancel();
this.searchCancelTokenSource = new CancellationTokenSource();
var asyncEnum = this.luminaItems.ToAsyncEnumerable();
if (!string.IsNullOrEmpty(this.searchText)) {
Log.Debug("Searching for " + this.searchText);
asyncEnum = asyncEnum.Where(
x => (x.Name.ToLower().Contains(this.searchText.ToLower()) ||
int.TryParse(this.searchText, out var parsedId) &&
parsedId == x.RowId));
}
if (this.currentKind != 0) {
Log.Debug("Searching for C" + this.currentKind);
asyncEnum = asyncEnum.Where(x => x.ItemSearchCategory == this.currentKind);
}
this.selectedItemIndex = -1;
this.selectedItemTex?.Dispose();
this.selectedItemTex = null;
this.searchTask = asyncEnum.ToListAsync(this.searchCancelTokenSource.Token);
}
if (this.searchTask.IsCompletedSuccessfully) {
for (var i = 0; i < this.searchTask.Result.Count; i++) {
if (ImGui.Selectable(this.searchTask.Result[i].Name, this.selectedItemIndex == i)) {
this.selectedItemIndex = i;
var iconTex = this.data.GetIcon(this.searchTask.Result[i].Icon);
this.selectedItemTex?.Dispose();
this.selectedItemTex =
this.builder.LoadImageRaw(iconTex.GetRgbaImageData(), iconTex.Header.Width,
iconTex.Header.Height, 4);
}
}
}
} else {
ImGui.TextColored(new Vector4(0.86f, 0.86f, 0.86f, 1.00f), Loc.Localize("DalamudItemSelectHint", "Type to start searching..."));
this.selectedItemIndex = -1;
this.selectedItemTex?.Dispose();
this.selectedItemTex = null;
}
ImGui.PopStyleVar();
ImGui.EndChild();
if (ImGui.Button(Loc.Localize("Choose", "Choose"))) {
OnItemChosen?.Invoke(this, this.searchTask.Result[this.selectedItemIndex]);
this.selectedItemTex?.Dispose();
isOpen = false;
}
ImGui.End();
return isOpen;
}
public void Dispose() {
this.selectedItemTex?.Dispose();
}
}
}