Use InputText/Combo hybrids for MCDO ACLs (#81)
* Use InputText/Combo hybrids for MCDO ACLs * Hybrid combo factoring, filtering, ordering, caching
This commit is contained in:
@@ -709,8 +709,8 @@ internal sealed partial class CharaDataHubUi
|
||||
{
|
||||
using (ImRaii.Group())
|
||||
{
|
||||
ImGui.SetNextItemWidth(200);
|
||||
ImGui.InputText("##AliasToAdd", ref _specificIndividualAdd, 20);
|
||||
InputComboHybrid("##AliasToAdd", "##AliasToAddPicker", ref _specificIndividualAdd, _pairManager.PairsWithGroups.Keys,
|
||||
static pair => (pair.UserData.UID, pair.UserData.Alias, pair.UserData.AliasOrUID, pair.GetNote()));
|
||||
ImGui.SameLine();
|
||||
using (ImRaii.Disabled(string.IsNullOrEmpty(_specificIndividualAdd)
|
||||
|| updateDto.UserList.Any(f => string.Equals(f.UID, _specificIndividualAdd, StringComparison.Ordinal) || string.Equals(f.Alias, _specificIndividualAdd, StringComparison.Ordinal))))
|
||||
@@ -756,8 +756,8 @@ internal sealed partial class CharaDataHubUi
|
||||
{
|
||||
using (ImRaii.Group())
|
||||
{
|
||||
ImGui.SetNextItemWidth(200);
|
||||
ImGui.InputText("##GroupAliasToAdd", ref _specificGroupAdd, 20);
|
||||
InputComboHybrid("##GroupAliasToAdd", "##GroupAliasToAddPicker", ref _specificGroupAdd, _pairManager.Groups.Keys,
|
||||
group => (group.GID, group.Alias, group.AliasOrGID, _serverConfigurationManager.GetNoteForGid(group.GID)));
|
||||
ImGui.SameLine();
|
||||
using (ImRaii.Disabled(string.IsNullOrEmpty(_specificGroupAdd)
|
||||
|| updateDto.GroupList.Any(f => string.Equals(f.GID, _specificGroupAdd, StringComparison.Ordinal) || string.Equals(f.Alias, _specificGroupAdd, StringComparison.Ordinal))))
|
||||
@@ -800,4 +800,46 @@ internal sealed partial class CharaDataHubUi
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
});
|
||||
}
|
||||
|
||||
private void InputComboHybrid<T>(string inputId, string comboId, ref string value, IEnumerable<T> comboEntries,
|
||||
Func<T, (string Id, string? Alias, string AliasOrId, string? Note)> parseEntry)
|
||||
{
|
||||
const float ComponentWidth = 200;
|
||||
ImGui.SetNextItemWidth(ComponentWidth - ImGui.GetFrameHeight());
|
||||
ImGui.InputText(inputId, ref value, 20);
|
||||
ImGui.SameLine(0.0f, 0.0f);
|
||||
|
||||
using var combo = ImRaii.Combo(comboId, string.Empty, ImGuiComboFlags.NoPreview | ImGuiComboFlags.PopupAlignLeft);
|
||||
if (!combo)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_openComboHybridEntries is null || !string.Equals(_openComboHybridId, comboId, StringComparison.Ordinal))
|
||||
{
|
||||
var valueSnapshot = value;
|
||||
_openComboHybridEntries = comboEntries
|
||||
.Select(parseEntry)
|
||||
.Where(entry => entry.Id.Contains(valueSnapshot, StringComparison.OrdinalIgnoreCase)
|
||||
|| (entry.Alias is not null && entry.Alias.Contains(valueSnapshot, StringComparison.OrdinalIgnoreCase))
|
||||
|| (entry.Note is not null && entry.Note.Contains(valueSnapshot, StringComparison.OrdinalIgnoreCase)))
|
||||
.OrderBy(entry => entry.Note is null ? entry.AliasOrId : $"{entry.Note} ({entry.AliasOrId})", StringComparer.OrdinalIgnoreCase)
|
||||
.ToArray();
|
||||
_openComboHybridId = comboId;
|
||||
}
|
||||
_comboHybridUsedLastFrame = true;
|
||||
|
||||
// Is there a better way to handle this?
|
||||
var width = ComponentWidth - 2 * ImGui.GetStyle().FramePadding.X - (_openComboHybridEntries.Length > 8 ? ImGui.GetStyle().ScrollbarSize : 0);
|
||||
foreach (var (id, alias, aliasOrId, note) in _openComboHybridEntries)
|
||||
{
|
||||
var selected = !string.IsNullOrEmpty(value)
|
||||
&& (string.Equals(id, value, StringComparison.Ordinal) || string.Equals(alias, value, StringComparison.Ordinal));
|
||||
using var font = ImRaii.PushFont(UiBuilder.MonoFont, note is null);
|
||||
if (ImGui.Selectable(note is null ? aliasOrId : $"{note} ({aliasOrId})", selected, ImGuiSelectableFlags.None, new(width, 0)))
|
||||
{
|
||||
value = aliasOrId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ using ImGuiNET;
|
||||
using MareSynchronos.API.Dto.CharaData;
|
||||
using MareSynchronos.MareConfiguration;
|
||||
using MareSynchronos.MareConfiguration.Models;
|
||||
using MareSynchronos.PlayerData.Pairs;
|
||||
using MareSynchronos.Services;
|
||||
using MareSynchronos.Services.CharaData.Models;
|
||||
using MareSynchronos.Services.Mediator;
|
||||
@@ -24,6 +25,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
|
||||
private readonly CharaDataConfigService _configService;
|
||||
private readonly DalamudUtilService _dalamudUtilService;
|
||||
private readonly FileDialogManager _fileDialogManager;
|
||||
private readonly PairManager _pairManager;
|
||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||
private readonly UiSharedService _uiSharedService;
|
||||
private CancellationTokenSource _closalCts = new();
|
||||
@@ -53,11 +55,14 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
|
||||
private string _specificIndividualAdd = string.Empty;
|
||||
private string _specificGroupAdd = string.Empty;
|
||||
private bool _abbreviateCharaName = false;
|
||||
private string? _openComboHybridId = null;
|
||||
private (string Id, string? Alias, string AliasOrId, string? Note)[]? _openComboHybridEntries = null;
|
||||
private bool _comboHybridUsedLastFrame = false;
|
||||
|
||||
public CharaDataHubUi(ILogger<CharaDataHubUi> logger, MareMediator mediator, PerformanceCollectorService performanceCollectorService,
|
||||
CharaDataManager charaDataManager, CharaDataNearbyManager charaDataNearbyManager, CharaDataConfigService configService,
|
||||
UiSharedService uiSharedService, ServerConfigurationManager serverConfigurationManager,
|
||||
DalamudUtilService dalamudUtilService, FileDialogManager fileDialogManager)
|
||||
DalamudUtilService dalamudUtilService, FileDialogManager fileDialogManager, PairManager pairManager)
|
||||
: base(logger, mediator, "Mare Synchronos Character Data Hub###MareSynchronosCharaDataUI", performanceCollectorService)
|
||||
{
|
||||
SetWindowSizeConstraints();
|
||||
@@ -69,6 +74,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
|
||||
_serverConfigurationManager = serverConfigurationManager;
|
||||
_dalamudUtilService = dalamudUtilService;
|
||||
_fileDialogManager = fileDialogManager;
|
||||
_pairManager = pairManager;
|
||||
Mediator.Subscribe<GposeStartMessage>(this, (_) => IsOpen |= _configService.Current.OpenMareHubOnGposeStart);
|
||||
}
|
||||
|
||||
@@ -97,6 +103,8 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
|
||||
_sharedWithYouOwnerFilter = string.Empty;
|
||||
_importCode = string.Empty;
|
||||
_charaDataNearbyManager.ComputeNearbyData = false;
|
||||
_openComboHybridId = null;
|
||||
_openComboHybridEntries = null;
|
||||
}
|
||||
|
||||
public override void OnOpen()
|
||||
@@ -117,6 +125,13 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
|
||||
|
||||
protected override void DrawInternal()
|
||||
{
|
||||
if (!_comboHybridUsedLastFrame)
|
||||
{
|
||||
_openComboHybridId = null;
|
||||
_openComboHybridEntries = null;
|
||||
}
|
||||
_comboHybridUsedLastFrame = false;
|
||||
|
||||
_disableUI = !(_charaDataManager.UiBlockingComputation?.IsCompleted ?? true);
|
||||
if (DateTime.UtcNow.Subtract(_lastFavoriteUpdateTime).TotalSeconds > 2)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user