69 lines
1.8 KiB
C#
69 lines
1.8 KiB
C#
using System.Reactive.Linq;
|
|
using System.Runtime.InteropServices;
|
|
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
|
|
namespace InkForge.Desktop.Services;
|
|
|
|
public class TopLevels
|
|
{
|
|
public static readonly AttachedProperty<object?> RegisterProperty
|
|
= AvaloniaProperty.RegisterAttached<TopLevels, Visual, object?>("Register");
|
|
private static readonly Dictionary<object, Visual> RegistrationMapper = [];
|
|
|
|
public static TopLevel? ActiveTopLevel { get; private set; }
|
|
|
|
static TopLevels()
|
|
{
|
|
RegisterProperty.Changed.AddClassHandler<Visual>(RegisterChanged);
|
|
WindowBase.IsActiveProperty.Changed.Subscribe(WindowActiveChanged);
|
|
}
|
|
|
|
public static object? GetRegister(AvaloniaObject element)
|
|
{
|
|
return element.GetValue(RegisterProperty);
|
|
}
|
|
|
|
public static TopLevel? GetTopLevelForContext(object context)
|
|
{
|
|
return TopLevel.GetTopLevel(GetVisualForContext(context));
|
|
}
|
|
|
|
public static Visual? GetVisualForContext(object context)
|
|
{
|
|
return RegistrationMapper.TryGetValue(context, out var result) ? result : null;
|
|
}
|
|
|
|
public static void SetRegister(AvaloniaObject element, object value)
|
|
{
|
|
element.SetValue(RegisterProperty, value);
|
|
}
|
|
|
|
private static void RegisterChanged(Visual sender, AvaloniaPropertyChangedEventArgs e)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(sender);
|
|
|
|
// Unregister any old registered context
|
|
if (e.OldValue != null)
|
|
{
|
|
RegistrationMapper.Remove(e.OldValue);
|
|
}
|
|
|
|
// Register any new context
|
|
if (e.NewValue != null)
|
|
{
|
|
CollectionsMarshal.GetValueRefOrAddDefault(RegistrationMapper, e.NewValue, out _) = sender;
|
|
}
|
|
}
|
|
|
|
private static void WindowActiveChanged(AvaloniaPropertyChangedEventArgs<bool> e)
|
|
{
|
|
ActiveTopLevel = (e.GetOldAndNewValue<bool>(), e.Sender) switch
|
|
{
|
|
((false, true), TopLevel topLevel) => topLevel,
|
|
((true, false), { } topLevel) when topLevel == ActiveTopLevel => null,
|
|
_ => ActiveTopLevel,
|
|
};
|
|
}
|
|
}
|