inital
This commit is contained in:
210
FasdDesktopUi/Basics/Helper/TrayTicketNotificationManager.cs
Normal file
210
FasdDesktopUi/Basics/Helper/TrayTicketNotificationManager.cs
Normal file
@@ -0,0 +1,210 @@
|
||||
using C4IT.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Helper
|
||||
{
|
||||
internal sealed class TrayTicketNotificationManager
|
||||
{
|
||||
private readonly NotifyIcon _notifyIcon;
|
||||
private readonly object _syncRoot = new object();
|
||||
private string _baseTooltip;
|
||||
private string _currentTooltip;
|
||||
private bool _overlayInitialized;
|
||||
|
||||
private const string OverlayKey = "TicketChanges";
|
||||
private const string OverlaySetName = "OverlayTicketChanges";
|
||||
|
||||
public TrayTicketNotificationManager(NotifyIcon notifyIcon)
|
||||
{
|
||||
_notifyIcon = notifyIcon ?? throw new ArgumentNullException(nameof(notifyIcon));
|
||||
}
|
||||
|
||||
public bool HasNotification
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (_syncRoot)
|
||||
return !string.IsNullOrWhiteSpace(_currentTooltip);
|
||||
}
|
||||
}
|
||||
|
||||
public void CaptureBaseTooltip()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_baseTooltip = _notifyIcon.Text;
|
||||
}
|
||||
}
|
||||
|
||||
public void Show(string message)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(message))
|
||||
{
|
||||
Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureOverlaySet();
|
||||
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_currentTooltip = BuildTooltip(message);
|
||||
}
|
||||
|
||||
NotifyerSupport.SetNotifyIconOverlay(OverlayKey, OverlaySetName, NotifyerSupport.enumIconAlignment.TopRight, priority: 100);
|
||||
ApplyTooltip();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
lock (_syncRoot)
|
||||
{
|
||||
_currentTooltip = null;
|
||||
}
|
||||
|
||||
NotifyerSupport.SetNotifyIconOverlay(OverlayKey, null, NotifyerSupport.enumIconAlignment.TopRight);
|
||||
ApplyTooltip();
|
||||
}
|
||||
|
||||
public void ApplyTooltip()
|
||||
{
|
||||
if (_notifyIcon == null)
|
||||
return;
|
||||
|
||||
string tooltip;
|
||||
lock (_syncRoot)
|
||||
{
|
||||
tooltip = string.IsNullOrWhiteSpace(_currentTooltip)
|
||||
? _baseTooltip
|
||||
: $"F4SD - {_currentTooltip}";
|
||||
}
|
||||
|
||||
_notifyIcon.Text = TrimTooltip(tooltip);
|
||||
}
|
||||
|
||||
private void EnsureOverlaySet()
|
||||
{
|
||||
if (_overlayInitialized)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var overlayFactories = new Dictionary<int, Func<Bitmap>>();
|
||||
var sizeMap = new SortedDictionary<int, int>();
|
||||
|
||||
foreach (var size in NotifyerSupport.DefaultIconSizes)
|
||||
{
|
||||
var overlaySize = CalculateOverlayDiameter(size);
|
||||
if (overlaySize <= 0)
|
||||
continue;
|
||||
|
||||
sizeMap[size] = overlaySize;
|
||||
|
||||
if (!overlayFactories.ContainsKey(overlaySize))
|
||||
{
|
||||
var localSize = overlaySize;
|
||||
overlayFactories[localSize] = () => CreateBadgeBitmap(localSize);
|
||||
}
|
||||
}
|
||||
|
||||
var iconSet = NotifyerSupport.RegisterDynamicSet(OverlaySetName, overlayFactories, NoRefresh: true)
|
||||
?? NotifyerSupport.GetIconSet(OverlaySetName);
|
||||
|
||||
if (iconSet != null)
|
||||
{
|
||||
iconSet.SizeMap = sizeMap;
|
||||
_overlayInitialized = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildTooltip(string message)
|
||||
{
|
||||
try
|
||||
{
|
||||
var parts = message
|
||||
.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(part => part.Trim())
|
||||
.Where(part => part.Length > 0);
|
||||
|
||||
var summary = string.Join(" | ", parts);
|
||||
if (summary.Length > 140)
|
||||
summary = summary.Substring(0, 139) + "…";
|
||||
|
||||
return summary;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
private static string TrimTooltip(string tooltip)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(tooltip))
|
||||
return tooltip;
|
||||
|
||||
tooltip = tooltip.Replace("\r", " ").Replace("\n", " ");
|
||||
tooltip = tooltip.Trim();
|
||||
|
||||
return tooltip.Length <= 63
|
||||
? tooltip
|
||||
: tooltip.Substring(0, 63);
|
||||
}
|
||||
|
||||
private static int CalculateOverlayDiameter(int baseSize)
|
||||
{
|
||||
if (baseSize <= 0)
|
||||
return 0;
|
||||
|
||||
if (baseSize <= 18)
|
||||
return 8;
|
||||
if (baseSize <= 26)
|
||||
return 10;
|
||||
if (baseSize <= 36)
|
||||
return 11;
|
||||
|
||||
var diameter = (int)Math.Round(baseSize * 0.22f);
|
||||
return Math.Max(9, Math.Min(diameter, baseSize));
|
||||
}
|
||||
|
||||
private static Bitmap CreateBadgeBitmap(int size)
|
||||
{
|
||||
var diameter = Math.Max(2, size);
|
||||
var bitmap = new Bitmap(diameter, diameter, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
bitmap.SetResolution(96f, 96f);
|
||||
|
||||
using (var graphics = Graphics.FromImage(bitmap))
|
||||
{
|
||||
graphics.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
graphics.Clear(Color.Transparent);
|
||||
|
||||
int margin = 0;
|
||||
if (diameter >= 12)
|
||||
margin = Math.Max(1, (int)Math.Round(diameter * 0.08f));
|
||||
else if (diameter >= 9)
|
||||
margin = 1;
|
||||
|
||||
var circleSize = Math.Max(1, diameter - (margin * 2));
|
||||
var circleRect = new Rectangle(margin, margin, circleSize, circleSize);
|
||||
|
||||
using (var brush = new SolidBrush(Color.FromArgb(235, 220, 0, 0)))
|
||||
{
|
||||
graphics.FillEllipse(brush, circleRect);
|
||||
}
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user