2019-06-04 23:55:27 +02:00
|
|
|
/*++
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Licensed under the MIT license.
|
|
|
|
|
|
|
|
Module Name:
|
|
|
|
- Utils.h
|
|
|
|
|
|
|
|
Abstract:
|
|
|
|
- Helpers for the TerminalApp project
|
|
|
|
Author(s):
|
|
|
|
- Mike Griese - May 2019
|
|
|
|
|
|
|
|
--*/
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Create a std::string from a string_view. We do this because we can't look
|
|
|
|
// up a key in a Json::Value with a string_view directly, so instead we'll use
|
|
|
|
// this helper. Should a string_view lookup ever be added to jsoncpp, we can
|
|
|
|
// remove this entirely.
|
|
|
|
// Arguments:
|
|
|
|
// - key: the string_view to build a string from
|
|
|
|
// Return Value:
|
|
|
|
// - a std::string to use for looking up a value from a Json::Value
|
|
|
|
inline std::string JsonKey(const std::string_view key)
|
|
|
|
{
|
|
|
|
return static_cast<std::string>(key);
|
|
|
|
}
|
2019-08-15 01:12:14 +02:00
|
|
|
|
Add Cascading User + Default Settings (#2515)
This PR represents the start of the work on Cascading User + default settings, #754.
Cascading settings will be done in two parts:
* [ ] Layered Default+User settings (this PR)
* [ ] Dynamic Profile Generation (#2603).
Until _both_ are done, _neither are going in. The dynamic profiles PR will target this PR when it's ready, but will go in as a separate commit into master.
This PR covers adding one primary feature: the settings are now in two separate files:
* a static `defaults.json` that ships with the package (the "default settings")
* a `profiles.json` with the user's customizations (the "user settings)
User settings are _layered_ upon the settings in the defaults settings.
## References
Other things that might be related here:
* #1378 - This seems like it's definitely fixed. The default keybindings are _much_ cleaner, and without the save-on-load behavior, the user's keybindings will be left in a good state
* #1398 - This might have honestly been solved by #2475
## PR Checklist
* [x] Closes #754
* [x] Closes #1378
* [x] Closes #2566
* [x] I work here
* [x] Tests added/passed
* [x] Requires documentation to be updated - it **ABSOLUTELY DOES**
## Detailed Description of the Pull Request / Additional comments
1. We start by taking all of the `FromJson` functions in Profile, ColorScheme, Globals, etc, and converting them to `LayerJson` methods. These are effectively the same, with the change that instead of building a new object, they are simply layering the values on top of `this` object.
2. Next, we add tests for layering properties like that.
3. Now, we add a `defaults.json` to the package. This is the file the users can refer to as our default settings.
4. We then take that `defaults.json` and stamp it into an auto generated `.h` file, so we can use it's data without having to worry about reading it from disk.
5. We then change the `LoadAll` function in `CascadiaSettings`. Now, the function does two loads - one from the defaults, and then a second load from the `profiles.json` file, layering the settings from each source upon the previous values.
6. If the `profiles.json` file doesn't exist, we'll create it from a hardcoded `userDefaults.json`, which is stamped in similar to how `defaults.json` is.
7. We also add support for _unbinding_ keybindings that might exist in the `defaults.json`, but the user doesn't want to be bound to anything.
8. We add support for _hiding_ a profile, which is useful if a user doesn't want one of the default profiles to appear in the list of profiles.
## TODO:
* [x] Still need to make Alt+Click work on the settings button
* [x] Need to write some user documentation on how the new settings model works
* [x] Fix the pair of tests I broke (re: Duplicate profiles)
<hr>
* Create profiles by layering them
* Update test to layer multiple times on the same profile
* Add support for layering an array of profiles, but break a couple tests
* Add a defaults.json to the package
* Layer colorschemes
* Moves tests into individual classes
* adds support for layering a colorscheme on top of another
* Layer an array of color schemes
* oh no, this was missed with #2481
must have committed without staging this change, uh oh. Not like those tests actually work so nbd
* Layer keybindings
* Read settings from defaults.json + profiles.json, layer appropriately
This is like 80% of #754. Needs tests.
* Add tests for keybindings
* add support to unbind a key with `null` or `"unbound"` or `"garbage"`
* Layer or clear optional properties
* Add a helper to get an optional variable for a bunch of different types
In the end, I think we need to ask _was this worth it_
* Do this with the stretch mode too
* Add back in the GUID check for profiles
* Add some tests for global settings layering
* M A D W I T H P O W E R
Add a MsBuild target to auto-generate a header with the defaults.json as a
string in the file. That way, we can _always_ load the defaults. Literally impossible to not.
* When the user's profile.json doesn't exist, create it from a template
* Re-order profiles to match the order set in the user's profiles.json
* Add tests for re-ordering profiles to match user ordering
* Add support for hiding profiles using `"hidden": true`
* Use the hardcoded defaults.json for the exception->"use defaults" case
* Somehow I messed up the git submodules?
* woo documentation
* Fix a Terminal.App.Unit.Tests failure
* signed/unsigned is hard
* Use Alt+Settings button to open the default settings
* Missed a signed/unsigned
* Some very preliminary PR feedback
* More PR feedback
Use the wil helper for the exe path
Move jsonutils into their own file
kill some dead code
* Add templates to these bois
* remove some code for generating defaults, reorder defaults.json a tad
* Make guid a std::optional
* Large block of PR feedback
* Remove some dead code
* add some comments
* tag some todos
* stl is love, stl is life
* add `-noprofile`
* Fix the crash that dustin found
* -Encoding ASCII
* Set a profile's default scheme to Campbell
* Fix the tests I regressed
* Update UsingJsonSetting.md to reflect that changes from these PRs
* Change how GenerateGuidForProfile works
* Make AppKeyBindings do its own serialization
* Remove leftover dead code from the previous commit
* Fix up an enormous number of PR nits
* Fix a typo; Update the defaults to match #2378
* Tiny nits
* Some typos, PR nits
* Fix this broken defaults case
2019-09-16 21:57:10 +02:00
|
|
|
// This is a pair of helpers for determining if a pair of guids are equal, and
|
|
|
|
// establishing an ordering on GUIDs (via std::less).
|
|
|
|
namespace std
|
|
|
|
{
|
|
|
|
template<>
|
|
|
|
struct less<GUID>
|
|
|
|
{
|
|
|
|
bool operator()(const GUID& lhs, const GUID& rhs) const
|
|
|
|
{
|
|
|
|
return memcmp(&lhs, &rhs, sizeof(rhs)) < 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct equal_to<GUID>
|
|
|
|
{
|
|
|
|
bool operator()(const GUID& lhs, const GUID& rhs) const
|
|
|
|
{
|
|
|
|
return memcmp(&lhs, &rhs, sizeof(rhs)) == 0;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2019-10-15 07:41:43 +02:00
|
|
|
|
|
|
|
namespace winrt::Microsoft::UI::Xaml::Controls
|
|
|
|
{
|
|
|
|
struct IconSource;
|
|
|
|
struct BitmapIconSource;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace winrt::Windows::UI::Xaml::Controls
|
|
|
|
{
|
|
|
|
struct IconSource;
|
|
|
|
struct BitmapIconSource;
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace Microsoft::TerminalApp::details
|
|
|
|
{
|
|
|
|
// This is a template that helps us figure out which BitmapIconSource to use for a given IconSource.
|
|
|
|
// We have to do this because some of our code still wants to use WUX IconSources.
|
|
|
|
template<typename TIconSource>
|
|
|
|
struct BitmapIconSource
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct BitmapIconSource<winrt::Microsoft::UI::Xaml::Controls::IconSource>
|
|
|
|
{
|
|
|
|
using type = winrt::Microsoft::UI::Xaml::Controls::BitmapIconSource;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<>
|
|
|
|
struct BitmapIconSource<winrt::Windows::UI::Xaml::Controls::IconSource>
|
|
|
|
{
|
|
|
|
using type = winrt::Windows::UI::Xaml::Controls::BitmapIconSource;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// Method Description:
|
|
|
|
// - Creates an IconElement for the given path. The icon returned is a colored
|
|
|
|
// icon. If we couldn't create the icon for any reason, we return an empty
|
|
|
|
// IconElement.
|
|
|
|
// Template Types:
|
|
|
|
// - <TIconSource>: The type of IconSource (MUX, WUX) to generate.
|
|
|
|
// Arguments:
|
|
|
|
// - path: the full, expanded path to the icon.
|
|
|
|
// Return Value:
|
|
|
|
// - An IconElement with its IconSource set, if possible.
|
|
|
|
template<typename TIconSource>
|
|
|
|
TIconSource GetColoredIcon(const winrt::hstring& path)
|
|
|
|
{
|
|
|
|
if (!path.empty())
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
winrt::Windows::Foundation::Uri iconUri{ path };
|
|
|
|
::Microsoft::TerminalApp::details::BitmapIconSource<TIconSource>::type iconSource;
|
|
|
|
// Make sure to set this to false, so we keep the RGB data of the
|
|
|
|
// image. Otherwise, the icon will be white for all the
|
|
|
|
// non-transparent pixels in the image.
|
|
|
|
iconSource.ShowAsMonochrome(false);
|
|
|
|
iconSource.UriSource(iconUri);
|
|
|
|
return iconSource;
|
|
|
|
}
|
|
|
|
CATCH_LOG();
|
|
|
|
}
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
}
|