@@ -4988,9 +4988,48 @@ namespace winrt::TerminalApp::implementation
4988
4988
};
4989
4989
};
4990
4990
4991
- auto makeItem = [&menu, &makeCallback](const winrt::hstring& label,
4991
+ auto makeItem = [&makeCallback](const winrt::hstring& label,
4992
+ const winrt::hstring& icon,
4993
+ const auto & action,
4994
+ auto & targetMenu) {
4995
+ AppBarButton button{};
4996
+
4997
+ if (!icon.empty ())
4998
+ {
4999
+ auto iconElement = UI::IconPathConverter::IconWUX (icon);
5000
+ Automation::AutomationProperties::SetAccessibilityView (iconElement, Automation::Peers::AccessibilityView::Raw);
5001
+ button.Icon (iconElement);
5002
+ }
5003
+
5004
+ button.Label (label);
5005
+ button.Click (makeCallback (action));
5006
+ targetMenu.SecondaryCommands ().Append (button);
5007
+ };
5008
+
5009
+ auto makeMenuItem = [](const winrt::hstring& label,
5010
+ const winrt::hstring& icon,
5011
+ const auto & subMenu,
5012
+ auto & targetMenu) {
5013
+ AppBarButton button{};
5014
+
5015
+ if (!icon.empty ())
5016
+ {
5017
+ auto iconElement = UI::IconPathConverter::IconWUX (icon);
5018
+ Automation::AutomationProperties::SetAccessibilityView (iconElement, Automation::Peers::AccessibilityView::Raw);
5019
+ button.Icon (iconElement);
5020
+ }
5021
+
5022
+ button.Label (label);
5023
+ button.Flyout (subMenu);
5024
+ targetMenu.SecondaryCommands ().Append (button);
5025
+ };
5026
+
5027
+ auto makeContextItem = [&makeCallback](const winrt::hstring& label,
4992
5028
const winrt::hstring& icon,
4993
- const auto & action) {
5029
+ const winrt::hstring& tooltip,
5030
+ const auto & action,
5031
+ const auto & subMenu,
5032
+ auto & targetMenu) {
4994
5033
AppBarButton button{};
4995
5034
4996
5035
if (!icon.empty ())
@@ -5002,34 +5041,122 @@ namespace winrt::TerminalApp::implementation
5002
5041
5003
5042
button.Label (label);
5004
5043
button.Click (makeCallback (action));
5005
- menu.SecondaryCommands ().Append (button);
5044
+ WUX::Controls::ToolTipService::SetToolTip (button, box_value (tooltip));
5045
+ button.ContextFlyout (subMenu);
5046
+ targetMenu.SecondaryCommands ().Append (button);
5006
5047
};
5007
5048
5049
+ const auto focusedProfile = _GetFocusedTabImpl ()->GetFocusedProfile ();
5050
+ auto separatorItem = AppBarSeparator{};
5051
+ auto activeProfiles = _settings.ActiveProfiles ();
5052
+ auto activeProfileCount = gsl::narrow_cast<int >(activeProfiles.Size ());
5053
+ MUX::Controls::CommandBarFlyout splitPaneMenu{};
5054
+
5008
5055
// Wire up each item to the action that should be performed. By actually
5009
5056
// connecting these to actions, we ensure the implementation is
5010
5057
// consistent. This also leaves room for customizing this menu with
5011
5058
// actions in the future.
5012
5059
5013
- makeItem (RS_ (L" SplitPaneText" ), L" \xF246 " , ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate } });
5014
- makeItem (RS_ (L" DuplicateTabText" ), L" \xF5ED " , ActionAndArgs{ ShortcutAction::DuplicateTab, nullptr });
5060
+ makeItem (RS_ (L" DuplicateTabText" ), L" \xF5ED " , ActionAndArgs{ ShortcutAction::DuplicateTab, nullptr }, menu);
5061
+
5062
+ const auto focusedProfileName = focusedProfile.Name ();
5063
+ const auto focusedProfileIcon = focusedProfile.Icon ();
5064
+ const auto splitPaneDuplicateText = RS_ (L" SplitPaneDuplicateText" ) + L" " + focusedProfileName; // SplitPaneDuplicateText
5065
+
5066
+ const auto splitPaneRightText = RS_ (L" SplitPaneRightText" );
5067
+ const auto splitPaneDownText = RS_ (L" SplitPaneDownText" );
5068
+ const auto splitPaneUpText = RS_ (L" SplitPaneUpText" );
5069
+ const auto splitPaneLeftText = RS_ (L" SplitPaneLeftText" );
5070
+ const auto splitPaneToolTipText = RS_ (L" SplitPaneToolTipText" );
5071
+
5072
+ MUX::Controls::CommandBarFlyout splitPaneContextMenu{};
5073
+ makeItem (splitPaneRightText, focusedProfileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate, SplitDirection::Right, .5 , nullptr } }, splitPaneContextMenu);
5074
+ makeItem (splitPaneDownText, focusedProfileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate, SplitDirection::Down, .5 , nullptr } }, splitPaneContextMenu);
5075
+ makeItem (splitPaneUpText, focusedProfileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate, SplitDirection::Up, .5 , nullptr } }, splitPaneContextMenu);
5076
+ makeItem (splitPaneLeftText, focusedProfileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate, SplitDirection::Left, .5 , nullptr } }, splitPaneContextMenu);
5077
+
5078
+ makeContextItem (splitPaneDuplicateText, focusedProfileIcon, splitPaneToolTipText, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate, SplitDirection::Automatic, .5 , nullptr } }, splitPaneContextMenu, splitPaneMenu);
5079
+
5080
+ // add menu separator
5081
+ const auto separatorAutoItem = AppBarSeparator{};
5082
+
5083
+ splitPaneMenu.SecondaryCommands ().Append (separatorAutoItem);
5084
+
5085
+ for (auto profileIndex = 0 ; profileIndex < activeProfileCount; profileIndex++)
5086
+ {
5087
+ const auto profile = activeProfiles.GetAt (profileIndex);
5088
+ const auto profileName = profile.Name ();
5089
+ const auto profileIcon = profile.Icon ();
5090
+
5091
+ NewTerminalArgs args{};
5092
+ args.Profile (profileName);
5093
+
5094
+ MUX::Controls::CommandBarFlyout splitPaneContextMenu{};
5095
+ makeItem (splitPaneRightText, profileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Manual, SplitDirection::Right, .5 , args } }, splitPaneContextMenu);
5096
+ makeItem (splitPaneDownText, profileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Manual, SplitDirection::Down, .5 , args } }, splitPaneContextMenu);
5097
+ makeItem (splitPaneUpText, profileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Manual, SplitDirection::Up, .5 , args } }, splitPaneContextMenu);
5098
+ makeItem (splitPaneLeftText, profileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Manual, SplitDirection::Left, .5 , args } }, splitPaneContextMenu);
5099
+
5100
+ makeContextItem (profileName, profileIcon, splitPaneToolTipText, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Manual, SplitDirection::Automatic, .5 , args } }, splitPaneContextMenu, splitPaneMenu);
5101
+ }
5102
+
5103
+ makeMenuItem (RS_ (L" SplitPaneText" ), L" \xF246 " , splitPaneMenu, menu);
5015
5104
5016
5105
// Only wire up "Close Pane" if there's multiple panes.
5017
5106
if (_GetFocusedTabImpl ()->GetLeafPaneCount () > 1 )
5018
5107
{
5019
- makeItem (RS_ (L" PaneClose" ), L" \xE89F " , ActionAndArgs{ ShortcutAction::ClosePane, nullptr });
5108
+ MUX::Controls::CommandBarFlyout swapPaneMenu{};
5109
+ const auto rootPane = _GetFocusedTabImpl ()->GetRootPane ();
5110
+ const auto mruPanes = _GetFocusedTabImpl ()->GetMruPanes ();
5111
+ auto activePane = _GetFocusedTabImpl ()->GetActivePane ();
5112
+ rootPane->WalkTree ([&](auto p) {
5113
+ if (const auto & c{ p->GetTerminalControl () })
5114
+ {
5115
+ if (c == control)
5116
+ {
5117
+ activePane = p;
5118
+ }
5119
+ }
5120
+ });
5121
+
5122
+ if (auto neighbor = rootPane->NavigateDirection (activePane, FocusDirection::Down, mruPanes))
5123
+ {
5124
+ makeItem (RS_ (L" SwapPaneDownText" ), neighbor->GetProfile ().Icon (), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Down } }, swapPaneMenu);
5125
+ }
5126
+
5127
+ if (auto neighbor = rootPane->NavigateDirection (activePane, FocusDirection::Right, mruPanes))
5128
+ {
5129
+ makeItem (RS_ (L" SwapPaneRightText" ), neighbor->GetProfile ().Icon (), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Right } }, swapPaneMenu);
5130
+ }
5131
+
5132
+ if (auto neighbor = rootPane->NavigateDirection (activePane, FocusDirection::Up, mruPanes))
5133
+ {
5134
+ makeItem (RS_ (L" SwapPaneUpText" ), neighbor->GetProfile ().Icon (), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Up } }, swapPaneMenu);
5135
+ }
5136
+
5137
+ if (auto neighbor = rootPane->NavigateDirection (activePane, FocusDirection::Left, mruPanes))
5138
+ {
5139
+ makeItem (RS_ (L" SwapPaneLeftText" ), neighbor->GetProfile ().Icon (), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Left } }, swapPaneMenu);
5140
+ }
5141
+
5142
+ makeMenuItem (RS_ (L" SwapPaneText" ), L" \xF1CB " , swapPaneMenu, menu);
5143
+
5144
+ makeItem (RS_ (L" TogglePaneZoomText" ), L" \xE8A3 " , ActionAndArgs{ ShortcutAction::TogglePaneZoom, nullptr }, menu);
5145
+ makeItem (RS_ (L" CloseOtherPanesText" ), L" \xE89F " , ActionAndArgs{ ShortcutAction::CloseOtherPanes, nullptr }, menu);
5146
+ makeItem (RS_ (L" PaneClose" ), L" \xE89F " , ActionAndArgs{ ShortcutAction::ClosePane, nullptr }, menu);
5020
5147
}
5021
5148
5022
5149
if (control.ConnectionState () >= ConnectionState::Closed)
5023
5150
{
5024
- makeItem (RS_ (L" RestartConnectionText" ), L" \xE72C " , ActionAndArgs{ ShortcutAction::RestartConnection, nullptr });
5151
+ makeItem (RS_ (L" RestartConnectionText" ), L" \xE72C " , ActionAndArgs{ ShortcutAction::RestartConnection, nullptr }, menu );
5025
5152
}
5026
5153
5027
5154
if (withSelection)
5028
5155
{
5029
- makeItem (RS_ (L" SearchWebText" ), L" \xF6FA " , ActionAndArgs{ ShortcutAction::SearchForText, nullptr });
5156
+ makeItem (RS_ (L" SearchWebText" ), L" \xF6FA " , ActionAndArgs{ ShortcutAction::SearchForText, nullptr }, menu );
5030
5157
}
5031
5158
5032
- makeItem (RS_ (L" TabClose" ), L" \xE711 " , ActionAndArgs{ ShortcutAction::CloseTab, CloseTabArgs{ _GetFocusedTabIndex ().value () } });
5159
+ makeItem (RS_ (L" TabClose" ), L" \xE711 " , ActionAndArgs{ ShortcutAction::CloseTab, CloseTabArgs{ _GetFocusedTabIndex ().value () } }, menu );
5033
5160
}
5034
5161
5035
5162
void TerminalPage::_PopulateQuickFixMenu (const TermControl& control,
0 commit comments