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:
N. Lo.
2025-01-13 21:50:06 +01:00
committed by GitHub
parent 0646ffd351
commit 02cd6d3c10
2 changed files with 62 additions and 5 deletions

View File

@@ -709,8 +709,8 @@ internal sealed partial class CharaDataHubUi
{ {
using (ImRaii.Group()) using (ImRaii.Group())
{ {
ImGui.SetNextItemWidth(200); InputComboHybrid("##AliasToAdd", "##AliasToAddPicker", ref _specificIndividualAdd, _pairManager.PairsWithGroups.Keys,
ImGui.InputText("##AliasToAdd", ref _specificIndividualAdd, 20); static pair => (pair.UserData.UID, pair.UserData.Alias, pair.UserData.AliasOrUID, pair.GetNote()));
ImGui.SameLine(); ImGui.SameLine();
using (ImRaii.Disabled(string.IsNullOrEmpty(_specificIndividualAdd) using (ImRaii.Disabled(string.IsNullOrEmpty(_specificIndividualAdd)
|| updateDto.UserList.Any(f => string.Equals(f.UID, _specificIndividualAdd, StringComparison.Ordinal) || string.Equals(f.Alias, _specificIndividualAdd, StringComparison.Ordinal)))) || 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()) using (ImRaii.Group())
{ {
ImGui.SetNextItemWidth(200); InputComboHybrid("##GroupAliasToAdd", "##GroupAliasToAddPicker", ref _specificGroupAdd, _pairManager.Groups.Keys,
ImGui.InputText("##GroupAliasToAdd", ref _specificGroupAdd, 20); group => (group.GID, group.Alias, group.AliasOrGID, _serverConfigurationManager.GetNoteForGid(group.GID)));
ImGui.SameLine(); ImGui.SameLine();
using (ImRaii.Disabled(string.IsNullOrEmpty(_specificGroupAdd) using (ImRaii.Disabled(string.IsNullOrEmpty(_specificGroupAdd)
|| updateDto.GroupList.Any(f => string.Equals(f.GID, _specificGroupAdd, StringComparison.Ordinal) || string.Equals(f.Alias, _specificGroupAdd, StringComparison.Ordinal)))) || 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); 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;
}
}
}
} }

View File

@@ -7,6 +7,7 @@ using ImGuiNET;
using MareSynchronos.API.Dto.CharaData; using MareSynchronos.API.Dto.CharaData;
using MareSynchronos.MareConfiguration; using MareSynchronos.MareConfiguration;
using MareSynchronos.MareConfiguration.Models; using MareSynchronos.MareConfiguration.Models;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.Services; using MareSynchronos.Services;
using MareSynchronos.Services.CharaData.Models; using MareSynchronos.Services.CharaData.Models;
using MareSynchronos.Services.Mediator; using MareSynchronos.Services.Mediator;
@@ -24,6 +25,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
private readonly CharaDataConfigService _configService; private readonly CharaDataConfigService _configService;
private readonly DalamudUtilService _dalamudUtilService; private readonly DalamudUtilService _dalamudUtilService;
private readonly FileDialogManager _fileDialogManager; private readonly FileDialogManager _fileDialogManager;
private readonly PairManager _pairManager;
private readonly ServerConfigurationManager _serverConfigurationManager; private readonly ServerConfigurationManager _serverConfigurationManager;
private readonly UiSharedService _uiSharedService; private readonly UiSharedService _uiSharedService;
private CancellationTokenSource _closalCts = new(); private CancellationTokenSource _closalCts = new();
@@ -53,11 +55,14 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
private string _specificIndividualAdd = string.Empty; private string _specificIndividualAdd = string.Empty;
private string _specificGroupAdd = string.Empty; private string _specificGroupAdd = string.Empty;
private bool _abbreviateCharaName = false; 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, public CharaDataHubUi(ILogger<CharaDataHubUi> logger, MareMediator mediator, PerformanceCollectorService performanceCollectorService,
CharaDataManager charaDataManager, CharaDataNearbyManager charaDataNearbyManager, CharaDataConfigService configService, CharaDataManager charaDataManager, CharaDataNearbyManager charaDataNearbyManager, CharaDataConfigService configService,
UiSharedService uiSharedService, ServerConfigurationManager serverConfigurationManager, UiSharedService uiSharedService, ServerConfigurationManager serverConfigurationManager,
DalamudUtilService dalamudUtilService, FileDialogManager fileDialogManager) DalamudUtilService dalamudUtilService, FileDialogManager fileDialogManager, PairManager pairManager)
: base(logger, mediator, "Mare Synchronos Character Data Hub###MareSynchronosCharaDataUI", performanceCollectorService) : base(logger, mediator, "Mare Synchronos Character Data Hub###MareSynchronosCharaDataUI", performanceCollectorService)
{ {
SetWindowSizeConstraints(); SetWindowSizeConstraints();
@@ -69,6 +74,7 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
_serverConfigurationManager = serverConfigurationManager; _serverConfigurationManager = serverConfigurationManager;
_dalamudUtilService = dalamudUtilService; _dalamudUtilService = dalamudUtilService;
_fileDialogManager = fileDialogManager; _fileDialogManager = fileDialogManager;
_pairManager = pairManager;
Mediator.Subscribe<GposeStartMessage>(this, (_) => IsOpen |= _configService.Current.OpenMareHubOnGposeStart); Mediator.Subscribe<GposeStartMessage>(this, (_) => IsOpen |= _configService.Current.OpenMareHubOnGposeStart);
} }
@@ -97,6 +103,8 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
_sharedWithYouOwnerFilter = string.Empty; _sharedWithYouOwnerFilter = string.Empty;
_importCode = string.Empty; _importCode = string.Empty;
_charaDataNearbyManager.ComputeNearbyData = false; _charaDataNearbyManager.ComputeNearbyData = false;
_openComboHybridId = null;
_openComboHybridEntries = null;
} }
public override void OnOpen() public override void OnOpen()
@@ -117,6 +125,13 @@ internal sealed partial class CharaDataHubUi : WindowMediatorSubscriberBase
protected override void DrawInternal() protected override void DrawInternal()
{ {
if (!_comboHybridUsedLastFrame)
{
_openComboHybridId = null;
_openComboHybridEntries = null;
}
_comboHybridUsedLastFrame = false;
_disableUI = !(_charaDataManager.UiBlockingComputation?.IsCompleted ?? true); _disableUI = !(_charaDataManager.UiBlockingComputation?.IsCompleted ?? true);
if (DateTime.UtcNow.Subtract(_lastFavoriteUpdateTime).TotalSeconds > 2) if (DateTime.UtcNow.Subtract(_lastFavoriteUpdateTime).TotalSeconds > 2)
{ {