This commit introduces the terminal settings editor (to wit: the Settings UI) as a standalone project. This project, and this commit, is the result of two and a half months of work. TSE started as a hackathon project in the Microsoft 2020 Hackathon, and from there it's grown to be a bona-fide graphical settings editor. There is a lot of xaml data binding in here, a number of views and a number of view models, and a bunch of paradigms that we've been reviewing and testing out and designing and refining. Specified in #6720, #8269 Follow-up work in #6800 Closes #1564 Closes #8048 (PR) Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com> Co-authored-by: Kayla Cinnamon <cinnamon@microsoft.com> Co-authored-by: Alberto Medina Gutierrez <almedina@microsoft.com> Co-authored-by: John Grandle <jograndl@microsoft.com> Co-authored-by: xerootg <xerootg@users.noreply.github.com> Co-authored-by: Scott <sarmiger1@gmail.com> Co-authored-by: Vineeth Thomas Alex <vineeththomasalex@gmail.com> Co-authored-by: Leon Liang <lelian@microsoft.com> Co-authored-by: Dustin L. Howett <duhowett@microsoft.com> Signed-off-by: Dustin L. Howett <duhowett@microsoft.com>
75 lines
2.7 KiB
C++
75 lines
2.7 KiB
C++
// Copyright (c) Microsoft Corporation.
|
|
// Licensed under the MIT license.
|
|
|
|
#pragma once
|
|
|
|
#include "../inc/cppwinrt_utils.h"
|
|
|
|
template<typename T>
|
|
struct ViewModelHelper
|
|
{
|
|
public:
|
|
winrt::event_token PropertyChanged(::winrt::Windows::UI::Xaml::Data::PropertyChangedEventHandler const& handler)
|
|
{
|
|
return _propertyChangedHandlers.add(handler);
|
|
}
|
|
|
|
void PropertyChanged(winrt::event_token const& token)
|
|
{
|
|
_propertyChangedHandlers.remove(token);
|
|
}
|
|
|
|
protected:
|
|
void _NotifyChangeCore(const std::wstring_view name)
|
|
{
|
|
_propertyChangedHandlers(*static_cast<T*>(this), ::winrt::Windows::UI::Xaml::Data::PropertyChangedEventArgs{ name });
|
|
}
|
|
|
|
// template recursion base case: single dispatch
|
|
void _NotifyChanges(const std::wstring_view name) { _NotifyChangeCore(name); }
|
|
|
|
template<typename... Args>
|
|
void _NotifyChanges(const std::wstring_view name, Args&&... more)
|
|
{
|
|
_NotifyChangeCore(name);
|
|
_NotifyChanges(std::forward<Args>(more)...);
|
|
}
|
|
|
|
private:
|
|
winrt::event<::winrt::Windows::UI::Xaml::Data::PropertyChangedEventHandler> _propertyChangedHandlers;
|
|
};
|
|
|
|
#define _BASE_OBSERVABLE_PROJECTED_SETTING(target, name) \
|
|
public: \
|
|
auto name() const noexcept { return target.name(); }; \
|
|
template<typename T> \
|
|
void name(const T& value) \
|
|
{ \
|
|
if (name() != value) \
|
|
{ \
|
|
target.name(value); \
|
|
_NotifyChanges(L"Has" #name, L#name); \
|
|
} \
|
|
} \
|
|
bool Has##name() { return target.Has##name(); }
|
|
|
|
// Defines a setting that reflects another object's same-named
|
|
// setting.
|
|
#define OBSERVABLE_PROJECTED_SETTING(target, name) \
|
|
_BASE_OBSERVABLE_PROJECTED_SETTING(target, name) \
|
|
void Clear##name() \
|
|
{ \
|
|
const auto hadValue{ target.Has##Name() }; \
|
|
target.Clear##name(); \
|
|
if (hadValue) \
|
|
{ \
|
|
_NotifyChanges(L"Has" #name, L#name); \
|
|
} \
|
|
}
|
|
|
|
// Defines a setting that reflects another object's same-named
|
|
// setting, but which cannot be erased.
|
|
#define PERMANENT_OBSERVABLE_PROJECTED_SETTING(target, name) \
|
|
_BASE_OBSERVABLE_PROJECTED_SETTING(target, name) \
|
|
void Clear##name() {}
|