feat: 使用 HandyControl 的 NotifyIcon

This commit is contained in:
枫雨
2023-08-30 14:17:36 +08:00
committed by uye
parent 01cd21d25a
commit 456bcbaf66
6 changed files with 139 additions and 156 deletions

View File

@@ -14,7 +14,6 @@
using System;
using GlobalHotKey;
using MaaWpfGui.Main;
using MaaWpfGui.Services;
using MaaWpfGui.Services.HotKeys;
using MaaWpfGui.Services.Managers;
using MaaWpfGui.Services.RemoteControl;
@@ -76,8 +75,6 @@ namespace MaaWpfGui.Helper
public static AsstProxy AsstProxy { get; private set; }
public static TrayIcon TrayIcon { get; private set; }
public static HotKeyManager HotKeyManager { get; private set; }
public static IMaaHotKeyManager MaaHotKeyManager { get; private set; }
@@ -106,7 +103,7 @@ namespace MaaWpfGui.Helper
VersionUpdateViewModel = container.Get<VersionUpdateViewModel>();
AnnouncementViewModel = container.Get<AnnouncementViewModel>();
// 这实例化时存在依赖顺序
// 这实例化时存在依赖顺序
HttpService = container.Get<HttpService>();
MaaApiService = container.Get<MaaApiService>();
@@ -120,7 +117,6 @@ namespace MaaWpfGui.Helper
public static void InstantiateOnRootViewDisplayed(IContainer container)
{
MainWindowManager = container.Get<MainWindowManager>();
TrayIcon = container.Get<TrayIcon>();
}
}
}

View File

@@ -26,6 +26,7 @@ using MaaWpfGui.Services.HotKeys;
using MaaWpfGui.Services.Managers;
using MaaWpfGui.Services.RemoteControl;
using MaaWpfGui.Services.Web;
using MaaWpfGui.ViewModels;
using MaaWpfGui.ViewModels.UI;
using MaaWpfGui.Views.UI;
using Serilog;
@@ -164,7 +165,6 @@ namespace MaaWpfGui.Main
builder.Bind<CopilotViewModel>().ToSelf().InSingletonScope();
builder.Bind<AsstProxy>().ToSelf().InSingletonScope();
builder.Bind<TrayIcon>().ToSelf().InSingletonScope();
builder.Bind<StageManager>().ToSelf();
builder.Bind<HotKeyManager>().ToSelf().InSingletonScope();
@@ -230,8 +230,6 @@ namespace MaaWpfGui.Main
new ToastNotificationHistory().Clear();
}
// 注销任务栏图标
Instances.TrayIcon.Close();
ConfigurationHelper.Release();
_logger.Information("MaaAssistantArknights GUI exited");

View File

@@ -1,147 +0,0 @@
// <copyright file="TrayIcon.cs" company="MaaAssistantArknights">
// MaaWpfGui - A part of the MaaCoreArknights project
// Copyright (C) 2021 MistEO and Contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
// </copyright>
using System;
using System.Drawing;
using System.Windows.Forms;
using MaaWpfGui.Helper;
using MaaWpfGui.ViewModels.UI;
using Serilog;
namespace MaaWpfGui.Services
{
/// <summary>
/// 托盘图标。
/// </summary>
public class TrayIcon
{
private readonly NotifyIcon _notifyIcon = new NotifyIcon();
private static readonly ILogger _logger = Log.ForContext<TrayIcon>();
/// <summary>
/// Initializes a new instance of the <see cref="TrayIcon"/> class.
/// </summary>
public TrayIcon()
{
InitIcon();
this.SetVisible(true);
}
private void InitIcon()
{
this._notifyIcon.Text = "MaaAssistantArknights";
this._notifyIcon.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
_notifyIcon.MouseClick += NotifyIcon_MouseClick;
_notifyIcon.MouseDoubleClick += OnNotifyIconDoubleClick;
ToolStripMenuItem startMenu = new ToolStripMenuItem (LocalizationHelper.GetString("Farming"));
startMenu.Click += StartTask;
ToolStripMenuItem stopMenu = new ToolStripMenuItem(LocalizationHelper.GetString("Stop"));
stopMenu.Click += StopTask;
ToolStripMenuItem switchLangMenu = new ToolStripMenuItem(LocalizationHelper.GetString("SwitchLanguage"));
foreach (var lang in LocalizationHelper.SupportedLanguages)
{
if (lang.Key == SettingsViewModel.PallasLangKey)
{
continue;
}
var langMenu = new ToolStripMenuItem(lang.Value);
langMenu.Click += (sender, e) =>
{
Instances.SettingsViewModel.Language = lang.Key;
};
switchLangMenu.DropDownItems.Add(langMenu);
}
ToolStripMenuItem forceShowMenu = new ToolStripMenuItem(LocalizationHelper.GetString("ForceShow"));
forceShowMenu.Click += ForceShow;
ToolStripMenuItem exitMenu = new ToolStripMenuItem(LocalizationHelper.GetString("Exit"));
exitMenu.Click += AppExit;
ToolStripMenuItem[] menuItems = new ToolStripMenuItem[] { startMenu, stopMenu, switchLangMenu, forceShowMenu, exitMenu };
var contextMenuStrip = new ContextMenuStrip();
foreach (var item in menuItems)
{
contextMenuStrip.Items.Add(item);
}
this._notifyIcon.ContextMenuStrip = contextMenuStrip;
}
private static void NotifyIcon_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
{
return;
}
Instances.MainWindowManager.SwitchWindowState();
}
private static void StartTask(object sender, EventArgs e)
{
// taskQueueViewModel意外为null了是不是也可以考虑Log一下
// 先放个log点方便跟踪
Instances.TaskQueueViewModel?.LinkStart();
_logger.Information("Tray service task started.");
}
private static void StopTask(object sender, EventArgs e)
{
Instances.TaskQueueViewModel?.Stop();
_logger.Information("Tray service task stop.");
}
private static void ForceShow(object sender, EventArgs e)
{
Instances.MainWindowManager.ForceShow();
_logger.Information("WindowManager ForceShow.");
}
private static void AppExit(object sender, EventArgs e)
{
if (Instances.TaskQueueViewModel.ConfirmExit())
{
System.Windows.Application.Current.Shutdown();
}
}
private static void OnNotifyIconDoubleClick(object sender, EventArgs e)
{
Instances.MainWindowManager.Show();
}
/// <summary>
/// Sets visibility.
/// </summary>
/// <param name="visible">Whether it is visible.</param>
public void SetVisible(bool visible)
{
_notifyIcon.Visible = visible;
}
/// <summary>
/// Closes this instance.
/// </summary>
public void Close()
{
_notifyIcon.Icon = null;
_notifyIcon.Visible = false;
_notifyIcon.Dispose();
}
}
}

