Compare commits
8 Commits
1.12.2.0-D
...
debug-clie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
012e80219e | ||
|
|
dae8127ac8 | ||
|
|
0635caab65 | ||
| 1530ac3911 | |||
| 3f80467180 | |||
|
|
4b4e587a89 | ||
|
|
02c3846031 | ||
|
|
a8a01b3034 |
@@ -150,7 +150,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
private void LightlessWatcher_FileChanged(object sender, FileSystemEventArgs e)
|
private void LightlessWatcher_FileChanged(object sender, FileSystemEventArgs e)
|
||||||
{
|
{
|
||||||
Logger.LogTrace("Lightless FSW: FileChanged: {change} => {path}", e.ChangeType, e.FullPath);
|
Logger.LogInformation("Lightless FSW: FileChanged: {change} => {path}", e.ChangeType, e.FullPath);
|
||||||
|
|
||||||
if (!AllowedFileExtensions.Any(ext => e.FullPath.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) return;
|
if (!AllowedFileExtensions.Any(ext => e.FullPath.EndsWith(ext, StringComparison.OrdinalIgnoreCase))) return;
|
||||||
|
|
||||||
@@ -350,6 +350,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
|
|||||||
|
|
||||||
public void InvokeScan()
|
public void InvokeScan()
|
||||||
{
|
{
|
||||||
|
Logger.LogInformation("InvokeScan called");
|
||||||
TotalFiles = 0;
|
TotalFiles = 0;
|
||||||
_currentFileProgress = 0;
|
_currentFileProgress = 0;
|
||||||
_scanCancellationTokenSource = _scanCancellationTokenSource?.CancelRecreate() ?? new CancellationTokenSource();
|
_scanCancellationTokenSource = _scanCancellationTokenSource?.CancelRecreate() ?? new CancellationTokenSource();
|
||||||
@@ -388,6 +389,7 @@ public sealed class CacheMonitor : DisposableMediatorSubscriberBase
|
|||||||
TotalFiles = 0;
|
TotalFiles = 0;
|
||||||
_currentFileProgress = 0;
|
_currentFileProgress = 0;
|
||||||
}, token);
|
}, token);
|
||||||
|
Logger.LogInformation("InvokeScan finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RecalculateFileCacheSize(CancellationToken token)
|
public void RecalculateFileCacheSize(CancellationToken token)
|
||||||
|
|||||||
@@ -152,6 +152,7 @@ public sealed class FileCacheManager : IHostedService
|
|||||||
_logger.LogTrace("Creating cache entry for {path}", path);
|
_logger.LogTrace("Creating cache entry for {path}", path);
|
||||||
var cacheFolder = _configService.Current.CacheFolder;
|
var cacheFolder = _configService.Current.CacheFolder;
|
||||||
if (string.IsNullOrEmpty(cacheFolder)) return null;
|
if (string.IsNullOrEmpty(cacheFolder)) return null;
|
||||||
|
_logger.LogInformation("CreateCacheEntry finished for {path}", path);
|
||||||
return CreateFileEntity(cacheFolder, CachePrefix, fi);
|
return CreateFileEntity(cacheFolder, CachePrefix, fi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,6 +310,8 @@ public sealed class FileCacheManager : IHostedService
|
|||||||
|
|
||||||
public Dictionary<string, FileCacheEntity?> GetFileCachesByPaths(string[] paths)
|
public Dictionary<string, FileCacheEntity?> GetFileCachesByPaths(string[] paths)
|
||||||
{
|
{
|
||||||
|
_logger.LogInformation("GetFileCachesByPaths called for {count} paths", paths.Length);
|
||||||
|
|
||||||
_getCachesByPathsSemaphore.Wait();
|
_getCachesByPathsSemaphore.Wait();
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -365,6 +368,8 @@ public sealed class FileCacheManager : IHostedService
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
||||||
|
_logger.LogInformation("GetFileCachesByPaths finished for {count} paths", paths.Length);
|
||||||
_getCachesByPathsSemaphore.Release();
|
_getCachesByPathsSemaphore.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ public class LightlessConfig : ILightlessConfiguration
|
|||||||
public bool ShowNotificationTimestamp { get; set; } = false;
|
public bool ShowNotificationTimestamp { get; set; } = false;
|
||||||
|
|
||||||
// Position & Layout
|
// Position & Layout
|
||||||
|
public NotificationCorner NotificationCorner { get; set; } = NotificationCorner.Right;
|
||||||
public int NotificationOffsetY { get; set; } = 50;
|
public int NotificationOffsetY { get; set; } = 50;
|
||||||
public int NotificationOffsetX { get; set; } = 0;
|
public int NotificationOffsetX { get; set; } = 0;
|
||||||
public float NotificationWidth { get; set; } = 350f;
|
public float NotificationWidth { get; set; } = 350f;
|
||||||
@@ -102,6 +103,7 @@ public class LightlessConfig : ILightlessConfiguration
|
|||||||
|
|
||||||
// Animation & Effects
|
// Animation & Effects
|
||||||
public float NotificationAnimationSpeed { get; set; } = 10f;
|
public float NotificationAnimationSpeed { get; set; } = 10f;
|
||||||
|
public float NotificationSlideSpeed { get; set; } = 10f;
|
||||||
public float NotificationAccentBarWidth { get; set; } = 3f;
|
public float NotificationAccentBarWidth { get; set; } = 3f;
|
||||||
|
|
||||||
// Duration per Type
|
// Duration per Type
|
||||||
|
|||||||
@@ -18,4 +18,10 @@ public enum NotificationType
|
|||||||
Error,
|
Error,
|
||||||
PairRequest,
|
PairRequest,
|
||||||
Download
|
Download
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum NotificationCorner
|
||||||
|
{
|
||||||
|
Right,
|
||||||
|
Left
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Authors></Authors>
|
<Authors></Authors>
|
||||||
<Company></Company>
|
<Company></Company>
|
||||||
<Version>1.12.2</Version>
|
<Version>1.12.3</Version>
|
||||||
<Description></Description>
|
<Description></Description>
|
||||||
<Copyright></Copyright>
|
<Copyright></Copyright>
|
||||||
<PackageProjectUrl>https://github.com/Light-Public-Syncshells/LightlessClient</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/Light-Public-Syncshells/LightlessClient</PackageProjectUrl>
|
||||||
|
|||||||
@@ -98,7 +98,19 @@ public class PlayerDataFactory
|
|||||||
|
|
||||||
private unsafe bool CheckForNullDrawObjectUnsafe(IntPtr playerPointer)
|
private unsafe bool CheckForNullDrawObjectUnsafe(IntPtr playerPointer)
|
||||||
{
|
{
|
||||||
return ((Character*)playerPointer)->GameObject.DrawObject == null;
|
if (playerPointer == IntPtr.Zero)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var character = (Character*)playerPointer;
|
||||||
|
|
||||||
|
if (character == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
var gameObject = &character->GameObject;
|
||||||
|
if (gameObject == null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return gameObject->DrawObject == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<CharacterDataFragment> CreateCharacterData(GameObjectHandler playerRelatedObject, CancellationToken ct)
|
private async Task<CharacterDataFragment> CreateCharacterData(GameObjectHandler playerRelatedObject, CancellationToken ct)
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ public record PetNamesMessage(string PetNicknamesData) : MessageBase;
|
|||||||
public record HonorificReadyMessage : MessageBase;
|
public record HonorificReadyMessage : MessageBase;
|
||||||
public record TransientResourceChangedMessage(IntPtr Address) : MessageBase;
|
public record TransientResourceChangedMessage(IntPtr Address) : MessageBase;
|
||||||
public record HaltScanMessage(string Source) : MessageBase;
|
public record HaltScanMessage(string Source) : MessageBase;
|
||||||
public record ResumeScanMessage(string Source) : MessageBase;
|
|
||||||
public record NotificationMessage
|
public record NotificationMessage
|
||||||
(string Title, string Message, NotificationType Type, TimeSpan? TimeShownOnScreen = null) : MessageBase;
|
(string Title, string Message, NotificationType Type, TimeSpan? TimeShownOnScreen = null) : MessageBase;
|
||||||
public record CreateCacheForObjectMessage(GameObjectHandler ObjectToCreateFor) : SameThreadMessage;
|
public record CreateCacheForObjectMessage(GameObjectHandler ObjectToCreateFor) : SameThreadMessage;
|
||||||
@@ -56,12 +55,14 @@ public record ClearCacheForObjectMessage(GameObjectHandler ObjectToCreateFor) :
|
|||||||
public record CharacterDataCreatedMessage(CharacterData CharacterData) : SameThreadMessage;
|
public record CharacterDataCreatedMessage(CharacterData CharacterData) : SameThreadMessage;
|
||||||
public record LightlessNotificationMessage(LightlessSync.UI.Models.LightlessNotification Notification) : MessageBase;
|
public record LightlessNotificationMessage(LightlessSync.UI.Models.LightlessNotification Notification) : MessageBase;
|
||||||
public record LightlessNotificationDismissMessage(string NotificationId) : MessageBase;
|
public record LightlessNotificationDismissMessage(string NotificationId) : MessageBase;
|
||||||
|
public record ClearAllNotificationsMessage : MessageBase;
|
||||||
public record CharacterDataAnalyzedMessage : MessageBase;
|
public record CharacterDataAnalyzedMessage : MessageBase;
|
||||||
public record PenumbraStartRedrawMessage(IntPtr Address) : MessageBase;
|
public record PenumbraStartRedrawMessage(IntPtr Address) : MessageBase;
|
||||||
public record PenumbraEndRedrawMessage(IntPtr Address) : MessageBase;
|
public record PenumbraEndRedrawMessage(IntPtr Address) : MessageBase;
|
||||||
public record HubReconnectingMessage(Exception? Exception) : SameThreadMessage;
|
public record HubReconnectingMessage(Exception? Exception) : SameThreadMessage;
|
||||||
public record HubReconnectedMessage(string? Arg) : SameThreadMessage;
|
public record HubReconnectedMessage(string? Arg) : SameThreadMessage;
|
||||||
public record HubClosedMessage(Exception? Exception) : SameThreadMessage;
|
public record HubClosedMessage(Exception? Exception) : SameThreadMessage;
|
||||||
|
public record ResumeScanMessage(string Source) : MessageBase;
|
||||||
public record DownloadReadyMessage(Guid RequestId) : MessageBase;
|
public record DownloadReadyMessage(Guid RequestId) : MessageBase;
|
||||||
public record DownloadStartedMessage(GameObjectHandler DownloadId, Dictionary<string, FileDownloadStatus> DownloadStatus) : MessageBase;
|
public record DownloadStartedMessage(GameObjectHandler DownloadId, Dictionary<string, FileDownloadStatus> DownloadStatus) : MessageBase;
|
||||||
public record DownloadFinishedMessage(GameObjectHandler DownloadId) : MessageBase;
|
public record DownloadFinishedMessage(GameObjectHandler DownloadId) : MessageBase;
|
||||||
|
|||||||
@@ -201,6 +201,9 @@ public unsafe class NameplateHandler : IMediatorSubscriber
|
|||||||
private void UpdateNameplateNodes()
|
private void UpdateNameplateNodes()
|
||||||
{
|
{
|
||||||
var framework = Framework.Instance();
|
var framework = Framework.Instance();
|
||||||
|
|
||||||
|
if (framework == null) return;
|
||||||
|
|
||||||
var ui3DModule = framework->GetUIModule()->GetUI3DModule();
|
var ui3DModule = framework->GetUIModule()->GetUI3DModule();
|
||||||
|
|
||||||
if (ui3DModule == null)
|
if (ui3DModule == null)
|
||||||
@@ -208,7 +211,13 @@ public unsafe class NameplateHandler : IMediatorSubscriber
|
|||||||
|
|
||||||
for (int i = 0; i < ui3DModule->NamePlateObjectInfoCount; ++i)
|
for (int i = 0; i < ui3DModule->NamePlateObjectInfoCount; ++i)
|
||||||
{
|
{
|
||||||
var objectInfo = ui3DModule->NamePlateObjectInfoPointers[i].Value;
|
if (ui3DModule->NamePlateObjectInfoPointers.IsEmpty) continue;
|
||||||
|
|
||||||
|
var objectInfoPtr = ui3DModule->NamePlateObjectInfoPointers[i];
|
||||||
|
|
||||||
|
if (objectInfoPtr == null) continue;
|
||||||
|
|
||||||
|
var objectInfo = objectInfoPtr.Value;
|
||||||
|
|
||||||
if (objectInfo == null || objectInfo->GameObject == null)
|
if (objectInfo == null || objectInfo->GameObject == null)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
|||||||
private readonly List<LightlessNotification> _notifications = new();
|
private readonly List<LightlessNotification> _notifications = new();
|
||||||
private readonly object _notificationLock = new();
|
private readonly object _notificationLock = new();
|
||||||
private readonly LightlessConfigService _configService;
|
private readonly LightlessConfigService _configService;
|
||||||
|
private readonly Dictionary<string, float> _notificationYOffsets = new();
|
||||||
|
private readonly Dictionary<string, float> _notificationTargetYOffsets = new();
|
||||||
|
|
||||||
public LightlessNotificationUI(ILogger<LightlessNotificationUI> logger, LightlessMediator mediator, PerformanceCollectorService performanceCollector, LightlessConfigService configService)
|
public LightlessNotificationUI(ILogger<LightlessNotificationUI> logger, LightlessMediator mediator, PerformanceCollectorService performanceCollector, LightlessConfigService configService)
|
||||||
: base(logger, mediator, "Lightless Notifications##LightlessNotifications", performanceCollector)
|
: base(logger, mediator, "Lightless Notifications##LightlessNotifications", performanceCollector)
|
||||||
@@ -49,12 +51,11 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
|||||||
|
|
||||||
Mediator.Subscribe<LightlessNotificationMessage>(this, HandleNotificationMessage);
|
Mediator.Subscribe<LightlessNotificationMessage>(this, HandleNotificationMessage);
|
||||||
Mediator.Subscribe<LightlessNotificationDismissMessage>(this, HandleNotificationDismissMessage);
|
Mediator.Subscribe<LightlessNotificationDismissMessage>(this, HandleNotificationDismissMessage);
|
||||||
|
Mediator.Subscribe<ClearAllNotificationsMessage>(this, HandleClearAllNotifications);
|
||||||
}
|
}
|
||||||
private void HandleNotificationMessage(LightlessNotificationMessage message) =>
|
private void HandleNotificationMessage(LightlessNotificationMessage message) => AddNotification(message.Notification);
|
||||||
AddNotification(message.Notification);
|
private void HandleNotificationDismissMessage(LightlessNotificationDismissMessage message) => RemoveNotification(message.NotificationId);
|
||||||
|
private void HandleClearAllNotifications(ClearAllNotificationsMessage message) => ClearAllNotifications();
|
||||||
private void HandleNotificationDismissMessage(LightlessNotificationDismissMessage message) =>
|
|
||||||
RemoveNotification(message.NotificationId);
|
|
||||||
|
|
||||||
public void AddNotification(LightlessNotification notification)
|
public void AddNotification(LightlessNotification notification)
|
||||||
{
|
{
|
||||||
@@ -96,20 +97,34 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearAllNotifications()
|
||||||
|
{
|
||||||
|
lock (_notificationLock)
|
||||||
|
{
|
||||||
|
foreach (var notification in _notifications)
|
||||||
|
{
|
||||||
|
StartOutAnimation(notification);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void StartOutAnimation(LightlessNotification notification)
|
private void StartOutAnimation(LightlessNotification notification)
|
||||||
{
|
{
|
||||||
notification.IsAnimatingOut = true;
|
notification.IsAnimatingOut = true;
|
||||||
notification.IsAnimatingIn = false;
|
notification.IsAnimatingIn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool ShouldRemoveNotification(LightlessNotification notification) =>
|
||||||
|
notification.IsAnimatingOut && notification.AnimationProgress <= 0.01f;
|
||||||
|
|
||||||
protected override void DrawInternal()
|
protected override void DrawInternal()
|
||||||
{
|
{
|
||||||
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
|
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
|
||||||
|
|
||||||
lock (_notificationLock)
|
lock (_notificationLock)
|
||||||
{
|
{
|
||||||
UpdateNotifications();
|
UpdateNotifications();
|
||||||
|
|
||||||
if (_notifications.Count == 0)
|
if (_notifications.Count == 0)
|
||||||
{
|
{
|
||||||
ImGui.PopStyleVar();
|
ImGui.PopStyleVar();
|
||||||
@@ -118,33 +133,49 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
var viewport = ImGui.GetMainViewport();
|
var viewport = ImGui.GetMainViewport();
|
||||||
|
|
||||||
|
// Set window to full viewport height
|
||||||
|
var width = _configService.Current.NotificationWidth;
|
||||||
|
Size = new Vector2(width, viewport.WorkSize.Y);
|
||||||
|
SizeCondition = ImGuiCond.Always;
|
||||||
|
|
||||||
Position = CalculateWindowPosition(viewport);
|
Position = CalculateWindowPosition(viewport);
|
||||||
|
PositionCondition = ImGuiCond.Always;
|
||||||
|
|
||||||
DrawAllNotifications();
|
DrawAllNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.PopStyleVar();
|
ImGui.PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector2 CalculateWindowPosition(ImGuiViewportPtr viewport)
|
private Vector2 CalculateWindowPosition(ImGuiViewportPtr viewport)
|
||||||
{
|
{
|
||||||
var x = viewport.WorkPos.X + viewport.WorkSize.X -
|
var corner = _configService.Current.NotificationCorner;
|
||||||
_configService.Current.NotificationWidth -
|
var offsetX = _configService.Current.NotificationOffsetX;
|
||||||
_configService.Current.NotificationOffsetX -
|
var width = _configService.Current.NotificationWidth;
|
||||||
WindowPaddingOffset;
|
|
||||||
var y = viewport.WorkPos.Y + _configService.Current.NotificationOffsetY;
|
float posX = corner == NotificationCorner.Left
|
||||||
return new Vector2(x, y);
|
? viewport.WorkPos.X + offsetX - WindowPaddingOffset
|
||||||
|
: viewport.WorkPos.X + viewport.WorkSize.X - width - offsetX - WindowPaddingOffset;
|
||||||
|
|
||||||
|
return new Vector2(posX, viewport.WorkPos.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawAllNotifications()
|
private void DrawAllNotifications()
|
||||||
{
|
{
|
||||||
|
var offsetY = _configService.Current.NotificationOffsetY;
|
||||||
|
var startY = ImGui.GetCursorPosY() + offsetY;
|
||||||
|
|
||||||
for (int i = 0; i < _notifications.Count; i++)
|
for (int i = 0; i < _notifications.Count; i++)
|
||||||
{
|
{
|
||||||
DrawNotification(_notifications[i], i);
|
var notification = _notifications[i];
|
||||||
|
|
||||||
if (i < _notifications.Count - 1)
|
if (_notificationYOffsets.TryGetValue(notification.Id, out var yOffset))
|
||||||
{
|
{
|
||||||
ImGui.Dummy(new Vector2(0, _configService.Current.NotificationSpacing));
|
ImGui.SetCursorPosY(startY + yOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DrawNotification(notification, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,18 +205,65 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
|||||||
|
|
||||||
private void UpdateAnimationsAndRemoveExpired(float deltaTime)
|
private void UpdateAnimationsAndRemoveExpired(float deltaTime)
|
||||||
{
|
{
|
||||||
|
UpdateTargetYPositions();
|
||||||
|
|
||||||
for (int i = _notifications.Count - 1; i >= 0; i--)
|
for (int i = _notifications.Count - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
var notification = _notifications[i];
|
var notification = _notifications[i];
|
||||||
UpdateNotificationAnimation(notification, deltaTime);
|
UpdateNotificationAnimation(notification, deltaTime);
|
||||||
|
UpdateNotificationYOffset(notification, deltaTime);
|
||||||
|
|
||||||
if (ShouldRemoveNotification(notification))
|
if (ShouldRemoveNotification(notification))
|
||||||
{
|
{
|
||||||
_notifications.RemoveAt(i);
|
_notifications.RemoveAt(i);
|
||||||
|
_notificationYOffsets.Remove(notification.Id);
|
||||||
|
_notificationTargetYOffsets.Remove(notification.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void UpdateTargetYPositions()
|
||||||
|
{
|
||||||
|
float currentY = 0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < _notifications.Count; i++)
|
||||||
|
{
|
||||||
|
var notification = _notifications[i];
|
||||||
|
|
||||||
|
if (!_notificationTargetYOffsets.ContainsKey(notification.Id))
|
||||||
|
{
|
||||||
|
_notificationTargetYOffsets[notification.Id] = currentY;
|
||||||
|
_notificationYOffsets[notification.Id] = currentY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_notificationTargetYOffsets[notification.Id] = currentY;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentY += CalculateNotificationHeight(notification) + _configService.Current.NotificationSpacing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateNotificationYOffset(LightlessNotification notification, float deltaTime)
|
||||||
|
{
|
||||||
|
if (!_notificationYOffsets.ContainsKey(notification.Id) || !_notificationTargetYOffsets.ContainsKey(notification.Id))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var current = _notificationYOffsets[notification.Id];
|
||||||
|
var target = _notificationTargetYOffsets[notification.Id];
|
||||||
|
var diff = target - current;
|
||||||
|
|
||||||
|
if (Math.Abs(diff) < 0.5f)
|
||||||
|
{
|
||||||
|
_notificationYOffsets[notification.Id] = target;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var speed = _configService.Current.NotificationSlideSpeed;
|
||||||
|
_notificationYOffsets[notification.Id] = current + (diff * deltaTime * speed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void UpdateNotificationAnimation(LightlessNotification notification, float deltaTime)
|
private void UpdateNotificationAnimation(LightlessNotification notification, float deltaTime)
|
||||||
{
|
{
|
||||||
if (notification.IsAnimatingIn && notification.AnimationProgress < 1f)
|
if (notification.IsAnimatingIn && notification.AnimationProgress < 1f)
|
||||||
@@ -209,20 +287,24 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool ShouldRemoveNotification(LightlessNotification notification) =>
|
private Vector2 CalculateSlideOffset(float alpha)
|
||||||
notification.IsAnimatingOut && notification.AnimationProgress <= 0.01f;
|
{
|
||||||
|
var distance = (1f - alpha) * SlideAnimationDistance;
|
||||||
|
var corner = _configService.Current.NotificationCorner;
|
||||||
|
return corner == NotificationCorner.Left ? new Vector2(-distance, 0) : new Vector2(distance, 0);
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawNotification(LightlessNotification notification, int index)
|
private void DrawNotification(LightlessNotification notification, int index)
|
||||||
{
|
{
|
||||||
var alpha = notification.AnimationProgress;
|
var alpha = notification.AnimationProgress;
|
||||||
if (alpha <= 0f) return;
|
if (alpha <= 0f) return;
|
||||||
|
|
||||||
var slideOffset = (1f - alpha) * SlideAnimationDistance;
|
var slideOffset = CalculateSlideOffset(alpha);
|
||||||
var originalCursorPos = ImGui.GetCursorPos();
|
var originalCursorPos = ImGui.GetCursorPos();
|
||||||
ImGui.SetCursorPosX(originalCursorPos.X + slideOffset);
|
ImGui.SetCursorPos(originalCursorPos + slideOffset);
|
||||||
|
|
||||||
var notificationHeight = CalculateNotificationHeight(notification);
|
var notificationHeight = CalculateNotificationHeight(notification);
|
||||||
var notificationWidth = _configService.Current.NotificationWidth - slideOffset;
|
var notificationWidth = _configService.Current.NotificationWidth - Math.Abs(slideOffset.X);
|
||||||
|
|
||||||
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
|
ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, Vector2.Zero);
|
||||||
|
|
||||||
@@ -308,15 +390,28 @@ public class LightlessNotificationUI : WindowMediatorSubscriberBase
|
|||||||
private void DrawAccentBar(ImDrawListPtr drawList, Vector2 windowPos, Vector2 windowSize, Vector4 accentColor)
|
private void DrawAccentBar(ImDrawListPtr drawList, Vector2 windowPos, Vector2 windowSize, Vector4 accentColor)
|
||||||
{
|
{
|
||||||
var accentWidth = _configService.Current.NotificationAccentBarWidth;
|
var accentWidth = _configService.Current.NotificationAccentBarWidth;
|
||||||
if (accentWidth > 0f)
|
if (accentWidth <= 0f) return;
|
||||||
|
|
||||||
|
var corner = _configService.Current.NotificationCorner;
|
||||||
|
Vector2 accentStart, accentEnd;
|
||||||
|
|
||||||
|
if (corner == NotificationCorner.Left)
|
||||||
{
|
{
|
||||||
drawList.AddRectFilled(
|
accentStart = windowPos + new Vector2(windowSize.X - accentWidth, 0);
|
||||||
windowPos,
|
accentEnd = windowPos + windowSize;
|
||||||
windowPos + new Vector2(accentWidth, windowSize.Y),
|
|
||||||
ImGui.ColorConvertFloat4ToU32(accentColor),
|
|
||||||
3f
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
accentStart = windowPos;
|
||||||
|
accentEnd = windowPos + new Vector2(accentWidth, windowSize.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
drawList.AddRectFilled(
|
||||||
|
accentStart,
|
||||||
|
accentEnd,
|
||||||
|
ImGui.ColorConvertFloat4ToU32(accentColor),
|
||||||
|
3f
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawDurationProgressBar(LightlessNotification notification, float alpha, Vector2 windowPos, Vector2 windowSize, ImDrawListPtr drawList)
|
private void DrawDurationProgressBar(LightlessNotification notification, float alpha, Vector2 windowPos, Vector2 windowSize, ImDrawListPtr drawList)
|
||||||
|
|||||||
@@ -3493,69 +3493,162 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
if (useLightlessNotifications)
|
if (useLightlessNotifications)
|
||||||
{
|
{
|
||||||
// Lightless notification locations
|
// Lightless notification locations
|
||||||
ImGui.Indent();
|
|
||||||
|
|
||||||
var lightlessLocations = GetLightlessNotificationLocations();
|
var lightlessLocations = GetLightlessNotificationLocations();
|
||||||
|
|
||||||
ImGui.AlignTextToFramePadding();
|
|
||||||
ImGui.TextUnformatted("Info Notifications:");
|
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
|
||||||
_uiShared.DrawCombo("###enhanced_info", lightlessLocations, GetNotificationLocationLabel, (location) =>
|
|
||||||
{
|
|
||||||
_configService.Current.LightlessInfoNotification = location;
|
|
||||||
_configService.Save();
|
|
||||||
}, _configService.Current.LightlessInfoNotification);
|
|
||||||
|
|
||||||
ImGui.AlignTextToFramePadding();
|
|
||||||
ImGui.TextUnformatted("Warning Notifications:");
|
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
|
||||||
_uiShared.DrawCombo("###enhanced_warning", lightlessLocations, GetNotificationLocationLabel,
|
|
||||||
(location) =>
|
|
||||||
{
|
|
||||||
_configService.Current.LightlessWarningNotification = location;
|
|
||||||
_configService.Save();
|
|
||||||
}, _configService.Current.LightlessWarningNotification);
|
|
||||||
|
|
||||||
ImGui.AlignTextToFramePadding();
|
|
||||||
ImGui.TextUnformatted("Error Notifications:");
|
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
|
||||||
_uiShared.DrawCombo("###enhanced_error", lightlessLocations, GetNotificationLocationLabel, (location) =>
|
|
||||||
{
|
|
||||||
_configService.Current.LightlessErrorNotification = location;
|
|
||||||
_configService.Save();
|
|
||||||
}, _configService.Current.LightlessErrorNotification);
|
|
||||||
|
|
||||||
ImGuiHelpers.ScaledDummy(3);
|
|
||||||
_uiShared.DrawHelpText("Special notification types:");
|
|
||||||
|
|
||||||
ImGui.AlignTextToFramePadding();
|
|
||||||
ImGui.TextUnformatted("Pair Request Notifications:");
|
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
|
||||||
_uiShared.DrawCombo("###enhanced_pairrequest", lightlessLocations, GetNotificationLocationLabel,
|
|
||||||
(location) =>
|
|
||||||
{
|
|
||||||
_configService.Current.LightlessPairRequestNotification = location;
|
|
||||||
_configService.Save();
|
|
||||||
}, _configService.Current.LightlessPairRequestNotification);
|
|
||||||
|
|
||||||
ImGui.AlignTextToFramePadding();
|
|
||||||
ImGui.TextUnformatted("Download Progress Notifications:");
|
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
|
||||||
var downloadLocations = GetDownloadNotificationLocations();
|
var downloadLocations = GetDownloadNotificationLocations();
|
||||||
_uiShared.DrawCombo("###enhanced_download", downloadLocations, GetNotificationLocationLabel,
|
|
||||||
(location) =>
|
if (ImGui.BeginTable("##NotificationLocationTable", 3, ImGuiTableFlags.Borders | ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit))
|
||||||
|
{
|
||||||
|
ImGui.TableSetupColumn("Notification Type", ImGuiTableColumnFlags.WidthFixed, 200f * ImGuiHelpers.GlobalScale);
|
||||||
|
ImGui.TableSetupColumn("Location", ImGuiTableColumnFlags.WidthStretch);
|
||||||
|
ImGui.TableSetupColumn("Test", ImGuiTableColumnFlags.WidthFixed, 40f * ImGuiHelpers.GlobalScale);
|
||||||
|
ImGui.TableHeadersRow();
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
ImGui.AlignTextToFramePadding();
|
||||||
|
ImGui.TextUnformatted("Info Notifications");
|
||||||
|
ImGui.TableSetColumnIndex(1);
|
||||||
|
ImGui.SetNextItemWidth(-1);
|
||||||
|
_uiShared.DrawCombo("###enhanced_info", lightlessLocations, GetNotificationLocationLabel, (location) =>
|
||||||
{
|
{
|
||||||
_configService.Current.LightlessDownloadNotification = location;
|
_configService.Current.LightlessInfoNotification = location;
|
||||||
_configService.Save();
|
_configService.Save();
|
||||||
}, _configService.Current.LightlessDownloadNotification);
|
}, _configService.Current.LightlessInfoNotification);
|
||||||
|
ImGui.TableSetColumnIndex(2);
|
||||||
|
var availableWidth = ImGui.GetContentRegionAvail().X;
|
||||||
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||||
|
{
|
||||||
|
if (ImGui.Button($"{FontAwesomeIcon.Play.ToIconString()}##test_info", new Vector2(availableWidth, 0)))
|
||||||
|
{
|
||||||
|
Mediator.Publish(new NotificationMessage("Test Info",
|
||||||
|
"This is a test info notification to let you know Chocola is cute :3", NotificationType.Info));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UiSharedService.AttachToolTip("Test info notification");
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
ImGui.AlignTextToFramePadding();
|
||||||
|
ImGui.TextUnformatted("Warning Notifications");
|
||||||
|
ImGui.TableSetColumnIndex(1);
|
||||||
|
ImGui.SetNextItemWidth(-1);
|
||||||
|
_uiShared.DrawCombo("###enhanced_warning", lightlessLocations, GetNotificationLocationLabel,
|
||||||
|
(location) =>
|
||||||
|
{
|
||||||
|
_configService.Current.LightlessWarningNotification = location;
|
||||||
|
_configService.Save();
|
||||||
|
}, _configService.Current.LightlessWarningNotification);
|
||||||
|
ImGui.TableSetColumnIndex(2);
|
||||||
|
availableWidth = ImGui.GetContentRegionAvail().X;
|
||||||
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||||
|
{
|
||||||
|
if (ImGui.Button($"{FontAwesomeIcon.Play.ToIconString()}##test_warning", new Vector2(availableWidth, 0)))
|
||||||
|
{
|
||||||
|
Mediator.Publish(new NotificationMessage("Test Warning", "This is a test warning notification!",
|
||||||
|
NotificationType.Warning));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UiSharedService.AttachToolTip("Test warning notification");
|
||||||
|
|
||||||
ImGui.Unindent();
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
ImGui.AlignTextToFramePadding();
|
||||||
|
ImGui.TextUnformatted("Error Notifications");
|
||||||
|
ImGui.TableSetColumnIndex(1);
|
||||||
|
ImGui.SetNextItemWidth(-1);
|
||||||
|
_uiShared.DrawCombo("###enhanced_error", lightlessLocations, GetNotificationLocationLabel, (location) =>
|
||||||
|
{
|
||||||
|
_configService.Current.LightlessErrorNotification = location;
|
||||||
|
_configService.Save();
|
||||||
|
}, _configService.Current.LightlessErrorNotification);
|
||||||
|
ImGui.TableSetColumnIndex(2);
|
||||||
|
availableWidth = ImGui.GetContentRegionAvail().X;
|
||||||
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||||
|
{
|
||||||
|
if (ImGui.Button($"{FontAwesomeIcon.Play.ToIconString()}##test_error", new Vector2(availableWidth, 0)))
|
||||||
|
{
|
||||||
|
Mediator.Publish(new NotificationMessage("Test Error", "This is a test error notification!",
|
||||||
|
NotificationType.Error));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UiSharedService.AttachToolTip("Test error notification");
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
ImGui.AlignTextToFramePadding();
|
||||||
|
ImGui.TextUnformatted("Pair Request Notifications");
|
||||||
|
ImGui.TableSetColumnIndex(1);
|
||||||
|
ImGui.SetNextItemWidth(-1);
|
||||||
|
_uiShared.DrawCombo("###enhanced_pairrequest", lightlessLocations, GetNotificationLocationLabel,
|
||||||
|
(location) =>
|
||||||
|
{
|
||||||
|
_configService.Current.LightlessPairRequestNotification = location;
|
||||||
|
_configService.Save();
|
||||||
|
}, _configService.Current.LightlessPairRequestNotification);
|
||||||
|
ImGui.TableSetColumnIndex(2);
|
||||||
|
availableWidth = ImGui.GetContentRegionAvail().X;
|
||||||
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||||
|
{
|
||||||
|
if (ImGui.Button($"{FontAwesomeIcon.Play.ToIconString()}##test_pair", new Vector2(availableWidth, 0)))
|
||||||
|
{
|
||||||
|
_lightlessNotificationService.ShowPairRequestNotification(
|
||||||
|
"Test User",
|
||||||
|
"test-uid-123",
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
Mediator.Publish(new NotificationMessage("Accepted", "You accepted the test pair request.",
|
||||||
|
NotificationType.Info));
|
||||||
|
},
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
Mediator.Publish(new NotificationMessage("Declined", "You declined the test pair request.",
|
||||||
|
NotificationType.Info));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UiSharedService.AttachToolTip("Test pair request notification");
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
ImGui.AlignTextToFramePadding();
|
||||||
|
ImGui.TextUnformatted("Download Progress Notifications");
|
||||||
|
ImGui.TableSetColumnIndex(1);
|
||||||
|
ImGui.SetNextItemWidth(-1);
|
||||||
|
_uiShared.DrawCombo("###enhanced_download", downloadLocations, GetNotificationLocationLabel,
|
||||||
|
(location) =>
|
||||||
|
{
|
||||||
|
_configService.Current.LightlessDownloadNotification = location;
|
||||||
|
_configService.Save();
|
||||||
|
}, _configService.Current.LightlessDownloadNotification);
|
||||||
|
ImGui.TableSetColumnIndex(2);
|
||||||
|
availableWidth = ImGui.GetContentRegionAvail().X;
|
||||||
|
using (ImRaii.PushFont(UiBuilder.IconFont))
|
||||||
|
{
|
||||||
|
if (ImGui.Button($"{FontAwesomeIcon.Play.ToIconString()}##test_download", new Vector2(availableWidth, 0)))
|
||||||
|
{
|
||||||
|
_lightlessNotificationService.ShowPairDownloadNotification(
|
||||||
|
new List<(string playerName, float progress, string status)>
|
||||||
|
{
|
||||||
|
("Player One", 0.35f, "downloading"),
|
||||||
|
("Player Two", 0.75f, "downloading"),
|
||||||
|
("Player Three", 1.0f, "downloading")
|
||||||
|
},
|
||||||
|
queueWaiting: 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UiSharedService.AttachToolTip("Test download progress notification");
|
||||||
|
|
||||||
|
ImGui.EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiHelpers.ScaledDummy(5);
|
||||||
|
if (_uiShared.IconTextButton(FontAwesomeIcon.Trash, "Clear All Notifications"))
|
||||||
|
{
|
||||||
|
Mediator.Publish(new ClearAllNotificationsMessage());
|
||||||
|
}
|
||||||
|
_uiShared.DrawHelpText("Dismiss all active notifications immediately.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -3602,73 +3695,6 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
if (useLightlessNotifications)
|
if (useLightlessNotifications)
|
||||||
{
|
{
|
||||||
if (_uiShared.MediumTreeNode("Test Notifications", UIColors.Get("LightlessPurple")))
|
|
||||||
{
|
|
||||||
ImGui.Indent();
|
|
||||||
|
|
||||||
// Test notification buttons
|
|
||||||
if (_uiShared.IconTextButton(FontAwesomeIcon.Bell, "Test Info"))
|
|
||||||
{
|
|
||||||
Mediator.Publish(new NotificationMessage("Test Info",
|
|
||||||
"This is a test info notification to let you know Chocola is cute :3", NotificationType.Info));
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
if (_uiShared.IconTextButton(FontAwesomeIcon.ExclamationTriangle, "Test Warning"))
|
|
||||||
{
|
|
||||||
Mediator.Publish(new NotificationMessage("Test Warning", "This is a test warning notification!",
|
|
||||||
NotificationType.Warning));
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
if (_uiShared.IconTextButton(FontAwesomeIcon.ExclamationCircle, "Test Error"))
|
|
||||||
{
|
|
||||||
Mediator.Publish(new NotificationMessage("Test Error", "This is a test error notification!",
|
|
||||||
NotificationType.Error));
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGuiHelpers.ScaledDummy(3);
|
|
||||||
if (_uiShared.IconTextButton(FontAwesomeIcon.UserPlus, "Test Pair Request"))
|
|
||||||
{
|
|
||||||
_lightlessNotificationService.ShowPairRequestNotification(
|
|
||||||
"Test User",
|
|
||||||
"test-uid-123",
|
|
||||||
() =>
|
|
||||||
{
|
|
||||||
Mediator.Publish(new NotificationMessage("Accepted", "You accepted the test pair request.",
|
|
||||||
NotificationType.Info));
|
|
||||||
},
|
|
||||||
() =>
|
|
||||||
{
|
|
||||||
Mediator.Publish(new NotificationMessage("Declined", "You declined the test pair request.",
|
|
||||||
NotificationType.Info));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.SameLine();
|
|
||||||
if (_uiShared.IconTextButton(FontAwesomeIcon.Download, "Test Download Progress"))
|
|
||||||
{
|
|
||||||
_lightlessNotificationService.ShowPairDownloadNotification(
|
|
||||||
new List<(string playerName, float progress, string status)>
|
|
||||||
{
|
|
||||||
("Player One", 0.35f, "downloading"),
|
|
||||||
("Player Two", 0.75f, "downloading"),
|
|
||||||
("Player Three", 1.0f, "downloading")
|
|
||||||
},
|
|
||||||
queueWaiting: 2
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_uiShared.DrawHelpText("Preview how notifications will appear with your current settings.");
|
|
||||||
|
|
||||||
ImGui.Unindent();
|
|
||||||
|
|
||||||
_uiShared.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
|
|
||||||
ImGui.TreePop();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui.Separator();
|
|
||||||
if (_uiShared.MediumTreeNode("Basic Settings", UIColors.Get("LightlessPurple")))
|
if (_uiShared.MediumTreeNode("Basic Settings", UIColors.Get("LightlessPurple")))
|
||||||
{
|
{
|
||||||
int maxNotifications = _configService.Current.MaxSimultaneousNotifications;
|
int maxNotifications = _configService.Current.MaxSimultaneousNotifications;
|
||||||
@@ -3768,10 +3794,28 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
ImGui.Spacing();
|
ImGui.Spacing();
|
||||||
ImGui.TextUnformatted("Position");
|
ImGui.TextUnformatted("Position");
|
||||||
|
|
||||||
int offsetY = _configService.Current.NotificationOffsetY;
|
var currentCorner = _configService.Current.NotificationCorner;
|
||||||
if (ImGui.SliderInt("Vertical Offset", ref offsetY, 0, 500))
|
if (ImGui.BeginCombo("Notification Position", GetNotificationCornerLabel(currentCorner)))
|
||||||
{
|
{
|
||||||
_configService.Current.NotificationOffsetY = Math.Clamp(offsetY, 0, 500);
|
foreach (NotificationCorner corner in Enum.GetValues(typeof(NotificationCorner)))
|
||||||
|
{
|
||||||
|
bool isSelected = currentCorner == corner;
|
||||||
|
if (ImGui.Selectable(GetNotificationCornerLabel(corner), isSelected))
|
||||||
|
{
|
||||||
|
_configService.Current.NotificationCorner = corner;
|
||||||
|
_configService.Save();
|
||||||
|
}
|
||||||
|
if (isSelected)
|
||||||
|
ImGui.SetItemDefaultFocus();
|
||||||
|
}
|
||||||
|
ImGui.EndCombo();
|
||||||
|
}
|
||||||
|
_uiShared.DrawHelpText("Choose which corner of the screen notifications appear in.");
|
||||||
|
|
||||||
|
int offsetY = _configService.Current.NotificationOffsetY;
|
||||||
|
if (ImGui.SliderInt("Vertical Offset", ref offsetY, 0, 1000))
|
||||||
|
{
|
||||||
|
_configService.Current.NotificationOffsetY = Math.Clamp(offsetY, 0, 1000);
|
||||||
_configService.Save();
|
_configService.Save();
|
||||||
}
|
}
|
||||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||||
@@ -3781,7 +3825,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
}
|
}
|
||||||
if (ImGui.IsItemHovered())
|
if (ImGui.IsItemHovered())
|
||||||
ImGui.SetTooltip("Right click to reset to default (50).");
|
ImGui.SetTooltip("Right click to reset to default (50).");
|
||||||
_uiShared.DrawHelpText("Move notifications down from the top-right corner.");
|
_uiShared.DrawHelpText("Distance from the top edge of the screen.");
|
||||||
|
|
||||||
int offsetX = _configService.Current.NotificationOffsetX;
|
int offsetX = _configService.Current.NotificationOffsetX;
|
||||||
if (ImGui.SliderInt("Horizontal Offset", ref offsetX, 0, 500))
|
if (ImGui.SliderInt("Horizontal Offset", ref offsetX, 0, 500))
|
||||||
@@ -3802,9 +3846,9 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
ImGui.TextUnformatted("Animation Settings");
|
ImGui.TextUnformatted("Animation Settings");
|
||||||
|
|
||||||
float animSpeed = _configService.Current.NotificationAnimationSpeed;
|
float animSpeed = _configService.Current.NotificationAnimationSpeed;
|
||||||
if (ImGui.SliderFloat("Animation Speed", ref animSpeed, 1f, 30f, "%.1f"))
|
if (ImGui.SliderFloat("Animation Speed", ref animSpeed, 1f, 20f, "%.1f"))
|
||||||
{
|
{
|
||||||
_configService.Current.NotificationAnimationSpeed = Math.Clamp(animSpeed, 1f, 30f);
|
_configService.Current.NotificationAnimationSpeed = Math.Clamp(animSpeed, 1f, 20f);
|
||||||
_configService.Save();
|
_configService.Save();
|
||||||
}
|
}
|
||||||
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||||
@@ -3816,6 +3860,21 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
ImGui.SetTooltip("Right click to reset to default (10).");
|
ImGui.SetTooltip("Right click to reset to default (10).");
|
||||||
_uiShared.DrawHelpText("How fast notifications slide in/out. Higher = faster.");
|
_uiShared.DrawHelpText("How fast notifications slide in/out. Higher = faster.");
|
||||||
|
|
||||||
|
float slideSpeed = _configService.Current.NotificationSlideSpeed;
|
||||||
|
if (ImGui.SliderFloat("Slide Speed", ref slideSpeed, 1f, 20f, "%.1f"))
|
||||||
|
{
|
||||||
|
_configService.Current.NotificationSlideSpeed = Math.Clamp(slideSpeed, 1f, 20f);
|
||||||
|
_configService.Save();
|
||||||
|
}
|
||||||
|
if (ImGui.IsItemClicked(ImGuiMouseButton.Right))
|
||||||
|
{
|
||||||
|
_configService.Current.NotificationSlideSpeed = 10f;
|
||||||
|
_configService.Save();
|
||||||
|
}
|
||||||
|
if (ImGui.IsItemHovered())
|
||||||
|
ImGui.SetTooltip("Right click to reset to default (10).");
|
||||||
|
_uiShared.DrawHelpText("How fast notifications slide into position when others disappear. Higher = faster.");
|
||||||
|
|
||||||
ImGui.Spacing();
|
ImGui.Spacing();
|
||||||
ImGui.TextUnformatted("Visual Effects");
|
ImGui.TextUnformatted("Visual Effects");
|
||||||
|
|
||||||
@@ -3999,6 +4058,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
// Location descriptions removed - information is now inline with each setting
|
// Location descriptions removed - information is now inline with each setting
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4043,6 +4103,16 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string GetNotificationCornerLabel(NotificationCorner corner)
|
||||||
|
{
|
||||||
|
return corner switch
|
||||||
|
{
|
||||||
|
NotificationCorner.Right => "Right",
|
||||||
|
NotificationCorner.Left => "Left",
|
||||||
|
_ => corner.ToString()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawSoundTable()
|
private void DrawSoundTable()
|
||||||
{
|
{
|
||||||
var soundEffects = new[]
|
var soundEffects = new[]
|
||||||
@@ -4087,7 +4157,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
|
|||||||
var currentIndex = Array.FindIndex(soundEffects, s => s.Item1 == currentSoundId);
|
var currentIndex = Array.FindIndex(soundEffects, s => s.Item1 == currentSoundId);
|
||||||
if (currentIndex == -1) currentIndex = 1;
|
if (currentIndex == -1) currentIndex = 1;
|
||||||
|
|
||||||
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
|
ImGui.SetNextItemWidth(-1);
|
||||||
if (ImGui.Combo($"##sound_{typeIndex}", ref currentIndex,
|
if (ImGui.Combo($"##sound_{typeIndex}", ref currentIndex,
|
||||||
soundEffects.Select(s => s.Item2).ToArray(), soundEffects.Length))
|
soundEffects.Select(s => s.Item2).ToArray(), soundEffects.Length))
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user