diff --git a/source/SylphyHorn/ApplicationPreparation.cs b/source/SylphyHorn/ApplicationPreparation.cs index a649706..abd5e87 100644 --- a/source/SylphyHorn/ApplicationPreparation.cs +++ b/source/SylphyHorn/ApplicationPreparation.cs @@ -127,6 +127,9 @@ public TaskTrayIcon CreateTaskTrayIcon() { new TaskTrayIconItem(Resources.TaskTray_Menu_Settings, ShowSettings, () => Application.Args.CanSettings), new TaskTrayIconItem(Resources.TaskTray_Menu_Exit, this._shutdownAction), +#if DEBUG + new TaskTrayIconItem("Tasktray Icon Test", () => new TaskTrayTestWindow().Show()), +#endif }; this._taskTrayIcon = new TaskTrayIcon(icon, lightIcon, menus); diff --git a/source/SylphyHorn/Interop/ColorHelper.cs b/source/SylphyHorn/Interop/ColorHelper.cs new file mode 100644 index 0000000..e1a643f --- /dev/null +++ b/source/SylphyHorn/Interop/ColorHelper.cs @@ -0,0 +1,12 @@ +using System.Windows.Media; + +namespace SylphyHorn.Interop +{ + public static class ColorHelper + { + public static System.Drawing.Color ToGDIColor(this Color color) + { + return System.Drawing.Color.FromArgb(color.A, color.R, color.G, color.B); + } + } +} diff --git a/source/SylphyHorn/Interop/IconHelper.cs b/source/SylphyHorn/Interop/IconHelper.cs index a50d74c..f793730 100644 --- a/source/SylphyHorn/Interop/IconHelper.cs +++ b/source/SylphyHorn/Interop/IconHelper.cs @@ -1,6 +1,7 @@ using System; using System.Drawing; -using System.Windows; +using System.IO; +using System.Windows.Media.Imaging; using MetroRadiance.Interop; namespace SylphyHorn.Interop @@ -20,6 +21,35 @@ public static Icon GetIconFromResource(Uri uri) } } + public static RenderTargetBitmap ToRenderTargetBitmap(this System.Windows.Media.DrawingVisual drawingVisual, Size size, Dpi? dpi = null) + { + var imageDpi = dpi ?? new Dpi(96, 96); + var imageSize = ScaleSizeByDpi(size, imageDpi); + var renderTarget = new RenderTargetBitmap(imageSize.Width, imageSize.Height, imageDpi.X, imageDpi.Y, System.Windows.Media.PixelFormats.Default); + renderTarget.Render(drawingVisual); + return renderTarget; + } + + public static Bitmap ToBitmap(this System.Windows.Media.DrawingVisual drawingVisual, Size size, Dpi? dpi = null, Color? transparentColor = null) + { + var renderTarget = drawingVisual.ToRenderTargetBitmap(size, dpi); + var encoder = new BmpBitmapEncoder(); + var frame = BitmapFrame.Create(renderTarget); + encoder.Frames.Add(frame); + + using (var stream = new MemoryStream()) + { + encoder.Save(stream); + + var bitmap = new Bitmap(stream, useIcm: true); + if (transparentColor.HasValue) + { + bitmap.MakeTransparent(transparentColor.Value); + } + return bitmap; + } + } + public static Icon ToIcon(this Bitmap bitmap) { var iconHandle = bitmap.GetHicon(); @@ -28,21 +58,43 @@ public static Icon ToIcon(this Bitmap bitmap) return icon; } +#if DEBUG + internal static BitmapSource ToBitmapSource(this Icon icon) + { + using (var bitmap = icon.ToBitmap()) + using (var stream = new MemoryStream()) + { + bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png); + stream.Seek(0, SeekOrigin.Begin); + + var bitmapSource = BitmapFrame.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad); + return bitmapSource; + } + } +#endif + private static Icon ScaleIconToDpi(Icon targetIcon) { - var dpi = GetMonitorDpi(); + var dpi = GetSystemDpi(); - return new Icon(targetIcon, new System.Drawing.Size((int)(16 * dpi.ScaleX), (int)(16 * dpi.ScaleY))); + return new Icon(targetIcon, new Size((int)(16 * dpi.ScaleX), (int)(16 * dpi.ScaleY))); } - public static System.Windows.Size GetIconSize() + public static Size GetIconSize() { - var dpi = GetMonitorDpi(); + return new Size( + (int)System.Windows.SystemParameters.SmallIconWidth, + (int)System.Windows.SystemParameters.SmallIconHeight); + } - return new System.Windows.Size(SystemParameters.SmallIconWidth * dpi.ScaleX, SystemParameters.SmallIconHeight * dpi.ScaleY); + private static Size ScaleSizeByDpi(Size size, Dpi dpi) + { + return new Size( + (int)Math.Round(size.Width * dpi.ScaleX), + (int)Math.Round(size.Height * dpi.ScaleY)); } - - private static Dpi GetMonitorDpi() + + public static Dpi GetSystemDpi() { return PerMonitorDpi.GetDpi(IntPtr.Zero); } diff --git a/source/SylphyHorn/SylphyHorn.csproj b/source/SylphyHorn/SylphyHorn.csproj index c7bdb6c..5324de9 100644 --- a/source/SylphyHorn/SylphyHorn.csproj +++ b/source/SylphyHorn/SylphyHorn.csproj @@ -230,6 +230,7 @@ + @@ -282,6 +283,9 @@ SettingsWindow.xaml + + TaskTrayTestWindow.xaml + Designer MSBuild:Compile @@ -324,6 +328,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + diff --git a/source/SylphyHorn/UI/DynamicInfoTrayIcon.cs b/source/SylphyHorn/UI/DynamicInfoTrayIcon.cs index 9c333a8..3c58fa5 100644 --- a/source/SylphyHorn/UI/DynamicInfoTrayIcon.cs +++ b/source/SylphyHorn/UI/DynamicInfoTrayIcon.cs @@ -1,112 +1,138 @@ using System; -using System.Drawing; +using System.Globalization; +using System.Windows; using System.Windows.Controls; +using System.Windows.Media; +using MetroRadiance.Interop; using MetroRadiance.Platform; using SylphyHorn.Interop; namespace SylphyHorn.UI { - public class DynamicInfoTrayIcon : IDisposable + public class DynamicInfoTrayIcon { private const string _defaultFontFamilyName = "Segoe UI"; - private const float _horizontalFontSize = 7; - private const float _verticalFontSize = 6; + private const double _horizontalFontSize = 9; + private const double _verticalFontSize = 8; + private const double _verticalSpacing = -0.5; + private const double _triggerFontSizeInEffectivePixels = 14.0; - private readonly FontFamily _fontFamily; - private readonly Color? _color; - private Font _font; - private Brush _brush; - private Orientation _lastOrientation; + private static readonly SolidColorBrush _lightForegroundBrush = new SolidColorBrush(ImmersiveColor.GetColorByTypeName(ImmersiveColorNames.SystemTextLightTheme)); + private static readonly SolidColorBrush _lightBackgroundBrush = new SolidColorBrush(ImmersiveColor.GetColorByTypeName(ImmersiveColorNames.SystemBackgroundLightTheme)); + private static readonly SolidColorBrush _darkForegroundBrush = new SolidColorBrush(ImmersiveColor.GetColorByTypeName(ImmersiveColorNames.SystemTextDarkTheme)); + private static readonly SolidColorBrush _darkBackgroundBrush = new SolidColorBrush(ImmersiveColor.GetColorByTypeName(ImmersiveColorNames.SystemBackgroundDarkTheme)); - public DynamicInfoTrayIcon(int totalDesktopCount, Theme theme, FontFamily fontFamily = null, Color? color = null) - { - var currentOrientation = this._lastOrientation = GetOrientation(totalDesktopCount); - var fontSize = GetFontSize(currentOrientation); + private static readonly Typeface _defaultFont = new Typeface(new FontFamily(_defaultFontFamilyName), FontStyles.Normal, FontWeights.Bold, FontStretches.Normal); - this._fontFamily = fontFamily ?? new FontFamily(_defaultFontFamilyName); - this._font = new Font(this._fontFamily, fontSize, FontStyle.Bold); + private SolidColorBrush _foregroundBrush; + private SolidColorBrush _backgroundBrush; + private Dpi? _dpi; - this._color = color; - this._brush = new SolidBrush(color.GetValueOrDefault(GetForegroundColor(theme))); + public DynamicInfoTrayIcon(Theme theme, bool colorPrevalence, Dpi? dpi = null) + { + (this._foregroundBrush, this._backgroundBrush) = GetThemeBrushes(theme, colorPrevalence); + this._dpi = dpi; } - public Icon GetDesktopInfoIcon(int currentDesktop, int totalDesktopCount) + public System.Drawing.Icon GetDesktopInfoIcon(int currentDesktop, int totalDesktopCount) { - var currentOrientation = GetOrientation(totalDesktopCount); - - if (currentOrientation != this._lastOrientation) - { - this.UpdateFontSize(currentOrientation); - } - - this._lastOrientation = currentOrientation; - - using (var iconBitmap = currentOrientation == Orientation.Horizontal - ? this.DrawHorizontalInfo(currentDesktop, totalDesktopCount) - : this.DrawVerticalInfo(currentDesktop, totalDesktopCount)) + using (var iconBitmap = this.DrawInfo(currentDesktop, totalDesktopCount)) { return iconBitmap.ToIcon(); } } - private void UpdateFontSize(Orientation newOrientation) - { - var fontSize = GetFontSize(newOrientation); - - this._font?.Dispose(); - this._font = new Font(this._fontFamily, fontSize, FontStyle.Bold); - } - - public void UpdateBrush(Theme theme) + public void UpdateBrush(Theme theme, bool colorPrevalence) { - this._brush?.Dispose(); - this._brush = new SolidBrush(this._color.GetValueOrDefault(GetForegroundColor(theme))); + (this._foregroundBrush, this._backgroundBrush) = GetThemeBrushes(theme, colorPrevalence); } // consolidate two methods below? - private Bitmap DrawHorizontalInfo(int currentDesktop, int totalDesktopCount) + private System.Drawing.Bitmap DrawInfo(int currentDesktop, int totalDesktopCount) { var iconSize = IconHelper.GetIconSize(); - var bitmap = new Bitmap((int)iconSize.Width, (int)iconSize.Height); - - var stringToDraw = $"{currentDesktop}/{totalDesktopCount}"; + var dpi = this._dpi ?? GetDpi(); + var scale = dpi.X / 96.0; - var offset = GetHorizontalStringOffset(); - - using (var graphics = Graphics.FromImage(bitmap)) + var drawingVisual = new DrawingVisual(); + using (var context = drawingVisual.RenderOpen()) { - graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; - graphics.DrawString(stringToDraw, this._font, this._brush, offset); + context.DrawRectangle(this._backgroundBrush, null, new Rect(0.0, 0.0, iconSize.Width, iconSize.Height)); + + var currentOrientation = GetOrientation(totalDesktopCount); + if (currentOrientation == Orientation.Horizontal) + { + this.DrawHorizontalInfo(context, iconSize, scale, currentDesktop, totalDesktopCount); + } + else + { + this.DrawVerticalInfo(context, iconSize, scale, currentDesktop, totalDesktopCount); + } } - return bitmap; + return drawingVisual.ToBitmap( + iconSize, + dpi, + this._backgroundBrush.Color.ToGDIColor()); } - private Bitmap DrawVerticalInfo(int currentDesktop, int totalDesktops) + private void DrawHorizontalInfo(DrawingContext context, System.Drawing.Size size, double scale, int currentDesktop, int totalDesktopCount) { - var iconSize = IconHelper.GetIconSize(); - var bitmap = new Bitmap((int)iconSize.Width, (int)iconSize.Height); + var stringToDraw = $"{currentDesktop}/{totalDesktopCount}"; + var formattedText = this.GetFormattedTextFromText(stringToDraw, _horizontalFontSize, size, scale); + formattedText.LineHeight = Math.Min(_horizontalFontSize, size.Height); - var firstOffset = GetFirstVerticalStringOffset(currentDesktop); - var secondOffset = GetSecondVerticalStringOffset(totalDesktops, bitmap.Height); + var offsetY = Math.Floor(0.5 * (size.Height - formattedText.Extent)); + context.DrawText(formattedText, new Point(0, offsetY)); + } + + private void DrawVerticalInfo(DrawingContext context, System.Drawing.Size size, double scale, int currentDesktop, int totalDesktopCount, double? currentFontSize = null) + { + var fontSize = currentFontSize ?? _verticalFontSize; + var lineHeight = Math.Min(fontSize, size.Height); var firstString = currentDesktop.ToString(); - var secondString = totalDesktops.ToString(); + var firstFormattedText = this.GetFormattedTextFromText(firstString, fontSize, size, scale); + firstFormattedText.LineHeight = lineHeight; + if (firstFormattedText.MinWidth > size.Width) + { + DrawVerticalInfo(context, size, scale, currentDesktop, totalDesktopCount, fontSize - 1); + return; + } - using (var graphics = Graphics.FromImage(bitmap)) + var secondString = totalDesktopCount.ToString(); + var secondFormattedText = this.GetFormattedTextFromText(secondString, fontSize, size, scale); + secondFormattedText.LineHeight = lineHeight; + if (secondFormattedText.MinWidth > size.Width) { - graphics.DrawString(firstString, this._font, this._brush, firstOffset); - graphics.DrawString(secondString, this._font, this._brush, secondOffset); + DrawVerticalInfo(context, size, scale, currentDesktop, totalDesktopCount, fontSize - 1); + return; } - return bitmap; + var offsetY1 = Math.Floor(0.5 * size.Height - _verticalSpacing - firstFormattedText.Extent); + context.DrawText(firstFormattedText, new Point(0, offsetY1)); + + var offsetY2 = Math.Ceiling(0.5 * size.Height + _verticalSpacing); + context.DrawText(secondFormattedText, new Point(0, offsetY2)); } - public void Dispose() + private FormattedText GetFormattedTextFromText(string text, double fontSize, System.Drawing.Size size, double scale = 1) { - this._fontFamily?.Dispose(); - this._font?.Dispose(); - this._brush?.Dispose(); + var formattedText = new FormattedText( + text, + CultureInfo.CurrentUICulture, + FlowDirection.LeftToRight, + _defaultFont, + fontSize, + this._foregroundBrush, + null, + fontSize * scale >= _triggerFontSizeInEffectivePixels ? TextFormattingMode.Ideal : TextFormattingMode.Display, + scale); + formattedText.MaxLineCount = 1; + formattedText.MaxTextWidth = size.Width; + formattedText.TextAlignment = TextAlignment.Center; + formattedText.Trimming = TextTrimming.None; + return formattedText; } private static Orientation GetOrientation(int totalDesktopCount) @@ -114,44 +140,21 @@ private static Orientation GetOrientation(int totalDesktopCount) return totalDesktopCount >= 10 ? Orientation.Vertical : Orientation.Horizontal; } - private static float GetFontSize(Orientation orientation) - { - return orientation == Orientation.Horizontal ? _horizontalFontSize : _verticalFontSize; - } - - private static Color GetForegroundColor(Theme theme) + private static (SolidColorBrush Foreground, SolidColorBrush Background) GetThemeBrushes(Theme theme, bool colorPrevalence) { - return theme == Theme.Light ? Color.Black : Color.White; + return colorPrevalence + ? (_darkForegroundBrush, new SolidColorBrush(ImmersiveColor.GetColorByTypeName(ImmersiveColorNames.SystemAccentDark1))) + : theme == Theme.Light + ? (_lightForegroundBrush, _lightBackgroundBrush) + : (_darkForegroundBrush, _darkBackgroundBrush); } - private static PointF GetHorizontalStringOffset() + private static Dpi GetDpi() { - return new PointF(-2, 0); - } - - private static PointF GetFirstVerticalStringOffset(int value) - { - var offset = new PointF(-2, -2); - - if (value < 10) - { - offset.X += 7; - } - else if (value < 100) - { - offset.X += 4; - } - - return offset; - } - - private static PointF GetSecondVerticalStringOffset(int value, int bitmapHeight) - { - var offset = GetFirstVerticalStringOffset(value); - - offset.Y += bitmapHeight / 2f; - - return offset; + var dpi = IconHelper.GetSystemDpi(); + var maxDpi = Math.Max(dpi.X, dpi.Y); + var newDpi = new Dpi(maxDpi, maxDpi); + return newDpi; } } } diff --git a/source/SylphyHorn/UI/TaskTrayIcon.cs b/source/SylphyHorn/UI/TaskTrayIcon.cs index 278d1aa..2a7e3b8 100644 --- a/source/SylphyHorn/UI/TaskTrayIcon.cs +++ b/source/SylphyHorn/UI/TaskTrayIcon.cs @@ -6,6 +6,7 @@ using MetroRadiance.Platform; using SylphyHorn.Properties; using SylphyHorn.Serialization; +using SylphyHorn.Services; using WindowsDesktop; namespace SylphyHorn.UI @@ -30,6 +31,7 @@ public TaskTrayIcon(Icon icon, Icon lightIcon, TaskTrayIconItem[] items) this._items = items; WindowsTheme.SystemTheme.Changed += this.OnSystemThemeChanged; + WindowsTheme.ColorPrevalence.Changed += this.OnColorPrevalenceChanged; VirtualDesktop.CurrentChanged += this.OnCurrentDesktopChanged; } @@ -68,11 +70,10 @@ public void Reload(VirtualDesktop desktop = null) { if (Settings.General.TrayShowDesktop) { - this.UpdateWithDesktopInfo(desktop ?? VirtualDesktop.Current); + VisualHelper.InvokeOnUIDispatcher(() => this.UpdateWithDesktopInfo(desktop ?? VirtualDesktop.Current)); } else if (this._icon != this._defaultIcon && this._icon != this._lightIcon) { - this._infoIcon?.Dispose(); this._infoIcon = null; this.ChangeIcon(WindowsTheme.SystemTheme.Current == Theme.Light @@ -89,7 +90,9 @@ private void UpdateWithDesktopInfo(VirtualDesktop currentDesktop) if (this._infoIcon == null) { - this._infoIcon = new DynamicInfoTrayIcon(totalDesktopCount, WindowsTheme.SystemTheme.Current); + this._infoIcon = new DynamicInfoTrayIcon( + WindowsTheme.SystemTheme.Current, + WindowsTheme.ColorPrevalence.Current); } this.ChangeIcon(this._infoIcon.GetDesktopInfoIcon(currentDesktopIndex, totalDesktopCount)); @@ -100,12 +103,21 @@ private void OnCurrentDesktopChanged(object sender, VirtualDesktopChangedEventAr this.Reload(e.NewDesktop); } + private void OnColorPrevalenceChanged(object sender, bool e) + { + if (Settings.General.TrayShowDesktop) + { + this._infoIcon.UpdateBrush(WindowsTheme.SystemTheme.Current, e); + VisualHelper.InvokeOnUIDispatcher(() => this.UpdateWithDesktopInfo(VirtualDesktop.Current)); + } + } + private void OnSystemThemeChanged(object sender, Theme e) { if (Settings.General.TrayShowDesktop) { - this._infoIcon.UpdateBrush(e); - this.UpdateWithDesktopInfo(VirtualDesktop.Current); + this._infoIcon.UpdateBrush(e, WindowsTheme.ColorPrevalence.Current); + VisualHelper.InvokeOnUIDispatcher(() => this.UpdateWithDesktopInfo(VirtualDesktop.Current)); } else { @@ -128,12 +140,13 @@ private void ChangeIcon(Icon newIcon) public void Dispose() { + WindowsTheme.SystemTheme.Changed -= this.OnSystemThemeChanged; + WindowsTheme.ColorPrevalence.Changed -= this.OnColorPrevalenceChanged; + VirtualDesktop.CurrentChanged -= this.OnCurrentDesktopChanged; + this._notifyIcon?.Dispose(); this._lightIcon?.Dispose(); this._icon?.Dispose(); - - WindowsTheme.SystemTheme.Changed -= this.OnSystemThemeChanged; - VirtualDesktop.CurrentChanged -= this.OnCurrentDesktopChanged; } } diff --git a/source/SylphyHorn/UI/TaskTrayTestWindow.xaml b/source/SylphyHorn/UI/TaskTrayTestWindow.xaml new file mode 100644 index 0000000..2319cdd --- /dev/null +++ b/source/SylphyHorn/UI/TaskTrayTestWindow.xaml @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/SylphyHorn/UI/TaskTrayTestWindow.xaml.cs b/source/SylphyHorn/UI/TaskTrayTestWindow.xaml.cs new file mode 100644 index 0000000..ed38c5d --- /dev/null +++ b/source/SylphyHorn/UI/TaskTrayTestWindow.xaml.cs @@ -0,0 +1,149 @@ +using MetroRadiance.Platform; +using MetroRadiance.UI.Controls; +using SylphyHorn.Interop; +using System; +using System.Collections.ObjectModel; +using System.Windows; +using System.Windows.Input; +using System.Windows.Media; + +namespace SylphyHorn.UI +{ + partial class TaskTrayTestWindow + { + public TaskTrayTestWindow() + { + this.InitializeComponent(); + + this.ThemeMode = BlurWindowThemeMode.Dark; + this.LightRadioButton.Click += (sender, e) => this.ThemeMode = BlurWindowThemeMode.Light; + this.DarkRadioButton.Click += (sender, e) => this.ThemeMode = BlurWindowThemeMode.Dark; + this.AccentRadioButton.Click += (sender, e) => this.ThemeMode = BlurWindowThemeMode.Accent; + + this.DataContext = new TaskTrayIconsTestViewModel(Theme.Dark, false); + } + + protected override void OnThemeModeChanged(DependencyPropertyChangedEventArgs e) + { + var themeMode = (BlurWindowThemeMode)e.NewValue; + this.DataContext = new TaskTrayIconsTestViewModel( + themeMode == BlurWindowThemeMode.Light ? Theme.Light : Theme.Dark, + themeMode == BlurWindowThemeMode.Accent); + + switch (themeMode) + { + case BlurWindowThemeMode.Dark: + this.LightRadioButton.IsChecked = false; + this.DarkRadioButton.IsChecked = true; + this.AccentRadioButton.IsChecked = false; + break; + + case BlurWindowThemeMode.Accent: + this.LightRadioButton.IsChecked = false; + this.DarkRadioButton.IsChecked = false; + this.AccentRadioButton.IsChecked = true; + break; + + default: + this.LightRadioButton.IsChecked = true; + this.DarkRadioButton.IsChecked = false; + this.AccentRadioButton.IsChecked = false; + break; + } + } + + protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) + { + base.OnMouseLeftButtonDown(e); + + var position = e.GetPosition(this); + var result = VisualTreeHelper.HitTest(this.CaptionBar, position); + if (result != null) + { + this.DragMove(); + } + } + + private class TaskTrayIconTestViewModel + { + public TaskTrayIconTestViewModel(double scale, Theme theme, bool colorPrevalence) + { + this.Header = $"{100.0 * scale}%"; + this.Width = Math.Round(scale * 16.0); + this.Height = Math.Round(scale * 16.0); + + var colorName = theme == Theme.Light + ? ImmersiveColorNames.SystemBackgroundLightTheme + : ImmersiveColorNames.SystemBackgroundDarkTheme; + this.OpacityMask = new SolidColorBrush(ImmersiveColor.GetColorByTypeName(colorName)); + + var dpi = (uint)(96.0 * scale); + var generator = new DynamicInfoTrayIcon( + theme, + colorPrevalence, + new MetroRadiance.Interop.Dpi(dpi, dpi)); + this.Icon1By3 = generator.GetDesktopInfoIcon(1, 3).ToBitmapSource(); + this.Icon2By7 = generator.GetDesktopInfoIcon(2, 7).ToBitmapSource(); + this.Icon9By9 = generator.GetDesktopInfoIcon(9, 9).ToBitmapSource(); + this.Icon5By10 = generator.GetDesktopInfoIcon(5, 10).ToBitmapSource(); + this.Icon2By100 = generator.GetDesktopInfoIcon(2, 100).ToBitmapSource(); + this.Icon14By100 = generator.GetDesktopInfoIcon(14, 100).ToBitmapSource(); + this.Icon99By100 = generator.GetDesktopInfoIcon(99, 100).ToBitmapSource(); + this.Icon5By1000 = generator.GetDesktopInfoIcon(5, 1000).ToBitmapSource(); + this.Icon52By1000 = generator.GetDesktopInfoIcon(52, 1000).ToBitmapSource(); + this.Icon834By1000 = generator.GetDesktopInfoIcon(834, 1000).ToBitmapSource(); + this.Icon999By1000 = generator.GetDesktopInfoIcon(999, 1000).ToBitmapSource(); + this.Icon1000By1024 = generator.GetDesktopInfoIcon(1000, 1024).ToBitmapSource(); + } + + public string Header { get; } + public double Width { get; } + public double Height { get; } + public SolidColorBrush OpacityMask { get; } + + public ImageSource Icon1By3 { get; } + public ImageSource Icon2By7 { get; } + public ImageSource Icon9By9 { get; } + public ImageSource Icon5By10 { get; } + public ImageSource Icon2By100 { get; } + public ImageSource Icon14By100 { get; } + public ImageSource Icon99By100 { get; } + public ImageSource Icon5By1000 { get; } + public ImageSource Icon52By1000 { get; } + public ImageSource Icon834By1000 { get; } + public ImageSource Icon999By1000 { get; } + public ImageSource Icon1000By1024 { get; } + } + + private class TaskTrayIconsTestViewModel + { + public TaskTrayIconsTestViewModel(Theme theme, bool colorPrevalence) + { + this.Scales = new Collection() + { + new TaskTrayIconTestViewModel(1, theme, colorPrevalence), + new TaskTrayIconTestViewModel(1.25, theme, colorPrevalence), + new TaskTrayIconTestViewModel(1.5, theme, colorPrevalence), + new TaskTrayIconTestViewModel(1.75, theme, colorPrevalence), + new TaskTrayIconTestViewModel(2, theme, colorPrevalence), + new TaskTrayIconTestViewModel(2.25, theme, colorPrevalence), + new TaskTrayIconTestViewModel(2.5, theme, colorPrevalence), + new TaskTrayIconTestViewModel(2.75, theme, colorPrevalence), + new TaskTrayIconTestViewModel(3, theme, colorPrevalence), + }; + } + + public double HorizontalFontSize { get; } = 9; + + public double VerticalFontSize { get; } = 8; + + public double Vertical1000FontSize { get; } = 7; + + public FontFamily FontFamily { get; } = new FontFamily("Segoe UI"); + + public FontWeight FontWeight { get; } = FontWeights.Bold; + + public Collection Scales { get; } + } + } +}