Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01815db1fe | ||
|
|
80cf43d3bf | ||
|
|
050f162c08 | ||
|
|
f5e03c9856 | ||
|
|
f763798683 | ||
|
|
46120e3431 | ||
|
|
829077883b | ||
|
|
8c928faa09 | ||
|
|
1654e9f1f5 | ||
|
|
f542331192 |
No files matched your search
+1
-2
@@ -1,6 +1,6 @@
|
||||
# Project specific
|
||||
FluentTerminal.App/Win32
|
||||
FluentTerminal.SystemTray/Client
|
||||
FluentTerminal.App/Client/
|
||||
FluentTerminal.Client/dist
|
||||
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
@@ -291,4 +291,3 @@ __pycache__/
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
FluentTerminal.Client/dist/bundle.js
|
||||
@@ -1,12 +1,32 @@
|
||||
<Application
|
||||
x:Class="FluentTerminal.App.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:converters="using:FluentTerminal.App.Converters">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Styles\Custom.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<converters:IntToVisibilityConverter
|
||||
x:Key="OneToVisibleConverter"
|
||||
Else="Collapsed"
|
||||
If="1"
|
||||
Then="Visible" />
|
||||
<converters:IntToVisibilityConverter
|
||||
x:Key="OneToCollapsedConverter"
|
||||
Else="Visible"
|
||||
If="1"
|
||||
Then="Collapsed" />
|
||||
<converters:NegateConverter x:Key="NegateConverter" />
|
||||
<converters:FalseToVisibleConverter x:Key="FalseToVisibleConverter" />
|
||||
<converters:TrueToVisibleConverter x:Key="TrueToVisibleConverter" />
|
||||
<converters:IntToVisibilityConverter
|
||||
x:Key="ZeroToCollapsedConverter"
|
||||
Else="Visible"
|
||||
If="0"
|
||||
Then="Collapsed" />
|
||||
<converters:IntToExtendedVirtualKeyConverter x:Key="IntToExtendedVirtualKeyConverter" />
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -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,31 +30,44 @@ 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<MainViewModel> _mainViewModels;
|
||||
|
||||
public App()
|
||||
{
|
||||
_mainViewModels = new List<MainViewModel>();
|
||||
|
||||
InitializeComponent();
|
||||
Instance = this;
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<SettingsService>().As<ISettingsService>().SingleInstance();
|
||||
builder.RegisterType<DefaultValueProvider>().As<IDefaultValueProvider>().SingleInstance();
|
||||
builder.RegisterType<TerminalService>().As<ITerminalService>().SingleInstance();
|
||||
builder.RegisterType<TrayProcessCommunicationService>().As<ITrayProcessCommunicationService>().SingleInstance();
|
||||
builder.RegisterType<DialogService>().As<IDialogService>().SingleInstance();
|
||||
builder.RegisterType<KeyboardCommandService>().As<IKeyboardCommandService>().InstancePerDependency();
|
||||
builder.RegisterType<MainViewModel>().InstancePerDependency();
|
||||
builder.RegisterType<SettingsViewModel>().InstancePerDependency();
|
||||
|
||||
_container = builder.Build();
|
||||
|
||||
_settingsService = _container.Resolve<ISettingsService>();
|
||||
_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<MainViewModel>();
|
||||
viewModel.AddTerminal(startupDirectory);
|
||||
var id = await CreateSecondaryView(typeof(MainPage), viewModel, true);
|
||||
var id = await CreateSecondaryView<MainViewModel>(typeof(MainPage), true, startupDirectory);
|
||||
await ApplicationViewSwitcher.TryShowAsStandaloneAsync(id);
|
||||
}
|
||||
|
||||
@@ -63,15 +80,14 @@ namespace FluentTerminal.App
|
||||
{
|
||||
if (_settingsWindowId == null)
|
||||
{
|
||||
var viewModel = _container.Resolve<SettingsViewModel>();
|
||||
_settingsWindowId = await CreateSecondaryView(typeof(SettingsPage), viewModel, true);
|
||||
_settingsWindowId = await CreateSecondaryView<SettingsViewModel>(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<MainViewModel>();
|
||||
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<MainViewModel>();
|
||||
await viewModel.AddTerminal(parameter);
|
||||
await CreateMainView(typeof(MainPage), viewModel, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,15 +163,13 @@ namespace FluentTerminal.App
|
||||
if (!_alreadyLaunched)
|
||||
{
|
||||
var viewModel = _container.Resolve<MainViewModel>();
|
||||
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<MainViewModel>();
|
||||
viewModel.AddTerminal(null);
|
||||
await CreateSecondaryView(typeof(MainPage), viewModel, true);
|
||||
await CreateSecondaryView<MainViewModel>(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<int> CreateSecondaryView(Type pageType, INotifyPropertyChanged viewModel, bool ExtendViewIntoTitleBar)
|
||||
private async Task<int> CreateSecondaryView<TViewModel>(Type pageType, bool ExtendViewIntoTitleBar, object parameter)
|
||||
{
|
||||
int windowId = 0;
|
||||
TViewModel viewModel = default;
|
||||
await CoreApplication.CreateNewView().Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
|
||||
{
|
||||
viewModel = _container.Resolve<TViewModel>();
|
||||
|
||||
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;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using FluentTerminal.Models.Enums;
|
||||
using System;
|
||||
using Windows.UI.Xaml.Data;
|
||||
|
||||
namespace FluentTerminal.App.Converters
|
||||
{
|
||||
public class IntToExtendedVirtualKeyConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is int intValue)
|
||||
{
|
||||
return ((ExtendedVirtualKey)intValue).ToString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
<LangVersion>7.1</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -79,6 +80,7 @@
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<LangVersion>7.1</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
@@ -91,6 +93,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
<LangVersion>7.1</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
@@ -101,6 +104,7 @@
|
||||
</Compile>
|
||||
<Compile Include="Behaviors\MiddleClickBehavior.cs" />
|
||||
<Compile Include="Converters\FalseToVisibleConverter.cs" />
|
||||
<Compile Include="Converters\IntToExtendedVirtualKeyConverter.cs" />
|
||||
<Compile Include="Converters\IntToVisibilityConverter.cs" />
|
||||
<Compile Include="Converters\NegateConverter.cs" />
|
||||
<Compile Include="Converters\TerminalViewModelToViewConverter.cs" />
|
||||
@@ -113,22 +117,35 @@
|
||||
<Compile Include="Services\IDefaultValueProvider.cs" />
|
||||
<Compile Include="Services\Implementation\DefaultValueProvider.cs" />
|
||||
<Compile Include="Services\Implementation\SettingsService.cs" />
|
||||
<Compile Include="Services\Implementation\TerminalService.cs" />
|
||||
<Compile Include="Services\Implementation\TrayProcessCommunicationService.cs" />
|
||||
<Compile Include="Services\ISettingsService.cs" />
|
||||
<Compile Include="Services\ITerminalService.cs" />
|
||||
<Compile Include="Services\ITrayProcessCommunicationService.cs" />
|
||||
<Compile Include="Utilities\ColorExtensions.cs" />
|
||||
<Compile Include="Utilities\HttpJsonContent.cs" />
|
||||
<Compile Include="Utilities\IHttpContentExtensions.cs" />
|
||||
<Compile Include="ViewModels\MainViewModel.cs" />
|
||||
<Compile Include="ViewModels\SettingsViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\GeneralPageViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\KeyBindingsPageViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\KeyBindingsViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\KeyBindingViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\ShellPageViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\TerminalPageViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\ThemesPageViewModel.cs" />
|
||||
<Compile Include="ViewModels\ThemeViewModel.cs" />
|
||||
<Compile Include="ViewModels\TerminalViewModel.cs" />
|
||||
<Compile Include="Views\BindableColorsTitleBar.cs" />
|
||||
<Compile Include="Views\ITerminalView.cs" />
|
||||
<Compile Include="Views\KeyBindingsView.xaml.cs">
|
||||
<DependentUpon>KeyBindingsView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\MainPage.xaml.cs">
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Views\CreateKeyBindingDialog.xaml.cs">
|
||||
<DependentUpon>CreateKeyBindingDialog.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\SettingsPage.xaml.cs">
|
||||
<DependentUpon>SettingsPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -159,75 +176,17 @@
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
<Content Include="Assets\settingsicons.ttf" />
|
||||
<None Include="FluentTerminal.App_StoreKey.pfx" />
|
||||
<None Include="FluentTerminal.App_TemporaryKey.pfx" />
|
||||
<Content Include="Win32\FluentTerminal.Models.dll" />
|
||||
<Content Include="Win32\FluentTerminal.Models.pdb" />
|
||||
<Content Include="Win32\FluentTerminal.SystemTray.exe.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\AppIcons\LargeTile.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\LargeTile.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\LargeTile.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\LargeTile.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\LargeTile.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\SmallTile.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\SmallTile.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\SmallTile.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\SmallTile.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\SmallTile.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\SplashScreen.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\SplashScreen.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\SplashScreen.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\SplashScreen.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\SplashScreen.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\Square150x150Logo.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\Square150x150Logo.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\Square150x150Logo.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\Square150x150Logo.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.altform-unplated_targetsize-16.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.altform-unplated_targetsize-24.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.altform-unplated_targetsize-256.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.altform-unplated_targetsize-32.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.altform-unplated_targetsize-48.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.targetsize-16.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.targetsize-24.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.targetsize-256.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.targetsize-32.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.targetsize-48.png" />
|
||||
<Content Include="Assets\AppIcons\StoreLogo.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\StoreLogo.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\StoreLogo.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\StoreLogo.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\StoreLogo.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\Wide310x150Logo.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\Wide310x150Logo.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\Wide310x150Logo.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\Wide310x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\Wide310x150Logo.scale-400.png" />
|
||||
<None Include="Package.StoreAssociation.xml" />
|
||||
<Content Include="Properties\Default.rd.xml" />
|
||||
<Content Include="Win32\Client\bundle.js" />
|
||||
<Content Include="Win32\Client\index.html" />
|
||||
<Content Include="Win32\Client\style.css" />
|
||||
<Content Include="Win32\Client\xterm.css" />
|
||||
<Content Include="Win32\CommonServiceLocator.dll" />
|
||||
<Content Include="Win32\CommonServiceLocator.pdb" />
|
||||
<Content Include="Win32\Fleck.dll" />
|
||||
<Content Include="Win32\FluentTerminal.Models.dll" />
|
||||
<Content Include="Win32\FluentTerminal.Models.pdb" />
|
||||
<Content Include="Win32\FluentTerminal.SystemTray.exe" />
|
||||
<Content Include="Win32\FluentTerminal.SystemTray.pdb" />
|
||||
<Content Include="Win32\GlobalHotKey.dll" />
|
||||
<Content Include="Win32\Microsoft.Owin.dll" />
|
||||
<Content Include="Win32\Microsoft.Owin.FileSystems.dll" />
|
||||
<Content Include="Win32\Microsoft.Owin.Host.HttpListener.dll" />
|
||||
<Content Include="Win32\Microsoft.Owin.Hosting.dll" />
|
||||
<Content Include="Win32\Microsoft.Owin.StaticFiles.dll" />
|
||||
<Content Include="Win32\Microsoft.Win32.Primitives.dll" />
|
||||
<Content Include="Win32\netstandard.dll" />
|
||||
<Content Include="Win32\Newtonsoft.Json.dll" />
|
||||
@@ -348,12 +307,72 @@
|
||||
<Content Include="Win32\winpty-debugserver.exe" />
|
||||
<Content Include="Win32\winpty.dll" />
|
||||
<Content Include="Win32\winpty.NET.dll" />
|
||||
<None Include="FluentTerminal.App_StoreKey.pfx" />
|
||||
<None Include="FluentTerminal.App_TemporaryKey.pfx" />
|
||||
<Content Include="Client\bundle.js" />
|
||||
<Content Include="Client\index.html" />
|
||||
<Content Include="Client\style.css" />
|
||||
<Content Include="Client\xterm.css" />
|
||||
<Content Include="Win32\FluentTerminal.SystemTray.exe.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\AppIcons\LargeTile.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\LargeTile.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\LargeTile.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\LargeTile.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\LargeTile.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\SmallTile.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\SmallTile.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\SmallTile.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\SmallTile.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\SmallTile.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\SplashScreen.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\SplashScreen.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\SplashScreen.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\SplashScreen.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\SplashScreen.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\Square150x150Logo.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\Square150x150Logo.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\Square150x150Logo.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\Square150x150Logo.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.altform-unplated_targetsize-16.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.altform-unplated_targetsize-24.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.altform-unplated_targetsize-256.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.altform-unplated_targetsize-32.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.altform-unplated_targetsize-48.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.targetsize-16.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.targetsize-24.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.targetsize-256.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.targetsize-32.png" />
|
||||
<Content Include="Assets\AppIcons\Square44x44Logo.targetsize-48.png" />
|
||||
<Content Include="Assets\AppIcons\StoreLogo.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\StoreLogo.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\StoreLogo.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\StoreLogo.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\StoreLogo.scale-400.png" />
|
||||
<Content Include="Assets\AppIcons\Wide310x150Logo.scale-100.png" />
|
||||
<Content Include="Assets\AppIcons\Wide310x150Logo.scale-125.png" />
|
||||
<Content Include="Assets\AppIcons\Wide310x150Logo.scale-150.png" />
|
||||
<Content Include="Assets\AppIcons\Wide310x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\AppIcons\Wide310x150Logo.scale-400.png" />
|
||||
<None Include="Package.StoreAssociation.xml" />
|
||||
<Content Include="Properties\Default.rd.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="App.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Page Include="Views\KeyBindingsView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\MainPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
@@ -363,6 +382,10 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Page>
|
||||
<Page Include="Views\CreateKeyBindingDialog.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\SettingsPage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@@ -437,6 +460,7 @@
|
||||
<Name>FluentTerminal.RuntimeComponent</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
@@ -445,6 +469,9 @@
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>xcopy /y "$(SolutionDir)FluentTerminal.Client\dist" "$(ProjectDir)Client"</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:uap5="http://schemas.microsoft.com/appx/manifest/uap/windows10/5" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" IgnorableNamespaces="uap mp desktop rescap">
|
||||
<Identity Name="53621FSApps.FluentTerminal" Publisher="CN=BDC72197-B634-438A-B863-16DCB7D90C85" Version="0.1.6.0" />
|
||||
<Identity Name="53621FSApps.FluentTerminal" Publisher="CN=BDC72197-B634-438A-B863-16DCB7D90C85" Version="0.1.7.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="f7225014-f405-4342-ad2e-ebf6ac60ea2c" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>Fluent Terminal</DisplayName>
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace FluentTerminal.App.Services
|
||||
{
|
||||
ShellConfiguration GetDefaultShellConfiguration();
|
||||
TerminalOptions GetDefaultTerminalOptions();
|
||||
IEnumerable<KeyBinding> GetDefaultKeyBindings();
|
||||
KeyBindings GetDefaultKeyBindings();
|
||||
ApplicationSettings GetDefaultApplicationSettings();
|
||||
Guid GetDefaultThemeId();
|
||||
IEnumerable<TerminalTheme> GetPreInstalledThemes();
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace FluentTerminal.App.Services
|
||||
event EventHandler CurrentThemeChanged;
|
||||
event EventHandler TerminalOptionsChanged;
|
||||
event EventHandler ApplicationSettingsChanged;
|
||||
event EventHandler KeyBindingsChanged;
|
||||
|
||||
ShellConfiguration GetShellConfiguration();
|
||||
void SaveShellConfiguration(ShellConfiguration shellConfiguration);
|
||||
@@ -19,7 +20,8 @@ namespace FluentTerminal.App.Services
|
||||
ApplicationSettings GetApplicationSettings();
|
||||
void SaveApplicationSettings(ApplicationSettings applicationSettings);
|
||||
|
||||
IEnumerable<KeyBinding> GetKeyBindings();
|
||||
KeyBindings GetKeyBindings();
|
||||
void SaveKeyBindings(KeyBindings keyBindings);
|
||||
|
||||
TerminalTheme GetCurrentTheme();
|
||||
Guid GetCurrentThemeId();
|
||||
|
||||
+2
-1
@@ -3,9 +3,10 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public interface ITerminalService
|
||||
public interface ITrayProcessCommunicationService
|
||||
{
|
||||
Task<CreateTerminalResponse> CreateTerminal(TerminalSize size, ShellConfiguration shellConfiguration);
|
||||
Task ResizeTerminal(int id, TerminalSize size);
|
||||
Task UpdateToggleWindowKeyBindings();
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,114 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
internal class DefaultValueProvider : IDefaultValueProvider
|
||||
{
|
||||
public ApplicationSettings GetDefaultApplicationSettings()
|
||||
{
|
||||
return new ApplicationSettings
|
||||
{
|
||||
ConfirmClosingTabs = false,
|
||||
ConfirmClosingWindows = false,
|
||||
NewTerminalLocation = NewTerminalLocation.Tab
|
||||
};
|
||||
}
|
||||
|
||||
public KeyBindings GetDefaultKeyBindings()
|
||||
{
|
||||
return new KeyBindings
|
||||
{
|
||||
NewTab = new[]
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NewTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.T
|
||||
}
|
||||
},
|
||||
CloseTab = new[] {
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.CloseTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.W
|
||||
}
|
||||
},
|
||||
NextTab = new[] {
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NextTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.Tab
|
||||
}
|
||||
},
|
||||
PreviousTab = new[] {
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.PreviousTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = true,
|
||||
Key = (int)VirtualKey.Tab
|
||||
}
|
||||
},
|
||||
NewWindow = new[] {
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NewWindow,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.N
|
||||
}
|
||||
},
|
||||
ShowSettings = new[] {
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.ShowSettings,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = 188 // comma
|
||||
}
|
||||
},
|
||||
Copy = new[] {
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.Copy,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = true,
|
||||
Key = (int)VirtualKey.C
|
||||
}
|
||||
},
|
||||
Paste = new[] {
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.Paste,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.V
|
||||
}
|
||||
},
|
||||
ToggleWindow = new[] {
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.ToggleWindow,
|
||||
Ctrl = false,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.Scroll
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ShellConfiguration GetDefaultShellConfiguration()
|
||||
{
|
||||
return new ShellConfiguration
|
||||
@@ -106,93 +214,5 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
|
||||
return new[] { defaultXterm, powerShell };
|
||||
}
|
||||
|
||||
public IEnumerable<KeyBinding> GetDefaultKeyBindings()
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NewTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Meta = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.T
|
||||
},
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.CloseTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Meta = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.W
|
||||
},
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NextTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Meta = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.Tab
|
||||
},
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.PreviousTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Meta = false,
|
||||
Shift = true,
|
||||
Key = (int)VirtualKey.Tab
|
||||
},
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NewWindow,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Meta = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.N
|
||||
},
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.ShowSettings,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Meta = false,
|
||||
Shift = false,
|
||||
Key = 188 // comma
|
||||
},
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.Copy,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Meta = false,
|
||||
Shift = true,
|
||||
Key = (int)VirtualKey.C
|
||||
},
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.Paste,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Meta = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.V
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public ApplicationSettings GetDefaultApplicationSettings()
|
||||
{
|
||||
return new ApplicationSettings
|
||||
{
|
||||
ConfirmClosingTabs = false,
|
||||
ConfirmClosingWindows = false
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
public event EventHandler CurrentThemeChanged;
|
||||
public event EventHandler TerminalOptionsChanged;
|
||||
public event EventHandler ApplicationSettingsChanged;
|
||||
public event EventHandler KeyBindingsChanged;
|
||||
|
||||
public SettingsService(IDefaultValueProvider defaultValueProvider)
|
||||
{
|
||||
@@ -119,9 +120,15 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
ApplicationSettingsChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public IEnumerable<KeyBinding> GetKeyBindings()
|
||||
public KeyBindings GetKeyBindings()
|
||||
{
|
||||
return _roamingSettings.ReadValueFromJson("KeyBindings", _defaultValueProvider.GetDefaultKeyBindings());
|
||||
return _roamingSettings.ReadValueFromJson(nameof(KeyBindings), _defaultValueProvider.GetDefaultKeyBindings());
|
||||
}
|
||||
|
||||
public void SaveKeyBindings(KeyBindings keyBindings)
|
||||
{
|
||||
_roamingSettings.WriteValueAsJson(nameof(KeyBindings), keyBindings);
|
||||
KeyBindingsChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-2
@@ -6,13 +6,23 @@ using Windows.Web.Http;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
internal class TerminalService : ITerminalService
|
||||
internal class TrayProcessCommunicationService : ITrayProcessCommunicationService
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly ISettingsService _settingsService;
|
||||
|
||||
public TerminalService()
|
||||
public TrayProcessCommunicationService(ISettingsService settingsService)
|
||||
{
|
||||
_httpClient = new HttpClient();
|
||||
_settingsService = settingsService;
|
||||
|
||||
UpdateToggleWindowKeyBindings();
|
||||
}
|
||||
|
||||
public Task UpdateToggleWindowKeyBindings()
|
||||
{
|
||||
var keyBindings = _settingsService.GetKeyBindings().ToggleWindow;
|
||||
return _httpClient.PostAsync(new Uri($"http://localhost:9000/keybindings/togglewindow"), HttpJsonContent.From(keyBindings)).AsTask();
|
||||
}
|
||||
|
||||
public async Task<CreateTerminalResponse> CreateTerminal(TerminalSize size, ShellConfiguration shellConfiguration)
|
||||
@@ -18,20 +18,21 @@ namespace FluentTerminal.App.ViewModels
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IKeyboardCommandService _keyboardCommandService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ITerminalService _terminalService;
|
||||
private readonly ITrayProcessCommunicationService _trayProcessCommunicationService;
|
||||
private ApplicationSettings _applicationSettings;
|
||||
private string _background;
|
||||
private double _backgroundOpacity;
|
||||
private CoreDispatcher _dispatcher;
|
||||
private int _nextTerminalId;
|
||||
private TerminalViewModel _selectedTerminal;
|
||||
private string _title;
|
||||
|
||||
public MainViewModel(ISettingsService settingsService, ITerminalService terminalService, IDialogService dialogService, IKeyboardCommandService keyboardCommandService)
|
||||
public MainViewModel(ISettingsService settingsService, ITrayProcessCommunicationService trayProcessCommunicationService, IDialogService dialogService, IKeyboardCommandService keyboardCommandService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_settingsService.CurrentThemeChanged += OnCurrentThemeChanged;
|
||||
_settingsService.ApplicationSettingsChanged += OnApplicationSettingsChanged;
|
||||
_terminalService = terminalService;
|
||||
_trayProcessCommunicationService = trayProcessCommunicationService;
|
||||
_dialogService = dialogService;
|
||||
_keyboardCommandService = keyboardCommandService;
|
||||
_keyboardCommandService.RegisterCommandHandler(Command.NewTab, () => AddTerminal(null));
|
||||
@@ -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<TerminalViewModel> Terminals { get; } = new ObservableCollection<TerminalViewModel>();
|
||||
|
||||
public void AddTerminal(string startupDirectory)
|
||||
public string Title
|
||||
{
|
||||
var terminal = new TerminalViewModel(GetNextTerminalId(), _settingsService, _terminalService, _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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Views;
|
||||
using FluentTerminal.Models;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels.Settings
|
||||
{
|
||||
public class KeyBindingViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IDialogService _dialogService;
|
||||
|
||||
public KeyBindingViewModel(KeyBinding keyBinding, IDialogService dialogService)
|
||||
{
|
||||
Model = keyBinding;
|
||||
_dialogService = dialogService;
|
||||
EditCommand = new RelayCommand(async () => await Edit());
|
||||
DeleteCommand = new RelayCommand(async () => await Delete());
|
||||
}
|
||||
|
||||
public event EventHandler Deleted;
|
||||
|
||||
public event EventHandler Edited;
|
||||
|
||||
public bool Alt
|
||||
{
|
||||
get => Model.Alt;
|
||||
set
|
||||
{
|
||||
if (Model.Alt != value)
|
||||
{
|
||||
Model.Alt = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Ctrl
|
||||
{
|
||||
get => Model.Ctrl;
|
||||
set
|
||||
{
|
||||
if (Model.Ctrl != value)
|
||||
{
|
||||
Model.Ctrl = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RelayCommand DeleteCommand { get; }
|
||||
public RelayCommand EditCommand { get; }
|
||||
|
||||
public int Key
|
||||
{
|
||||
get => Model.Key;
|
||||
set
|
||||
{
|
||||
if (Model.Key != value)
|
||||
{
|
||||
Model.Key = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public KeyBinding Model { get; }
|
||||
|
||||
public bool Shift
|
||||
{
|
||||
get => Model.Shift;
|
||||
set
|
||||
{
|
||||
if (Model.Shift != value)
|
||||
{
|
||||
Model.Shift = value;
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> Edit()
|
||||
{
|
||||
var dialog = new CreateKeyBindingDialog(_dialogService);
|
||||
var result = await dialog.ShowAsync();
|
||||
|
||||
if (result == ContentDialogResult.Primary)
|
||||
{
|
||||
Alt = dialog.KeyBinding.Alt;
|
||||
Ctrl = dialog.KeyBinding.Ctrl;
|
||||
Shift = dialog.KeyBinding.Shift;
|
||||
Key = dialog.KeyBinding.Key;
|
||||
|
||||
Edited?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private async Task Delete()
|
||||
{
|
||||
var result = await _dialogService.ShowDialogAsnyc("Please confirm", "Are you sure you want to delete this keybinding?", DialogButton.OK, DialogButton.Cancel);
|
||||
|
||||
if (result == DialogButton.OK)
|
||||
{
|
||||
Deleted?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels.Settings
|
||||
{
|
||||
public class KeyBindingsPageViewModel : ViewModelBase
|
||||
{
|
||||
private KeyBindings _keyBindings;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IDefaultValueProvider _defaultValueProvider;
|
||||
private readonly ITrayProcessCommunicationService _trayProcessCommunicationService;
|
||||
|
||||
public KeyBindingsPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider, ITrayProcessCommunicationService trayProcessCommunicationService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_dialogService = dialogService;
|
||||
_defaultValueProvider = defaultValueProvider;
|
||||
_trayProcessCommunicationService = trayProcessCommunicationService;
|
||||
RestoreDefaultsCommand = new RelayCommand(async () => await RestoreDefaults());
|
||||
AddCommand = new RelayCommand<Command>(async command => await Add(command));
|
||||
|
||||
Initialize(_settingsService.GetKeyBindings());
|
||||
}
|
||||
|
||||
private void Initialize(KeyBindings keyBindings)
|
||||
{
|
||||
_keyBindings = keyBindings;
|
||||
|
||||
_keyBindings.NewTab = new List<KeyBinding>(_keyBindings.NewTab);
|
||||
|
||||
NewTab = CreateViewModel(Command.NewTab, _keyBindings.NewTab);
|
||||
ToggleWindow = CreateViewModel(Command.ToggleWindow, _keyBindings.ToggleWindow);
|
||||
NextTab = CreateViewModel(Command.NextTab, _keyBindings.NextTab);
|
||||
PreviousTab = CreateViewModel(Command.PreviousTab, _keyBindings.PreviousTab);
|
||||
CloseTab = CreateViewModel(Command.CloseTab, _keyBindings.CloseTab);
|
||||
NewWindow = CreateViewModel(Command.NewWindow, _keyBindings.NewWindow);
|
||||
ShowSettings = CreateViewModel(Command.ShowSettings, _keyBindings.ShowSettings);
|
||||
Copy = CreateViewModel(Command.Copy, _keyBindings.Copy);
|
||||
Paste = CreateViewModel(Command.Paste, _keyBindings.Paste);
|
||||
|
||||
RaisePropertyChanged(nameof(NewTab));
|
||||
RaisePropertyChanged(nameof(ToggleWindow));
|
||||
RaisePropertyChanged(nameof(NextTab));
|
||||
RaisePropertyChanged(nameof(PreviousTab));
|
||||
RaisePropertyChanged(nameof(CloseTab));
|
||||
RaisePropertyChanged(nameof(NewWindow));
|
||||
RaisePropertyChanged(nameof(ShowSettings));
|
||||
RaisePropertyChanged(nameof(Copy));
|
||||
RaisePropertyChanged(nameof(Paste));
|
||||
}
|
||||
|
||||
public KeyBindingsViewModel NewTab { get; private set; }
|
||||
public KeyBindingsViewModel ToggleWindow { get; private set; }
|
||||
public KeyBindingsViewModel NextTab { get; private set; }
|
||||
public KeyBindingsViewModel PreviousTab { get; private set; }
|
||||
public KeyBindingsViewModel CloseTab { get; private set; }
|
||||
public KeyBindingsViewModel NewWindow { get; private set; }
|
||||
public KeyBindingsViewModel ShowSettings { get; private set; }
|
||||
public KeyBindingsViewModel Copy { get; private set; }
|
||||
public KeyBindingsViewModel Paste { get; private set; }
|
||||
|
||||
public RelayCommand RestoreDefaultsCommand { get; }
|
||||
public RelayCommand<Command> AddCommand { get; }
|
||||
|
||||
private Task Add(Command command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case Command.ToggleWindow:
|
||||
return ToggleWindow.Add();
|
||||
case Command.NextTab:
|
||||
return NextTab.Add();
|
||||
case Command.PreviousTab:
|
||||
return PreviousTab.Add();
|
||||
case Command.NewTab:
|
||||
return NewTab.Add();
|
||||
case Command.CloseTab:
|
||||
return CloseTab.Add();
|
||||
case Command.NewWindow:
|
||||
return NewWindow.Add();
|
||||
case Command.ShowSettings:
|
||||
return ShowSettings.Add();
|
||||
case Command.Copy:
|
||||
return Copy.Add();
|
||||
case Command.Paste:
|
||||
return Paste.Add();
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task RestoreDefaults()
|
||||
{
|
||||
var result = await _dialogService.ShowDialogAsnyc("Please confirm", "Are you sure you want to restore the default keybindings?", DialogButton.OK, DialogButton.Cancel);
|
||||
|
||||
if (result == DialogButton.OK)
|
||||
{
|
||||
Initialize(_defaultValueProvider.GetDefaultKeyBindings());
|
||||
_settingsService.SaveKeyBindings(_keyBindings);
|
||||
}
|
||||
}
|
||||
|
||||
private KeyBindingsViewModel CreateViewModel(Command command, ICollection<KeyBinding> keyBindings)
|
||||
{
|
||||
var viewModel = new KeyBindingsViewModel(command, keyBindings, _dialogService);
|
||||
viewModel.Edited += OnEdited;
|
||||
|
||||
return viewModel;
|
||||
}
|
||||
|
||||
private void OnEdited(object sender, System.EventArgs e)
|
||||
{
|
||||
_settingsService.SaveKeyBindings(_keyBindings);
|
||||
_trayProcessCommunicationService.UpdateToggleWindowKeyBindings();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels.Settings
|
||||
{
|
||||
public class KeyBindingsViewModel : ViewModelBase
|
||||
{
|
||||
private readonly Command _command;
|
||||
private readonly IDialogService _dialogService;
|
||||
private ICollection<KeyBinding> _keyBindings;
|
||||
|
||||
public KeyBindingsViewModel(Command command, ICollection<KeyBinding> keyBindings, IDialogService dialogService)
|
||||
{
|
||||
_command = command;
|
||||
_keyBindings = keyBindings;
|
||||
_dialogService = dialogService;
|
||||
|
||||
foreach (var binding in keyBindings)
|
||||
{
|
||||
var viewModel = new KeyBindingViewModel(binding, _dialogService);
|
||||
viewModel.Deleted += ViewModel_Deleted;
|
||||
viewModel.Edited += ViewModel_Edited;
|
||||
KeyBindings.Add(viewModel);
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler Edited;
|
||||
|
||||
public ObservableCollection<KeyBindingViewModel> KeyBindings { get; } = new ObservableCollection<KeyBindingViewModel>();
|
||||
|
||||
public async Task Add()
|
||||
{
|
||||
var newKeyBinding = new KeyBindingViewModel(new KeyBinding { Command = _command }, _dialogService);
|
||||
|
||||
if (await newKeyBinding.Edit())
|
||||
{
|
||||
newKeyBinding.Deleted += ViewModel_Deleted;
|
||||
newKeyBinding.Edited += ViewModel_Edited;
|
||||
KeyBindings.Add(newKeyBinding);
|
||||
_keyBindings.Add(newKeyBinding.Model);
|
||||
Edited?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private void ViewModel_Deleted(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is KeyBindingViewModel keyBinding)
|
||||
{
|
||||
_keyBindings.Remove(keyBinding.Model);
|
||||
KeyBindings.Remove(keyBinding);
|
||||
Edited?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
private void ViewModel_Edited(object sender, EventArgs e)
|
||||
{
|
||||
Edited?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage.Pickers;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels.Settings
|
||||
{
|
||||
public class ShellPageViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IDefaultValueProvider _defaultValueProvider;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private ShellConfiguration _shellConfiguration;
|
||||
private bool _editingShellType;
|
||||
|
||||
public ShellPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_dialogService = dialogService;
|
||||
_defaultValueProvider = defaultValueProvider;
|
||||
|
||||
RestoreDefaultsCommand = new RelayCommand(async () => await RestoreDefaults());
|
||||
BrowseForCustomShellCommand = new RelayCommand(async () => await BrowseForCustomShell());
|
||||
BrowseForWorkingDirectoryCommand = new RelayCommand(async () => await BrowseForWorkingDirectory());
|
||||
|
||||
_shellConfiguration = _settingsService.GetShellConfiguration();
|
||||
}
|
||||
|
||||
public string Arguments
|
||||
{
|
||||
get => _shellConfiguration.Arguments;
|
||||
set
|
||||
{
|
||||
if (_shellConfiguration.Arguments != value)
|
||||
{
|
||||
_shellConfiguration.Arguments = value;
|
||||
_settingsService.SaveShellConfiguration(_shellConfiguration);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RelayCommand BrowseForCustomShellCommand { get; }
|
||||
|
||||
public RelayCommand BrowseForWorkingDirectoryCommand { get; }
|
||||
|
||||
public bool CMDIsSelected
|
||||
{
|
||||
get => ShellType == ShellType.CMD;
|
||||
set => ShellType = ShellType.CMD;
|
||||
}
|
||||
|
||||
public bool CustomShellIsSelected
|
||||
{
|
||||
get => ShellType == ShellType.Custom;
|
||||
set => ShellType = ShellType.Custom;
|
||||
}
|
||||
|
||||
public string CustomShellLocation
|
||||
{
|
||||
get => _shellConfiguration.CustomShellLocation;
|
||||
set
|
||||
{
|
||||
if (_shellConfiguration.CustomShellLocation != value)
|
||||
{
|
||||
_shellConfiguration.CustomShellLocation = value;
|
||||
_settingsService.SaveShellConfiguration(_shellConfiguration);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool PoweShellIsSelected
|
||||
{
|
||||
get => ShellType == ShellType.PowerShell;
|
||||
set => ShellType = ShellType.PowerShell;
|
||||
}
|
||||
|
||||
public RelayCommand RestoreDefaultsCommand { get; }
|
||||
|
||||
public ShellType ShellType
|
||||
{
|
||||
get => _shellConfiguration.Shell;
|
||||
set
|
||||
{
|
||||
if (_shellConfiguration.Shell != value && !_editingShellType)
|
||||
{
|
||||
_editingShellType = true;
|
||||
_shellConfiguration.Shell = value;
|
||||
_settingsService.SaveShellConfiguration(_shellConfiguration);
|
||||
RaisePropertyChanged();
|
||||
RaisePropertyChanged(nameof(CustomShellIsSelected));
|
||||
RaisePropertyChanged(nameof(PoweShellIsSelected));
|
||||
RaisePropertyChanged(nameof(CMDIsSelected));
|
||||
_editingShellType = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string WorkingDirectory
|
||||
{
|
||||
get => _shellConfiguration.WorkingDirectory;
|
||||
set
|
||||
{
|
||||
if (_shellConfiguration.WorkingDirectory != value)
|
||||
{
|
||||
_shellConfiguration.WorkingDirectory = value;
|
||||
_settingsService.SaveShellConfiguration(_shellConfiguration);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BrowseForCustomShell()
|
||||
{
|
||||
var picker = new FileOpenPicker();
|
||||
picker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
|
||||
picker.FileTypeFilter.Add(".exe");
|
||||
|
||||
var file = await picker.PickSingleFileAsync().AsTask();
|
||||
if (file != null)
|
||||
{
|
||||
CustomShellLocation = file.Path;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BrowseForWorkingDirectory()
|
||||
{
|
||||
var picker = new FolderPicker();
|
||||
picker.FileTypeFilter.Add(".whatever"); // else a ComException is thrown
|
||||
picker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
|
||||
|
||||
var folder = await picker.PickSingleFolderAsync();
|
||||
if (folder != null)
|
||||
{
|
||||
WorkingDirectory = folder.Path;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RestoreDefaults()
|
||||
{
|
||||
var result = await _dialogService.ShowDialogAsnyc("Please confirm", "Are you sure you want to restore the default shell configuration?", DialogButton.OK, DialogButton.Cancel);
|
||||
|
||||
if (result == DialogButton.OK)
|
||||
{
|
||||
var defaults = _defaultValueProvider.GetDefaultShellConfiguration();
|
||||
ShellType = defaults.Shell;
|
||||
CustomShellLocation = defaults.CustomShellLocation;
|
||||
WorkingDirectory = defaults.WorkingDirectory;
|
||||
Arguments = defaults.Arguments;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels.Settings
|
||||
{
|
||||
public class TerminalPageViewModel : ViewModelBase
|
||||
{
|
||||
private TerminalOptions _terminalOptions;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IDefaultValueProvider _defaultValueProvider;
|
||||
private bool _isEditingCursorStyle;
|
||||
|
||||
public bool BarIsSelected
|
||||
{
|
||||
get => CursorStyle == CursorStyle.Bar;
|
||||
set => CursorStyle = CursorStyle.Bar;
|
||||
}
|
||||
|
||||
public bool BlockIsSelected
|
||||
{
|
||||
get => CursorStyle == CursorStyle.Block;
|
||||
set => CursorStyle = CursorStyle.Block;
|
||||
}
|
||||
|
||||
public bool CursorBlink
|
||||
{
|
||||
get => _terminalOptions.CursorBlink;
|
||||
set
|
||||
{
|
||||
if (_terminalOptions.CursorBlink != value)
|
||||
{
|
||||
_terminalOptions.CursorBlink = value;
|
||||
_settingsService.SaveTerminalOptions(_terminalOptions);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string FontFamily
|
||||
{
|
||||
get => _terminalOptions.FontFamily;
|
||||
set
|
||||
{
|
||||
if (_terminalOptions.FontFamily != value)
|
||||
{
|
||||
_terminalOptions.FontFamily = value;
|
||||
_settingsService.SaveTerminalOptions(_terminalOptions);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> Fonts { get; }
|
||||
|
||||
public int FontSize
|
||||
{
|
||||
get => _terminalOptions.FontSize;
|
||||
set
|
||||
{
|
||||
if (_terminalOptions.FontSize != value)
|
||||
{
|
||||
_terminalOptions.FontSize = value;
|
||||
_settingsService.SaveTerminalOptions(_terminalOptions);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<int> Sizes { get; }
|
||||
|
||||
public bool UnderlineIsSelected
|
||||
{
|
||||
get => CursorStyle == CursorStyle.Underline;
|
||||
set => CursorStyle = CursorStyle.Underline;
|
||||
}
|
||||
|
||||
public RelayCommand RestoreDefaultsCommand { get; }
|
||||
|
||||
private CursorStyle CursorStyle
|
||||
{
|
||||
get => _terminalOptions.CursorStyle;
|
||||
set
|
||||
{
|
||||
if (_terminalOptions.CursorStyle != value && !_isEditingCursorStyle)
|
||||
{
|
||||
_isEditingCursorStyle = true;
|
||||
_terminalOptions.CursorStyle = value;
|
||||
_settingsService.SaveTerminalOptions(_terminalOptions);
|
||||
RaisePropertyChanged();
|
||||
RaisePropertyChanged(nameof(BlockIsSelected));
|
||||
RaisePropertyChanged(nameof(BarIsSelected));
|
||||
RaisePropertyChanged(nameof(UnderlineIsSelected));
|
||||
_isEditingCursorStyle = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RestoreDefaults()
|
||||
{
|
||||
var result = await _dialogService.ShowDialogAsnyc("Please confirm", "Are you sure you want to restore the default terminal options?", DialogButton.OK, DialogButton.Cancel);
|
||||
|
||||
if (result == DialogButton.OK)
|
||||
{
|
||||
var defaults = _defaultValueProvider.GetDefaultTerminalOptions();
|
||||
CursorBlink = defaults.CursorBlink;
|
||||
CursorStyle = defaults.CursorStyle;
|
||||
FontFamily = defaults.FontFamily;
|
||||
FontSize = defaults.FontSize;
|
||||
}
|
||||
}
|
||||
|
||||
public TerminalPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_dialogService = dialogService;
|
||||
_defaultValueProvider = defaultValueProvider;
|
||||
|
||||
RestoreDefaultsCommand = new RelayCommand(async () => await RestoreDefaults());
|
||||
|
||||
Fonts = CanvasTextFormat.GetSystemFontFamilies().OrderBy(s => s);
|
||||
Sizes = Enumerable.Range(1, 72);
|
||||
|
||||
_terminalOptions = _settingsService.GetTerminalOptions();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.Models;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels.Settings
|
||||
{
|
||||
public class ThemesPageViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IDefaultValueProvider _defaultValueProvider;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private ThemeViewModel _selectedTheme;
|
||||
|
||||
public ThemesPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_dialogService = dialogService;
|
||||
_defaultValueProvider = defaultValueProvider;
|
||||
|
||||
CreateThemeCommand = new RelayCommand(CreateTheme);
|
||||
|
||||
var activeThemeId = _settingsService.GetCurrentThemeId();
|
||||
foreach (var theme in _settingsService.GetThemes())
|
||||
{
|
||||
var viewModel = new ThemeViewModel(theme, _settingsService, _dialogService);
|
||||
viewModel.Activated += OnThemeActivated;
|
||||
viewModel.Deleted += OnThemeDeleted;
|
||||
|
||||
if (theme.Id == activeThemeId)
|
||||
{
|
||||
viewModel.IsActive = true;
|
||||
}
|
||||
Themes.Add(viewModel);
|
||||
}
|
||||
|
||||
SelectedTheme = Themes.First(t => t.IsActive);
|
||||
}
|
||||
|
||||
public RelayCommand CreateThemeCommand { get; set; }
|
||||
|
||||
public ThemeViewModel SelectedTheme
|
||||
{
|
||||
get => _selectedTheme;
|
||||
set => Set(ref _selectedTheme, value);
|
||||
}
|
||||
|
||||
public ObservableCollection<ThemeViewModel> Themes { get; } = new ObservableCollection<ThemeViewModel>();
|
||||
|
||||
private void CreateTheme()
|
||||
{
|
||||
var defaultTheme = _settingsService.GetTheme(_defaultValueProvider.GetDefaultThemeId());
|
||||
var theme = new TerminalTheme
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
PreInstalled = false,
|
||||
Name = "New Theme",
|
||||
BackgroundOpacity = defaultTheme.BackgroundOpacity,
|
||||
Colors = new TerminalColors(defaultTheme.Colors)
|
||||
};
|
||||
|
||||
_settingsService.SaveTheme(theme);
|
||||
|
||||
var viewModel = new ThemeViewModel(theme, _settingsService, _dialogService);
|
||||
viewModel.Activated += OnThemeActivated;
|
||||
viewModel.Deleted += OnThemeDeleted;
|
||||
Themes.Add(viewModel);
|
||||
SelectedTheme = viewModel;
|
||||
}
|
||||
|
||||
private void OnThemeActivated(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ThemeViewModel activatedTheme)
|
||||
{
|
||||
_settingsService.SaveCurrentThemeId(activatedTheme.Id);
|
||||
|
||||
foreach (var theme in Themes)
|
||||
{
|
||||
theme.IsActive = theme.Id == activatedTheme.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnThemeDeleted(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ThemeViewModel theme)
|
||||
{
|
||||
if (SelectedTheme == theme)
|
||||
{
|
||||
SelectedTheme = Themes.First();
|
||||
}
|
||||
Themes.Remove(theme);
|
||||
|
||||
if (theme.IsActive)
|
||||
{
|
||||
Themes.First().IsActive = true;
|
||||
_settingsService.SaveCurrentThemeId(Themes.First().Id);
|
||||
}
|
||||
_settingsService.DeleteTheme(theme.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,371 +1,24 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage.Pickers;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels
|
||||
{
|
||||
public class SettingsViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IDefaultValueProvider _defaultValueProvider;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private ApplicationSettings _applicationSettings;
|
||||
private ThemeViewModel _selectedTheme;
|
||||
private ShellConfiguration _shellConfiguration;
|
||||
private TerminalOptions _terminalOptions;
|
||||
|
||||
public SettingsViewModel(ISettingsService settingsService, IDefaultValueProvider defaultValueProvider, IDialogService dialogService)
|
||||
public SettingsViewModel(ISettingsService settingsService, IDefaultValueProvider defaultValueProvider, IDialogService dialogService, ITrayProcessCommunicationService trayProcessCommunicationService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_defaultValueProvider = defaultValueProvider;
|
||||
_dialogService = dialogService;
|
||||
BrowseForCustomShellCommand = new RelayCommand(async () => await BrowseForCustomShell());
|
||||
BrowseForWorkingDirectoryCommand = new RelayCommand(async () => await BrowseForWorkingDirectory());
|
||||
RestoreDefaultsCommand = new RelayCommand<string>(async (area) => await RestoreDefaults(area));
|
||||
CreateThemeCommand = new RelayCommand(CreateTheme);
|
||||
|
||||
_shellConfiguration = _settingsService.GetShellConfiguration();
|
||||
_terminalOptions = _settingsService.GetTerminalOptions();
|
||||
_applicationSettings = _settingsService.GetApplicationSettings();
|
||||
ShellType = _shellConfiguration.Shell;
|
||||
|
||||
var activeThemeId = _settingsService.GetCurrentThemeId();
|
||||
foreach (var theme in _settingsService.GetThemes())
|
||||
{
|
||||
var viewModel = new ThemeViewModel(theme, _settingsService, _dialogService);
|
||||
viewModel.Activated += OnThemeActivated;
|
||||
viewModel.Deleted += OnThemeDeleted;
|
||||
|
||||
if (theme.Id == activeThemeId)
|
||||
{
|
||||
viewModel.IsActive = true;
|
||||
}
|
||||
Themes.Add(viewModel);
|
||||
}
|
||||
|
||||
SelectedTheme = Themes.First();
|
||||
|
||||
Fonts = CanvasTextFormat.GetSystemFontFamilies().OrderBy(s => s);
|
||||
|
||||
Sizes = Enumerable.Range(1, 72);
|
||||
KeyBindings = new KeyBindingsPageViewModel(settingsService, dialogService, defaultValueProvider, trayProcessCommunicationService);
|
||||
General = new GeneralPageViewModel(settingsService, dialogService, defaultValueProvider);
|
||||
Shell = new ShellPageViewModel(settingsService, dialogService, defaultValueProvider);
|
||||
Terminal = new TerminalPageViewModel(settingsService, dialogService, defaultValueProvider);
|
||||
Themes = new ThemesPageViewModel(settingsService, dialogService, defaultValueProvider);
|
||||
}
|
||||
|
||||
public string Arguments
|
||||
{
|
||||
get => _shellConfiguration.Arguments;
|
||||
set
|
||||
{
|
||||
if (_shellConfiguration.Arguments != value)
|
||||
{
|
||||
_shellConfiguration.Arguments = value;
|
||||
_settingsService.SaveShellConfiguration(_shellConfiguration);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool BarIsSelected
|
||||
{
|
||||
get => CursorStyle == CursorStyle.Bar;
|
||||
set => CursorStyle = CursorStyle.Bar;
|
||||
}
|
||||
|
||||
public bool BlockIsSelected
|
||||
{
|
||||
get => CursorStyle == CursorStyle.Block;
|
||||
set => CursorStyle = CursorStyle.Block;
|
||||
}
|
||||
|
||||
public RelayCommand BrowseForCustomShellCommand { get; }
|
||||
|
||||
public RelayCommand BrowseForWorkingDirectoryCommand { get; }
|
||||
|
||||
public bool CMDIsSelected
|
||||
{
|
||||
get => ShellType == ShellType.CMD;
|
||||
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
|
||||
{
|
||||
get => _terminalOptions.CursorBlink;
|
||||
set
|
||||
{
|
||||
if (_terminalOptions.CursorBlink != value)
|
||||
{
|
||||
_terminalOptions.CursorBlink = value;
|
||||
_settingsService.SaveTerminalOptions(_terminalOptions);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool CustomShellIsSelected
|
||||
{
|
||||
get => ShellType == ShellType.Custom;
|
||||
set => ShellType = ShellType.Custom;
|
||||
}
|
||||
|
||||
public string CustomShellLocation
|
||||
{
|
||||
get => _shellConfiguration.CustomShellLocation;
|
||||
set
|
||||
{
|
||||
if (_shellConfiguration.CustomShellLocation != value)
|
||||
{
|
||||
_shellConfiguration.CustomShellLocation = value;
|
||||
_settingsService.SaveShellConfiguration(_shellConfiguration);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string FontFamily
|
||||
{
|
||||
get => _terminalOptions.FontFamily;
|
||||
set
|
||||
{
|
||||
if (_terminalOptions.FontFamily != value)
|
||||
{
|
||||
_terminalOptions.FontFamily = value;
|
||||
_settingsService.SaveTerminalOptions(_terminalOptions);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> Fonts { get; }
|
||||
|
||||
public int FontSize
|
||||
{
|
||||
get => _terminalOptions.FontSize;
|
||||
set
|
||||
{
|
||||
if (_terminalOptions.FontSize != value)
|
||||
{
|
||||
_terminalOptions.FontSize = value;
|
||||
_settingsService.SaveTerminalOptions(_terminalOptions);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool PoweShellIsSelected
|
||||
{
|
||||
get => ShellType == ShellType.PowerShell;
|
||||
set => ShellType = ShellType.PowerShell;
|
||||
}
|
||||
|
||||
public RelayCommand<string> RestoreDefaultsCommand { get; }
|
||||
|
||||
public ThemeViewModel SelectedTheme
|
||||
{
|
||||
get => _selectedTheme;
|
||||
set => Set(ref _selectedTheme, value);
|
||||
}
|
||||
|
||||
public ShellType ShellType
|
||||
{
|
||||
get => _shellConfiguration.Shell;
|
||||
set
|
||||
{
|
||||
if (_shellConfiguration.Shell != value)
|
||||
{
|
||||
_shellConfiguration.Shell = value;
|
||||
_settingsService.SaveShellConfiguration(_shellConfiguration);
|
||||
RaisePropertyChanged();
|
||||
RaisePropertyChanged(nameof(CustomShellIsSelected));
|
||||
RaisePropertyChanged(nameof(PoweShellIsSelected));
|
||||
RaisePropertyChanged(nameof(CMDIsSelected));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<int> Sizes { get; }
|
||||
|
||||
public ObservableCollection<ThemeViewModel> Themes { get; } = new ObservableCollection<ThemeViewModel>();
|
||||
|
||||
public bool UnderlineIsSelected
|
||||
{
|
||||
get => CursorStyle == CursorStyle.Underline;
|
||||
set => CursorStyle = CursorStyle.Underline;
|
||||
}
|
||||
|
||||
public string WorkingDirectory
|
||||
{
|
||||
get => _shellConfiguration.WorkingDirectory;
|
||||
set
|
||||
{
|
||||
if (_shellConfiguration.WorkingDirectory != value)
|
||||
{
|
||||
_shellConfiguration.WorkingDirectory = value;
|
||||
_settingsService.SaveShellConfiguration(_shellConfiguration);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private CursorStyle CursorStyle
|
||||
{
|
||||
get => _terminalOptions.CursorStyle;
|
||||
set
|
||||
{
|
||||
if (_terminalOptions.CursorStyle != value)
|
||||
{
|
||||
_terminalOptions.CursorStyle = value;
|
||||
_settingsService.SaveTerminalOptions(_terminalOptions);
|
||||
RaisePropertyChanged();
|
||||
RaisePropertyChanged(nameof(BlockIsSelected));
|
||||
RaisePropertyChanged(nameof(BarIsSelected));
|
||||
RaisePropertyChanged(nameof(UnderlineIsSelected));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BrowseForCustomShell()
|
||||
{
|
||||
var picker = new FileOpenPicker();
|
||||
picker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
|
||||
picker.FileTypeFilter.Add(".exe");
|
||||
|
||||
var file = await picker.PickSingleFileAsync().AsTask();
|
||||
if (file != null)
|
||||
{
|
||||
CustomShellLocation = file.Path;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task BrowseForWorkingDirectory()
|
||||
{
|
||||
var picker = new FolderPicker();
|
||||
picker.FileTypeFilter.Add(".whatever"); // else a ComException is thrown
|
||||
picker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
|
||||
|
||||
var folder = await picker.PickSingleFolderAsync();
|
||||
if (folder != null)
|
||||
{
|
||||
WorkingDirectory = folder.Path;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateTheme()
|
||||
{
|
||||
var defaultTheme = _settingsService.GetTheme(_defaultValueProvider.GetDefaultThemeId());
|
||||
var theme = new TerminalTheme
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
PreInstalled = false,
|
||||
Name = "New Theme",
|
||||
BackgroundOpacity = defaultTheme.BackgroundOpacity,
|
||||
Colors = new TerminalColors(defaultTheme.Colors)
|
||||
};
|
||||
|
||||
_settingsService.SaveTheme(theme);
|
||||
|
||||
var viewModel = new ThemeViewModel(theme, _settingsService, _dialogService);
|
||||
viewModel.Activated += OnThemeActivated;
|
||||
viewModel.Deleted += OnThemeDeleted;
|
||||
Themes.Add(viewModel);
|
||||
SelectedTheme = viewModel;
|
||||
}
|
||||
|
||||
private void OnThemeActivated(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ThemeViewModel activatedTheme)
|
||||
{
|
||||
_settingsService.SaveCurrentThemeId(activatedTheme.Id);
|
||||
|
||||
foreach (var theme in Themes)
|
||||
{
|
||||
theme.IsActive = theme.Id == activatedTheme.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnThemeDeleted(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ThemeViewModel theme)
|
||||
{
|
||||
if (SelectedTheme == theme)
|
||||
{
|
||||
SelectedTheme = Themes.First();
|
||||
}
|
||||
Themes.Remove(theme);
|
||||
|
||||
if (theme.IsActive)
|
||||
{
|
||||
Themes.First().IsActive = true;
|
||||
_settingsService.SaveCurrentThemeId(Themes.First().Id);
|
||||
}
|
||||
_settingsService.DeleteTheme(theme.Id);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RestoreDefaults(string area)
|
||||
{
|
||||
var result = await _dialogService.ShowDialogAsnyc("Please confirm", "Are you sure you want to restore default values for this page?", DialogButton.OK, DialogButton.Cancel);
|
||||
|
||||
if (result == DialogButton.OK && area == "shell")
|
||||
{
|
||||
var defaults = _defaultValueProvider.GetDefaultShellConfiguration();
|
||||
ShellType = defaults.Shell;
|
||||
CustomShellLocation = defaults.CustomShellLocation;
|
||||
WorkingDirectory = defaults.WorkingDirectory;
|
||||
Arguments = defaults.Arguments;
|
||||
}
|
||||
else if (result == DialogButton.OK && area == "terminal")
|
||||
{
|
||||
var defaults = _defaultValueProvider.GetDefaultTerminalOptions();
|
||||
CursorBlink = defaults.CursorBlink;
|
||||
CursorStyle = defaults.CursorStyle;
|
||||
FontFamily = defaults.FontFamily;
|
||||
FontSize = defaults.FontSize;
|
||||
}
|
||||
else if (result == DialogButton.OK && area == "general")
|
||||
{
|
||||
var defaults = _defaultValueProvider.GetDefaultApplicationSettings();
|
||||
ConfirmClosingWindows = defaults.ConfirmClosingWindows;
|
||||
ConfirmClosingTabs = defaults.ConfirmClosingTabs;
|
||||
}
|
||||
}
|
||||
public GeneralPageViewModel General { get; }
|
||||
public KeyBindingsPageViewModel KeyBindings { get; }
|
||||
public TerminalPageViewModel Terminal { get; }
|
||||
public ShellPageViewModel Shell { get; }
|
||||
public ThemesPageViewModel Themes { get; }
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using FluentTerminal.Models.Enums;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
@@ -18,7 +19,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IKeyboardCommandService _keyboardCommandService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ITerminalService _terminalService;
|
||||
private readonly ITrayProcessCommunicationService _trayProcessCommunicationService;
|
||||
private ApplicationSettings _applicationSettings;
|
||||
private CoreDispatcher _dispatcher;
|
||||
private string _resizeOverlayContent;
|
||||
@@ -29,7 +30,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
private ITerminalView _terminalView;
|
||||
private string _title;
|
||||
|
||||
public TerminalViewModel(int id, ISettingsService settingsService, ITerminalService terminalService, IDialogService dialogService, IKeyboardCommandService keyboardCommandService, ApplicationSettings applicationSettings, string startupDirectory)
|
||||
public TerminalViewModel(int id, ISettingsService settingsService, ITrayProcessCommunicationService trayProcessCommunicationService, IDialogService dialogService, IKeyboardCommandService keyboardCommandService, ApplicationSettings applicationSettings, string startupDirectory)
|
||||
{
|
||||
Id = id;
|
||||
Title = DefaultTitle;
|
||||
@@ -38,7 +39,8 @@ namespace FluentTerminal.App.ViewModels
|
||||
_settingsService.CurrentThemeChanged += OnCurrentThemeChanged;
|
||||
_settingsService.TerminalOptionsChanged += OnTerminalOptionsChanged;
|
||||
_settingsService.ApplicationSettingsChanged += OnApplicationSettingsChanged;
|
||||
_terminalService = terminalService;
|
||||
_settingsService.KeyBindingsChanged += OnKeyBindingsChanged;
|
||||
_trayProcessCommunicationService = trayProcessCommunicationService;
|
||||
_dialogService = dialogService;
|
||||
_keyboardCommandService = keyboardCommandService;
|
||||
_applicationSettings = applicationSettings;
|
||||
@@ -52,6 +54,15 @@ namespace FluentTerminal.App.ViewModels
|
||||
_dispatcher = CoreApplication.GetCurrentView().Dispatcher;
|
||||
}
|
||||
|
||||
private async void OnKeyBindingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
|
||||
{
|
||||
var keyBindings = _settingsService.GetKeyBindings();
|
||||
await _terminalView.ChangeKeyBindings(GetKeyBindingsCollection(keyBindings));
|
||||
});
|
||||
}
|
||||
|
||||
public event EventHandler CloseRequested;
|
||||
|
||||
public event EventHandler<string> TitleChanged;
|
||||
@@ -119,7 +130,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
var theme = _settingsService.GetCurrentTheme();
|
||||
var keyBindings = _settingsService.GetKeyBindings();
|
||||
|
||||
var size = await _terminalView.CreateTerminal(options, theme.Colors, keyBindings);
|
||||
var size = await _terminalView.CreateTerminal(options, theme.Colors, GetKeyBindingsCollection(keyBindings));
|
||||
var configuration = _settingsService.GetShellConfiguration();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_startupDirectory))
|
||||
@@ -127,7 +138,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
configuration.WorkingDirectory = _startupDirectory;
|
||||
}
|
||||
|
||||
var response = await _terminalService.CreateTerminal(size, configuration);
|
||||
var response = await _trayProcessCommunicationService.CreateTerminal(size, configuration);
|
||||
|
||||
if (response.Success)
|
||||
{
|
||||
@@ -167,7 +178,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
private async void OnApplicationSettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
|
||||
{
|
||||
_applicationSettings = _settingsService.GetApplicationSettings();
|
||||
});
|
||||
@@ -229,12 +240,27 @@ namespace FluentTerminal.App.ViewModels
|
||||
}
|
||||
ResizeOverlayContent = $"{e.Columns} x {e.Rows}";
|
||||
ShowResizeOverlay = true;
|
||||
await _terminalService.ResizeTerminal(_terminalId, e);
|
||||
await _trayProcessCommunicationService.ResizeTerminal(_terminalId, e);
|
||||
}
|
||||
|
||||
private void OnTerminalTitleChanged(object sender, string e)
|
||||
{
|
||||
Title = e;
|
||||
}
|
||||
|
||||
private IEnumerable<KeyBinding> GetKeyBindingsCollection(KeyBindings keyBindings)
|
||||
{
|
||||
var list = new List<KeyBinding>();
|
||||
list.AddRange(keyBindings.CloseTab);
|
||||
list.AddRange(keyBindings.Copy);
|
||||
list.AddRange(keyBindings.NewTab);
|
||||
list.AddRange(keyBindings.NewWindow);
|
||||
list.AddRange(keyBindings.NextTab);
|
||||
list.AddRange(keyBindings.Paste);
|
||||
list.AddRange(keyBindings.PreviousTab);
|
||||
list.AddRange(keyBindings.ShowSettings);
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,19 @@
|
||||
using Windows.UI;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.ViewManagement;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using System;
|
||||
|
||||
namespace FluentTerminal.App.Views
|
||||
{
|
||||
public sealed class BindableColorsTitleBar : Control
|
||||
{
|
||||
private ApplicationViewTitleBar _titleBar;
|
||||
private readonly ApplicationViewTitleBar _titleBar;
|
||||
private readonly UISettings _uiSettings;
|
||||
private readonly CoreDispatcher _dispatcher;
|
||||
|
||||
private bool _customValues;
|
||||
|
||||
private Color? _buttonForeground;
|
||||
private Color? _buttonHoverBackground;
|
||||
@@ -18,12 +24,32 @@ namespace FluentTerminal.App.Views
|
||||
|
||||
public BindableColorsTitleBar()
|
||||
{
|
||||
DefaultStyleKey = typeof(BindableColorsTitleBar);
|
||||
_uiSettings = new UISettings();
|
||||
_uiSettings.ColorValuesChanged += OnColorValuesChanged;
|
||||
_titleBar = ApplicationView.GetForCurrentView().TitleBar;
|
||||
|
||||
_titleBar = ApplicationView.GetForCurrentView().TitleBar;
|
||||
_titleBar.ButtonBackgroundColor = Colors.Transparent;
|
||||
_titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
|
||||
_titleBar.ButtonForegroundColor = (Color)this.Resources["SystemBaseHighColor"];
|
||||
|
||||
_dispatcher = Window.Current.Dispatcher;
|
||||
|
||||
_buttonHoverBackground = _titleBar.ButtonHoverBackgroundColor = Color.FromArgb(24, 255, 255, 255);
|
||||
_buttonPressedBackground = _titleBar.ButtonPressedBackgroundColor = Color.FromArgb(48, 255, 255, 255);
|
||||
}
|
||||
|
||||
private async void OnColorValuesChanged(UISettings sender, object args)
|
||||
{
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
|
||||
{
|
||||
if (!_customValues)
|
||||
{
|
||||
_titleBar.ButtonForegroundColor = (Color)this.Resources["SystemBaseHighColor"];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Color TitleBarForeground
|
||||
{
|
||||
get { return (Color)GetValue(TitleBarForegroundProperty); }
|
||||
@@ -55,6 +81,8 @@ namespace FluentTerminal.App.Views
|
||||
_titleBar.ButtonPressedForegroundColor = _buttonPressedForeground;
|
||||
_titleBar.ButtonHoverForegroundColor = _buttonHoverForeground;
|
||||
_titleBar.InactiveForegroundColor = _inactiveForeground;
|
||||
|
||||
_customValues = true;
|
||||
}
|
||||
|
||||
public void ResetTitleBar()
|
||||
@@ -65,6 +93,8 @@ namespace FluentTerminal.App.Views
|
||||
_titleBar.ButtonPressedForegroundColor = null;
|
||||
_titleBar.ButtonHoverForegroundColor = null;
|
||||
_titleBar.InactiveForegroundColor = null;
|
||||
|
||||
_customValues = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<ContentDialog
|
||||
x:Class="FluentTerminal.App.Views.CreateKeyBindingDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="400"
|
||||
PrimaryButtonText="OK"
|
||||
SecondaryButtonText="Cancel"
|
||||
mc:Ignorable="d">
|
||||
<StackPanel>
|
||||
<TextBlock Margin="0,0,0,24" Text="Enter your keybinding now" />
|
||||
<StackPanel x:Name="Root" Orientation="Horizontal">
|
||||
<Grid
|
||||
Width="48"
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind KeyBinding.Ctrl, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="Ctrl" />
|
||||
</Grid>
|
||||
<Grid
|
||||
Width="48"
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind KeyBinding.Alt, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="Alt" />
|
||||
</Grid>
|
||||
<Grid
|
||||
Width="48"
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind KeyBinding.Shift, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="Shift" />
|
||||
</Grid>
|
||||
<Grid
|
||||
Width="48"
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind KeyBinding.Key, Mode=OneWay, Converter={StaticResource ZeroToCollapsedConverter}}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind KeyBinding.Key, Mode=OneWay, Converter={StaticResource IntToExtendedVirtualKeyConverter}}" />
|
||||
</Grid>
|
||||
<HyperlinkButton
|
||||
x:Name="ResetButton"
|
||||
Margin="24,0,0,0"
|
||||
Command="{x:Bind ResetCommand}"
|
||||
Content="Reset"
|
||||
PreviewKeyDown="OnResetButtonPreviewKeyDown" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ContentDialog>
|
||||
@@ -0,0 +1,69 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using FluentTerminal.Models;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace FluentTerminal.App.Views
|
||||
{
|
||||
public sealed partial class CreateKeyBindingDialog : ContentDialog
|
||||
{
|
||||
public static readonly DependencyProperty KeyBindingProperty =
|
||||
DependencyProperty.Register(nameof(KeyBinding), typeof(KeyBindingViewModel), typeof(CreateKeyBindingDialog), new PropertyMetadata(null));
|
||||
|
||||
private readonly IDialogService _dialogService;
|
||||
|
||||
public CreateKeyBindingDialog(IDialogService dialogService)
|
||||
{
|
||||
_dialogService = dialogService;
|
||||
InitializeComponent();
|
||||
ResetCommand = new RelayCommand(Reset);
|
||||
PreviewKeyDown += RegisterKeyBindingDialog_PreviewKeyDown;
|
||||
Reset();
|
||||
}
|
||||
|
||||
public KeyBindingViewModel KeyBinding
|
||||
{
|
||||
get { return (KeyBindingViewModel)GetValue(KeyBindingProperty); }
|
||||
set { SetValue(KeyBindingProperty, value); }
|
||||
}
|
||||
|
||||
public RelayCommand ResetCommand { get; }
|
||||
|
||||
private void OnResetButtonPreviewKeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void RegisterKeyBindingDialog_PreviewKeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case VirtualKey.Control:
|
||||
KeyBinding.Ctrl = true;
|
||||
break;
|
||||
|
||||
case VirtualKey.Shift:
|
||||
KeyBinding.Shift = true;
|
||||
break;
|
||||
|
||||
case VirtualKey.Menu:
|
||||
KeyBinding.Alt = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
KeyBinding.Key = (int)e.Key;
|
||||
break;
|
||||
}
|
||||
ResetButton.Visibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
KeyBinding = new KeyBindingViewModel(new KeyBinding(), _dialogService);
|
||||
ResetButton.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ namespace FluentTerminal.App.Views
|
||||
|
||||
Task ChangeTheme(TerminalColors theme);
|
||||
Task ChangeOptions(TerminalOptions options);
|
||||
Task ChangeKeyBindings(IEnumerable<KeyBinding> keyBindings);
|
||||
Task<TerminalSize> CreateTerminal(TerminalOptions options, TerminalColors theme, IEnumerable<KeyBinding> keyBindings);
|
||||
Task ConnectToSocket(string url);
|
||||
void Close();
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
<UserControl
|
||||
x:Class="FluentTerminal.App.Views.KeyBindingsView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:settings="using:FluentTerminal.App.ViewModels.Settings"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="400"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ItemsControl Grid.Row="0" ItemsSource="{x:Bind ViewModel.KeyBindings, Mode=OneWay}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="settings:KeyBindingViewModel">
|
||||
<StackPanel
|
||||
x:Name="Root"
|
||||
Margin="0,0,0,6"
|
||||
Orientation="Horizontal">
|
||||
<Grid
|
||||
Width="48"
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind Ctrl, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="Ctrl" />
|
||||
</Grid>
|
||||
<Grid
|
||||
Width="48"
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind Alt, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="Alt" />
|
||||
</Grid>
|
||||
<Grid
|
||||
Width="48"
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind Shift, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="Shift" />
|
||||
</Grid>
|
||||
<Grid
|
||||
Width="64"
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind Key, Mode=OneWay, Converter={StaticResource IntToExtendedVirtualKeyConverter}}" />
|
||||
</Grid>
|
||||
<HyperlinkButton
|
||||
Margin="12,0,0,0"
|
||||
Command="{x:Bind EditCommand}"
|
||||
Content="Edit" />
|
||||
<HyperlinkButton
|
||||
Margin="12,0,0,0"
|
||||
Command="{x:Bind DeleteCommand}"
|
||||
Content="Delete" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,23 @@
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace FluentTerminal.App.Views
|
||||
{
|
||||
public sealed partial class KeyBindingsView : UserControl
|
||||
{
|
||||
public static readonly DependencyProperty ViewModelProperty =
|
||||
DependencyProperty.Register(nameof(ViewModel), typeof(KeyBindingsViewModel), typeof(KeyBindingsView), new PropertyMetadata(null));
|
||||
|
||||
public KeyBindingsView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public KeyBindingsViewModel ViewModel
|
||||
{
|
||||
get { return (KeyBindingsViewModel)GetValue(ViewModelProperty); }
|
||||
set { SetValue(ViewModelProperty, value); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,16 +13,6 @@
|
||||
mc:Ignorable="d">
|
||||
<Page.Resources>
|
||||
<converters:TerminalViewModelToViewConverter x:Key="TerminalViewModelToViewConverter" />
|
||||
<converters:IntToVisibilityConverter
|
||||
x:Key="OneToVisibleConverter"
|
||||
Else="Collapsed"
|
||||
If="1"
|
||||
Then="Visible" />
|
||||
<converters:IntToVisibilityConverter
|
||||
x:Key="OneToCollapsedConverter"
|
||||
Else="Visible"
|
||||
If="1"
|
||||
Then="Collapsed" />
|
||||
</Page.Resources>
|
||||
<Grid x:Name="Root">
|
||||
<Grid.Background>
|
||||
@@ -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}}" />
|
||||
<ListView
|
||||
x:Name="Tabs"
|
||||
|
||||
@@ -2,15 +2,10 @@
|
||||
x:Class="FluentTerminal.App.Views.SettingsPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:converters="using:FluentTerminal.App.Converters"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d">
|
||||
<Page.Resources>
|
||||
<converters:TrueToVisibleConverter x:Key="TrueToVisibleConverter" />
|
||||
<converters:FalseToVisibleConverter x:Key="FalseToVisibleConverter" />
|
||||
</Page.Resources>
|
||||
<Grid x:Name="Root" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Grid x:Name="Root">
|
||||
<TextBlock
|
||||
x:Name="AppTitle"
|
||||
Canvas.ZIndex="1"
|
||||
@@ -70,7 +65,7 @@
|
||||
</NavigationViewItem.Icon>
|
||||
</NavigationViewItem>
|
||||
</NavigationView.MenuItems>
|
||||
<Grid>
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Frame x:Name="ContentFrame" />
|
||||
<TextBlock
|
||||
Margin="12,8,0,0"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using FluentTerminal.App.Views.SettingsPages;
|
||||
using System.Linq;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Core.Preview;
|
||||
using Windows.UI.ViewManagement;
|
||||
using Windows.UI.Xaml;
|
||||
@@ -13,25 +12,15 @@ namespace FluentTerminal.App.Views
|
||||
{
|
||||
public sealed partial class SettingsPage : Page
|
||||
{
|
||||
public double CoreTitleBarHeight { get; }
|
||||
|
||||
public SettingsViewModel ViewModel { get; private set; }
|
||||
|
||||
public SettingsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
Root.DataContext = this;
|
||||
|
||||
ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar;
|
||||
titleBar.ButtonBackgroundColor = Colors.Transparent;
|
||||
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
|
||||
titleBar.ButtonForegroundColor = (Color)this.Resources["SystemBaseHighColor"];
|
||||
|
||||
ApplicationView.PreferredLaunchViewSize = new Windows.Foundation.Size(1024, 768);
|
||||
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
|
||||
|
||||
ApplicationView.GetForCurrentView().Title = "Settings";
|
||||
|
||||
|
||||
CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
|
||||
coreTitleBar.LayoutMetricsChanged += TitleBar_LayoutMetricsChanged;
|
||||
@@ -40,6 +29,9 @@ namespace FluentTerminal.App.Views
|
||||
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += SettingsPage_CloseRequested;
|
||||
}
|
||||
|
||||
public double CoreTitleBarHeight { get; }
|
||||
|
||||
public SettingsViewModel ViewModel { get; private set; }
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
if (e.Parameter is SettingsViewModel viewModel)
|
||||
@@ -48,16 +40,6 @@ namespace FluentTerminal.App.Views
|
||||
}
|
||||
}
|
||||
|
||||
private void SettingsPage_CloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e)
|
||||
{
|
||||
App.Instance.SettingsWindowClosed();
|
||||
}
|
||||
|
||||
private void TitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args)
|
||||
{
|
||||
AppTitle.Margin = new Thickness(CoreApplication.GetCurrentView().TitleBar.SystemOverlayLeftInset + 12, 8, 0, 0);
|
||||
}
|
||||
|
||||
private void NavigationView_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
NavigationView.SelectedItem = NavigationView.MenuItems.Cast<NavigationViewItemBase>().FirstOrDefault(m => m.Tag.ToString() == "general");
|
||||
@@ -70,22 +52,36 @@ namespace FluentTerminal.App.Views
|
||||
switch (item.Tag)
|
||||
{
|
||||
case "general":
|
||||
ContentFrame.Navigate(typeof(GeneralSettings), ViewModel);
|
||||
ContentFrame.Navigate(typeof(GeneralSettings), ViewModel.General);
|
||||
break;
|
||||
|
||||
case "shell":
|
||||
ContentFrame.Navigate(typeof(ShellSettings), ViewModel);
|
||||
ContentFrame.Navigate(typeof(ShellSettings), ViewModel.Shell);
|
||||
break;
|
||||
|
||||
case "themes":
|
||||
ContentFrame.Navigate(typeof(ThemeSettings), ViewModel);
|
||||
ContentFrame.Navigate(typeof(ThemeSettings), ViewModel.Themes);
|
||||
break;
|
||||
|
||||
case "terminal":
|
||||
ContentFrame.Navigate(typeof(TerminalSettings), ViewModel);
|
||||
ContentFrame.Navigate(typeof(TerminalSettings), ViewModel.Terminal);
|
||||
break;
|
||||
|
||||
case "keyBindings":
|
||||
ContentFrame.Navigate(typeof(KeyBindingSettings), ViewModel);
|
||||
ContentFrame.Navigate(typeof(KeyBindingSettings), ViewModel.KeyBindings);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SettingsPage_CloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e)
|
||||
{
|
||||
App.Instance.SettingsWindowClosed();
|
||||
}
|
||||
|
||||
private void TitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args)
|
||||
{
|
||||
AppTitle.Margin = new Thickness(CoreApplication.GetCurrentView().TitleBar.SystemOverlayLeftInset + 12, 8, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
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"
|
||||
NavigationCacheMode="Required"
|
||||
mc:Ignorable="d">
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
@@ -30,14 +29,18 @@
|
||||
Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
|
||||
DefaultLabelPosition="Right">
|
||||
<AppBarButton
|
||||
Command="{Binding ViewModel.RestoreDefaultsCommand}"
|
||||
CommandParameter="general"
|
||||
Command="{x:Bind ViewModel.RestoreDefaultsCommand}"
|
||||
Icon="Undo"
|
||||
Label="Restore Defaults" />
|
||||
</CommandBar>
|
||||
</Grid>
|
||||
<StackPanel Grid.Row="2" Margin="24,0,0,0">
|
||||
|
||||
<TextBlock Margin="0,0,0,8" Text="Open new terminals as" />
|
||||
<RadioButton Content="Tabs" IsChecked="{x:Bind ViewModel.TabIsSelected, Mode=TwoWay}" />
|
||||
<RadioButton
|
||||
Margin="0,0,0,24"
|
||||
Content="Windows"
|
||||
IsChecked="{x:Bind ViewModel.WindowIsSelected, Mode=TwoWay}" />
|
||||
<ToggleSwitch
|
||||
Margin="0,0,0,24"
|
||||
Header="Ask before closing windows"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using FluentTerminal.App.ViewModels;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
{
|
||||
public sealed partial class GeneralSettings : Page
|
||||
{
|
||||
public SettingsViewModel ViewModel { get; private set; }
|
||||
public GeneralPageViewModel ViewModel { get; private set; }
|
||||
|
||||
public GeneralSettings()
|
||||
{
|
||||
@@ -15,7 +15,7 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
if (e.Parameter is SettingsViewModel viewModel)
|
||||
if (e.Parameter is GeneralPageViewModel viewModel)
|
||||
{
|
||||
ViewModel = viewModel;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,208 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:FluentTerminal.App.Views.SettingsPages"
|
||||
xmlns:enums="using:FluentTerminal.Models.Enums"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:views="using:FluentTerminal.App.Views"
|
||||
mc:Ignorable="d">
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="32" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="1" Margin="24,0,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Margin="0,10,0,0"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="28"
|
||||
Style="{StaticResource TitleTextBlockStyle}"
|
||||
Text="Keybindings" />
|
||||
<CommandBar
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
|
||||
DefaultLabelPosition="Right">
|
||||
<AppBarButton Icon="Add" Label="Add">
|
||||
<AppBarButton.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem Command="{x:Bind ViewModel.AddCommand}" Text="New tab">
|
||||
<MenuFlyoutItem.CommandParameter>
|
||||
<enums:Command>NewTab</enums:Command>
|
||||
</MenuFlyoutItem.CommandParameter>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem Command="{x:Bind ViewModel.AddCommand}" Text="Close tab">
|
||||
<MenuFlyoutItem.CommandParameter>
|
||||
<enums:Command>CloseTab</enums:Command>
|
||||
</MenuFlyoutItem.CommandParameter>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem Command="{x:Bind ViewModel.AddCommand}" Text="Next tab">
|
||||
<MenuFlyoutItem.CommandParameter>
|
||||
<enums:Command>NextTab</enums:Command>
|
||||
</MenuFlyoutItem.CommandParameter>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem Command="{x:Bind ViewModel.AddCommand}" Text="Previous tab">
|
||||
<MenuFlyoutItem.CommandParameter>
|
||||
<enums:Command>PreviousTab</enums:Command>
|
||||
</MenuFlyoutItem.CommandParameter>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem Command="{x:Bind ViewModel.AddCommand}" Text="New window">
|
||||
<MenuFlyoutItem.CommandParameter>
|
||||
<enums:Command>NewWindow</enums:Command>
|
||||
</MenuFlyoutItem.CommandParameter>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem Command="{x:Bind ViewModel.AddCommand}" Text="Show settings">
|
||||
<MenuFlyoutItem.CommandParameter>
|
||||
<enums:Command>ShowSettings</enums:Command>
|
||||
</MenuFlyoutItem.CommandParameter>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem Command="{x:Bind ViewModel.AddCommand}" Text="Toggle window">
|
||||
<MenuFlyoutItem.CommandParameter>
|
||||
<enums:Command>ToggleWindow</enums:Command>
|
||||
</MenuFlyoutItem.CommandParameter>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem Command="{x:Bind ViewModel.AddCommand}" Text="Copy">
|
||||
<MenuFlyoutItem.CommandParameter>
|
||||
<enums:Command>Copy</enums:Command>
|
||||
</MenuFlyoutItem.CommandParameter>
|
||||
</MenuFlyoutItem>
|
||||
<MenuFlyoutItem Command="{x:Bind ViewModel.AddCommand}" Text="Paste">
|
||||
<MenuFlyoutItem.CommandParameter>
|
||||
<enums:Command>Paste</enums:Command>
|
||||
</MenuFlyoutItem.CommandParameter>
|
||||
</MenuFlyoutItem>
|
||||
</MenuFlyout>
|
||||
</AppBarButton.Flyout>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
Command="{x:Bind ViewModel.RestoreDefaultsCommand}"
|
||||
CommandParameter="keyBindings"
|
||||
Icon="Undo"
|
||||
Label="Restore Defaults" />
|
||||
</CommandBar>
|
||||
</Grid>
|
||||
<ScrollViewer Grid.Row="2" Margin="24,24,0,0">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="New tab" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="0"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.NewTab, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Close tab" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.CloseTab, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Next tab" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.NextTab, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Previous tab" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.PreviousTab, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="New window" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.NewWindow, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Show settings" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.ShowSettings, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Toggle window" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.ToggleWindow, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="7"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Copy" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="7"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.Copy, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="8"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Paste" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="8"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.Paste, Mode=OneWay}" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -1,30 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using FluentTerminal.App.ViewModels;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
// Die Elementvorlage "Leere Seite" wird unter https://go.microsoft.com/fwlink/?LinkId=234238 dokumentiert.
|
||||
|
||||
namespace FluentTerminal.App.Views.SettingsPages
|
||||
{
|
||||
/// <summary>
|
||||
/// Eine leere Seite, die eigenständig verwendet oder zu der innerhalb eines Rahmens navigiert werden kann.
|
||||
/// </summary>
|
||||
public sealed partial class KeyBindingSettings : Page
|
||||
{
|
||||
public KeyBindingsPageViewModel ViewModel { get; private set; }
|
||||
|
||||
public KeyBindingSettings()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
if (e.Parameter is KeyBindingsPageViewModel viewModel)
|
||||
{
|
||||
ViewModel = viewModel;
|
||||
}
|
||||
}
|
||||
|
||||
private void KeyBindingView_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
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"
|
||||
NavigationCacheMode="Required"
|
||||
mc:Ignorable="d">
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
@@ -30,8 +29,7 @@
|
||||
Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
|
||||
DefaultLabelPosition="Right">
|
||||
<AppBarButton
|
||||
Command="{Binding ViewModel.RestoreDefaultsCommand}"
|
||||
CommandParameter="shell"
|
||||
Command="{x:Bind ViewModel.RestoreDefaultsCommand}"
|
||||
Icon="Undo"
|
||||
Label="Restore Defaults" />
|
||||
</CommandBar>
|
||||
@@ -39,9 +37,9 @@
|
||||
<StackPanel Grid.Row="2" Margin="24,0,0,0">
|
||||
|
||||
<TextBlock Margin="0,0,0,8" Text="Type" />
|
||||
<RadioButton Content="PowerShell" IsChecked="{Binding ViewModel.PoweShellIsSelected, Mode=TwoWay}" />
|
||||
<RadioButton Content="CMD" IsChecked="{Binding ViewModel.CMDIsSelected, Mode=TwoWay}" />
|
||||
<RadioButton Content="Custom" IsChecked="{Binding ViewModel.CustomShellIsSelected, Mode=TwoWay}" />
|
||||
<RadioButton Content="PowerShell" IsChecked="{x:Bind ViewModel.PoweShellIsSelected, Mode=TwoWay}" />
|
||||
<RadioButton Content="CMD" IsChecked="{x:Bind ViewModel.CMDIsSelected, Mode=TwoWay}" />
|
||||
<RadioButton Content="Custom" IsChecked="{x:Bind ViewModel.CustomShellIsSelected, Mode=TwoWay}" />
|
||||
|
||||
<StackPanel Margin="0,24,0,0" Orientation="Horizontal">
|
||||
<TextBox
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using FluentTerminal.App.ViewModels;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
{
|
||||
public sealed partial class ShellSettings : Page
|
||||
{
|
||||
public SettingsViewModel ViewModel { get; private set; }
|
||||
public ShellPageViewModel ViewModel { get; private set; }
|
||||
|
||||
public ShellSettings()
|
||||
{
|
||||
@@ -15,7 +15,7 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
if (e.Parameter is SettingsViewModel viewModel)
|
||||
if (e.Parameter is ShellPageViewModel viewModel)
|
||||
{
|
||||
ViewModel = viewModel;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
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"
|
||||
NavigationCacheMode="Required"
|
||||
mc:Ignorable="d">
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<Grid.RowDefinitions>
|
||||
@@ -30,8 +29,7 @@
|
||||
Background="{ThemeResource SystemControlBackgroundAltHighBrush}"
|
||||
DefaultLabelPosition="Right">
|
||||
<AppBarButton
|
||||
Command="{Binding ViewModel.RestoreDefaultsCommand}"
|
||||
CommandParameter="terminal"
|
||||
Command="{x:Bind ViewModel.RestoreDefaultsCommand}"
|
||||
Icon="Undo"
|
||||
Label="Restore Defaults" />
|
||||
</CommandBar>
|
||||
@@ -54,9 +52,9 @@
|
||||
Header="Blinking Cursor"
|
||||
IsOn="{x:Bind ViewModel.CursorBlink, Mode=TwoWay}" />
|
||||
<TextBlock Margin="0,0,0,8" Text="Cursor Style" />
|
||||
<RadioButton Content="Block" IsChecked="{Binding ViewModel.BlockIsSelected, Mode=TwoWay}" />
|
||||
<RadioButton Content="Underline" IsChecked="{Binding ViewModel.UnderlineIsSelected, Mode=TwoWay}" />
|
||||
<RadioButton Content="Bar" IsChecked="{Binding ViewModel.BarIsSelected, Mode=TwoWay}" />
|
||||
<RadioButton Content="Block" IsChecked="{x:Bind ViewModel.BlockIsSelected, Mode=TwoWay}" />
|
||||
<RadioButton Content="Underline" IsChecked="{x:Bind ViewModel.UnderlineIsSelected, Mode=TwoWay}" />
|
||||
<RadioButton Content="Bar" IsChecked="{x:Bind ViewModel.BarIsSelected, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -1,4 +1,4 @@
|
||||
using FluentTerminal.App.ViewModels;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
@@ -11,11 +11,11 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public SettingsViewModel ViewModel { get; private set; }
|
||||
public TerminalPageViewModel ViewModel { get; private set; }
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
if (e.Parameter is SettingsViewModel viewModel)
|
||||
if (e.Parameter is TerminalPageViewModel viewModel)
|
||||
{
|
||||
ViewModel = viewModel;
|
||||
}
|
||||
|
||||
@@ -2,18 +2,11 @@
|
||||
x:Class="FluentTerminal.App.Views.SettingsPages.ThemeSettings"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:converters="using:FluentTerminal.App.Converters"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewmodels="using:FluentTerminal.App.ViewModels"
|
||||
xmlns:views="using:FluentTerminal.App.Views"
|
||||
NavigationCacheMode="Required"
|
||||
mc:Ignorable="d">
|
||||
<Page.Resources>
|
||||
<converters:NegateConverter x:Key="NegateConverter" />
|
||||
<converters:FalseToVisibleConverter x:Key="FalseToVisibleConverter" />
|
||||
<converters:TrueToVisibleConverter x:Key="TrueToVisibleConverter" />
|
||||
</Page.Resources>
|
||||
<Grid x:Name="Root">
|
||||
<Grid.Background>
|
||||
<AcrylicBrush
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using FluentTerminal.App.ViewModels;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
{
|
||||
public sealed partial class ThemeSettings : Page
|
||||
{
|
||||
public SettingsViewModel ViewModel { get; private set; }
|
||||
public ThemesPageViewModel ViewModel { get; private set; }
|
||||
|
||||
public ThemeSettings()
|
||||
{
|
||||
@@ -16,7 +16,7 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
{
|
||||
if (e.Parameter is SettingsViewModel viewModel)
|
||||
if (e.Parameter is ThemesPageViewModel viewModel)
|
||||
{
|
||||
ViewModel = viewModel;
|
||||
}
|
||||
@@ -27,6 +27,5 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
{
|
||||
TitleBar.ResetTitleBar();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,16 +2,11 @@
|
||||
x:Class="FluentTerminal.App.Views.TerminalView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:converters="using:FluentTerminal.App.Converters"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="using:FluentTerminal.App.Views"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
d:DesignHeight="300"
|
||||
d:DesignWidth="400"
|
||||
mc:Ignorable="d">
|
||||
<UserControl.Resources>
|
||||
<converters:TrueToVisibleConverter x:Key="TrueToVisibleConverter" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid x:Name="WebViewContainer" Margin="12" />
|
||||
<Grid
|
||||
|
||||
@@ -70,6 +70,12 @@ namespace FluentTerminal.App.Views
|
||||
return ExecuteScriptAsync($"changeTheme('{serialized}')");
|
||||
}
|
||||
|
||||
public Task ChangeKeyBindings(IEnumerable<KeyBinding> keyBindings)
|
||||
{
|
||||
var serialized = JsonConvert.SerializeObject(keyBindings);
|
||||
return ExecuteScriptAsync($"changeKeyBindings('{serialized}')");
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
_webView?.Navigate(new Uri("about:blank"));
|
||||
@@ -190,7 +196,7 @@ namespace FluentTerminal.App.Views
|
||||
Items = { _copyMenuItem, _pasteMenuItem }
|
||||
};
|
||||
|
||||
_webView.Navigate(new Uri("http://localhost:9000/Client/index.html"));
|
||||
_webView.Navigate(new Uri("ms-appx-web:///Client/index.html"));
|
||||
|
||||
await _loaded.WaitAsync();
|
||||
|
||||
|
||||
@@ -67,7 +67,6 @@ function createTerminal(options, theme, keyBindings) {
|
||||
var keyBinding = window.keyBindings[i];
|
||||
if (keyBinding.ctrl == e.ctrlKey
|
||||
&& keyBinding.alt == e.altKey
|
||||
&& keyBinding.meta == e.metaKey
|
||||
&& keyBinding.shift == e.shiftKey
|
||||
&& keyBinding.key == e.keyCode) {
|
||||
if (document.visibilityState == 'visible') {
|
||||
@@ -113,6 +112,11 @@ function changeOptions(options) {
|
||||
term.setOption('fontSize', options.fontSize);
|
||||
}
|
||||
|
||||
function changeKeyBindings(keyBindings) {
|
||||
keyBindings = JSON.parse(keyBindings);
|
||||
window.keyBindings = keyBindings;
|
||||
}
|
||||
|
||||
function paste(content) {
|
||||
content = b64DecodeUnicode(content);
|
||||
term.send(content);
|
||||
@@ -132,4 +136,5 @@ window.createTerminal = createTerminal;
|
||||
window.connectToWebSocket = connectToWebSocket;
|
||||
window.changeTheme = changeTheme;
|
||||
window.changeOptions = changeOptions;
|
||||
window.changeKeyBindings = changeKeyBindings;
|
||||
window.paste = paste;
|
||||
@@ -1,8 +1,11 @@
|
||||
namespace FluentTerminal.Models
|
||||
using FluentTerminal.Models.Enums;
|
||||
|
||||
namespace FluentTerminal.Models
|
||||
{
|
||||
public class ApplicationSettings
|
||||
{
|
||||
public bool ConfirmClosingTabs { get; set; }
|
||||
public bool ConfirmClosingWindows { get; set; }
|
||||
public NewTerminalLocation NewTerminalLocation { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
namespace FluentTerminal.Models.Enums
|
||||
{
|
||||
public enum ExtendedVirtualKey
|
||||
{
|
||||
None = 0,
|
||||
LeftButton = 1,
|
||||
RightButton = 2,
|
||||
Cancel = 3,
|
||||
MiddleButton = 4,
|
||||
XButton1 = 5,
|
||||
XButton2 = 6,
|
||||
Back = 8,
|
||||
Tab = 9,
|
||||
Clear = 12,
|
||||
Enter = 13,
|
||||
Shift = 16,
|
||||
Control = 17,
|
||||
Menu = 18,
|
||||
Pause = 19,
|
||||
CapitalLock = 20,
|
||||
Kana = 21,
|
||||
Hangul = 21,
|
||||
Junja = 23,
|
||||
Final = 24,
|
||||
Hanja = 25,
|
||||
Kanji = 25,
|
||||
Escape = 27,
|
||||
Convert = 28,
|
||||
NonConvert = 29,
|
||||
Accept = 30,
|
||||
ModeChange = 31,
|
||||
Space = 32,
|
||||
PageUp = 33,
|
||||
PageDown = 34,
|
||||
End = 35,
|
||||
Home = 36,
|
||||
Left = 37,
|
||||
Up = 38,
|
||||
Right = 39,
|
||||
Down = 40,
|
||||
Select = 41,
|
||||
Print = 42,
|
||||
Execute = 43,
|
||||
Snapshot = 44,
|
||||
Insert = 45,
|
||||
Delete = 46,
|
||||
Help = 47,
|
||||
Number0 = 48,
|
||||
Number1 = 49,
|
||||
Number2 = 50,
|
||||
Number3 = 51,
|
||||
Number4 = 52,
|
||||
Number5 = 53,
|
||||
Number6 = 54,
|
||||
Number7 = 55,
|
||||
Number8 = 56,
|
||||
Number9 = 57,
|
||||
A = 65,
|
||||
B = 66,
|
||||
C = 67,
|
||||
D = 68,
|
||||
E = 69,
|
||||
F = 70,
|
||||
G = 71,
|
||||
H = 72,
|
||||
I = 73,
|
||||
J = 74,
|
||||
K = 75,
|
||||
L = 76,
|
||||
M = 77,
|
||||
N = 78,
|
||||
O = 79,
|
||||
P = 80,
|
||||
Q = 81,
|
||||
R = 82,
|
||||
S = 83,
|
||||
T = 84,
|
||||
U = 85,
|
||||
V = 86,
|
||||
W = 87,
|
||||
X = 88,
|
||||
Y = 89,
|
||||
Z = 90,
|
||||
LeftWindows = 91,
|
||||
RightWindows = 92,
|
||||
Application = 93,
|
||||
Sleep = 95,
|
||||
NumberPad0 = 96,
|
||||
NumberPad1 = 97,
|
||||
NumberPad2 = 98,
|
||||
NumberPad3 = 99,
|
||||
NumberPad4 = 100,
|
||||
NumberPad5 = 101,
|
||||
NumberPad6 = 102,
|
||||
NumberPad7 = 103,
|
||||
NumberPad8 = 104,
|
||||
NumberPad9 = 105,
|
||||
Multiply = 106,
|
||||
Add = 107,
|
||||
Separator = 108,
|
||||
Subtract = 109,
|
||||
Decimal = 110,
|
||||
Divide = 111,
|
||||
F1 = 112,
|
||||
F2 = 113,
|
||||
F3 = 114,
|
||||
F4 = 115,
|
||||
F5 = 116,
|
||||
F6 = 117,
|
||||
F7 = 118,
|
||||
F8 = 119,
|
||||
F9 = 120,
|
||||
F10 = 121,
|
||||
F11 = 122,
|
||||
F12 = 123,
|
||||
F13 = 124,
|
||||
F14 = 125,
|
||||
F15 = 126,
|
||||
F16 = 127,
|
||||
F17 = 128,
|
||||
F18 = 129,
|
||||
F19 = 130,
|
||||
F20 = 131,
|
||||
F21 = 132,
|
||||
F22 = 133,
|
||||
F23 = 134,
|
||||
F24 = 135,
|
||||
NavigationView = 136,
|
||||
NavigationMenu = 137,
|
||||
NavigationUp = 138,
|
||||
NavigationDown = 139,
|
||||
NavigationLeft = 140,
|
||||
NavigationRight = 141,
|
||||
NavigationAccept = 142,
|
||||
NavigationCancel = 143,
|
||||
NumberKeyLock = 144,
|
||||
Scroll = 145,
|
||||
LeftShift = 160,
|
||||
RightShift = 161,
|
||||
LeftControl = 162,
|
||||
RightControl = 163,
|
||||
LeftMenu = 164,
|
||||
RightMenu = 165,
|
||||
GoBack = 166,
|
||||
GoForward = 167,
|
||||
Refresh = 168,
|
||||
Stop = 169,
|
||||
Search = 170,
|
||||
Favorites = 171,
|
||||
GoHome = 172,
|
||||
VolumeMute = 173,
|
||||
VolumeDown = 174,
|
||||
VolumeUp = 175,
|
||||
MediaNext = 176,
|
||||
MediaPrevious = 177,
|
||||
MediaStop = 178,
|
||||
MediaPlayPause = 179,
|
||||
Plus = 187,
|
||||
Comma = 188,
|
||||
Minus = 189,
|
||||
Period = 190,
|
||||
GamepadA = 195,
|
||||
GamepadB = 196,
|
||||
GamepadX = 197,
|
||||
GamepadY = 198,
|
||||
GamepadRightShoulder = 199,
|
||||
GamepadLeftShoulder = 200,
|
||||
GamepadLeftTrigger = 201,
|
||||
GamepadRightTrigger = 202,
|
||||
GamepadDPadUp = 203,
|
||||
GamepadDPadDown = 204,
|
||||
GamepadDPadLeft = 205,
|
||||
GamepadDPadRight = 206,
|
||||
GamepadMenu = 207,
|
||||
GamepadView = 208,
|
||||
GamepadLeftThumbstickButton = 209,
|
||||
GamepadRightThumbstickButton = 210,
|
||||
GamepadLeftThumbstickUp = 211,
|
||||
GamepadLeftThumbstickDown = 212,
|
||||
GamepadLeftThumbstickRight = 213,
|
||||
GamepadLeftThumbstickLeft = 214,
|
||||
GamepadRightThumbstickUp = 215,
|
||||
GamepadRightThumbstickDown = 216,
|
||||
GamepadRightThumbstickRight = 217,
|
||||
GamepadRightThumbstickLeft = 218
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace FluentTerminal.Models.Enums
|
||||
{
|
||||
public enum NewTerminalLocation
|
||||
{
|
||||
Tab,
|
||||
Window
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ namespace FluentTerminal.Models
|
||||
public int Key { get; set; }
|
||||
public bool Ctrl { get; set; }
|
||||
public bool Alt { get; set; }
|
||||
public bool Meta { get; set; }
|
||||
public bool Shift { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FluentTerminal.Models
|
||||
{
|
||||
public class KeyBindings
|
||||
{
|
||||
public ICollection<KeyBinding> ToggleWindow { get; set; }
|
||||
public ICollection<KeyBinding> NextTab { get; set; }
|
||||
public ICollection<KeyBinding> PreviousTab { get; set; }
|
||||
public ICollection<KeyBinding> NewTab { get; set; }
|
||||
public ICollection<KeyBinding> CloseTab { get; set; }
|
||||
public ICollection<KeyBinding> NewWindow { get; set; }
|
||||
public ICollection<KeyBinding> ShowSettings { get; set; }
|
||||
public ICollection<KeyBinding> Copy { get; set; }
|
||||
public ICollection<KeyBinding> Paste { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.SystemTray.Services;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace FluentTerminal.SystemTray.Controllers
|
||||
{
|
||||
public class KeyBindingsController : ApiController
|
||||
{
|
||||
private readonly ToggleWindowService _toggleWindowService;
|
||||
|
||||
public KeyBindingsController(ToggleWindowService toggleWindowService)
|
||||
{
|
||||
_toggleWindowService = toggleWindowService;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("keybindings/togglewindow")]
|
||||
public void PostToggleWindowKeyBindings([FromBody]IEnumerable<KeyBinding> keyBindings)
|
||||
{
|
||||
_toggleWindowService.SetHotKeys(keyBindings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,10 +112,13 @@
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Controllers\KeyBindingsController.cs" />
|
||||
<Compile Include="Controllers\TerminalsController.cs" />
|
||||
<Compile Include="LoopbackEnabler.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Services\ToggleWindowService.cs" />
|
||||
<Compile Include="Services\NotificationService.cs" />
|
||||
<Compile Include="Services\TerminalSession.cs" />
|
||||
<Compile Include="Services\TerminalsManager.cs" />
|
||||
<Compile Include="Startup.cs" />
|
||||
@@ -156,10 +159,7 @@
|
||||
<Version>1.1.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost">
|
||||
<Version>5.2.3</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Owin.StaticFiles">
|
||||
<Version>3.1.0</Version>
|
||||
<Version>5.2.4</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Unity.WebAPI">
|
||||
<Version>5.3.0</Version>
|
||||
@@ -175,18 +175,6 @@
|
||||
<Content Include="BinaryDependencies\x86\winpty-agent.exe" />
|
||||
<Content Include="BinaryDependencies\x86\winpty-debugserver.exe" />
|
||||
<Content Include="BinaryDependencies\x86\winpty.dll" />
|
||||
<Content Include="Client\bundle.js">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Client\index.html">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Client\style.css">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Client\xterm.css">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FluentTerminal.Models\FluentTerminal.Models.csproj">
|
||||
@@ -201,6 +189,7 @@ xcopy /y /s "$(ProjectDir)bin\$(PlatformName)\$(ConfigurationName)" "$(SolutionD
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>xcopy /y "$(SolutionDir)FluentTerminal.Client\dist" "$(ProjectDir)Client"</PreBuildEvent>
|
||||
<PreBuildEvent>
|
||||
</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,26 @@
|
||||
using Windows.Data.Xml.Dom;
|
||||
using Windows.UI.Notifications;
|
||||
|
||||
namespace FluentTerminal.SystemTray.Services
|
||||
{
|
||||
public class NotificationService
|
||||
{
|
||||
public void ShowNotification(string title, string content)
|
||||
{
|
||||
string xml = $@"<toast>
|
||||
<visual>
|
||||
<binding template='ToastGeneric'>
|
||||
<text>{title}</text>
|
||||
<text>{content}</text>
|
||||
</binding>
|
||||
</visual>
|
||||
</toast>";
|
||||
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(xml);
|
||||
|
||||
var toast = new ToastNotification(doc);
|
||||
ToastNotificationManager.CreateToastNotifier().Show(toast);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using GlobalHotKey;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Core;
|
||||
|
||||
namespace FluentTerminal.SystemTray.Services
|
||||
{
|
||||
public class ToggleWindowService : IDisposable
|
||||
{
|
||||
private readonly HotKeyManager _hotKeyManager;
|
||||
private readonly NotificationService _notificationService;
|
||||
private Dispatcher _dispatcher;
|
||||
private bool _disposedValue;
|
||||
private List<HotKey> _hotKeys;
|
||||
|
||||
public ToggleWindowService(Dispatcher dispatcher, HotKeyManager hotKeyManager, NotificationService notificationService)
|
||||
{
|
||||
_dispatcher = dispatcher;
|
||||
_notificationService = notificationService;
|
||||
_hotKeyManager = hotKeyManager;
|
||||
_hotKeys = new List<HotKey>();
|
||||
_hotKeyManager.KeyPressed += OnKeyPressed;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
public void SetHotKeys(IEnumerable<KeyBinding> keyBindings)
|
||||
{
|
||||
foreach (var hotKey in _hotKeys)
|
||||
{
|
||||
_dispatcher.Invoke(() =>
|
||||
{
|
||||
_hotKeyManager.Unregister(hotKey);
|
||||
});
|
||||
}
|
||||
|
||||
_hotKeys.Clear();
|
||||
|
||||
foreach (var keyBinding in keyBindings)
|
||||
{
|
||||
try
|
||||
{
|
||||
var key = Utilities.ExtendVirtualKeyToInputKey((ExtendedVirtualKey)keyBinding.Key);
|
||||
var modifiers = ModifierKeys.None;
|
||||
if (keyBinding.Alt)
|
||||
{
|
||||
modifiers |= ModifierKeys.Alt;
|
||||
}
|
||||
if (keyBinding.Ctrl)
|
||||
{
|
||||
modifiers |= ModifierKeys.Control;
|
||||
}
|
||||
if (keyBinding.Shift)
|
||||
{
|
||||
modifiers |= ModifierKeys.Shift;
|
||||
}
|
||||
|
||||
var hotKey = new HotKey(key, modifiers);
|
||||
|
||||
_dispatcher.Invoke(() =>
|
||||
{
|
||||
_hotKeyManager.Register(hotKey);
|
||||
});
|
||||
|
||||
_hotKeys.Add(hotKey);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_notificationService.ShowNotification("Error", "Failed to register the following hotkey: " + GetKeyBindingRepresentation(keyBinding));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_hotKeyManager?.Dispose();
|
||||
}
|
||||
|
||||
_disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetForegroundWindow();
|
||||
|
||||
private static string GetKeyBindingRepresentation(KeyBinding keyBinding)
|
||||
{
|
||||
var keys = new List<string>();
|
||||
if (keyBinding.Ctrl)
|
||||
{
|
||||
keys.Add("Ctrl");
|
||||
}
|
||||
if (keyBinding.Alt)
|
||||
{
|
||||
keys.Add("Alt");
|
||||
}
|
||||
if (keyBinding.Shift)
|
||||
{
|
||||
keys.Add("Shift");
|
||||
}
|
||||
|
||||
keys.Add(((ExtendedVirtualKey)keyBinding.Key).ToString());
|
||||
|
||||
return string.Join(" + ", keys);
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint ProcessId);
|
||||
|
||||
private string GetActiveProcessFileName()
|
||||
{
|
||||
try
|
||||
{
|
||||
var hwnd = GetForegroundWindow();
|
||||
GetWindowThreadProcessId(hwnd, out uint pid);
|
||||
var process = Process.GetProcessById((int)pid);
|
||||
return process.MainWindowTitle;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnKeyPressed(object sender, KeyPressedEventArgs e)
|
||||
{
|
||||
if (GetActiveProcessFileName() == "Fluent Terminal")
|
||||
{
|
||||
SendKeys.Send("%{Tab}");
|
||||
}
|
||||
else
|
||||
{
|
||||
IEnumerable<AppListEntry> appListEntries = await Package.Current.GetAppListEntriesAsync();
|
||||
await appListEntries.First().LaunchAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
using FluentTerminal.SystemTray.Services;
|
||||
using GlobalHotKey;
|
||||
using Owin;
|
||||
using System.Web.Http;
|
||||
using System.Windows.Threading;
|
||||
using Unity;
|
||||
using Unity.Lifetime;
|
||||
|
||||
@@ -15,10 +17,13 @@ namespace FluentTerminal.SystemTray
|
||||
|
||||
var container = new UnityContainer();
|
||||
container.RegisterType<TerminalsManager>(new ContainerControlledLifetimeManager());
|
||||
container.RegisterType<NotificationService>(new ContainerControlledLifetimeManager());
|
||||
container.RegisterType<ToggleWindowService>(new ContainerControlledLifetimeManager());
|
||||
container.RegisterInstance(new HotKeyManager(), new ContainerControlledLifetimeManager());
|
||||
container.RegisterInstance(Dispatcher.CurrentDispatcher, new ContainerControlledLifetimeManager());
|
||||
|
||||
config.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
|
||||
|
||||
appBuilder.UseStaticFiles("/Client");
|
||||
appBuilder.UseWebApi(config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,72 +1,43 @@
|
||||
using GlobalHotKey;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Input;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.AppService;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.Data.Xml.Dom;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Notifications;
|
||||
|
||||
namespace FluentTerminal.SystemTray
|
||||
{
|
||||
public class SystemTrayApplicationContext : ApplicationContext
|
||||
{
|
||||
private AppServiceConnection connection = null;
|
||||
private HotKeyManager hotKeyManager = null;
|
||||
private NotifyIcon notifyIcon = null;
|
||||
private AppServiceConnection _connection;
|
||||
private readonly NotifyIcon _notifyIcon;
|
||||
|
||||
public SystemTrayApplicationContext()
|
||||
|
||||
{
|
||||
var openMenuItem = new MenuItem("Show", new EventHandler(OpenApp));
|
||||
var newWindowItem = new MenuItem("New Window", new EventHandler(NewWindow));
|
||||
var settingsMenuItem = new MenuItem("Show Settings", new EventHandler(ShowSettings));
|
||||
var newWindowItem = new MenuItem("New window", new EventHandler(NewWindow));
|
||||
var settingsMenuItem = new MenuItem("Show settings", new EventHandler(ShowSettings));
|
||||
var exitMenuItem = new MenuItem("Exit", new EventHandler(Exit));
|
||||
|
||||
openMenuItem.DefaultItem = true;
|
||||
|
||||
notifyIcon = new NotifyIcon();
|
||||
notifyIcon.DoubleClick += OpenApp;
|
||||
notifyIcon.Text = "Fluent Terminal";
|
||||
notifyIcon.Icon = Properties.Resources.Square44x44Logo_scale_100;
|
||||
notifyIcon.ContextMenu = new ContextMenu(new MenuItem[] { openMenuItem, newWindowItem, settingsMenuItem, exitMenuItem });
|
||||
notifyIcon.Visible = true;
|
||||
|
||||
hotKeyManager = new HotKeyManager();
|
||||
try
|
||||
{
|
||||
hotKeyManager.Register(Key.Scroll, ModifierKeys.None);
|
||||
hotKeyManager.KeyPressed += HotkeyManager_KeyPressed;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
ShowNotification("Fluent Terminal", "Unable to register hotkey for toggle window command");
|
||||
}
|
||||
_notifyIcon = new NotifyIcon();
|
||||
_notifyIcon.DoubleClick += OpenApp;
|
||||
_notifyIcon.Text = "Fluent Terminal";
|
||||
_notifyIcon.Icon = Properties.Resources.Square44x44Logo_scale_100;
|
||||
_notifyIcon.ContextMenu = new ContextMenu(new MenuItem[] { openMenuItem, newWindowItem, settingsMenuItem, exitMenuItem });
|
||||
_notifyIcon.Visible = true;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out uint ProcessId);
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
hotKeyManager.Dispose();
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetForegroundWindow();
|
||||
|
||||
private void Connection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args)
|
||||
{
|
||||
connection.ServiceClosed -= Connection_ServiceClosed;
|
||||
connection = null;
|
||||
_connection.ServiceClosed -= Connection_ServiceClosed;
|
||||
_connection = null;
|
||||
}
|
||||
|
||||
private async void Exit(object sender, EventArgs e)
|
||||
@@ -79,36 +50,6 @@ namespace FluentTerminal.SystemTray
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
private string GetActiveProcessFileName()
|
||||
{
|
||||
try
|
||||
{
|
||||
IntPtr hwnd = GetForegroundWindow();
|
||||
GetWindowThreadProcessId(hwnd, out uint pid);
|
||||
Process p = Process.GetProcessById((int)pid);
|
||||
return p.MainWindowTitle;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void HotkeyManager_KeyPressed(object sender, KeyPressedEventArgs e)
|
||||
{
|
||||
if (e.HotKey.Key == Key.Scroll)
|
||||
{
|
||||
if (GetActiveProcessFileName() == "Fluent Terminal")
|
||||
{
|
||||
SendKeys.Send("%{Tab}");
|
||||
}
|
||||
else
|
||||
{
|
||||
OpenApp(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void NewWindow(object sender, EventArgs e)
|
||||
{
|
||||
Process.Start("flute.exe", "new");
|
||||
@@ -123,15 +64,15 @@ namespace FluentTerminal.SystemTray
|
||||
private async Task SendMessage(ValueSet message)
|
||||
|
||||
{
|
||||
if (connection == null)
|
||||
if (_connection == null)
|
||||
{
|
||||
connection = new AppServiceConnection
|
||||
_connection = new AppServiceConnection
|
||||
{
|
||||
PackageFamilyName = Package.Current.Id.FamilyName,
|
||||
AppServiceName = "FluentTerminalAppService"
|
||||
};
|
||||
connection.ServiceClosed += Connection_ServiceClosed;
|
||||
AppServiceConnectionStatus connectionStatus = await connection.OpenAsync();
|
||||
_connection.ServiceClosed += Connection_ServiceClosed;
|
||||
AppServiceConnectionStatus connectionStatus = await _connection.OpenAsync();
|
||||
|
||||
if (connectionStatus != AppServiceConnectionStatus.Success)
|
||||
{
|
||||
@@ -139,25 +80,7 @@ namespace FluentTerminal.SystemTray
|
||||
return;
|
||||
}
|
||||
}
|
||||
await connection.SendMessageAsync(message);
|
||||
}
|
||||
|
||||
private void ShowNotification(string title, string content)
|
||||
{
|
||||
string xml = $@"<toast>
|
||||
<visual>
|
||||
<binding template='ToastGeneric'>
|
||||
<text>{title}</text>
|
||||
<text>{content}</text>
|
||||
</binding>
|
||||
</visual>
|
||||
</toast>";
|
||||
|
||||
var doc = new XmlDocument();
|
||||
doc.LoadXml(xml);
|
||||
|
||||
var toast = new ToastNotification(doc);
|
||||
ToastNotificationManager.CreateToastNotifier().Show(toast);
|
||||
await _connection.SendMessageAsync(message);
|
||||
}
|
||||
|
||||
private void ShowSettings(object sender, EventArgs e)
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace FluentTerminal.SystemTray
|
||||
{
|
||||
@@ -33,5 +35,294 @@ namespace FluentTerminal.SystemTray
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Key ExtendVirtualKeyToInputKey(ExtendedVirtualKey key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case ExtendedVirtualKey.Cancel:
|
||||
return Key.Cancel;
|
||||
case ExtendedVirtualKey.Back:
|
||||
return Key.Back;
|
||||
case ExtendedVirtualKey.Tab:
|
||||
return Key.Tab;
|
||||
case ExtendedVirtualKey.Clear:
|
||||
return Key.Clear;
|
||||
case ExtendedVirtualKey.Enter:
|
||||
return Key.Enter;
|
||||
case ExtendedVirtualKey.Shift:
|
||||
return Key.LeftShift;
|
||||
case ExtendedVirtualKey.Menu:
|
||||
return Key.LeftAlt;
|
||||
case ExtendedVirtualKey.Pause:
|
||||
return Key.Pause;
|
||||
case ExtendedVirtualKey.CapitalLock:
|
||||
return Key.CapsLock;
|
||||
case ExtendedVirtualKey.Kana:
|
||||
return Key.KanaMode;
|
||||
case ExtendedVirtualKey.Junja:
|
||||
return Key.JunjaMode;
|
||||
case ExtendedVirtualKey.Final:
|
||||
return Key.FinalMode;
|
||||
case ExtendedVirtualKey.Kanji:
|
||||
return Key.KanjiMode;
|
||||
case ExtendedVirtualKey.Escape:
|
||||
return Key.Escape;
|
||||
case ExtendedVirtualKey.Convert:
|
||||
return Key.ImeConvert;
|
||||
case ExtendedVirtualKey.NonConvert:
|
||||
return Key.ImeNonConvert;
|
||||
case ExtendedVirtualKey.Accept:
|
||||
return Key.ImeAccept;
|
||||
case ExtendedVirtualKey.ModeChange:
|
||||
return Key.ImeModeChange;
|
||||
case ExtendedVirtualKey.Space:
|
||||
return Key.Space;
|
||||
case ExtendedVirtualKey.PageUp:
|
||||
return Key.PageUp;
|
||||
case ExtendedVirtualKey.PageDown:
|
||||
return Key.PageDown;
|
||||
case ExtendedVirtualKey.End:
|
||||
return Key.End;
|
||||
case ExtendedVirtualKey.Home:
|
||||
return Key.Home;
|
||||
case ExtendedVirtualKey.Left:
|
||||
return Key.Left;
|
||||
case ExtendedVirtualKey.Up:
|
||||
return Key.Up;
|
||||
case ExtendedVirtualKey.Right:
|
||||
return Key.Right;
|
||||
case ExtendedVirtualKey.Down:
|
||||
return Key.Down;
|
||||
case ExtendedVirtualKey.Select:
|
||||
return Key.Select;
|
||||
case ExtendedVirtualKey.Print:
|
||||
return Key.Print;
|
||||
case ExtendedVirtualKey.Execute:
|
||||
return Key.Execute;
|
||||
case ExtendedVirtualKey.Snapshot:
|
||||
return Key.Snapshot;
|
||||
case ExtendedVirtualKey.Insert:
|
||||
return Key.Insert;
|
||||
case ExtendedVirtualKey.Delete:
|
||||
return Key.Delete;
|
||||
case ExtendedVirtualKey.Help:
|
||||
return Key.Help;
|
||||
case ExtendedVirtualKey.Number0:
|
||||
return Key.D0;
|
||||
case ExtendedVirtualKey.Number1:
|
||||
return Key.D1;
|
||||
case ExtendedVirtualKey.Number2:
|
||||
return Key.D2;
|
||||
case ExtendedVirtualKey.Number3:
|
||||
return Key.D3;
|
||||
case ExtendedVirtualKey.Number4:
|
||||
return Key.D4;
|
||||
case ExtendedVirtualKey.Number5:
|
||||
return Key.D5;
|
||||
case ExtendedVirtualKey.Number6:
|
||||
return Key.D6;
|
||||
case ExtendedVirtualKey.Number7:
|
||||
return Key.D7;
|
||||
case ExtendedVirtualKey.Number8:
|
||||
return Key.D8;
|
||||
case ExtendedVirtualKey.Number9:
|
||||
return Key.D9;
|
||||
case ExtendedVirtualKey.A:
|
||||
return Key.A;
|
||||
case ExtendedVirtualKey.B:
|
||||
return Key.B;
|
||||
case ExtendedVirtualKey.C:
|
||||
return Key.C;
|
||||
case ExtendedVirtualKey.D:
|
||||
return Key.D;
|
||||
case ExtendedVirtualKey.E:
|
||||
return Key.E;
|
||||
case ExtendedVirtualKey.F:
|
||||
return Key.F;
|
||||
case ExtendedVirtualKey.G:
|
||||
return Key.G;
|
||||
case ExtendedVirtualKey.H:
|
||||
return Key.H;
|
||||
case ExtendedVirtualKey.I:
|
||||
return Key.I;
|
||||
case ExtendedVirtualKey.J:
|
||||
return Key.J;
|
||||
case ExtendedVirtualKey.K:
|
||||
return Key.K;
|
||||
case ExtendedVirtualKey.L:
|
||||
return Key.L;
|
||||
case ExtendedVirtualKey.M:
|
||||
return Key.M;
|
||||
case ExtendedVirtualKey.N:
|
||||
return Key.N;
|
||||
case ExtendedVirtualKey.O:
|
||||
return Key.O;
|
||||
case ExtendedVirtualKey.P:
|
||||
return Key.P;
|
||||
case ExtendedVirtualKey.Q:
|
||||
return Key.Q;
|
||||
case ExtendedVirtualKey.R:
|
||||
return Key.R;
|
||||
case ExtendedVirtualKey.S:
|
||||
return Key.S;
|
||||
case ExtendedVirtualKey.T:
|
||||
return Key.T;
|
||||
case ExtendedVirtualKey.U:
|
||||
return Key.U;
|
||||
case ExtendedVirtualKey.V:
|
||||
return Key.V;
|
||||
case ExtendedVirtualKey.W:
|
||||
return Key.W;
|
||||
case ExtendedVirtualKey.X:
|
||||
return Key.X;
|
||||
case ExtendedVirtualKey.Y:
|
||||
return Key.Y;
|
||||
case ExtendedVirtualKey.Z:
|
||||
return Key.Z;
|
||||
case ExtendedVirtualKey.LeftWindows:
|
||||
return Key.LWin;
|
||||
case ExtendedVirtualKey.RightWindows:
|
||||
return Key.RWin;
|
||||
case ExtendedVirtualKey.Application:
|
||||
return Key.Apps;
|
||||
case ExtendedVirtualKey.Sleep:
|
||||
return Key.Sleep;
|
||||
case ExtendedVirtualKey.NumberPad0:
|
||||
return Key.NumPad0;
|
||||
case ExtendedVirtualKey.NumberPad1:
|
||||
return Key.NumPad1;
|
||||
case ExtendedVirtualKey.NumberPad2:
|
||||
return Key.NumPad2;
|
||||
case ExtendedVirtualKey.NumberPad3:
|
||||
return Key.NumPad3;
|
||||
case ExtendedVirtualKey.NumberPad4:
|
||||
return Key.NumPad4;
|
||||
case ExtendedVirtualKey.NumberPad5:
|
||||
return Key.NumPad5;
|
||||
case ExtendedVirtualKey.NumberPad6:
|
||||
return Key.NumPad6;
|
||||
case ExtendedVirtualKey.NumberPad7:
|
||||
return Key.NumPad7;
|
||||
case ExtendedVirtualKey.NumberPad8:
|
||||
return Key.NumPad8;
|
||||
case ExtendedVirtualKey.NumberPad9:
|
||||
return Key.NumPad9;
|
||||
case ExtendedVirtualKey.Multiply:
|
||||
return Key.Multiply;
|
||||
case ExtendedVirtualKey.Add:
|
||||
return Key.Add;
|
||||
case ExtendedVirtualKey.Separator:
|
||||
return Key.Separator;
|
||||
case ExtendedVirtualKey.Subtract:
|
||||
return Key.Subtract;
|
||||
case ExtendedVirtualKey.Decimal:
|
||||
return Key.Decimal;
|
||||
case ExtendedVirtualKey.Divide:
|
||||
return Key.Divide;
|
||||
case ExtendedVirtualKey.F1:
|
||||
return Key.F1;
|
||||
case ExtendedVirtualKey.F2:
|
||||
return Key.F2;
|
||||
case ExtendedVirtualKey.F3:
|
||||
return Key.F3;
|
||||
case ExtendedVirtualKey.F4:
|
||||
return Key.F4;
|
||||
case ExtendedVirtualKey.F5:
|
||||
return Key.F5;
|
||||
case ExtendedVirtualKey.F6:
|
||||
return Key.F6;
|
||||
case ExtendedVirtualKey.F7:
|
||||
return Key.F7;
|
||||
case ExtendedVirtualKey.F8:
|
||||
return Key.F8;
|
||||
case ExtendedVirtualKey.F9:
|
||||
return Key.F9;
|
||||
case ExtendedVirtualKey.F10:
|
||||
return Key.F10;
|
||||
case ExtendedVirtualKey.F11:
|
||||
return Key.F11;
|
||||
case ExtendedVirtualKey.F12:
|
||||
return Key.F12;
|
||||
case ExtendedVirtualKey.F13:
|
||||
return Key.F13;
|
||||
case ExtendedVirtualKey.F14:
|
||||
return Key.F14;
|
||||
case ExtendedVirtualKey.F15:
|
||||
return Key.F15;
|
||||
case ExtendedVirtualKey.F16:
|
||||
return Key.F16;
|
||||
case ExtendedVirtualKey.F17:
|
||||
return Key.F17;
|
||||
case ExtendedVirtualKey.F18:
|
||||
return Key.F18;
|
||||
case ExtendedVirtualKey.F19:
|
||||
return Key.F19;
|
||||
case ExtendedVirtualKey.F20:
|
||||
return Key.F20;
|
||||
case ExtendedVirtualKey.F21:
|
||||
return Key.F21;
|
||||
case ExtendedVirtualKey.F22:
|
||||
return Key.F22;
|
||||
case ExtendedVirtualKey.F23:
|
||||
return Key.F23;
|
||||
case ExtendedVirtualKey.F24:
|
||||
return Key.F24;
|
||||
case ExtendedVirtualKey.NumberKeyLock:
|
||||
return Key.NumLock;
|
||||
case ExtendedVirtualKey.Scroll:
|
||||
return Key.Scroll;
|
||||
case ExtendedVirtualKey.LeftShift:
|
||||
return Key.LeftShift;
|
||||
case ExtendedVirtualKey.RightShift:
|
||||
return Key.RightShift;
|
||||
case ExtendedVirtualKey.LeftControl:
|
||||
return Key.LeftCtrl;
|
||||
case ExtendedVirtualKey.RightControl:
|
||||
return Key.RightCtrl;
|
||||
case ExtendedVirtualKey.LeftMenu:
|
||||
return Key.LeftAlt;
|
||||
case ExtendedVirtualKey.RightMenu:
|
||||
return Key.RightAlt;
|
||||
case ExtendedVirtualKey.GoBack:
|
||||
return Key.BrowserBack;
|
||||
case ExtendedVirtualKey.GoForward:
|
||||
return Key.BrowserForward;
|
||||
case ExtendedVirtualKey.Refresh:
|
||||
return Key.BrowserRefresh;
|
||||
case ExtendedVirtualKey.Stop:
|
||||
return Key.BrowserStop;
|
||||
case ExtendedVirtualKey.Search:
|
||||
return Key.BrowserSearch;
|
||||
case ExtendedVirtualKey.Favorites:
|
||||
return Key.BrowserFavorites;
|
||||
case ExtendedVirtualKey.GoHome:
|
||||
return Key.BrowserHome;
|
||||
case ExtendedVirtualKey.VolumeMute:
|
||||
return Key.VolumeMute;
|
||||
case ExtendedVirtualKey.VolumeDown:
|
||||
return Key.VolumeDown;
|
||||
case ExtendedVirtualKey.VolumeUp:
|
||||
return Key.VolumeUp;
|
||||
case ExtendedVirtualKey.MediaNext:
|
||||
return Key.MediaNextTrack;
|
||||
case ExtendedVirtualKey.MediaPrevious:
|
||||
return Key.MediaPreviousTrack;
|
||||
case ExtendedVirtualKey.MediaStop:
|
||||
return Key.MediaStop;
|
||||
case ExtendedVirtualKey.MediaPlayPause:
|
||||
return Key.MediaPlayPause;
|
||||
case ExtendedVirtualKey.Plus:
|
||||
return Key.OemPlus;
|
||||
case ExtendedVirtualKey.Comma:
|
||||
return Key.OemComma;
|
||||
case ExtendedVirtualKey.Minus:
|
||||
return Key.OemMinus;
|
||||
case ExtendedVirtualKey.Period:
|
||||
return Key.OemPeriod;
|
||||
default:
|
||||
return Key.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user