Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76cb528eb4 | ||
|
|
def3aa3683 | ||
|
|
77d9a42c36 | ||
|
|
d395085064 | ||
|
|
56e5d60dae | ||
|
|
780cbf64b1 | ||
|
|
6b25d78ce6 | ||
|
|
53726e0e68 | ||
|
|
5e11e5d58b | ||
|
|
3e0417ce47 | ||
|
|
417bc843b0 | ||
|
|
6d6bdcca3e | ||
|
|
b4bfe39586 | ||
|
|
940cb6f38b | ||
|
|
59c6a39458 |
No files matched your search
@@ -3,56 +3,54 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using AutoFixture;
|
||||
using FluentAssertions;
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Services.Dialogs;
|
||||
using FluentTerminal.App.Services.Implementation;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace FluentTerminal.App.Test.Services
|
||||
namespace FluentTerminal.App.Services.Test
|
||||
{
|
||||
[TestClass]
|
||||
public class DialogServiceTests
|
||||
{
|
||||
private Fixture _fixture;
|
||||
private readonly Fixture _fixture;
|
||||
|
||||
[TestInitialize]
|
||||
public void TestInitialize()
|
||||
public DialogServiceTests()
|
||||
{
|
||||
_fixture = new Fixture();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Fact]
|
||||
public void ShowDialogAsync_TitleIsEmpty_ThrowsArgumentNullException()
|
||||
{
|
||||
var title = string.Empty;
|
||||
var content = _fixture.Create<string>();
|
||||
var buttons = _fixture.CreateMany<DialogButton>(2);
|
||||
var dialogService = new DialogService(Mock.Of<ISettingsService>());
|
||||
var dialogService = new DialogService(() => Mock.Of<IShellProfileSelectionDialog>(), () => Mock.Of<IMessageDialog>(), () => Mock.Of<ICreateKeyBindingDialog>());
|
||||
|
||||
Func<Task<DialogButton>> invoke = () => dialogService.ShowMessageDialogAsnyc(title, content, buttons.ElementAt(0), buttons.ElementAt(1));
|
||||
|
||||
invoke.Should().Throw<ArgumentNullException>().And.ParamName.Should().Be("title");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Fact]
|
||||
public void ShowDialogAsync_ContentIsEmpty_ThrowsArgumentNullException()
|
||||
{
|
||||
var title = _fixture.Create<string>();
|
||||
var content = string.Empty;
|
||||
var buttons = _fixture.CreateMany<DialogButton>(2);
|
||||
var dialogService = new DialogService(Mock.Of<ISettingsService>());
|
||||
var dialogService = new DialogService(() => Mock.Of<IShellProfileSelectionDialog>(), () => Mock.Of<IMessageDialog>(), () => Mock.Of<ICreateKeyBindingDialog>());
|
||||
|
||||
Func<Task<DialogButton>> invoke = () => dialogService.ShowMessageDialogAsnyc(title, content, buttons.ElementAt(0), buttons.ElementAt(1));
|
||||
|
||||
invoke.Should().Throw<ArgumentNullException>().And.ParamName.Should().Be("content");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Fact]
|
||||
public void ShowDialogAsync_NoButtonsPassed_ThrowsArgumentException()
|
||||
{
|
||||
var title = _fixture.Create<string>();
|
||||
var content = _fixture.Create<string>();
|
||||
var dialogService = new DialogService(Mock.Of<ISettingsService>());
|
||||
var dialogService = new DialogService(() => Mock.Of<IShellProfileSelectionDialog>(), () => Mock.Of<IMessageDialog>(), () => Mock.Of<ICreateKeyBindingDialog>());
|
||||
|
||||
Func<Task<DialogButton>> invoke = () => dialogService.ShowMessageDialogAsnyc(title, content);
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoFixture" Version="4.4.0" />
|
||||
<PackageReference Include="FluentAssertions" Version="5.4.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
|
||||
<PackageReference Include="Moq" Version="4.8.3" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FluentTerminal.App.Services\FluentTerminal.App.Services.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -2,27 +2,25 @@
|
||||
using FluentAssertions;
|
||||
using FluentTerminal.App.Services.Implementation;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Xunit;
|
||||
|
||||
namespace FluentTerminal.App.Test.Services
|
||||
namespace FluentTerminal.App.Services.Test
|
||||
{
|
||||
[TestClass]
|
||||
public class KeyboardCommandServiceTests
|
||||
{
|
||||
private Fixture _fixture;
|
||||
private readonly Fixture _fixture;
|
||||
|
||||
[TestInitialize]
|
||||
public void TestInitialize()
|
||||
public KeyboardCommandServiceTests()
|
||||
{
|
||||
_fixture = new Fixture();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Fact]
|
||||
public void RegisterCommandHandler_HandlerIsNull_ThrowsArgumentNullException()
|
||||
{
|
||||
var command = _fixture.Create<Command>();
|
||||
var command = (Command)new Random().Next(1, Enum.GetValues(typeof(Command)).Length);
|
||||
Action handler = null;
|
||||
var keyboardCommandService = new KeyboardCommandService();
|
||||
|
||||
@@ -31,10 +29,10 @@ namespace FluentTerminal.App.Test.Services
|
||||
invoke.Should().Throw<ArgumentNullException>().And.ParamName.Should().Be("handler");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Fact]
|
||||
public void RegisterCommandHandler_CommandAlreadyRegisted_ThrowsInvalidOperationException()
|
||||
{
|
||||
var command = _fixture.Create<Command>();
|
||||
var command = (Command)new Random().Next(1, Enum.GetValues(typeof(Command)).Length);
|
||||
var handler = _fixture.Create<Action>();
|
||||
var keyboardCommandService = new KeyboardCommandService();
|
||||
keyboardCommandService.RegisterCommandHandler(command, handler);
|
||||
@@ -44,10 +42,10 @@ namespace FluentTerminal.App.Test.Services
|
||||
invoke.Should().Throw<InvalidOperationException>();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Fact]
|
||||
public void SendCommand_CommandIsRegistered_HandlerGetsInvoked()
|
||||
{
|
||||
var command = _fixture.Create<Command>();
|
||||
var command = (Command)new Random().Next(1, Enum.GetValues(typeof(Command)).Length);
|
||||
var handlerCalled = false;
|
||||
var keyboardCommandService = new KeyboardCommandService();
|
||||
keyboardCommandService.RegisterCommandHandler(command, () => handlerCalled = true);
|
||||
@@ -57,10 +55,10 @@ namespace FluentTerminal.App.Test.Services
|
||||
handlerCalled.Should().BeTrue();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[Fact]
|
||||
public void SendCommand_CommandIsNotRegisted_KeyNotFoundExceptionIsThrown()
|
||||
{
|
||||
var command = _fixture.Create<Command>();
|
||||
var command = (Command)new Random().Next(1, Enum.GetValues(typeof(Command)).Length);
|
||||
var keyboardCommandService = new KeyboardCommandService();
|
||||
|
||||
Action invoke = () => keyboardCommandService.SendCommand(command);
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public class ApplicationDataContainers
|
||||
{
|
||||
public IApplicationDataContainer LocalSettings { get; set; }
|
||||
public IApplicationDataContainer RoamingSettings { get; set; }
|
||||
public IApplicationDataContainer Themes { get; set; }
|
||||
public IApplicationDataContainer KeyBindings { get; set; }
|
||||
public IApplicationDataContainer ShellProfiles { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using FluentTerminal.Models;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.Services.Dialogs
|
||||
{
|
||||
public interface ICreateKeyBindingDialog
|
||||
{
|
||||
Task<KeyBinding> CreateKeyBinding();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.Services.Dialogs
|
||||
{
|
||||
public interface IMessageDialog
|
||||
{
|
||||
string Title { get; set; }
|
||||
string Content { get; set; }
|
||||
|
||||
void AddButton(DialogButton button);
|
||||
|
||||
Task<DialogButton> ShowAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using FluentTerminal.Models;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.Services.Dialogs
|
||||
{
|
||||
public interface IShellProfileSelectionDialog
|
||||
{
|
||||
ShellProfile SelectedProfile { get; }
|
||||
|
||||
Task<ShellProfile> SelectProfile();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace FluentTerminal.App.Services.EventArgs
|
||||
{
|
||||
public class CancelableEventArgs : System.EventArgs
|
||||
{
|
||||
public bool Cancelled { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using System;
|
||||
|
||||
namespace FluentTerminal.App.Exceptions
|
||||
namespace FluentTerminal.App.Services.Exceptions
|
||||
{
|
||||
public class ParseThemeException : Exception
|
||||
{
|
||||
@@ -0,0 +1,24 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<LangVersion>7.1</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<LangVersion>7.1</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="PListNet" Version="2.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FluentTerminal.Models\FluentTerminal.Models.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public interface IAppServiceConnection
|
||||
{
|
||||
Task<IDictionary<string, string>> SendMessageAsync(IDictionary<string, string> message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public interface IApplicationDataContainer
|
||||
{
|
||||
T ReadValueFromJson<T>(string name, T fallbackValue);
|
||||
|
||||
void WriteValueAsJson<T>(string name, T value);
|
||||
|
||||
bool TryGetValue(string key, out object value);
|
||||
|
||||
void SetValue(string key, object value);
|
||||
|
||||
void Delete(string key);
|
||||
|
||||
IEnumerable<object> GetAll();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using FluentTerminal.App.Services.EventArgs;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public delegate Task CloseRequestedHandler(object sender, CancelableEventArgs args);
|
||||
|
||||
public interface IApplicationView
|
||||
{
|
||||
event CloseRequestedHandler CloseRequested;
|
||||
|
||||
string Title { get; set; }
|
||||
|
||||
Task RunOnDispatcherThread(Action action);
|
||||
Task<bool> TryClose();
|
||||
bool ToggleFullScreen();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public interface IClipboardService
|
||||
{
|
||||
Task<string> GetText();
|
||||
void SetText(string text);
|
||||
}
|
||||
}
|
||||
@@ -14,5 +14,7 @@ namespace FluentTerminal.App.Services
|
||||
Task<DialogButton> ShowMessageDialogAsnyc(string title, string content, params DialogButton[] buttons);
|
||||
|
||||
Task<ShellProfile> ShowProfileSelectionDialogAsync();
|
||||
|
||||
Task<KeyBinding> ShowCreateKeyBindingDialog();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public interface IDispatcherTimer
|
||||
{
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
TimeSpan Interval { get; set; }
|
||||
bool IsEnabled { get; }
|
||||
|
||||
event EventHandler<object> Tick;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using FluentTerminal.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public interface IFileSystemService
|
||||
{
|
||||
Task<File> OpenFile(IEnumerable<string> fileTypes);
|
||||
|
||||
Task<string> BrowseForDirectory();
|
||||
|
||||
Task SaveTextFile(string name, string fileTypeDescription, string fileType, string content);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public interface ISystemFontService
|
||||
{
|
||||
IEnumerable<string> GetSystemFontFamilies();
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FluentTerminal.App.Views
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public interface ITerminalView
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
using FluentTerminal.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
@@ -9,6 +9,6 @@ namespace FluentTerminal.App.Services
|
||||
{
|
||||
IEnumerable<string> SupportedFileTypes { get; }
|
||||
|
||||
Task<TerminalTheme> Parse(StorageFile themeFile);
|
||||
Task<TerminalTheme> Parse(string fileName, Stream fileContent);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
@@ -7,6 +6,6 @@ namespace FluentTerminal.App.Services
|
||||
{
|
||||
IEnumerable<string> SupportedFileTypes { get; }
|
||||
|
||||
IThemeParser GetParser(StorageFile themeFile);
|
||||
IThemeParser GetParser(string fileType);
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Responses;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.AppService;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public interface ITrayProcessCommunicationService
|
||||
{
|
||||
Task Initialize(AppServiceConnection appServiceConnection);
|
||||
Task Initialize(IAppServiceConnection appServiceConnection);
|
||||
Task<CreateTerminalResponse> CreateTerminal(TerminalSize size, ShellProfile shellProfile);
|
||||
Task ResizeTerminal(int id, TerminalSize size);
|
||||
Task UpdateToggleWindowKeyBindings();
|
||||
@@ -2,11 +2,10 @@
|
||||
using FluentTerminal.Models.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Windows.System;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
internal class DefaultValueProvider : IDefaultValueProvider
|
||||
public class DefaultValueProvider : IDefaultValueProvider
|
||||
{
|
||||
public ApplicationSettings GetDefaultApplicationSettings()
|
||||
{
|
||||
@@ -32,7 +31,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = false,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.Scroll
|
||||
Key = (int)ExtendedVirtualKey.Scroll
|
||||
}
|
||||
};
|
||||
|
||||
@@ -45,7 +44,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.Tab
|
||||
Key = (int)ExtendedVirtualKey.Tab
|
||||
}
|
||||
};
|
||||
|
||||
@@ -58,7 +57,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = true,
|
||||
Key = (int)VirtualKey.Tab
|
||||
Key = (int)ExtendedVirtualKey.Tab
|
||||
}
|
||||
};
|
||||
|
||||
@@ -71,7 +70,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.T
|
||||
Key = (int)ExtendedVirtualKey.T
|
||||
}
|
||||
};
|
||||
|
||||
@@ -84,7 +83,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = true,
|
||||
Key = (int)VirtualKey.T
|
||||
Key = (int)ExtendedVirtualKey.T
|
||||
}
|
||||
};
|
||||
|
||||
@@ -97,7 +96,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.W
|
||||
Key = (int)ExtendedVirtualKey.W
|
||||
}
|
||||
};
|
||||
|
||||
@@ -110,7 +109,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.N
|
||||
Key = (int)ExtendedVirtualKey.N
|
||||
}
|
||||
};
|
||||
|
||||
@@ -136,7 +135,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.C
|
||||
Key = (int)ExtendedVirtualKey.C
|
||||
}
|
||||
};
|
||||
|
||||
@@ -149,7 +148,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.V
|
||||
Key = (int)ExtendedVirtualKey.V
|
||||
}
|
||||
};
|
||||
|
||||
@@ -162,7 +161,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.F
|
||||
Key = (int)ExtendedVirtualKey.F
|
||||
}
|
||||
};
|
||||
|
||||
@@ -175,7 +174,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = false,
|
||||
Alt = true,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.Enter
|
||||
Key = (int)ExtendedVirtualKey.Enter
|
||||
}
|
||||
};
|
||||
|
||||
@@ -188,7 +187,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.A
|
||||
Key = (int)ExtendedVirtualKey.A
|
||||
}
|
||||
};
|
||||
|
||||
@@ -201,7 +200,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Ctrl = true,
|
||||
Alt = false,
|
||||
Shift = false,
|
||||
Key = (int)VirtualKey.L
|
||||
Key = (int)ExtendedVirtualKey.L
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -255,6 +254,15 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Location = @"C:\Windows\System32\cmd.exe",
|
||||
PreInstalled = true,
|
||||
WorkingDirectory = string.Empty
|
||||
},
|
||||
new ShellProfile
|
||||
{
|
||||
Id= Guid.Parse("e5785ad6-584f-40cb-bdcd-d5b3b3953e7f"),
|
||||
Name = "WSL",
|
||||
Arguments = string.Empty,
|
||||
Location = @"C:\windows\system32\wsl.exe",
|
||||
PreInstalled = true,
|
||||
WorkingDirectory = string.Empty
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -389,7 +397,39 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
}
|
||||
};
|
||||
|
||||
return new[] { defaultXterm, powerShell, homebrew, tomorrow };
|
||||
var ubuntu = new TerminalTheme
|
||||
{
|
||||
Id = Guid.Parse("32519543-bf94-4db6-92a1-7bcec3966c82"),
|
||||
Author = "Canonical",
|
||||
Name = "Ubuntu Bash",
|
||||
PreInstalled = true,
|
||||
Colors = new TerminalColors
|
||||
{
|
||||
Foreground = "#EEEEEE",
|
||||
Background = "#300A24",
|
||||
Cursor = "#CFF5DB",
|
||||
CursorAccent = "#000000",
|
||||
Selection = "#4DABEDC1",
|
||||
Black = "#300A24",
|
||||
Red = "#3465A4",
|
||||
Green = "#4E9A06",
|
||||
Yellow = "#06989A",
|
||||
Blue = "#CC0000",
|
||||
Magenta = "#75507B",
|
||||
Cyan = "#C4A000",
|
||||
White = "#D3D7CF",
|
||||
BrightBlack = "#554E53",
|
||||
BrightRed = "#729FCF",
|
||||
BrightGreen = "#8AE234",
|
||||
BrightYellow = "#34E2E2",
|
||||
BrightBlue = "#EF2929",
|
||||
BrightMagenta = "#AD7FA8",
|
||||
BrightCyan = "#FCE94F",
|
||||
BrightWhite = "#EEEEEE"
|
||||
}
|
||||
};
|
||||
|
||||
return new[] { defaultXterm, powerShell, homebrew, tomorrow, ubuntu };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using FluentTerminal.App.Services.Dialogs;
|
||||
using FluentTerminal.Models;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
public class DialogService : IDialogService
|
||||
{
|
||||
private readonly Func<IShellProfileSelectionDialog> _shellProfileSelectionDialogFactory;
|
||||
private readonly Func<IMessageDialog> _messageDialogFactory;
|
||||
private readonly Func<ICreateKeyBindingDialog> _createKeyBindingDialogFactory;
|
||||
|
||||
public DialogService(Func<IShellProfileSelectionDialog> shellProfileSelectionDialogFactory, Func<IMessageDialog> messageDialogFactory, Func<ICreateKeyBindingDialog> createKeyBindingDialogFactory)
|
||||
{
|
||||
_shellProfileSelectionDialogFactory = shellProfileSelectionDialogFactory;
|
||||
_messageDialogFactory = messageDialogFactory;
|
||||
_createKeyBindingDialogFactory = createKeyBindingDialogFactory;
|
||||
}
|
||||
|
||||
public Task<KeyBinding> ShowCreateKeyBindingDialog()
|
||||
{
|
||||
var dialog = _createKeyBindingDialogFactory();
|
||||
|
||||
return dialog.CreateKeyBinding();
|
||||
}
|
||||
|
||||
public Task<DialogButton> ShowMessageDialogAsnyc(string title, string content, params DialogButton[] buttons)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(title))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(title));
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(content))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(content));
|
||||
}
|
||||
|
||||
if (buttons.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("Must not be empty", nameof(buttons));
|
||||
}
|
||||
|
||||
var dialog = _messageDialogFactory();
|
||||
dialog.Content = content;
|
||||
dialog.Title = title;
|
||||
|
||||
foreach (var button in buttons)
|
||||
{
|
||||
dialog.AddButton(button);
|
||||
}
|
||||
|
||||
return dialog.ShowAsync();
|
||||
}
|
||||
|
||||
public Task<ShellProfile> ShowProfileSelectionDialogAsync()
|
||||
{
|
||||
var dialog = _shellProfileSelectionDialogFactory();
|
||||
|
||||
return dialog.SelectProfile();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using FluentTerminal.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
public class FluentTerminalThemeParser : IThemeParser
|
||||
{
|
||||
public IEnumerable<string> SupportedFileTypes { get; } = new string[] { ".flutecolors" };
|
||||
|
||||
public async Task<TerminalTheme> Parse(string fileName, Stream fileContent)
|
||||
{
|
||||
using (var streamReader = new StreamReader(fileContent))
|
||||
{
|
||||
var content = await streamReader.ReadToEndAsync();
|
||||
var theme = JsonConvert.DeserializeObject<TerminalTheme>(content);
|
||||
|
||||
theme.PreInstalled = false;
|
||||
theme.Id = Guid.NewGuid();
|
||||
|
||||
return theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,12 @@
|
||||
using FluentTerminal.App.Exceptions;
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.App.Services.Exceptions;
|
||||
using FluentTerminal.Models;
|
||||
using PListNet;
|
||||
using PListNet.Nodes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.UI;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
@@ -53,14 +51,13 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
public const string RedComponent = "Red Component";
|
||||
}
|
||||
|
||||
public async Task<TerminalTheme> Parse(StorageFile themeFile)
|
||||
public async Task<TerminalTheme> Parse(string fileName, Stream fileContent)
|
||||
{
|
||||
var stream = await themeFile.OpenStreamForReadAsync().ConfigureAwait(false);
|
||||
var node = PList.Load(stream) as DictionaryNode ?? throw new ParseThemeException("Root node was not a dictionary.");
|
||||
var node = PList.Load(fileContent) as DictionaryNode ?? throw new ParseThemeException("Root node was not a dictionary.");
|
||||
|
||||
return new TerminalTheme
|
||||
{
|
||||
Name = Path.GetFileNameWithoutExtension(themeFile.Name),
|
||||
Name = Path.GetFileNameWithoutExtension(fileName),
|
||||
Colors = GetColors(node),
|
||||
Id = Guid.NewGuid(),
|
||||
PreInstalled = false
|
||||
@@ -103,15 +100,15 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
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));
|
||||
var color = $"#{alpha:X2}{GetByteValue(red):X2}{GetByteValue(green):X2}{GetByteValue(blue):X2}";
|
||||
|
||||
if (alpha == byte.MaxValue)
|
||||
{
|
||||
return color.ToColorString(false);
|
||||
return $"#{GetByteValue(red):X2}{GetByteValue(green):X2}{GetByteValue(blue):X2}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return color.ToColorString(true);
|
||||
return $"rgba({GetByteValue(red):G}, {GetByteValue(green):G}, {GetByteValue(blue):G}, {ToDoubleString(alpha)})";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,5 +118,10 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
|
||||
return Convert.ToByte(doubleValue);
|
||||
}
|
||||
|
||||
private static string ToDoubleString(byte alpha)
|
||||
{
|
||||
return (alpha / 256.0).ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,13 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
handler.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
// already registered by SystemTray's ToggleWindowService
|
||||
if (command == Command.ToggleWindow)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
throw new KeyNotFoundException($"No handler registered for command: {command}");
|
||||
}
|
||||
}
|
||||
@@ -2,43 +2,38 @@
|
||||
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;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
internal class SettingsService : ISettingsService
|
||||
public 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";
|
||||
|
||||
private readonly IDefaultValueProvider _defaultValueProvider;
|
||||
private readonly ApplicationDataContainer _localSettings;
|
||||
private readonly ApplicationDataContainer _themes;
|
||||
private readonly ApplicationDataContainer _keyBindings;
|
||||
private readonly ApplicationDataContainer _shellProfiles;
|
||||
private readonly ApplicationDataContainer _roamingSettings;
|
||||
private readonly IApplicationDataContainer _localSettings;
|
||||
private readonly IApplicationDataContainer _themes;
|
||||
private readonly IApplicationDataContainer _keyBindings;
|
||||
private readonly IApplicationDataContainer _shellProfiles;
|
||||
private readonly IApplicationDataContainer _roamingSettings;
|
||||
|
||||
public event EventHandler<Guid> CurrentThemeChanged;
|
||||
public event EventHandler<TerminalOptions> TerminalOptionsChanged;
|
||||
public event EventHandler<ApplicationSettings> ApplicationSettingsChanged;
|
||||
public event EventHandler KeyBindingsChanged;
|
||||
|
||||
public SettingsService(IDefaultValueProvider defaultValueProvider)
|
||||
public SettingsService(IDefaultValueProvider defaultValueProvider, ApplicationDataContainers containers)
|
||||
{
|
||||
_defaultValueProvider = defaultValueProvider;
|
||||
_localSettings = ApplicationData.Current.LocalSettings;
|
||||
_roamingSettings = ApplicationData.Current.RoamingSettings;
|
||||
_localSettings = containers.LocalSettings;
|
||||
_roamingSettings = containers.RoamingSettings;
|
||||
|
||||
_themes = _roamingSettings.CreateContainer(ThemesContainerName, ApplicationDataCreateDisposition.Always);
|
||||
_keyBindings = _roamingSettings.CreateContainer(KeyBindingsContainerName, ApplicationDataCreateDisposition.Always);
|
||||
_shellProfiles = _roamingSettings.CreateContainer(ShellProfilesContainerName, ApplicationDataCreateDisposition.Always);
|
||||
_themes = containers.Themes;
|
||||
_keyBindings = containers.KeyBindings;
|
||||
_shellProfiles = containers.ShellProfiles;
|
||||
|
||||
foreach (var theme in _defaultValueProvider.GetPreInstalledThemes())
|
||||
{
|
||||
@@ -59,7 +54,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
|
||||
public Guid GetCurrentThemeId()
|
||||
{
|
||||
if (_roamingSettings.Values.TryGetValue(CurrentThemeKey, out object value))
|
||||
if (_roamingSettings.TryGetValue(CurrentThemeKey, out object value))
|
||||
{
|
||||
return (Guid)value;
|
||||
}
|
||||
@@ -68,7 +63,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
|
||||
public void SaveCurrentThemeId(Guid id)
|
||||
{
|
||||
_roamingSettings.Values[CurrentThemeKey] = id;
|
||||
_roamingSettings.SetValue(CurrentThemeKey, id);
|
||||
|
||||
CurrentThemeChanged?.Invoke(this, id);
|
||||
}
|
||||
@@ -85,12 +80,12 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
|
||||
public void DeleteTheme(Guid id)
|
||||
{
|
||||
_themes.Values.Remove(id.ToString());
|
||||
_themes.Delete(id.ToString());
|
||||
}
|
||||
|
||||
public IEnumerable<TerminalTheme> GetThemes()
|
||||
{
|
||||
return _themes.Values.Select(x => JsonConvert.DeserializeObject<TerminalTheme>((string)x.Value)).ToList();
|
||||
return _themes.GetAll().Select(x => JsonConvert.DeserializeObject<TerminalTheme>((string)x)).ToList();
|
||||
}
|
||||
|
||||
public TerminalTheme GetTheme(Guid id)
|
||||
@@ -136,7 +131,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
_keyBindings.WriteValueAsJson(command.ToString(), keyBindings);
|
||||
_roamingSettings.WriteValueAsJson(nameof(KeyBindings), keyBindings);
|
||||
KeyBindingsChanged?.Invoke(this, EventArgs.Empty);
|
||||
KeyBindingsChanged?.Invoke(this, System.EventArgs.Empty);
|
||||
}
|
||||
|
||||
public void ResetKeyBindings()
|
||||
@@ -147,12 +142,12 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
_keyBindings.WriteValueAsJson(command.ToString(), _defaultValueProvider.GetDefaultKeyBindings(command));
|
||||
}
|
||||
|
||||
KeyBindingsChanged?.Invoke(this, EventArgs.Empty);
|
||||
KeyBindingsChanged?.Invoke(this, System.EventArgs.Empty);
|
||||
}
|
||||
|
||||
public Guid GetDefaultShellProfileId()
|
||||
{
|
||||
if (_roamingSettings.Values.TryGetValue(DefaultShellProfileKey, out object value))
|
||||
if (_roamingSettings.TryGetValue(DefaultShellProfileKey, out object value))
|
||||
{
|
||||
return (Guid)value;
|
||||
}
|
||||
@@ -167,12 +162,12 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
|
||||
public void SaveDefaultShellProfileId(Guid id)
|
||||
{
|
||||
_roamingSettings.Values[DefaultShellProfileKey] = id;
|
||||
_roamingSettings.SetValue(DefaultShellProfileKey, id);
|
||||
}
|
||||
|
||||
public IEnumerable<ShellProfile> GetShellProfiles()
|
||||
{
|
||||
return _shellProfiles.Values.Select(x => JsonConvert.DeserializeObject<ShellProfile>((string)x.Value)).ToList();
|
||||
return _shellProfiles.GetAll().Select(x => JsonConvert.DeserializeObject<ShellProfile>((string)x)).ToList();
|
||||
}
|
||||
|
||||
public void SaveShellProfile(ShellProfile shellProfile)
|
||||
@@ -182,7 +177,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
|
||||
public void DeleteShellProfile(Guid id)
|
||||
{
|
||||
_shellProfiles.Values.Remove(id.ToString());
|
||||
_shellProfiles.Delete(id.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
@@ -16,9 +15,9 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
SupportedFileTypes = _parsers.SelectMany(p => p.SupportedFileTypes);
|
||||
}
|
||||
|
||||
public IThemeParser GetParser(StorageFile themeFile)
|
||||
public IThemeParser GetParser(string fileType)
|
||||
{
|
||||
return _parsers.FirstOrDefault(p => p.SupportedFileTypes.Contains(themeFile.FileType));
|
||||
return _parsers.FirstOrDefault(p => p.SupportedFileTypes.Contains(fileType));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using FluentTerminal.Models.Requests;
|
||||
using FluentTerminal.Models.Responses;
|
||||
using Newtonsoft.Json;
|
||||
using Windows.ApplicationModel.AppService;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
internal class TrayProcessCommunicationService : ITrayProcessCommunicationService
|
||||
public class TrayProcessCommunicationService : ITrayProcessCommunicationService
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
private AppServiceConnection _appServiceConnection;
|
||||
private IAppServiceConnection _appServiceConnection;
|
||||
|
||||
public TrayProcessCommunicationService(ISettingsService settingsService)
|
||||
{
|
||||
@@ -28,7 +26,7 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
Profile = shellProfile
|
||||
};
|
||||
|
||||
var message = new ValueSet
|
||||
var message = new Dictionary<string, string>
|
||||
{
|
||||
{ MessageKeys.Type, MessageTypes.CreateTerminalRequest },
|
||||
{ MessageKeys.Content, JsonConvert.SerializeObject(request) }
|
||||
@@ -36,10 +34,10 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
|
||||
var responseMessage = await _appServiceConnection.SendMessageAsync(message);
|
||||
|
||||
return JsonConvert.DeserializeObject<CreateTerminalResponse>((string)responseMessage.Message[MessageKeys.Content]);
|
||||
return JsonConvert.DeserializeObject<CreateTerminalResponse>(responseMessage[MessageKeys.Content]);
|
||||
}
|
||||
|
||||
public Task Initialize(AppServiceConnection appServiceConnection)
|
||||
public Task Initialize(IAppServiceConnection appServiceConnection)
|
||||
{
|
||||
_appServiceConnection = appServiceConnection;
|
||||
return UpdateToggleWindowKeyBindings();
|
||||
@@ -53,13 +51,13 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
NewSize = size
|
||||
};
|
||||
|
||||
var message = new ValueSet
|
||||
var message = new Dictionary<string, string>
|
||||
{
|
||||
{ MessageKeys.Type, MessageTypes.ResizeTerminalRequest },
|
||||
{ MessageKeys.Content, JsonConvert.SerializeObject(request) }
|
||||
};
|
||||
|
||||
return _appServiceConnection.SendMessageAsync(message).AsTask();
|
||||
return _appServiceConnection.SendMessageAsync(message);
|
||||
}
|
||||
|
||||
public Task UpdateToggleWindowKeyBindings()
|
||||
@@ -71,13 +69,13 @@ namespace FluentTerminal.App.Services.Implementation
|
||||
KeyBindings = keyBindings
|
||||
};
|
||||
|
||||
var message = new ValueSet
|
||||
var message = new Dictionary<string, string>
|
||||
{
|
||||
{ MessageKeys.Type, MessageTypes.SetToggleWindowKeyBindingsRequest },
|
||||
{ MessageKeys.Content, JsonConvert.SerializeObject(request) }
|
||||
};
|
||||
|
||||
return _appServiceConnection.SendMessageAsync(message).AsTask();
|
||||
return _appServiceConnection.SendMessageAsync(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace FluentTerminal.App.Utilities
|
||||
namespace FluentTerminal.App.Services.Utilities
|
||||
{
|
||||
public static class EnumHelper
|
||||
{
|
||||
@@ -9,7 +9,7 @@ namespace FluentTerminal.App.Utilities
|
||||
{
|
||||
var fieldInfo = value.GetType().GetField(value.ToString());
|
||||
|
||||
DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||
var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||
|
||||
if (attributes?.Length > 0)
|
||||
{
|
||||
@@ -3,7 +3,7 @@ using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System.Reflection;
|
||||
|
||||
namespace FluentTerminal.App.Utilities
|
||||
namespace FluentTerminal.App.Services.Utilities
|
||||
{
|
||||
public class TerminalThemeContractResolver : DefaultContractResolver
|
||||
{
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1,171 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProjectGuid>{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}</ProjectGuid>
|
||||
<OutputType>AppContainerExe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>FluentTerminal.App.Test</RootNamespace>
|
||||
<AssemblyName>FluentTerminal.App.Test</AssemblyName>
|
||||
<DefaultLanguage>de-DE</DefaultLanguage>
|
||||
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
|
||||
<TargetPlatformVersion>10.0.16299.0</TargetPlatformVersion>
|
||||
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
|
||||
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>FluentTerminal.App.Test_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<UnitTestPlatformVersion Condition="'$(UnitTestPlatformVersion)' == ''">$(VisualStudioVersion)</UnitTestPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\ARM\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
|
||||
<OutputPath>bin\ARM\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>ARM</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<NoWarn>;2008</NoWarn>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<SDKReference Include="TestPlatform.Universal, Version=$(UnitTestPlatformVersion)" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Services\DialogServiceTests.cs" />
|
||||
<Compile Include="Services\KeyboardCommandServiceTests.cs" />
|
||||
<Compile Include="UnitTestApp.xaml.cs">
|
||||
<DependentUpon>UnitTestApp.xaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="UnitTestApp.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxManifest Include="Package.appxmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</AppxManifest>
|
||||
<None Include="FluentTerminal.App.Test_TemporaryKey.pfx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Properties\UnitTestApp.rd.xml" />
|
||||
<Content Include="Assets\LockScreenLogo.scale-200.png" />
|
||||
<Content Include="Assets\SplashScreen.scale-200.png" />
|
||||
<Content Include="Assets\Square150x150Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.scale-200.png" />
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Assets\StoreLogo.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoFixture">
|
||||
<Version>4.4.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="FluentAssertions">
|
||||
<Version>5.3.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||
<Version>6.1.5</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Moq">
|
||||
<Version>4.8.3</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestAdapter">
|
||||
<Version>1.3.2</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MSTest.TestFramework">
|
||||
<Version>1.3.2</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FluentTerminal.App\FluentTerminal.App.csproj">
|
||||
<Project>{41020100-3414-4e0a-9a8e-92d3c4179df8}</Project>
|
||||
<Name>FluentTerminal.App</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\FluentTerminal.Models\FluentTerminal.Models.csproj">
|
||||
<Project>{5EA40453-A0AA-449E-8406-D6EA51D7E70E}</Project>
|
||||
<Name>FluentTerminal.Models</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -1,45 +0,0 @@
|
||||
<?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"
|
||||
IgnorableNamespaces="uap mp">
|
||||
|
||||
<Identity Name="63c2a56f-7075-408a-a37d-24bb7fb21665"
|
||||
Publisher="CN=Felix"
|
||||
Version="1.0.0.0" />
|
||||
|
||||
<mp:PhoneIdentity PhoneProductId="63c2a56f-7075-408a-a37d-24bb7fb21665" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
|
||||
|
||||
<Properties>
|
||||
<DisplayName>FluentTerminal.App.Test</DisplayName>
|
||||
<PublisherDisplayName>Felix</PublisherDisplayName>
|
||||
<Logo>Assets\StoreLogo.png</Logo>
|
||||
</Properties>
|
||||
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
|
||||
</Dependencies>
|
||||
|
||||
<Resources>
|
||||
<Resource Language="x-generate" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="vstest.executionengine.universal.App"
|
||||
Executable="$targetnametoken$.exe"
|
||||
EntryPoint="FluentTerminal.App.Test.App">
|
||||
<uap:VisualElements
|
||||
DisplayName="FluentTerminal.App.Test"
|
||||
Square150x150Logo="Assets\Square150x150Logo.png"
|
||||
Square44x44Logo="Assets\Square44x44Logo.png"
|
||||
Description="FluentTerminal.App.Test"
|
||||
BackgroundColor="transparent">
|
||||
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
|
||||
<uap:SplashScreen Image="Assets\SplashScreen.png" />
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<Capability Name="internetClientServer" />
|
||||
</Capabilities>
|
||||
</Package>
|
||||
@@ -1,18 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[assembly: AssemblyTitle("FluentTerminal.App.Test")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("FluentTerminal.App.Test")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: AssemblyMetadata("TargetPlatform","UAP")]
|
||||
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: ComVisible(false)]
|
||||
@@ -1,29 +0,0 @@
|
||||
<!--
|
||||
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
|
||||
developers. However, you can modify these parameters to modify the behavior of the .NET Native
|
||||
optimizer.
|
||||
|
||||
Runtime Directives are documented at http://go.microsoft.com/fwlink/?LinkID=391919
|
||||
|
||||
To fully enable reflection for App1.MyClass and all of its public/private members
|
||||
<Type Name="App1.MyClass" Dynamic="Required All"/>
|
||||
|
||||
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
|
||||
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
|
||||
|
||||
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
|
||||
<Namespace Name="DataClasses.ViewModels" Seralize="All" />
|
||||
-->
|
||||
|
||||
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
|
||||
<Application>
|
||||
<!--
|
||||
An Assembly element with Name="*Application*" applies to all assemblies in
|
||||
the application package. The asterisks are not wildcards.
|
||||
-->
|
||||
<Assembly Name="*Application*" Dynamic="Required All" />
|
||||
<!-- Add your application specific runtime directives here. -->
|
||||
|
||||
|
||||
</Application>
|
||||
</Directives>
|
||||
@@ -1,8 +0,0 @@
|
||||
<Application
|
||||
x:Class="FluentTerminal.App.Test.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:FluentTerminal.App.Test"
|
||||
RequestedTheme="Light">
|
||||
|
||||
</Application>
|
||||
@@ -1,102 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
|
||||
namespace FluentTerminal.App.Test
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides application-specific behavior to supplement the default Application class.
|
||||
/// </summary>
|
||||
sealed partial class App : Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
this.Suspending += OnSuspending;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the application is launched normally by the end user. Other entry points
|
||||
/// will be used such as when the application is launched to open a specific file.
|
||||
/// </summary>
|
||||
/// <param name="e">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||
{
|
||||
|
||||
#if DEBUG
|
||||
if (System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
this.DebugSettings.EnableFrameRateCounter = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
Frame rootFrame = Window.Current.Content as Frame;
|
||||
|
||||
// Do not repeat app initialization when the Window already has content,
|
||||
// just ensure that the window is active
|
||||
if (rootFrame == null)
|
||||
{
|
||||
// Create a Frame to act as the navigation context and navigate to the first page
|
||||
rootFrame = new Frame();
|
||||
|
||||
rootFrame.NavigationFailed += OnNavigationFailed;
|
||||
|
||||
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
|
||||
{
|
||||
//TODO: Load state from previously suspended application
|
||||
}
|
||||
|
||||
// Place the frame in the current Window
|
||||
Window.Current.Content = rootFrame;
|
||||
}
|
||||
|
||||
Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.CreateDefaultUI();
|
||||
|
||||
// Ensure the current window is active
|
||||
Window.Current.Activate();
|
||||
|
||||
Microsoft.VisualStudio.TestPlatform.TestExecutor.UnitTestClient.Run(e.Arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when Navigation to a certain page fails
|
||||
/// </summary>
|
||||
/// <param name="sender">The Frame which failed navigation</param>
|
||||
/// <param name="e">Details about the navigation failure</param>
|
||||
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
|
||||
{
|
||||
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when application execution is being suspended. Application state is saved
|
||||
/// without knowing whether the application will be terminated or resumed with the contents
|
||||
/// of memory still intact.
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the suspend request.</param>
|
||||
/// <param name="e">Details about the suspend request.</param>
|
||||
private void OnSuspending(object sender, SuspendingEventArgs e)
|
||||
{
|
||||
var deferral = e.SuspendingOperation.GetDeferral();
|
||||
//TODO: Save application state and stop any background activity
|
||||
deferral.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fleck" Version="1.0.3" />
|
||||
<PackageReference Include="MvvmLightLibs" Version="5.4.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FluentTerminal.App.Services\FluentTerminal.App.Services.csproj" />
|
||||
<ProjectReference Include="..\FluentTerminal.Models\FluentTerminal.Models.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,4 +1,5 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Services.EventArgs;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using GalaSoft.MvvmLight;
|
||||
@@ -7,10 +8,6 @@ using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Core.Preview;
|
||||
using Windows.UI.ViewManagement;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels
|
||||
{
|
||||
@@ -23,16 +20,19 @@ namespace FluentTerminal.App.ViewModels
|
||||
private ApplicationSettings _applicationSettings;
|
||||
private string _background;
|
||||
private double _backgroundOpacity;
|
||||
private readonly CoreDispatcher _dispatcher;
|
||||
private int _nextTerminalId;
|
||||
private TerminalViewModel _selectedTerminal;
|
||||
private string _title;
|
||||
private readonly IApplicationView _applicationView;
|
||||
private readonly IDispatcherTimer _dispatcherTimer;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
|
||||
public event EventHandler Closed;
|
||||
public event EventHandler NewWindowRequested;
|
||||
public event EventHandler ShowSettingsRequested;
|
||||
|
||||
public MainViewModel(ISettingsService settingsService, ITrayProcessCommunicationService trayProcessCommunicationService, IDialogService dialogService, IKeyboardCommandService keyboardCommandService)
|
||||
public MainViewModel(ISettingsService settingsService, ITrayProcessCommunicationService trayProcessCommunicationService, IDialogService dialogService, IKeyboardCommandService keyboardCommandService,
|
||||
IApplicationView applicationView, IDispatcherTimer dispatcherTimer, IClipboardService clipboardService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_settingsService.CurrentThemeChanged += OnCurrentThemeChanged;
|
||||
@@ -40,6 +40,9 @@ namespace FluentTerminal.App.ViewModels
|
||||
_settingsService.TerminalOptionsChanged += OnTerminalOptionsChanged;
|
||||
_trayProcessCommunicationService = trayProcessCommunicationService;
|
||||
_dialogService = dialogService;
|
||||
_applicationView = applicationView;
|
||||
_dispatcherTimer = dispatcherTimer;
|
||||
_clipboardService = clipboardService;
|
||||
_keyboardCommandService = keyboardCommandService;
|
||||
_keyboardCommandService.RegisterCommandHandler(Command.NewTab, () => AddTerminal(null, false));
|
||||
_keyboardCommandService.RegisterCommandHandler(Command.ConfigurableNewTab, () => AddTerminal(null, true));
|
||||
@@ -62,13 +65,12 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
Title = "Fluent Terminal";
|
||||
|
||||
_dispatcher = CoreApplication.GetCurrentView().Dispatcher;
|
||||
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += OnCloseRequest;
|
||||
_applicationView.CloseRequested += OnCloseRequest;
|
||||
}
|
||||
|
||||
private async void OnTerminalOptionsChanged(object sender, TerminalOptions e)
|
||||
{
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
|
||||
await _applicationView.RunOnDispatcherThread(() =>
|
||||
{
|
||||
BackgroundOpacity = e.BackgroundOpacity;
|
||||
});
|
||||
@@ -120,7 +122,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
public Task AddTerminal(string startupDirectory, bool showProfileSelection)
|
||||
{
|
||||
return _dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
|
||||
return _applicationView.RunOnDispatcherThread(async () =>
|
||||
{
|
||||
ShellProfile profile = null;
|
||||
if (showProfileSelection)
|
||||
@@ -137,13 +139,14 @@ namespace FluentTerminal.App.ViewModels
|
||||
profile = _settingsService.GetDefaultShellProfile();
|
||||
}
|
||||
|
||||
var terminal = new TerminalViewModel(GetNextTerminalId(), _settingsService, _trayProcessCommunicationService, _dialogService, _keyboardCommandService, _applicationSettings, startupDirectory, profile);
|
||||
var terminal = new TerminalViewModel(GetNextTerminalId(), _settingsService, _trayProcessCommunicationService, _dialogService, _keyboardCommandService,
|
||||
_applicationSettings, startupDirectory, profile, _applicationView, _dispatcherTimer, _clipboardService);
|
||||
terminal.CloseRequested += OnTerminalCloseRequested;
|
||||
terminal.TitleChanged += OnTitleChanged;
|
||||
Terminals.Add(terminal);
|
||||
|
||||
SelectedTerminal = terminal;
|
||||
}).AsTask();
|
||||
});
|
||||
}
|
||||
|
||||
public void CloseAllTerminals()
|
||||
@@ -171,13 +174,11 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
private async void OnApplicationSettingsChanged(object sender, ApplicationSettings e)
|
||||
{
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => _applicationSettings = e);
|
||||
await _applicationView.RunOnDispatcherThread(() => _applicationSettings = e);
|
||||
}
|
||||
|
||||
private async void OnCloseRequest(object sender, SystemNavigationCloseRequestedPreviewEventArgs e)
|
||||
private async Task OnCloseRequest(object sender, CancelableEventArgs e)
|
||||
{
|
||||
var deferral = e.GetDeferral();
|
||||
|
||||
if (_applicationSettings.ConfirmClosingWindows)
|
||||
{
|
||||
var result = await _dialogService.ShowMessageDialogAsnyc("Please confirm", "Are you sure you want to close this window?", DialogButton.OK, DialogButton.Cancel).ConfigureAwait(false);
|
||||
@@ -189,7 +190,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Handled = true;
|
||||
e.Cancelled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -197,12 +198,11 @@ namespace FluentTerminal.App.ViewModels
|
||||
CloseAllTerminals();
|
||||
Closed?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
deferral.Complete();
|
||||
}
|
||||
|
||||
private async void OnCurrentThemeChanged(object sender, Guid e)
|
||||
{
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
|
||||
await _applicationView.RunOnDispatcherThread(() =>
|
||||
{
|
||||
var currentTheme = _settingsService.GetTheme(e);
|
||||
Background = currentTheme.Colors.Background;
|
||||
@@ -223,7 +223,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
if (Terminals.Count == 0)
|
||||
{
|
||||
Closed?.Invoke(this, EventArgs.Empty);
|
||||
ApplicationView.GetForCurrentView().TryConsolidateAsync();
|
||||
_applicationView.TryClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -262,19 +262,10 @@ namespace FluentTerminal.App.ViewModels
|
||||
{
|
||||
ShowSettingsRequested?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
|
||||
private void ToggleFullScreen()
|
||||
{
|
||||
var applicationView = ApplicationView.GetForCurrentView();
|
||||
|
||||
if (applicationView.IsFullScreenMode)
|
||||
{
|
||||
applicationView.ExitFullScreenMode();
|
||||
}
|
||||
else
|
||||
{
|
||||
applicationView.TryEnterFullScreenMode();
|
||||
}
|
||||
_applicationView.ToggleFullScreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Views;
|
||||
using FluentTerminal.Models;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels.Settings
|
||||
{
|
||||
@@ -97,16 +95,15 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
|
||||
public async Task<bool> Edit()
|
||||
{
|
||||
var dialog = new CreateKeyBindingDialog(_dialogService);
|
||||
var result = await dialog.ShowAsync();
|
||||
var keyBinding = await _dialogService.ShowCreateKeyBindingDialog().ConfigureAwait(true);
|
||||
|
||||
if (result == ContentDialogResult.Primary)
|
||||
if (keyBinding != null)
|
||||
{
|
||||
Alt = dialog.KeyBinding.Alt;
|
||||
Ctrl = dialog.KeyBinding.Ctrl;
|
||||
Shift = dialog.KeyBinding.Shift;
|
||||
Meta = dialog.KeyBinding.Meta;
|
||||
Key = dialog.KeyBinding.Key;
|
||||
Alt = keyBinding.Alt;
|
||||
Ctrl = keyBinding.Ctrl;
|
||||
Shift = keyBinding.Shift;
|
||||
Meta = keyBinding.Meta;
|
||||
Key = keyBinding.Key;
|
||||
|
||||
Edited?.Invoke(this, EventArgs.Empty);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.App.Services.Utilities;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using GalaSoft.MvvmLight;
|
||||
@@ -13,20 +13,23 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
private readonly IDefaultValueProvider _defaultValueProvider;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IFileSystemService _fileSystemService;
|
||||
private ShellProfileViewModel _selectedShellProfile;
|
||||
|
||||
|
||||
public ProfilesPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider)
|
||||
public ProfilesPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider, IFileSystemService fileSystemService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_dialogService = dialogService;
|
||||
_defaultValueProvider = defaultValueProvider;
|
||||
_fileSystemService = fileSystemService;
|
||||
|
||||
CreateShellProfileCommand = new RelayCommand(CreateShellProfile);
|
||||
|
||||
var defaultShellProfileId = _settingsService.GetDefaultShellProfileId();
|
||||
foreach (var shellProfile in _settingsService.GetShellProfiles())
|
||||
{
|
||||
var viewModel = new ShellProfileViewModel(shellProfile, settingsService, dialogService);
|
||||
var viewModel = new ShellProfileViewModel(shellProfile, settingsService, dialogService, fileSystemService);
|
||||
viewModel.Deleted += OnShellProfileDeleted;
|
||||
viewModel.SetAsDefault += OnShellProfileSetAsDefault;
|
||||
|
||||
@@ -85,7 +88,7 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
|
||||
_settingsService.SaveShellProfile(shellProfile);
|
||||
|
||||
var viewModel = new ShellProfileViewModel(shellProfile, _settingsService, _dialogService);
|
||||
var viewModel = new ShellProfileViewModel(shellProfile, _settingsService, _dialogService, _fileSystemService);
|
||||
viewModel.EditCommand.Execute(null);
|
||||
viewModel.SetAsDefault += OnShellProfileSetAsDefault;
|
||||
viewModel.Deleted += OnShellProfileDeleted;
|
||||
@@ -3,7 +3,6 @@ using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@@ -198,7 +197,7 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
}
|
||||
}
|
||||
|
||||
public TerminalPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider)
|
||||
public TerminalPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider, ISystemFontService systemFontService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_dialogService = dialogService;
|
||||
@@ -206,7 +205,7 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
|
||||
RestoreDefaultsCommand = new RelayCommand(async () => await RestoreDefaults().ConfigureAwait(false));
|
||||
|
||||
Fonts = CanvasTextFormat.GetSystemFontFamilies().OrderBy(s => s);
|
||||
Fonts = systemFontService.GetSystemFontFamilies().OrderBy(s => s);
|
||||
Sizes = Enumerable.Range(1, 72);
|
||||
|
||||
_terminalOptions = _settingsService.GetTerminalOptions();
|
||||
@@ -1,13 +1,10 @@
|
||||
using FluentTerminal.App.Exceptions;
|
||||
using FluentTerminal.App.Services;
|
||||
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
|
||||
{
|
||||
@@ -19,15 +16,18 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
private ThemeViewModel _selectedTheme;
|
||||
private double _backgroundOpacity;
|
||||
private readonly IThemeParserFactory _themeParserFactory;
|
||||
private readonly IFileSystemService _fileSystemService;
|
||||
|
||||
public event EventHandler<Color> SelectedThemeBackgroundColorChanged;
|
||||
public event EventHandler<string> SelectedThemeBackgroundColorChanged;
|
||||
|
||||
public ThemesPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider, IThemeParserFactory themeParserFactory)
|
||||
public ThemesPageViewModel(ISettingsService settingsService, IDialogService dialogService, IDefaultValueProvider defaultValueProvider,
|
||||
IThemeParserFactory themeParserFactory, IFileSystemService fileSystemService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
_dialogService = dialogService;
|
||||
_defaultValueProvider = defaultValueProvider;
|
||||
_themeParserFactory = themeParserFactory;
|
||||
_fileSystemService = fileSystemService;
|
||||
|
||||
CreateThemeCommand = new RelayCommand(CreateTheme);
|
||||
ImportThemeCommand = new RelayCommand(ImportTheme);
|
||||
@@ -39,7 +39,7 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
var activeThemeId = _settingsService.GetCurrentThemeId();
|
||||
foreach (var theme in _settingsService.GetThemes())
|
||||
{
|
||||
var viewModel = new ThemeViewModel(theme, _settingsService, _dialogService);
|
||||
var viewModel = new ThemeViewModel(theme, _settingsService, _dialogService, fileSystemService);
|
||||
viewModel.Activated += OnThemeActivated;
|
||||
viewModel.Deleted += OnThemeDeleted;
|
||||
|
||||
@@ -51,7 +51,6 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
}
|
||||
|
||||
SelectedTheme = Themes.First(t => t.IsActive);
|
||||
|
||||
}
|
||||
|
||||
public RelayCommand CreateThemeCommand { get; }
|
||||
@@ -95,7 +94,7 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
|
||||
_settingsService.SaveTheme(theme);
|
||||
|
||||
var viewModel = new ThemeViewModel(theme, _settingsService, _dialogService);
|
||||
var viewModel = new ThemeViewModel(theme, _settingsService, _dialogService, _fileSystemService);
|
||||
viewModel.Activated += OnThemeActivated;
|
||||
viewModel.Deleted += OnThemeDeleted;
|
||||
Themes.Add(viewModel);
|
||||
@@ -104,20 +103,10 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
|
||||
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();
|
||||
var file = await _fileSystemService.OpenFile(_themeParserFactory.SupportedFileTypes).ConfigureAwait(true);
|
||||
if (file != null)
|
||||
{
|
||||
var parser = _themeParserFactory.GetParser(file);
|
||||
var parser = _themeParserFactory.GetParser(file.FileType);
|
||||
|
||||
if (parser == null)
|
||||
{
|
||||
@@ -127,11 +116,11 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
|
||||
try
|
||||
{
|
||||
var theme = await parser.Parse(file).ConfigureAwait(true);
|
||||
var theme = await parser.Parse(file.Name, file.Content).ConfigureAwait(true);
|
||||
|
||||
_settingsService.SaveTheme(theme);
|
||||
|
||||
var viewModel = new ThemeViewModel(theme, _settingsService, _dialogService);
|
||||
var viewModel = new ThemeViewModel(theme, _settingsService, _dialogService, _fileSystemService);
|
||||
viewModel.Activated += OnThemeActivated;
|
||||
viewModel.Deleted += OnThemeDeleted;
|
||||
Themes.Add(viewModel);
|
||||
@@ -181,7 +170,7 @@ namespace FluentTerminal.App.ViewModels.Settings
|
||||
BackgroundOpacity = e.BackgroundOpacity;
|
||||
}
|
||||
|
||||
private void OnSelectedThemeBackgroundChanged(object sender, Color e)
|
||||
private void OnSelectedThemeBackgroundChanged(object sender, string e)
|
||||
{
|
||||
SelectedThemeBackgroundColorChanged?.Invoke(this, e);
|
||||
}
|
||||
@@ -7,13 +7,14 @@ namespace FluentTerminal.App.ViewModels
|
||||
{
|
||||
public class SettingsViewModel : ViewModelBase
|
||||
{
|
||||
public SettingsViewModel(ISettingsService settingsService, IDefaultValueProvider defaultValueProvider, IDialogService dialogService, ITrayProcessCommunicationService trayProcessCommunicationService, IThemeParserFactory themeParserFactory)
|
||||
public SettingsViewModel(ISettingsService settingsService, IDefaultValueProvider defaultValueProvider, IDialogService dialogService,
|
||||
ITrayProcessCommunicationService trayProcessCommunicationService, IThemeParserFactory themeParserFactory, ISystemFontService systemFontService, IFileSystemService fileSystemService)
|
||||
{
|
||||
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, themeParserFactory);
|
||||
Shell = new ProfilesPageViewModel(settingsService, dialogService, defaultValueProvider, fileSystemService);
|
||||
Terminal = new TerminalPageViewModel(settingsService, dialogService, defaultValueProvider, systemFontService);
|
||||
Themes = new ThemesPageViewModel(settingsService, dialogService, defaultValueProvider, themeParserFactory, fileSystemService);
|
||||
}
|
||||
|
||||
public event EventHandler Closed;
|
||||
@@ -4,7 +4,6 @@ using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage.Pickers;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels
|
||||
{
|
||||
@@ -23,12 +22,14 @@ namespace FluentTerminal.App.ViewModels
|
||||
private bool _inEditMode;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly IFileSystemService _fileSystemService;
|
||||
|
||||
public ShellProfileViewModel(ShellProfile shellProfile, ISettingsService settingsService, IDialogService dialogService)
|
||||
public ShellProfileViewModel(ShellProfile shellProfile, ISettingsService settingsService, IDialogService dialogService, IFileSystemService fileSystemService)
|
||||
{
|
||||
_shellProfile = shellProfile;
|
||||
_settingsService = settingsService;
|
||||
_dialogService = dialogService;
|
||||
_fileSystemService = fileSystemService;
|
||||
|
||||
Id = shellProfile.Id;
|
||||
Name = shellProfile.Name;
|
||||
@@ -157,13 +158,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
private async Task BrowseForCustomShell()
|
||||
{
|
||||
var picker = new FileOpenPicker
|
||||
{
|
||||
SuggestedStartLocation = PickerLocationId.ComputerFolder
|
||||
};
|
||||
picker.FileTypeFilter.Add(".exe");
|
||||
|
||||
var file = await picker.PickSingleFileAsync();
|
||||
var file = await _fileSystemService.OpenFile(new[] { ".exe" }).ConfigureAwait(true);
|
||||
if (file != null)
|
||||
{
|
||||
Location = file.Path;
|
||||
@@ -172,14 +167,10 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
private async Task BrowseForWorkingDirectory()
|
||||
{
|
||||
var picker = new FolderPicker();
|
||||
picker.FileTypeFilter.Add(".whatever"); // else a ComException is thrown
|
||||
picker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
|
||||
|
||||
var folder = await picker.PickSingleFolderAsync();
|
||||
if (folder != null)
|
||||
var directory = await _fileSystemService.BrowseForDirectory().ConfigureAwait(true);
|
||||
if (directory != null)
|
||||
{
|
||||
WorkingDirectory = folder.Path;
|
||||
WorkingDirectory = directory;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Views;
|
||||
using Fleck;
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using GalaSoft.MvvmLight;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Xaml;
|
||||
|
||||
namespace FluentTerminal.App.ViewModels
|
||||
{
|
||||
@@ -22,9 +22,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ITrayProcessCommunicationService _trayProcessCommunicationService;
|
||||
private ApplicationSettings _applicationSettings;
|
||||
private readonly CoreDispatcher _dispatcher;
|
||||
private string _resizeOverlayContent;
|
||||
private readonly DispatcherTimer _resizeOverlayTimer;
|
||||
private bool _showResizeOverlay;
|
||||
private readonly string _startupDirectory;
|
||||
private int _terminalId;
|
||||
@@ -34,9 +32,15 @@ namespace FluentTerminal.App.ViewModels
|
||||
private bool _showSearchPanel;
|
||||
private string _searchText;
|
||||
private bool _isSelected;
|
||||
private readonly IApplicationView _applicationView;
|
||||
private readonly IDispatcherTimer _resizeOverlayTimer;
|
||||
private readonly IClipboardService _clipboardService;
|
||||
private IWebSocketConnection _webSocket;
|
||||
private NamedPipeClientStream _namedPipe;
|
||||
|
||||
public TerminalViewModel(int id, ISettingsService settingsService, ITrayProcessCommunicationService trayProcessCommunicationService, IDialogService dialogService,
|
||||
IKeyboardCommandService keyboardCommandService, ApplicationSettings applicationSettings, string startupDirectory, ShellProfile shellProfile)
|
||||
IKeyboardCommandService keyboardCommandService, ApplicationSettings applicationSettings, string startupDirectory, ShellProfile shellProfile,
|
||||
IApplicationView applicationView, IDispatcherTimer dispatcherTimer, IClipboardService clipboardService)
|
||||
{
|
||||
Id = id;
|
||||
Title = DefaultTitle;
|
||||
@@ -52,24 +56,23 @@ namespace FluentTerminal.App.ViewModels
|
||||
_applicationSettings = applicationSettings;
|
||||
_startupDirectory = startupDirectory;
|
||||
_shellProfile = shellProfile;
|
||||
_resizeOverlayTimer = new DispatcherTimer
|
||||
{
|
||||
Interval = new TimeSpan(0, 0, 2)
|
||||
};
|
||||
_applicationView = applicationView;
|
||||
_clipboardService = clipboardService;
|
||||
_resizeOverlayTimer = dispatcherTimer;
|
||||
_resizeOverlayTimer.Interval = new TimeSpan(0, 0, 2);
|
||||
_resizeOverlayTimer.Tick += OnResizeOverlayTimerFinished;
|
||||
|
||||
CloseCommand = new RelayCommand(async () => await InvokeCloseRequested().ConfigureAwait(false));
|
||||
FindNextCommand = new RelayCommand(async () => await FindNext().ConfigureAwait(false));
|
||||
FindPreviousCommand = new RelayCommand(async () => await FindPrevious().ConfigureAwait(false));
|
||||
CloseSearchPanelCommand = new RelayCommand(CloseSearchPanel);
|
||||
|
||||
_dispatcher = CoreApplication.GetCurrentView().Dispatcher;
|
||||
|
||||
}
|
||||
|
||||
private async void OnKeyBindingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
var keyBindings = _settingsService.GetKeyBindings();
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
|
||||
await _applicationView.RunOnDispatcherThread(async () =>
|
||||
{
|
||||
await _terminalView.ChangeKeyBindings(FlattenKeyBindings(keyBindings)).ConfigureAwait(false);
|
||||
});
|
||||
@@ -191,7 +194,37 @@ namespace FluentTerminal.App.ViewModels
|
||||
DefaultTitle = response.ShellExecutableName;
|
||||
Title = DefaultTitle;
|
||||
|
||||
await _terminalView.ConnectToSocket(response.WebSocketUrl).ConfigureAwait(true);
|
||||
_namedPipe = new NamedPipeClientStream(".", response.PipeName, PipeDirection.InOut, PipeOptions.None);
|
||||
if (!_namedPipe.IsConnected)
|
||||
{
|
||||
_namedPipe.Connect();
|
||||
}
|
||||
|
||||
var webSocketUrl = "ws://127.0.0.1:" + response.Port;
|
||||
var webSocketServer = new WebSocketServer(webSocketUrl);
|
||||
webSocketServer.Start(socket =>
|
||||
{
|
||||
_webSocket = socket;
|
||||
socket.OnOpen = () =>
|
||||
{
|
||||
Console.WriteLine("open");
|
||||
//_connectedEvent.Set();
|
||||
};
|
||||
socket.OnClose = () =>
|
||||
{
|
||||
Console.WriteLine("closing");
|
||||
_namedPipe.Close();
|
||||
};
|
||||
socket.OnMessage = message =>
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(message);
|
||||
_namedPipe.Write(bytes, 0, bytes.Length);
|
||||
};
|
||||
});
|
||||
|
||||
ListenToNamedPipe();
|
||||
|
||||
await _terminalView.ConnectToSocket(webSocketUrl).ConfigureAwait(true);
|
||||
Initialized = true;
|
||||
}
|
||||
else
|
||||
@@ -202,6 +235,26 @@ namespace FluentTerminal.App.ViewModels
|
||||
await FocusTerminal().ConfigureAwait(true);
|
||||
}
|
||||
|
||||
private void ListenToNamedPipe()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var reader = new StreamReader(_namedPipe);
|
||||
do
|
||||
{
|
||||
var offset = 0;
|
||||
var buffer = new char[1024];
|
||||
var readChars = await reader.ReadAsync(buffer, offset, buffer.Length - offset);
|
||||
if (readChars > 0)
|
||||
{
|
||||
await _webSocket.Send(new String(buffer));
|
||||
}
|
||||
}
|
||||
while (!reader.EndOfStream);
|
||||
_webSocket.Close();
|
||||
});
|
||||
}
|
||||
|
||||
private async Task InvokeCloseRequested()
|
||||
{
|
||||
if (_applicationSettings.ConfirmClosingTabs)
|
||||
@@ -219,7 +272,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
private async void OnApplicationSettingsChanged(object sender, ApplicationSettings e)
|
||||
{
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
|
||||
await _applicationView.RunOnDispatcherThread(() =>
|
||||
{
|
||||
_applicationSettings = e;
|
||||
RaisePropertyChanged(nameof(IsUnderlined));
|
||||
@@ -228,7 +281,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
private async void OnCurrentThemeChanged(object sender, Guid e)
|
||||
{
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
|
||||
await _applicationView.RunOnDispatcherThread(async () =>
|
||||
{
|
||||
var currentTheme = _settingsService.GetTheme(e);
|
||||
await _terminalView.ChangeTheme(currentTheme.Colors).ConfigureAwait(true);
|
||||
@@ -240,17 +293,14 @@ namespace FluentTerminal.App.ViewModels
|
||||
if (e == Command.Copy)
|
||||
{
|
||||
var selection = await _terminalView.GetSelection().ConfigureAwait(true);
|
||||
var dataPackage = new DataPackage();
|
||||
dataPackage.SetText(selection);
|
||||
Clipboard.SetContent(dataPackage);
|
||||
_clipboardService.SetText(selection);
|
||||
}
|
||||
else if (e == Command.Paste)
|
||||
{
|
||||
var content = Clipboard.GetContent();
|
||||
if (content.Contains(StandardDataFormats.Text))
|
||||
var content = await _clipboardService.GetText().ConfigureAwait(true);
|
||||
if (content != null)
|
||||
{
|
||||
var text = await content.GetTextAsync();
|
||||
await _terminalView.Write(text).ConfigureAwait(true);
|
||||
await _terminalView.Write(content).ConfigureAwait(true);
|
||||
}
|
||||
}
|
||||
else if (e == Command.Search)
|
||||
@@ -275,7 +325,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
private async void OnTerminalOptionsChanged(object sender, TerminalOptions e)
|
||||
{
|
||||
await _dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
|
||||
await _applicationView.RunOnDispatcherThread(async () =>
|
||||
{
|
||||
await _terminalView.ChangeOptions(e).ConfigureAwait(true);
|
||||
});
|
||||
@@ -318,5 +368,34 @@ namespace FluentTerminal.App.ViewModels
|
||||
ShowSearchPanel = false;
|
||||
_terminalView.FocusTerminal();
|
||||
}
|
||||
|
||||
private const int FirstDynamicPort = 49151;
|
||||
|
||||
public static int? GetAvailablePort()
|
||||
{
|
||||
var usedPorts = new List<int>();
|
||||
|
||||
var properties = IPGlobalProperties.GetIPGlobalProperties();
|
||||
|
||||
var connections = properties.GetActiveTcpConnections();
|
||||
usedPorts.AddRange(connections.Where(c => c.LocalEndPoint.Port >= FirstDynamicPort).Select(c => c.LocalEndPoint.Port));
|
||||
|
||||
var endPoints = properties.GetActiveTcpListeners();
|
||||
usedPorts.AddRange(endPoints.Where(e => e.Port >= FirstDynamicPort).Select(e => e.Port));
|
||||
|
||||
endPoints = properties.GetActiveUdpListeners();
|
||||
usedPorts.AddRange(endPoints.Where(e => e.Port >= FirstDynamicPort).Select(e => e.Port));
|
||||
|
||||
usedPorts.Sort();
|
||||
|
||||
for (var i = FirstDynamicPort; i < UInt16.MaxValue; i++)
|
||||
{
|
||||
if (!usedPorts.Contains(i))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,16 +1,11 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.App.Services.Utilities;
|
||||
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
|
||||
{
|
||||
@@ -19,71 +14,73 @@ namespace FluentTerminal.App.ViewModels
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly ISettingsService _settingsService;
|
||||
private string _author;
|
||||
private Color _background;
|
||||
private string _background;
|
||||
private double _backgroundOpacity;
|
||||
private Color _black;
|
||||
private Color _blue;
|
||||
private Color _brightBlack;
|
||||
private Color _brightBlue;
|
||||
private Color _brightCyan;
|
||||
private Color _brightGreen;
|
||||
private Color _brightMagenta;
|
||||
private Color _brightRed;
|
||||
private Color _brightWhite;
|
||||
private Color _brightYellow;
|
||||
private Color _cursor;
|
||||
private Color _cursorAccent;
|
||||
private Color _cyan;
|
||||
private string _black;
|
||||
private string _blue;
|
||||
private string _brightBlack;
|
||||
private string _brightBlue;
|
||||
private string _brightCyan;
|
||||
private string _brightGreen;
|
||||
private string _brightMagenta;
|
||||
private string _brightRed;
|
||||
private string _brightWhite;
|
||||
private string _brightYellow;
|
||||
private string _cursor;
|
||||
private string _cursorAccent;
|
||||
private string _cyan;
|
||||
private string _fallBackAuthor;
|
||||
private TerminalColors _fallBackColors;
|
||||
private string _fallBackName;
|
||||
private Color _foreground;
|
||||
private Color _green;
|
||||
private string _foreground;
|
||||
private string _green;
|
||||
private bool _inEditMode;
|
||||
private bool _isActive;
|
||||
private Color _magenta;
|
||||
private string _magenta;
|
||||
private string _name;
|
||||
private Color _red;
|
||||
private Color _selection;
|
||||
private string _red;
|
||||
private string _selection;
|
||||
private readonly TerminalTheme _theme;
|
||||
private Color _white;
|
||||
private Color _yellow;
|
||||
private string _white;
|
||||
private string _yellow;
|
||||
private readonly IFileSystemService _fileSystemService;
|
||||
|
||||
public event EventHandler<Color> BackgroundChanged;
|
||||
public event EventHandler<string> BackgroundChanged;
|
||||
|
||||
public ThemeViewModel(TerminalTheme theme, ISettingsService settingsService, IDialogService dialogService)
|
||||
public ThemeViewModel(TerminalTheme theme, ISettingsService settingsService, IDialogService dialogService, IFileSystemService fileSystemService)
|
||||
{
|
||||
_theme = theme;
|
||||
_settingsService = settingsService;
|
||||
_dialogService = dialogService;
|
||||
_fileSystemService = fileSystemService;
|
||||
|
||||
Name = _theme.Name;
|
||||
Author = _theme.Author;
|
||||
Id = _theme.Id;
|
||||
|
||||
Black = _theme.Colors.Black.ToColor();
|
||||
Red = _theme.Colors.Red.ToColor();
|
||||
Green = _theme.Colors.Green.ToColor();
|
||||
Yellow = _theme.Colors.Yellow.ToColor();
|
||||
Blue = _theme.Colors.Blue.ToColor();
|
||||
Magenta = _theme.Colors.Magenta.ToColor();
|
||||
Cyan = _theme.Colors.Cyan.ToColor();
|
||||
White = _theme.Colors.White.ToColor();
|
||||
Black = _theme.Colors.Black;
|
||||
Red = _theme.Colors.Red;
|
||||
Green = _theme.Colors.Green;
|
||||
Yellow = _theme.Colors.Yellow;
|
||||
Blue = _theme.Colors.Blue;
|
||||
Magenta = _theme.Colors.Magenta;
|
||||
Cyan = _theme.Colors.Cyan;
|
||||
White = _theme.Colors.White;
|
||||
|
||||
BrightBlack = _theme.Colors.BrightBlack.ToColor();
|
||||
BrightRed = _theme.Colors.BrightRed.ToColor();
|
||||
BrightGreen = _theme.Colors.BrightGreen.ToColor();
|
||||
BrightYellow = _theme.Colors.BrightYellow.ToColor();
|
||||
BrightBlue = _theme.Colors.BrightBlue.ToColor();
|
||||
BrightMagenta = _theme.Colors.BrightMagenta.ToColor();
|
||||
BrightCyan = _theme.Colors.BrightCyan.ToColor();
|
||||
BrightWhite = _theme.Colors.BrightWhite.ToColor();
|
||||
BrightBlack = _theme.Colors.BrightBlack;
|
||||
BrightRed = _theme.Colors.BrightRed;
|
||||
BrightGreen = _theme.Colors.BrightGreen;
|
||||
BrightYellow = _theme.Colors.BrightYellow;
|
||||
BrightBlue = _theme.Colors.BrightBlue;
|
||||
BrightMagenta = _theme.Colors.BrightMagenta;
|
||||
BrightCyan = _theme.Colors.BrightCyan;
|
||||
BrightWhite = _theme.Colors.BrightWhite;
|
||||
|
||||
Background = _theme.Colors.Background.ToColor();
|
||||
Foreground = _theme.Colors.Foreground.ToColor();
|
||||
Cursor = _theme.Colors.Cursor.ToColor();
|
||||
CursorAccent = _theme.Colors.CursorAccent.ToColor();
|
||||
Selection = _theme.Colors.Selection.FromString();
|
||||
Background = _theme.Colors.Background;
|
||||
Foreground = _theme.Colors.Foreground;
|
||||
Cursor = _theme.Colors.Cursor;
|
||||
CursorAccent = _theme.Colors.CursorAccent;
|
||||
Selection = _theme.Colors.Selection;
|
||||
|
||||
SetActiveCommand = new RelayCommand(SetActive);
|
||||
DeleteCommand = new RelayCommand(async () => await Delete().ConfigureAwait(false), NotPreInstalled);
|
||||
@@ -103,7 +100,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
set => Set(ref _author, value);
|
||||
}
|
||||
|
||||
public Color Background
|
||||
public string Background
|
||||
{
|
||||
get => _background;
|
||||
set
|
||||
@@ -119,61 +116,61 @@ namespace FluentTerminal.App.ViewModels
|
||||
set => Set(ref _backgroundOpacity, value);
|
||||
}
|
||||
|
||||
public Color Black
|
||||
public string Black
|
||||
{
|
||||
get => _black;
|
||||
set => Set(ref _black, value);
|
||||
}
|
||||
|
||||
public Color Blue
|
||||
public string Blue
|
||||
{
|
||||
get => _blue;
|
||||
set => Set(ref _blue, value);
|
||||
}
|
||||
|
||||
public Color BrightBlack
|
||||
public string BrightBlack
|
||||
{
|
||||
get => _brightBlack;
|
||||
set => Set(ref _brightBlack, value);
|
||||
}
|
||||
|
||||
public Color BrightBlue
|
||||
public string BrightBlue
|
||||
{
|
||||
get => _brightBlue;
|
||||
set => Set(ref _brightBlue, value);
|
||||
}
|
||||
|
||||
public Color BrightCyan
|
||||
public string BrightCyan
|
||||
{
|
||||
get => _brightCyan;
|
||||
set => Set(ref _brightCyan, value);
|
||||
}
|
||||
|
||||
public Color BrightGreen
|
||||
public string BrightGreen
|
||||
{
|
||||
get => _brightGreen;
|
||||
set => Set(ref _brightGreen, value);
|
||||
}
|
||||
|
||||
public Color BrightMagenta
|
||||
public string BrightMagenta
|
||||
{
|
||||
get => _brightMagenta;
|
||||
set => Set(ref _brightMagenta, value);
|
||||
}
|
||||
|
||||
public Color BrightRed
|
||||
public string BrightRed
|
||||
{
|
||||
get => _brightRed;
|
||||
set => Set(ref _brightRed, value);
|
||||
}
|
||||
|
||||
public Color BrightWhite
|
||||
public string BrightWhite
|
||||
{
|
||||
get => _brightWhite;
|
||||
set => Set(ref _brightWhite, value);
|
||||
}
|
||||
|
||||
public Color BrightYellow
|
||||
public string BrightYellow
|
||||
{
|
||||
get => _brightYellow;
|
||||
set => Set(ref _brightYellow, value);
|
||||
@@ -181,19 +178,19 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
public RelayCommand CancelEditCommand { get; }
|
||||
|
||||
public Color Cursor
|
||||
public string Cursor
|
||||
{
|
||||
get => _cursor;
|
||||
set => Set(ref _cursor, value);
|
||||
}
|
||||
|
||||
public Color CursorAccent
|
||||
public string CursorAccent
|
||||
{
|
||||
get => _cursorAccent;
|
||||
set => Set(ref _cursorAccent, value);
|
||||
}
|
||||
|
||||
public Color Cyan
|
||||
public string Cyan
|
||||
{
|
||||
get => _cyan;
|
||||
set => Set(ref _cyan, value);
|
||||
@@ -203,13 +200,13 @@ namespace FluentTerminal.App.ViewModels
|
||||
public RelayCommand EditCommand { get; }
|
||||
public RelayCommand ExportCommand { get; }
|
||||
|
||||
public Color Foreground
|
||||
public string Foreground
|
||||
{
|
||||
get => _foreground;
|
||||
set => Set(ref _foreground, value);
|
||||
}
|
||||
|
||||
public Color Green
|
||||
public string Green
|
||||
{
|
||||
get => _green;
|
||||
set => Set(ref _green, value);
|
||||
@@ -229,7 +226,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
set => Set(ref _isActive, value);
|
||||
}
|
||||
|
||||
public Color Magenta
|
||||
public string Magenta
|
||||
{
|
||||
get => _magenta;
|
||||
set => Set(ref _magenta, value);
|
||||
@@ -241,7 +238,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
set => Set(ref _name, value);
|
||||
}
|
||||
|
||||
public Color Red
|
||||
public string Red
|
||||
{
|
||||
get => _red;
|
||||
set => Set(ref _red, value);
|
||||
@@ -249,7 +246,7 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
public RelayCommand SaveChangesCommand { get; }
|
||||
|
||||
public Color Selection
|
||||
public string Selection
|
||||
{
|
||||
get => _selection;
|
||||
set => Set(ref _selection, value);
|
||||
@@ -257,13 +254,13 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
public RelayCommand SetActiveCommand { get; }
|
||||
|
||||
public Color White
|
||||
public string White
|
||||
{
|
||||
get => _white;
|
||||
set => Set(ref _white, value);
|
||||
}
|
||||
|
||||
public Color Yellow
|
||||
public string Yellow
|
||||
{
|
||||
get => _yellow;
|
||||
set => Set(ref _yellow, value);
|
||||
@@ -274,29 +271,29 @@ namespace FluentTerminal.App.ViewModels
|
||||
_theme.Name = Name;
|
||||
_theme.Author = Author;
|
||||
|
||||
_theme.Colors.Black = Black.ToColorString(false);
|
||||
_theme.Colors.Red = Red.ToColorString(false);
|
||||
_theme.Colors.Green = Green.ToColorString(false);
|
||||
_theme.Colors.Yellow = Yellow.ToColorString(false);
|
||||
_theme.Colors.Blue = Blue.ToColorString(false);
|
||||
_theme.Colors.Magenta = Magenta.ToColorString(false);
|
||||
_theme.Colors.Cyan = Cyan.ToColorString(false);
|
||||
_theme.Colors.White = White.ToColorString(false);
|
||||
_theme.Colors.Black = Black;
|
||||
_theme.Colors.Red = Red;
|
||||
_theme.Colors.Green = Green;
|
||||
_theme.Colors.Yellow = Yellow;
|
||||
_theme.Colors.Blue = Blue;
|
||||
_theme.Colors.Magenta = Magenta;
|
||||
_theme.Colors.Cyan = Cyan;
|
||||
_theme.Colors.White = White;
|
||||
|
||||
_theme.Colors.BrightBlack = BrightBlack.ToColorString(false);
|
||||
_theme.Colors.BrightRed = BrightRed.ToColorString(false);
|
||||
_theme.Colors.BrightGreen = BrightGreen.ToColorString(false);
|
||||
_theme.Colors.BrightYellow = BrightYellow.ToColorString(false);
|
||||
_theme.Colors.BrightBlue = BrightBlue.ToColorString(false);
|
||||
_theme.Colors.BrightMagenta = BrightMagenta.ToColorString(false);
|
||||
_theme.Colors.BrightCyan = BrightCyan.ToColorString(false);
|
||||
_theme.Colors.BrightWhite = BrightWhite.ToColorString(false);
|
||||
_theme.Colors.BrightBlack = BrightBlack;
|
||||
_theme.Colors.BrightRed = BrightRed;
|
||||
_theme.Colors.BrightGreen = BrightGreen;
|
||||
_theme.Colors.BrightYellow = BrightYellow;
|
||||
_theme.Colors.BrightBlue = BrightBlue;
|
||||
_theme.Colors.BrightMagenta = BrightMagenta;
|
||||
_theme.Colors.BrightCyan = BrightCyan;
|
||||
_theme.Colors.BrightWhite = BrightWhite;
|
||||
|
||||
_theme.Colors.Background = Background.ToColorString(false);
|
||||
_theme.Colors.Foreground = Foreground.ToColorString(false);
|
||||
_theme.Colors.Cursor = Cursor.ToColorString(false);
|
||||
_theme.Colors.CursorAccent = CursorAccent.ToColorString(false);
|
||||
_theme.Colors.Selection = Selection.ToColorString(true);
|
||||
_theme.Colors.Background = Background;
|
||||
_theme.Colors.Foreground = Foreground;
|
||||
_theme.Colors.Cursor = Cursor;
|
||||
_theme.Colors.CursorAccent = CursorAccent;
|
||||
_theme.Colors.Selection = Selection;
|
||||
|
||||
_settingsService.SaveTheme(_theme);
|
||||
|
||||
@@ -309,29 +306,29 @@ namespace FluentTerminal.App.ViewModels
|
||||
|
||||
if (result == DialogButton.OK)
|
||||
{
|
||||
Black = _fallBackColors.Black.ToColor();
|
||||
Red = _fallBackColors.Red.ToColor();
|
||||
Green = _fallBackColors.Green.ToColor();
|
||||
Yellow = _fallBackColors.Yellow.ToColor();
|
||||
Blue = _fallBackColors.Blue.ToColor();
|
||||
Magenta = _fallBackColors.Magenta.ToColor();
|
||||
Cyan = _fallBackColors.Cyan.ToColor();
|
||||
White = _fallBackColors.White.ToColor();
|
||||
Black = _fallBackColors.Black;
|
||||
Red = _fallBackColors.Red;
|
||||
Green = _fallBackColors.Green;
|
||||
Yellow = _fallBackColors.Yellow;
|
||||
Blue = _fallBackColors.Blue;
|
||||
Magenta = _fallBackColors.Magenta;
|
||||
Cyan = _fallBackColors.Cyan;
|
||||
White = _fallBackColors.White;
|
||||
|
||||
BrightBlack = _fallBackColors.BrightBlack.ToColor();
|
||||
BrightRed = _fallBackColors.BrightRed.ToColor();
|
||||
BrightGreen = _fallBackColors.BrightGreen.ToColor();
|
||||
BrightYellow = _fallBackColors.BrightYellow.ToColor();
|
||||
BrightBlue = _fallBackColors.BrightBlue.ToColor();
|
||||
BrightMagenta = _fallBackColors.BrightMagenta.ToColor();
|
||||
BrightCyan = _fallBackColors.BrightCyan.ToColor();
|
||||
BrightWhite = _fallBackColors.BrightWhite.ToColor();
|
||||
BrightBlack = _fallBackColors.BrightBlack;
|
||||
BrightRed = _fallBackColors.BrightRed;
|
||||
BrightGreen = _fallBackColors.BrightGreen;
|
||||
BrightYellow = _fallBackColors.BrightYellow;
|
||||
BrightBlue = _fallBackColors.BrightBlue;
|
||||
BrightMagenta = _fallBackColors.BrightMagenta;
|
||||
BrightCyan = _fallBackColors.BrightCyan;
|
||||
BrightWhite = _fallBackColors.BrightWhite;
|
||||
|
||||
Background = _fallBackColors.Background.ToColor();
|
||||
Foreground = _fallBackColors.Foreground.ToColor();
|
||||
Cursor = _fallBackColors.Cursor.ToColor();
|
||||
CursorAccent = _fallBackColors.CursorAccent.ToColor();
|
||||
Selection = _fallBackColors.Selection.FromString();
|
||||
Background = _fallBackColors.Background;
|
||||
Foreground = _fallBackColors.Foreground;
|
||||
Cursor = _fallBackColors.Cursor;
|
||||
CursorAccent = _fallBackColors.CursorAccent;
|
||||
Selection = _fallBackColors.Selection;
|
||||
|
||||
Name = _fallBackName;
|
||||
Author = _fallBackAuthor;
|
||||
@@ -368,20 +365,10 @@ namespace FluentTerminal.App.ViewModels
|
||||
Activated?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private async Task Export()
|
||||
private 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);
|
||||
}
|
||||
var content = JsonConvert.SerializeObject(_theme, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new TerminalThemeContractResolver() });
|
||||
return _fileSystemService.SaveTextFile(Name, "Fluent Terminal Theme", ".flutecolors", content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.AppService;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
namespace FluentTerminal.App.Adapters
|
||||
{
|
||||
public class AppServiceConnectionAdapter : IAppServiceConnection
|
||||
{
|
||||
private readonly AppServiceConnection _appServiceConnection;
|
||||
|
||||
public AppServiceConnectionAdapter(AppServiceConnection appServiceConnection)
|
||||
{
|
||||
_appServiceConnection = appServiceConnection;
|
||||
}
|
||||
|
||||
public async Task<IDictionary<string, string>> SendMessageAsync(IDictionary<string, string> message)
|
||||
{
|
||||
var valueSet = new ValueSet();
|
||||
|
||||
foreach (var pair in message)
|
||||
{
|
||||
valueSet.Add(pair.Key, pair.Value);
|
||||
}
|
||||
|
||||
var response = await _appServiceConnection.SendMessageAsync(valueSet).AsTask();
|
||||
|
||||
if (response.Status == AppServiceResponseStatus.Success)
|
||||
{
|
||||
var responseDict = new Dictionary<string, string>();
|
||||
foreach (var pair in response.Message)
|
||||
{
|
||||
responseDict.Add(pair.Key, (string)pair.Value);
|
||||
}
|
||||
return responseDict;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace FluentTerminal.App.Adapters
|
||||
{
|
||||
public class ApplicationDataContainerAdapter : IApplicationDataContainer
|
||||
{
|
||||
private readonly ApplicationDataContainer _applicationDataContainer;
|
||||
|
||||
public ApplicationDataContainerAdapter(ApplicationDataContainer applicationDataContainer)
|
||||
{
|
||||
_applicationDataContainer = applicationDataContainer;
|
||||
}
|
||||
|
||||
public void Delete(string key)
|
||||
{
|
||||
_applicationDataContainer.Values.Remove(key);
|
||||
}
|
||||
|
||||
public IEnumerable<object> GetAll()
|
||||
{
|
||||
return _applicationDataContainer.Values.Select(x => x.Value);
|
||||
}
|
||||
|
||||
public T ReadValueFromJson<T>(string name, T fallbackValue)
|
||||
{
|
||||
if (_applicationDataContainer.Values.TryGetValue(name, out object value))
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(fallbackValue, default))
|
||||
{
|
||||
fallbackValue = Activator.CreateInstance<T>();
|
||||
}
|
||||
|
||||
JsonConvert.PopulateObject((string)value, fallbackValue);
|
||||
}
|
||||
return fallbackValue;
|
||||
}
|
||||
|
||||
public void SetValue(string key, object value)
|
||||
{
|
||||
_applicationDataContainer.Values[key] = value;
|
||||
}
|
||||
|
||||
public bool TryGetValue(string key, out object value)
|
||||
{
|
||||
return _applicationDataContainer.Values.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
|
||||
public void WriteValueAsJson<T>(string name, T value)
|
||||
{
|
||||
_applicationDataContainer.Values[name] = JsonConvert.SerializeObject(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Services.EventArgs;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.Core.Preview;
|
||||
using Windows.UI.ViewManagement;
|
||||
|
||||
namespace FluentTerminal.App.Adapters
|
||||
{
|
||||
public class ApplicationViewAdapter : IApplicationView
|
||||
{
|
||||
private readonly ApplicationView _applicationView;
|
||||
private readonly CoreDispatcher _dispatcher;
|
||||
|
||||
public event CloseRequestedHandler CloseRequested;
|
||||
|
||||
public ApplicationViewAdapter()
|
||||
{
|
||||
_applicationView = ApplicationView.GetForCurrentView();
|
||||
_dispatcher = CoreApplication.GetCurrentView().Dispatcher;
|
||||
SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += OnCloseRequest;
|
||||
}
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => _applicationView.Title;
|
||||
set => _applicationView.Title = value;
|
||||
}
|
||||
|
||||
public Task RunOnDispatcherThread(Action action)
|
||||
{
|
||||
return _dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => action()).AsTask();
|
||||
}
|
||||
|
||||
public Task<bool> TryClose()
|
||||
{
|
||||
return _applicationView.TryConsolidateAsync().AsTask();
|
||||
}
|
||||
|
||||
public bool ToggleFullScreen()
|
||||
{
|
||||
if (_applicationView.IsFullScreenMode)
|
||||
{
|
||||
_applicationView.ExitFullScreenMode();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return _applicationView.TryEnterFullScreenMode();
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnCloseRequest(object sender, SystemNavigationCloseRequestedPreviewEventArgs e)
|
||||
{
|
||||
var deferral = e.GetDeferral();
|
||||
|
||||
var args = new CancelableEventArgs();
|
||||
await CloseRequested?.Invoke(this, args);
|
||||
|
||||
e.Handled = args.Cancelled;
|
||||
|
||||
deferral.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using FluentTerminal.App.Services;
|
||||
using Windows.UI.Xaml;
|
||||
|
||||
namespace FluentTerminal.App.Adapters
|
||||
{
|
||||
public class DispatcherTimerAdapter : IDispatcherTimer
|
||||
{
|
||||
private readonly DispatcherTimer _dispatcherTimer;
|
||||
|
||||
public DispatcherTimerAdapter()
|
||||
{
|
||||
_dispatcherTimer = new DispatcherTimer();
|
||||
_dispatcherTimer.Tick += OnDispatcherTimerTick;
|
||||
}
|
||||
|
||||
private void OnDispatcherTimerTick(object sender, object e)
|
||||
{
|
||||
Tick?.Invoke(this, null);
|
||||
}
|
||||
|
||||
public TimeSpan Interval
|
||||
{
|
||||
get => _dispatcherTimer.Interval;
|
||||
set => _dispatcherTimer.Interval = value;
|
||||
}
|
||||
|
||||
public bool IsEnabled => _dispatcherTimer.IsEnabled;
|
||||
|
||||
public event EventHandler<object> Tick;
|
||||
|
||||
public void Start()
|
||||
{
|
||||
_dispatcherTimer.Start();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
_dispatcherTimer.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Services.Dialogs;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Popups;
|
||||
|
||||
namespace FluentTerminal.App.Adapters
|
||||
{
|
||||
public class MessageDialogAdapter : IMessageDialog
|
||||
{
|
||||
private readonly MessageDialog _messageDialog;
|
||||
|
||||
public MessageDialogAdapter()
|
||||
{
|
||||
_messageDialog = new MessageDialog(string.Empty);
|
||||
}
|
||||
|
||||
public string Title
|
||||
{
|
||||
get => _messageDialog.Title;
|
||||
set => _messageDialog.Title = value;
|
||||
}
|
||||
|
||||
public string Content
|
||||
{
|
||||
get => _messageDialog.Content;
|
||||
set => _messageDialog.Content = value;
|
||||
}
|
||||
|
||||
public void AddButton(DialogButton button)
|
||||
{
|
||||
_messageDialog.Commands.Add(new UICommand(button.ToString()));
|
||||
}
|
||||
|
||||
public async Task<DialogButton> ShowAsync()
|
||||
{
|
||||
var result = await _messageDialog.ShowAsync();
|
||||
|
||||
return Enum.Parse<DialogButton>(result.Label);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@
|
||||
Then="Collapsed" />
|
||||
<converters:IntToExtendedVirtualKeyConverter x:Key="IntToExtendedVirtualKeyConverter" />
|
||||
<converters:BackgroundToApplicationThemeConverter x:Key="BackgroundToApplicationThemeConverter" />
|
||||
<converters:StringToColorConverter x:Key="StringToColorConverter" />
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -1,5 +1,8 @@
|
||||
using Autofac;
|
||||
using FluentTerminal.App.Adapters;
|
||||
using FluentTerminal.App.Dialogs;
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Services.Dialogs;
|
||||
using FluentTerminal.App.Services.Implementation;
|
||||
using FluentTerminal.App.ViewModels;
|
||||
using FluentTerminal.App.Views;
|
||||
@@ -15,6 +18,7 @@ using Windows.ApplicationModel.Activation;
|
||||
using Windows.ApplicationModel.AppService;
|
||||
using Windows.ApplicationModel.Background;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.Storage;
|
||||
using Windows.UI.Core;
|
||||
using Windows.UI.ViewManagement;
|
||||
using Windows.UI.Xaml;
|
||||
@@ -25,6 +29,10 @@ namespace FluentTerminal.App
|
||||
{
|
||||
public sealed partial class App : Application
|
||||
{
|
||||
public const string ThemesContainerName = "Themes";
|
||||
public const string KeyBindingsContainerName = "KeyBindings";
|
||||
public const string ShellProfilesContainerName = "ShellProfiles";
|
||||
|
||||
public TaskCompletionSource<int> _trayReady = new TaskCompletionSource<int>();
|
||||
private readonly ISettingsService _settingsService;
|
||||
private readonly ITrayProcessCommunicationService _trayProcessCommunicationService;
|
||||
@@ -34,7 +42,7 @@ namespace FluentTerminal.App
|
||||
private readonly List<MainViewModel> _mainViewModels;
|
||||
private SettingsViewModel _settingsViewModel;
|
||||
private int? _settingsWindowId;
|
||||
private AppServiceConnection _appServiceConnection;
|
||||
private IAppServiceConnection _appServiceConnection;
|
||||
private BackgroundTaskDeferral _appServiceDeferral;
|
||||
|
||||
public App()
|
||||
@@ -43,6 +51,15 @@ namespace FluentTerminal.App
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
var applicationDataContainers = new ApplicationDataContainers
|
||||
{
|
||||
LocalSettings = new ApplicationDataContainerAdapter(ApplicationData.Current.LocalSettings),
|
||||
RoamingSettings = new ApplicationDataContainerAdapter(ApplicationData.Current.RoamingSettings),
|
||||
KeyBindings = new ApplicationDataContainerAdapter(ApplicationData.Current.RoamingSettings.CreateContainer(KeyBindingsContainerName, ApplicationDataCreateDisposition.Always)),
|
||||
ShellProfiles = new ApplicationDataContainerAdapter(ApplicationData.Current.LocalSettings.CreateContainer(ShellProfilesContainerName, ApplicationDataCreateDisposition.Always)),
|
||||
Themes = new ApplicationDataContainerAdapter(ApplicationData.Current.RoamingSettings.CreateContainer(ThemesContainerName, ApplicationDataCreateDisposition.Always))
|
||||
};
|
||||
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<SettingsService>().As<ISettingsService>().SingleInstance();
|
||||
builder.RegisterType<DefaultValueProvider>().As<IDefaultValueProvider>().SingleInstance();
|
||||
@@ -54,6 +71,15 @@ namespace FluentTerminal.App
|
||||
builder.RegisterType<ThemeParserFactory>().As<IThemeParserFactory>().SingleInstance();
|
||||
builder.RegisterType<ITermThemeParser>().As<IThemeParser>().SingleInstance();
|
||||
builder.RegisterType<FluentTerminalThemeParser>().As<IThemeParser>().SingleInstance();
|
||||
builder.RegisterType<ClipboardService>().As<IClipboardService>().SingleInstance();
|
||||
builder.RegisterType<FileSystemService>().As<IFileSystemService>().SingleInstance();
|
||||
builder.RegisterType<SystemFontService>().As<ISystemFontService>().SingleInstance();
|
||||
builder.RegisterType<ShellProfileSelectionDialog>().As<IShellProfileSelectionDialog>().InstancePerDependency();
|
||||
builder.RegisterType<CreateKeyBindingDialog>().As<ICreateKeyBindingDialog>().InstancePerDependency();
|
||||
builder.RegisterType<MessageDialogAdapter>().As<IMessageDialog>().InstancePerDependency();
|
||||
builder.RegisterType<ApplicationViewAdapter>().As<IApplicationView>().InstancePerDependency();
|
||||
builder.RegisterType<DispatcherTimerAdapter>().As<IDispatcherTimer>().InstancePerDependency();
|
||||
builder.RegisterInstance(applicationDataContainers);
|
||||
|
||||
_container = builder.Build();
|
||||
|
||||
@@ -139,7 +165,7 @@ namespace FluentTerminal.App
|
||||
_appServiceDeferral = args.TaskInstance.GetDeferral();
|
||||
args.TaskInstance.Canceled += OnTaskCanceled;
|
||||
|
||||
_appServiceConnection = details.AppServiceConnection;
|
||||
_appServiceConnection = new AppServiceConnectionAdapter(details.AppServiceConnection);
|
||||
|
||||
_trayReady.SetResult(0);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using FluentTerminal.Models.Enums;
|
||||
using FluentTerminal.App.Services.Utilities;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using Windows.UI.Xaml.Data;
|
||||
|
||||
namespace FluentTerminal.App.Converters
|
||||
@@ -11,7 +11,7 @@ namespace FluentTerminal.App.Converters
|
||||
{
|
||||
if (value is int intValue)
|
||||
{
|
||||
return GetEnumDescription((ExtendedVirtualKey)intValue);
|
||||
return EnumHelper.GetEnumDescription((ExtendedVirtualKey)intValue);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -20,24 +20,5 @@ namespace FluentTerminal.App.Converters
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private static string GetEnumDescription(Enum value)
|
||||
{
|
||||
var fieldInfo = value.GetType().GetField(value.ToString());
|
||||
|
||||
if (fieldInfo == null)
|
||||
{
|
||||
return value.ToString();
|
||||
}
|
||||
|
||||
var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
||||
|
||||
if (attributes?.Length > 0)
|
||||
{
|
||||
return attributes[0].Description;
|
||||
}
|
||||
|
||||
return value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using FluentTerminal.App.Utilities;
|
||||
using System;
|
||||
using Windows.UI;
|
||||
using Windows.UI.Xaml.Data;
|
||||
|
||||
namespace FluentTerminal.App.Converters
|
||||
{
|
||||
public class StringToColorConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is string colorString)
|
||||
{
|
||||
return colorString.FromString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value is Color color && bool.TryParse((string)parameter, out bool allowTransparency))
|
||||
{
|
||||
return color.ToColorString(allowTransparency);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<ContentDialog
|
||||
x:Class="FluentTerminal.App.Views.CreateKeyBindingDialog"
|
||||
x:Class="FluentTerminal.App.Dialogs.CreateKeyBindingDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
@@ -17,7 +17,7 @@
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind KeyBinding.Ctrl, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
Visibility="{x:Bind Ctrl, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
@@ -28,7 +28,7 @@
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind KeyBinding.Meta, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
Visibility="{x:Bind Meta, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
<FontIcon
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
@@ -40,7 +40,7 @@
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind KeyBinding.Alt, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
Visibility="{x:Bind Alt, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
@@ -51,7 +51,7 @@
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind KeyBinding.Shift, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
Visibility="{x:Bind Shift, Mode=OneWay, Converter={StaticResource TrueToVisibleConverter}}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
@@ -62,11 +62,11 @@
|
||||
Height="32"
|
||||
Margin="0,0,6,0"
|
||||
Background="{ThemeResource SystemControlBackgroundBaseLowBrush}"
|
||||
Visibility="{x:Bind KeyBinding.Key, Mode=OneWay, Converter={StaticResource ZeroToCollapsedConverter}}">
|
||||
Visibility="{x:Bind Key, Mode=OneWay, Converter={StaticResource ZeroToCollapsedConverter}}">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind KeyBinding.Key, Mode=OneWay, Converter={StaticResource IntToExtendedVirtualKeyConverter}}" />
|
||||
Text="{x:Bind Key, Mode=OneWay, Converter={StaticResource IntToExtendedVirtualKeyConverter}}" />
|
||||
</Grid>
|
||||
<HyperlinkButton
|
||||
x:Name="ResetButton"
|
||||
@@ -0,0 +1,131 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using FluentTerminal.App.Services.Dialogs;
|
||||
using FluentTerminal.Models;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using System;
|
||||
|
||||
namespace FluentTerminal.App.Dialogs
|
||||
{
|
||||
public sealed partial class CreateKeyBindingDialog : ContentDialog, ICreateKeyBindingDialog, INotifyPropertyChanged
|
||||
{
|
||||
private bool _ctrl;
|
||||
private bool _shift;
|
||||
private bool _alt;
|
||||
private bool _meta;
|
||||
private int _key;
|
||||
|
||||
public bool Ctrl
|
||||
{
|
||||
get => _ctrl;
|
||||
set => Set(ref _ctrl, value);
|
||||
}
|
||||
|
||||
public bool Shift
|
||||
{
|
||||
get => _shift;
|
||||
set => Set(ref _shift, value);
|
||||
}
|
||||
|
||||
public bool Alt
|
||||
{
|
||||
get => _alt;
|
||||
set => Set(ref _alt, value);
|
||||
}
|
||||
|
||||
public bool Meta
|
||||
{
|
||||
get => _meta;
|
||||
set => Set(ref _meta, value);
|
||||
}
|
||||
|
||||
public int Key
|
||||
{
|
||||
get => _key;
|
||||
set => Set(ref _key, value);
|
||||
}
|
||||
|
||||
public CreateKeyBindingDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
ResetCommand = new RelayCommand(Reset);
|
||||
PreviewKeyDown += RegisterKeyBindingDialog_PreviewKeyDown;
|
||||
Reset();
|
||||
}
|
||||
|
||||
public RelayCommand ResetCommand { get; }
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public async Task<KeyBinding> CreateKeyBinding()
|
||||
{
|
||||
var result = await ShowAsync();
|
||||
|
||||
if (result == ContentDialogResult.Primary)
|
||||
{
|
||||
return new KeyBinding
|
||||
{
|
||||
Alt = Alt,
|
||||
Ctrl = Ctrl,
|
||||
Key = Key,
|
||||
Meta = Meta,
|
||||
Shift = Shift
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void OnResetButtonPreviewKeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void RegisterKeyBindingDialog_PreviewKeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case VirtualKey.Control:
|
||||
Ctrl = true;
|
||||
break;
|
||||
case VirtualKey.Shift:
|
||||
Shift = true;
|
||||
break;
|
||||
case VirtualKey.Menu:
|
||||
Alt = true;
|
||||
break;
|
||||
case VirtualKey.LeftWindows:
|
||||
case VirtualKey.RightWindows:
|
||||
Meta = true;
|
||||
break;
|
||||
default:
|
||||
Key = (int)e.Key;
|
||||
break;
|
||||
}
|
||||
|
||||
ResetButton.Visibility = Visibility.Visible;
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
Alt = false;
|
||||
Ctrl = false;
|
||||
Meta = false;
|
||||
Shift = false;
|
||||
Key = 0;
|
||||
|
||||
ResetButton.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private void Set<T>(ref T field, T value, [CallerMemberName]string propertyName = "")
|
||||
{
|
||||
field = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,16 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using System;
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.Services.Dialogs;
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.Models;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace FluentTerminal.App.Dialogs
|
||||
{
|
||||
public sealed partial class ShellProfileSelectionDialog : ContentDialog
|
||||
public sealed partial class ShellProfileSelectionDialog : ContentDialog, IShellProfileSelectionDialog
|
||||
{
|
||||
public IEnumerable<ShellProfile> Profiles { get; }
|
||||
|
||||
@@ -21,5 +24,15 @@ namespace FluentTerminal.App.Dialogs
|
||||
var currentTheme = settingsService.GetCurrentTheme();
|
||||
RequestedTheme = ContrastHelper.GetIdealThemeForBackgroundColor(currentTheme.Colors.Background);
|
||||
}
|
||||
|
||||
public async Task<ShellProfile> SelectProfile()
|
||||
{
|
||||
var result = await ShowAsync();
|
||||
if (result == ContentDialogResult.Primary)
|
||||
{
|
||||
return SelectedProfile;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@
|
||||
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
<LangVersion>7.1</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
@@ -102,6 +103,10 @@
|
||||
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Adapters\ApplicationDataContainerAdapter.cs" />
|
||||
<Compile Include="Adapters\ApplicationViewAdapter.cs" />
|
||||
<Compile Include="Adapters\AppServiceConnectionAdapter.cs" />
|
||||
<Compile Include="Adapters\DispatcherTimerAdapter.cs" />
|
||||
<Compile Include="App.xaml.cs">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -111,45 +116,18 @@
|
||||
<Compile Include="Converters\IntToExtendedVirtualKeyConverter.cs" />
|
||||
<Compile Include="Converters\IntToVisibilityConverter.cs" />
|
||||
<Compile Include="Converters\NegateConverter.cs" />
|
||||
<Compile Include="Converters\StringToColorConverter.cs" />
|
||||
<Compile Include="Converters\TerminalViewModelToViewConverter.cs" />
|
||||
<Compile Include="Converters\TrueToVisibleConverter.cs" />
|
||||
<Compile Include="Adapters\MessageDialogAdapter.cs" />
|
||||
<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" />
|
||||
<Compile Include="Services\Implementation\SettingsService.cs" />
|
||||
<Compile Include="Services\Implementation\TrayProcessCommunicationService.cs" />
|
||||
<Compile Include="Services\ISettingsService.cs" />
|
||||
<Compile Include="Services\ITrayProcessCommunicationService.cs" />
|
||||
<Compile Include="Services\ClipboardService.cs" />
|
||||
<Compile Include="Services\FileSystemService.cs" />
|
||||
<Compile Include="Services\SystemFontService.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" />
|
||||
<Compile Include="ViewModels\Settings\KeyBindingsPageViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\KeyBindingsViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\KeyBindingViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\ProfilesPageViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\TerminalPageViewModel.cs" />
|
||||
<Compile Include="ViewModels\Settings\ThemesPageViewModel.cs" />
|
||||
<Compile Include="ViewModels\ShellProfileViewModel.cs" />
|
||||
<Compile Include="ViewModels\ThemeViewModel.cs" />
|
||||
<Compile Include="ViewModels\TerminalViewModel.cs" />
|
||||
<Compile Include="Views\ITerminalView.cs" />
|
||||
<Compile Include="Views\KeyBindingsView.xaml.cs">
|
||||
<DependentUpon>KeyBindingsView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
@@ -157,7 +135,7 @@
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Views\CreateKeyBindingDialog.xaml.cs">
|
||||
<Compile Include="Dialogs\CreateKeyBindingDialog.xaml.cs">
|
||||
<DependentUpon>CreateKeyBindingDialog.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Views\SettingsPage.xaml.cs">
|
||||
@@ -293,7 +271,7 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Page>
|
||||
<Page Include="Views\CreateKeyBindingDialog.xaml">
|
||||
<Page Include="Dialogs\CreateKeyBindingDialog.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
@@ -346,15 +324,9 @@
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Uwp.Managed">
|
||||
<Version>2.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MvvmLightLibs">
|
||||
<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>
|
||||
@@ -365,6 +337,14 @@
|
||||
</SDKReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FluentTerminal.App.Services\FluentTerminal.App.Services.csproj">
|
||||
<Project>{a1ad7385-f92e-46ac-a349-43dc99b1e72d}</Project>
|
||||
<Name>FluentTerminal.App.Services</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\FluentTerminal.App.ViewModels\FluentTerminal.App.ViewModels.csproj">
|
||||
<Project>{44e8e225-f46c-47ec-9290-ffa08fccf1b5}</Project>
|
||||
<Name>FluentTerminal.App.ViewModels</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\FluentTerminal.Models\FluentTerminal.Models.csproj">
|
||||
<Project>{5EA40453-A0AA-449E-8406-D6EA51D7E70E}</Project>
|
||||
<Name>FluentTerminal.Models</Name>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.DataTransfer;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public class ClipboardService : IClipboardService
|
||||
{
|
||||
public Task<string> GetText()
|
||||
{
|
||||
var content = Clipboard.GetContent();
|
||||
if (content.Contains(StandardDataFormats.Text))
|
||||
{
|
||||
return content.GetTextAsync().AsTask();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void SetText(string text)
|
||||
{
|
||||
var dataPackage = new DataPackage();
|
||||
dataPackage.SetText(text);
|
||||
Clipboard.SetContent(dataPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using Windows.Storage.Pickers;
|
||||
using File = FluentTerminal.Models.File;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public class FileSystemService : IFileSystemService
|
||||
{
|
||||
public async Task<string> BrowseForDirectory()
|
||||
{
|
||||
var picker = new FolderPicker();
|
||||
picker.FileTypeFilter.Add(".whatever"); // else a ComException is thrown
|
||||
picker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
|
||||
|
||||
var folder = await picker.PickSingleFolderAsync();
|
||||
|
||||
return folder?.Path;
|
||||
}
|
||||
|
||||
public async Task<File> OpenFile(IEnumerable<string> fileTypes)
|
||||
{
|
||||
var picker = new FileOpenPicker
|
||||
{
|
||||
SuggestedStartLocation = PickerLocationId.ComputerFolder
|
||||
};
|
||||
|
||||
foreach (var fileType in fileTypes)
|
||||
{
|
||||
picker.FileTypeFilter.Add(fileType);
|
||||
}
|
||||
|
||||
var file = await picker.PickSingleFileAsync();
|
||||
if (file != null)
|
||||
{
|
||||
var stream = await file.OpenStreamForReadAsync().ConfigureAwait(true);
|
||||
|
||||
return new File(file.DisplayName, file.FileType, file.Path, stream);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task SaveTextFile(string name, string fileTypeDescription, string fileType, string content)
|
||||
{
|
||||
var picker = new FileSavePicker();
|
||||
picker.SuggestedStartLocation = PickerLocationId.ComputerFolder;
|
||||
picker.SuggestedFileName = name;
|
||||
picker.FileTypeChoices.Add(fileTypeDescription, new List<string> { fileType });
|
||||
|
||||
var file = await picker.PickSaveFileAsync();
|
||||
|
||||
if (file != null)
|
||||
{
|
||||
await FileIO.WriteTextAsync(file, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using FluentTerminal.App.Dialogs;
|
||||
using FluentTerminal.Models;
|
||||
using Windows.UI.Popups;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace FluentTerminal.App.Services.Implementation
|
||||
{
|
||||
public class DialogService : IDialogService
|
||||
{
|
||||
private readonly ISettingsService _settingsService;
|
||||
|
||||
public DialogService(ISettingsService settingsService)
|
||||
{
|
||||
_settingsService = settingsService;
|
||||
}
|
||||
|
||||
public async Task<DialogButton> ShowMessageDialogAsnyc(string title, string content, params DialogButton[] buttons)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(title))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(title));
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(content))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(content));
|
||||
}
|
||||
|
||||
if (buttons.Length == 0)
|
||||
{
|
||||
throw new ArgumentException("Must not be empty", nameof(buttons));
|
||||
}
|
||||
|
||||
var dialog = new MessageDialog(content, title);
|
||||
|
||||
foreach (var button in buttons)
|
||||
{
|
||||
dialog.Commands.Add(new UICommand(button.ToString()));
|
||||
}
|
||||
|
||||
var result = await dialog.ShowAsync();
|
||||
|
||||
return Enum.Parse<DialogButton>(result.Label);
|
||||
}
|
||||
|
||||
public async Task<ShellProfile> ShowProfileSelectionDialogAsync()
|
||||
{
|
||||
var dialog = new ShellProfileSelectionDialog(_settingsService);
|
||||
|
||||
var result = await dialog.ShowAsync();
|
||||
|
||||
if (result == ContentDialogResult.Primary)
|
||||
{
|
||||
return dialog.SelectedProfile;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
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,13 @@
|
||||
using Microsoft.Graphics.Canvas.Text;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FluentTerminal.App.Services
|
||||
{
|
||||
public class SystemFontService : ISystemFontService
|
||||
{
|
||||
public IEnumerable<string> GetSystemFontFamilies()
|
||||
{
|
||||
return CanvasTextFormat.GetSystemFontFamilies();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Windows.Storage;
|
||||
|
||||
namespace FluentTerminal.App.Utilities
|
||||
{
|
||||
public static class ApplicationDataContainerExtensions
|
||||
{
|
||||
public static T ReadValueFromJson<T>(this ApplicationDataContainer container, string name, T fallbackValue)
|
||||
{
|
||||
if (container.Values.TryGetValue(name, out object value))
|
||||
{
|
||||
if (EqualityComparer<T>.Default.Equals(fallbackValue, default))
|
||||
{
|
||||
fallbackValue = Activator.CreateInstance<T>();
|
||||
}
|
||||
|
||||
JsonConvert.PopulateObject((string)value, fallbackValue);
|
||||
}
|
||||
return fallbackValue;
|
||||
}
|
||||
|
||||
public static void WriteValueAsJson<T>(this ApplicationDataContainer container, string name, T value)
|
||||
{
|
||||
container.Values[name] = JsonConvert.SerializeObject(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using FluentTerminal.Models;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Windows.System;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace FluentTerminal.App.Views
|
||||
{
|
||||
public sealed partial class CreateKeyBindingDialog : ContentDialog
|
||||
{
|
||||
public static readonly DependencyProperty KeyBindingProperty =
|
||||
DependencyProperty.Register(nameof(KeyBinding), typeof(KeyBindingViewModel), typeof(CreateKeyBindingDialog), new PropertyMetadata(null));
|
||||
|
||||
private readonly IDialogService _dialogService;
|
||||
|
||||
public CreateKeyBindingDialog(IDialogService dialogService)
|
||||
{
|
||||
_dialogService = dialogService;
|
||||
InitializeComponent();
|
||||
ResetCommand = new RelayCommand(Reset);
|
||||
PreviewKeyDown += RegisterKeyBindingDialog_PreviewKeyDown;
|
||||
Reset();
|
||||
}
|
||||
|
||||
public KeyBindingViewModel KeyBinding
|
||||
{
|
||||
get { return (KeyBindingViewModel)GetValue(KeyBindingProperty); }
|
||||
set { SetValue(KeyBindingProperty, value); }
|
||||
}
|
||||
|
||||
public RelayCommand ResetCommand { get; }
|
||||
|
||||
private void OnResetButtonPreviewKeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void RegisterKeyBindingDialog_PreviewKeyDown(object sender, Windows.UI.Xaml.Input.KeyRoutedEventArgs e)
|
||||
{
|
||||
switch (e.Key)
|
||||
{
|
||||
case VirtualKey.Control:
|
||||
KeyBinding.Ctrl = true;
|
||||
break;
|
||||
case VirtualKey.Shift:
|
||||
KeyBinding.Shift = true;
|
||||
break;
|
||||
case VirtualKey.Menu:
|
||||
KeyBinding.Alt = true;
|
||||
break;
|
||||
case VirtualKey.LeftWindows:
|
||||
case VirtualKey.RightWindows:
|
||||
KeyBinding.Meta = true;
|
||||
break;
|
||||
default:
|
||||
KeyBinding.Key = (int)e.Key;
|
||||
break;
|
||||
}
|
||||
|
||||
ResetButton.Visibility = Visibility.Visible;
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
KeyBinding = new KeyBindingViewModel(new KeyBinding(), _dialogService);
|
||||
ResetButton.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.App.Services.Utilities;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using System;
|
||||
|
||||
@@ -206,92 +206,92 @@
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Black"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind Black, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind Black, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Red"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind Red, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind Red, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Green"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind Green, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind Green, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Yellow"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind Yellow, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind Yellow, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Blue"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind Blue, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind Blue, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Magenta"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind Magenta, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind Magenta, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Cyan"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind Cyan, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind Cyan, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="White"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind White, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind White, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Bright Black"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind BrightBlack, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind BrightBlack, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Bright Red"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind BrightRed, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind BrightRed, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Bright Green"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind BrightGreen, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind BrightGreen, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Bright Yellow"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind BrightYellow, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind BrightYellow, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Bright Blue"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind BrightBlue, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind BrightBlue, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Bright Magenta"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind BrightMagenta, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind BrightMagenta, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Bright Cyan"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind BrightCyan, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind BrightCyan, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Bright White"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind BrightWhite, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind BrightWhite, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Row="2" Orientation="Horizontal">
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Foreground"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind Foreground, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind Foreground, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Background"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind Background, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind Background, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Cursor"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind Cursor, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind Cursor, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Cursor Accent"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
SelectedColor="{x:Bind CursorAccent, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind CursorAccent, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=false}" />
|
||||
<views:TerminalColorPicker
|
||||
ColorName="Selection"
|
||||
EnableEditing="{x:Bind InEditMode, Mode=OneWay}"
|
||||
IsAlphaEnabled="True"
|
||||
SelectedColor="{x:Bind Selection, Mode=TwoWay}" />
|
||||
SelectedColor="{x:Bind Selection, Mode=TwoWay, Converter={StaticResource StringToColorConverter}, ConverterParameter=true}" />
|
||||
</StackPanel>
|
||||
<TextBlock
|
||||
Grid.Row="3"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using FluentTerminal.App.Utilities;
|
||||
using FluentTerminal.App.ViewModels.Settings;
|
||||
using Windows.UI;
|
||||
using Microsoft.Toolkit.Uwp.Helpers;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
@@ -28,7 +28,7 @@ namespace FluentTerminal.App.Views.SettingsPages
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectedThemeBackgroundColorChanged(object sender, Color e)
|
||||
private void OnSelectedThemeBackgroundColorChanged(object sender, string e)
|
||||
{
|
||||
var theme = ContrastHelper.GetIdealThemeForBackgroundColor(e);
|
||||
SetTheme(theme);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using FluentTerminal.App.ViewModels;
|
||||
using FluentTerminal.App.Services;
|
||||
using FluentTerminal.App.ViewModels;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Enums;
|
||||
using FluentTerminal.RuntimeComponent.Interfaces;
|
||||
|
||||
@@ -177,6 +177,8 @@ namespace FluentTerminal.Models.Enums
|
||||
Period = 190,
|
||||
[Description("#")]
|
||||
NumberSign = 191,
|
||||
[Description("`")]
|
||||
GraveAccent = 192,
|
||||
GamepadA = 195,
|
||||
GamepadB = 196,
|
||||
GamepadX = 197,
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using System.IO;
|
||||
|
||||
namespace FluentTerminal.Models
|
||||
{
|
||||
public class File
|
||||
{
|
||||
public File(string name, string fileType, string path, Stream content)
|
||||
{
|
||||
Name = name;
|
||||
FileType = fileType;
|
||||
Path = path;
|
||||
Content = content;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public string FileType { get; }
|
||||
public string Path { get; }
|
||||
public Stream Content { get; }
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,9 @@
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public bool Success { get; set; }
|
||||
public string WebSocketUrl { get; set; }
|
||||
public int Port { get; set; }
|
||||
public string Error { get; set; }
|
||||
public string ShellExecutableName { get; set; }
|
||||
public string PipeName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,8 @@
|
||||
using Fleck;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models;
|
||||
using FluentTerminal.Models.Requests;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static winpty.WinPty;
|
||||
@@ -18,7 +16,7 @@ namespace FluentTerminal.SystemTray.Services
|
||||
private IntPtr _handle;
|
||||
private Stream _stdin;
|
||||
private Stream _stdout;
|
||||
private IWebSocketConnection _webSocket;
|
||||
private NamedPipeServerStream _outServer;
|
||||
|
||||
public TerminalSession(CreateTerminalRequest request)
|
||||
{
|
||||
@@ -72,29 +70,17 @@ namespace FluentTerminal.SystemTray.Services
|
||||
|
||||
Id = port.Value;
|
||||
_connectedEvent = new ManualResetEventSlim(false);
|
||||
WebSocketUrl = "ws://127.0.0.1:" + port;
|
||||
var webSocketServer = new WebSocketServer(WebSocketUrl);
|
||||
webSocketServer.Start(socket =>
|
||||
{
|
||||
_webSocket = socket;
|
||||
socket.OnOpen = () =>
|
||||
{
|
||||
Console.WriteLine("open");
|
||||
_connectedEvent.Set();
|
||||
};
|
||||
socket.OnClose = () =>
|
||||
{
|
||||
Console.WriteLine("closing");
|
||||
ConnectionClosed?.Invoke(this, EventArgs.Empty);
|
||||
};
|
||||
socket.OnMessage = message =>
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(message);
|
||||
_stdin.Write(bytes, 0, bytes.Length);
|
||||
};
|
||||
});
|
||||
|
||||
PipeName = @"LOCAL\" + Guid.NewGuid().ToString();
|
||||
|
||||
_outServer = new NamedPipeServerStream(PipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.None);
|
||||
|
||||
StreamReader reader = new StreamReader(_outServer);
|
||||
|
||||
|
||||
|
||||
ListenToStdOut();
|
||||
ListenToNamedPipe();
|
||||
}
|
||||
|
||||
~TerminalSession()
|
||||
@@ -114,7 +100,9 @@ namespace FluentTerminal.SystemTray.Services
|
||||
public event EventHandler ConnectionClosed;
|
||||
|
||||
public int Id { get; }
|
||||
public string WebSocketUrl { get; }
|
||||
|
||||
public string PipeName { get; }
|
||||
|
||||
public string ShellExecutableName { get; }
|
||||
|
||||
public void Dispose()
|
||||
@@ -178,12 +166,18 @@ namespace FluentTerminal.SystemTray.Services
|
||||
return pipe;
|
||||
}
|
||||
|
||||
private void ListenToStdOut()
|
||||
private void ListenToNamedPipe()
|
||||
{
|
||||
new NotificationService().ShowNotification("DEBUG", "wating now");
|
||||
_outServer.WaitForConnection();
|
||||
new NotificationService().ShowNotification("DEBUG", "connected");
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
_connectedEvent.Wait();
|
||||
var reader = new StreamReader(_stdout);
|
||||
//_connectedEvent.Wait();
|
||||
var reader = new StreamReader(_outServer);
|
||||
var writer = new StreamWriter(_stdin);
|
||||
|
||||
do
|
||||
{
|
||||
var offset = 0;
|
||||
@@ -191,12 +185,34 @@ namespace FluentTerminal.SystemTray.Services
|
||||
var readChars = await reader.ReadAsync(buffer, offset, buffer.Length - offset);
|
||||
if (readChars > 0)
|
||||
{
|
||||
await _webSocket.Send(new String(buffer));
|
||||
writer.Write(buffer, 0, readChars);
|
||||
}
|
||||
}
|
||||
while (!reader.EndOfStream);
|
||||
_webSocket.Close();
|
||||
_stdin.Close();
|
||||
});
|
||||
}
|
||||
|
||||
private void ListenToStdOut()
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var reader = new StreamReader(_stdout);
|
||||
var writer = new StreamWriter(_outServer);
|
||||
|
||||
do
|
||||
{
|
||||
var offset = 0;
|
||||
var buffer = new char[1024];
|
||||
var readChars = await reader.ReadAsync(buffer, offset, buffer.Length - offset);
|
||||
if (readChars > 0)
|
||||
{
|
||||
writer.Write(buffer, 0, readChars);
|
||||
}
|
||||
}
|
||||
while (!reader.EndOfStream);
|
||||
_outServer.Close();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,8 @@ namespace FluentTerminal.SystemTray.Services
|
||||
{
|
||||
Success = true,
|
||||
Id = terminal.Id,
|
||||
WebSocketUrl = terminal.WebSocketUrl,
|
||||
Port = Utilities.GetAvailablePort().Value,
|
||||
PipeName = terminal.PipeName,
|
||||
ShellExecutableName = terminal.ShellExecutableName
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace FluentTerminal.SystemTray.Services
|
||||
private bool _disposedValue;
|
||||
private List<HotKey> _hotKeys;
|
||||
|
||||
private const int SW_MINIMIZE = 6;
|
||||
|
||||
public ToggleWindowService(Dispatcher dispatcher, HotKeyManager hotKeyManager, NotificationService notificationService)
|
||||
{
|
||||
_dispatcher = dispatcher;
|
||||
@@ -103,6 +105,9 @@ namespace FluentTerminal.SystemTray.Services
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetForegroundWindow();
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
|
||||
private static string GetKeyBindingRepresentation(KeyBinding keyBinding)
|
||||
{
|
||||
var keys = new List<string>();
|
||||
@@ -145,8 +150,9 @@ namespace FluentTerminal.SystemTray.Services
|
||||
private async void OnKeyPressed(object sender, KeyPressedEventArgs e)
|
||||
{
|
||||
if (GetActiveProcessFileName() == "Fluent Terminal")
|
||||
{
|
||||
SendKeys.Send("%{Tab}");
|
||||
{
|
||||
var hwnd = GetForegroundWindow();
|
||||
ShowWindow(hwnd, SW_MINIMIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -326,6 +326,8 @@ namespace FluentTerminal.SystemTray
|
||||
return Key.OemQuestion;
|
||||
case ExtendedVirtualKey.OpenBrackets:
|
||||
return Key.OemOpenBrackets;
|
||||
case ExtendedVirtualKey.GraveAccent:
|
||||
return Key.Oem3;
|
||||
case ExtendedVirtualKey.Circumflex:
|
||||
return Key.Oem5;
|
||||
case ExtendedVirtualKey.AcuteAccent:
|
||||
|
||||
@@ -15,7 +15,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentTerminal.RuntimeCompo
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentTerminal.Models", "FluentTerminal.Models\FluentTerminal.Models.csproj", "{5EA40453-A0AA-449E-8406-D6EA51D7E70E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentTerminal.App.Test", "FluentTerminal.App.Test\FluentTerminal.App.Test.csproj", "{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentTerminal.App.Services", "FluentTerminal.App.Services\FluentTerminal.App.Services.csproj", "{A1AD7385-F92E-46AC-A349-43DC99B1E72D}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentTerminal.App.Services.Test", "FluentTerminal.App.Services.Test\FluentTerminal.App.Services.Test.csproj", "{B353EAF4-8332-4C89-B986-B0B29F7E21FC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentTerminal.App.ViewModels", "FluentTerminal.App.ViewModels\FluentTerminal.App.ViewModels.csproj", "{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@@ -97,22 +101,54 @@ Global
|
||||
{5EA40453-A0AA-449E-8406-D6EA51D7E70E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{5EA40453-A0AA-449E-8406-D6EA51D7E70E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{5EA40453-A0AA-449E-8406-D6EA51D7E70E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|ARM.ActiveCfg = Debug|ARM
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|ARM.Build.0 = Debug|ARM
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|ARM.Deploy.0 = Debug|ARM
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|x64.Build.0 = Debug|x64
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Debug|x86.Build.0 = Debug|x86
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|ARM.ActiveCfg = Release|ARM
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|ARM.Build.0 = Release|ARM
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|ARM.Deploy.0 = Release|ARM
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|x64.ActiveCfg = Release|x64
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|x64.Build.0 = Release|x64
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|x86.ActiveCfg = Release|x86
|
||||
{812A09E4-3A05-41AB-8E9A-DC4389B5D73E}.Release|x86.Build.0 = Release|x86
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A1AD7385-F92E-46AC-A349-43DC99B1E72D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Release|x64.Build.0 = Release|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B353EAF4-8332-4C89-B986-B0B29F7E21FC}.Release|x86.Build.0 = Release|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Release|x64.Build.0 = Release|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{44E8E225-F46C-47EC-9290-FFA08FCCF1B5}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||

|
||||
[](https://ci.appveyor.com/project/felixse/fluentterminal)
|
||||
|
||||
# Fluent Terminal
|
||||
A Terminal Emulator based on UWP and web technologies.
|
||||
|
||||
## Features:
|
||||
- Terminal for PowerShell, CMD, or custom shells
|
||||
- Terminal for PowerShell, CMD, WSL, or custom shells
|
||||
- Supports tabs and multiple windows
|
||||
- Theming and appearance configuration
|
||||
- Editable keybindings
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
os: Visual Studio 2017
|
||||
configuration: Debug
|
||||
platform:
|
||||
- x64
|
||||
skip_commits:
|
||||
files:
|
||||
- README.md
|
||||
install:
|
||||
- ps: iex ((New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/appveyor/secure-file/master/install.ps1'))
|
||||
- cmd: appveyor-tools\secure-file -decrypt FluentTerminal.App\FluentTerminal.App_StoreKey.pfx.enc -secret %CertificationFilesSecret%
|
||||
- cmd: appveyor-tools\secure-file -decrypt FluentTerminal.App\Package.StoreAssociation.xml.enc -secret %CertificationFilesSecret%
|
||||
before_build:
|
||||
- cmd: pushd FluentTerminal.Client && npm install && npm run build && popd
|
||||
- cmd: nuget restore
|
||||
build:
|
||||
project: FluentTerminal.sln
|
||||
parallel: true
|
||||
verbosity: minimal
|
||||
before_test:
|
||||
- cmd: dotnet build FluentTerminal.App.Services.Test\FluentTerminal.App.Services.Test.csproj
|
||||
test:
|
||||
assemblies:
|
||||
only:
|
||||
- '**\*.Test.dll'
|
||||
deploy: off
|
||||