qstbak/Questionable/Questionable.Windows.Utils/QuestSelector.cs
2025-12-24 05:01:16 +10:00

86 lines
2.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface.Utility.Raii;
using Questionable.Controller;
using Questionable.Model;
using Questionable.Model.Questing;
namespace Questionable.Windows.Utils;
internal sealed class QuestSelector(QuestRegistry questRegistry)
{
private string _searchString = string.Empty;
private bool _comboJustOpened;
public Predicate<Quest>? SuggestionPredicate { private get; set; }
public Predicate<Quest>? DefaultPredicate { private get; set; }
public Action<Quest>? QuestSelected { private get; set; }
public void DrawSelection()
{
if (QuestSelected == null)
{
throw new InvalidOperationException("QuestSelected action must be set before drawing the quest selector.");
}
ImGui.SetNextItemWidth(ImGui.GetContentRegionAvail().X);
if (ImGui.BeginCombo("##QuestSelection", "Add Quest...", ImGuiComboFlags.HeightLarge))
{
if (!_comboJustOpened)
{
ImGui.SetKeyboardFocusHere();
_comboJustOpened = true;
}
ImGui.SetNextItemWidth(-1f);
bool flag = ImGui.InputTextWithHint("##QuestSearch", "Search quests...", ref _searchString, 256, ImGuiInputTextFlags.AutoSelectAll | ImGuiInputTextFlags.EnterReturnsTrue);
ImGui.Separator();
IEnumerable<Quest> enumerable;
if (!string.IsNullOrEmpty(_searchString))
{
enumerable = Enumerable.Where(predicate: (!ElementId.TryFromString(_searchString, out ElementId elementId)) ? new Func<Quest, bool>(SearchPredicate) : ((Func<Quest, bool>)((Quest x) => SearchPredicate(x) || x.Id == elementId)), source: questRegistry.AllQuests.Where(delegate(Quest x)
{
ElementId id = x.Id;
return !(id is SatisfactionSupplyNpcId) && !(id is AlliedSocietyDailyId);
}));
}
else
{
enumerable = questRegistry.AllQuests.Where((Quest x) => DefaultPredicate?.Invoke(x) ?? true);
}
using (ImRaii.IEndObject endObject = ImRaii.Child("##QuestScrollArea", new Vector2(0f, 300f), border: false))
{
if (endObject)
{
foreach (Quest item in enumerable)
{
if ((SuggestionPredicate == null || SuggestionPredicate(item)) && (ImGui.Selectable(item.Info.Name) || flag))
{
QuestSelected(item);
_searchString = string.Empty;
if (flag)
{
ImGui.CloseCurrentPopup();
flag = false;
}
}
}
}
}
ImGui.EndCombo();
}
else
{
_comboJustOpened = false;
}
ImGui.Spacing();
bool SearchPredicate(Quest x)
{
return x.Info.Name.Contains(_searchString, StringComparison.CurrentCultureIgnoreCase);
}
}
}