Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
05ce19ec8c | ||
|
|
7b2bd59365 | ||
|
|
6a67883777 | ||
|
|
847e1c045a | ||
|
|
e918c5492e | ||
|
|
1aba3d4926 | ||
|
|
5ad51b6bf7 | ||
|
|
72cfe1168f | ||
|
|
5a96a0387b | ||
|
|
00a5b6377d | ||
|
|
f610aa8a0f | ||
|
|
c32342bca8 | ||
|
|
84af36f6bc | ||
|
|
f56465f54a |
No files matched your search
@@ -126,22 +126,22 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoFixture">
|
||||
<Version>4.2.1</Version>
|
||||
<Version>4.4.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="FluentAssertions">
|
||||
<Version>5.3.0</Version>
|
||||
<Version>5.3.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||
<Version>6.1.2</Version>
|
||||
<Version>6.1.5</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Moq">
|
||||
<Version>4.8.2</Version>
|
||||
<Version>4.8.3</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestAdapter">
|
||||
<Version>1.2.1</Version>
|
||||
<Version>1.3.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestFramework">
|
||||
<Version>1.2.1</Version>
|
||||
<Version>1.3.2</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
If="0"
|
||||
Then="Collapsed" />
|
||||
<converters:IntToExtendedVirtualKeyConverter x:Key="IntToExtendedVirtualKeyConverter" />
|
||||
<converters:BackgroundToApplicationThemeConverter x:Key="BackgroundToApplicationThemeConverter" />
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -51,6 +51,9 @@ namespace FluentTerminal.App
|
||||
builder.RegisterType<KeyboardCommandService>().As<IKeyboardCommandService>().InstancePerDependency();
|
||||
builder.RegisterType<MainViewModel>().InstancePerDependency();
|
||||
builder.RegisterType<SettingsViewModel>().InstancePerDependency();
|
||||
builder.RegisterType<ThemeParserFactory>().As<IThemeParserFactory>().SingleInstance();
|
||||
builder.RegisterType<ITermThemeParser>().As<IThemeParser>().SingleInstance();
|
||||
builder.RegisterType<FluentTerminalThemeParser>().As<IThemeParser>().SingleInstance();
|
||||
|
||||
_container = builder.Build();
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using FluentTerminal.App.Utilities;
|
||||
using Microsoft.Toolkit.Uwp.Helpers;
|
||||
using System;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Xaml.Data;
|
||||
|
||||
namespace FluentTerminal.App.Converters
|
||||
{
|
||||
public class BackgroundToApplicationThemeConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
Color color;
|
||||
if (value is string colorString)
|
||||
{
|
||||
color = colorString.ToColor();
|
||||
} else if (value is Color)
|
||||
{
|
||||
color = (Color)value;
|
||||
}
|
||||
|
||||
if (color != null)
|
||||
{
|
||||
return ContrastHelper.GetIdealThemeForBackgroundColor(color);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
CloseButtonText="Cancel"
|
||||
PrimaryButtonText="Start"
|
||||
RequestedTheme="Dark"
|
||||
mc:Ignorable="d">
|
||||
<ComboBox
|
||||
HorizontalAlignment="Stretch"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -17,6 +18,8 @@ namespace FluentTerminal.App.Dialogs
|
||||
Profiles = settingsService.GetShellProfiles();
|
||||
SelectedProfile = Profiles.First();
|
||||
this.InitializeComponent();
|
||||
var currentTheme = settingsService.GetCurrentTheme();
|
||||
RequestedTheme = ContrastHelper.GetIdealThemeForBackgroundColor(currentTheme.Colors.Background);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace FluentTerminal.App.Exceptions
|
||||
{
|
||||
public class ParseThemeException : Exception
|
||||
{
|
||||
public ParseThemeException() : base()
|
||||
{
|
||||
}
|
||||
|
||||
public ParseThemeException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public ParseThemeException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
protected ParseThemeException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,6 +106,7 @@
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Behaviors\MiddleClickBehavior.cs" />
|
||||
<Compile Include="Converters\BackgroundToApplicationThemeConverter.cs" />
|
||||
<Compile Include="Converters\FalseToVisibleConverter.cs" />
|
||||
<Compile Include="Converters\IntToExtendedVirtualKeyConverter.cs" />
|
||||
<Compile Include="Converters\IntToVisibilityConverter.cs" />
|
||||
@@ -115,10 +116,16 @@
|
||||
<Compile Include="Dialogs\ShellProfileSelectionDialog.xaml.cs">
|
||||
<DependentUpon>ShellProfileSelectionDialog.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Exceptions\ParseThemeException.cs" />
|
||||
<Compile Include="Services\IDialogService.cs" />
|
||||
<Compile Include="Services\Implementation\DialogService.cs" />
|
||||
<Compile Include="Services\Implementation\FluentTerminalThemeParser.cs" />
|
||||
<Compile Include="Services\Implementation\KeyboardCommandService.cs" />
|
||||
<Compile Include="Services\IKeyboardCommandService.cs" />
|
||||
<Compile Include="Services\Implementation\ITermThemeParser.cs" />
|
||||
<Compile Include="Services\Implementation\ThemeParserFactory.cs" />
|
||||
<Compile Include="Services\IThemeParser.cs" />
|
||||
<Compile Include="Services\IThemeParserFactory.cs" />
|
||||
<Compile Include="Utilities\ApplicationDataContainerExtensions.cs" />
|
||||
<Compile Include="Services\IDefaultValueProvider.cs" />
|
||||
<Compile Include="Services\Implementation\DefaultValueProvider.cs" />
|
||||
@@ -127,6 +134,9 @@
|
||||
<Compile Include="Services\ISettingsService.cs" />
|
||||
<Compile Include="Services\ITrayProcessCommunicationService.cs" />
|
||||
<Compile Include="Utilities\ColorExtensions.cs" />
|
||||
<Compile Include="Utilities\ContrastHelper.cs" />
|
||||
<Compile Include="Utilities\EnumHelper.cs" />
|
||||
<Compile Include="Utilities\TerminalThemeContractResolver.cs" />
|
||||
<Compile Include="ViewModels\MainViewModel.cs" />
|
||||
<Compile Include="ViewModels\SettingsViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\GeneralPageViewModel.cs" />
|
||||
@@ -322,26 +332,29 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac">
|
||||
<Version>4.8.0</Version>
|
||||
<Version>4.8.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||
<Version>6.0.6</Version>
|
||||
<Version>6.1.5</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Toolkit.Uwp.UI">
|
||||
<Version>2.1.1</Version>
|
||||
<Version>3.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Toolkit.Uwp.UI.Controls">
|
||||
<Version>2.1.1</Version>
|
||||
<Version>3.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Uwp.Managed">
|
||||
<Version>2.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MvvmLightLibs">
|
||||
<Version>5.3.0</Version>
|
||||
<Version>5.4.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json">
|
||||
<Version>11.0.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="PListNet">
|
||||
<Version>2.0.3</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Win2D.uwp">
|
||||
<Version>1.21.0</Version>
|
||||
</PackageReference>
|
||||
|
||||
@@ -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.10.0" />
|
||||
<Identity Name="53621FSApps.FluentTerminal" Publisher="CN=BDC72197-B634-438A-B863-16DCB7D90C85" Version="0.1.11.0" />
|
||||
<mp:PhoneIdentity PhoneProductId="f7225014-f405-4342-ad2e-ebf6ac60ea2c" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
|
||||
<Properties>
|
||||
<DisplayName>Fluent Terminal</DisplayName>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -9,7 +10,7 @@ namespace FluentTerminal.App.Services
|
||||
IEnumerable<ShellProfile> GetPreinstalledShellProfiles();
|
||||
Guid GetDefaultShellProfileId();
|
||||
TerminalOptions GetDefaultTerminalOptions();
|
||||
KeyBindings GetDefaultKeyBindings();
|
||||
ICollection<KeyBinding> GetDefaultKeyBindings(Command command);
|
||||
ApplicationSettings GetDefaultApplicationSettings();
|
||||
Guid GetDefaultThemeId();
|
||||
IEnumerable<TerminalTheme> GetPreInstalledThemes();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -9,7 +10,7 @@ namespace FluentTerminal.App.Services
|
||||
event EventHandler<Guid> CurrentThemeChanged;
|
||||
event EventHandler<TerminalOptions> TerminalOptionsChanged;
|
||||
event EventHandler<ApplicationSettings> ApplicationSettingsChanged;
|
||||
event EventHandler<KeyBindings> KeyBindingsChanged;
|
||||
event EventHandler KeyBindingsChanged;
|
||||
|
||||
Guid GetDefaultShellProfileId();
|
||||
ShellProfile GetDefaultShellProfile();
|
||||
@@ -25,8 +26,9 @@ namespace FluentTerminal.App.Services
|
||||
ApplicationSettings GetApplicationSettings();
|
||||
void SaveApplicationSettings(ApplicationSettings applicationSettings);
|
||||
|
||||
KeyBindings GetKeyBindings();
|
||||
void SaveKeyBindings(KeyBindings keyBindings);
|
||||
IDictionary<Command, ICollection<KeyBinding>> GetKeyBindings();
|
||||
void SaveKeyBindings(Command command, ICollection<KeyBinding> keyBindings);
|
||||
void ResetKeyBindings();
|
||||
|
||||
TerminalTheme GetCurrentTheme();
|
||||
Guid GetCurrentThemeId();
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using FluentTerminal.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public interface IThemeParser
|
||||
{
|
||||
IEnumerable<string> SupportedFileTypes { get; }
|
||||
|
||||
Task<TerminalTheme> Parse(StorageFile themeFile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public interface IThemeParserFactory
|
||||
{
|
||||
IEnumerable<string> SupportedFileTypes { get; }
|
||||
|
||||
IThemeParser GetParser(StorageFile themeFile);
|
||||
}
|
||||
}
|
||||
@@ -14,114 +14,17 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
ConfirmClosingTabs = false,
|
||||
ConfirmClosingWindows = false,
|
||||
UnderlineSelectedTab = false,
|
||||
NewTerminalLocation = NewTerminalLocation.Tab
|
||||
};
|
||||
}
|
||||
|
||||
public KeyBindings GetDefaultKeyBindings()
|
||||
public ICollection<KeyBinding> GetDefaultKeyBindings(Command command)
|
||||
{
|
||||
return new KeyBindings
|
||||
switch (command)
|
||||
{
|
||||
NewTab = new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NewTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.T
|
||||
}
|
||||
},
|
||||
ConfigurableNewTab = new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.ConfigurableNewTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = true,
|
||||
Key = (int)VirtualKey.T
|
||||
}
|
||||
},
|
||||
CloseTab = new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.CloseTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.W
|
||||
}
|
||||
},
|
||||
NextTab = new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NextTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.Tab
|
||||
}
|
||||
},
|
||||
PreviousTab = new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.PreviousTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = true,
|
||||
Key = (int)VirtualKey.Tab
|
||||
}
|
||||
},
|
||||
NewWindow = new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NewWindow,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.N
|
||||
}
|
||||
},
|
||||
ShowSettings = new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.ShowSettings,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = 188 // comma
|
||||
}
|
||||
},
|
||||
Copy = new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.Copy,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.C
|
||||
}
|
||||
},
|
||||
Paste = new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.Paste,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.V
|
||||
}
|
||||
},
|
||||
ToggleWindow = new List<KeyBinding>
|
||||
case Command.ToggleWindow:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
@@ -131,8 +34,127 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.Scroll
|
||||
}
|
||||
},
|
||||
Search = new List<KeyBinding>
|
||||
};
|
||||
|
||||
case Command.NextTab:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NextTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.Tab
|
||||
}
|
||||
};
|
||||
|
||||
case Command.PreviousTab:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.PreviousTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = true,
|
||||
Key = (int)VirtualKey.Tab
|
||||
}
|
||||
};
|
||||
|
||||
case Command.NewTab:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NewTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.T
|
||||
}
|
||||
};
|
||||
|
||||
case Command.ConfigurableNewTab:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.ConfigurableNewTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = true,
|
||||
Key = (int)VirtualKey.T
|
||||
}
|
||||
};
|
||||
|
||||
case Command.CloseTab:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.CloseTab,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.W
|
||||
}
|
||||
};
|
||||
|
||||
case Command.NewWindow:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.NewWindow,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.N
|
||||
}
|
||||
};
|
||||
|
||||
case Command.ShowSettings:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.ShowSettings,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)ExtendedVirtualKey.Comma
|
||||
}
|
||||
};
|
||||
|
||||
case Command.Copy:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.Copy,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.C
|
||||
}
|
||||
};
|
||||
|
||||
case Command.Paste:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.Paste,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.V
|
||||
}
|
||||
};
|
||||
|
||||
case Command.Search:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
@@ -142,8 +164,49 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.F
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
case Command.ToggleFullScreen:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.ToggleFullScreen,
|
||||
Ctrl = false,
|
||||
Alt = true,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.Enter
|
||||
}
|
||||
};
|
||||
|
||||
case Command.SelectAll:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.SelectAll,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.A
|
||||
}
|
||||
};
|
||||
|
||||
case Command.Clear:
|
||||
return new List<KeyBinding>
|
||||
{
|
||||
new KeyBinding
|
||||
{
|
||||
Command = Command.Clear,
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.L
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Guid GetDefaultShellProfileId()
|
||||
@@ -161,7 +224,8 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
ScrollBarStyle = ScrollBarStyle.Hidden,
|
||||
FontFamily = "Consolas",
|
||||
FontSize = 13,
|
||||
BackgroundOpacity = 0.8
|
||||
BackgroundOpacity = 0.8,
|
||||
ScrollBackLimit = 1000
|
||||
};
|
||||
}
|
||||
|
||||
@@ -257,7 +321,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Background = "#012456",
|
||||
Cursor = "#fedba9",
|
||||
CursorAccent = "#000000",
|
||||
Selection = "#fedba9"
|
||||
Selection = "rgba(254, 219, 169, 0.3)"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -293,7 +357,39 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
}
|
||||
};
|
||||
|
||||
return new[] { defaultXterm, powerShell, homebrew };
|
||||
var tomorrow = new TerminalTheme
|
||||
{
|
||||
Id = Guid.Parse("0cbbf805-fa86-4be5-ac51-75f3054dcc3a"),
|
||||
Author = "Chris Kempson",
|
||||
Name = "Tomorrow",
|
||||
PreInstalled = true,
|
||||
Colors = new TerminalColors
|
||||
{
|
||||
Foreground = "#4D4D4C",
|
||||
Background = "#FFFFFF",
|
||||
Cursor = "#4D4D4C",
|
||||
CursorAccent = "#FFFFFF",
|
||||
Selection = "rgba(214, 214, 214, 0.5)",
|
||||
Black = "#000000",
|
||||
Red = "#C82829",
|
||||
Green = "#718C00",
|
||||
Yellow = "#EAB700",
|
||||
Blue = "#4271AE",
|
||||
Magenta = "#8959A8",
|
||||
Cyan = "#3E999F",
|
||||
White = "#FFFFFF",
|
||||
BrightBlack = "#000000",
|
||||
BrightRed = "#C82829",
|
||||
BrightGreen = "#718C00",
|
||||
BrightYellow = "#EAB700",
|
||||
BrightBlue = "#4271AE",
|
||||
BrightMagenta = "#8959A8",
|
||||
BrightCyan = "#3E999F",
|
||||
BrightWhite = "#FFFFFF"
|
||||
}
|
||||
};
|
||||
|
||||
return new[] { defaultXterm, powerShell, homebrew, tomorrow };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using FluentTerminal.Models;
|
||||
using Newtonsoft.Json;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
public class FluentTerminalThemeParser : IThemeParser
|
||||
{
|
||||
public IEnumerable<string> SupportedFileTypes { get; } = new string[] { ".flutecolors" };
|
||||
|
||||
public async Task<TerminalTheme> Parse(StorageFile themeFile)
|
||||
{
|
||||
var content = await FileIO.ReadTextAsync(themeFile);
|
||||
|
||||
var theme = JsonConvert.DeserializeObject<TerminalTheme>(content);
|
||||
|
||||
theme.PreInstalled = false;
|
||||
theme.Id = Guid.NewGuid();
|
||||
|
||||
return theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
using FluentTerminal.App.Exceptions;
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.Models;
|
||||
using PListNet;
|
||||
using PListNet.Nodes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.UI;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
public class ITermThemeParser : IThemeParser
|
||||
{
|
||||
private const byte Opacity30Percent = 77;
|
||||
|
||||
public IEnumerable<string> SupportedFileTypes { get; } = new string[] { ".itermcolors" };
|
||||
|
||||
private static class ITermThemeKeys
|
||||
{
|
||||
public const string Ansi0Color = "Ansi 0 Color";
|
||||
public const string Ansi1Color = "Ansi 1 Color";
|
||||
public const string Ansi2Color = "Ansi 2 Color";
|
||||
public const string Ansi3Color = "Ansi 3 Color";
|
||||
public const string Ansi4Color = "Ansi 4 Color";
|
||||
public const string Ansi5Color = "Ansi 5 Color";
|
||||
public const string Ansi6Color = "Ansi 6 Color";
|
||||
public const string Ansi7Color = "Ansi 7 Color";
|
||||
public const string Ansi8Color = "Ansi 8 Color";
|
||||
public const string Ansi9Color = "Ansi 9 Color";
|
||||
public const string Ansi10Color = "Ansi 10 Color";
|
||||
public const string Ansi11Color = "Ansi 11 Color";
|
||||
public const string Ansi12Color = "Ansi 12 Color";
|
||||
public const string Ansi13Color = "Ansi 13 Color";
|
||||
public const string Ansi14Color = "Ansi 14 Color";
|
||||
public const string Ansi15Color = "Ansi 15 Color";
|
||||
|
||||
public const string BackgroundColor = "Background Color";
|
||||
public const string BoldColor = "Bold Color";
|
||||
public const string CursorColor = "Cursor Color";
|
||||
public const string CursorTextColor = "Cursor Text Color";
|
||||
public const string ForegroundColor = "Foreground Color";
|
||||
public const string SelectedTextColor = "Selected Text Color";
|
||||
public const string SelectionColor = "Selection Color";
|
||||
}
|
||||
|
||||
private static class ITermThemeColorKeys
|
||||
{
|
||||
public const string BlueComponent = "Blue Component";
|
||||
public const string GreenComponent = "Green Component";
|
||||
public const string RedComponent = "Red Component";
|
||||
}
|
||||
|
||||
public async Task<TerminalTheme> Parse(StorageFile themeFile)
|
||||
{
|
||||
var stream = await themeFile.OpenStreamForReadAsync().ConfigureAwait(false);
|
||||
var node = PList.Load(stream) as DictionaryNode ?? throw new ParseThemeException("Root node was not a dictionary.");
|
||||
|
||||
return new TerminalTheme
|
||||
{
|
||||
Name = Path.GetFileNameWithoutExtension(themeFile.Name),
|
||||
Colors = GetColors(node),
|
||||
Id = Guid.NewGuid(),
|
||||
PreInstalled = false
|
||||
};
|
||||
}
|
||||
|
||||
private TerminalColors GetColors(DictionaryNode themeDictionary)
|
||||
{
|
||||
return new TerminalColors
|
||||
{
|
||||
Background = GetColorString(themeDictionary[ITermThemeKeys.BackgroundColor]),
|
||||
Foreground = GetColorString(themeDictionary[ITermThemeKeys.ForegroundColor]),
|
||||
Cursor = GetColorString(themeDictionary[ITermThemeKeys.CursorColor]),
|
||||
CursorAccent = GetColorString(themeDictionary[ITermThemeKeys.CursorTextColor]),
|
||||
Selection = GetColorString(themeDictionary[ITermThemeKeys.SelectionColor], Opacity30Percent),
|
||||
Black = GetColorString(themeDictionary[ITermThemeKeys.Ansi0Color]),
|
||||
Red = GetColorString(themeDictionary[ITermThemeKeys.Ansi1Color]),
|
||||
Green = GetColorString(themeDictionary[ITermThemeKeys.Ansi2Color]),
|
||||
Yellow = GetColorString(themeDictionary[ITermThemeKeys.Ansi3Color]),
|
||||
Blue = GetColorString(themeDictionary[ITermThemeKeys.Ansi4Color]),
|
||||
Magenta = GetColorString(themeDictionary[ITermThemeKeys.Ansi5Color]),
|
||||
Cyan = GetColorString(themeDictionary[ITermThemeKeys.Ansi6Color]),
|
||||
White = GetColorString(themeDictionary[ITermThemeKeys.Ansi7Color]),
|
||||
BrightBlack = GetColorString(themeDictionary[ITermThemeKeys.Ansi8Color]),
|
||||
BrightRed = GetColorString(themeDictionary[ITermThemeKeys.Ansi9Color]),
|
||||
BrightGreen = GetColorString(themeDictionary[ITermThemeKeys.Ansi10Color]),
|
||||
BrightYellow = GetColorString(themeDictionary[ITermThemeKeys.Ansi11Color]),
|
||||
BrightBlue = GetColorString(themeDictionary[ITermThemeKeys.Ansi12Color]),
|
||||
BrightMagenta = GetColorString(themeDictionary[ITermThemeKeys.Ansi13Color]),
|
||||
BrightCyan = GetColorString(themeDictionary[ITermThemeKeys.Ansi14Color]),
|
||||
BrightWhite = GetColorString(themeDictionary[ITermThemeKeys.Ansi15Color]),
|
||||
};
|
||||
}
|
||||
|
||||
private string GetColorString(PNode colorNode, byte alpha = Byte.MaxValue)
|
||||
{
|
||||
var dictionaryNode = colorNode as DictionaryNode ?? throw new ParseThemeException("Color node was not a dictionary");
|
||||
|
||||
var red = dictionaryNode[ITermThemeColorKeys.RedComponent] as RealNode ?? throw new ParseThemeException("Red node value was not a real number");
|
||||
var green = dictionaryNode[ITermThemeColorKeys.GreenComponent] as RealNode ?? throw new ParseThemeException("Green node value was not a real number");
|
||||
var blue = dictionaryNode[ITermThemeColorKeys.BlueComponent] as RealNode ?? throw new ParseThemeException("Blue node value was not a real number");
|
||||
|
||||
var color = Color.FromArgb(alpha, GetByteValue(red), GetByteValue(green), GetByteValue(blue));
|
||||
|
||||
if (alpha == byte.MaxValue)
|
||||
{
|
||||
return color.ToColorString(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
return color.ToColorString(true);
|
||||
}
|
||||
}
|
||||
|
||||
private byte GetByteValue(RealNode node)
|
||||
{
|
||||
var doubleValue = node.Value * Byte.MaxValue;
|
||||
|
||||
return Convert.ToByte(doubleValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using Newtonsoft.Json;
|
||||
using Windows.Storage;
|
||||
|
||||
@@ -11,6 +13,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
internal class SettingsService : ISettingsService
|
||||
{
|
||||
public const string ThemesContainerName = "Themes";
|
||||
public const string KeyBindingsContainerName = "KeyBindings";
|
||||
public const string ShellProfilesContainerName = "ShellProfiles";
|
||||
public const string CurrentThemeKey = "CurrentTheme";
|
||||
public const string DefaultShellProfileKey = "DefaultShellProfile";
|
||||
@@ -18,13 +21,14 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
private readonly IDefaultValueProvider _defaultValueProvider;
|
||||
private readonly ApplicationDataContainer _localSettings;
|
||||
private readonly ApplicationDataContainer _themes;
|
||||
private readonly ApplicationDataContainer _keyBindings;
|
||||
private readonly ApplicationDataContainer _shellProfiles;
|
||||
private readonly ApplicationDataContainer _roamingSettings;
|
||||
|
||||
public event EventHandler<Guid> CurrentThemeChanged;
|
||||
public event EventHandler<TerminalOptions> TerminalOptionsChanged;
|
||||
public event EventHandler<ApplicationSettings> ApplicationSettingsChanged;
|
||||
public event EventHandler<KeyBindings> KeyBindingsChanged;
|
||||
public event EventHandler KeyBindingsChanged;
|
||||
|
||||
public SettingsService(IDefaultValueProvider defaultValueProvider)
|
||||
{
|
||||
@@ -33,6 +37,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
_roamingSettings = ApplicationData.Current.RoamingSettings;
|
||||
|
||||
_themes = _roamingSettings.CreateContainer(ThemesContainerName, ApplicationDataCreateDisposition.Always);
|
||||
_keyBindings = _roamingSettings.CreateContainer(KeyBindingsContainerName, ApplicationDataCreateDisposition.Always);
|
||||
_shellProfiles = _roamingSettings.CreateContainer(ShellProfilesContainerName, ApplicationDataCreateDisposition.Always);
|
||||
|
||||
foreach (var theme in _defaultValueProvider.GetPreInstalledThemes())
|
||||
@@ -115,28 +120,34 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
ApplicationSettingsChanged?.Invoke(this, applicationSettings);
|
||||
}
|
||||
|
||||
public KeyBindings GetKeyBindings()
|
||||
public IDictionary<Command, ICollection<KeyBinding>> GetKeyBindings()
|
||||
{
|
||||
var defaults = _defaultValueProvider.GetDefaultKeyBindings();
|
||||
var keyBindings = _roamingSettings.ReadValueFromJson<KeyBindings>(nameof(KeyBindings), null) ?? defaults;
|
||||
|
||||
if (keyBindings.ConfigurableNewTab == null)
|
||||
var keyBindings = new Dictionary<Command, ICollection<KeyBinding>>();
|
||||
foreach (var value in Enum.GetValues(typeof(Command)))
|
||||
{
|
||||
keyBindings.ConfigurableNewTab = defaults.ConfigurableNewTab;
|
||||
}
|
||||
|
||||
if (keyBindings.Search == null)
|
||||
{
|
||||
keyBindings.Search = defaults.Search;
|
||||
var command = (Command)value;
|
||||
keyBindings.Add(command, _keyBindings.ReadValueFromJson<Collection<KeyBinding>>(command.ToString(), null) ?? _defaultValueProvider.GetDefaultKeyBindings(command));
|
||||
}
|
||||
|
||||
return keyBindings;
|
||||
}
|
||||
|
||||
public void SaveKeyBindings(KeyBindings keyBindings)
|
||||
public void SaveKeyBindings(Command command, ICollection<KeyBinding> keyBindings)
|
||||
{
|
||||
_keyBindings.WriteValueAsJson(command.ToString(), keyBindings);
|
||||
_roamingSettings.WriteValueAsJson(nameof(KeyBindings), keyBindings);
|
||||
KeyBindingsChanged?.Invoke(this, keyBindings);
|
||||
KeyBindingsChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public void ResetKeyBindings()
|
||||
{
|
||||
foreach (var value in Enum.GetValues(typeof(Command)))
|
||||
{
|
||||
var command = (Command)value;
|
||||
_keyBindings.WriteValueAsJson(command.ToString(), _defaultValueProvider.GetDefaultKeyBindings(command));
|
||||
}
|
||||
|
||||
KeyBindingsChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public Guid GetDefaultShellProfileId()
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
public class ThemeParserFactory : IThemeParserFactory
|
||||
{
|
||||
private IEnumerable<IThemeParser> _parsers;
|
||||
|
||||
public IEnumerable<string> SupportedFileTypes { get; }
|
||||
|
||||
public ThemeParserFactory(IEnumerable<IThemeParser> parsers)
|
||||
{
|
||||
_parsers = parsers;
|
||||
SupportedFileTypes = _parsers.SelectMany(p => p.SupportedFileTypes);
|
||||
}
|
||||
|
||||
public IThemeParser GetParser(StorageFile themeFile)
|
||||
{
|
||||
return _parsers.FirstOrDefault(p => p.SupportedFileTypes.Contains(themeFile.FileType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using FluentTerminal.Models.Requests;
|
||||
using FluentTerminal.Models.Responses;
|
||||
using Newtonsoft.Json;
|
||||
@@ -63,7 +64,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
|
||||
public Task UpdateToggleWindowKeyBindings()
|
||||
{
|
||||
var keyBindings = _settingsService.GetKeyBindings().ToggleWindow;
|
||||
var keyBindings = _settingsService.GetKeyBindings()[Command.ToggleWindow];
|
||||
|
||||
var request = new SetToggleWindowKeyBindingsRequest
|
||||
{
|
||||
|
||||
@@ -8,11 +8,6 @@
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<SolidColorBrush x:Key="TitleBarHoverBackgroundColor" Color="#18FFFFFF" />
|
||||
|
||||
<SolidColorBrush x:Key="TitleBarPressedBackgroundColor" Color="#30FFFFFF" />
|
||||
<SolidColorBrush x:Key="DisabledForegroundColor" Color="#80FFFFFF" />
|
||||
|
||||
<Style x:Key="TitleBarButtonStyle" TargetType="Button">
|
||||
<Setter Property="Background" Value="Transparent" />
|
||||
<Setter Property="BorderThickness" Value="0" />
|
||||
@@ -51,14 +46,14 @@
|
||||
<VisualState x:Name="PointerOver">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TitleBarHoverBackgroundColor}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemListLowColor}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Pressed">
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="RootGrid" Storyboard.TargetProperty="Background">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource TitleBarPressedBackgroundColor}" />
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemListMediumColor}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
@@ -101,247 +96,4 @@
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ThemeAppBarButtonStyle" TargetType="AppBarButton">
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource AppBarButtonBorderBrush}" />
|
||||
<Setter Property="HorizontalAlignment" Value="Left" />
|
||||
<Setter Property="VerticalAlignment" Value="Top" />
|
||||
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
<Setter Property="Width" Value="68" />
|
||||
<Setter Property="UseSystemFocusVisuals" Value="True" />
|
||||
<Setter Property="AllowFocusOnInteraction" Value="False" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="AppBarButton">
|
||||
<Grid
|
||||
x:Name="Root"
|
||||
MinWidth="{TemplateBinding MinWidth}"
|
||||
MaxWidth="{TemplateBinding MaxWidth}"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}">
|
||||
<Grid x:Name="ContentRoot" MinHeight="{ThemeResource AppBarThemeMinHeight}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Viewbox
|
||||
x:Name="ContentViewbox"
|
||||
Height="20"
|
||||
Margin="0,14,0,4"
|
||||
HorizontalAlignment="Stretch"
|
||||
AutomationProperties.AccessibilityView="Raw">
|
||||
<ContentPresenter
|
||||
x:Name="Content"
|
||||
Height="20"
|
||||
Content="{TemplateBinding Icon}"
|
||||
Foreground="{TemplateBinding Foreground}" />
|
||||
</Viewbox>
|
||||
<TextBlock
|
||||
x:Name="TextLabel"
|
||||
Grid.Row="1"
|
||||
Margin="2,0,2,6"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
FontFamily="{TemplateBinding FontFamily}"
|
||||
FontSize="12"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
Text="{TemplateBinding Label}"
|
||||
TextAlignment="Center"
|
||||
TextWrapping="Wrap" />
|
||||
<TextBlock
|
||||
x:Name="OverflowTextLabel"
|
||||
Margin="12,0,12,0"
|
||||
Padding="0,5,0,7"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
AutomationProperties.AccessibilityView="Raw"
|
||||
FontFamily="{TemplateBinding FontFamily}"
|
||||
FontSize="15"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
Text="{TemplateBinding Label}"
|
||||
TextAlignment="Left"
|
||||
TextTrimming="Clip"
|
||||
TextWrapping="NoWrap"
|
||||
Visibility="Collapsed" />
|
||||
</Grid>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="ApplicationViewStates">
|
||||
<VisualState x:Name="FullSize" />
|
||||
<VisualState x:Name="Compact">
|
||||
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="LabelOnRight">
|
||||
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentViewbox" Storyboard.TargetProperty="Margin">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="12,14,0,14" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="MinHeight">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarThemeCompactHeight}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="(Grid.Row)">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="0" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="(Grid.Column)">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="1" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="TextAlignment">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Left" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Margin">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="8,15,12,17" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="LabelCollapsed">
|
||||
|
||||
<Storyboard>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentRoot" Storyboard.TargetProperty="MinHeight">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarThemeCompactHeight}" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextLabel" Storyboard.TargetProperty="Visibility">
|
||||
<DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
|
||||
</ObjectAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Overflow">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ContentRoot.MinHeight" Value="0" />
|
||||
<Setter Target="ContentViewbox.Visibility" Value="Collapsed" />
|
||||
<Setter Target="TextLabel.Visibility" Value="Collapsed" />
|
||||
<Setter Target="OverflowTextLabel.Visibility" Value="Visible" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="OverflowWithToggleButtons">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ContentRoot.MinHeight" Value="0" />
|
||||
<Setter Target="ContentViewbox.Visibility" Value="Collapsed" />
|
||||
<Setter Target="TextLabel.Visibility" Value="Collapsed" />
|
||||
<Setter Target="OverflowTextLabel.Visibility" Value="Visible" />
|
||||
<Setter Target="OverflowTextLabel.Margin" Value="38,0,12,0" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="OverflowWithMenuIcons">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ContentRoot.MinHeight" Value="0" />
|
||||
<Setter Target="ContentViewbox.HorizontalAlignment" Value="Left" />
|
||||
<Setter Target="ContentViewbox.VerticalAlignment" Value="Center" />
|
||||
<Setter Target="ContentViewbox.Width" Value="16" />
|
||||
<Setter Target="ContentViewbox.Height" Value="16" />
|
||||
<Setter Target="ContentViewbox.Margin" Value="12,0,12,0" />
|
||||
<Setter Target="TextLabel.Visibility" Value="Collapsed" />
|
||||
<Setter Target="OverflowTextLabel.Visibility" Value="Visible" />
|
||||
<Setter Target="OverflowTextLabel.Margin" Value="38,0,12,0" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="OverflowWithToggleButtonsAndMenuIcons">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="ContentRoot.MinHeight" Value="0" />
|
||||
<Setter Target="ContentViewbox.HorizontalAlignment" Value="Left" />
|
||||
<Setter Target="ContentViewbox.VerticalAlignment" Value="Center" />
|
||||
<Setter Target="ContentViewbox.Width" Value="16" />
|
||||
<Setter Target="ContentViewbox.Height" Value="16" />
|
||||
<Setter Target="ContentViewbox.Margin" Value="38,0,12,0" />
|
||||
<Setter Target="TextLabel.Visibility" Value="Collapsed" />
|
||||
<Setter Target="OverflowTextLabel.Visibility" Value="Visible" />
|
||||
<Setter Target="OverflowTextLabel.Margin" Value="76,0,12,0" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal">
|
||||
<Storyboard>
|
||||
<PointerUpThemeAnimation Storyboard.TargetName="OverflowTextLabel" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="PointerOver">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="Root.Background" Value="{StaticResource TitleBarHoverBackgroundColor}" />
|
||||
<Setter Target="Root.BorderBrush" Value="{ThemeResource AppBarButtonBorderBrushPointerOver}" />
|
||||
</VisualState.Setters>
|
||||
|
||||
<Storyboard>
|
||||
<PointerUpThemeAnimation Storyboard.TargetName="OverflowTextLabel" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="Pressed">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="Root.Background" Value="{StaticResource TitleBarPressedBackgroundColor}" />
|
||||
<Setter Target="Root.BorderBrush" Value="{ThemeResource AppBarButtonBorderBrushPressed}" />
|
||||
</VisualState.Setters>
|
||||
|
||||
<Storyboard>
|
||||
<PointerDownThemeAnimation Storyboard.TargetName="OverflowTextLabel" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
|
||||
<VisualState x:Name="Disabled">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="Root.Background" Value="Transparent" />
|
||||
<Setter Target="Root.BorderBrush" Value="{ThemeResource AppBarButtonBorderBrushDisabled}" />
|
||||
<Setter Target="Content.Foreground" Value="{StaticResource DisabledForegroundColor}" />
|
||||
<Setter Target="TextLabel.Foreground" Value="{StaticResource DisabledForegroundColor}" />
|
||||
<Setter Target="OverflowTextLabel.Foreground" Value="{StaticResource DisabledForegroundColor}" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="OverflowNormal">
|
||||
|
||||
<Storyboard>
|
||||
<PointerUpThemeAnimation Storyboard.TargetName="ContentRoot" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="OverflowPointerOver">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="Root.Background" Value="{StaticResource TitleBarHoverBackgroundColor}" />
|
||||
<Setter Target="Root.BorderBrush" Value="{ThemeResource AppBarButtonBorderBrushPointerOver}" />
|
||||
</VisualState.Setters>
|
||||
|
||||
<Storyboard>
|
||||
<PointerUpThemeAnimation Storyboard.TargetName="ContentRoot" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="OverflowPressed">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="Root.Background" Value="{StaticResource TitleBarPressedBackgroundColor}" />
|
||||
<Setter Target="Root.BorderBrush" Value="{ThemeResource AppBarButtonBorderBrushPressed}" />
|
||||
</VisualState.Setters>
|
||||
|
||||
<Storyboard>
|
||||
<PointerDownThemeAnimation Storyboard.TargetName="ContentRoot" />
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="InputModeStates">
|
||||
<VisualState x:Name="InputModeDefault" />
|
||||
<VisualState x:Name="TouchInputMode">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="OverflowTextLabel.Padding" Value="0,11,0,13" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
<VisualState x:Name="GameControllerInputMode">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="OverflowTextLabel.Padding" Value="0,11,0,13" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
@@ -0,0 +1,75 @@
|
||||
using Microsoft.Toolkit.Uwp.Helpers;
|
||||
using Windows.UI;
|
||||
using Windows.UI.ViewManagement;
|
||||
using Windows.UI.Xaml;
|
||||
|
||||
namespace FluentTerminal.App.Utilities
|
||||
{
|
||||
public static class ContrastHelper
|
||||
{
|
||||
public static ElementTheme GetIdealThemeForBackgroundColor(string color)
|
||||
{
|
||||
return GetIdealThemeForBackgroundColor(color.ToColor());
|
||||
}
|
||||
|
||||
public static ElementTheme GetIdealThemeForBackgroundColor(Color color)
|
||||
{
|
||||
if (((color.R * 0.299) + (color.G * 0.587) + (color.B * 0.114)) > 186)
|
||||
{
|
||||
return ElementTheme.Light;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ElementTheme.Dark;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetTitleBarButtonsForTheme(ElementTheme theme)
|
||||
{
|
||||
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
|
||||
|
||||
titleBar.ButtonBackgroundColor = Colors.Transparent;
|
||||
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
|
||||
|
||||
titleBar.ButtonForegroundColor = GetColor("SystemBaseHighColor", theme);
|
||||
titleBar.ButtonInactiveForegroundColor = GetColor("SystemBaseHighColor", theme);
|
||||
titleBar.ButtonHoverForegroundColor = GetColor("SystemBaseHighColor", theme);
|
||||
titleBar.ButtonPressedForegroundColor = GetColor("SystemBaseHighColor", theme);
|
||||
|
||||
titleBar.ButtonHoverBackgroundColor = GetColor("SystemListLowColor", theme);
|
||||
titleBar.ButtonPressedBackgroundColor = GetColor("SystemListMediumColor", theme);
|
||||
}
|
||||
|
||||
private static Color? GetColor(string name, ElementTheme theme)
|
||||
{
|
||||
if (theme == ElementTheme.Light)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "SystemBaseHighColor":
|
||||
return new Color { A = 0xFF, R = 0x00, G = 0x00, B = 0x00 };
|
||||
case "SystemListLowColor":
|
||||
return new Color { A = 0x19, R = 0x00, G = 0x00, B = 0x00 };
|
||||
case "SystemListMediumColor":
|
||||
return new Color { A = 0x33, R = 0x00, G = 0x00, B = 0x00 };
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
case "SystemBaseHighColor":
|
||||
return new Color { A = 0xFF, R = 0xFF, G = 0xFF, B = 0xFF };
|
||||
case "SystemListLowColor":
|
||||
return new Color { A = 0x19, R = 0xFF, G = 0xFF, B = 0xFF };
|
||||
case "SystemListMediumColor":
|
||||
return new Color { A = 0x33, R = 0xFF, G = 0xFF, B = 0xFF };
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace FluentTerminal.App.Utilities
|
||||
{
|
||||
public static class EnumHelper
|
||||
{
|
||||
public static string GetEnumDescription(Enum value)
|
||||
{
|
||||
var fieldInfo = value.GetType().GetField(value.ToString());
|
||||
|
||||
DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||
|
||||
if (attributes?.Length > 0)
|
||||
{
|
||||
return attributes[0].Description;
|
||||
}
|
||||
return value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using FluentTerminal.Models;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System.Reflection;
|
||||
|
||||
namespace FluentTerminal.App.Utilities
|
||||
{
|
||||
public class TerminalThemeContractResolver : DefaultContractResolver
|
||||
{
|
||||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
|
||||
{
|
||||
JsonProperty property = base.CreateProperty(member, memberSerialization);
|
||||
|
||||
if (property.DeclaringType == typeof(TerminalTheme) && property.PropertyName == nameof(TerminalTheme.PreInstalled))
|
||||
{
|
||||
property.ShouldSerialize = (_) => false;
|
||||
}
|
||||
|
||||
if (property.DeclaringType == typeof(TerminalTheme) && property.PropertyName == nameof(TerminalTheme.Id))
|
||||
{
|
||||
property.ShouldSerialize = (_) => false;
|
||||
}
|
||||
|
||||
return property;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
_keyboardCommandService.RegisterCommandHandler(Command.PreviousTab, SelectPreviousTab);
|
||||
_keyboardCommandService.RegisterCommandHandler(Command.NewWindow, NewWindow);
|
||||
_keyboardCommandService.RegisterCommandHandler(Command.ShowSettings, ShowSettings);
|
||||
_keyboardCommandService.RegisterCommandHandler(Command.ToggleFullScreen, ToggleFullScreen);
|
||||
var currentTheme = _settingsService.GetCurrentTheme();
|
||||
var options = _settingsService.GetTerminalOptions();
|
||||
Background = currentTheme.Colors.Background;
|
||||
@@ -92,9 +93,17 @@ namespace FluentTerminal.App.ViewModels
|
||||
get => _selectedTerminal;
|
||||
set
|
||||
{
|
||||
if (SelectedTerminal != null)
|
||||
{
|
||||
_selectedTerminal.IsSelected = false;
|
||||
}
|
||||
if (Set(ref _selectedTerminal, value))
|
||||
{
|
||||
SelectedTerminal?.FocusTerminal();
|
||||
if (SelectedTerminal != null)
|
||||
{
|
||||
SelectedTerminal.IsSelected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,5 +262,19 @@ namespace FluentTerminal.App.ViewModels
|
||||
{
|
||||
ShowSettingsRequested?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void ToggleFullScreen()
|
||||
{
|
||||
var applicationView = ApplicationView.GetForCurrentView();
|
||||
|
||||
if (applicationView.IsFullScreenMode)
|
||||
{
|
||||
applicationView.ExitFullScreenMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
applicationView.TryEnterFullScreenMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,20 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
}
|
||||
}
|
||||
|
||||
public bool UnderlineSelectedTab
|
||||
{
|
||||
get => _applicationSettings.UnderlineSelectedTab;
|
||||
set
|
||||
{
|
||||
if (_applicationSettings.UnderlineSelectedTab != value)
|
||||
{
|
||||
_applicationSettings.UnderlineSelectedTab = value;
|
||||
_settingsService.SaveApplicationSettings(_applicationSettings);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public NewTerminalLocation NewTerminalLocation
|
||||
{
|
||||
get => _applicationSettings.NewTerminalLocation;
|
||||
@@ -94,6 +108,7 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
var defaults = _defaultValueProvider.GetDefaultApplicationSettings();
|
||||
ConfirmClosingWindows = defaults.ConfirmClosingWindows;
|
||||
ConfirmClosingTabs = defaults.ConfirmClosingTabs;
|
||||
UnderlineSelectedTab = defaults.UnderlineSelectedTab;
|
||||
NewTerminalLocation = defaults.NewTerminalLocation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,18 +3,21 @@ 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.Linq;
|
||||
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 IDialogService _dialogService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ITrayProcessCommunicationService _trayProcessCommunicationService;
|
||||
private IDictionary<Command, ICollection<KeyBinding>> _keyBindings;
|
||||
|
||||
public KeyBindingsPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider, ITrayProcessCommunicationService trayProcessCommunicationService)
|
||||
{
|
||||
@@ -28,79 +31,45 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
Initialize(_settingsService.GetKeyBindings());
|
||||
}
|
||||
|
||||
private void Initialize(KeyBindings keyBindings)
|
||||
public RelayCommand<Command> AddCommand { get; }
|
||||
public ObservableCollection<KeyBindingsViewModel> KeyBindings { get; } = new ObservableCollection<KeyBindingsViewModel>();
|
||||
public RelayCommand RestoreDefaultsCommand { get; }
|
||||
|
||||
private async Task Add(Command command)
|
||||
{
|
||||
var keyBinding = KeyBindings.FirstOrDefault(k => k.Command == command);
|
||||
await keyBinding?.Add();
|
||||
}
|
||||
|
||||
private void ClearKeyBindings()
|
||||
{
|
||||
foreach (var keyBinding in KeyBindings)
|
||||
{
|
||||
keyBinding.Edited -= OnEdited;
|
||||
}
|
||||
|
||||
KeyBindings.Clear();
|
||||
}
|
||||
|
||||
private void Initialize(IDictionary<Command, ICollection<KeyBinding>> keyBindings)
|
||||
{
|
||||
_keyBindings = keyBindings;
|
||||
|
||||
NewTab = CreateViewModel(Command.NewTab, _keyBindings.NewTab);
|
||||
ConfigurableNewTab = CreateViewModel(Command.ConfigurableNewTab, _keyBindings.ConfigurableNewTab);
|
||||
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);
|
||||
Search = CreateViewModel(Command.Search, _keyBindings.Search);
|
||||
ClearKeyBindings();
|
||||
|
||||
RaisePropertyChanged(nameof(NewTab));
|
||||
RaisePropertyChanged(nameof(ConfigurableNewTab));
|
||||
RaisePropertyChanged(nameof(ToggleWindow));
|
||||
RaisePropertyChanged(nameof(NextTab));
|
||||
RaisePropertyChanged(nameof(PreviousTab));
|
||||
RaisePropertyChanged(nameof(CloseTab));
|
||||
RaisePropertyChanged(nameof(NewWindow));
|
||||
RaisePropertyChanged(nameof(ShowSettings));
|
||||
RaisePropertyChanged(nameof(Copy));
|
||||
RaisePropertyChanged(nameof(Paste));
|
||||
RaisePropertyChanged(nameof(Search));
|
||||
foreach (var value in Enum.GetValues(typeof(Command)))
|
||||
{
|
||||
var command = (Command)value;
|
||||
var viewModel = new KeyBindingsViewModel(command, _keyBindings[command], _dialogService);
|
||||
viewModel.Edited += OnEdited;
|
||||
KeyBindings.Add(viewModel);
|
||||
}
|
||||
}
|
||||
|
||||
public KeyBindingsViewModel NewTab { get; private set; }
|
||||
public KeyBindingsViewModel ConfigurableNewTab { 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 KeyBindingsViewModel Search { get; private set; }
|
||||
|
||||
public RelayCommand RestoreDefaultsCommand { get; }
|
||||
public RelayCommand<Command> AddCommand { get; }
|
||||
|
||||
private Task Add(Command command)
|
||||
private void OnEdited(Command command, ICollection<KeyBinding> keyBindings)
|
||||
{
|
||||
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.ConfigurableNewTab:
|
||||
return ConfigurableNewTab.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();
|
||||
case Command.Search:
|
||||
return Search.Add();
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
_settingsService.SaveKeyBindings(command, keyBindings);
|
||||
_trayProcessCommunicationService.UpdateToggleWindowKeyBindings();
|
||||
}
|
||||
|
||||
private async Task RestoreDefaults()
|
||||
@@ -109,23 +78,9 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
|
||||
if (result == DialogButton.OK)
|
||||
{
|
||||
Initialize(_defaultValueProvider.GetDefaultKeyBindings());
|
||||
_settingsService.SaveKeyBindings(_keyBindings);
|
||||
_settingsService.ResetKeyBindings();
|
||||
Initialize(_settingsService.GetKeyBindings());
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using GalaSoft.MvvmLight;
|
||||
@@ -11,16 +12,17 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
{
|
||||
public class KeyBindingsViewModel : ViewModelBase
|
||||
{
|
||||
private readonly Command _command;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly ICollection<KeyBinding> _keyBindings;
|
||||
|
||||
public KeyBindingsViewModel(Command command, ICollection<KeyBinding> keyBindings, IDialogService dialogService)
|
||||
{
|
||||
_command = command;
|
||||
Command = command;
|
||||
_keyBindings = keyBindings;
|
||||
_dialogService = dialogService;
|
||||
|
||||
CommandName = EnumHelper.GetEnumDescription(command);
|
||||
|
||||
foreach (var binding in keyBindings)
|
||||
{
|
||||
var viewModel = new KeyBindingViewModel(binding, _dialogService);
|
||||
@@ -30,13 +32,19 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler Edited;
|
||||
public delegate void EditedEvent(Command command, ICollection<KeyBinding> keyBindings);
|
||||
|
||||
public event EditedEvent Edited;
|
||||
|
||||
public Command Command { get; }
|
||||
|
||||
public string CommandName { get; }
|
||||
|
||||
public ObservableCollection<KeyBindingViewModel> KeyBindings { get; } = new ObservableCollection<KeyBindingViewModel>();
|
||||
|
||||
public async Task Add()
|
||||
{
|
||||
var newKeyBinding = new KeyBindingViewModel(new KeyBinding { Command = _command }, _dialogService);
|
||||
var newKeyBinding = new KeyBindingViewModel(new KeyBinding { Command = Command }, _dialogService);
|
||||
|
||||
if (await newKeyBinding.Edit().ConfigureAwait(true))
|
||||
{
|
||||
@@ -44,7 +52,7 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
newKeyBinding.Edited += ViewModel_Edited;
|
||||
KeyBindings.Add(newKeyBinding);
|
||||
_keyBindings.Add(newKeyBinding.Model);
|
||||
Edited?.Invoke(this, EventArgs.Empty);
|
||||
Edited?.Invoke(Command, _keyBindings);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,13 +62,13 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
{
|
||||
_keyBindings.Remove(keyBinding.Model);
|
||||
KeyBindings.Remove(keyBinding);
|
||||
Edited?.Invoke(this, EventArgs.Empty);
|
||||
Edited?.Invoke(Command, _keyBindings);
|
||||
}
|
||||
}
|
||||
|
||||
private void ViewModel_Edited(object sender, EventArgs e)
|
||||
{
|
||||
Edited?.Invoke(this, EventArgs.Empty);
|
||||
Edited?.Invoke(Command, _keyBindings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,6 +97,32 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
}
|
||||
}
|
||||
|
||||
public string ScrollBackLimit
|
||||
{
|
||||
get => _terminalOptions.ScrollBackLimit.ToString();
|
||||
set
|
||||
{
|
||||
var oldValue = _terminalOptions.ScrollBackLimit;
|
||||
if (uint.TryParse(value, out uint intValue))
|
||||
{
|
||||
if (intValue == uint.MinValue)
|
||||
{
|
||||
intValue = uint.MaxValue;
|
||||
}
|
||||
if (_terminalOptions.ScrollBackLimit != intValue)
|
||||
{
|
||||
_terminalOptions.ScrollBackLimit = intValue;
|
||||
_settingsService.SaveTerminalOptions(_terminalOptions);
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RaisePropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> Fonts { get; }
|
||||
|
||||
public int FontSize
|
||||
@@ -168,6 +194,7 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
FontFamily = defaults.FontFamily;
|
||||
FontSize = defaults.FontSize;
|
||||
BackgroundOpacity = defaults.BackgroundOpacity;
|
||||
ScrollBackLimit = defaults.ScrollBackLimit.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Exceptions;
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.Models;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Windows.Storage.Pickers;
|
||||
using Windows.UI;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels.Settings
|
||||
{
|
||||
@@ -15,14 +18,19 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
private readonly ISettingsService _settingsService;
|
||||
private ThemeViewModel _selectedTheme;
|
||||
private double _backgroundOpacity;
|
||||
private readonly IThemeParserFactory _themeParserFactory;
|
||||
|
||||
public ThemesPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider)
|
||||
public event EventHandler<Color> SelectedThemeBackgroundColorChanged;
|
||||
|
||||
public ThemesPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider, IThemeParserFactory themeParserFactory)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_dialogService = dialogService;
|
||||
_defaultValueProvider = defaultValueProvider;
|
||||
_themeParserFactory = themeParserFactory;
|
||||
|
||||
CreateThemeCommand = new RelayCommand(CreateTheme);
|
||||
ImportThemeCommand = new RelayCommand(ImportTheme);
|
||||
|
||||
_settingsService.TerminalOptionsChanged += OnTerminalOptionsChanged;
|
||||
|
||||
@@ -43,14 +51,11 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
}
|
||||
|
||||
SelectedTheme = Themes.First(t => t.IsActive);
|
||||
}
|
||||
|
||||
private void OnTerminalOptionsChanged(object sender, TerminalOptions e)
|
||||
{
|
||||
BackgroundOpacity = e.BackgroundOpacity;
|
||||
}
|
||||
|
||||
public RelayCommand CreateThemeCommand { get; }
|
||||
public RelayCommand ImportThemeCommand { get; }
|
||||
|
||||
public double BackgroundOpacity
|
||||
{
|
||||
@@ -61,7 +66,18 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
public ThemeViewModel SelectedTheme
|
||||
{
|
||||
get => _selectedTheme;
|
||||
set => Set(ref _selectedTheme, value);
|
||||
set
|
||||
{
|
||||
if (_selectedTheme != null)
|
||||
{
|
||||
_selectedTheme.BackgroundChanged -= OnSelectedThemeBackgroundChanged;
|
||||
}
|
||||
Set(ref _selectedTheme, value);
|
||||
if (value != null)
|
||||
{
|
||||
value.BackgroundChanged += OnSelectedThemeBackgroundChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<ThemeViewModel> Themes { get; } = new ObservableCollection<ThemeViewModel>();
|
||||
@@ -86,6 +102,48 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
SelectedTheme = viewModel;
|
||||
}
|
||||
|
||||
private async void ImportTheme()
|
||||
{
|
||||
var picker = new FileOpenPicker
|
||||
{
|
||||
SuggestedStartLocation = PickerLocationId.ComputerFolder
|
||||
};
|
||||
|
||||
foreach (var supportedFileType in _themeParserFactory.SupportedFileTypes)
|
||||
{
|
||||
picker.FileTypeFilter.Add(supportedFileType);
|
||||
}
|
||||
|
||||
var file = await picker.PickSingleFileAsync();
|
||||
if (file != null)
|
||||
{
|
||||
var parser = _themeParserFactory.GetParser(file);
|
||||
|
||||
if (parser == null)
|
||||
{
|
||||
await _dialogService.ShowMessageDialogAsnyc("Import theme failed", "No suitable parser found", DialogButton.OK).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var theme = await parser.Parse(file).ConfigureAwait(true);
|
||||
|
||||
_settingsService.SaveTheme(theme);
|
||||
|
||||
var viewModel = new ThemeViewModel(theme, _settingsService, _dialogService);
|
||||
viewModel.Activated += OnThemeActivated;
|
||||
viewModel.Deleted += OnThemeDeleted;
|
||||
Themes.Add(viewModel);
|
||||
SelectedTheme = viewModel;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
await _dialogService.ShowMessageDialogAsnyc("Import theme failed", exception.Message, DialogButton.OK).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnThemeActivated(object sender, EventArgs e)
|
||||
{
|
||||
if (sender is ThemeViewModel activatedTheme)
|
||||
@@ -117,5 +175,15 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
_settingsService.DeleteTheme(theme.Id);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTerminalOptionsChanged(object sender, TerminalOptions e)
|
||||
{
|
||||
BackgroundOpacity = e.BackgroundOpacity;
|
||||
}
|
||||
|
||||
private void OnSelectedThemeBackgroundChanged(object sender, Color e)
|
||||
{
|
||||
SelectedThemeBackgroundColorChanged?.Invoke(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,13 +7,13 @@ namespace FluentTerminal.App.ViewModels
|
||||
{
|
||||
public class SettingsViewModel : ViewModelBase
|
||||
{
|
||||
public SettingsViewModel(ISettingsService settingsService, IDefaultValueProvider defaultValueProvider, IDialogService dialogService, ITrayProcessCommunicationService trayProcessCommunicationService)
|
||||
public SettingsViewModel(ISettingsService settingsService, IDefaultValueProvider defaultValueProvider, IDialogService dialogService, ITrayProcessCommunicationService trayProcessCommunicationService, IThemeParserFactory themeParserFactory)
|
||||
{
|
||||
KeyBindings = new KeyBindingsPageViewModel(settingsService, dialogService, defaultValueProvider, trayProcessCommunicationService);
|
||||
General = new GeneralPageViewModel(settingsService, dialogService, defaultValueProvider);
|
||||
Shell = new ProfilesPageViewModel(settingsService, dialogService, defaultValueProvider);
|
||||
Terminal = new TerminalPageViewModel(settingsService, dialogService, defaultValueProvider);
|
||||
Themes = new ThemesPageViewModel(settingsService, dialogService, defaultValueProvider);
|
||||
Themes = new ThemesPageViewModel(settingsService, dialogService, defaultValueProvider, themeParserFactory);
|
||||
}
|
||||
|
||||
public event EventHandler Closed;
|
||||
|
||||
@@ -6,6 +6,7 @@ using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
@@ -32,6 +33,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
private readonly ShellProfile _shellProfile;
|
||||
private bool _showSearchPanel;
|
||||
private string _searchText;
|
||||
private bool _isSelected;
|
||||
|
||||
public TerminalViewModel(int id, ISettingsService settingsService, ITrayProcessCommunicationService trayProcessCommunicationService, IDialogService dialogService,
|
||||
IKeyboardCommandService keyboardCommandService, ApplicationSettings applicationSettings, string startupDirectory, ShellProfile shellProfile)
|
||||
@@ -64,11 +66,12 @@ namespace FluentTerminal.App.ViewModels
|
||||
_dispatcher = CoreApplication.GetCurrentView().Dispatcher;
|
||||
}
|
||||
|
||||
private async void OnKeyBindingsChanged(object sender, KeyBindings e)
|
||||
private async void OnKeyBindingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
var keyBindings = _settingsService.GetKeyBindings();
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
|
||||
{
|
||||
await _terminalView.ChangeKeyBindings(GetKeyBindingsCollection(e)).ConfigureAwait(false);
|
||||
await _terminalView.ChangeKeyBindings(FlattenKeyBindings(keyBindings)).ConfigureAwait(false);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -82,6 +85,20 @@ namespace FluentTerminal.App.ViewModels
|
||||
public RelayCommand FindNextCommand { get; }
|
||||
public RelayCommand CloseSearchPanelCommand { get; }
|
||||
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _isSelected;
|
||||
set
|
||||
{
|
||||
if (Set(ref _isSelected, value))
|
||||
{
|
||||
RaisePropertyChanged(nameof(IsUnderlined));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsUnderlined => IsSelected && _applicationSettings.UnderlineSelectedTab;
|
||||
|
||||
public int Id { get; }
|
||||
|
||||
public bool Initialized { get; private set; }
|
||||
@@ -128,7 +145,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
get => _title;
|
||||
set
|
||||
{
|
||||
value = string.IsNullOrWhiteSpace(value) ? DefaultTitle: value;
|
||||
value = string.IsNullOrWhiteSpace(value) ? DefaultTitle : value;
|
||||
|
||||
if (Set(ref _title, value))
|
||||
{
|
||||
@@ -155,7 +172,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
var theme = _settingsService.GetCurrentTheme();
|
||||
var keyBindings = _settingsService.GetKeyBindings();
|
||||
|
||||
var size = await _terminalView.CreateTerminal(options, theme.Colors, GetKeyBindingsCollection(keyBindings)).ConfigureAwait(true);
|
||||
var size = await _terminalView.CreateTerminal(options, theme.Colors, FlattenKeyBindings(keyBindings)).ConfigureAwait(true);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_startupDirectory))
|
||||
{
|
||||
@@ -202,7 +219,11 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
private async void OnApplicationSettingsChanged(object sender, ApplicationSettings e)
|
||||
{
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => _applicationSettings = e);
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
|
||||
{
|
||||
_applicationSettings = e;
|
||||
RaisePropertyChanged(nameof(IsUnderlined));
|
||||
});
|
||||
}
|
||||
|
||||
private async void OnCurrentThemeChanged(object sender, Guid e)
|
||||
@@ -276,21 +297,9 @@ namespace FluentTerminal.App.ViewModels
|
||||
Title = e;
|
||||
}
|
||||
|
||||
private IEnumerable<KeyBinding> GetKeyBindingsCollection(KeyBindings keyBindings)
|
||||
private IEnumerable<KeyBinding> FlattenKeyBindings(IDictionary<Command, ICollection<KeyBinding>> keyBindings)
|
||||
{
|
||||
var list = new List<KeyBinding>();
|
||||
list.AddRange(keyBindings.CloseTab);
|
||||
list.AddRange(keyBindings.Copy);
|
||||
list.AddRange(keyBindings.NewTab);
|
||||
list.AddRange(keyBindings.ConfigurableNewTab);
|
||||
list.AddRange(keyBindings.NewWindow);
|
||||
list.AddRange(keyBindings.NextTab);
|
||||
list.AddRange(keyBindings.Paste);
|
||||
list.AddRange(keyBindings.PreviousTab);
|
||||
list.AddRange(keyBindings.ShowSettings);
|
||||
list.AddRange(keyBindings.Search);
|
||||
|
||||
return list;
|
||||
return keyBindings.Values.SelectMany(k => k);
|
||||
}
|
||||
|
||||
private Task FindNext()
|
||||
|
||||
@@ -4,8 +4,12 @@ using FluentTerminal.Models;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Microsoft.Toolkit.Uwp.Helpers;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Pickers;
|
||||
using Windows.UI;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels
|
||||
@@ -45,6 +49,8 @@ namespace FluentTerminal.App.ViewModels
|
||||
private Color _white;
|
||||
private Color _yellow;
|
||||
|
||||
public event EventHandler<Color> BackgroundChanged;
|
||||
|
||||
public ThemeViewModel(TerminalTheme theme, ISettingsService settingsService, IDialogService dialogService)
|
||||
{
|
||||
_theme = theme;
|
||||
@@ -80,10 +86,11 @@ namespace FluentTerminal.App.ViewModels
|
||||
Selection = _theme.Colors.Selection.FromString();
|
||||
|
||||
SetActiveCommand = new RelayCommand(SetActive);
|
||||
DeleteCommand = new RelayCommand(async () => await Delete().ConfigureAwait(false), CanDelete);
|
||||
EditCommand = new RelayCommand(Edit, CanEdit);
|
||||
DeleteCommand = new RelayCommand(async () => await Delete().ConfigureAwait(false), NotPreInstalled);
|
||||
EditCommand = new RelayCommand(Edit, NotPreInstalled);
|
||||
CancelEditCommand = new RelayCommand(async () => await CancelEdit().ConfigureAwait(false));
|
||||
SaveChangesCommand = new RelayCommand(SaveChanges);
|
||||
ExportCommand = new RelayCommand(async () => await Export().ConfigureAwait(false), NotPreInstalled);
|
||||
}
|
||||
|
||||
public event EventHandler Activated;
|
||||
@@ -99,7 +106,11 @@ namespace FluentTerminal.App.ViewModels
|
||||
public Color Background
|
||||
{
|
||||
get => _background;
|
||||
set => Set(ref _background, value);
|
||||
set
|
||||
{
|
||||
Set(ref _background, value);
|
||||
BackgroundChanged?.Invoke(this, value);
|
||||
}
|
||||
}
|
||||
|
||||
public double BackgroundOpacity
|
||||
@@ -190,6 +201,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
public RelayCommand DeleteCommand { get; }
|
||||
public RelayCommand EditCommand { get; }
|
||||
public RelayCommand ExportCommand { get; }
|
||||
|
||||
public Color Foreground
|
||||
{
|
||||
@@ -328,12 +340,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
private bool CanDelete()
|
||||
{
|
||||
return !_theme.PreInstalled;
|
||||
}
|
||||
|
||||
private bool CanEdit()
|
||||
private bool NotPreInstalled()
|
||||
{
|
||||
return !_theme.PreInstalled;
|
||||
}
|
||||
@@ -360,5 +367,21 @@ namespace FluentTerminal.App.ViewModels
|
||||
{
|
||||
Activated?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private async Task Export()
|
||||
{
|
||||
var picker = new FileSavePicker();
|
||||
picker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
|
||||
picker.SuggestedFileName = Name;
|
||||
picker.FileTypeChoices.Add("Fluent Terminal Theme", new List<string> { ".flutecolors" });
|
||||
|
||||
var file = await picker.PickSaveFileAsync();
|
||||
|
||||
if (file != null)
|
||||
{
|
||||
var content = JsonConvert.SerializeObject(_theme, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new TerminalThemeContractResolver() });
|
||||
await FileIO.WriteTextAsync(file, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,15 @@
|
||||
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}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="180" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="{x:Bind ViewModel.CommandName, Mode=OneWay}" />
|
||||
<ItemsControl Grid.Column="1" ItemsSource="{x:Bind ViewModel.KeyBindings, Mode=OneWay}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="settings:KeyBindingViewModel">
|
||||
<StackPanel
|
||||
|
||||
@@ -7,7 +7,7 @@ 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));
|
||||
DependencyProperty.Register(nameof(ViewModel), typeof(KeyBindingsViewModel), typeof(KeyBindingsView), new PropertyMetadata(null));
|
||||
|
||||
public KeyBindingsView()
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:viewmodels="using:FluentTerminal.App.ViewModels"
|
||||
RequestedTheme="Dark"
|
||||
RequestedTheme="{x:Bind ViewModel.Background, Mode=OneWay, Converter={StaticResource BackgroundToApplicationThemeConverter}}"
|
||||
mc:Ignorable="d">
|
||||
<Page.Resources>
|
||||
<converters:TerminalViewModelToViewConverter x:Key="TerminalViewModelToViewConverter" />
|
||||
@@ -72,9 +72,15 @@
|
||||
</behaviors:MiddleClickBehavior.Actions>
|
||||
</behaviors:MiddleClickBehavior>
|
||||
</Interactivity:Interaction.Behaviors>
|
||||
<Border
|
||||
Grid.ColumnSpan="3"
|
||||
Height="3"
|
||||
VerticalAlignment="Bottom"
|
||||
Background="{ThemeResource SystemAccentColor}"
|
||||
Visibility="{x:Bind IsUnderlined, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}" />
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
Margin="12,8,0,0"
|
||||
Margin="12,8,6,0"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind Title, Mode=OneWay}" />
|
||||
<Button
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using FluentTerminal.App.ViewModels;
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.App.ViewModels;
|
||||
using System.ComponentModel;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.UI;
|
||||
@@ -39,14 +40,16 @@ namespace FluentTerminal.App.Views
|
||||
{
|
||||
InitializeComponent();
|
||||
Root.DataContext = this;
|
||||
SetTitleBarColors();
|
||||
Window.Current.SetTitleBar(TitleBar);
|
||||
Loaded += OnLoaded;
|
||||
Unloaded += OnUnloaded;
|
||||
Window.Current.Activated += OnWindowActivated;
|
||||
RegisterPropertyChangedCallback(RequestedThemeProperty, (s, e) =>
|
||||
{
|
||||
ContrastHelper.SetTitleBarButtonsForTheme(RequestedTheme);
|
||||
});
|
||||
|
||||
ApplicationView.PreferredLaunchViewSize = new Windows.Foundation.Size(800, 600);
|
||||
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
|
||||
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Auto;
|
||||
}
|
||||
|
||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||
@@ -81,18 +84,6 @@ namespace FluentTerminal.App.Views
|
||||
UpdateLayoutMetrics();
|
||||
}
|
||||
|
||||
private void SetTitleBarColors()
|
||||
{
|
||||
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
|
||||
titleBar.ButtonBackgroundColor = Colors.Transparent;
|
||||
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
|
||||
titleBar.ButtonForegroundColor = Colors.White;
|
||||
titleBar.ButtonInactiveForegroundColor = Colors.White;
|
||||
titleBar.ButtonPressedForegroundColor = Colors.White;
|
||||
titleBar.ButtonHoverForegroundColor = Colors.White;
|
||||
titleBar.ButtonHoverBackgroundColor = Color.FromArgb(24, 255, 255, 255);
|
||||
titleBar.ButtonPressedBackgroundColor = Color.FromArgb(48, 255, 255, 255);
|
||||
}
|
||||
|
||||
private void UpdateLayoutMetrics()
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
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"
|
||||
Loaded="Page_Loaded"
|
||||
mc:Ignorable="d">
|
||||
<Grid x:Name="Root">
|
||||
<TextBlock
|
||||
|
||||
@@ -12,6 +12,7 @@ using Windows.UI.ViewManagement;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
using FluentTerminal.App.Utilities;
|
||||
|
||||
namespace FluentTerminal.App.Views
|
||||
{
|
||||
@@ -27,9 +28,6 @@ namespace FluentTerminal.App.Views
|
||||
InitializeComponent();
|
||||
Root.DataContext = this;
|
||||
|
||||
ApplicationView.PreferredLaunchViewSize = new Windows.Foundation.Size(1024, 768);
|
||||
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
|
||||
|
||||
ApplicationView.GetForCurrentView().Title = "Settings";
|
||||
|
||||
CoreApplicationViewTitleBar coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
|
||||
@@ -58,36 +56,8 @@ namespace FluentTerminal.App.Views
|
||||
{
|
||||
return _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
|
||||
{
|
||||
_titleBar.ButtonBackgroundColor = Colors.Transparent;
|
||||
_titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
|
||||
_titleBar.ButtonForegroundColor = (Color)Resources["SystemBaseHighColor"];
|
||||
_titleBar.ButtonHoverForegroundColor = (Color)Resources["SystemBaseHighColor"];
|
||||
_titleBar.ButtonPressedForegroundColor = (Color)Resources["SystemBaseHighColor"];
|
||||
|
||||
if (Application.Current.RequestedTheme == ApplicationTheme.Light)
|
||||
{
|
||||
_titleBar.ButtonHoverBackgroundColor = (Color)Resources["SystemChromeMediumColor"];
|
||||
_titleBar.ButtonPressedBackgroundColor = (Color)Resources["SystemChromeHighColor"];
|
||||
}
|
||||
else
|
||||
{
|
||||
_titleBar.ButtonHoverBackgroundColor = (Color)Resources["SystemChromeLowColor"];
|
||||
_titleBar.ButtonPressedBackgroundColor = (Color)Resources["SystemChromeMediumLowColor"];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private IAsyncAction SetTitleBarColorsForThemesPage()
|
||||
{
|
||||
return _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
|
||||
{
|
||||
_titleBar.ButtonBackgroundColor = Colors.Transparent;
|
||||
_titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
|
||||
_titleBar.ButtonForegroundColor = Colors.White;
|
||||
_titleBar.ButtonHoverForegroundColor = Colors.White;
|
||||
_titleBar.ButtonPressedForegroundColor = Colors.White;
|
||||
_titleBar.ButtonHoverBackgroundColor = Color.FromArgb(24, 255, 255, 255);
|
||||
_titleBar.ButtonPressedBackgroundColor = Color.FromArgb(48, 255, 255, 255);
|
||||
var theme = Application.Current.RequestedTheme == ApplicationTheme.Light ? ElementTheme.Light : ElementTheme.Dark;
|
||||
ContrastHelper.SetTitleBarButtonsForTheme(theme);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -139,11 +109,7 @@ namespace FluentTerminal.App.Views
|
||||
}
|
||||
}
|
||||
|
||||
if (_onThemesPage)
|
||||
{
|
||||
SetTitleBarColorsForThemesPage();
|
||||
}
|
||||
else
|
||||
if (!_onThemesPage)
|
||||
{
|
||||
SetTitleBarColors();
|
||||
}
|
||||
@@ -158,5 +124,10 @@ namespace FluentTerminal.App.Views
|
||||
{
|
||||
AppTitle.Margin = new Thickness(CoreApplication.GetCurrentView().TitleBar.SystemOverlayLeftInset + 12, 8, 0, 0);
|
||||
}
|
||||
|
||||
private void Page_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ApplicationView.GetForCurrentView().TryResizeView(new Size { Width = 800, Height = 600 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,10 @@
|
||||
Margin="0,0,0,24"
|
||||
Content="Windows"
|
||||
IsChecked="{x:Bind ViewModel.WindowIsSelected, Mode=TwoWay}" />
|
||||
<ToggleSwitch
|
||||
Margin="0,0,0,24"
|
||||
Header="Underline selected tab"
|
||||
IsOn="{x:Bind ViewModel.UnderlineSelectedTab, Mode=TwoWay}" />
|
||||
<ToggleSwitch
|
||||
Margin="0,0,0,24"
|
||||
Header="Ask before closing windows"
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
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:enums="using:FluentTerminal.Models.Enums"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:settings="using:FluentTerminal.App.ViewModels.Settings"
|
||||
xmlns:views="using:FluentTerminal.App.Views"
|
||||
mc:Ignorable="d">
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
@@ -32,63 +32,7 @@
|
||||
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="New configurable tab">
|
||||
<MenuFlyoutItem.CommandParameter>
|
||||
<enums:Command>ConfigurableNewTab</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="Search">
|
||||
<MenuFlyoutItem.CommandParameter>
|
||||
<enums:Command>Search</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>
|
||||
<MenuFlyout x:Name="AddCommandMenu" />
|
||||
</AppBarButton.Flyout>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
@@ -99,146 +43,13 @@
|
||||
</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" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<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="New configurable tab" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="1"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.ConfigurableNewTab, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="2"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Close tab" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.CloseTab, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Next tab" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="3"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.NextTab, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="4"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Previous tab" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="4"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.PreviousTab, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="5"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="New window" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="5"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.NewWindow, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="6"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Search" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="6"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.Search, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="7"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Show settings" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="7"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.ShowSettings, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="8"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Toggle window" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="8"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.ToggleWindow, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="9"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Copy" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="9"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.Copy, Mode=OneWay}" />
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="10"
|
||||
Grid.Column="0"
|
||||
Margin="0,6,24,0"
|
||||
Text="Paste" />
|
||||
<views:KeyBindingsView
|
||||
Grid.Row="10"
|
||||
Grid.Column="1"
|
||||
Margin="0,0,0,24"
|
||||
ViewModel="{x:Bind ViewModel.Paste, Mode=OneWay}" />
|
||||
</Grid>
|
||||
<ItemsControl ItemsSource="{x:Bind ViewModel.KeyBindings, Mode=OneWay}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate x:DataType="settings:KeyBindingsViewModel">
|
||||
<views:KeyBindingsView Margin="0,0,0,24" ViewModel="{x:Bind}" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -1,4 +1,7 @@
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using System;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
@@ -18,6 +21,17 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
if (e.Parameter is KeyBindingsPageViewModel viewModel)
|
||||
{
|
||||
ViewModel = viewModel;
|
||||
|
||||
foreach (var value in Enum.GetValues(typeof(Command)))
|
||||
{
|
||||
var command = (Command)value;
|
||||
AddCommandMenu.Items.Add(new MenuFlyoutItem
|
||||
{
|
||||
Text = EnumHelper.GetEnumDescription(command),
|
||||
Command = ViewModel.AddCommand,
|
||||
CommandParameter = command
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,13 @@
|
||||
Minimum="0"
|
||||
StepFrequency="0.01"
|
||||
Value="{x:Bind ViewModel.BackgroundOpacity, Mode=TwoWay}" />
|
||||
<TextBox
|
||||
Width="200"
|
||||
Margin="0,0,0,24"
|
||||
HorizontalAlignment="Left"
|
||||
Header="Scrollback limit"
|
||||
KeyDown="ScrollBackTextBoxOnKeyDown"
|
||||
Text="{x:Bind ViewModel.ScrollBackLimit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
|
||||
<ToggleSwitch
|
||||
Margin="0,0,0,24"
|
||||
Header="Blinking cursor"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace FluentTerminal.App.Views.SettingsPages
|
||||
@@ -20,5 +22,24 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
ViewModel = viewModel;
|
||||
}
|
||||
}
|
||||
|
||||
private void ScrollBackTextBoxOnKeyDown(object sender, KeyRoutedEventArgs e)
|
||||
{
|
||||
if (e.Key == VirtualKey.Back)
|
||||
{
|
||||
e.Handled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
if (e.Key.ToString() == string.Format("Number{0}", i))
|
||||
{
|
||||
e.Handled = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,24 +50,29 @@
|
||||
DefaultLabelPosition="Right"
|
||||
Visibility="{x:Bind ViewModel.SelectedTheme.InEditMode, Mode=OneWay, Converter={StaticResource FalseToVisibleConverter}}">
|
||||
<AppBarButton
|
||||
Name="SetActiveButton"
|
||||
Command="{x:Bind ViewModel.SelectedTheme.SetActiveCommand, Mode=OneWay}"
|
||||
Foreground="White"
|
||||
Icon="Accept"
|
||||
IsEnabled="{x:Bind ViewModel.SelectedTheme.IsActive, Mode=OneWay, Converter={StaticResource NegateConverter}}"
|
||||
Label="Set Active"
|
||||
Style="{StaticResource ThemeAppBarButtonStyle}" />
|
||||
IsEnabled="{Binding ViewModel.SelectedTheme.IsActive, Mode=OneWay, Converter={StaticResource NegateConverter}}"
|
||||
Label="Set Active" />
|
||||
<AppBarButton
|
||||
Name="ExportButton"
|
||||
Command="{x:Bind ViewModel.SelectedTheme.ExportCommand, Mode=OneWay}"
|
||||
Label="Export">
|
||||
<AppBarButton.Icon>
|
||||
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="" />
|
||||
</AppBarButton.Icon>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
Name="EditButton"
|
||||
Command="{x:Bind ViewModel.SelectedTheme.EditCommand, Mode=OneWay}"
|
||||
Foreground="White"
|
||||
Icon="Edit"
|
||||
Label="Edit"
|
||||
Style="{StaticResource ThemeAppBarButtonStyle}" />
|
||||
Label="Edit" />
|
||||
<AppBarButton
|
||||
Name="DeleteButton"
|
||||
Command="{x:Bind ViewModel.SelectedTheme.DeleteCommand, Mode=OneWay}"
|
||||
Foreground="White"
|
||||
Icon="Delete"
|
||||
Label="Delete"
|
||||
Style="{StaticResource ThemeAppBarButtonStyle}" />
|
||||
Label="Delete" />
|
||||
</CommandBar>
|
||||
<CommandBar
|
||||
Grid.Column="1"
|
||||
@@ -77,17 +82,15 @@
|
||||
DefaultLabelPosition="Right"
|
||||
Visibility="{x:Bind ViewModel.SelectedTheme.InEditMode, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
<AppBarButton
|
||||
Name="SaveButton"
|
||||
Command="{x:Bind ViewModel.SelectedTheme.SaveChangesCommand, Mode=OneWay}"
|
||||
Foreground="White"
|
||||
Icon="Save"
|
||||
Label="Save"
|
||||
Style="{StaticResource ThemeAppBarButtonStyle}" />
|
||||
Label="Save" />
|
||||
<AppBarButton
|
||||
Name="CancelButton"
|
||||
Command="{x:Bind ViewModel.SelectedTheme.CancelEditCommand, Mode=OneWay}"
|
||||
Foreground="White"
|
||||
Icon="Cancel"
|
||||
Label="Cancel"
|
||||
Style="{StaticResource ThemeAppBarButtonStyle}" />
|
||||
Label="Cancel" />
|
||||
</CommandBar>
|
||||
</Grid>
|
||||
<StackPanel Grid.Row="2" Grid.Column="0">
|
||||
@@ -136,13 +139,34 @@
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
<Button
|
||||
Height="48"
|
||||
Margin="0,0,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Left"
|
||||
Background="Transparent"
|
||||
Command="{x:Bind ViewModel.ImportThemeCommand}"
|
||||
Style="{StaticResource ButtonRevealStyle}">
|
||||
<Button.Content>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Viewbox
|
||||
Width="12"
|
||||
Height="12"
|
||||
Margin="0,0,6,0">
|
||||
<SymbolIcon Symbol="OpenFile" />
|
||||
</Viewbox>
|
||||
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="Import" />
|
||||
</StackPanel>
|
||||
</Button.Content>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
|
||||
<ContentControl
|
||||
Grid.Row="2"
|
||||
Grid.Column="1"
|
||||
Margin="24,0,0,0"
|
||||
Content="{x:Bind ViewModel.SelectedTheme, Mode=TwoWay}">
|
||||
Content="{x:Bind ViewModel.SelectedTheme, Mode=TwoWay}"
|
||||
RequestedTheme="{x:Bind ViewModel.SelectedTheme.Background, Mode=OneWay, Converter={StaticResource BackgroundToApplicationThemeConverter}}">
|
||||
<ContentControl.ContentTemplate>
|
||||
<DataTemplate x:DataType="viewmodels:ThemeViewModel">
|
||||
<StackPanel>
|
||||
@@ -154,19 +178,14 @@
|
||||
<SolidColorBrush Color="{x:Bind Foreground, Mode=OneWay}" />
|
||||
</TextBlock.Foreground>
|
||||
</TextBlock>
|
||||
<TextBlock
|
||||
Foreground="White"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{x:Bind Author, Mode=OneWay}" />
|
||||
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{x:Bind Author, Mode=OneWay}" />
|
||||
<TextBox
|
||||
Header="Name"
|
||||
RequestedTheme="Dark"
|
||||
Text="{x:Bind Name, Mode=TwoWay}"
|
||||
Visibility="{x:Bind InEditMode, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}" />
|
||||
<TextBox
|
||||
Margin="0,24,0,0"
|
||||
Header="Author"
|
||||
RequestedTheme="Dark"
|
||||
Text="{x:Bind Author, Mode=TwoWay}"
|
||||
Visibility="{x:Bind InEditMode, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}" />
|
||||
<Grid Margin="0,48,0,0">
|
||||
@@ -277,7 +296,6 @@
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
Margin="0,6,0,0"
|
||||
Foreground="White"
|
||||
Text="Click on a color to edit"
|
||||
Visibility="{x:Bind InEditMode, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}" />
|
||||
</Grid>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
@@ -19,7 +22,28 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
if (e.Parameter is ThemesPageViewModel viewModel)
|
||||
{
|
||||
ViewModel = viewModel;
|
||||
viewModel.SelectedThemeBackgroundColorChanged += OnSelectedThemeBackgroundColorChanged;
|
||||
var theme = ContrastHelper.GetIdealThemeForBackgroundColor(ViewModel.SelectedTheme.Background);
|
||||
SetTheme(theme);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectedThemeBackgroundColorChanged(object sender, Color e)
|
||||
{
|
||||
var theme = ContrastHelper.GetIdealThemeForBackgroundColor(e);
|
||||
SetTheme(theme);
|
||||
}
|
||||
|
||||
private void SetTheme(ElementTheme theme)
|
||||
{
|
||||
SetActiveButton.RequestedTheme = theme;
|
||||
EditButton.RequestedTheme = theme;
|
||||
DeleteButton.RequestedTheme = theme;
|
||||
SaveButton.RequestedTheme = theme;
|
||||
CancelButton.RequestedTheme = theme;
|
||||
ExportButton.RequestedTheme = theme;
|
||||
|
||||
ContrastHelper.SetTitleBarButtonsForTheme(theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ function createTerminal(options, theme, keyBindings) {
|
||||
cursorStyle: options.cursorStyle,
|
||||
cursorBlink: options.cursorBlink,
|
||||
bellStyle: options.bellStyle,
|
||||
scrollback: options.scrollBackLimit,
|
||||
allowTransparency: true,
|
||||
theme: theme,
|
||||
experimentalCharAtlas: 'dynamic'
|
||||
@@ -79,6 +80,16 @@ function createTerminal(options, theme, keyBindings) {
|
||||
if (keyBinding.command == 'copy' && term.getSelection() == '') {
|
||||
return true;
|
||||
}
|
||||
if (keyBinding.command == 'clear') {
|
||||
term.clearSelection();
|
||||
term.clear();
|
||||
return false;
|
||||
}
|
||||
if (keyBinding.command == 'selectAll') {
|
||||
term.selectAll();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
e.preventDefault();
|
||||
terminalBridge.invokeCommand(keyBinding.command);
|
||||
@@ -123,6 +134,7 @@ function changeOptions(options) {
|
||||
term.setOption('cursorStyle', options.cursorStyle);
|
||||
term.setOption('fontFamily', options.fontFamily);
|
||||
term.setOption('fontSize', options.fontSize);
|
||||
term.setOption('scrollback', options.scrollBackLimit);
|
||||
setScrollBarStyle(options.scrollBarStyle);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace FluentTerminal.Models
|
||||
{
|
||||
public bool ConfirmClosingTabs { get; set; }
|
||||
public bool ConfirmClosingWindows { get; set; }
|
||||
public bool UnderlineSelectedTab { get; set; }
|
||||
public NewTerminalLocation NewTerminalLocation { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,49 @@
|
||||
namespace FluentTerminal.Models.Enums
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace FluentTerminal.Models.Enums
|
||||
{
|
||||
public enum Command
|
||||
{
|
||||
[Description("Toggle window")]
|
||||
ToggleWindow,
|
||||
|
||||
[Description("Next tab")]
|
||||
NextTab,
|
||||
|
||||
[Description("Previous tab")]
|
||||
PreviousTab,
|
||||
|
||||
[Description("New tab")]
|
||||
NewTab,
|
||||
|
||||
[Description("Configurable new tab")]
|
||||
ConfigurableNewTab,
|
||||
|
||||
[Description("Close tab")]
|
||||
CloseTab,
|
||||
|
||||
[Description("New window")]
|
||||
NewWindow,
|
||||
|
||||
[Description("Show settings")]
|
||||
ShowSettings,
|
||||
|
||||
[Description("Copy")]
|
||||
Copy,
|
||||
|
||||
[Description("Paste")]
|
||||
Paste,
|
||||
Search
|
||||
|
||||
[Description("Search")]
|
||||
Search,
|
||||
|
||||
[Description("Toggle Fullscreen")]
|
||||
ToggleFullScreen,
|
||||
|
||||
[Description("Select all")]
|
||||
SelectAll,
|
||||
|
||||
[Description("Clear")]
|
||||
Clear
|
||||
}
|
||||
}
|
||||
@@ -17,5 +17,7 @@ namespace FluentTerminal.Models
|
||||
public ScrollBarStyle ScrollBarStyle { get; set; }
|
||||
|
||||
public double BackgroundOpacity { get; set; }
|
||||
|
||||
public uint ScrollBackLimit { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -113,7 +113,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||
<Version>6.0.6</Version>
|
||||
<Version>6.1.5</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
|
||||
@@ -151,10 +151,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autofac">
|
||||
<Version>4.8.0</Version>
|
||||
<Version>4.8.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Fleck">
|
||||
<Version>1.0.2</Version>
|
||||
<Version>1.0.3</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="GlobalHotKey">
|
||||
<Version>1.1.0</Version>
|
||||
|
||||
Reference in new issue
Block a user