mirror of
https://github.com/sp-tarkov/patcher.git
synced 2025-02-12 17:10:46 -05:00
Replace ViewNavigator with ReactiveUI RouterState, Fix PatchHelper rasing progress changed with no remaining source files, fix view load race conditions
This commit is contained in:
parent
6ef883958d
commit
25a3c270be
@ -1,14 +0,0 @@
|
||||
using ReactiveUI;
|
||||
|
||||
namespace PatchClient.Models
|
||||
{
|
||||
public class ViewNavigator : ReactiveObject
|
||||
{
|
||||
private object _SelectedViewModel;
|
||||
public object SelectedViewModel
|
||||
{
|
||||
get => _SelectedViewModel;
|
||||
set => this.RaiseAndSetIfChanged(ref _SelectedViewModel, value);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
using Avalonia;
|
||||
using Avalonia.ReactiveUI;
|
||||
using Splat;
|
||||
using System;
|
||||
using ReactiveUI;
|
||||
using System.Reflection;
|
||||
|
||||
namespace PatchClient
|
||||
{
|
||||
@ -15,9 +18,14 @@ namespace PatchClient
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
{
|
||||
Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetExecutingAssembly());
|
||||
|
||||
return AppBuilder.Configure<App>()
|
||||
.UseReactiveUI()
|
||||
.UsePlatformDetect()
|
||||
.LogToTrace()
|
||||
.UseReactiveUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
using Avalonia;
|
||||
using PatchClient.Models;
|
||||
using ReactiveUI;
|
||||
using Splat;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace PatchClient.ViewModels
|
||||
{
|
||||
public class MainWindowViewModel : ViewModelBase
|
||||
public class MainWindowViewModel : ReactiveObject, IActivatableViewModel, IScreen
|
||||
{
|
||||
public ViewModelActivator Activator { get; } = new ViewModelActivator();
|
||||
public RoutingState Router { get; } = new RoutingState();
|
||||
|
||||
public ICommand CloseCommand => ReactiveCommand.Create(() =>
|
||||
{
|
||||
if (Application.Current.ApplicationLifetime is Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime desktopApp)
|
||||
@ -16,12 +18,12 @@ namespace PatchClient.ViewModels
|
||||
}
|
||||
});
|
||||
|
||||
public ViewNavigator navigator { get; set; } = new ViewNavigator();
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
navigator.SelectedViewModel = new PatcherViewModel();
|
||||
|
||||
Locator.CurrentMutable.RegisterConstant(navigator, typeof(ViewNavigator));
|
||||
this.WhenActivated((CompositeDisposable disposable) =>
|
||||
{
|
||||
Router.Navigate.Execute(new PatcherViewModel(this));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,14 +4,14 @@ namespace PatchClient.ViewModels
|
||||
{
|
||||
public class MessageViewModel : ViewModelBase
|
||||
{
|
||||
private string _InfoText;
|
||||
private string _InfoText = "";
|
||||
public string InfoText
|
||||
{
|
||||
get => _InfoText;
|
||||
set => this.RaiseAndSetIfChanged(ref _InfoText, value);
|
||||
}
|
||||
|
||||
public MessageViewModel(string Message)
|
||||
public MessageViewModel(IScreen Host, string Message) : base(Host)
|
||||
{
|
||||
InfoText = Message;
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Threading;
|
||||
using PatchClient.Models;
|
||||
using PatcherUtils;
|
||||
using ReactiveUI;
|
||||
using Splat;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PatchClient.ViewModels
|
||||
@ -16,7 +17,7 @@ namespace PatchClient.ViewModels
|
||||
|
||||
public ObservableCollection<LineItemProgress> LineItems { get; set; } = new ObservableCollection<LineItemProgress>();
|
||||
|
||||
private string _ProgressMessage;
|
||||
private string _ProgressMessage = "";
|
||||
public string ProgressMessage
|
||||
{
|
||||
get => _ProgressMessage;
|
||||
@ -30,35 +31,67 @@ namespace PatchClient.ViewModels
|
||||
set => this.RaiseAndSetIfChanged(ref _PatchPercent, value);
|
||||
}
|
||||
|
||||
private string _PatchMessage;
|
||||
private string _PatchMessage = "";
|
||||
public string PatchMessage
|
||||
{
|
||||
get => _PatchMessage;
|
||||
set => this.RaiseAndSetIfChanged(ref _PatchMessage, value);
|
||||
}
|
||||
|
||||
private ViewNavigator navigator => Locator.Current.GetService<ViewNavigator>();
|
||||
|
||||
public PatcherViewModel()
|
||||
public PatcherViewModel(IScreen Host) : base(Host)
|
||||
{
|
||||
RunPatcher();
|
||||
this.WhenActivated((CompositeDisposable disposables) =>
|
||||
{
|
||||
//Test();
|
||||
RunPatcher();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A dumb testing method to see if things look right. Obsolete is used more like a warning here.
|
||||
/// </summary>
|
||||
[Obsolete]
|
||||
private void Test()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
LineItem x = new LineItem("test 1", 30);
|
||||
LineItem xx = new LineItem("test 2", 100);
|
||||
LineItem xxx = new LineItem("test 3", 70);
|
||||
|
||||
LineItems.Add(new LineItemProgress(x));
|
||||
LineItems.Add(new LineItemProgress(xx));
|
||||
LineItems.Add(new LineItemProgress(xxx));
|
||||
|
||||
for (int i = 0; i <= 100; i++)
|
||||
{
|
||||
System.Threading.Thread.Sleep(20);
|
||||
PatchPercent = i;
|
||||
ProgressMessage = $"Patching @ {i}%";
|
||||
|
||||
foreach (var item in LineItems)
|
||||
{
|
||||
item.UpdateProgress(item.Total - i);
|
||||
}
|
||||
}
|
||||
|
||||
await NavigateToWithDelay(new MessageViewModel(HostScreen, "Test Complete"), 400);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void RunPatcher()
|
||||
{
|
||||
Task.Run(() =>
|
||||
Task.Run(async() =>
|
||||
{
|
||||
//Slight delay to avoid some weird race condition in avalonia core, seems to be a bug, but also maybe I'm just stupid, idk -waffle
|
||||
//Error without delay: An item with the same key has already been added. Key: [1, Avalonia.Controls.Generators.ItemContainerInfo]
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
|
||||
PatchHelper patcher = new PatchHelper(Environment.CurrentDirectory, null, LazyOperations.PatchFolder);
|
||||
|
||||
patcher.ProgressChanged += patcher_ProgressChanged;
|
||||
|
||||
string message = patcher.ApplyPatches();
|
||||
|
||||
navigator.SelectedViewModel = new MessageViewModel(message).WithDelay(400);
|
||||
await NavigateToWithDelay(new MessageViewModel(HostScreen, message), 400);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,22 +1,72 @@
|
||||
using PatchClient.Models;
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PatchClient.ViewModels
|
||||
{
|
||||
public class ViewModelBase : ReactiveObject
|
||||
public class ViewModelBase : ReactiveObject, IActivatableViewModel, IRoutableViewModel
|
||||
{
|
||||
public ViewModelActivator Activator { get; } = new ViewModelActivator();
|
||||
|
||||
public string? UrlPathSegment => Guid.NewGuid().ToString().Substring(0, 7);
|
||||
|
||||
public IScreen HostScreen { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Delay the return of the viewmodel
|
||||
/// </summary>
|
||||
/// <param name="Milliseconds">The amount of time in milliseconds to delay</param>
|
||||
/// <returns>The viewmodel after the delay time</returns>
|
||||
/// <remarks>Useful to delay the navigation to another view via the <see cref="ViewNavigator"/>. For instance, to allow an animation to complete.</remarks>
|
||||
public ViewModelBase WithDelay(int Milliseconds)
|
||||
/// <remarks>Useful to delay the navigation to another view. For instance, to allow an animation to complete.</remarks>
|
||||
private async Task<ViewModelBase> WithDelay(int Milliseconds)
|
||||
{
|
||||
System.Threading.Thread.Sleep(Milliseconds);
|
||||
await Task.Delay(Milliseconds);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigate to another viewmodel after a delay
|
||||
/// </summary>
|
||||
/// <param name="ViewModel"></param>
|
||||
/// <param name="Milliseconds"></param>
|
||||
/// <returns></returns>
|
||||
public async Task NavigateToWithDelay(ViewModelBase ViewModel, int Milliseconds)
|
||||
{
|
||||
await Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
HostScreen.Router.Navigate.Execute(await ViewModel.WithDelay(Milliseconds));
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigate to another viewmodel
|
||||
/// </summary>
|
||||
/// <param name="ViewModel"></param>
|
||||
public void NavigateTo(ViewModelBase ViewModel)
|
||||
{
|
||||
Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
HostScreen.Router.Navigate.Execute(ViewModel);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigate to the previous viewmodel
|
||||
/// </summary>
|
||||
public void NavigateBack()
|
||||
{
|
||||
Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
HostScreen.Router.NavigateBack.Execute();
|
||||
});
|
||||
}
|
||||
|
||||
public ViewModelBase(IScreen Host)
|
||||
{
|
||||
HostScreen = Host;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:cc="using:PatchClient.CustomControls"
|
||||
xmlns:rxui="using:Avalonia.ReactiveUI"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="PatchClient.Views.MainWindow"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
@ -29,9 +30,7 @@
|
||||
<cc:TitleBar Title="Patch Client"
|
||||
XButtonCommand="{Binding CloseCommand}"/>
|
||||
|
||||
<DockPanel LastChildFill="True" Grid.Row="1">
|
||||
<ContentControl Content="{Binding navigator.SelectedViewModel}"/>
|
||||
</DockPanel>
|
||||
<rxui:RoutedViewHost Router="{Binding Router}" Grid.Row="1"/>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
|
@ -1,10 +1,12 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using PatchClient.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace PatchClient.Views
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
public partial class MainWindow : ReactiveWindow<MainWindowViewModel>
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
@ -16,6 +18,7 @@ namespace PatchClient.Views
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.WhenActivated(disposables => { });
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using PatchClient.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace PatchClient.Views
|
||||
{
|
||||
public partial class MessageView : UserControl
|
||||
public partial class MessageView : ReactiveUserControl<MessageViewModel>
|
||||
{
|
||||
public MessageView()
|
||||
{
|
||||
@ -12,6 +14,7 @@ namespace PatchClient.Views
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.WhenActivated(disposables => { });
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using PatchClient.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace PatchClient.Views
|
||||
{
|
||||
public partial class PatcherView : UserControl
|
||||
public partial class PatcherView : ReactiveUserControl<PatcherViewModel>
|
||||
{
|
||||
public PatcherView()
|
||||
{
|
||||
@ -12,6 +14,7 @@ namespace PatchClient.Views
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.WhenActivated(disposables => { });
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
using Avalonia;
|
||||
using Avalonia.ReactiveUI;
|
||||
using Splat;
|
||||
using System;
|
||||
using ReactiveUI;
|
||||
using System.Reflection;
|
||||
|
||||
namespace PatchGenerator
|
||||
{
|
||||
@ -15,9 +18,14 @@ namespace PatchGenerator
|
||||
|
||||
// Avalonia configuration, don't remove; also used by visual designer.
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
{
|
||||
Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetExecutingAssembly());
|
||||
|
||||
return AppBuilder.Configure<App>()
|
||||
.UseReactiveUI()
|
||||
.UsePlatformDetect()
|
||||
.LogToTrace()
|
||||
.UseReactiveUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
{
|
||||
"profiles": {
|
||||
"PatchGenerator": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "\"OutputFolderName::Patcher_12.3.4.5_to_6.7.8.9\" \"SourceFolderPath::C:\\Users\\JohnO\\Desktop\\12.12.10.16338\" \"TargetFolderPath::C:\\Users\\JohnO\\Desktop\\12.11.7.15680\" \"AutoZip::True\"",
|
||||
"workingDirectory": "C:\\Users\\JohnO\\Desktop\\Patcher\\"
|
||||
"commandName": "Project"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,17 @@
|
||||
using Avalonia;
|
||||
using PatchGenerator.Models;
|
||||
using ReactiveUI;
|
||||
using Splat;
|
||||
using System.Windows.Input;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Disposables;
|
||||
|
||||
namespace PatchGenerator.ViewModels
|
||||
{
|
||||
public class MainWindowViewModel : ViewModelBase
|
||||
public class MainWindowViewModel : ReactiveObject, IActivatableViewModel, IScreen
|
||||
{
|
||||
public ICommand CloseCommand => ReactiveCommand.Create(() =>
|
||||
public RoutingState Router { get; } = new RoutingState();
|
||||
public ViewModelActivator Activator { get; } = new ViewModelActivator();
|
||||
|
||||
public ReactiveCommand<Unit, Unit> CloseCommand => ReactiveCommand.Create(() =>
|
||||
{
|
||||
if (Application.Current.ApplicationLifetime is Avalonia.Controls.ApplicationLifetimes.IClassicDesktopStyleApplicationLifetime desktopApp)
|
||||
{
|
||||
@ -16,25 +19,26 @@ namespace PatchGenerator.ViewModels
|
||||
}
|
||||
});
|
||||
|
||||
public ViewNavigator navigator { get; set; } = new ViewNavigator();
|
||||
public MainWindowViewModel(GenStartupArgs genArgs = null)
|
||||
{
|
||||
Locator.CurrentMutable.RegisterConstant(navigator, typeof(ViewNavigator));
|
||||
|
||||
if (genArgs != null && genArgs.ReadyToRun)
|
||||
this.WhenActivated((CompositeDisposable disposables) =>
|
||||
{
|
||||
PatchGenInfo genInfo = new PatchGenInfo();
|
||||
|
||||
genInfo.TargetFolderPath = genArgs.TargetFolderPath;
|
||||
genInfo.SourceFolderPath = genArgs.SourceFolderPath;
|
||||
genInfo.PatchName = genArgs.OutputFolderName;
|
||||
genInfo.AutoZip = genArgs.AutoZip;
|
||||
if (genArgs != null && genArgs.ReadyToRun)
|
||||
{
|
||||
PatchGenInfo genInfo = new PatchGenInfo();
|
||||
|
||||
navigator.SelectedViewModel = new PatchGenerationViewModel(genInfo);
|
||||
return;
|
||||
}
|
||||
genInfo.TargetFolderPath = genArgs.TargetFolderPath;
|
||||
genInfo.SourceFolderPath = genArgs.SourceFolderPath;
|
||||
genInfo.PatchName = genArgs.OutputFolderName;
|
||||
genInfo.AutoZip = genArgs.AutoZip;
|
||||
|
||||
navigator.SelectedViewModel = new OptionsViewModel();
|
||||
Router.Navigate.Execute(new PatchGenerationViewModel(this, genInfo));
|
||||
return;
|
||||
}
|
||||
|
||||
Router.Navigate.Execute(new OptionsViewModel(this));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
using PatchGenerator.Models;
|
||||
using Splat;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace PatchGenerator.ViewModels
|
||||
{
|
||||
@ -7,9 +7,7 @@ namespace PatchGenerator.ViewModels
|
||||
{
|
||||
public PatchGenInfo GenerationInfo { get; set; } = new PatchGenInfo();
|
||||
|
||||
private ViewNavigator navigator => Locator.Current.GetService<ViewNavigator>();
|
||||
|
||||
public OptionsViewModel()
|
||||
public OptionsViewModel(IScreen Host) : base(Host)
|
||||
{
|
||||
GenerationInfo.SourceFolderPath = "Drop SOURCE folder here";
|
||||
GenerationInfo.TargetFolderPath = "Drop TARGET folder here";
|
||||
@ -17,7 +15,7 @@ namespace PatchGenerator.ViewModels
|
||||
|
||||
public void GeneratePatches()
|
||||
{
|
||||
navigator.SelectedViewModel = new PatchGenerationViewModel(GenerationInfo);
|
||||
NavigateTo(new PatchGenerationViewModel(HostScreen, GenerationInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -42,7 +43,7 @@ namespace PatchGenerator.ViewModels
|
||||
private Stopwatch patchGenStopwatch = new Stopwatch();
|
||||
|
||||
private readonly PatchGenInfo generationInfo;
|
||||
public PatchGenerationViewModel(PatchGenInfo GenerationInfo)
|
||||
public PatchGenerationViewModel(IScreen Host, PatchGenInfo GenerationInfo) : base(Host)
|
||||
{
|
||||
generationInfo = GenerationInfo;
|
||||
|
||||
@ -55,17 +56,16 @@ namespace PatchGenerator.ViewModels
|
||||
});
|
||||
}
|
||||
|
||||
GeneratePatches();
|
||||
this.WhenActivated((CompositeDisposable dissposables) =>
|
||||
{
|
||||
GeneratePatches();
|
||||
});
|
||||
}
|
||||
|
||||
public void GeneratePatches()
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
//Slight delay to avoid some weird race condition in avalonia core, seems to be a bug, but also maybe I'm just stupid, idk -waffle
|
||||
//Error without delay: An item with the same key has already been added. Key: [1, Avalonia.Controls.Generators.ItemContainerInfo]
|
||||
System.Threading.Thread.Sleep(1000);
|
||||
|
||||
string patchOutputFolder = Path.Join(generationInfo.PatchName.FromCwd(), LazyOperations.PatchFolder);
|
||||
|
||||
PatchHelper patcher = new PatchHelper(generationInfo.SourceFolderPath, generationInfo.TargetFolderPath, patchOutputFolder);
|
||||
|
@ -1,8 +1,72 @@
|
||||
using Avalonia.Threading;
|
||||
using ReactiveUI;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PatchGenerator.ViewModels
|
||||
{
|
||||
public class ViewModelBase : ReactiveObject
|
||||
public class ViewModelBase : ReactiveObject, IActivatableViewModel, IRoutableViewModel
|
||||
{
|
||||
public ViewModelActivator Activator { get; } = new ViewModelActivator();
|
||||
|
||||
public string? UrlPathSegment => Guid.NewGuid().ToString().Substring(0, 7);
|
||||
|
||||
public IScreen HostScreen { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Delay the return of the viewmodel
|
||||
/// </summary>
|
||||
/// <param name="Milliseconds">The amount of time in milliseconds to delay</param>
|
||||
/// <returns>The viewmodel after the delay time</returns>
|
||||
/// <remarks>Useful to delay the navigation to another view. For instance, to allow an animation to complete.</remarks>
|
||||
private async Task<ViewModelBase> WithDelay(int Milliseconds)
|
||||
{
|
||||
await Task.Delay(Milliseconds);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigate to another viewmodel after a delay
|
||||
/// </summary>
|
||||
/// <param name="ViewModel"></param>
|
||||
/// <param name="Milliseconds"></param>
|
||||
/// <returns></returns>
|
||||
public async Task NavigateToWithDelay(ViewModelBase ViewModel, int Milliseconds)
|
||||
{
|
||||
await Dispatcher.UIThread.InvokeAsync(async () =>
|
||||
{
|
||||
HostScreen.Router.Navigate.Execute(await ViewModel.WithDelay(Milliseconds));
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigate to another viewmodel
|
||||
/// </summary>
|
||||
/// <param name="ViewModel"></param>
|
||||
public void NavigateTo(ViewModelBase ViewModel)
|
||||
{
|
||||
Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
HostScreen.Router.Navigate.Execute(ViewModel);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigate to the previous viewmodel
|
||||
/// </summary>
|
||||
public void NavigateBack()
|
||||
{
|
||||
Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
HostScreen.Router.NavigateBack.Execute();
|
||||
});
|
||||
}
|
||||
|
||||
public ViewModelBase(IScreen Host)
|
||||
{
|
||||
HostScreen = Host;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:cc="using:PatchGenerator.CustomControls"
|
||||
xmlns:rxui="using:Avalonia.ReactiveUI"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="PatchGenerator.Views.MainWindow"
|
||||
Icon="/Assets/avalonia-logo.ico"
|
||||
@ -28,9 +29,7 @@
|
||||
<cc:TitleBar Title="Patch Generator"
|
||||
XButtonCommand="{Binding CloseCommand}"/>
|
||||
|
||||
<DockPanel LastChildFill="True" Grid.Row="1">
|
||||
<ContentControl Content="{Binding navigator.SelectedViewModel}"/>
|
||||
</DockPanel>
|
||||
<rxui:RoutedViewHost Router="{Binding Router}" Grid.Row="1" />
|
||||
|
||||
</Grid>
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using PatchGenerator.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace PatchGenerator.Views
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
public partial class MainWindow : ReactiveWindow<MainWindowViewModel>
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
@ -16,6 +18,7 @@ namespace PatchGenerator.Views
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.WhenActivated(disposables => { });
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using PatchGenerator.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace PatchGenerator.Views
|
||||
{
|
||||
public partial class OptionsView : UserControl
|
||||
public partial class OptionsView : ReactiveUserControl<OptionsViewModel>
|
||||
{
|
||||
public OptionsView()
|
||||
{
|
||||
@ -12,6 +14,7 @@ namespace PatchGenerator.Views
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.WhenActivated(disposables => { });
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Avalonia.ReactiveUI;
|
||||
using PatchGenerator.AttachedProperties;
|
||||
using PatchGenerator.ViewModels;
|
||||
using ReactiveUI;
|
||||
|
||||
namespace PatchGenerator.Views
|
||||
{
|
||||
public partial class PatchGenerationView : UserControl
|
||||
public partial class PatchGenerationView : ReactiveUserControl<PatchGenerationViewModel>
|
||||
{
|
||||
public PatchGenerationView()
|
||||
{
|
||||
@ -13,6 +16,7 @@ namespace PatchGenerator.Views
|
||||
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.WhenActivated(disposables => { });
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
|
@ -242,6 +242,9 @@ namespace PatcherUtils
|
||||
|
||||
//Any remaining source files do not exist in the target folder and can be removed.
|
||||
//reset progress info
|
||||
|
||||
if (SourceFiles.Count == 0) return true;
|
||||
|
||||
RaiseProgressChanged(0, SourceFiles.Count, "Processing .del files...");
|
||||
filesProcessed = 0;
|
||||
fileCountTotal = SourceFiles.Count;
|
||||
|
BIN
Patcher/PatcherUtils/Resources/PatchClient.exe
(Stored with Git LFS)
BIN
Patcher/PatcherUtils/Resources/PatchClient.exe
(Stored with Git LFS)
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user