Enable previewing the color scheme in the command palette (#9794)
## Summary of the Pull Request Allow schemes to be previewed as the user hovers over them in the Command Palette. ![preview-set-color-scheme](https://user-images.githubusercontent.com/18356694/114557761-9a3cbd80-9c2f-11eb-987f-eb0c89ee1fa6.gif) ## References * Branched off of #8392, which is why the commit history is so polluted.330a8e8
:544b2fd
has the interesting commits * #5400: cmdpal megathread ### Potential follow-ups * changing the font size * changing the font face * changing the opacity of acrylic ## PR Checklist * [x] Closes #6689, a last straggling FHL PR * [x] I work here * [ ] Tests added/passed * [n/a] Requires documentation to be updated - I don't think so ## Detailed Description of the Pull Request / Additional comments This works by inserting a "preview" `TerminalSettings` into the settings hierarchy, before the `TermControl`'s runtime settings, and after the ones from the actual `CascadiaSettings`. This allows us to modify that preview settings object, then discard it when we're done with the preview. This could also be used for other settings in the future - I built it to be extensible to other `ShortcutAction`s, though I haven't implemented those yet. ## Validation Steps Performed * Select a colorscheme - it becomes the active one * `colortool -x <scheme>` after selecting a scheme - colortool overrides the selected scheme * Select a colorscheme after a `colortool -x <scheme>` after selecting a scheme - the scheme in the palette becomes the active one * Pressing <kbd>esc</kbd> at any point to dismiss the command palette - scheme returns to the previous one * reloading the settings - returns to the scheme in the settings
This commit is contained in:
parent
d7e176998c
commit
546322b5c1
|
@ -88,6 +88,11 @@ namespace TerminalAppLocalTests
|
|||
TEST_METHOD(TestWindowRenameSuccessful);
|
||||
TEST_METHOD(TestWindowRenameFailure);
|
||||
|
||||
TEST_METHOD(TestControlSettingsHasParent);
|
||||
TEST_METHOD(TestPreviewCommitScheme);
|
||||
TEST_METHOD(TestPreviewDismissScheme);
|
||||
TEST_METHOD(TestPreviewSchemeWhilePreviewing);
|
||||
|
||||
TEST_CLASS_SETUP(ClassSetup)
|
||||
{
|
||||
return true;
|
||||
|
@ -578,6 +583,75 @@ namespace TerminalAppLocalTests
|
|||
"tabTitle" : "Profile 3",
|
||||
"historySize": 4
|
||||
}
|
||||
],
|
||||
"schemes":
|
||||
[
|
||||
{
|
||||
"name": "Campbell",
|
||||
"foreground": "#CCCCCC",
|
||||
"background": "#0C0C0C",
|
||||
"cursorColor": "#FFFFFF",
|
||||
"black": "#0C0C0C",
|
||||
"red": "#C50F1F",
|
||||
"green": "#13A10E",
|
||||
"yellow": "#C19C00",
|
||||
"blue": "#0037DA",
|
||||
"purple": "#881798",
|
||||
"cyan": "#3A96DD",
|
||||
"white": "#CCCCCC",
|
||||
"brightBlack": "#767676",
|
||||
"brightRed": "#E74856",
|
||||
"brightGreen": "#16C60C",
|
||||
"brightYellow": "#F9F1A5",
|
||||
"brightBlue": "#3B78FF",
|
||||
"brightPurple": "#B4009E",
|
||||
"brightCyan": "#61D6D6",
|
||||
"brightWhite": "#F2F2F2"
|
||||
},
|
||||
{
|
||||
"name": "Vintage",
|
||||
"foreground": "#C0C0C0",
|
||||
"background": "#000000",
|
||||
"cursorColor": "#FFFFFF",
|
||||
"black": "#000000",
|
||||
"red": "#800000",
|
||||
"green": "#008000",
|
||||
"yellow": "#808000",
|
||||
"blue": "#000080",
|
||||
"purple": "#800080",
|
||||
"cyan": "#008080",
|
||||
"white": "#C0C0C0",
|
||||
"brightBlack": "#808080",
|
||||
"brightRed": "#FF0000",
|
||||
"brightGreen": "#00FF00",
|
||||
"brightYellow": "#FFFF00",
|
||||
"brightBlue": "#0000FF",
|
||||
"brightPurple": "#FF00FF",
|
||||
"brightCyan": "#00FFFF",
|
||||
"brightWhite": "#FFFFFF"
|
||||
},
|
||||
{
|
||||
"name": "One Half Light",
|
||||
"foreground": "#383A42",
|
||||
"background": "#FAFAFA",
|
||||
"cursorColor": "#4F525D",
|
||||
"black": "#383A42",
|
||||
"red": "#E45649",
|
||||
"green": "#50A14F",
|
||||
"yellow": "#C18301",
|
||||
"blue": "#0184BC",
|
||||
"purple": "#A626A4",
|
||||
"cyan": "#0997B3",
|
||||
"white": "#FAFAFA",
|
||||
"brightBlack": "#4F525D",
|
||||
"brightRed": "#DF6C75",
|
||||
"brightGreen": "#98C379",
|
||||
"brightYellow": "#E4C07A",
|
||||
"brightBlue": "#61AFEF",
|
||||
"brightPurple": "#C577DD",
|
||||
"brightCyan": "#56B5C1",
|
||||
"brightWhite": "#FFFFFF"
|
||||
}
|
||||
]
|
||||
})" };
|
||||
|
||||
|
@ -1012,4 +1086,260 @@ namespace TerminalAppLocalTests
|
|||
L"The window name should not have changed, we should have rejected the change.");
|
||||
});
|
||||
}
|
||||
|
||||
void TabTests::TestControlSettingsHasParent()
|
||||
{
|
||||
Log::Comment(L"Ensure that when we create a control, it always has a parent TerminalSettings");
|
||||
|
||||
auto page = _commonSetup();
|
||||
VERIFY_IS_NOT_NULL(page);
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
});
|
||||
}
|
||||
|
||||
void TabTests::TestPreviewCommitScheme()
|
||||
{
|
||||
Log::Comment(L"Preview a color scheme. Make sure it's applied, then committed accordingly");
|
||||
|
||||
auto page = _commonSetup();
|
||||
VERIFY_IS_NOT_NULL(page);
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
Log::Comment(L"Emulate previewing the SetColorScheme action");
|
||||
SetColorSchemeArgs args{ L"Vintage" };
|
||||
page->_PreviewColorScheme(args);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& previewSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(previewSettings);
|
||||
|
||||
const auto& originalSettings = previewSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed to the preview");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
|
||||
VERIFY_ARE_EQUAL(originalSettings, page->_originalSettings);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
Log::Comment(L"Emulate committing the SetColorScheme action");
|
||||
|
||||
SetColorSchemeArgs args{ L"Vintage" };
|
||||
page->_EndPreviewColorScheme();
|
||||
page->_HandleSetColorScheme(nullptr, ActionEventArgs{ args });
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
const auto& grandparentSettings = originalSettings.GetParent();
|
||||
VERIFY_IS_NULL(grandparentSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
|
||||
VERIFY_ARE_EQUAL(nullptr, page->_originalSettings);
|
||||
});
|
||||
}
|
||||
|
||||
void TabTests::TestPreviewDismissScheme()
|
||||
{
|
||||
Log::Comment(L"Preview a color scheme. Make sure it's applied, then dismissed accordingly");
|
||||
|
||||
auto page = _commonSetup();
|
||||
VERIFY_IS_NOT_NULL(page);
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
Log::Comment(L"Emulate previewing the SetColorScheme action");
|
||||
SetColorSchemeArgs args{ L"Vintage" };
|
||||
page->_PreviewColorScheme(args);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& previewSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(previewSettings);
|
||||
|
||||
const auto& originalSettings = previewSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed to the preview");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
|
||||
VERIFY_ARE_EQUAL(originalSettings, page->_originalSettings);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
Log::Comment(L"Emulate dismissing the SetColorScheme action");
|
||||
page->_EndPreviewColorScheme();
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
const auto& grandparentSettings = originalSettings.GetParent();
|
||||
VERIFY_IS_NULL(grandparentSettings);
|
||||
|
||||
Log::Comment(L"Color should be the same as it originally was");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
|
||||
VERIFY_ARE_EQUAL(nullptr, page->_originalSettings);
|
||||
});
|
||||
}
|
||||
|
||||
void TabTests::TestPreviewSchemeWhilePreviewing()
|
||||
{
|
||||
Log::Comment(L"Preview a color scheme, then preview another scheme. ");
|
||||
|
||||
Log::Comment(L"Preview a color scheme. Make sure it's applied, then committed accordingly");
|
||||
|
||||
auto page = _commonSetup();
|
||||
VERIFY_IS_NOT_NULL(page);
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff0c0c0c }, controlSettings.DefaultBackground());
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
Log::Comment(L"Emulate previewing the SetColorScheme action");
|
||||
SetColorSchemeArgs args{ L"Vintage" };
|
||||
page->_PreviewColorScheme(args);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& previewSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(previewSettings);
|
||||
|
||||
const auto& originalSettings = previewSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed to the preview");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xff000000 }, controlSettings.DefaultBackground());
|
||||
VERIFY_ARE_EQUAL(originalSettings, page->_originalSettings);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
Log::Comment(L"Now, preview another scheme");
|
||||
SetColorSchemeArgs args{ L"One Half Light" };
|
||||
page->_PreviewColorScheme(args);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& previewSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(previewSettings);
|
||||
|
||||
const auto& originalSettings = previewSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed to the preview");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xffFAFAFA }, controlSettings.DefaultBackground());
|
||||
VERIFY_ARE_EQUAL(originalSettings, page->_originalSettings);
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
Log::Comment(L"Emulate committing the SetColorScheme action");
|
||||
|
||||
SetColorSchemeArgs args{ L"One Half Light" };
|
||||
page->_EndPreviewColorScheme();
|
||||
page->_HandleSetColorScheme(nullptr, ActionEventArgs{ args });
|
||||
});
|
||||
|
||||
TestOnUIThread([&page]() {
|
||||
const auto& activeControl{ page->_GetActiveControl() };
|
||||
VERIFY_IS_NOT_NULL(activeControl);
|
||||
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
VERIFY_IS_NOT_NULL(controlSettings);
|
||||
|
||||
const auto& originalSettings = controlSettings.GetParent();
|
||||
VERIFY_IS_NOT_NULL(originalSettings);
|
||||
|
||||
const auto& grandparentSettings = originalSettings.GetParent();
|
||||
VERIFY_IS_NULL(grandparentSettings);
|
||||
|
||||
Log::Comment(L"Color should be changed");
|
||||
VERIFY_ARE_EQUAL(til::color{ 0xffFAFAFA }, controlSettings.DefaultBackground());
|
||||
VERIFY_ARE_EQUAL(nullptr, page->_originalSettings);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
189
src/cascadia/TerminalApp/ActionPreviewHandlers.cpp
Normal file
189
src/cascadia/TerminalApp/ActionPreviewHandlers.cpp
Normal file
|
@ -0,0 +1,189 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "TerminalPage.h"
|
||||
#include "Utils.h"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
|
||||
#include <LibraryResources.h>
|
||||
|
||||
using namespace winrt;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Core;
|
||||
using namespace winrt::Windows::System;
|
||||
using namespace winrt::Windows::ApplicationModel::DataTransfer;
|
||||
using namespace winrt::Windows::UI::Text;
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using namespace winrt::Microsoft::Terminal::TerminalConnection;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace ::TerminalApp;
|
||||
using namespace ::Microsoft::Console;
|
||||
using namespace std::chrono_literals;
|
||||
namespace winrt
|
||||
{
|
||||
namespace MUX = Microsoft::UI::Xaml;
|
||||
namespace WUX = Windows::UI::Xaml;
|
||||
using IInspectable = Windows::Foundation::IInspectable;
|
||||
}
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// Method Description:
|
||||
// - Stop previewing the currently previewed action. We can use this to
|
||||
// clean up any state from that action's preview.
|
||||
// - We use _lastPreviewedCommand to determine what type of action to clean up.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_EndPreview()
|
||||
{
|
||||
if (_lastPreviewedCommand == nullptr || _lastPreviewedCommand.Action() == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
switch (_lastPreviewedCommand.Action().Action())
|
||||
{
|
||||
case ShortcutAction::SetColorScheme:
|
||||
{
|
||||
_EndPreviewColorScheme();
|
||||
break;
|
||||
}
|
||||
}
|
||||
_lastPreviewedCommand = nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Revert any changes from the preview on a SetColorScheme action. This
|
||||
// will remove the preview TerminalSettings we inserted into the control's
|
||||
// TerminalSettings graph, and update the control.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_EndPreviewColorScheme()
|
||||
{
|
||||
// Get the focused control
|
||||
if (const auto& activeControl{ _GetActiveControl() })
|
||||
{
|
||||
// Get the runtime settings of the focused control
|
||||
const auto& controlSettings{ activeControl.Settings().as<TerminalSettings>() };
|
||||
|
||||
// Get the control's root settings, the ones that we actually
|
||||
// assigned to it.
|
||||
auto parentSettings{ controlSettings.GetParent() };
|
||||
while (parentSettings.GetParent() != nullptr)
|
||||
{
|
||||
parentSettings = parentSettings.GetParent();
|
||||
}
|
||||
|
||||
// If the root settings are the same as the ones we stashed,
|
||||
// then reset the parent of the runtime settings to the stashed
|
||||
// settings. This condition might be false if the settings
|
||||
// hot-reloaded while the palette was open. In that case, we
|
||||
// don't want to reset the settings to what they were _before_
|
||||
// the hot-reload.
|
||||
if (_originalSettings == parentSettings)
|
||||
{
|
||||
// Set the original settings as the parent of the control's settings
|
||||
activeControl.Settings().as<TerminalSettings>().SetParent(_originalSettings);
|
||||
}
|
||||
|
||||
activeControl.UpdateSettings();
|
||||
}
|
||||
_originalSettings = nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Preview handler for the SetColorScheme action.
|
||||
// - This method will stash the settings of the current control in
|
||||
// _originalSettings. Then it will create a new TerminalSettings object
|
||||
// with only the properties from the ColorScheme set. It'll _insert_ a
|
||||
// TerminalSettings between the control's root settings (built from
|
||||
// CascadiaSettings) and the control's runtime settings. That'll cause the
|
||||
// control to use _that_ table as the active color scheme.
|
||||
// Arguments:
|
||||
// - args: The SetColorScheme args with the name of the scheme to use.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_PreviewColorScheme(const Settings::Model::SetColorSchemeArgs& args)
|
||||
{
|
||||
// Get the focused control
|
||||
if (const auto& activeControl{ _GetActiveControl() })
|
||||
{
|
||||
if (const auto& scheme{ _settings.GlobalSettings().ColorSchemes().TryLookup(args.SchemeName()) })
|
||||
{
|
||||
// Get the settings of the focused control and stash them
|
||||
const auto& controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
// Make sure to recurse up to the root - if you're doing
|
||||
// this while you're currently previewing a SetColorScheme
|
||||
// action, then the parent of the control's settings is _the
|
||||
// last preview TerminalSettings we inserted! We don't want
|
||||
// to save that one!
|
||||
_originalSettings = controlSettings.GetParent();
|
||||
while (_originalSettings.GetParent() != nullptr)
|
||||
{
|
||||
_originalSettings = _originalSettings.GetParent();
|
||||
}
|
||||
// Create a new child for those settings
|
||||
TerminalSettingsCreateResult fake{ _originalSettings };
|
||||
const auto& childStruct = TerminalSettings::CreateWithParent(fake);
|
||||
// Modify the child to have the applied color scheme
|
||||
childStruct.DefaultSettings().ApplyColorScheme(scheme);
|
||||
|
||||
// Insert that new child as the parent of the control's settings
|
||||
controlSettings.SetParent(childStruct.DefaultSettings());
|
||||
activeControl.UpdateSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Handler for the CommandPalette::PreviewAction event. The Command
|
||||
// Palette will raise this even when an action is selected, but _not_
|
||||
// committed. This gives the Terminal a chance to display a "preview" of
|
||||
// the action.
|
||||
// - This will be called with a null args before an action is dispatched, or
|
||||
// when the palette is dismissed.
|
||||
// - For any actions that are to be previewed here, MAKE SURE TO RESTORE THE
|
||||
// STATE IN `TerminalPage::_EndPreview`. That method is called to revert
|
||||
// the terminal to the state it was in at the start of the preview.
|
||||
// - Currently, only SetColorScheme actions are preview-able.
|
||||
// Arguments:
|
||||
// - args: The Command that's trying to be previewed, or nullptr if we should stop the preview.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalPage::_PreviewActionHandler(const IInspectable& /*sender*/,
|
||||
const Microsoft::Terminal::Settings::Model::Command& args)
|
||||
{
|
||||
if (args == nullptr || args.Action() == nullptr)
|
||||
{
|
||||
_EndPreview();
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (args.Action().Action())
|
||||
{
|
||||
case ShortcutAction::SetColorScheme:
|
||||
{
|
||||
_PreviewColorScheme(args.Action().Args().try_as<SetColorSchemeArgs>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// GH#9818 Other ideas for actions that could be preview-able:
|
||||
// * Set Font size
|
||||
// * Set acrylic true/false/opacity?
|
||||
// * SetPixelShaderPath?
|
||||
// * SetWindowTheme (light/dark/system/<some theme from #3327>)?
|
||||
|
||||
// Stash this action, so we know what to do when we're done
|
||||
// previewing.
|
||||
_lastPreviewedCommand = args;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -383,8 +383,27 @@ namespace winrt::TerminalApp::implementation
|
|||
{
|
||||
if (const auto scheme = _settings.GlobalSettings().ColorSchemes().TryLookup(realArgs.SchemeName()))
|
||||
{
|
||||
// Start by getting the current settings of the control
|
||||
auto controlSettings = activeControl.Settings().as<TerminalSettings>();
|
||||
controlSettings.ApplyColorScheme(scheme);
|
||||
auto parentSettings = controlSettings;
|
||||
// Those are the _runtime_ settings however. What we
|
||||
// need to do is:
|
||||
//
|
||||
// 1. Blow away any colors set in the runtime settings.
|
||||
// 2. Apply the color scheme to the parent settings.
|
||||
//
|
||||
// 1 is important to make sure that the effects of
|
||||
// something like `colortool` are cleared when setting
|
||||
// the scheme.
|
||||
if (controlSettings.GetParent() != nullptr)
|
||||
{
|
||||
parentSettings = controlSettings.GetParent();
|
||||
}
|
||||
|
||||
// ApplyColorScheme(nullptr) will clear the old color scheme.
|
||||
controlSettings.ApplyColorScheme(nullptr);
|
||||
parentSettings.ApplyColorScheme(scheme);
|
||||
|
||||
activeControl.UpdateSettings();
|
||||
args.Handled(true);
|
||||
}
|
||||
|
|
|
@ -231,12 +231,19 @@ namespace winrt::TerminalApp::implementation
|
|||
void CommandPalette::_selectedCommandChanged(const IInspectable& /*sender*/,
|
||||
const Windows::UI::Xaml::RoutedEventArgs& /*args*/)
|
||||
{
|
||||
const auto selectedCommand = _filteredActionsView().SelectedItem();
|
||||
const auto filteredCommand{ selectedCommand.try_as<winrt::TerminalApp::FilteredCommand>() };
|
||||
if (_currentMode == CommandPaletteMode::TabSwitchMode)
|
||||
{
|
||||
const auto selectedCommand = _filteredActionsView().SelectedItem();
|
||||
const auto filteredCommand{ selectedCommand.try_as<winrt::TerminalApp::FilteredCommand>() };
|
||||
_switchToTab(filteredCommand);
|
||||
}
|
||||
else if (_currentMode == CommandPaletteMode::ActionMode && filteredCommand != nullptr)
|
||||
{
|
||||
if (const auto actionPaletteItem{ filteredCommand.Item().try_as<winrt::TerminalApp::ActionPaletteItem>() })
|
||||
{
|
||||
_PreviewActionHandlers(*this, actionPaletteItem.Command());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CommandPalette::_previewKeyDownHandler(IInspectable const& /*sender*/,
|
||||
|
@ -1084,6 +1091,8 @@ namespace winrt::TerminalApp::implementation
|
|||
{
|
||||
Visibility(Visibility::Collapsed);
|
||||
|
||||
_PreviewActionHandlers(*this, nullptr);
|
||||
|
||||
// Reset visibility in case anchor mode tab switcher just finished.
|
||||
_searchBox().Visibility(Visibility::Visible);
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ namespace winrt::TerminalApp::implementation
|
|||
TYPED_EVENT(SwitchToTabRequested, winrt::TerminalApp::CommandPalette, winrt::TerminalApp::TabBase);
|
||||
TYPED_EVENT(CommandLineExecutionRequested, winrt::TerminalApp::CommandPalette, winrt::hstring);
|
||||
TYPED_EVENT(DispatchCommandRequested, winrt::TerminalApp::CommandPalette, Microsoft::Terminal::Settings::Model::Command);
|
||||
TYPED_EVENT(PreviewAction, Windows::Foundation::IInspectable, Microsoft::Terminal::Settings::Model::Command);
|
||||
|
||||
private:
|
||||
friend struct CommandPaletteT<CommandPalette>; // for Xaml to bind events
|
||||
|
|
|
@ -36,5 +36,6 @@ namespace TerminalApp
|
|||
event Windows.Foundation.TypedEventHandler<CommandPalette, TabBase> SwitchToTabRequested;
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, Microsoft.Terminal.Settings.Model.Command> DispatchCommandRequested;
|
||||
event Windows.Foundation.TypedEventHandler<CommandPalette, String> CommandLineExecutionRequested;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Settings.Model.Command> PreviewAction;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,6 +176,10 @@
|
|||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ActionPreviewHandlers.cpp">
|
||||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TerminalTabStatus.cpp">
|
||||
<DependentUpon>TerminalTabStatus.idl</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
|
@ -220,7 +224,7 @@
|
|||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AppActionHandlers.cpp">
|
||||
<DependentUpon>App.xaml</DependentUpon>
|
||||
<DependentUpon>TerminalPage.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="AppLogic.cpp">
|
||||
<DependentUpon>AppLogic.idl</DependentUpon>
|
||||
|
|
|
@ -235,6 +235,7 @@ namespace winrt::TerminalApp::implementation
|
|||
CommandPalette().DispatchCommandRequested({ this, &TerminalPage::_OnDispatchCommandRequested });
|
||||
CommandPalette().CommandLineExecutionRequested({ this, &TerminalPage::_OnCommandLineExecutionRequested });
|
||||
CommandPalette().SwitchToTabRequested({ this, &TerminalPage::_OnSwitchToTabRequested });
|
||||
CommandPalette().PreviewAction({ this, &TerminalPage::_PreviewActionHandler });
|
||||
|
||||
// Settings AllowDependentAnimations will affect whether animations are
|
||||
// enabled application-wide, so we don't need to check it each time we
|
||||
|
@ -2751,4 +2752,5 @@ namespace winrt::TerminalApp::implementation
|
|||
WindowRenamer().IsOpen(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -321,6 +321,13 @@ namespace winrt::TerminalApp::implementation
|
|||
void _HidePointerCursorHandler(const IInspectable& sender, const IInspectable& eventArgs);
|
||||
void _RestorePointerCursorHandler(const IInspectable& sender, const IInspectable& eventArgs);
|
||||
|
||||
void _PreviewActionHandler(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::Command& args);
|
||||
void _EndPreview();
|
||||
void _EndPreviewColorScheme();
|
||||
void _PreviewColorScheme(const Microsoft::Terminal::Settings::Model::SetColorSchemeArgs& args);
|
||||
winrt::Microsoft::Terminal::Settings::Model::Command _lastPreviewedCommand{ nullptr };
|
||||
winrt::Microsoft::Terminal::Settings::Model::TerminalSettings _originalSettings{ nullptr };
|
||||
|
||||
void _OnNewConnection(winrt::Microsoft::Terminal::TerminalConnection::ITerminalConnection connection);
|
||||
void _HandleToggleInboundPty(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::ActionEventArgs& args);
|
||||
|
||||
|
|
|
@ -498,6 +498,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
struct SetColorSchemeArgs : public SetColorSchemeArgsT<SetColorSchemeArgs>
|
||||
{
|
||||
SetColorSchemeArgs() = default;
|
||||
SetColorSchemeArgs(winrt::hstring name) :
|
||||
_SchemeName{ name } {};
|
||||
WINRT_PROPERTY(winrt::hstring, SchemeName, L"");
|
||||
|
||||
static constexpr std::string_view NameKey{ "colorScheme" };
|
||||
|
@ -1045,6 +1047,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
|||
BASIC_FACTORY(NewTabArgs);
|
||||
BASIC_FACTORY(MoveFocusArgs);
|
||||
BASIC_FACTORY(SplitPaneArgs);
|
||||
BASIC_FACTORY(SetColorSchemeArgs);
|
||||
BASIC_FACTORY(ExecuteCommandlineArgs);
|
||||
BASIC_FACTORY(CloseOtherTabsArgs);
|
||||
BASIC_FACTORY(CloseTabsAfterArgs);
|
||||
|
|
|
@ -173,6 +173,7 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
|
||||
[default_interface] runtimeclass SetColorSchemeArgs : IActionArgs
|
||||
{
|
||||
SetColorSchemeArgs(String name);
|
||||
String SchemeName { get; };
|
||||
};
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "../../types/inc/colorTable.hpp"
|
||||
|
||||
#include "TerminalSettings.g.cpp"
|
||||
#include "TerminalSettingsCreateResult.g.cpp"
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using namespace Microsoft::Console::Utils;
|
||||
|
@ -231,6 +232,15 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
InsertParent(parentImpl);
|
||||
}
|
||||
|
||||
Model::TerminalSettings TerminalSettings::GetParent()
|
||||
{
|
||||
if (_parents.size() > 0)
|
||||
{
|
||||
return *_parents.at(0);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Apply Profile settings, as well as any colors from our color scheme, if we have one.
|
||||
// Arguments:
|
||||
|
@ -307,15 +317,30 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
// - <none>
|
||||
void TerminalSettings::ApplyColorScheme(const Model::ColorScheme& scheme)
|
||||
{
|
||||
_DefaultForeground = til::color{ scheme.Foreground() };
|
||||
_DefaultBackground = til::color{ scheme.Background() };
|
||||
_SelectionBackground = til::color{ scheme.SelectionBackground() };
|
||||
_CursorColor = til::color{ scheme.CursorColor() };
|
||||
// If the scheme was nullptr, then just clear out the current color
|
||||
// settings.
|
||||
if (scheme == nullptr)
|
||||
{
|
||||
ClearDefaultForeground();
|
||||
ClearDefaultBackground();
|
||||
ClearSelectionBackground();
|
||||
ClearCursorColor();
|
||||
_ColorTable = std::nullopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
_DefaultForeground = til::color{ scheme.Foreground() };
|
||||
_DefaultBackground = til::color{ scheme.Background() };
|
||||
_SelectionBackground = til::color{ scheme.SelectionBackground() };
|
||||
_CursorColor = til::color{ scheme.CursorColor() };
|
||||
|
||||
const auto table = scheme.Table();
|
||||
std::array<winrt::Microsoft::Terminal::Core::Color, COLOR_TABLE_SIZE> colorTable{};
|
||||
std::copy(table.cbegin(), table.cend(), colorTable.begin());
|
||||
ColorTable(colorTable);
|
||||
const auto table = scheme.Table();
|
||||
std::array<winrt::Microsoft::Terminal::Core::Color, COLOR_TABLE_SIZE> colorTable{};
|
||||
std::transform(table.cbegin(), table.cend(), colorTable.begin(), [](auto&& color) {
|
||||
return static_cast<winrt::Microsoft::Terminal::Core::Color>(til::color{ color });
|
||||
});
|
||||
ColorTable(colorTable);
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Core::Color TerminalSettings::GetColorTableEntry(int32_t index) noexcept
|
||||
|
|
|
@ -37,6 +37,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
_defaultSettings(defaultSettings),
|
||||
_unfocusedSettings(unfocusedSettings) {}
|
||||
|
||||
TerminalSettingsCreateResult(Model::TerminalSettings defaultSettings) :
|
||||
_defaultSettings(defaultSettings),
|
||||
_unfocusedSettings(nullptr) {}
|
||||
|
||||
Model::TerminalSettings DefaultSettings() { return _defaultSettings; };
|
||||
Model::TerminalSettings UnfocusedSettings() { return _unfocusedSettings; };
|
||||
|
||||
|
@ -58,6 +62,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
const Control::IKeyBindings& keybindings);
|
||||
|
||||
static Model::TerminalSettingsCreateResult CreateWithParent(const Model::TerminalSettingsCreateResult& parent);
|
||||
|
||||
Model::TerminalSettings GetParent();
|
||||
|
||||
void SetParent(const Model::TerminalSettings& parent);
|
||||
|
||||
void ApplyColorScheme(const Model::ColorScheme& scheme);
|
||||
|
@ -152,5 +159,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
|||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(TerminalSettingsCreateResult);
|
||||
BASIC_FACTORY(TerminalSettings);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
{
|
||||
runtimeclass TerminalSettingsCreateResult
|
||||
{
|
||||
TerminalSettingsCreateResult(TerminalSettings defaultSettings);
|
||||
TerminalSettings DefaultSettings { get; };
|
||||
TerminalSettings UnfocusedSettings { get; };
|
||||
}
|
||||
|
@ -30,6 +31,7 @@ namespace Microsoft.Terminal.Settings.Model
|
|||
static TerminalSettingsCreateResult CreateWithParent(TerminalSettingsCreateResult parent);
|
||||
|
||||
void SetParent(TerminalSettings parent);
|
||||
TerminalSettings GetParent();
|
||||
void ApplyColorScheme(ColorScheme scheme);
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue