add mcdo creation filters, upload all, apply data to all, more scaling bullshit
This commit is contained in:
@@ -608,6 +608,18 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase
|
|||||||
return _metaInfoCache.TryGetValue(key, out metaInfo);
|
return _metaInfoCache.TryGetValue(key, out metaInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UploadAllCharaData()
|
||||||
|
{
|
||||||
|
UiBlockingComputation = Task.Run(async () =>
|
||||||
|
{
|
||||||
|
foreach (var updateDto in _updateDtos.Values.Where(u => u.HasChanges))
|
||||||
|
{
|
||||||
|
CharaUpdateTask = CharaUpdateAsync(updateDto);
|
||||||
|
await CharaUpdateTask.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public void UploadCharaData(string id)
|
public void UploadCharaData(string id)
|
||||||
{
|
{
|
||||||
var hasUpdateDto = _updateDtos.TryGetValue(id, out var updateDto);
|
var hasUpdateDto = _updateDtos.TryGetValue(id, out var updateDto);
|
||||||
@@ -903,7 +915,6 @@ public sealed partial class CharaDataManager : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
var res = await _apiController.CharaDataUpdate(baseUpdateDto).ConfigureAwait(false);
|
var res = await _apiController.CharaDataUpdate(baseUpdateDto).ConfigureAwait(false);
|
||||||
await AddOrUpdateDto(res).ConfigureAwait(false);
|
await AddOrUpdateDto(res).ConfigureAwait(false);
|
||||||
CharaUpdateTask = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DownloadAndAplyDataAsync(string charaName, CharaDataDownloadDto charaDataDownloadDto, CharaDataMetaInfoDto metaInfo, bool autoRevert = true)
|
private async Task DownloadAndAplyDataAsync(string charaName, CharaDataDownloadDto charaDataDownloadDto, CharaDataMetaInfoDto metaInfo, bool autoRevert = true)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ internal sealed partial class CharaDataHubUi
|
|||||||
_charaDataGposeTogetherManager.CreateNewLobby();
|
_charaDataGposeTogetherManager.CreateNewLobby();
|
||||||
}
|
}
|
||||||
ImGuiHelpers.ScaledDummy(5);
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
ImGui.SetNextItemWidth(250);
|
UiSharedService.ScaledNextItemWidth(250);
|
||||||
ImGui.InputTextWithHint("##lobbyId", "GPose Lobby Id", ref _joinLobbyId, 30);
|
ImGui.InputTextWithHint("##lobbyId", "GPose Lobby Id", ref _joinLobbyId, 30);
|
||||||
if (_uiSharedService.IconTextButton(FontAwesomeIcon.ArrowRight, "Join GPose Together Lobby"))
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.ArrowRight, "Join GPose Together Lobby"))
|
||||||
{
|
{
|
||||||
@@ -187,7 +187,7 @@ internal sealed partial class CharaDataHubUi
|
|||||||
|
|
||||||
using (ImRaii.Disabled(!_uiSharedService.IsInGpose))
|
using (ImRaii.Disabled(!_uiSharedService.IsInGpose))
|
||||||
{
|
{
|
||||||
ImGui.SetNextItemWidth(200);
|
UiSharedService.ScaledNextItemWidth(200);
|
||||||
using (var combo = ImRaii.Combo("##character", string.IsNullOrEmpty(user.AssociatedCharaName) ? "No character assigned" : CharaName(user.AssociatedCharaName)))
|
using (var combo = ImRaii.Combo("##character", string.IsNullOrEmpty(user.AssociatedCharaName) ? "No character assigned" : CharaName(user.AssociatedCharaName)))
|
||||||
{
|
{
|
||||||
if (combo)
|
if (combo)
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ namespace MareSynchronos.UI;
|
|||||||
|
|
||||||
internal sealed partial class CharaDataHubUi
|
internal sealed partial class CharaDataHubUi
|
||||||
{
|
{
|
||||||
|
private string _createDescFilter = string.Empty;
|
||||||
|
private string _createCodeFilter = string.Empty;
|
||||||
|
private bool _createOnlyShowFav = false;
|
||||||
|
private bool _createOnlyShowNotDownloadable = false;
|
||||||
|
|
||||||
private void DrawEditCharaData(CharaDataFullExtendedDto? dataDto)
|
private void DrawEditCharaData(CharaDataFullExtendedDto? dataDto)
|
||||||
{
|
{
|
||||||
using var imguiid = ImRaii.PushId(dataDto?.Id ?? "NoData");
|
using var imguiid = ImRaii.PushId(dataDto?.Id ?? "NoData");
|
||||||
@@ -30,8 +35,17 @@ internal sealed partial class CharaDataHubUi
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int otherUpdates = 0;
|
||||||
|
foreach (var item in _charaDataManager.OwnCharaData.Values.Where(v => !string.Equals(v.Id, dataDto.Id, StringComparison.Ordinal)))
|
||||||
|
{
|
||||||
|
if (_charaDataManager.GetUpdateDto(item.Id)?.HasChanges ?? false)
|
||||||
|
{
|
||||||
|
otherUpdates++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool canUpdate = updateDto.HasChanges;
|
bool canUpdate = updateDto.HasChanges;
|
||||||
if (canUpdate || _charaDataManager.CharaUpdateTask != null)
|
if (canUpdate || otherUpdates > 0 || (!_charaDataManager.CharaUpdateTask?.IsCompleted ?? false))
|
||||||
{
|
{
|
||||||
ImGuiHelpers.ScaledDummy(5);
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
}
|
}
|
||||||
@@ -91,9 +105,27 @@ internal sealed partial class CharaDataHubUi
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (otherUpdates > 0)
|
||||||
|
{
|
||||||
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
|
UiSharedService.DrawGrouped(() =>
|
||||||
|
{
|
||||||
|
ImGui.AlignTextToFramePadding();
|
||||||
|
UiSharedService.ColorTextWrapped($"You have {otherUpdates} other entries with unsaved changes.", ImGuiColors.DalamudYellow);
|
||||||
|
ImGui.SameLine();
|
||||||
|
using (ImRaii.Disabled(_charaDataManager.CharaUpdateTask != null && !_charaDataManager.CharaUpdateTask.IsCompleted))
|
||||||
|
{
|
||||||
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.ArrowAltCircleUp, "Save all to server"))
|
||||||
|
{
|
||||||
|
_charaDataManager.UploadAllCharaData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
indent.Dispose();
|
indent.Dispose();
|
||||||
|
|
||||||
if (canUpdate || _charaDataManager.CharaUpdateTask != null)
|
if (canUpdate || otherUpdates > 0 || (!_charaDataManager.CharaUpdateTask?.IsCompleted ?? false))
|
||||||
{
|
{
|
||||||
ImGuiHelpers.ScaledDummy(5);
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
}
|
}
|
||||||
@@ -550,7 +582,7 @@ internal sealed partial class CharaDataHubUi
|
|||||||
}
|
}
|
||||||
|
|
||||||
using (var table = ImRaii.Table("Own Character Data", 12, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollY,
|
using (var table = ImRaii.Table("Own Character Data", 12, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollY,
|
||||||
new Vector2(ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X, 110 * ImGuiHelpers.GlobalScale)))
|
new Vector2(ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X, 140 * ImGuiHelpers.GlobalScale)))
|
||||||
{
|
{
|
||||||
if (table)
|
if (table)
|
||||||
{
|
{
|
||||||
@@ -566,9 +598,64 @@ internal sealed partial class CharaDataHubUi
|
|||||||
ImGui.TableSetupColumn("Glamourer", ImGuiTableColumnFlags.WidthFixed, 18 * ImGuiHelpers.GlobalScale);
|
ImGui.TableSetupColumn("Glamourer", ImGuiTableColumnFlags.WidthFixed, 18 * ImGuiHelpers.GlobalScale);
|
||||||
ImGui.TableSetupColumn("Customize+", ImGuiTableColumnFlags.WidthFixed, 18 * ImGuiHelpers.GlobalScale);
|
ImGui.TableSetupColumn("Customize+", ImGuiTableColumnFlags.WidthFixed, 18 * ImGuiHelpers.GlobalScale);
|
||||||
ImGui.TableSetupColumn("Expires", ImGuiTableColumnFlags.WidthFixed, 18 * ImGuiHelpers.GlobalScale);
|
ImGui.TableSetupColumn("Expires", ImGuiTableColumnFlags.WidthFixed, 18 * ImGuiHelpers.GlobalScale);
|
||||||
ImGui.TableSetupScrollFreeze(0, 1);
|
ImGui.TableSetupScrollFreeze(0, 2);
|
||||||
ImGui.TableHeadersRow();
|
ImGui.TableHeadersRow();
|
||||||
foreach (var entry in _charaDataManager.OwnCharaData.Values.OrderBy(b => b.CreatedDate))
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Dummy(new(0, 0));
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Checkbox("###createOnlyShowfav", ref _createOnlyShowFav);
|
||||||
|
UiSharedService.AttachToolTip("Filter by favorites");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
var x1 = ImGui.GetContentRegionAvail().X;
|
||||||
|
ImGui.SetNextItemWidth(x1);
|
||||||
|
ImGui.InputTextWithHint("###createFilterCode", "Filter by code", ref _createCodeFilter, 200);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
var x2 = ImGui.GetContentRegionAvail().X;
|
||||||
|
ImGui.SetNextItemWidth(x2);
|
||||||
|
ImGui.InputTextWithHint("###createFilterDesc", "Filter by description", ref _createDescFilter, 200);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Dummy(new(0, 0));
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Dummy(new(0, 0));
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Dummy(new(0, 0));
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Checkbox("###createShowNotDl", ref _createOnlyShowNotDownloadable);
|
||||||
|
UiSharedService.AttachToolTip("Filter by not downloadable");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Dummy(new(0, 0));
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Dummy(new(0, 0));
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Dummy(new(0, 0));
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Dummy(new(0, 0));
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var entry in _charaDataManager.OwnCharaData.Values
|
||||||
|
.Where(v =>
|
||||||
|
{
|
||||||
|
bool show = true;
|
||||||
|
if (!string.IsNullOrWhiteSpace(_createCodeFilter))
|
||||||
|
{
|
||||||
|
show &= v.FullId.Contains(_createCodeFilter, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrWhiteSpace(_createDescFilter))
|
||||||
|
{
|
||||||
|
show &= v.Description.Contains(_createDescFilter, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
if (_createOnlyShowFav)
|
||||||
|
{
|
||||||
|
show &= _configService.Current.FavoriteCodes.ContainsKey(v.FullId);
|
||||||
|
}
|
||||||
|
if (_createOnlyShowNotDownloadable)
|
||||||
|
{
|
||||||
|
show &= !(!v.HasMissingFiles && !string.IsNullOrEmpty(v.GlamourerData));
|
||||||
|
}
|
||||||
|
|
||||||
|
return show;
|
||||||
|
}).OrderBy(b => b.CreatedDate))
|
||||||
{
|
{
|
||||||
var uDto = _charaDataManager.GetUpdateDto(entry.Id);
|
var uDto = _charaDataManager.GetUpdateDto(entry.Id);
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
@@ -729,7 +816,7 @@ internal sealed partial class CharaDataHubUi
|
|||||||
_uiSharedService.DrawHelpText("Users added to this list will be able to access this character data regardless of your pause or pair state with them." + UiSharedService.TooltipSeparator
|
_uiSharedService.DrawHelpText("Users added to this list will be able to access this character data regardless of your pause or pair state with them." + UiSharedService.TooltipSeparator
|
||||||
+ "Note: Mistyped entries will be automatically removed on updating data to server.");
|
+ "Note: Mistyped entries will be automatically removed on updating data to server.");
|
||||||
|
|
||||||
using (var lb = ImRaii.ListBox("Allowed Individuals", new(200, 200)))
|
using (var lb = ImRaii.ListBox("Allowed Individuals", new(200 * ImGuiHelpers.GlobalScale, 200 * ImGuiHelpers.GlobalScale)))
|
||||||
{
|
{
|
||||||
foreach (var user in updateDto.UserList)
|
foreach (var user in updateDto.UserList)
|
||||||
{
|
{
|
||||||
@@ -749,6 +836,28 @@ internal sealed partial class CharaDataHubUi
|
|||||||
_selectedSpecificUserIndividual = string.Empty;
|
_selectedSpecificUserIndividual = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using (ImRaii.Disabled(!UiSharedService.CtrlPressed()))
|
||||||
|
{
|
||||||
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.ExclamationTriangle, "Apply current Allowed Individuals to all MCDO entries"))
|
||||||
|
{
|
||||||
|
foreach (var own in _charaDataManager.OwnCharaData.Values.Where(k => !string.Equals(k.Id, updateDto.Id, StringComparison.Ordinal)))
|
||||||
|
{
|
||||||
|
var otherUpdateDto = _charaDataManager.GetUpdateDto(own.Id);
|
||||||
|
if (otherUpdateDto == null) continue;
|
||||||
|
foreach (var user in otherUpdateDto.UserList.Select(k => k.UID).Concat(otherUpdateDto.AllowedUsers ?? []).Distinct(StringComparer.Ordinal).ToList())
|
||||||
|
{
|
||||||
|
otherUpdateDto.RemoveUserFromList(user);
|
||||||
|
}
|
||||||
|
foreach (var user in updateDto.UserList.Select(k => k.UID).Concat(updateDto.AllowedUsers ?? []).Distinct(StringComparer.Ordinal).ToList())
|
||||||
|
{
|
||||||
|
otherUpdateDto.AddUserToList(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UiSharedService.AttachToolTip("This will apply the current list of allowed specific individuals to ALL of your MCDO entries." + UiSharedService.TooltipSeparator
|
||||||
|
+ "Hold CTRL to enable.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
@@ -776,7 +885,7 @@ internal sealed partial class CharaDataHubUi
|
|||||||
_uiSharedService.DrawHelpText("Users in Syncshells added to this list will be able to access this character data regardless of your pause or pair state with them." + UiSharedService.TooltipSeparator
|
_uiSharedService.DrawHelpText("Users in Syncshells added to this list will be able to access this character data regardless of your pause or pair state with them." + UiSharedService.TooltipSeparator
|
||||||
+ "Note: Mistyped entries will be automatically removed on updating data to server.");
|
+ "Note: Mistyped entries will be automatically removed on updating data to server.");
|
||||||
|
|
||||||
using (var lb = ImRaii.ListBox("Allowed Syncshells", new(200, 200)))
|
using (var lb = ImRaii.ListBox("Allowed Syncshells", new(200 * ImGuiHelpers.GlobalScale, 200 * ImGuiHelpers.GlobalScale)))
|
||||||
{
|
{
|
||||||
foreach (var group in updateDto.GroupList)
|
foreach (var group in updateDto.GroupList)
|
||||||
{
|
{
|
||||||
@@ -796,6 +905,28 @@ internal sealed partial class CharaDataHubUi
|
|||||||
_selectedSpecificGroupIndividual = string.Empty;
|
_selectedSpecificGroupIndividual = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using (ImRaii.Disabled(!UiSharedService.CtrlPressed()))
|
||||||
|
{
|
||||||
|
if (_uiSharedService.IconTextButton(FontAwesomeIcon.ExclamationTriangle, "Apply current Allowed Syncshells to all MCDO entries"))
|
||||||
|
{
|
||||||
|
foreach (var own in _charaDataManager.OwnCharaData.Values.Where(k => !string.Equals(k.Id, updateDto.Id, StringComparison.Ordinal)))
|
||||||
|
{
|
||||||
|
var otherUpdateDto = _charaDataManager.GetUpdateDto(own.Id);
|
||||||
|
if (otherUpdateDto == null) continue;
|
||||||
|
foreach (var group in otherUpdateDto.GroupList.Select(k => k.GID).Concat(otherUpdateDto.AllowedGroups ?? []).Distinct(StringComparer.Ordinal).ToList())
|
||||||
|
{
|
||||||
|
otherUpdateDto.RemoveGroupFromList(group);
|
||||||
|
}
|
||||||
|
foreach (var group in updateDto.GroupList.Select(k => k.GID).Concat(updateDto.AllowedGroups ?? []).Distinct(StringComparer.Ordinal).ToList())
|
||||||
|
{
|
||||||
|
otherUpdateDto.AddGroupToList(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UiSharedService.AttachToolTip("This will apply the current list of allowed specific syncshells to ALL of your MCDO entries." + UiSharedService.TooltipSeparator
|
||||||
|
+ "Hold CTRL to enable.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ internal partial class CharaDataHubUi
|
|||||||
}
|
}
|
||||||
_uiSharedService.DrawHelpText("When enabled, Mare will draw floating wisps where other's poses are in the world.");
|
_uiSharedService.DrawHelpText("When enabled, Mare will draw floating wisps where other's poses are in the world.");
|
||||||
int poseDetectionDistance = _configService.Current.NearbyDistanceFilter;
|
int poseDetectionDistance = _configService.Current.NearbyDistanceFilter;
|
||||||
ImGui.SetNextItemWidth(100);
|
UiSharedService.ScaledNextItemWidth(100);
|
||||||
if (ImGui.SliderInt("Detection Distance", ref poseDetectionDistance, 5, 1000))
|
if (ImGui.SliderInt("Detection Distance", ref poseDetectionDistance, 5, 1000))
|
||||||
{
|
{
|
||||||
_configService.Current.NearbyDistanceFilter = poseDetectionDistance;
|
_configService.Current.NearbyDistanceFilter = poseDetectionDistance;
|
||||||
|
|||||||
@@ -34,58 +34,45 @@ namespace MareSynchronos.UI;
|
|||||||
public partial class UiSharedService : DisposableMediatorSubscriberBase
|
public partial class UiSharedService : DisposableMediatorSubscriberBase
|
||||||
{
|
{
|
||||||
public const string TooltipSeparator = "--SEP--";
|
public const string TooltipSeparator = "--SEP--";
|
||||||
public static string DoubleNewLine => Environment.NewLine + Environment.NewLine;
|
|
||||||
|
|
||||||
public static readonly ImGuiWindowFlags PopupWindowFlags = ImGuiWindowFlags.NoResize |
|
public static readonly ImGuiWindowFlags PopupWindowFlags = ImGuiWindowFlags.NoResize |
|
||||||
ImGuiWindowFlags.NoScrollbar |
|
ImGuiWindowFlags.NoScrollbar |
|
||||||
ImGuiWindowFlags.NoScrollWithMouse;
|
ImGuiWindowFlags.NoScrollWithMouse;
|
||||||
|
|
||||||
public readonly FileDialogManager FileDialogManager;
|
public readonly FileDialogManager FileDialogManager;
|
||||||
|
|
||||||
private const string _notesEnd = "##MARE_SYNCHRONOS_USER_NOTES_END##";
|
private const string _notesEnd = "##MARE_SYNCHRONOS_USER_NOTES_END##";
|
||||||
|
|
||||||
private const string _notesStart = "##MARE_SYNCHRONOS_USER_NOTES_START##";
|
private const string _notesStart = "##MARE_SYNCHRONOS_USER_NOTES_START##";
|
||||||
|
|
||||||
private readonly ApiController _apiController;
|
private readonly ApiController _apiController;
|
||||||
|
|
||||||
private readonly CacheMonitor _cacheMonitor;
|
private readonly CacheMonitor _cacheMonitor;
|
||||||
|
|
||||||
private readonly MareConfigService _configService;
|
private readonly MareConfigService _configService;
|
||||||
|
|
||||||
private readonly DalamudUtilService _dalamudUtil;
|
private readonly DalamudUtilService _dalamudUtil;
|
||||||
private readonly IpcManager _ipcManager;
|
private readonly IpcManager _ipcManager;
|
||||||
private readonly Dalamud.Localization _localization;
|
private readonly Dalamud.Localization _localization;
|
||||||
private readonly IDalamudPluginInterface _pluginInterface;
|
private readonly IDalamudPluginInterface _pluginInterface;
|
||||||
private readonly ITextureProvider _textureProvider;
|
|
||||||
private readonly Dictionary<string, object?> _selectedComboItems = new(StringComparer.Ordinal);
|
private readonly Dictionary<string, object?> _selectedComboItems = new(StringComparer.Ordinal);
|
||||||
private readonly ServerConfigurationManager _serverConfigurationManager;
|
private readonly ServerConfigurationManager _serverConfigurationManager;
|
||||||
|
private readonly ITextureProvider _textureProvider;
|
||||||
private readonly TokenProvider _tokenProvider;
|
private readonly TokenProvider _tokenProvider;
|
||||||
|
private bool _brioExists = false;
|
||||||
private bool _cacheDirectoryHasOtherFilesThanCache = false;
|
private bool _cacheDirectoryHasOtherFilesThanCache = false;
|
||||||
|
|
||||||
private bool _cacheDirectoryIsValidPath = true;
|
private bool _cacheDirectoryIsValidPath = true;
|
||||||
|
|
||||||
private bool _customizePlusExists = false;
|
private bool _customizePlusExists = false;
|
||||||
|
|
||||||
private string _customServerName = "";
|
private string _customServerName = "";
|
||||||
|
|
||||||
private string _customServerUri = "";
|
private string _customServerUri = "";
|
||||||
|
private Task<Uri?>? _discordOAuthCheck;
|
||||||
|
private Task<string?>? _discordOAuthGetCode;
|
||||||
|
private CancellationTokenSource _discordOAuthGetCts = new();
|
||||||
|
private Task<Dictionary<string, string>>? _discordOAuthUIDs;
|
||||||
private bool _glamourerExists = false;
|
private bool _glamourerExists = false;
|
||||||
|
|
||||||
private bool _heelsExists = false;
|
private bool _heelsExists = false;
|
||||||
|
|
||||||
private bool _honorificExists = false;
|
private bool _honorificExists = false;
|
||||||
private bool _isDirectoryWritable = false;
|
private bool _isDirectoryWritable = false;
|
||||||
private bool _isOneDrive = false;
|
private bool _isOneDrive = false;
|
||||||
private bool _isPenumbraDirectory = false;
|
private bool _isPenumbraDirectory = false;
|
||||||
private bool _moodlesExists = false;
|
private bool _moodlesExists = false;
|
||||||
|
private Dictionary<string, DateTime> _oauthTokenExpiry = new();
|
||||||
private bool _penumbraExists = false;
|
private bool _penumbraExists = false;
|
||||||
private bool _petNamesExists = false;
|
private bool _petNamesExists = false;
|
||||||
private bool _brioExists = false;
|
|
||||||
|
|
||||||
private int _serverSelectionIndex = -1;
|
private int _serverSelectionIndex = -1;
|
||||||
private Dictionary<string, DateTime> _oauthTokenExpiry = new();
|
|
||||||
|
|
||||||
public UiSharedService(ILogger<UiSharedService> logger, IpcManager ipcManager, ApiController apiController,
|
public UiSharedService(ILogger<UiSharedService> logger, IpcManager ipcManager, ApiController apiController,
|
||||||
CacheMonitor cacheMonitor, FileDialogManager fileDialogManager,
|
CacheMonitor cacheMonitor, FileDialogManager fileDialogManager,
|
||||||
MareConfigService configService, DalamudUtilService dalamudUtil, IDalamudPluginInterface pluginInterface,
|
MareConfigService configService, DalamudUtilService dalamudUtil, IDalamudPluginInterface pluginInterface,
|
||||||
@@ -131,6 +118,7 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
IconFont = _pluginInterface.UiBuilder.IconFontFixedWidthHandle;
|
IconFont = _pluginInterface.UiBuilder.IconFontFixedWidthHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string DoubleNewLine => Environment.NewLine + Environment.NewLine;
|
||||||
public ApiController ApiController => _apiController;
|
public ApiController ApiController => _apiController;
|
||||||
|
|
||||||
public bool EditTrackerPosition { get; set; }
|
public bool EditTrackerPosition { get; set; }
|
||||||
@@ -141,12 +129,11 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
public IFontHandle IconFont { get; init; }
|
public IFontHandle IconFont { get; init; }
|
||||||
public bool IsInGpose => _dalamudUtil.IsInGpose;
|
public bool IsInGpose => _dalamudUtil.IsInGpose;
|
||||||
|
|
||||||
|
public Dictionary<uint, string> JobData => _dalamudUtil.JobData.Value;
|
||||||
public string PlayerName => _dalamudUtil.GetPlayerName();
|
public string PlayerName => _dalamudUtil.GetPlayerName();
|
||||||
|
|
||||||
public IFontHandle UidFont { get; init; }
|
public IFontHandle UidFont { get; init; }
|
||||||
public Dictionary<ushort, string> WorldData => _dalamudUtil.WorldData.Value;
|
public Dictionary<ushort, string> WorldData => _dalamudUtil.WorldData.Value;
|
||||||
public Dictionary<uint, string> JobData => _dalamudUtil.JobData.Value;
|
|
||||||
|
|
||||||
public uint WorldId => _dalamudUtil.GetHomeWorldId();
|
public uint WorldId => _dalamudUtil.GetHomeWorldId();
|
||||||
|
|
||||||
public static void AttachToolTip(string text)
|
public static void AttachToolTip(string text)
|
||||||
@@ -221,6 +208,38 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
public static bool CtrlPressed() => (GetKeyState(0xA2) & 0x8000) != 0 || (GetKeyState(0xA3) & 0x8000) != 0;
|
public static bool CtrlPressed() => (GetKeyState(0xA2) & 0x8000) != 0 || (GetKeyState(0xA3) & 0x8000) != 0;
|
||||||
|
|
||||||
|
public static void DrawGrouped(Action imguiDrawAction, float rounding = 5f, float? expectedWidth = null)
|
||||||
|
{
|
||||||
|
var cursorPos = ImGui.GetCursorPos();
|
||||||
|
using (ImRaii.Group())
|
||||||
|
{
|
||||||
|
if (expectedWidth != null)
|
||||||
|
{
|
||||||
|
ImGui.Dummy(new(expectedWidth.Value, 0));
|
||||||
|
ImGui.SetCursorPos(cursorPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
imguiDrawAction.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.GetWindowDrawList().AddRect(
|
||||||
|
ImGui.GetItemRectMin() - ImGui.GetStyle().ItemInnerSpacing,
|
||||||
|
ImGui.GetItemRectMax() + ImGui.GetStyle().ItemInnerSpacing,
|
||||||
|
Color(ImGuiColors.DalamudGrey2), rounding);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DrawGroupedCenteredColorText(string text, Vector4 color, float? maxWidth = null)
|
||||||
|
{
|
||||||
|
var availWidth = ImGui.GetContentRegionAvail().X;
|
||||||
|
var textWidth = ImGui.CalcTextSize(text, availWidth).X;
|
||||||
|
if (maxWidth != null && textWidth > maxWidth * ImGuiHelpers.GlobalScale) textWidth = maxWidth.Value * ImGuiHelpers.GlobalScale;
|
||||||
|
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + (availWidth / 2f) - (textWidth / 2f));
|
||||||
|
DrawGrouped(() =>
|
||||||
|
{
|
||||||
|
ColorTextWrapped(text, color, ImGui.GetCursorPosX() + textWidth);
|
||||||
|
}, expectedWidth: maxWidth == null ? null : maxWidth * ImGuiHelpers.GlobalScale);
|
||||||
|
}
|
||||||
|
|
||||||
public static void DrawOutlinedFont(string text, Vector4 fontColor, Vector4 outlineColor, int thickness)
|
public static void DrawOutlinedFont(string text, Vector4 fontColor, Vector4 outlineColor, int thickness)
|
||||||
{
|
{
|
||||||
var original = ImGui.GetCursorPos();
|
var original = ImGui.GetCursorPos();
|
||||||
@@ -277,18 +296,16 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
drawList.AddText(textPos, fontColor, text);
|
drawList.AddText(textPos, fontColor, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector4 GetBoolColor(bool input) => input ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
public static void DrawTree(string leafName, Action drawOnOpened, ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags.None)
|
||||||
|
|
||||||
public float GetIconTextButtonSize(FontAwesomeIcon icon, string text)
|
|
||||||
{
|
{
|
||||||
Vector2 vector;
|
using var tree = ImRaii.TreeNode(leafName, flags);
|
||||||
using (IconFont.Push())
|
if (tree)
|
||||||
vector = ImGui.CalcTextSize(icon.ToIconString());
|
{
|
||||||
|
drawOnOpened();
|
||||||
Vector2 vector2 = ImGui.CalcTextSize(text);
|
|
||||||
float num = 3f * ImGuiHelpers.GlobalScale;
|
|
||||||
return vector.X + vector2.X + ImGui.GetStyle().FramePadding.X * 2f + num;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vector4 GetBoolColor(bool input) => input ? ImGuiColors.ParsedGreen : ImGuiColors.DalamudRed;
|
||||||
|
|
||||||
public static string GetNotes(List<Pair> pairs)
|
public static string GetNotes(List<Pair> pairs)
|
||||||
{
|
{
|
||||||
@@ -311,69 +328,6 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
return ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X;
|
return ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IconButton(FontAwesomeIcon icon, float? height = null)
|
|
||||||
{
|
|
||||||
string text = icon.ToIconString();
|
|
||||||
|
|
||||||
ImGui.PushID(text);
|
|
||||||
Vector2 vector;
|
|
||||||
using (IconFont.Push())
|
|
||||||
vector = ImGui.CalcTextSize(text);
|
|
||||||
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
||||||
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
||||||
float x = vector.X + ImGui.GetStyle().FramePadding.X * 2f;
|
|
||||||
float frameHeight = height ?? ImGui.GetFrameHeight();
|
|
||||||
bool result = ImGui.Button(string.Empty, new Vector2(x, frameHeight));
|
|
||||||
Vector2 pos = new Vector2(cursorScreenPos.X + ImGui.GetStyle().FramePadding.X,
|
|
||||||
cursorScreenPos.Y + (height ?? ImGui.GetFrameHeight()) / 2f - (vector.Y / 2f));
|
|
||||||
using (IconFont.Push())
|
|
||||||
windowDrawList.AddText(pos, ImGui.GetColorU32(ImGuiCol.Text), text);
|
|
||||||
ImGui.PopID();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IconTextButtonInternal(FontAwesomeIcon icon, string text, Vector4? defaultColor = null, float? width = null)
|
|
||||||
{
|
|
||||||
int num = 0;
|
|
||||||
if (defaultColor.HasValue)
|
|
||||||
{
|
|
||||||
ImGui.PushStyleColor(ImGuiCol.Button, defaultColor.Value);
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.PushID(text);
|
|
||||||
Vector2 vector;
|
|
||||||
using (IconFont.Push())
|
|
||||||
vector = ImGui.CalcTextSize(icon.ToIconString());
|
|
||||||
Vector2 vector2 = ImGui.CalcTextSize(text);
|
|
||||||
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
|
||||||
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
|
||||||
float num2 = 3f * ImGuiHelpers.GlobalScale;
|
|
||||||
float x = width ?? vector.X + vector2.X + ImGui.GetStyle().FramePadding.X * 2f + num2;
|
|
||||||
float frameHeight = ImGui.GetFrameHeight();
|
|
||||||
bool result = ImGui.Button(string.Empty, new Vector2(x, frameHeight));
|
|
||||||
Vector2 pos = new Vector2(cursorScreenPos.X + ImGui.GetStyle().FramePadding.X, cursorScreenPos.Y + ImGui.GetStyle().FramePadding.Y);
|
|
||||||
using (IconFont.Push())
|
|
||||||
windowDrawList.AddText(pos, ImGui.GetColorU32(ImGuiCol.Text), icon.ToIconString());
|
|
||||||
Vector2 pos2 = new Vector2(pos.X + vector.X + num2, cursorScreenPos.Y + ImGui.GetStyle().FramePadding.Y);
|
|
||||||
windowDrawList.AddText(pos2, ImGui.GetColorU32(ImGuiCol.Text), text);
|
|
||||||
ImGui.PopID();
|
|
||||||
if (num > 0)
|
|
||||||
{
|
|
||||||
ImGui.PopStyleColor(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IconTextButton(FontAwesomeIcon icon, string text, float? width = null, bool isInPopup = false)
|
|
||||||
{
|
|
||||||
return IconTextButtonInternal(icon, text,
|
|
||||||
isInPopup ? ColorHelpers.RgbaUintToVector4(ImGui.GetColorU32(ImGuiCol.PopupBg)) : null,
|
|
||||||
width <= 0 ? null : width);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsDirectoryWritable(string dirPath, bool throwIfFails = false)
|
public static bool IsDirectoryWritable(string dirPath, bool throwIfFails = false)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -396,6 +350,16 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ScaledNextItemWidth(float width)
|
||||||
|
{
|
||||||
|
ImGui.SetNextItemWidth(width * ImGuiHelpers.GlobalScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ScaledSameLine(float offset)
|
||||||
|
{
|
||||||
|
ImGui.SameLine(offset * ImGuiHelpers.GlobalScale);
|
||||||
|
}
|
||||||
|
|
||||||
public static void SetScaledWindowSize(float width, bool centerWindow = true)
|
public static void SetScaledWindowSize(float width, bool centerWindow = true)
|
||||||
{
|
{
|
||||||
var newLineHeight = ImGui.GetCursorPosY();
|
var newLineHeight = ImGui.GetCursorPosY();
|
||||||
@@ -641,284 +605,6 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
AttachToolTip(helpText);
|
AttachToolTip(helpText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool DrawOtherPluginState()
|
|
||||||
{
|
|
||||||
var check = FontAwesomeIcon.Check;
|
|
||||||
var cross = FontAwesomeIcon.SquareXmark;
|
|
||||||
ImGui.TextUnformatted("Mandatory Plugins:");
|
|
||||||
|
|
||||||
ImGui.SameLine(150);
|
|
||||||
ColorText("Penumbra", GetBoolColor(_penumbraExists));
|
|
||||||
AttachToolTip($"Penumbra is " + (_penumbraExists ? "available and up to date." : "unavailable or not up to date."));
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
ColorText("Glamourer", GetBoolColor(_glamourerExists));
|
|
||||||
AttachToolTip($"Glamourer is " + (_glamourerExists ? "available and up to date." : "unavailable or not up to date."));
|
|
||||||
|
|
||||||
ImGui.TextUnformatted("Optional Plugins:");
|
|
||||||
ImGui.SameLine(150);
|
|
||||||
ColorText("SimpleHeels", GetBoolColor(_heelsExists));
|
|
||||||
AttachToolTip($"SimpleHeels is " + (_heelsExists ? "available and up to date." : "unavailable or not up to date."));
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
ColorText("Customize+", GetBoolColor(_customizePlusExists));
|
|
||||||
AttachToolTip($"Customize+ is " + (_customizePlusExists ? "available and up to date." : "unavailable or not up to date."));
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
ColorText("Honorific", GetBoolColor(_honorificExists));
|
|
||||||
AttachToolTip($"Honorific is " + (_honorificExists ? "available and up to date." : "unavailable or not up to date."));
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
ColorText("Moodles", GetBoolColor(_moodlesExists));
|
|
||||||
AttachToolTip($"Moodles is " + (_moodlesExists ? "available and up to date." : "unavailable or not up to date."));
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
ColorText("PetNicknames", GetBoolColor(_petNamesExists));
|
|
||||||
AttachToolTip($"PetNicknames is " + (_petNamesExists ? "available and up to date." : "unavailable or not up to date."));
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
ColorText("Brio", GetBoolColor(_brioExists));
|
|
||||||
AttachToolTip($"Brio is " + (_brioExists ? "available and up to date." : "unavailable or not up to date."));
|
|
||||||
|
|
||||||
if (!_penumbraExists || !_glamourerExists)
|
|
||||||
{
|
|
||||||
ImGui.TextColored(ImGuiColors.DalamudRed, "You need to install both Penumbra and Glamourer and keep them up to date to use Mare Synchronos.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int DrawServiceSelection(bool selectOnChange = false, bool showConnect = true)
|
|
||||||
{
|
|
||||||
string[] comboEntries = _serverConfigurationManager.GetServerNames();
|
|
||||||
|
|
||||||
if (_serverSelectionIndex == -1)
|
|
||||||
{
|
|
||||||
_serverSelectionIndex = Array.IndexOf(_serverConfigurationManager.GetServerApiUrls(), _serverConfigurationManager.CurrentApiUrl);
|
|
||||||
}
|
|
||||||
if (_serverSelectionIndex == -1 || _serverSelectionIndex >= comboEntries.Length)
|
|
||||||
{
|
|
||||||
_serverSelectionIndex = 0;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < comboEntries.Length; i++)
|
|
||||||
{
|
|
||||||
if (string.Equals(_serverConfigurationManager.CurrentServer?.ServerName, comboEntries[i], StringComparison.OrdinalIgnoreCase))
|
|
||||||
comboEntries[i] += " [Current]";
|
|
||||||
}
|
|
||||||
if (ImGui.BeginCombo("Select Service", comboEntries[_serverSelectionIndex]))
|
|
||||||
{
|
|
||||||
for (int i = 0; i < comboEntries.Length; i++)
|
|
||||||
{
|
|
||||||
bool isSelected = _serverSelectionIndex == i;
|
|
||||||
if (ImGui.Selectable(comboEntries[i], isSelected))
|
|
||||||
{
|
|
||||||
_serverSelectionIndex = i;
|
|
||||||
if (selectOnChange)
|
|
||||||
{
|
|
||||||
_serverConfigurationManager.SelectServer(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isSelected)
|
|
||||||
{
|
|
||||||
ImGui.SetItemDefaultFocus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.EndCombo();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showConnect)
|
|
||||||
{
|
|
||||||
ImGui.SameLine();
|
|
||||||
var text = "Connect";
|
|
||||||
if (_serverSelectionIndex == _serverConfigurationManager.CurrentServerIndex) text = "Reconnect";
|
|
||||||
if (IconTextButton(FontAwesomeIcon.Link, text))
|
|
||||||
{
|
|
||||||
_serverConfigurationManager.SelectServer(_serverSelectionIndex);
|
|
||||||
_ = _apiController.CreateConnectionsAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.TreeNode("Add Custom Service"))
|
|
||||||
{
|
|
||||||
ImGui.SetNextItemWidth(250);
|
|
||||||
ImGui.InputText("Custom Service URI", ref _customServerUri, 255);
|
|
||||||
ImGui.SetNextItemWidth(250);
|
|
||||||
ImGui.InputText("Custom Service Name", ref _customServerName, 255);
|
|
||||||
if (IconTextButton(FontAwesomeIcon.Plus, "Add Custom Service")
|
|
||||||
&& !string.IsNullOrEmpty(_customServerUri)
|
|
||||||
&& !string.IsNullOrEmpty(_customServerName))
|
|
||||||
{
|
|
||||||
_serverConfigurationManager.AddServer(new ServerStorage()
|
|
||||||
{
|
|
||||||
ServerName = _customServerName,
|
|
||||||
ServerUri = _customServerUri,
|
|
||||||
UseOAuth2 = true
|
|
||||||
});
|
|
||||||
_customServerName = string.Empty;
|
|
||||||
_customServerUri = string.Empty;
|
|
||||||
_configService.Save();
|
|
||||||
}
|
|
||||||
ImGui.TreePop();
|
|
||||||
}
|
|
||||||
|
|
||||||
return _serverSelectionIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2 GetIconButtonSize(FontAwesomeIcon icon)
|
|
||||||
{
|
|
||||||
using var font = IconFont.Push();
|
|
||||||
return ImGuiHelpers.GetButtonSize(icon.ToIconString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Vector2 GetIconSize(FontAwesomeIcon icon)
|
|
||||||
{
|
|
||||||
using var font = IconFont.Push();
|
|
||||||
return ImGui.CalcTextSize(icon.ToIconString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void IconText(FontAwesomeIcon icon, uint color)
|
|
||||||
{
|
|
||||||
FontText(icon.ToIconString(), IconFont, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void IconText(FontAwesomeIcon icon, Vector4? color = null)
|
|
||||||
{
|
|
||||||
IconText(icon, color == null ? ImGui.GetColorU32(ImGuiCol.Text) : ImGui.GetColorU32(color.Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDalamudTextureWrap LoadImage(byte[] imageData)
|
|
||||||
{
|
|
||||||
return _textureProvider.CreateFromImageAsync(imageData).Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void LoadLocalization(string languageCode)
|
|
||||||
{
|
|
||||||
_localization.SetupWithLangCode(languageCode);
|
|
||||||
Strings.ToS = new Strings.ToSStrings();
|
|
||||||
}
|
|
||||||
|
|
||||||
[LibraryImport("user32")]
|
|
||||||
internal static partial short GetKeyState(int nVirtKey);
|
|
||||||
|
|
||||||
private static void CenterWindow(float width, float height, ImGuiCond cond = ImGuiCond.None)
|
|
||||||
{
|
|
||||||
var center = ImGui.GetMainViewport().GetCenter();
|
|
||||||
ImGui.SetWindowPos(new Vector2(center.X - width / 2, center.Y - height / 2), cond);
|
|
||||||
}
|
|
||||||
|
|
||||||
[GeneratedRegex(@"^(?:[a-zA-Z]:\\[\w\s\-\\]+?|\/(?:[\w\s\-\/])+?)$", RegexOptions.ECMAScript, 5000)]
|
|
||||||
private static partial Regex PathRegex();
|
|
||||||
|
|
||||||
private void FontText(string text, IFontHandle font, Vector4? color = null)
|
|
||||||
{
|
|
||||||
FontText(text, font, color == null ? ImGui.GetColorU32(ImGuiCol.Text) : ImGui.GetColorU32(color.Value));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FontText(string text, IFontHandle font, uint color)
|
|
||||||
{
|
|
||||||
using var pushedFont = font.Push();
|
|
||||||
using var pushedColor = ImRaii.PushColor(ImGuiCol.Text, color);
|
|
||||||
ImGui.TextUnformatted(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
public sealed record IconScaleData(Vector2 IconSize, Vector2 NormalizedIconScale, float OffsetX, float IconScaling);
|
|
||||||
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if (!disposing) return;
|
|
||||||
|
|
||||||
base.Dispose(disposing);
|
|
||||||
|
|
||||||
UidFont.Dispose();
|
|
||||||
GameFont.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Task<Uri?>? _discordOAuthCheck;
|
|
||||||
private CancellationTokenSource _discordOAuthGetCts = new();
|
|
||||||
private Task<string?>? _discordOAuthGetCode;
|
|
||||||
private Task<Dictionary<string, string>>? _discordOAuthUIDs;
|
|
||||||
|
|
||||||
public void DrawUpdateOAuthUIDsButton(ServerStorage selectedServer)
|
|
||||||
{
|
|
||||||
if (!selectedServer.UseOAuth2)
|
|
||||||
return;
|
|
||||||
|
|
||||||
using (ImRaii.Disabled(string.IsNullOrEmpty(selectedServer.OAuthToken)))
|
|
||||||
{
|
|
||||||
if ((_discordOAuthUIDs == null || _discordOAuthUIDs.IsCompleted)
|
|
||||||
&& IconTextButton(FontAwesomeIcon.ArrowsSpin, "Update UIDs from Service")
|
|
||||||
&& !string.IsNullOrEmpty(selectedServer.OAuthToken))
|
|
||||||
{
|
|
||||||
_discordOAuthUIDs = _serverConfigurationManager.GetUIDsWithDiscordToken(selectedServer.ServerUri, selectedServer.OAuthToken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DateTime tokenExpiry = DateTime.MinValue;
|
|
||||||
if (!string.IsNullOrEmpty(selectedServer.OAuthToken) && !_oauthTokenExpiry.TryGetValue(selectedServer.OAuthToken, out tokenExpiry))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var handler = new JwtSecurityTokenHandler();
|
|
||||||
var jwt = handler.ReadJwtToken(selectedServer.OAuthToken);
|
|
||||||
tokenExpiry = _oauthTokenExpiry[selectedServer.OAuthToken] = jwt.ValidTo;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.LogWarning(ex, "Could not parse OAuth token, deleting");
|
|
||||||
selectedServer.OAuthToken = null;
|
|
||||||
_serverConfigurationManager.Save();
|
|
||||||
tokenExpiry = DateTime.MinValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (string.IsNullOrEmpty(selectedServer.OAuthToken) || tokenExpiry < DateTime.UtcNow)
|
|
||||||
{
|
|
||||||
ColorTextWrapped("You have no OAuth token or the OAuth token is expired. Please use the Service Settings to (re)link your OAuth account.", ImGuiColors.DalamudRed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private record UIDAliasPair(string? UID, string? Alias);
|
|
||||||
|
|
||||||
public void DrawUIDComboForAuthentication(int indexOffset, Authentication item, string serverUri, ILogger? logger = null)
|
|
||||||
{
|
|
||||||
using (ImRaii.Disabled(_discordOAuthUIDs == null))
|
|
||||||
{
|
|
||||||
var aliasPairs = _discordOAuthUIDs?.Result?.Select(t => new UIDAliasPair(t.Key, t.Value)).ToList() ?? [new UIDAliasPair(item.UID ?? null, null)];
|
|
||||||
var uidComboName = "UID###" + item.CharacterName + item.WorldId + serverUri + indexOffset + aliasPairs.Count;
|
|
||||||
DrawCombo(uidComboName, aliasPairs,
|
|
||||||
(v) =>
|
|
||||||
{
|
|
||||||
if (v is null)
|
|
||||||
return "No UID set";
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(v.Alias))
|
|
||||||
{
|
|
||||||
return $"{v.UID} ({v.Alias})";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(v.UID))
|
|
||||||
return "No UID set";
|
|
||||||
|
|
||||||
return $"{v.UID}";
|
|
||||||
},
|
|
||||||
(v) =>
|
|
||||||
{
|
|
||||||
if (!string.Equals(v?.UID ?? null, item.UID, StringComparison.Ordinal))
|
|
||||||
{
|
|
||||||
item.UID = v?.UID ?? null;
|
|
||||||
_serverConfigurationManager.Save();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
aliasPairs.Find(f => string.Equals(f.UID, item.UID, StringComparison.Ordinal)) ?? default);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_discordOAuthUIDs == null)
|
|
||||||
{
|
|
||||||
AttachToolTip("Use the button above to update your UIDs from the service before you can assign UIDs to characters.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void DrawOAuth(ServerStorage selectedServer)
|
public void DrawOAuth(ServerStorage selectedServer)
|
||||||
{
|
{
|
||||||
var oauthToken = selectedServer.OAuthToken;
|
var oauthToken = selectedServer.OAuthToken;
|
||||||
@@ -1069,6 +755,169 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool DrawOtherPluginState()
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("Mandatory Plugins:");
|
||||||
|
|
||||||
|
ImGui.SameLine(150);
|
||||||
|
ColorText("Penumbra", GetBoolColor(_penumbraExists));
|
||||||
|
AttachToolTip($"Penumbra is " + (_penumbraExists ? "available and up to date." : "unavailable or not up to date."));
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
ColorText("Glamourer", GetBoolColor(_glamourerExists));
|
||||||
|
AttachToolTip($"Glamourer is " + (_glamourerExists ? "available and up to date." : "unavailable or not up to date."));
|
||||||
|
|
||||||
|
ImGui.TextUnformatted("Optional Plugins:");
|
||||||
|
ImGui.SameLine(150);
|
||||||
|
ColorText("SimpleHeels", GetBoolColor(_heelsExists));
|
||||||
|
AttachToolTip($"SimpleHeels is " + (_heelsExists ? "available and up to date." : "unavailable or not up to date."));
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
ColorText("Customize+", GetBoolColor(_customizePlusExists));
|
||||||
|
AttachToolTip($"Customize+ is " + (_customizePlusExists ? "available and up to date." : "unavailable or not up to date."));
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
ColorText("Honorific", GetBoolColor(_honorificExists));
|
||||||
|
AttachToolTip($"Honorific is " + (_honorificExists ? "available and up to date." : "unavailable or not up to date."));
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
ColorText("Moodles", GetBoolColor(_moodlesExists));
|
||||||
|
AttachToolTip($"Moodles is " + (_moodlesExists ? "available and up to date." : "unavailable or not up to date."));
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
ColorText("PetNicknames", GetBoolColor(_petNamesExists));
|
||||||
|
AttachToolTip($"PetNicknames is " + (_petNamesExists ? "available and up to date." : "unavailable or not up to date."));
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
ColorText("Brio", GetBoolColor(_brioExists));
|
||||||
|
AttachToolTip($"Brio is " + (_brioExists ? "available and up to date." : "unavailable or not up to date."));
|
||||||
|
|
||||||
|
if (!_penumbraExists || !_glamourerExists)
|
||||||
|
{
|
||||||
|
ImGui.TextColored(ImGuiColors.DalamudRed, "You need to install both Penumbra and Glamourer and keep them up to date to use Mare Synchronos.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int DrawServiceSelection(bool selectOnChange = false, bool showConnect = true)
|
||||||
|
{
|
||||||
|
string[] comboEntries = _serverConfigurationManager.GetServerNames();
|
||||||
|
|
||||||
|
if (_serverSelectionIndex == -1)
|
||||||
|
{
|
||||||
|
_serverSelectionIndex = Array.IndexOf(_serverConfigurationManager.GetServerApiUrls(), _serverConfigurationManager.CurrentApiUrl);
|
||||||
|
}
|
||||||
|
if (_serverSelectionIndex == -1 || _serverSelectionIndex >= comboEntries.Length)
|
||||||
|
{
|
||||||
|
_serverSelectionIndex = 0;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < comboEntries.Length; i++)
|
||||||
|
{
|
||||||
|
if (string.Equals(_serverConfigurationManager.CurrentServer?.ServerName, comboEntries[i], StringComparison.OrdinalIgnoreCase))
|
||||||
|
comboEntries[i] += " [Current]";
|
||||||
|
}
|
||||||
|
if (ImGui.BeginCombo("Select Service", comboEntries[_serverSelectionIndex]))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < comboEntries.Length; i++)
|
||||||
|
{
|
||||||
|
bool isSelected = _serverSelectionIndex == i;
|
||||||
|
if (ImGui.Selectable(comboEntries[i], isSelected))
|
||||||
|
{
|
||||||
|
_serverSelectionIndex = i;
|
||||||
|
if (selectOnChange)
|
||||||
|
{
|
||||||
|
_serverConfigurationManager.SelectServer(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSelected)
|
||||||
|
{
|
||||||
|
ImGui.SetItemDefaultFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showConnect)
|
||||||
|
{
|
||||||
|
ImGui.SameLine();
|
||||||
|
var text = "Connect";
|
||||||
|
if (_serverSelectionIndex == _serverConfigurationManager.CurrentServerIndex) text = "Reconnect";
|
||||||
|
if (IconTextButton(FontAwesomeIcon.Link, text))
|
||||||
|
{
|
||||||
|
_serverConfigurationManager.SelectServer(_serverSelectionIndex);
|
||||||
|
_ = _apiController.CreateConnectionsAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.TreeNode("Add Custom Service"))
|
||||||
|
{
|
||||||
|
ImGui.SetNextItemWidth(250);
|
||||||
|
ImGui.InputText("Custom Service URI", ref _customServerUri, 255);
|
||||||
|
ImGui.SetNextItemWidth(250);
|
||||||
|
ImGui.InputText("Custom Service Name", ref _customServerName, 255);
|
||||||
|
if (IconTextButton(FontAwesomeIcon.Plus, "Add Custom Service")
|
||||||
|
&& !string.IsNullOrEmpty(_customServerUri)
|
||||||
|
&& !string.IsNullOrEmpty(_customServerName))
|
||||||
|
{
|
||||||
|
_serverConfigurationManager.AddServer(new ServerStorage()
|
||||||
|
{
|
||||||
|
ServerName = _customServerName,
|
||||||
|
ServerUri = _customServerUri,
|
||||||
|
UseOAuth2 = true
|
||||||
|
});
|
||||||
|
_customServerName = string.Empty;
|
||||||
|
_customServerUri = string.Empty;
|
||||||
|
_configService.Save();
|
||||||
|
}
|
||||||
|
ImGui.TreePop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return _serverSelectionIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawUIDComboForAuthentication(int indexOffset, Authentication item, string serverUri, ILogger? logger = null)
|
||||||
|
{
|
||||||
|
using (ImRaii.Disabled(_discordOAuthUIDs == null))
|
||||||
|
{
|
||||||
|
var aliasPairs = _discordOAuthUIDs?.Result?.Select(t => new UIDAliasPair(t.Key, t.Value)).ToList() ?? [new UIDAliasPair(item.UID ?? null, null)];
|
||||||
|
var uidComboName = "UID###" + item.CharacterName + item.WorldId + serverUri + indexOffset + aliasPairs.Count;
|
||||||
|
DrawCombo(uidComboName, aliasPairs,
|
||||||
|
(v) =>
|
||||||
|
{
|
||||||
|
if (v is null)
|
||||||
|
return "No UID set";
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(v.Alias))
|
||||||
|
{
|
||||||
|
return $"{v.UID} ({v.Alias})";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(v.UID))
|
||||||
|
return "No UID set";
|
||||||
|
|
||||||
|
return $"{v.UID}";
|
||||||
|
},
|
||||||
|
(v) =>
|
||||||
|
{
|
||||||
|
if (!string.Equals(v?.UID ?? null, item.UID, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
item.UID = v?.UID ?? null;
|
||||||
|
_serverConfigurationManager.Save();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
aliasPairs.Find(f => string.Equals(f.UID, item.UID, StringComparison.Ordinal)) ?? default);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_discordOAuthUIDs == null)
|
||||||
|
{
|
||||||
|
AttachToolTip("Use the button above to update your UIDs from the service before you can assign UIDs to characters.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void DrawUnlinkOAuthButton(ServerStorage selectedServer)
|
public void DrawUnlinkOAuthButton(ServerStorage selectedServer)
|
||||||
{
|
{
|
||||||
using (ImRaii.Disabled(!CtrlPressed()))
|
using (ImRaii.Disabled(!CtrlPressed()))
|
||||||
@@ -1083,54 +932,114 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
DrawHelpText("Hold CTRL to unlink the current OAuth2 connection.");
|
DrawHelpText("Hold CTRL to unlink the current OAuth2 connection.");
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void RestOAuthTasksState()
|
public void DrawUpdateOAuthUIDsButton(ServerStorage selectedServer)
|
||||||
{
|
{
|
||||||
_discordOAuthCheck = null;
|
if (!selectedServer.UseOAuth2)
|
||||||
_discordOAuthGetCts = _discordOAuthGetCts.CancelRecreate();
|
return;
|
||||||
_discordOAuthGetCode = null;
|
|
||||||
_discordOAuthUIDs = null;
|
using (ImRaii.Disabled(string.IsNullOrEmpty(selectedServer.OAuthToken)))
|
||||||
|
{
|
||||||
|
if ((_discordOAuthUIDs == null || _discordOAuthUIDs.IsCompleted)
|
||||||
|
&& IconTextButton(FontAwesomeIcon.ArrowsSpin, "Update UIDs from Service")
|
||||||
|
&& !string.IsNullOrEmpty(selectedServer.OAuthToken))
|
||||||
|
{
|
||||||
|
_discordOAuthUIDs = _serverConfigurationManager.GetUIDsWithDiscordToken(selectedServer.ServerUri, selectedServer.OAuthToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DateTime tokenExpiry = DateTime.MinValue;
|
||||||
|
if (!string.IsNullOrEmpty(selectedServer.OAuthToken) && !_oauthTokenExpiry.TryGetValue(selectedServer.OAuthToken, out tokenExpiry))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var handler = new JwtSecurityTokenHandler();
|
||||||
|
var jwt = handler.ReadJwtToken(selectedServer.OAuthToken);
|
||||||
|
tokenExpiry = _oauthTokenExpiry[selectedServer.OAuthToken] = jwt.ValidTo;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Logger.LogWarning(ex, "Could not parse OAuth token, deleting");
|
||||||
|
selectedServer.OAuthToken = null;
|
||||||
|
_serverConfigurationManager.Save();
|
||||||
|
tokenExpiry = DateTime.MinValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(selectedServer.OAuthToken) || tokenExpiry < DateTime.UtcNow)
|
||||||
|
{
|
||||||
|
ColorTextWrapped("You have no OAuth token or the OAuth token is expired. Please use the Service Settings to (re)link your OAuth account.", ImGuiColors.DalamudRed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawGrouped(Action imguiDrawAction, float rounding = 5f, float? expectedWidth = null)
|
public Vector2 GetIconButtonSize(FontAwesomeIcon icon)
|
||||||
{
|
{
|
||||||
var cursorPos = ImGui.GetCursorPos();
|
using var font = IconFont.Push();
|
||||||
using (ImRaii.Group())
|
return ImGuiHelpers.GetButtonSize(icon.ToIconString());
|
||||||
{
|
|
||||||
if (expectedWidth != null)
|
|
||||||
{
|
|
||||||
ImGui.Dummy(new(expectedWidth.Value, 0));
|
|
||||||
ImGui.SetCursorPos(cursorPos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
imguiDrawAction.Invoke();
|
public Vector2 GetIconSize(FontAwesomeIcon icon)
|
||||||
|
{
|
||||||
|
using var font = IconFont.Push();
|
||||||
|
return ImGui.CalcTextSize(icon.ToIconString());
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.GetWindowDrawList().AddRect(
|
public float GetIconTextButtonSize(FontAwesomeIcon icon, string text)
|
||||||
ImGui.GetItemRectMin() - ImGui.GetStyle().ItemInnerSpacing,
|
{
|
||||||
ImGui.GetItemRectMax() + ImGui.GetStyle().ItemInnerSpacing,
|
Vector2 vector;
|
||||||
Color(ImGuiColors.DalamudGrey2), rounding);
|
using (IconFont.Push())
|
||||||
|
vector = ImGui.CalcTextSize(icon.ToIconString());
|
||||||
|
|
||||||
|
Vector2 vector2 = ImGui.CalcTextSize(text);
|
||||||
|
float num = 3f * ImGuiHelpers.GlobalScale;
|
||||||
|
return vector.X + vector2.X + ImGui.GetStyle().FramePadding.X * 2f + num;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawGroupedCenteredColorText(string text, Vector4 color, float? maxWidth = null)
|
public bool IconButton(FontAwesomeIcon icon, float? height = null)
|
||||||
{
|
{
|
||||||
var availWidth = ImGui.GetContentRegionAvail().X;
|
string text = icon.ToIconString();
|
||||||
var textWidth = ImGui.CalcTextSize(text, availWidth).X;
|
|
||||||
if (maxWidth != null && textWidth > maxWidth * ImGuiHelpers.GlobalScale) textWidth = maxWidth.Value * ImGuiHelpers.GlobalScale;
|
ImGui.PushID(text);
|
||||||
ImGui.SetCursorPosX(ImGui.GetCursorPosX() + (availWidth / 2f) - (textWidth / 2f));
|
Vector2 vector;
|
||||||
DrawGrouped(() =>
|
using (IconFont.Push())
|
||||||
{
|
vector = ImGui.CalcTextSize(text);
|
||||||
ColorTextWrapped(text, color, ImGui.GetCursorPosX() + textWidth);
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
||||||
}, expectedWidth: maxWidth == null ? null : maxWidth * ImGuiHelpers.GlobalScale);
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
||||||
|
float x = vector.X + ImGui.GetStyle().FramePadding.X * 2f;
|
||||||
|
float frameHeight = height ?? ImGui.GetFrameHeight();
|
||||||
|
bool result = ImGui.Button(string.Empty, new Vector2(x, frameHeight));
|
||||||
|
Vector2 pos = new Vector2(cursorScreenPos.X + ImGui.GetStyle().FramePadding.X,
|
||||||
|
cursorScreenPos.Y + (height ?? ImGui.GetFrameHeight()) / 2f - (vector.Y / 2f));
|
||||||
|
using (IconFont.Push())
|
||||||
|
windowDrawList.AddText(pos, ImGui.GetColorU32(ImGuiCol.Text), text);
|
||||||
|
ImGui.PopID();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ScaledSameLine(float offset)
|
public void IconText(FontAwesomeIcon icon, uint color)
|
||||||
{
|
{
|
||||||
ImGui.SameLine(offset * ImGuiHelpers.GlobalScale);
|
FontText(icon.ToIconString(), IconFont, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ScaledNextItemWidth(float width)
|
public void IconText(FontAwesomeIcon icon, Vector4? color = null)
|
||||||
{
|
{
|
||||||
ImGui.SetNextItemWidth(width * ImGuiHelpers.GlobalScale);
|
IconText(icon, color == null ? ImGui.GetColorU32(ImGuiCol.Text) : ImGui.GetColorU32(color.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IconTextButton(FontAwesomeIcon icon, string text, float? width = null, bool isInPopup = false)
|
||||||
|
{
|
||||||
|
return IconTextButtonInternal(icon, text,
|
||||||
|
isInPopup ? ColorHelpers.RgbaUintToVector4(ImGui.GetColorU32(ImGuiCol.PopupBg)) : null,
|
||||||
|
width <= 0 ? null : width);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDalamudTextureWrap LoadImage(byte[] imageData)
|
||||||
|
{
|
||||||
|
return _textureProvider.CreateFromImageAsync(imageData).Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadLocalization(string languageCode)
|
||||||
|
{
|
||||||
|
_localization.SetupWithLangCode(languageCode);
|
||||||
|
Strings.ToS = new Strings.ToSStrings();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void DistanceSeparator()
|
internal static void DistanceSeparator()
|
||||||
@@ -1140,12 +1049,81 @@ public partial class UiSharedService : DisposableMediatorSubscriberBase
|
|||||||
ImGuiHelpers.ScaledDummy(5);
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawTree(string leafName, Action drawOnOpened, ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags.None)
|
[LibraryImport("user32")]
|
||||||
|
internal static partial short GetKeyState(int nVirtKey);
|
||||||
|
|
||||||
|
internal void RestOAuthTasksState()
|
||||||
{
|
{
|
||||||
using var tree = ImRaii.TreeNode(leafName, flags);
|
_discordOAuthCheck = null;
|
||||||
if (tree)
|
_discordOAuthGetCts = _discordOAuthGetCts.CancelRecreate();
|
||||||
|
_discordOAuthGetCode = null;
|
||||||
|
_discordOAuthUIDs = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
drawOnOpened();
|
if (!disposing) return;
|
||||||
|
|
||||||
|
base.Dispose(disposing);
|
||||||
|
|
||||||
|
UidFont.Dispose();
|
||||||
|
GameFont.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CenterWindow(float width, float height, ImGuiCond cond = ImGuiCond.None)
|
||||||
|
{
|
||||||
|
var center = ImGui.GetMainViewport().GetCenter();
|
||||||
|
ImGui.SetWindowPos(new Vector2(center.X - width / 2, center.Y - height / 2), cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[GeneratedRegex(@"^(?:[a-zA-Z]:\\[\w\s\-\\]+?|\/(?:[\w\s\-\/])+?)$", RegexOptions.ECMAScript, 5000)]
|
||||||
|
private static partial Regex PathRegex();
|
||||||
|
|
||||||
|
private static void FontText(string text, IFontHandle font, Vector4? color = null)
|
||||||
|
{
|
||||||
|
FontText(text, font, color == null ? ImGui.GetColorU32(ImGuiCol.Text) : ImGui.GetColorU32(color.Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FontText(string text, IFontHandle font, uint color)
|
||||||
|
{
|
||||||
|
using var pushedFont = font.Push();
|
||||||
|
using var pushedColor = ImRaii.PushColor(ImGuiCol.Text, color);
|
||||||
|
ImGui.TextUnformatted(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IconTextButtonInternal(FontAwesomeIcon icon, string text, Vector4? defaultColor = null, float? width = null)
|
||||||
|
{
|
||||||
|
int num = 0;
|
||||||
|
if (defaultColor.HasValue)
|
||||||
|
{
|
||||||
|
ImGui.PushStyleColor(ImGuiCol.Button, defaultColor.Value);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PushID(text);
|
||||||
|
Vector2 vector;
|
||||||
|
using (IconFont.Push())
|
||||||
|
vector = ImGui.CalcTextSize(icon.ToIconString());
|
||||||
|
Vector2 vector2 = ImGui.CalcTextSize(text);
|
||||||
|
ImDrawListPtr windowDrawList = ImGui.GetWindowDrawList();
|
||||||
|
Vector2 cursorScreenPos = ImGui.GetCursorScreenPos();
|
||||||
|
float num2 = 3f * ImGuiHelpers.GlobalScale;
|
||||||
|
float x = width ?? vector.X + vector2.X + ImGui.GetStyle().FramePadding.X * 2f + num2;
|
||||||
|
float frameHeight = ImGui.GetFrameHeight();
|
||||||
|
bool result = ImGui.Button(string.Empty, new Vector2(x, frameHeight));
|
||||||
|
Vector2 pos = new Vector2(cursorScreenPos.X + ImGui.GetStyle().FramePadding.X, cursorScreenPos.Y + ImGui.GetStyle().FramePadding.Y);
|
||||||
|
using (IconFont.Push())
|
||||||
|
windowDrawList.AddText(pos, ImGui.GetColorU32(ImGuiCol.Text), icon.ToIconString());
|
||||||
|
Vector2 pos2 = new Vector2(pos.X + vector.X + num2, cursorScreenPos.Y + ImGui.GetStyle().FramePadding.Y);
|
||||||
|
windowDrawList.AddText(pos2, ImGui.GetColorU32(ImGuiCol.Text), text);
|
||||||
|
ImGui.PopID();
|
||||||
|
if (num > 0)
|
||||||
|
{
|
||||||
|
ImGui.PopStyleColor(num);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public sealed record IconScaleData(Vector2 IconSize, Vector2 NormalizedIconScale, float OffsetX, float IconScaling);
|
||||||
|
private record UIDAliasPair(string? UID, string? Alias);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user