mirror of
https://github.com/BeyondDimension/SteamTools.git
synced 2026-10-23 18:38:04 +08:00
NotifyIcon
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
using Eto.Drawing;
|
||||
using Eto.Forms;
|
||||
|
||||
namespace System.Application.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// This Implements a Linux GTK3 Tray Icon
|
||||
/// </summary>
|
||||
internal sealed class LinuxTrayIcon<TContextMenu> : Form
|
||||
{
|
||||
public TrayIndicator? _tray;
|
||||
readonly bool _startup = true;
|
||||
|
||||
/// <summary>
|
||||
/// Everything has to be sent in on the constructor since things do not auto-refresh / update this is a limitation
|
||||
/// </summary>
|
||||
/// <param name="tooTip"></param>
|
||||
/// <param name="iconPath"></param>
|
||||
/// <param name="menu"></param>
|
||||
public LinuxTrayIcon(string tooTip, string iconPath, TContextMenu menu)
|
||||
{
|
||||
MainThreadDesktop.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
var ctxMnu = new ContextMenu();
|
||||
|
||||
var f = DI.Get<INotifyIcon<TContextMenu>.IUIFrameworkHelper>();
|
||||
|
||||
f.ForEachMenuItems(menu, item =>
|
||||
{
|
||||
ButtonMenuItem bmi = new ButtonMenuItem
|
||||
{
|
||||
Text = item.header,
|
||||
Command = new Command((s, e) =>
|
||||
{
|
||||
MainThreadDesktop.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
item.activated();
|
||||
});
|
||||
})
|
||||
};
|
||||
ctxMnu.Items.Add(bmi);
|
||||
});
|
||||
|
||||
ClientSize = new Size(200, 200);
|
||||
|
||||
var image = new Icon(f.OpenAsset(new Uri(iconPath)));
|
||||
|
||||
_tray = new TrayIndicator
|
||||
{
|
||||
//Image = Icon.FromResource(iconPath.Replace("resm:", "")),
|
||||
Image = image,
|
||||
Menu = ctxMnu,
|
||||
Title = tooTip
|
||||
};
|
||||
|
||||
_tray.Show();
|
||||
_tray.Visible = true;
|
||||
});
|
||||
}
|
||||
|
||||
protected override void OnShown(EventArgs e)
|
||||
{
|
||||
if (_startup)
|
||||
{
|
||||
Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnUnLoad(EventArgs e)
|
||||
{
|
||||
base.OnUnLoad(e);
|
||||
_tray?.Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using EtoFormsApplication = Eto.Forms.Application;
|
||||
using EtoPlatform = Eto.Platform;
|
||||
|
||||
namespace System.Application.UI
|
||||
{
|
||||
public class NotifyIcon<TContextMenu> : INotifyIcon<TContextMenu>
|
||||
{
|
||||
public event EventHandler<EventArgs>? Click;
|
||||
public event EventHandler<EventArgs>? DoubleClick;
|
||||
public event EventHandler<EventArgs>? RightClick;
|
||||
|
||||
LinuxTrayIcon<TContextMenu>? lti;
|
||||
|
||||
internal LinuxTrayIcon<TContextMenu>? LtiProp
|
||||
{
|
||||
get => lti;
|
||||
set => lti = value;
|
||||
}
|
||||
|
||||
public Task? TrayIconTask { get; private set; }
|
||||
|
||||
CancellationTokenSource? canTok;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the icon for the notify icon. Either a file system path
|
||||
/// or a <c>resm:</c> manifest resource path can be specified.
|
||||
/// </summary>
|
||||
string _iconPath = "";
|
||||
|
||||
public string IconPath
|
||||
{
|
||||
get => _iconPath;
|
||||
set
|
||||
{
|
||||
_iconPath = value;
|
||||
UpdateMenu();
|
||||
}
|
||||
}
|
||||
|
||||
string _toolTip = "";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the tooltip text for the notify icon.
|
||||
/// </summary>
|
||||
public string ToolTipText
|
||||
{
|
||||
get => _toolTip;
|
||||
set
|
||||
{
|
||||
_toolTip = value;
|
||||
UpdateMenu();
|
||||
}
|
||||
}
|
||||
|
||||
TContextMenu? _menu;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the context menu for the notify icon.
|
||||
/// </summary>
|
||||
public TContextMenu? ContextMenu
|
||||
{
|
||||
get => _menu; set
|
||||
{
|
||||
_menu = value;
|
||||
UpdateMenu();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets if the notify icon is visible in the
|
||||
/// taskbar notification area or not.
|
||||
/// </summary>
|
||||
public bool Visible { get; set; }
|
||||
|
||||
public void Remove()
|
||||
{
|
||||
MainThreadDesktop.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
lti?._tray?.Hide();
|
||||
canTok?.Cancel();
|
||||
});
|
||||
}
|
||||
|
||||
void UpdateMenu()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(IconPath) && !string.IsNullOrEmpty(ToolTipText) && ContextMenu != null)
|
||||
{
|
||||
canTok = new CancellationTokenSource();
|
||||
MainThreadDesktop.BeginInvokeOnMainThread(() =>
|
||||
{
|
||||
// Because of the way that Linux works this needs to run on its own Thread.
|
||||
TrayIconTask = Task.Factory.StartNew(() =>
|
||||
{
|
||||
new EtoFormsApplication(EtoPlatform.Detect)
|
||||
.Run(LtiProp =
|
||||
new LinuxTrayIcon<TContextMenu>(ToolTipText, IconPath, ContextMenu));
|
||||
}
|
||||
, canTok.Token, TaskCreationOptions.AttachedToParent, TaskScheduler.Default);
|
||||
}, MainThreadDesktop.DispatcherPriority.MaxValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -11,6 +11,10 @@
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Eto.Forms" Version="2.5.10" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop\System.Application.SteamTools.Client.Desktop.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user