mirror of
https://github.com/bloxstraplabs/bloxstrap.git
synced 2025-04-18 00:21:33 -07:00
144 lines
4.9 KiB
C#
144 lines
4.9 KiB
C#
using System.Windows.Controls;
|
|
using Wpf.Ui.Controls.Interfaces;
|
|
using Wpf.Ui.Mvvm.Contracts;
|
|
using System.ComponentModel;
|
|
using System.Windows;
|
|
|
|
using Bloxstrap.UI.ViewModels.Installer;
|
|
using Bloxstrap.UI.Elements.Installer.Pages;
|
|
using Bloxstrap.UI.Elements.Base;
|
|
using System.Windows.Media.Animation;
|
|
using System.Reflection.Metadata.Ecma335;
|
|
using Bloxstrap.Resources;
|
|
|
|
namespace Bloxstrap.UI.Elements.Installer
|
|
{
|
|
/// <summary>
|
|
/// Interaction logic for MainWindow.xaml
|
|
/// </summary>
|
|
///
|
|
/// The logic behind this wizard-like interface is full of gross hacks, but there's no easy way to do this and I've tried to
|
|
/// make it as nice and MVVM-"""conformant""" as can possibly be ¯\_(ツ)_/¯
|
|
///
|
|
/// Page ViewModels can request changing of navigation button states through the following call flow:
|
|
/// - Page ViewModel holds event for requesting button state change
|
|
/// - Page CodeBehind subscribes to event on page creation
|
|
/// - Page ViewModel invokes event when ready
|
|
/// - Page CodeBehind receives it, gets MainWindow, and directly calls MainWindow.SetButtonEnabled()
|
|
/// - MainWindow.SetButtonEnabled() directly calls MainWindowViewModel.SetButtonEnabled() which does the thing a voila
|
|
///
|
|
/// Page ViewModels can also be notified of when the next page button has been pressed and stop progression if needed through a callback
|
|
/// - MainWindow has a single-set Func<bool> property named NextPageCallback which is reset on every page load
|
|
/// - This callback is called when the next page button is pressed
|
|
/// - Page CodeBehind gets MainWindow and sets the callback to its own local function on page load
|
|
/// - CodeBehind's local function then directly calls its ViewModel to do whatever it needs to do
|
|
|
|
public partial class MainWindow : WpfUiWindow, INavigationWindow
|
|
{
|
|
internal readonly MainWindowViewModel _viewModel = new();
|
|
|
|
private Type _currentPage = typeof(WelcomePage);
|
|
|
|
private List<Type> _pages = new() { typeof(WelcomePage), typeof(InstallPage), typeof(CompletionPage) };
|
|
|
|
private DateTimeOffset _lastNavigation = DateTimeOffset.Now;
|
|
|
|
public Func<bool>? NextPageCallback;
|
|
|
|
public NextAction CloseAction = NextAction.Terminate;
|
|
|
|
public bool Finished => _currentPage == _pages.Last();
|
|
|
|
public MainWindow()
|
|
{
|
|
_viewModel.CloseWindowRequest += (_, _) => CloseWindow();
|
|
|
|
_viewModel.PageRequest += (_, type) =>
|
|
{
|
|
// debounce
|
|
if (DateTimeOffset.Now.Subtract(_lastNavigation).TotalMilliseconds < 500)
|
|
return;
|
|
|
|
if (type == "next")
|
|
NextPage();
|
|
else if (type == "back")
|
|
BackPage();
|
|
|
|
_lastNavigation = DateTimeOffset.Now;
|
|
};
|
|
|
|
DataContext = _viewModel;
|
|
InitializeComponent();
|
|
|
|
App.Logger.WriteLine("MainWindow", "Initializing installer window");
|
|
|
|
Closing += new CancelEventHandler(MainWindow_Closing);
|
|
}
|
|
|
|
void NextPage()
|
|
{
|
|
if (NextPageCallback is not null && !NextPageCallback())
|
|
return;
|
|
|
|
if (_currentPage == _pages.Last())
|
|
return;
|
|
|
|
var page = _pages[_pages.IndexOf(_currentPage) + 1];
|
|
|
|
Navigate(page);
|
|
|
|
SetButtonEnabled("next", page != _pages.Last());
|
|
SetButtonEnabled("back", true);
|
|
}
|
|
|
|
void BackPage()
|
|
{
|
|
if (_currentPage == _pages.First())
|
|
return;
|
|
|
|
var page = _pages[_pages.IndexOf(_currentPage) - 1];
|
|
|
|
Navigate(page);
|
|
|
|
SetButtonEnabled("next", true);
|
|
SetButtonEnabled("back", page != _pages.First());
|
|
}
|
|
|
|
void MainWindow_Closing(object? sender, CancelEventArgs e)
|
|
{
|
|
if (Finished)
|
|
return;
|
|
|
|
var result = Frontend.ShowMessageBox(Strings.Installer_ShouldCancel, MessageBoxImage.Warning, MessageBoxButton.YesNo);
|
|
|
|
if (result != MessageBoxResult.Yes)
|
|
e.Cancel = true;
|
|
}
|
|
|
|
public void SetNextButtonText(string text) => _viewModel.SetNextButtonText(text);
|
|
|
|
public void SetButtonEnabled(string type, bool state) => _viewModel.SetButtonEnabled(type, state);
|
|
|
|
#region INavigationWindow methods
|
|
|
|
public Frame GetFrame() => RootFrame;
|
|
|
|
public INavigation GetNavigation() => RootNavigation;
|
|
|
|
public bool Navigate(Type pageType)
|
|
{
|
|
_currentPage = pageType;
|
|
NextPageCallback = null;
|
|
return RootNavigation.Navigate(pageType);
|
|
}
|
|
|
|
public void SetPageService(IPageService pageService) => RootNavigation.PageService = pageService;
|
|
|
|
public void ShowWindow() => Show();
|
|
|
|
public void CloseWindow() => Close();
|
|
|
|
#endregion INavigationWindow methods
|
|
}
|
|
}
|