View File

@@ -0,0 +1,27 @@
<UserControl
x:Class="MaaWpfGui.Views.UI.NotifyIcon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:local="clr-namespace:MaaWpfGui.Views.UI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">
<hc:NotifyIcon
Name="notifyIcon"
Text="MaaAssistantArknights"
Token="Maa.Icon"
Visibility="Visible">
<hc:NotifyIcon.ContextMenu>
<ContextMenu>
<MenuItem Name="startMenu" Header="{DynamicResource Farming}" />
<MenuItem Name="stopMenu" Header="{DynamicResource Stop}" />
<MenuItem Name="switchLangMenu" Header="{DynamicResource SwitchLanguage}" />
<MenuItem Name="forceShowMenu" Header="{DynamicResource ForceShow}" />
<MenuItem Name="exitMenu" Header="{DynamicResource Exit}" />
</ContextMenu>
</hc:NotifyIcon.ContextMenu>
</hc:NotifyIcon>
</UserControl>

View File

@@ -0,0 +1,105 @@
// <copyright file="NotifyIcon.xaml.cs" company="MaaAssistantArknights">
// MaaWpfGui - A part of the MaaCoreArknights project
// Copyright (C) 2021 MistEO and Contributors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
// </copyright>
using System.Windows;
using System.Windows.Controls;
using MaaWpfGui.Helper;
using MaaWpfGui.ViewModels.UI;
using Serilog;
namespace MaaWpfGui.Views.UI
{
/// <summary>
/// 托盘图标。
/// </summary>
public partial class NotifyIcon : System.Windows.Controls.UserControl
{
private static readonly ILogger _logger = Log.ForContext<NotifyIcon>();
public NotifyIcon()
{
InitializeComponent();
InitIcon();
}
private void InitIcon()
{
notifyIcon.Click += NotifyIcon_MouseClick;
notifyIcon.MouseDoubleClick += OnNotifyIconDoubleClick;
startMenu.Click += StartTask;
stopMenu.Click += StopTask;
forceShowMenu.Click += ForceShow;
exitMenu.Click += App_exit;
foreach (var lang in LocalizationHelper.SupportedLanguages)
{
if (lang.Key == SettingsViewModel.PallasLangKey)
{
continue;
}
var langMenu = new MenuItem() { Header = lang.Value };
langMenu.Click += (sender, e) =>
{
Instances.SettingsViewModel.Language = lang.Key;
};
switchLangMenu.Items.Add(langMenu);
}
}
private void NotifyIcon_MouseClick(object sender, RoutedEventArgs e)
{
Instances.MainWindowManager?.SwitchWindowState();
}
private void StartTask(object sender, RoutedEventArgs e)
{
// taskQueueViewModel意外为null了是不是也可以考虑Log一下
// 先放个log点方便跟踪
Instances.TaskQueueViewModel?.LinkStart();
_logger.Information("Tray service task started.");
}
private void StopTask(object sender, RoutedEventArgs e)
{
Instances.TaskQueueViewModel?.Stop();
_logger.Information("Tray service task stop.");
}
private void ForceShow(object sender, RoutedEventArgs e)
{
Instances.MainWindowManager?.ForceShow();
_logger.Information("WindowManager force show.");
}
private void App_exit(object sender, RoutedEventArgs e)
{
if (Instances.TaskQueueViewModel.ConfirmExit())
{
Application.Current.Shutdown();
}
}
private void App_show(object sender, RoutedEventArgs e)
{
Instances.MainWindowManager?.Show();
}
private void OnNotifyIconDoubleClick(object sender, RoutedEventArgs e)
{
Instances.MainWindowManager?.Show();
}
}
}

View File

@@ -4,11 +4,11 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:local="clr-namespace:MaaWpfGui.Views.UI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:s="https://github.com/canton7/Stylet"
xmlns:ui="clr-namespace:MaaWpfGui.ViewModels.UI"
xmlns:viewModels="clr-namespace:MaaWpfGui.ViewModels"
xmlns:vm="clr-namespace:MaaWpfGui"
Title="{Binding WindowTitle}"
Width="800"
Height="600"
@@ -20,6 +20,7 @@
mc:Ignorable="d">
<DockPanel>
<local:NotifyIcon Visibility="Hidden" x:Name="NotifyIcon" />
<TabControl
BorderThickness="0,1,0,0"
DisplayMemberPath="DisplayName"
@@ -37,4 +38,7 @@
</TabControl.ContentTemplate>
</TabControl>
</DockPanel>
<hc:Interaction.Behaviors>
<hc:TaskbarRebuildBehavior Element="{Binding ElementName=NotifyIcon}" />
</hc:Interaction.Behaviors>
</hc:Window>