| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 | using Avalonia.Controls;using Avalonia.Layout;using CommunityToolkit.Mvvm.ComponentModel;using DialogHostAvalonia;using InABox.Avalonia.Components;using InABox.Avalonia.Router;namespace InABox.Avalonia;public interface IViewModelBase{    Task Activate();    Task Deactivate();    bool OnBackButtonPressed();    bool BackButtonVisible { get; set; }        bool ProgressVisible { get; set; }    AvaloniaMenuItemCollection PrimaryMenu { get; set; }    AvaloniaMenuItemCollection SecondaryMenu { get; set; }}public interface IPopupViewModel{    bool IsClosed { get; }}/// <summary>/// Indicates that this view model can be a module or a popup./// </summary>public interface IDualFunctionViewModel : IPopupViewModel, IViewModelBase{    bool IsPopup { get; set; }}public interface IAlignedPopup{    HorizontalAlignment HorizontalAlignment { get; }    VerticalAlignment VerticalAlignment { get; }}public interface IPopupViewModel<TResult> : IPopupViewModel{    TResult? GetResult();}public static class Navigation{    private static readonly HistoryRouter<IViewModelBase> _router;    // private static Dictionary<Type, Func<IViewModelBase>> ViewModelFactory = new();    //    // public static void Register<TViewModel>(Func<IViewModelBase> create) where TViewModel : IViewModelBase    // {    //     ViewModelFactory[typeof(TViewModel)] = create;    // }        static Navigation()    {        _router = new HistoryRouter<IViewModelBase>(x =>        {            // if (ViewModelFactory.TryGetValue(x, out var create))            // {            //     var result = create();            //     return result;            // }            var model = Activator.CreateInstance(x);            return model as IViewModelBase;        });        _router.CurrentViewModelChanging += (@base, direction) => CurrentViewModelChanging?.Invoke(@base, direction);        _router.CurrentViewModelChanged += @base => CurrentViewModelChanged?.Invoke(@base);    }    public static void Back()    {        _router.Back();    }    public static void Navigate<T>(Action<T>? configure = null) where T : IViewModelBase    {        _router.GoTo<T>(configure);    }    public static async Task<object?> Popup<T>(Action<T>? configure = null, bool canTapAway = true)        where T : IViewModelBase, IPopupViewModel    {        var viewModel = _router.InstantiateViewModel<T>(configure);        return await Popup(viewModel, canTapAway);    }    public static async Task<object?> Popup<T>(T viewModel, bool canTapAway = true)        where T : IViewModelBase, IPopupViewModel    {        if (viewModel is IDualFunctionViewModel dualFunction)        {            dualFunction.IsPopup = true;        }        await viewModel.Activate();        var _result = await DialogHostAvalonia.DialogHost.Show(viewModel, (object sender, DialogClosingEventArgs eventArgs) =>        {            if(!canTapAway && !viewModel.IsClosed)            {                eventArgs.Cancel();            }        });        await viewModel.Deactivate();        return _result;    }    public static async Task<TResult?> Popup<T, TResult>(Action<T>? configure = null, bool canTapAway = true)        where T : IViewModelBase, IPopupViewModel<TResult>    {        var viewModel = _router.InstantiateViewModel<T>(configure);        return await Popup<T, TResult>(viewModel, canTapAway);    }    public static async Task<TResult?> Popup<T, TResult>(T viewModel, bool canTapAway = true)        where T : IViewModelBase, IPopupViewModel<TResult>    {        if (viewModel is IDualFunctionViewModel dualFunction)        {            dualFunction.IsPopup = true;        }        await viewModel.Activate();        var _result = await DialogHostAvalonia.DialogHost.Show(viewModel, (object sender, DialogClosingEventArgs eventArgs) =>        {            if(!canTapAway && !viewModel.IsClosed)            {                eventArgs.Cancel();            }        });        await viewModel.Deactivate();        return viewModel.GetResult();    }    public static void Reset<T>(Action<T>? configure = null) where T : IViewModelBase    {        _router.Reset<T>(configure);    }    public static event Action<IViewModelBase, RouterDirection>? CurrentViewModelChanging;    public static event Action<IViewModelBase>? CurrentViewModelChanged;}public class BasePopupViewModel<TResult> : ObservableObject, IPopupViewModel<TResult?>, IViewModelBase{    #region IPopupViewModel    public bool IsClosed { get; private set; }    protected TResult? _result;    public TResult? GetResult()    {        return _result;    }    public void Close(TResult? result)    {        _result = result;        IsClosed = true;        DialogHost.GetDialogSession(null)?.Close();    }    #endregion    #region IViewModel    public bool BackButtonVisible { get; set; }    public bool ProgressVisible { get; set; }    public AvaloniaMenuItemCollection PrimaryMenu { get; set; } = new();    public AvaloniaMenuItemCollection SecondaryMenu { get; set; } = new();    public virtual Task Activate()    {        return Task.CompletedTask;    }    public virtual Task Deactivate()    {        return Task.CompletedTask;    }    public virtual bool OnBackButtonPressed()    {        return true;    }    #endregion}
 |