Upgrade Avalonia

This commit is contained in:
Robert committed 2023-07-26 22:13:40 +02:00
1 parent e03d6b20e9
commit ee6d295fd8
24 files changed
+337 -311

No files matched your search

+23 -36
View File
@@ -1,4 +1,5 @@
using System;
using System.Reactive.Disposables;
using System.Runtime.InteropServices;
using Avalonia;
using Avalonia.Controls;
@@ -26,6 +27,8 @@ public class ReactiveAppWindow<TViewModel> : AppWindow, IViewFor<TViewModel> whe
public static readonly StyledProperty<TViewModel?> ViewModelProperty = AvaloniaProperty
.Register<ReactiveAppWindow<TViewModel>, TViewModel?>(nameof(ViewModel));
private bool _micaEnabled;
/// <summary>
/// Initializes a new instance of the <see cref="ReactiveAppWindow{TViewModel}" /> class.
/// </summary>
@@ -33,23 +36,33 @@ public class ReactiveAppWindow<TViewModel> : AppWindow, IViewFor<TViewModel> whe
{
// This WhenActivated block calls ViewModel's WhenActivated
// block if the ViewModel implements IActivatableViewModel.
this.WhenActivated(disposables => { });
this.WhenActivated(disposables => UI.MicaEnabled.Subscribe(ToggleMica).DisposeWith(disposables));
this.GetObservable(DataContextProperty).Subscribe(OnDataContextChanged);
this.GetObservable(ViewModelProperty).Subscribe(OnViewModelChanged);
}
/// <inheritdoc />
protected override void OnOpened(EventArgs e)
private void ToggleMica(bool enable)
{
// TODO: Move to a style and remove opacity on focus loss
base.OnOpened(e);
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !IsWindows11)
if (enable == _micaEnabled)
return;
TransparencyBackgroundFallback = Brushes.Transparent;
TransparencyLevelHint = new[] {WindowTransparencyLevel.Mica};
TryEnableMicaEffect();
if (enable)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) || !IsWindows11)
return;
// TransparencyBackgroundFallback = Brushes.Transparent;
TransparencyLevelHint = new[] {WindowTransparencyLevel.Mica};
Background = new SolidColorBrush(new Color(80, 0,0,0));
}
else
{
ClearValue(TransparencyLevelHintProperty);
ClearValue(BackgroundProperty);
}
_micaEnabled = enable;
}
private void OnDataContextChanged(object? value)
@@ -67,32 +80,6 @@ public class ReactiveAppWindow<TViewModel> : AppWindow, IViewFor<TViewModel> whe
else if (DataContext != value) DataContext = value;
}
private void TryEnableMicaEffect()
{
// The background colors for the Mica brush are still based around SolidBackgroundFillColorBase resource
// BUT since we can't control the actual Mica brush color, we have to use the window background to create
// the same effect. However, we can't use SolidBackgroundFillColorBase directly since its opaque, and if
// we set the opacity the color become lighter than we want. So we take the normal color, darken it and
// apply the opacity until we get the roughly the correct color
// NOTE that the effect still doesn't look right, but it suffices. Ideally we need access to the Mica
// CompositionBrush to properly change the color but I don't know if we can do that or not
if (ActualThemeVariant == ThemeVariant.Dark)
{
Color2 color = this.TryFindResource("SolidBackgroundFillColorBase", ThemeVariant.Dark, out object? value) ? (Color) value : new Color2(32, 32, 32);
color = color.LightenPercent(-0.5f);
Background = new ImmutableSolidColorBrush(color, 0.78);
}
else if (ActualThemeVariant == ThemeVariant.Light)
{
// Similar effect here
Color2 color = this.TryFindResource("SolidBackgroundFillColorBase", ThemeVariant.Light, out object? value) ? (Color) value : new Color2(243, 243, 243);
color = color.LightenPercent(0.5f);
Background = new ImmutableSolidColorBrush(color, 0.9);
}
}
/// <summary>
/// The ViewModel.
/// </summary>
+29 -9
View File
@@ -1,29 +1,29 @@
using System;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Input.Platform;
using IContainer = DryIoc.IContainer;
using Avalonia.Threading;
using DryIoc;
namespace Artemis.UI.Shared;
/// <summary>
/// Static UI helpers.
/// Static UI helpers.
/// </summary>
public static class UI
{
private static readonly BehaviorSubject<bool> MicaEnabledSubject = new(false);
public static EventLoopScheduler BackgroundScheduler = new(ts => new Thread(ts));
static UI()
{
KeyBindingsEnabled = InputElement.GotFocusEvent.Raised.Select(e => e.Item2.Source is not TextBox).StartWith(true);
}
public static EventLoopScheduler BackgroundScheduler = new EventLoopScheduler(ts => new Thread(ts));
internal static void ClearCache()
{
DeviceVisualizer.BitmapCache.Clear();
MicaEnabled = MicaEnabledSubject.AsObservable();
}
/// <summary>
@@ -40,4 +40,24 @@ public static class UI
/// Gets a boolean indicating whether hotkeys are to be disabled.
/// </summary>
public static IObservable<bool> KeyBindingsEnabled { get; }
/// <summary>
/// Gets a boolean indicating whether the Mica effect should be enabled.
/// </summary>
public static IObservable<bool> MicaEnabled { get; }
/// <summary>
/// Changes whether Mica should be enabled.
/// </summary>
/// <param name="enabled"></param>
public static void SetMicaEnabled(bool enabled)
{
if (MicaEnabledSubject.Value != enabled)
Dispatcher.UIThread.Invoke(() => MicaEnabledSubject.OnNext(enabled));
}
internal static void ClearCache()
{
DeviceVisualizer.BitmapCache.Clear();
}
}