9525ee358e
GUI csproj enables UseWindowsForms (NotifyIcon lives in WinForms even in .NET 8). New Services/TrayIcon.cs wraps NotifyIcon with a context menu (Open / Restart service / Exit) and the embedded webhook-server icon. MainWindow creates the TrayIcon, hides itself on minimize and restores on tray double-click. Adds GlobalUsings.cs to alias the WPF defaults for types that exist in both WPF and WinForms (Application, MessageBox, TextBox, Binding, etc.) so existing code keeps compiling without per-file changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
61 lines
2.3 KiB
C#
61 lines
2.3 KiB
C#
using System.Globalization;
|
|
using System.Windows.Data;
|
|
using Brush = System.Windows.Media.Brush;
|
|
using Brushes = System.Windows.Media.Brushes;
|
|
|
|
namespace WebhookServer.Gui.Converters;
|
|
|
|
public sealed class NullToBoolConverter : IValueConverter
|
|
{
|
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
|
=> value is not null;
|
|
|
|
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
|
=> throw new NotSupportedException();
|
|
}
|
|
|
|
public sealed class HookUrlConverter : IMultiValueConverter
|
|
{
|
|
public object Convert(object[] values, Type targetType, object? parameter, CultureInfo culture)
|
|
{
|
|
if (values.Length < 2) return "";
|
|
var slug = values[0] as string ?? "";
|
|
var baseUrl = values[1] as string ?? "";
|
|
if (string.IsNullOrEmpty(baseUrl) || string.IsNullOrEmpty(slug)) return "";
|
|
return $"{baseUrl.TrimEnd('/')}/hook/{slug}";
|
|
}
|
|
|
|
public object[] ConvertBack(object? value, Type[] targetTypes, object? parameter, CultureInfo culture)
|
|
=> throw new NotSupportedException();
|
|
}
|
|
|
|
public sealed class InvertBoolConverter : IValueConverter
|
|
{
|
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
|
=> value is bool b && !b;
|
|
|
|
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
|
=> value is bool b && !b;
|
|
}
|
|
|
|
public sealed class StringEqualsConverter : IValueConverter
|
|
{
|
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
|
=> string.Equals(value as string, parameter as string, StringComparison.OrdinalIgnoreCase);
|
|
|
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
|
=> (value is bool b && b) ? parameter : Binding.DoNothing;
|
|
}
|
|
|
|
public sealed class BoolToBrushConverter : IValueConverter
|
|
{
|
|
public Brush TrueBrush { get; set; } = Brushes.SeaGreen;
|
|
public Brush FalseBrush { get; set; } = Brushes.IndianRed;
|
|
|
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
|
=> (value is bool b && b) ? TrueBrush : FalseBrush;
|
|
|
|
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
|
=> throw new NotSupportedException();
|
|
}
|