diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.h b/src/cascadia/TerminalSettingsModel/ActionArgs.h index f26099ca80..05c0ec6559 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.h +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.h @@ -636,6 +636,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { return 2; } + Model::ArgDescription GetArgDescriptionAt(uint32_t /*index*/) const + { + return {}; + } + IInspectable GetArgAt(uint32_t /*index*/) const + { + return nullptr; + } + void SetArgAt(uint32_t /*index*/, IInspectable /*value*/) + { + } }; struct SplitPaneArgs : public SplitPaneArgsT @@ -732,6 +743,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { return 4; } + Model::ArgDescription GetArgDescriptionAt(uint32_t /*index*/) const + { + return {}; + } + IInspectable GetArgAt(uint32_t /*index*/) const + { + return nullptr; + } + void SetArgAt(uint32_t /*index*/, IInspectable /*value*/) + { + } }; struct NewWindowArgs : public NewWindowArgsT @@ -786,6 +808,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { return 2; // todo: is this correct? or should we return the number of args in INewContentArgs? } + Model::ArgDescription GetArgDescriptionAt(uint32_t /*index*/) const + { + return {}; + } + IInspectable GetArgAt(uint32_t /*index*/) const + { + return nullptr; + } + void SetArgAt(uint32_t /*index*/, IInspectable /*value*/) + { + } }; ACTION_ARGS_STRUCT(CopyTextArgs, COPY_TEXT_ARGS); @@ -929,6 +962,17 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { return _Actions.Size(); } + Model::ArgDescription GetArgDescriptionAt(uint32_t /*index*/) const + { + return {}; + } + IInspectable GetArgAt(uint32_t /*index*/) const + { + return nullptr; + } + void SetArgAt(uint32_t /*index*/, IInspectable /*value*/) + { + } }; ACTION_ARGS_STRUCT(AdjustOpacityArgs, ADJUST_OPACITY_ARGS); diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.idl b/src/cascadia/TerminalSettingsModel/ActionArgs.idl index 2683d55d3e..1518723306 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.idl +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.idl @@ -18,15 +18,11 @@ namespace Microsoft.Terminal.Settings.Model String GenerateName(); IActionArgs Copy(); UInt64 Hash(); - // some info here that tells you Input is a string... - // 1. how many args - // 2. get descriptor of arg at index n (description is a custom struct we define here: name, type, required) - // 3. set arg at index n - // 4. get arg at index n + UInt32 GetArgCount(); - // ArgDescription GetArgDescriptorAt(UInt32 index); - // void SetArgAt(UInt32 index, Object value); - // IInspectable GetArgAt(UInt32 index); + ArgDescription GetArgDescriptionAt(UInt32 index); + IInspectable GetArgAt(UInt32 index); + void SetArgAt(UInt32 index, Object value); }; interface IActionEventArgs diff --git a/src/cascadia/TerminalSettingsModel/ActionArgsMagic.h b/src/cascadia/TerminalSettingsModel/ActionArgsMagic.h index 558ccd22c2..d26216965d 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgsMagic.h +++ b/src/cascadia/TerminalSettingsModel/ActionArgsMagic.h @@ -70,12 +70,36 @@ struct InitListPlaceholder #define INCREMENT_ARG_COUNT(type, name, jsonKey, required, ...) \ _argCount += 1; +// append this argument's description to the internal vector +#define APPEND_ARG_DESCRIPTION(type, name, jsonKey, required, ...) \ + _argDescriptions.push_back({ L## #name, L## #type, std::wstring(L## #required) != L"false" }); + // check each property in the Equals() method. You'll note there's a stray // `true` in the definition of Equals() below, that's to deal with trailing // commas #define EQUALS_ARGS(type, name, jsonKey, required, ...) \ &&(otherAsUs->_##name == _##name) +// getter and setter for each property by name +#define GET_ARG_BY_NAME(type, name, jsonKey, required, ...) \ + if (argName == L## #name) \ + { \ + if (_##name.has_value()) \ + { \ + return winrt::box_value(_##name.value()); \ + } \ + else \ + { \ + return nullptr; \ + } \ + } + +#define SET_ARG_BY_NAME(type, name, jsonKey, required, ...) \ + if (argName == L## #name) \ + { \ + _##name = winrt::unbox_value(value); \ + } + // JSON deserialization. If the parameter is required to pass any validation, // add that as the `required` parameter here, as the body of a conditional // EX: For the RESIZE_PANE_ARGS @@ -83,12 +107,13 @@ struct InitListPlaceholder // the bit // args->ResizeDirection() == ResizeDirection::None // is used as the conditional for the validation here. -#define FROM_JSON_ARGS(type, name, jsonKey, required, ...) \ - JsonUtils::GetValueForKey(json, jsonKey, args->_##name); \ - args->_argCount += 1; \ - if (required) \ - { \ - return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } }; \ +#define FROM_JSON_ARGS(type, name, jsonKey, required, ...) \ + JsonUtils::GetValueForKey(json, jsonKey, args->_##name); \ + args->_argCount += 1; \ + args->_argDescriptions.push_back({ L## #name, L## #type, std::wstring(L## #required) != L"false" }); \ + if (required) \ + { \ + return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } }; \ } // JSON serialization @@ -116,61 +141,79 @@ struct InitListPlaceholder // * NewTerminalArgs has a ToCommandline method it needs to additionally declare. // * GlobalSummonArgs has the QuakeModeFromJson helper -#define ACTION_ARG_BODY(className, argsMacro) \ - className() = default; \ - className( \ - argsMacro(CTOR_PARAMS) InitListPlaceholder = {}) : \ - argsMacro(CTOR_INIT) _placeholder{} { \ - argsMacro(INCREMENT_ARG_COUNT) \ - }; \ - argsMacro(DECLARE_ARGS); \ - \ -private: \ - InitListPlaceholder _placeholder; \ - uint32_t _argCount{ 0 }; \ - \ -public: \ - hstring GenerateName() const; \ - bool Equals(const IActionArgs& other) \ - { \ - auto otherAsUs = other.try_as(); \ - if (otherAsUs) \ - { \ - return true argsMacro(EQUALS_ARGS); \ - } \ - return false; \ - }; \ - static FromJsonResult FromJson(const Json::Value& json) \ - { \ - auto args = winrt::make_self(); \ - argsMacro(FROM_JSON_ARGS); \ - return { *args, {} }; \ - } \ - static Json::Value ToJson(const IActionArgs& val) \ - { \ - if (!val) \ - { \ - return {}; \ - } \ - Json::Value json{ Json::ValueType::objectValue }; \ - const auto args{ get_self(val) }; \ - argsMacro(TO_JSON_ARGS); \ - return json; \ - } \ - IActionArgs Copy() const \ - { \ - auto copy{ winrt::make_self() }; \ - argsMacro(COPY_ARGS); \ - copy->_argCount = _argCount; \ - return *copy; \ - } \ - size_t Hash() const \ - { \ - til::hasher h; \ - argsMacro(HASH_ARGS); \ - return h.finalize(); \ - } \ - uint32_t GetArgCount() const \ - { \ - return _argCount; \ +#define ACTION_ARG_BODY(className, argsMacro) \ + className() = default; \ + className( \ + argsMacro(CTOR_PARAMS) InitListPlaceholder = {}) : \ + argsMacro(CTOR_INIT) _placeholder{} { \ + argsMacro(INCREMENT_ARG_COUNT) \ + argsMacro(APPEND_ARG_DESCRIPTION) \ + }; \ + argsMacro(DECLARE_ARGS); \ + \ +private: \ + InitListPlaceholder _placeholder; \ + uint32_t _argCount{ 0 }; \ + std::vector _argDescriptions; \ + \ +public: \ + hstring GenerateName() const; \ + bool Equals(const IActionArgs& other) \ + { \ + auto otherAsUs = other.try_as(); \ + if (otherAsUs) \ + { \ + return true argsMacro(EQUALS_ARGS); \ + } \ + return false; \ + }; \ + static FromJsonResult FromJson(const Json::Value& json) \ + { \ + auto args = winrt::make_self(); \ + argsMacro(FROM_JSON_ARGS); \ + return { *args, {} }; \ + } \ + static Json::Value ToJson(const IActionArgs& val) \ + { \ + if (!val) \ + { \ + return {}; \ + } \ + Json::Value json{ Json::ValueType::objectValue }; \ + const auto args{ get_self(val) }; \ + argsMacro(TO_JSON_ARGS); \ + return json; \ + } \ + IActionArgs Copy() const \ + { \ + auto copy{ winrt::make_self() }; \ + argsMacro(COPY_ARGS); \ + copy->_argCount = _argCount; \ + copy->_argDescriptions = _argDescriptions; \ + return *copy; \ + } \ + size_t Hash() const \ + { \ + til::hasher h; \ + argsMacro(HASH_ARGS); \ + return h.finalize(); \ + } \ + uint32_t GetArgCount() const \ + { \ + return _argCount; \ + } \ + ArgDescription GetArgDescriptionAt(uint32_t index) const \ + { \ + return _argDescriptions.at(index); \ + } \ + IInspectable GetArgAt(uint32_t index) const \ + { \ + const auto& argName = GetArgDescriptionAt(index).Name; \ + argsMacro(GET_ARG_BY_NAME) \ + return nullptr; \ + } \ + void SetArgAt(uint32_t index, IInspectable value) \ + { \ + const auto& argName = GetArgDescriptionAt(index).Name; \ + argsMacro(SET_ARG_BY_NAME) \ }