UI - Added routing (#802)

ColorGradient - Fixed GetColor returning the first stop if position was after the last stop
This commit is contained in:
RobertBeekman authored and GitHub committed 2023-07-02 22:15:38 +02:00
1 parent 79309dcee7
commit 962b13c6ed
77 files changed
+2034 -854

No files matched your search

+7 -6
View File
@@ -2,14 +2,15 @@
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:reactiveUi="http://reactiveui.net"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:vm="clr-namespace:Artemis.UI.Screens.Root;assembly=Artemis.UI"
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:ui="clr-namespace:Artemis.UI"
x:DataType="vm:RootViewModel"
x:Class="Artemis.UI.Screens.Root.RootView">
<reactiveUi:RoutedViewHost Router="{CompiledBinding Router}">
<reactiveUi:RoutedViewHost.PageTransition>
<CompositePageTransition></CompositePageTransition>
</reactiveUi:RoutedViewHost.PageTransition>
</reactiveUi:RoutedViewHost>
<controls:Frame Name="RootFrame" IsNavigationStackEnabled="False" CacheSize="0">
<controls:Frame.NavigationPageFactory>
<ui:PageFactory/>
</controls:Frame.NavigationPageFactory>
</controls:Frame>
</UserControl>
+16 -1
View File
@@ -1,5 +1,8 @@
using Avalonia.Markup.Xaml;
using System;
using System.Reactive.Disposables;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using ReactiveUI;
namespace Artemis.UI.Screens.Root;
@@ -8,6 +11,18 @@ public partial class RootView : ReactiveUserControl<RootViewModel>
public RootView()
{
InitializeComponent();
this.WhenActivated(d => ViewModel.WhenAnyValue(vm => vm.Screen).Subscribe(Navigate).DisposeWith(d));
}
private void Navigate(IMainScreenViewModel viewModel)
{
try
{
Dispatcher.UIThread.Invoke(() => RootFrame.NavigateFromObject(viewModel));
}
catch (Exception)
{
// ignored
}
}
}
+31 -43
View File
@@ -1,69 +1,67 @@
using System;
using System.Linq;
using System.Reactive;
using System.Threading.Tasks;
using Artemis.Core;
using Artemis.Core.Services;
using Artemis.UI.DryIoc.Factories;
using Artemis.UI.Models;
using Artemis.UI.Screens.Sidebar;
using Artemis.UI.Services.Interfaces;
using Artemis.UI.Services.Updating;
using Artemis.UI.Shared;
using Artemis.UI.Shared.Routing;
using Artemis.UI.Shared.Services;
using Artemis.UI.Shared.Services.MainWindow;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Platform;
using Avalonia.Threading;
using ReactiveUI;
namespace Artemis.UI.Screens.Root;
public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvider
public class RootViewModel : RoutableScreen<IMainScreenViewModel>, IMainWindowProvider
{
private readonly IRouter _router;
private readonly ICoreService _coreService;
private readonly IDebugService _debugService;
private readonly DefaultTitleBarViewModel _defaultTitleBarViewModel;
private readonly IClassicDesktopStyleApplicationLifetime _lifeTime;
private readonly ISettingsService _settingsService;
private readonly ISidebarVmFactory _sidebarVmFactory;
private readonly IUpdateService _updateService;
private readonly IWindowService _windowService;
private SidebarViewModel? _sidebarViewModel;
private ViewModelBase? _titleBarViewModel;
public RootViewModel(ICoreService coreService,
public RootViewModel(IRouter router,
ICoreService coreService,
ISettingsService settingsService,
IRegistrationService registrationService,
IWindowService windowService,
IMainWindowService mainWindowService,
IDebugService debugService,
IUpdateService updateService,
DefaultTitleBarViewModel defaultTitleBarViewModel,
ISidebarVmFactory sidebarVmFactory)
SidebarViewModel sidebarViewModel,
DefaultTitleBarViewModel defaultTitleBarViewModel)
{
Router = new RoutingState();
WindowSizeSetting = settingsService.GetSetting<WindowSize?>("WindowSize");
SidebarViewModel = sidebarViewModel;
_router = router;
_coreService = coreService;
_settingsService = settingsService;
_windowService = windowService;
_debugService = debugService;
_updateService = updateService;
_defaultTitleBarViewModel = defaultTitleBarViewModel;
_sidebarVmFactory = sidebarVmFactory;
_lifeTime = (IClassicDesktopStyleApplicationLifetime) Application.Current!.ApplicationLifetime!;
router.SetRoot(this);
mainWindowService.ConfigureMainWindowProvider(this);
mainWindowService.HostScreen = this;
DisplayAccordingToSettings();
OpenScreen = ReactiveCommand.Create<string>(ExecuteOpenScreen);
OpenDebugger = ReactiveCommand.CreateFromTask(ExecuteOpenDebugger);
Exit = ReactiveCommand.CreateFromTask(ExecuteExit);
Router.CurrentViewModel.Subscribe(UpdateTitleBarViewModel);
this.WhenAnyValue(vm => vm.Screen).Subscribe(UpdateTitleBarViewModel);
Task.Run(() =>
{
if (_updateService.Initialize())
@@ -76,26 +74,33 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi
});
}
public SidebarViewModel SidebarViewModel { get; }
public ReactiveCommand<string, Unit> OpenScreen { get; }
public ReactiveCommand<Unit, Unit> OpenDebugger { get; }
public ReactiveCommand<Unit, Unit> Exit { get; }
public SidebarViewModel? SidebarViewModel
{
get => _sidebarViewModel;
set => RaiseAndSetIfChanged(ref _sidebarViewModel, value);
}
public ViewModelBase? TitleBarViewModel
{
get => _titleBarViewModel;
set => RaiseAndSetIfChanged(ref _titleBarViewModel, value);
}
private void UpdateTitleBarViewModel(IRoutableViewModel? viewModel)
public void GoBack()
{
if (viewModel is MainScreenViewModel mainScreenViewModel && mainScreenViewModel.TitleBarViewModel != null)
TitleBarViewModel = mainScreenViewModel.TitleBarViewModel;
_router.GoBack();
}
public void GoForward()
{
_router.GoForward();
}
public static PluginSetting<WindowSize?>? WindowSizeSetting { get; private set; }
private void UpdateTitleBarViewModel(IMainScreenViewModel? viewModel)
{
if (viewModel?.TitleBarViewModel != null)
TitleBarViewModel = viewModel.TitleBarViewModel;
else
TitleBarViewModel = _defaultTitleBarViewModel;
}
@@ -104,8 +109,6 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi
{
WindowSizeSetting?.Save();
_lifeTime.MainWindow = null;
SidebarViewModel = null;
Router.NavigateAndReset.Execute(new EmptyViewModel(this, "blank")).Subscribe();
OnMainWindowClosed();
}
@@ -127,14 +130,9 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi
_windowService.ShowWindow<SplashViewModel>();
}
/// <inheritdoc />
public RoutingState Router { get; }
public static PluginSetting<WindowSize?>? WindowSizeSetting { get; private set; }
#region Tray commands
private void ExecuteOpenScreen(string displayName)
private void ExecuteOpenScreen(string path)
{
// The window will open on the UI thread at some point, respond to that to select the chosen screen
MainWindowOpened += OnEventHandler;
@@ -142,10 +140,9 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi
void OnEventHandler(object? sender, EventArgs args)
{
// Avoid threading issues by running this on the UI thread
if (SidebarViewModel != null)
Dispatcher.UIThread.InvokeAsync(() => SidebarViewModel.SelectedSidebarScreen = SidebarViewModel.SidebarScreens.FirstOrDefault(s => s.DisplayName == displayName));
MainWindowOpened -= OnEventHandler;
// Avoid threading issues by running this on the UI thread
Dispatcher.UIThread.InvokeAsync(async () => await _router.Navigate(path));
}
}
@@ -176,7 +173,6 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi
{
if (_lifeTime.MainWindow == null)
{
SidebarViewModel = _sidebarVmFactory.SidebarViewModel(this);
_lifeTime.MainWindow = new MainWindow {DataContext = this};
_lifeTime.MainWindow.Show();
_lifeTime.MainWindow.Closing += CurrentMainWindowOnClosing;
@@ -237,12 +233,4 @@ public class RootViewModel : ActivatableViewModelBase, IScreen, IMainWindowProvi
}
#endregion
}
internal class EmptyViewModel : MainScreenViewModel
{
/// <inheritdoc />
public EmptyViewModel(IScreen hostScreen, string urlPathSegment) : base(hostScreen, urlPathSegment)
{
}
}