实现基于 WPF 的 AutoShutdown 主界面,支持关机、重启、睡眠、休眠、唤醒、锁屏和注销等电源任务。 支持指定时间和倒计时计划、执行前提醒、系统关机撤销、Windows 唤醒任务、托盘运行、自定义图标以及 OmniNotify 通知适配。 修复关闭到托盘时的运行提醒,并支持单击托盘图标打开或收起主界面。 补充 README、发布配置和 win-x64 Release 输出要求。 Release: win-x64
221 lines
7.5 KiB
C#
221 lines
7.5 KiB
C#
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using AutoShutdown.Models;
|
|
using AutoShutdown.Services;
|
|
using WpfBrush = System.Windows.Media.Brush;
|
|
using WpfBrushes = System.Windows.Media.Brushes;
|
|
using WpfButton = System.Windows.Controls.Button;
|
|
using WpfCursors = System.Windows.Input.Cursors;
|
|
using WpfFontFamily = System.Windows.Media.FontFamily;
|
|
using WpfOrientation = System.Windows.Controls.Orientation;
|
|
using WpfRadioButton = System.Windows.Controls.RadioButton;
|
|
using WpfTextBox = System.Windows.Controls.TextBox;
|
|
|
|
namespace AutoShutdown;
|
|
|
|
internal sealed class NotificationSettingsWindow : Window
|
|
{
|
|
private readonly NotificationService _notificationService;
|
|
private readonly WpfRadioButton _localMode = new() { Content = "软件本身" };
|
|
private readonly WpfRadioButton _omniNotifyMode = new() { Content = "OmniNotify" };
|
|
private readonly WpfTextBox _endpoint = new();
|
|
private readonly WpfTextBox _channel = new();
|
|
private readonly TextBlock _status = new();
|
|
|
|
public NotificationSettings Settings { get; private set; }
|
|
|
|
public NotificationSettingsWindow(NotificationSettings settings, NotificationService notificationService)
|
|
{
|
|
_notificationService = notificationService;
|
|
Settings = new NotificationSettings
|
|
{
|
|
Mode = settings.Mode,
|
|
OmniNotifyEndpoint = settings.OmniNotifyEndpoint,
|
|
Channel = settings.Channel
|
|
};
|
|
|
|
Title = "OmniNotify 适配设置";
|
|
Width = 640;
|
|
SizeToContent = SizeToContent.Height;
|
|
MinWidth = 640;
|
|
MaxWidth = 640;
|
|
WindowStartupLocation = WindowStartupLocation.CenterOwner;
|
|
ResizeMode = ResizeMode.NoResize;
|
|
Background = BrushFrom("#F6F8FC");
|
|
FontFamily = new WpfFontFamily("Microsoft YaHei UI");
|
|
FontSize = 14;
|
|
|
|
Content = BuildContent();
|
|
LoadSettings();
|
|
}
|
|
|
|
private UIElement BuildContent()
|
|
{
|
|
var host = new Grid
|
|
{
|
|
Background = BrushFrom("#F6F8FC")
|
|
};
|
|
|
|
var root = new Border
|
|
{
|
|
Background = BrushFrom("#FFFFFF"),
|
|
CornerRadius = new CornerRadius(12),
|
|
Padding = new Thickness(26),
|
|
Margin = new Thickness(22)
|
|
};
|
|
|
|
var stack = new StackPanel();
|
|
root.Child = stack;
|
|
|
|
stack.Children.Add(new TextBlock
|
|
{
|
|
Text = "通知方式",
|
|
FontSize = 22,
|
|
FontWeight = FontWeights.Bold,
|
|
Foreground = BrushFrom("#111827")
|
|
});
|
|
|
|
stack.Children.Add(new TextBlock
|
|
{
|
|
Text = "选择提示由 AutoShutdown 弹窗显示,或发送给本机 OmniNotify。",
|
|
Margin = new Thickness(0, 4, 0, 20),
|
|
Foreground = BrushFrom("#64748B"),
|
|
TextWrapping = TextWrapping.Wrap
|
|
});
|
|
|
|
stack.Children.Add(MakeLabel("提示模式"));
|
|
var modeRow = new StackPanel { Orientation = WpfOrientation.Horizontal, Margin = new Thickness(0, 8, 0, 18) };
|
|
StyleRadio(_localMode);
|
|
StyleRadio(_omniNotifyMode);
|
|
_localMode.Margin = new Thickness(0, 0, 22, 0);
|
|
modeRow.Children.Add(_localMode);
|
|
modeRow.Children.Add(_omniNotifyMode);
|
|
stack.Children.Add(modeRow);
|
|
|
|
stack.Children.Add(MakeLabel("监听地址"));
|
|
StyleInput(_endpoint, 536);
|
|
_endpoint.Margin = new Thickness(0, 8, 0, 14);
|
|
stack.Children.Add(_endpoint);
|
|
|
|
stack.Children.Add(MakeLabel("频道名"));
|
|
StyleInput(_channel, 260);
|
|
_channel.Margin = new Thickness(0, 8, 0, 12);
|
|
stack.Children.Add(_channel);
|
|
|
|
_status.Text = "OmniNotify 模式需要先在 OmniNotify 中创建对应频道。";
|
|
_status.Foreground = BrushFrom("#64748B");
|
|
_status.TextWrapping = TextWrapping.Wrap;
|
|
_status.Margin = new Thickness(0, 0, 0, 20);
|
|
stack.Children.Add(_status);
|
|
|
|
var buttons = new StackPanel
|
|
{
|
|
Orientation = WpfOrientation.Horizontal,
|
|
HorizontalAlignment = System.Windows.HorizontalAlignment.Right
|
|
};
|
|
var test = MakeButton("测试发送", BrushFrom("#475569"));
|
|
test.Click += async (_, _) => await TestAsync();
|
|
var cancel = MakeButton("取消", BrushFrom("#64748B"));
|
|
cancel.Click += (_, _) => DialogResult = false;
|
|
var save = MakeButton("保存", BrushFrom("#2563EB"));
|
|
save.Click += (_, _) => SaveAndClose();
|
|
buttons.Children.Add(test);
|
|
buttons.Children.Add(cancel);
|
|
buttons.Children.Add(save);
|
|
stack.Children.Add(buttons);
|
|
|
|
host.Children.Add(root);
|
|
return host;
|
|
}
|
|
|
|
private void LoadSettings()
|
|
{
|
|
_localMode.IsChecked = Settings.Mode == NotificationMode.Local;
|
|
_omniNotifyMode.IsChecked = Settings.Mode == NotificationMode.OmniNotify;
|
|
_endpoint.Text = Settings.OmniNotifyEndpoint;
|
|
_channel.Text = Settings.Channel;
|
|
}
|
|
|
|
private async Task TestAsync()
|
|
{
|
|
var testSettings = ReadSettings();
|
|
_status.Text = "正在发送测试消息...";
|
|
_status.Foreground = BrushFrom("#64748B");
|
|
var ok = await _notificationService.TestOmniNotifyAsync(testSettings);
|
|
_status.Text = ok
|
|
? "测试消息已发送。"
|
|
: "测试失败,请确认 OmniNotify 正在运行、监听地址正确,并且频道已创建。";
|
|
_status.Foreground = ok ? BrushFrom("#008060") : BrushFrom("#DC2626");
|
|
}
|
|
|
|
private void SaveAndClose()
|
|
{
|
|
Settings = ReadSettings();
|
|
DialogResult = true;
|
|
}
|
|
|
|
private NotificationSettings ReadSettings()
|
|
{
|
|
return new NotificationSettings
|
|
{
|
|
Mode = _omniNotifyMode.IsChecked == true ? NotificationMode.OmniNotify : NotificationMode.Local,
|
|
OmniNotifyEndpoint = string.IsNullOrWhiteSpace(_endpoint.Text) ? "http://127.0.0.1:19845/notify" : _endpoint.Text.Trim(),
|
|
Channel = string.IsNullOrWhiteSpace(_channel.Text) ? "default" : _channel.Text.Trim()
|
|
};
|
|
}
|
|
|
|
private static TextBlock MakeLabel(string text)
|
|
{
|
|
return new TextBlock
|
|
{
|
|
Text = text,
|
|
FontWeight = FontWeights.SemiBold,
|
|
Foreground = BrushFrom("#111827")
|
|
};
|
|
}
|
|
|
|
private static void StyleRadio(WpfRadioButton radio)
|
|
{
|
|
radio.Foreground = BrushFrom("#111827");
|
|
radio.FontSize = 14;
|
|
radio.Cursor = WpfCursors.Hand;
|
|
}
|
|
|
|
private static void StyleInput(WpfTextBox input, double width)
|
|
{
|
|
input.Height = 34;
|
|
input.Width = width;
|
|
input.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
|
|
input.Padding = new Thickness(10, 5, 10, 5);
|
|
input.BorderBrush = BrushFrom("#CBD5E1");
|
|
input.BorderThickness = new Thickness(1);
|
|
input.Background = WpfBrushes.White;
|
|
input.Foreground = BrushFrom("#111827");
|
|
}
|
|
|
|
private static WpfButton MakeButton(string text, WpfBrush background)
|
|
{
|
|
var button = new WpfButton
|
|
{
|
|
Content = text,
|
|
Height = 38,
|
|
MinWidth = 92,
|
|
Margin = new Thickness(10, 0, 0, 0),
|
|
Padding = new Thickness(16, 0, 16, 0),
|
|
Background = background,
|
|
Foreground = WpfBrushes.White,
|
|
BorderThickness = new Thickness(0),
|
|
FontWeight = FontWeights.SemiBold,
|
|
Cursor = WpfCursors.Hand
|
|
};
|
|
return button;
|
|
}
|
|
|
|
private static WpfBrush BrushFrom(string hex)
|
|
{
|
|
return (WpfBrush)new BrushConverter().ConvertFromString(hex)!;
|
|
}
|
|
}
|