200 lines
8.6 KiB
C++
200 lines
8.6 KiB
C++
// 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.ActionAndArgs() == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
switch (_lastPreviewedCommand.ActionAndArgs().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()
|
|
{
|
|
for (const auto& f : _restorePreviewFuncs)
|
|
{
|
|
f();
|
|
}
|
|
_restorePreviewFuncs.clear();
|
|
}
|
|
|
|
// Method Description:
|
|
// - Preview handler for the SetColorScheme action.
|
|
// - This method will stash functions to reset the settings of the selected controls in
|
|
// _restorePreviewFuncs. 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)
|
|
{
|
|
if (const auto& scheme{ _settings.GlobalSettings().ColorSchemes().TryLookup(args.SchemeName()) })
|
|
{
|
|
// Clear the saved preview funcs because we don't need to add a restore each time
|
|
// the preview color changes, we only need to be able to restore the last one.
|
|
_restorePreviewFuncs.clear();
|
|
|
|
_ApplyToActiveControls([&](const auto& control) {
|
|
auto originalScheme{ control.ColorScheme() };
|
|
control.ColorScheme(scheme.ToCoreScheme());
|
|
|
|
// // Get the settings of the focused control and stash them
|
|
// const auto& controlSettings = control.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!
|
|
// auto 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());
|
|
// control.UpdateControlSettings(controlSettings);
|
|
|
|
// // Take a copy of the inputs, since they are pointers anyways.
|
|
_restorePreviewFuncs.emplace_back([=]() {
|
|
control.ColorScheme(originalScheme);
|
|
//// Get the runtime settings of the focused control
|
|
//const auto& controlSettings{ control.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
|
|
// control.Settings().as<TerminalSettings>().SetParent(originalSettings);
|
|
//}
|
|
|
|
// control.UpdateControlSettings(control.Settings());
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
// 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.ActionAndArgs() == nullptr)
|
|
{
|
|
_EndPreview();
|
|
}
|
|
else
|
|
{
|
|
switch (args.ActionAndArgs().Action())
|
|
{
|
|
case ShortcutAction::SetColorScheme:
|
|
{
|
|
_PreviewColorScheme(args.ActionAndArgs().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;
|
|
}
|
|
}
|
|
}
|