Add icon override setting for newTabMenu entries (#18116)

## Summary of the Pull Request
This PR is to allow users to set a custom icon for entries in the new tab menu for "action" and "profile" type entries.

## References and Relevant Issues
This PR is in response to #18103 

## Detailed Description of the Pull Request / Additional comments
It is now possible to specify an optional "icon" setting for any "action" or "profile" type entry in the "newTabMenu" JSON settings. When specified, this icon will be used as the menu icon for that action/profile in the new tab menu. If not specified, the action/profile definition's default icon will be used instead (if present).

The Cascadia settings schema ("doc/cascadia/profiles.schema.json") has been updated to reflect this.

## Validation Steps Performed
Manually tested with multiple combinations of icon settings:
- ActionEntry:
  - valid path in action definition and new tab entry (renders new tab entry icon)
  - valid path in action definition but no path in new tab entry (renders action definition icon)
  - no path in action definition, valid path in new tab entry (renders new tab entry icon)
  - invalid path in action definition, valid path in new tab entry (renders new tab entry icon)
  - valid path in action definition, invalid path in new tab entry (renders no icon)
  - invalid path in both (renders no icon)
  - no path in both (renders no icon)
- ProfileEntry:
  - valid path in new tab entry (renders new tab entry icon)
  - no path in new tab entry (renders profile's default icon)
  - invalid path in new tab entry (renders no icon)

## PR Checklist
- [x] Closes #18103
- [x] Tests added/passed
- [x] Documentation updated
   - If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: [#808](https://github.com/MicrosoftDocs/terminal/pull/808)
- [x] Schema updated (if necessary)
This commit is contained in:
Josh Johnson 2024-10-29 18:45:19 +00:00 committed by GitHub
parent 8d3f12b1c0
commit 5b63465798
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 32 additions and 13 deletions

View File

@ -733,6 +733,9 @@
"type": "string",
"default": "",
"description": "The name or GUID of the profile to show in this entry"
},
"icon": {
"$ref": "#/$defs/Icon"
}
}
}
@ -804,6 +807,9 @@
"type": "string",
"default": "",
"description": "The ID of the action to show in this entry"
},
"icon": {
"$ref": "#/$defs/Icon"
}
}
}

View File

