diff --git a/FluentTerminal.App/App.xaml b/FluentTerminal.App/App.xaml
index 061c2b0..98d40d2 100644
--- a/FluentTerminal.App/App.xaml
+++ b/FluentTerminal.App/App.xaml
@@ -1,12 +1,23 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ xmlns:converters="using:FluentTerminal.App.Converters">
+
+
diff --git a/FluentTerminal.App/App.xaml.cs b/FluentTerminal.App/App.xaml.cs
index f826d0b..892d48e 100644
--- a/FluentTerminal.App/App.xaml.cs
+++ b/FluentTerminal.App/App.xaml.cs
@@ -3,8 +3,12 @@ using FluentTerminal.App.Services;
using FluentTerminal.App.Services.Implementation;
using FluentTerminal.App.ViewModels;
using FluentTerminal.App.Views;
+using FluentTerminal.Models;
+using FluentTerminal.Models.Enums;
using System;
+using System.Collections.Generic;
using System.ComponentModel;
+using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
@@ -26,11 +30,16 @@ namespace FluentTerminal.App
public static App Instance;
private bool _alreadyLaunched;
private IContainer _container;
- private int _openTerminalWindows;
private int? _settingsWindowId;
+ private readonly ISettingsService _settingsService;
+ private ApplicationSettings _applicationSettings;
+
+ private List _mainViewModels;
public App()
{
+ _mainViewModels = new List();
+
InitializeComponent();
Instance = this;
@@ -44,13 +53,21 @@ namespace FluentTerminal.App
builder.RegisterType().InstancePerDependency();
_container = builder.Build();
+
+ _settingsService = _container.Resolve();
+ _settingsService.ApplicationSettingsChanged += OnApplicationSettingsChanged;
+
+ _applicationSettings = _settingsService.GetApplicationSettings();
+ }
+
+ private void OnApplicationSettingsChanged(object sender, EventArgs e)
+ {
+ _applicationSettings = _settingsService.GetApplicationSettings();
}
public async Task CreateNewTerminalWindow(string startupDirectory)
{
- var viewModel = _container.Resolve();
- viewModel.AddTerminal(startupDirectory);
- var id = await CreateSecondaryView(typeof(MainPage), viewModel, true);
+ var id = await CreateSecondaryView(typeof(MainPage), true, startupDirectory);
await ApplicationViewSwitcher.TryShowAsStandaloneAsync(id);
}
@@ -63,15 +80,14 @@ namespace FluentTerminal.App
{
if (_settingsWindowId == null)
{
- var viewModel = _container.Resolve();
- _settingsWindowId = await CreateSecondaryView(typeof(SettingsPage), viewModel, true);
+ _settingsWindowId = await CreateSecondaryView(typeof(SettingsPage), true, null);
}
await ApplicationViewSwitcher.TryShowAsStandaloneAsync(_settingsWindowId.Value);
}
- public void TerminalWindowClosed()
+ public void TerminalWindowClosed(MainViewModel viewModel)
{
- _openTerminalWindows--;
+ _mainViewModels.Remove(viewModel);
}
protected override async void OnActivated(IActivatedEventArgs args)
@@ -95,7 +111,15 @@ namespace FluentTerminal.App
}
else if (command == "new")
{
- await CreateNewTerminalWindow(parameter);
+ if (_applicationSettings.NewTerminalLocation == NewTerminalLocation.Tab && _mainViewModels.Any())
+ {
+ await _mainViewModels.Last().AddTerminal(parameter);
+ }
+ else
+ {
+ await CreateNewTerminalWindow(parameter);
+ }
+
}
}
else
@@ -107,9 +131,16 @@ namespace FluentTerminal.App
}
else if (command == "new")
{
- var viewModel = _container.Resolve();
- viewModel.AddTerminal(parameter);
- await CreateMainView(typeof(MainPage), viewModel, true);
+ if (_applicationSettings.NewTerminalLocation == NewTerminalLocation.Tab && _mainViewModels.Any())
+ {
+ await _mainViewModels.Last().AddTerminal(parameter);
+ }
+ else
+ {
+ var viewModel = _container.Resolve();
+ await viewModel.AddTerminal(parameter);
+ await CreateMainView(typeof(MainPage), viewModel, true);
+ }
}
}
}
@@ -132,15 +163,13 @@ namespace FluentTerminal.App
if (!_alreadyLaunched)
{
var viewModel = _container.Resolve();
- viewModel.AddTerminal(null);
+ await viewModel.AddTerminal(null);
await CreateMainView(typeof(MainPage), viewModel, true);
Window.Current.Activate();
}
- else if (_openTerminalWindows == 0)
+ else if (_mainViewModels.Any() == false)
{
- var viewModel = _container.Resolve();
- viewModel.AddTerminal(null);
- await CreateSecondaryView(typeof(MainPage), viewModel, true);
+ await CreateSecondaryView(typeof(MainPage), true, string.Empty);
}
}
@@ -161,9 +190,9 @@ namespace FluentTerminal.App
{
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = extendViewIntoTitleBar;
- if (pageType == typeof(MainPage))
+ if (viewModel is MainViewModel mainViewModel)
{
- _openTerminalWindows++;
+ _mainViewModels.Add(mainViewModel);
}
rootFrame.Navigate(pageType, viewModel);
@@ -172,11 +201,14 @@ namespace FluentTerminal.App
Window.Current.Activate();
}
- private async Task CreateSecondaryView(Type pageType, INotifyPropertyChanged viewModel, bool ExtendViewIntoTitleBar)
+ private async Task CreateSecondaryView(Type pageType, bool ExtendViewIntoTitleBar, object parameter)
{
int windowId = 0;
+ TViewModel viewModel = default;
await CoreApplication.CreateNewView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
+ viewModel = _container.Resolve();
+
CoreApplication.GetCurrentView().TitleBar.ExtendViewIntoTitleBar = ExtendViewIntoTitleBar;
var frame = new Frame();
frame.Navigate(pageType, viewModel);
@@ -186,9 +218,10 @@ namespace FluentTerminal.App
windowId = ApplicationView.GetForCurrentView().Id;
});
- if (pageType == typeof(MainPage))
+ if (viewModel is MainViewModel mainViewModel && parameter is string directory)
{
- _openTerminalWindows++;
+ _mainViewModels.Add(mainViewModel);
+ await mainViewModel.AddTerminal(directory);
}
return windowId;
diff --git a/FluentTerminal.App/FluentTerminal.App.csproj b/FluentTerminal.App/FluentTerminal.App.csproj
index ea5612f..a2c7239 100644
--- a/FluentTerminal.App/FluentTerminal.App.csproj
+++ b/FluentTerminal.App/FluentTerminal.App.csproj
@@ -79,6 +79,7 @@
false
prompt
true
+ 7.1
bin\x64\Release\
@@ -122,6 +123,7 @@
+
diff --git a/FluentTerminal.App/Services/Implementation/DefaultValueProvider.cs b/FluentTerminal.App/Services/Implementation/DefaultValueProvider.cs
index 4c23cf5..d9b1b57 100644
--- a/FluentTerminal.App/Services/Implementation/DefaultValueProvider.cs
+++ b/FluentTerminal.App/Services/Implementation/DefaultValueProvider.cs
@@ -13,7 +13,8 @@ namespace FluentTerminal.App.Services.Implementation
return new ApplicationSettings
{
ConfirmClosingTabs = false,
- ConfirmClosingWindows = false
+ ConfirmClosingWindows = false,
+ NewTerminalLocation = NewTerminalLocation.Tab
};
}
diff --git a/FluentTerminal.App/ViewModels/MainViewModel.cs b/FluentTerminal.App/ViewModels/MainViewModel.cs
index 2165bda..a48bd4b 100644
--- a/FluentTerminal.App/ViewModels/MainViewModel.cs
+++ b/FluentTerminal.App/ViewModels/MainViewModel.cs
@@ -25,6 +25,7 @@ namespace FluentTerminal.App.ViewModels
private CoreDispatcher _dispatcher;
private int _nextTerminalId;
private TerminalViewModel _selectedTerminal;
+ private string _title;
public MainViewModel(ISettingsService settingsService, ITrayProcessCommunicationService trayProcessCommunicationService, IDialogService dialogService, IKeyboardCommandService keyboardCommandService)
{
@@ -48,6 +49,10 @@ namespace FluentTerminal.App.ViewModels
AddTerminalCommand = new RelayCommand(() => AddTerminal(null));
ShowSettingsCommand = new RelayCommand(async () => await ShowSettings());
+ Terminals.CollectionChanged += OnTerminalsCollectionChanged;
+
+ Title = "Fluent Terminal";
+
_dispatcher = CoreApplication.GetCurrentView().Dispatcher;
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += OnCloseRequest;
}
@@ -82,13 +87,23 @@ namespace FluentTerminal.App.ViewModels
public ObservableCollection Terminals { get; } = new ObservableCollection();
- public void AddTerminal(string startupDirectory)
+ public string Title
{
- var terminal = new TerminalViewModel(GetNextTerminalId(), _settingsService, _trayProcessCommunicationService, _dialogService, _keyboardCommandService, _applicationSettings, startupDirectory);
- terminal.CloseRequested += OnTerminalCloseRequested;
- Terminals.Add(terminal);
+ get => _title;
+ set => Set(ref _title, value);
+ }
- SelectedTerminal = terminal;
+ public Task AddTerminal(string startupDirectory)
+ {
+ return _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
+ {
+ var terminal = new TerminalViewModel(GetNextTerminalId(), _settingsService, _trayProcessCommunicationService, _dialogService, _keyboardCommandService, _applicationSettings, startupDirectory);
+ terminal.CloseRequested += OnTerminalCloseRequested;
+ terminal.TitleChanged += OnTitleChanged;
+ Terminals.Add(terminal);
+
+ SelectedTerminal = terminal;
+ }).AsTask();
}
public void CloseAllTerminals()
@@ -111,7 +126,7 @@ namespace FluentTerminal.App.ViewModels
private Task NewWindow()
{
- return App.Instance.CreateNewTerminalWindow(null);
+ return App.Instance.CreateNewTerminalWindow(string.Empty);
}
private async void OnApplicationSettingsChanged(object sender, EventArgs e)
@@ -133,7 +148,7 @@ namespace FluentTerminal.App.ViewModels
if (result == DialogButton.OK)
{
CloseAllTerminals();
- App.Instance.TerminalWindowClosed();
+ App.Instance.TerminalWindowClosed(this);
}
else
{
@@ -143,7 +158,7 @@ namespace FluentTerminal.App.ViewModels
else
{
CloseAllTerminals();
- App.Instance.TerminalWindowClosed();
+ App.Instance.TerminalWindowClosed(this);
}
deferral.Complete();
}
@@ -176,6 +191,22 @@ namespace FluentTerminal.App.ViewModels
}
}
+ private void OnTerminalsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
+ {
+ if (Terminals.Any())
+ {
+ Title = Terminals.First().Title;
+ }
+ }
+
+ private void OnTitleChanged(object sender, string e)
+ {
+ if (sender is TerminalViewModel terminal && Terminals.First() == terminal)
+ {
+ Title = e;
+ }
+ }
+
private void SelectNextTab()
{
var currentIndex = Terminals.IndexOf(SelectedTerminal);
diff --git a/FluentTerminal.App/ViewModels/Settings/GeneralPageViewModel.cs b/FluentTerminal.App/ViewModels/Settings/GeneralPageViewModel.cs
new file mode 100644
index 0000000..17a13cd
--- /dev/null
+++ b/FluentTerminal.App/ViewModels/Settings/GeneralPageViewModel.cs
@@ -0,0 +1,101 @@
+using FluentTerminal.App.Services;
+using FluentTerminal.Models;
+using FluentTerminal.Models.Enums;
+using GalaSoft.MvvmLight;
+using GalaSoft.MvvmLight.Command;
+using System.Threading.Tasks;
+
+namespace FluentTerminal.App.ViewModels.Settings
+{
+ public class GeneralPageViewModel : ViewModelBase
+ {
+ private readonly IDefaultValueProvider _defaultValueProvider;
+ private readonly IDialogService _dialogService;
+ private readonly ISettingsService _settingsService;
+ private ApplicationSettings _applicationSettings;
+ private bool _editingNewTerminalLocation;
+
+ public GeneralPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider)
+ {
+ _settingsService = settingsService;
+ _dialogService = dialogService;
+ _defaultValueProvider = defaultValueProvider;
+ _applicationSettings = _settingsService.GetApplicationSettings();
+
+ RestoreDefaultsCommand = new RelayCommand(async () => await RestoreDefaults());
+ }
+
+ public bool ConfirmClosingTabs
+ {
+ get => _applicationSettings.ConfirmClosingTabs;
+ set
+ {
+ if (_applicationSettings.ConfirmClosingTabs != value)
+ {
+ _applicationSettings.ConfirmClosingTabs = value;
+ _settingsService.SaveApplicationSettings(_applicationSettings);
+ RaisePropertyChanged();
+ }
+ }
+ }
+
+ public bool ConfirmClosingWindows
+ {
+ get => _applicationSettings.ConfirmClosingWindows;
+ set
+ {
+ if (_applicationSettings.ConfirmClosingWindows != value)
+ {
+ _applicationSettings.ConfirmClosingWindows = value;
+ _settingsService.SaveApplicationSettings(_applicationSettings);
+ RaisePropertyChanged();
+ }
+ }
+ }
+
+ public NewTerminalLocation NewTerminalLocation
+ {
+ get => _applicationSettings.NewTerminalLocation;
+ set
+ {
+ if (_applicationSettings.NewTerminalLocation != value && !_editingNewTerminalLocation)
+ {
+ _editingNewTerminalLocation = true;
+ _applicationSettings.NewTerminalLocation = value;
+ _settingsService.SaveApplicationSettings(_applicationSettings);
+ RaisePropertyChanged();
+ RaisePropertyChanged(nameof(WindowIsSelected));
+ RaisePropertyChanged(nameof(TabIsSelected));
+ _editingNewTerminalLocation = false;
+ }
+ }
+ }
+
+ public RelayCommand RestoreDefaultsCommand { get; }
+
+ public bool TabIsSelected
+ {
+ get => NewTerminalLocation == NewTerminalLocation.Tab;
+ set => NewTerminalLocation = NewTerminalLocation.Tab;
+ }
+
+ public bool WindowIsSelected
+ {
+ get => NewTerminalLocation == NewTerminalLocation.Window;
+ set => NewTerminalLocation = NewTerminalLocation.Window;
+ }
+
+ private async Task RestoreDefaults()
+ {
+ var result = await _dialogService.ShowDialogAsnyc("Please confirm", "Are you sure you want to restore the general settings?", DialogButton.OK, DialogButton.Cancel);
+
+ if (result == DialogButton.OK)
+ {
+ var defaults = _defaultValueProvider.GetDefaultApplicationSettings();
+ ConfirmClosingWindows = defaults.ConfirmClosingWindows;
+ ConfirmClosingTabs = defaults.ConfirmClosingTabs;
+ NewTerminalLocation = defaults.NewTerminalLocation;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/FluentTerminal.App/ViewModels/SettingsViewModel.cs b/FluentTerminal.App/ViewModels/SettingsViewModel.cs
index 976e585..73531d6 100644
--- a/FluentTerminal.App/ViewModels/SettingsViewModel.cs
+++ b/FluentTerminal.App/ViewModels/SettingsViewModel.cs
@@ -20,12 +20,12 @@ namespace FluentTerminal.App.ViewModels
private readonly IDialogService _dialogService;
private readonly ITrayProcessCommunicationService _trayProcessCommunicationService;
private readonly ISettingsService _settingsService;
- private ApplicationSettings _applicationSettings;
private ThemeViewModel _selectedTheme;
private ShellConfiguration _shellConfiguration;
private TerminalOptions _terminalOptions;
public KeyBindingsPageViewModel KeyBindings { get; }
+ public GeneralPageViewModel General { get; }
public SettingsViewModel(ISettingsService settingsService, IDefaultValueProvider defaultValueProvider, IDialogService dialogService, ITrayProcessCommunicationService trayProcessCommunicationService)
{
@@ -40,10 +40,10 @@ namespace FluentTerminal.App.ViewModels
_shellConfiguration = _settingsService.GetShellConfiguration();
_terminalOptions = _settingsService.GetTerminalOptions();
- _applicationSettings = _settingsService.GetApplicationSettings();
ShellType = _shellConfiguration.Shell;
KeyBindings = new KeyBindingsPageViewModel(_settingsService, dialogService, _defaultValueProvider, _trayProcessCommunicationService);
+ General = new GeneralPageViewModel(_settingsService, dialogService, _defaultValueProvider);
var activeThemeId = _settingsService.GetCurrentThemeId();
foreach (var theme in _settingsService.GetThemes())
@@ -102,34 +102,6 @@ namespace FluentTerminal.App.ViewModels
set => ShellType = ShellType.CMD;
}
- public bool ConfirmClosingTabs
- {
- get => _applicationSettings.ConfirmClosingTabs;
- set
- {
- if (_applicationSettings.ConfirmClosingTabs != value)
- {
- _applicationSettings.ConfirmClosingTabs = value;
- _settingsService.SaveApplicationSettings(_applicationSettings);
- RaisePropertyChanged();
- }
- }
- }
-
- public bool ConfirmClosingWindows
- {
- get => _applicationSettings.ConfirmClosingWindows;
- set
- {
- if (_applicationSettings.ConfirmClosingWindows != value)
- {
- _applicationSettings.ConfirmClosingWindows = value;
- _settingsService.SaveApplicationSettings(_applicationSettings);
- RaisePropertyChanged();
- }
- }
- }
-
public RelayCommand CreateThemeCommand { get; set; }
public bool CursorBlink
@@ -367,12 +339,6 @@ namespace FluentTerminal.App.ViewModels
FontFamily = defaults.FontFamily;
FontSize = defaults.FontSize;
}
- else if (result == DialogButton.OK && area == "general")
- {
- var defaults = _defaultValueProvider.GetDefaultApplicationSettings();
- ConfirmClosingWindows = defaults.ConfirmClosingWindows;
- ConfirmClosingTabs = defaults.ConfirmClosingTabs;
- }
}
}
}
\ No newline at end of file
diff --git a/FluentTerminal.App/Views/MainPage.xaml b/FluentTerminal.App/Views/MainPage.xaml
index d327754..4b224b2 100644
--- a/FluentTerminal.App/Views/MainPage.xaml
+++ b/FluentTerminal.App/Views/MainPage.xaml
@@ -13,16 +13,6 @@
mc:Ignorable="d">
-
-
@@ -51,7 +41,7 @@
Grid.Column="0"
IsHitTestVisible="False"
Style="{StaticResource WindowTitleTextBlockStyle}"
- Text="{x:Bind ViewModel.Terminals[0].Title, Mode=OneWay}"
+ Text="{x:Bind ViewModel.Title, Mode=OneWay}"
Visibility="{x:Bind ViewModel.Terminals.Count, Mode=OneWay, Converter={StaticResource OneToVisibleConverter}}" />
@@ -30,14 +29,18 @@
Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
DefaultLabelPosition="Right">
-
+
+
+