terminal/src/cascadia/TerminalApp/TerminalSettings.h
Mike Griese b140299e50
Implement user-specified pixel shaders, redux (#8565)
Co-authored-by: mrange <marten_range@hotmail.com>

I loved the pixel shaders in #7058, but that PR needed a bit of polish
to be ready for ingestion. This PR is almost _exactly_ that PR, with
some small changes.

* It adds a new pre-profile setting `"experimental.pixelShaderPath"`,
  which lets the user set a pixel shader to use with the Terminal.
    - CHANGED FROM #7058: It does _not_ add any built-in shaders.
    - CHANGED FROM #7058: it will _override_
      `experimental.retroTerminalEffect`
* It adds a bunch of sample shaders in `samples/shaders`. Included: 
    - A NOP shader as a base to build from.
    - An "invert" shader that inverts the colors, as a simple example
    - An "grayscale" shader that converts all colors to grayscale, as a
      simple example
    - An "raster bars" shader that draws some colored bars on the screen
      with a drop shadow, as a more involved example
    - The original retro terminal effects, as a more involved example
    - It also includes a broken shader, as an example of what heppens
      when the shader fails to compile
    - CHANGED FROM #7058: It does _not_ add the "retroII" shader we were
      all worried about.
* When a shader fails to be found or fails to compile, we'll display an
  error dialog to the user with a relevant error message.
    - CHANGED FROM #7058: Originally, #7058 would display "error bars"
      on the screen. I've removed that, and had the Terminal disable the
      shader entirely then.
* Renames the `toggleRetroEffect` action to `toggleShaderEffect`.
  (`toggleRetroEffect` is now an alias to `toggleShaderEffect`). This
  action will turn the shader OR the retro effects on/off. 

`toggleShaderEffect` works the way you'd expect it to, but the mental
math on _how_ is a little weird. The logic is basically:

```
useShader = shaderEffectsEnabled ? 
                (pixelShaderProvided ? 
                    pixelShader : 
                    (retroEffectEnabled ? 
                        retroEffect : null
                    )
                ) : 
                null
```

and `toggleShaderEffect` toggles `shaderEffectsEnabled`.

* If you've got both a shader and retro enabled, `toggleShaderEffect`
  will toggle between the shader on/off.
* If you've got a shader and retro disabled, `toggleShaderEffect` will
  toggle between the shader on/off.

References #6191
References #7058

Closes #7013

Closes #3930 "Add setting to retro terminal shader to control blur
radius, color" 
Closes #3929 "Add setting to retro terminal shader to enable drawing
scanlines" 
     - At this point, just roll your own version of the shader.
2020-12-15 20:40:22 +00:00

141 lines
6.7 KiB
C++

/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- TerminalSettings.h
Abstract:
- The implementation of the TerminalSettings winrt class. Provides both
terminal control settings and terminal core settings.
Author(s):
- Mike Griese - March 2019
--*/
#pragma once
#include "TerminalSettings.g.h"
#include "../inc/cppwinrt_utils.h"
#include <DefaultSettings.h>
#include <conattrs.hpp>
// fwdecl unittest classes
namespace TerminalAppLocalTests
{
class SettingsTests;
}
namespace winrt::TerminalApp::implementation
{
struct TerminalSettings : TerminalSettingsT<TerminalSettings>
{
TerminalSettings() = default;
TerminalSettings(const Microsoft::Terminal::Settings::Model::CascadiaSettings& appSettings,
guid profileGuid,
const Microsoft::Terminal::TerminalControl::IKeyBindings& keybindings);
static std::tuple<guid, TerminalApp::TerminalSettings> BuildSettings(const Microsoft::Terminal::Settings::Model::CascadiaSettings& appSettings,
const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs,
const Microsoft::Terminal::TerminalControl::IKeyBindings& keybindings);
void ApplyColorScheme(const Microsoft::Terminal::Settings::Model::ColorScheme& scheme);
// TECHNICALLY, the hstring copy assignment can throw, but the GETSET_PROPERTY
// macro defines the operator as `noexcept`. We're not really worried about it,
// because the only time it will throw is when we're out of memory, and then
// we've got much worse problems. So just suppress that warning for now.
#pragma warning(push)
#pragma warning(disable : 26447)
// --------------------------- Core Settings ---------------------------
// All of these settings are defined in ICoreSettings.
// GetColorTableEntry needs to be implemented manually, to get a
// particular value from the array.
uint32_t GetColorTableEntry(int32_t index) const noexcept;
GETSET_PROPERTY(uint32_t, DefaultForeground, DEFAULT_FOREGROUND_WITH_ALPHA);
GETSET_PROPERTY(uint32_t, DefaultBackground, DEFAULT_BACKGROUND_WITH_ALPHA);
GETSET_PROPERTY(uint32_t, SelectionBackground, DEFAULT_FOREGROUND);
GETSET_PROPERTY(int32_t, HistorySize, DEFAULT_HISTORY_SIZE);
GETSET_PROPERTY(int32_t, InitialRows, 30);
GETSET_PROPERTY(int32_t, InitialCols, 80);
GETSET_PROPERTY(bool, SnapOnInput, true);
GETSET_PROPERTY(bool, AltGrAliasing, true);
GETSET_PROPERTY(uint32_t, CursorColor, DEFAULT_CURSOR_COLOR);
GETSET_PROPERTY(Microsoft::Terminal::TerminalControl::CursorStyle, CursorShape, Microsoft::Terminal::TerminalControl::CursorStyle::Vintage);
GETSET_PROPERTY(uint32_t, CursorHeight, DEFAULT_CURSOR_HEIGHT);
GETSET_PROPERTY(hstring, WordDelimiters, DEFAULT_WORD_DELIMITERS);
GETSET_PROPERTY(bool, CopyOnSelect, false);
GETSET_PROPERTY(Windows::Foundation::IReference<uint32_t>, TabColor, nullptr);
// When set, StartingTabColor allows to create a terminal with a "sticky" tab color.
// This color is prioritized above the TabColor (that is usually initialized based on profile settings).
// Due to this prioritization, the tab color will be preserved upon settings reload
// (even if the profile's tab color gets altered or removed).
// This property is expected to be passed only once upon terminal creation.
// TODO: to ensure that this property is not populated during settings reload,
// we should consider moving this property to a separate interface,
// passed to the terminal only upon creation.
GETSET_PROPERTY(Windows::Foundation::IReference<uint32_t>, StartingTabColor, nullptr);
// ------------------------ End of Core Settings -----------------------
GETSET_PROPERTY(hstring, ProfileName);
GETSET_PROPERTY(bool, UseAcrylic, false);
GETSET_PROPERTY(double, TintOpacity, 0.5);
GETSET_PROPERTY(hstring, Padding, DEFAULT_PADDING);
GETSET_PROPERTY(hstring, FontFace, DEFAULT_FONT_FACE);
GETSET_PROPERTY(int32_t, FontSize, DEFAULT_FONT_SIZE);
GETSET_PROPERTY(winrt::Windows::UI::Text::FontWeight, FontWeight);
GETSET_PROPERTY(hstring, BackgroundImage);
GETSET_PROPERTY(double, BackgroundImageOpacity, 1.0);
GETSET_PROPERTY(winrt::Windows::UI::Xaml::Media::Stretch,
BackgroundImageStretchMode,
winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill);
GETSET_PROPERTY(winrt::Windows::UI::Xaml::HorizontalAlignment,
BackgroundImageHorizontalAlignment,
winrt::Windows::UI::Xaml::HorizontalAlignment::Center);
GETSET_PROPERTY(winrt::Windows::UI::Xaml::VerticalAlignment,
BackgroundImageVerticalAlignment,
winrt::Windows::UI::Xaml::VerticalAlignment::Center);
GETSET_PROPERTY(Microsoft::Terminal::TerminalControl::IKeyBindings, KeyBindings, nullptr);
GETSET_PROPERTY(hstring, Commandline);
GETSET_PROPERTY(hstring, StartingDirectory);
GETSET_PROPERTY(hstring, StartingTitle);
GETSET_PROPERTY(bool, SuppressApplicationTitle);
GETSET_PROPERTY(hstring, EnvironmentVariables);
GETSET_PROPERTY(Microsoft::Terminal::TerminalControl::ScrollbarState, ScrollState, Microsoft::Terminal::TerminalControl::ScrollbarState::Visible);
GETSET_PROPERTY(Microsoft::Terminal::TerminalControl::TextAntialiasingMode, AntialiasingMode, Microsoft::Terminal::TerminalControl::TextAntialiasingMode::Grayscale);
GETSET_PROPERTY(bool, RetroTerminalEffect, false);
GETSET_PROPERTY(bool, ForceFullRepaintRendering, false);
GETSET_PROPERTY(bool, SoftwareRendering, false);
GETSET_PROPERTY(bool, ForceVTInput, false);
GETSET_PROPERTY(hstring, PixelShaderPath);
#pragma warning(pop)
private:
std::array<uint32_t, COLOR_TABLE_SIZE> _colorTable{};
void _ApplyProfileSettings(const Microsoft::Terminal::Settings::Model::Profile& profile, const Windows::Foundation::Collections::IMapView<hstring, Microsoft::Terminal::Settings::Model::ColorScheme>& schemes);
void _ApplyGlobalSettings(const Microsoft::Terminal::Settings::Model::GlobalAppSettings& globalSettings) noexcept;
friend class TerminalAppLocalTests::SettingsTests;
};
}
namespace winrt::TerminalApp::factory_implementation
{
BASIC_FACTORY(TerminalSettings);
}