@ -989,7 +989,7 @@ namespace winrt::TerminalApp::implementation
for (auto&& [profileIndex, remainingProfile] : remainingProfilesEntry.Profiles())
{
items.push_back(_CreateNewTabFlyoutProfile(remainingProfile, profileIndex));
items.push_back(_CreateNewTabFlyoutProfile(remainingProfile, profileIndex, {}));
}
break;
@ -1003,7 +1003,7 @@ namespace winrt::TerminalApp::implementation
break;
}
auto profileItem = _CreateNewTabFlyoutProfile(profileEntry.Profile(), profileEntry.ProfileIndex());
auto profileItem = _CreateNewTabFlyoutProfile(profileEntry.Profile(), profileEntry.ProfileIndex(), profileEntry.Icon());
items.push_back(profileItem);
break;
}
@ -1013,7 +1013,7 @@ namespace winrt::TerminalApp::implementation
const auto actionId = actionEntry.ActionId();
if (_settings.ActionMap().GetActionByID(actionId))
{
auto actionItem = _CreateNewTabFlyoutAction(actionId);
auto actionItem = _CreateNewTabFlyoutAction(actionId, actionEntry.Icon());
items.push_back(actionItem);
}
@ -1028,7 +1028,7 @@ namespace winrt::TerminalApp::implementation
// Method Description:
// - This method creates a flyout menu item for a given profile with the given index.
// It makes sure to set the correct icon, keybinding, and click-action.
WUX::Controls::MenuFlyoutItem TerminalPage::_CreateNewTabFlyoutProfile(const Profile profile, int profileIndex)
WUX::Controls::MenuFlyoutItem TerminalPage::_CreateNewTabFlyoutProfile(const Profile profile, int profileIndex, const winrt::hstring& iconPathOverride)
{
auto profileMenuItem = WUX::Controls::MenuFlyoutItem{};
@ -1049,9 +1049,10 @@ namespace winrt::TerminalApp::implementation
auto profileName = profile.Name();
profileMenuItem.Text(profileName);
// If there's an icon set for this profile, set it as the icon for
// this flyout item
const auto& iconPath = profile.EvaluatedIcon();
// If a custom icon path has been specified, set it as the icon for
// this flyout item. Otherwise, if an icon is set for this profile, set that icon
// for this flyout item.
const auto& iconPath = iconPathOverride.empty() ? profile.EvaluatedIcon() : iconPathOverride;
if (!iconPath.empty())
{
const auto icon = _CreateNewTabFlyoutIcon(iconPath);
@ -1112,7 +1113,7 @@ namespace winrt::TerminalApp::implementation
// Method Description:
// - This method creates a flyout menu item for a given action
// It makes sure to set the correct icon, keybinding, and click-action.
WUX::Controls::MenuFlyoutItem TerminalPage::_CreateNewTabFlyoutAction(const winrt::hstring& actionId)
WUX::Controls::MenuFlyoutItem TerminalPage::_CreateNewTabFlyoutAction(const winrt::hstring& actionId, const winrt::hstring& iconPathOverride)
{
auto actionMenuItem = WUX::Controls::MenuFlyoutItem{};
const auto action{ _settings.ActionMap().GetActionByID(actionId) };
@ -1125,9 +1126,10 @@ namespace winrt::TerminalApp::implementation
actionMenuItem.Text(action.Name());
// If there's an icon set for this action, set it as the icon for
// this flyout item
const auto& iconPath = action.IconPath();
// If a custom icon path has been specified, set it as the icon for
// this flyout item. Otherwise, if an icon is set for this action, set that icon
// for this flyout item.
const auto& iconPath = iconPathOverride.empty() ? action.IconPath() : iconPathOverride;
if (!iconPath.empty())
{
const auto icon = _CreateNewTabFlyoutIcon(iconPath);

View File

@ -316,8 +316,8 @@ namespace winrt::TerminalApp::implementation
void _CreateNewTabFlyout();
std::vector<winrt::Windows::UI::Xaml::Controls::MenuFlyoutItemBase> _CreateNewTabFlyoutItems(winrt::Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::NewTabMenuEntry> entries);
winrt::Windows::UI::Xaml::Controls::IconElement _CreateNewTabFlyoutIcon(const winrt::hstring& icon);
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _CreateNewTabFlyoutProfile(const Microsoft::Terminal::Settings::Model::Profile profile, int profileIndex);
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _CreateNewTabFlyoutAction(const winrt::hstring& actionId);
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _CreateNewTabFlyoutProfile(const Microsoft::Terminal::Settings::Model::Profile profile, int profileIndex, const winrt::hstring& iconPathOverride);
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _CreateNewTabFlyoutAction(const winrt::hstring& actionId, const winrt::hstring& iconPathOverride);
void _OpenNewTabDropdown();
HRESULT _OpenNewTab(const Microsoft::Terminal::Settings::Model::INewContentArgs& newContentArgs);

View File

@ -11,6 +11,7 @@ using namespace Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
static constexpr std::string_view ActionIdKey{ "id" };
static constexpr std::string_view IconKey{ "icon" };
ActionEntry::ActionEntry() noexcept :
ActionEntryT<ActionEntry, NewTabMenuEntry>(NewTabMenuEntryType::Action)
@ -22,6 +23,7 @@ Json::Value ActionEntry::ToJson() const
auto json = NewTabMenuEntry::ToJson();
JsonUtils::SetValueForKey(json, ActionIdKey, _ActionId);
JsonUtils::SetValueForKey(json, IconKey, _Icon);
return json;
}
@ -31,6 +33,7 @@ winrt::com_ptr<NewTabMenuEntry> ActionEntry::FromJson(const Json::Value& json)
auto entry = winrt::make_self<ActionEntry>();
JsonUtils::GetValueForKey(json, ActionIdKey, entry->_ActionId);
JsonUtils::GetValueForKey(json, IconKey, entry->_Icon);
return entry;
}

View File

@ -28,6 +28,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
static com_ptr<NewTabMenuEntry> FromJson(const Json::Value& json);
WINRT_PROPERTY(winrt::hstring, ActionId);
WINRT_PROPERTY(winrt::hstring, Icon);
};
}

View File

@ -33,6 +33,7 @@ namespace Microsoft.Terminal.Settings.Model
Profile Profile;
Int32 ProfileIndex;
String Icon;
}
[default_interface] runtimeclass ActionEntry : NewTabMenuEntry
@ -40,6 +41,7 @@ namespace Microsoft.Terminal.Settings.Model
ActionEntry();
String ActionId;
String Icon;
}
enum FolderEntryInlining

View File

@ -11,6 +11,7 @@ using namespace Microsoft::Terminal::Settings::Model;
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
static constexpr std::string_view ProfileKey{ "profile" };
static constexpr std::string_view IconKey{ "icon" };
ProfileEntry::ProfileEntry() noexcept :
ProfileEntry{ winrt::hstring{} }
@ -46,6 +47,8 @@ Json::Value ProfileEntry::ToJson() const
JsonUtils::SetValueForKey(json, ProfileKey, _Profile.Guid());
}
JsonUtils::SetValueForKey(json, IconKey, _Icon);
return json;
}
@ -54,6 +57,7 @@ winrt::com_ptr<NewTabMenuEntry> ProfileEntry::FromJson(const Json::Value& json)
auto entry = winrt::make_self<ProfileEntry>();
JsonUtils::GetValueForKey(json, ProfileKey, entry->_ProfileName);
JsonUtils::GetValueForKey(json, IconKey, entry->_Icon);
return entry;
}

View File

@ -41,6 +41,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
WINRT_PROPERTY(Model::Profile, Profile);
WINRT_PROPERTY(int, ProfileIndex);
WINRT_PROPERTY(winrt::hstring, Icon);
private:
winrt::hstring _ProfileName;