mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-12 13:28:33 +00:00
UI - Move notifications to the overlay layer
This commit is contained in:
parent
02798b6d6e
commit
7eccdf079a
54
src/Artemis.UI.Shared/Controls/NotificationHost.cs
Normal file
54
src/Artemis.UI.Shared/Controls/NotificationHost.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Layout;
|
||||
|
||||
namespace Artemis.UI.Shared;
|
||||
|
||||
internal class NotificationHost : ContentControl
|
||||
{
|
||||
private IDisposable? _rootBoundsWatcher;
|
||||
|
||||
public NotificationHost()
|
||||
{
|
||||
Background = null;
|
||||
HorizontalAlignment = HorizontalAlignment.Center;
|
||||
VerticalAlignment = VerticalAlignment.Center;
|
||||
}
|
||||
|
||||
protected override Type StyleKeyOverride => typeof(OverlayPopupHost);
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
_ = base.MeasureOverride(availableSize);
|
||||
|
||||
if (VisualRoot is TopLevel tl)
|
||||
return tl.ClientSize;
|
||||
if (VisualRoot is Control c)
|
||||
return c.Bounds.Size;
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnAttachedToVisualTree(e);
|
||||
if (e.Root is Control wb)
|
||||
// OverlayLayer is a Canvas, so we won't get a signal to resize if the window
|
||||
// bounds change. Subscribe to force update
|
||||
_rootBoundsWatcher = wb.GetObservable(BoundsProperty).Subscribe(_ => OnRootBoundsChanged());
|
||||
}
|
||||
|
||||
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
||||
{
|
||||
base.OnDetachedFromVisualTree(e);
|
||||
_rootBoundsWatcher?.Dispose();
|
||||
_rootBoundsWatcher = null;
|
||||
}
|
||||
|
||||
private void OnRootBoundsChanged()
|
||||
{
|
||||
InvalidateMeasure();
|
||||
}
|
||||
}
|
||||
@ -2,11 +2,11 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Layout;
|
||||
using Avalonia.Threading;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using ReactiveUI;
|
||||
using Button = Avalonia.Controls.Button;
|
||||
|
||||
namespace Artemis.UI.Shared.Services.Builders;
|
||||
|
||||
@ -117,34 +117,34 @@ public class NotificationBuilder
|
||||
/// <exception cref="ArtemisSharedUIException" />
|
||||
public Action Show()
|
||||
{
|
||||
Panel? panel = _parent.Find<Panel>("NotificationContainer");
|
||||
if (panel == null)
|
||||
throw new ArtemisSharedUIException("Can't display a notification on a window without a NotificationContainer.");
|
||||
|
||||
Dispatcher.UIThread.Post(() =>
|
||||
{
|
||||
panel.Children.Add(_infoBar);
|
||||
OverlayLayer? overlayLayer = OverlayLayer.GetOverlayLayer(_parent);
|
||||
if (overlayLayer == null)
|
||||
throw new ArtemisSharedUIException("Can't display a notification on a window an overlay layer.");
|
||||
|
||||
NotificationHost container = new() {Content = _infoBar};
|
||||
overlayLayer.Children.Add(container);
|
||||
_infoBar.Closed += InfoBarOnClosed;
|
||||
_infoBar.IsOpen = true;
|
||||
});
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Task.Delay(_timeout);
|
||||
Dispatcher.UIThread.Post(() => _infoBar.IsOpen = false);
|
||||
Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
await Task.Delay(_timeout);
|
||||
_infoBar.IsOpen = false;
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
void InfoBarOnClosed(InfoBar sender, InfoBarClosedEventArgs args)
|
||||
{
|
||||
overlayLayer.Children.Remove(container);
|
||||
_infoBar.Closed -= InfoBarOnClosed;
|
||||
}
|
||||
});
|
||||
|
||||
return () => Dispatcher.UIThread.Post(() => _infoBar.IsOpen = false);
|
||||
}
|
||||
|
||||
private void InfoBarOnClosed(InfoBar sender, InfoBarClosedEventArgs args)
|
||||
{
|
||||
_infoBar.Closed -= InfoBarOnClosed;
|
||||
if (_parent.Content is not Panel panel)
|
||||
return;
|
||||
|
||||
panel.Children.Remove(_infoBar);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -180,7 +180,7 @@ public class NotificationButtonBuilder
|
||||
_action = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Changes action that is called when the button is clicked.
|
||||
/// </summary>
|
||||
@ -222,9 +222,13 @@ public class NotificationButtonBuilder
|
||||
button.Classes.Add("AppBarButton");
|
||||
|
||||
if (_action != null)
|
||||
{
|
||||
button.Command = ReactiveCommand.Create(() => _action());
|
||||
}
|
||||
else if (_asyncAction != null)
|
||||
{
|
||||
button.Command = ReactiveCommand.CreateFromTask(() => _asyncAction());
|
||||
}
|
||||
else if (_command != null)
|
||||
{
|
||||
button.Command = _command;
|
||||
|
||||
@ -17,6 +17,8 @@
|
||||
<Setter Property="Opacity" Value="0" />
|
||||
<Setter Property="MaxWidth" Value="600" />
|
||||
<Setter Property="Margin" Value="15"/>
|
||||
<Setter Property="VerticalAlignment" Value="Bottom"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Right"/>
|
||||
<Setter Property="Transitions">
|
||||
<Transitions>
|
||||
<DoubleTransition Property="Opacity" Duration="0:0:0.2"/>
|
||||
|
||||
@ -1,17 +1,14 @@
|
||||
<Styles xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia">
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:shared="clr-namespace:Artemis.UI.Shared">
|
||||
<Design.PreviewWith>
|
||||
<Border Padding="20">
|
||||
<!-- Add Controls for Previewer Here -->
|
||||
</Border>
|
||||
</Design.PreviewWith>
|
||||
|
||||
<Style Selector="StackPanel.notification-container">
|
||||
<Setter Property="Spacing" Value="-25" />
|
||||
</Style>
|
||||
|
||||
<Style Selector="StackPanel.notification-container controls|InfoBar">
|
||||
<Style Selector="shared|NotificationHost controls|InfoBar">
|
||||
<Setter Property="MaxHeight" Value="0" />
|
||||
<Style.Animations>
|
||||
<Animation Duration="0:0:0.2" Easing="CubicEaseOut" FillMode="Forward">
|
||||
|
||||
@ -36,6 +36,5 @@
|
||||
</Border>
|
||||
<ContentControl Content="{CompiledBinding}" />
|
||||
</DockPanel>
|
||||
<StackPanel Classes="notification-container" Name="NotificationContainer" VerticalAlignment="Bottom" HorizontalAlignment="Right"/>
|
||||
</Panel>
|
||||
</windowing:AppWindow>
|
||||
@ -2,7 +2,6 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
|
||||
xmlns:debugger="clr-namespace:Artemis.UI.Screens.Debugger"
|
||||
xmlns:shared="clr-namespace:Artemis.UI.Shared;assembly=Artemis.UI.Shared"
|
||||
@ -35,7 +34,5 @@
|
||||
<Border Classes="router-container" Grid.Column="1">
|
||||
<ContentControl Content="{CompiledBinding SelectedItem}" Margin="15"></ContentControl>
|
||||
</Border>
|
||||
|
||||
<StackPanel Grid.Column="0" Grid.ColumnSpan="2" Classes="notification-container" Name="NotificationContainer" VerticalAlignment="Bottom" HorizontalAlignment="Right" />
|
||||
</Grid>
|
||||
</windowing:AppWindow>
|
||||
@ -69,7 +69,5 @@
|
||||
</Panel>
|
||||
|
||||
</Border>
|
||||
|
||||
<StackPanel Grid.Column="0" Grid.ColumnSpan="3" Classes="notification-container" Name="NotificationContainer" VerticalAlignment="Top" HorizontalAlignment="Right" />
|
||||
</Grid>
|
||||
</windowing:AppWindow>
|
||||
@ -70,7 +70,5 @@
|
||||
<ContentControl Margin="0 0 5 0" Content="{CompiledBinding ConfigurationViewModel}"></ContentControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
|
||||
<StackPanel Name="NotificationContainer" Classes="notification-container" VerticalAlignment="Bottom" HorizontalAlignment="Right" />
|
||||
</Panel>
|
||||
</windowing:AppWindow>
|
||||
Loading…
x
Reference in New Issue
Block a user