terminal/src/cascadia/TerminalSettingsEditor/ViewModelHelpers.h
Dustin Howett 3e2b94334d Introduce the Terminal Settings Editor (#8048)
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>
2020-12-11 13:47:10 -08:00

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() {}