diff --git a/source/Cosmos.Build.Builder/App.xaml.cs b/source/Cosmos.Build.Builder/App.xaml.cs index b462abceb..23f598b75 100644 --- a/source/Cosmos.Build.Builder/App.xaml.cs +++ b/source/Cosmos.Build.Builder/App.xaml.cs @@ -13,8 +13,9 @@ namespace Cosmos.Build.Builder { if (e.Args.Length == 0) { - MessageBox.Show("Builder not meant to be called directly. Use install-VS2017.bat instead."); + ShowErrorMessageBox("Builder not meant to be called directly. Use install-VS2017.bat instead."); Shutdown(); + return; } var configuration = new CommandLineBuilderConfiguration(e.Args); @@ -31,13 +32,17 @@ namespace Cosmos.Build.Builder // For debugging, set params to something like this: // -VSPath=C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise - MessageBox.Show("Visual Studio path must be provided. (-VSPATH or /VSPATH)"); + ShowErrorMessageBox("Visual Studio path must be provided. (-VSPATH or /VSPATH)"); Shutdown(); + return; } BuilderConfiguration = configuration; base.OnStartup(e); } + + private void ShowErrorMessageBox(string message) => + MessageBox.Show(message, "Cosmos Kit Builder", MessageBoxButton.OK, MessageBoxImage.Error); } } diff --git a/source/Cosmos.Build.Builder/ViewModels/MainWindowLogger.cs b/source/Cosmos.Build.Builder/ViewModels/MainWindowLogger.cs index 2340f23a7..6128130e7 100644 --- a/source/Cosmos.Build.Builder/ViewModels/MainWindowLogger.cs +++ b/source/Cosmos.Build.Builder/ViewModels/MainWindowLogger.cs @@ -1,9 +1,14 @@ -using Cosmos.Build.Builder.Models; +using System; +using System.Windows; + +using Cosmos.Build.Builder.Models; namespace Cosmos.Build.Builder.ViewModels { internal class MainWindowLogger : ILogger { + private static readonly string[] NewLineStringArray = new string[] { Environment.NewLine }; + private readonly MainWindowViewModel _viewModel; public MainWindowLogger(MainWindowViewModel viewModel) @@ -11,21 +16,29 @@ namespace Cosmos.Build.Builder.ViewModels _viewModel = viewModel; } - public void LogMessage(string text) - { - _viewModel.CurrentSection.LogMessage(text); - _viewModel.TailItems.Push(text); - } + public void LogMessage(string text) => Application.Current.Dispatcher.Invoke( + () => + { + _viewModel.CurrentSection.LogMessage(text); - public void NewSection(string name) - { - _viewModel.Sections.Add(new Section(name)); - _viewModel.TailItems.Clear(); - } + foreach (var line in text.Split(NewLineStringArray, StringSplitOptions.None)) + { + _viewModel.TailItems.Push(line); + } + }); - public void SetError() - { - _viewModel.CurrentSection.SetError(); - } + public void NewSection(string name) => Application.Current.Dispatcher.Invoke( + () => + { + _viewModel.Sections.Add(new Section(name)); + _viewModel.TailItems.Clear(); + }); + + public void SetError() => Application.Current.Dispatcher.Invoke( + () => + { + _viewModel.CurrentSection.SetError(); + _viewModel.CloseWhenCompleted = false; + }); } } diff --git a/source/Cosmos.Build.Builder/ViewModels/MainWindowViewModel.cs b/source/Cosmos.Build.Builder/ViewModels/MainWindowViewModel.cs index c00fbf88b..0a5b8109e 100644 --- a/source/Cosmos.Build.Builder/ViewModels/MainWindowViewModel.cs +++ b/source/Cosmos.Build.Builder/ViewModels/MainWindowViewModel.cs @@ -1,16 +1,19 @@ using System; using System.Collections.ObjectModel; +using System.IO; using System.Linq; +using System.Threading.Tasks; using System.Windows; using System.Windows.Input; - using Cosmos.Build.Builder.Collections; using Cosmos.Build.Builder.Models; namespace Cosmos.Build.Builder.ViewModels { - internal class MainWindowViewModel + internal class MainWindowViewModel : ViewModelBase { + private const int ReleaseNumber = 106027; + private const int TailItemCount = 10; public ObservableFixedSizeStack TailItems { get; } @@ -20,19 +23,38 @@ namespace Cosmos.Build.Builder.ViewModels public ICommand CopyCommand { get; } - private ILogger _logger; + public bool CloseWhenCompleted + { + get => _closeWhenCompleted; + set => SetAndRaiseIfChanged(ref _closeWhenCompleted, value); + } + + private CosmosTask _cosmosTask; + private Task _cosmosTaskTask; + + private bool _closeWhenCompleted; public MainWindowViewModel() { TailItems = new ObservableFixedSizeStack(TailItemCount); Sections = new ObservableCollection
(); - CopyCommand = new CopyLogCommand(this); + CopyCommand = new RelayCommand(CopyLogToClipboard); - _logger = new MainWindowLogger(this); + var logger = new MainWindowLogger(this); + + _closeWhenCompleted = true; + + var cosmosDir = Directory.GetCurrentDirectory(); + + _cosmosTask = new CosmosTask(logger, cosmosDir, ReleaseNumber); + _cosmosTaskTask = Task.Run((Action)_cosmosTask.Run); + _cosmosTaskTask.ContinueWith(CosmosTaskFinishedAsync); } - public string BuildLog() + private void CopyLogToClipboard(object parameter) => Clipboard.SetText(BuildLog()); + + private string BuildLog() { var log = @" ======================================== @@ -55,23 +77,25 @@ namespace Cosmos.Build.Builder.ViewModels return log; } - private class CopyLogCommand : ICommand - { - public event EventHandler CanExecuteChanged; + private Task CosmosTaskFinishedAsync(Task task) => + Application.Current.Dispatcher.InvokeAsync( + async () => + { + var mainWindow = Application.Current.MainWindow; - private MainWindowViewModel _viewModel; - private Func _canExecute; + await Task.Delay(5000); - public CopyLogCommand(MainWindowViewModel viewModel, Func canExecute = null) - { - _viewModel = viewModel; - _canExecute = canExecute; - } - - public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true; - public void Execute(object parameter) => Clipboard.SetText(_viewModel.BuildLog()); - - public void RaiseCanExecuteChanged(object sender, EventArgs e) => CanExecuteChanged?.Invoke(sender, e); - } + if (CloseWhenCompleted) + { + mainWindow.Close(); + } + else + { + if (mainWindow.WindowState == WindowState.Maximized) + { + mainWindow.WindowState = WindowState.Normal; + } + } + }).Task; } } diff --git a/source/Cosmos.Build.Builder/ViewModels/RelayCommand.cs b/source/Cosmos.Build.Builder/ViewModels/RelayCommand.cs new file mode 100644 index 000000000..772de528a --- /dev/null +++ b/source/Cosmos.Build.Builder/ViewModels/RelayCommand.cs @@ -0,0 +1,24 @@ +using System; +using System.Windows.Input; + +namespace Cosmos.Build.Builder.ViewModels +{ + internal class RelayCommand : ICommand + { + public event EventHandler CanExecuteChanged; + + private Action _execute; + private Func _canExecute; + + public RelayCommand(Action execute, Func canExecute = null) + { + _execute = execute; + _canExecute = canExecute; + } + + public bool CanExecute(object parameter) => _canExecute?.Invoke(parameter) ?? true; + public void Execute(object parameter) => _execute?.Invoke(parameter); + + public void RaiseCanExecuteChanged(object sender, EventArgs e) => CanExecuteChanged?.Invoke(sender, e); + } +} diff --git a/source/Cosmos.Build.Builder/ViewModels/ViewModelBase.cs b/source/Cosmos.Build.Builder/ViewModels/ViewModelBase.cs new file mode 100644 index 000000000..ba4d5856c --- /dev/null +++ b/source/Cosmos.Build.Builder/ViewModels/ViewModelBase.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; +using System.ComponentModel; +using System.Runtime.CompilerServices; + +namespace Cosmos.Build.Builder.ViewModels +{ + internal abstract class ViewModelBase : INotifyPropertyChanged + { + public event PropertyChangedEventHandler PropertyChanged; + + protected void SetAndRaiseIfChanged(ref T field, T value, [CallerMemberName] string propertyName = null) + { + if (!EqualityComparer.Default.Equals(field, value)) + { + field = value; + OnPropertyChanged(propertyName); + } + } + + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) => + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } +} diff --git a/source/Cosmos.Build.Builder/Views/MainWindow.xaml b/source/Cosmos.Build.Builder/Views/MainWindow.xaml index 81a31af49..cc7dc85df 100644 --- a/source/Cosmos.Build.Builder/Views/MainWindow.xaml +++ b/source/Cosmos.Build.Builder/Views/MainWindow.xaml @@ -5,10 +5,8 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Icon="/Cosmos.Build.Builder;component/Resources/Cosmos.ico" - Loaded="Window_Loaded" MinHeight="480" MinWidth="800" - SizeChanged="Window_SizeChanged" Title="Cosmos Kit Builder" WindowStartupLocation="CenterScreen" DataContext="{StaticResource MainWindowViewModel}"> @@ -18,10 +16,21 @@ - -