diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index a178ae252d3..22578b85979 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -195,6 +195,10 @@ Right click for split directions - right/down/up/left + + Automatic + An option in the Split pane context menu that automatically chooses the split direction. + Split pane down diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index aaaed4c926b..755d204e453 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -5584,33 +5584,28 @@ namespace winrt::TerminalApp::implementation targetMenu.SecondaryCommands().Append(button); }; - auto makeContextItem = [&makeCallback](const winrt::hstring& label, - const winrt::hstring& icon, - const winrt::hstring& tooltip, - const auto& action, - const auto& subMenu, - auto& targetMenu) { - AppBarButton button{}; + auto makeMenuFlyoutItem = [&makeCallback](const winrt::hstring& label, + const winrt::hstring& icon, + const auto& action, + auto& targetMenu) { + WUX::Controls::MenuFlyoutItem item{}; if (!icon.empty()) { auto iconElement = UI::IconPathConverter::IconWUX(icon); Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw); - button.Icon(iconElement); + item.Icon(iconElement); } - button.Label(label); - button.Click(makeCallback(action)); - WUX::Controls::ToolTipService::SetToolTip(button, box_value(tooltip)); - button.ContextFlyout(subMenu); - targetMenu.SecondaryCommands().Append(button); + item.Text(label); + item.Click(makeCallback(action)); + targetMenu.Items().Append(item); }; const auto focusedProfile = _GetFocusedTabImpl()->GetFocusedProfile(); - auto separatorItem = AppBarSeparator{}; auto activeProfiles = _settings.ActiveProfiles(); auto activeProfileCount = gsl::narrow_cast(activeProfiles.Size()); - MUX::Controls::CommandBarFlyout splitPaneMenu{}; + WUX::Controls::MenuFlyout splitPaneMenu{}; // Wire up each item to the action that should be performed. By actually // connecting these to actions, we ensure the implementation is @@ -5627,20 +5622,41 @@ namespace winrt::TerminalApp::implementation const auto splitPaneDownText = RS_(L"SplitPaneDownText"); const auto splitPaneUpText = RS_(L"SplitPaneUpText"); const auto splitPaneLeftText = RS_(L"SplitPaneLeftText"); - const auto splitPaneToolTipText = RS_(L"SplitPaneToolTipText"); + const auto splitPaneAutomaticText = RS_(L"SplitPaneAutomaticText"); + + auto makeSplitSubMenu = [&](const winrt::hstring& label, + const winrt::hstring& icon, + const SplitType splitType, + const NewTerminalArgs& args) { + WUX::Controls::MenuFlyoutSubItem subMenu{}; + + if (!icon.empty()) + { + auto iconElement = UI::IconPathConverter::IconWUX(icon); + Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw); + subMenu.Icon(iconElement); + } - MUX::Controls::CommandBarFlyout splitPaneContextMenu{}; - makeItem(splitPaneRightText, focusedProfileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate, SplitDirection::Right, .5, nullptr } }, splitPaneContextMenu); - makeItem(splitPaneDownText, focusedProfileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate, SplitDirection::Down, .5, nullptr } }, splitPaneContextMenu); - makeItem(splitPaneUpText, focusedProfileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate, SplitDirection::Up, .5, nullptr } }, splitPaneContextMenu); - makeItem(splitPaneLeftText, focusedProfileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate, SplitDirection::Left, .5, nullptr } }, splitPaneContextMenu); + subMenu.Text(label); - makeContextItem(splitPaneDuplicateText, focusedProfileIcon, splitPaneToolTipText, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Duplicate, SplitDirection::Automatic, .5, nullptr } }, splitPaneContextMenu, splitPaneMenu); + // A MenuFlyoutSubItem can't be clicked, so the automatic split is an explicit entry. + WUX::Controls::MenuFlyoutItem autoItem{}; + autoItem.Text(splitPaneAutomaticText); + autoItem.Click(makeCallback(ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ splitType, SplitDirection::Automatic, .5, args } })); + subMenu.Items().Append(autoItem); + subMenu.Items().Append(WUX::Controls::MenuFlyoutSeparator{}); - // add menu separator - const auto separatorAutoItem = AppBarSeparator{}; + makeMenuFlyoutItem(splitPaneRightText, L"", ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ splitType, SplitDirection::Right, .5, args } }, subMenu); + makeMenuFlyoutItem(splitPaneDownText, L"", ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ splitType, SplitDirection::Down, .5, args } }, subMenu); + makeMenuFlyoutItem(splitPaneUpText, L"", ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ splitType, SplitDirection::Up, .5, args } }, subMenu); + makeMenuFlyoutItem(splitPaneLeftText, L"", ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ splitType, SplitDirection::Left, .5, args } }, subMenu); - splitPaneMenu.SecondaryCommands().Append(separatorAutoItem); + splitPaneMenu.Items().Append(subMenu); + }; + + makeSplitSubMenu(splitPaneDuplicateText, focusedProfileIcon, SplitType::Duplicate, nullptr); + + splitPaneMenu.Items().Append(WUX::Controls::MenuFlyoutSeparator{}); for (auto profileIndex = 0; profileIndex < activeProfileCount; profileIndex++) { @@ -5651,13 +5667,7 @@ namespace winrt::TerminalApp::implementation NewTerminalArgs args{}; args.Profile(profileName); - MUX::Controls::CommandBarFlyout splitPaneContextMenu{}; - makeItem(splitPaneRightText, profileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Manual, SplitDirection::Right, .5, args } }, splitPaneContextMenu); - makeItem(splitPaneDownText, profileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Manual, SplitDirection::Down, .5, args } }, splitPaneContextMenu); - makeItem(splitPaneUpText, profileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Manual, SplitDirection::Up, .5, args } }, splitPaneContextMenu); - makeItem(splitPaneLeftText, profileIcon, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Manual, SplitDirection::Left, .5, args } }, splitPaneContextMenu); - - makeContextItem(profileName, profileIcon, splitPaneToolTipText, ActionAndArgs{ ShortcutAction::SplitPane, SplitPaneArgs{ SplitType::Manual, SplitDirection::Automatic, .5, args } }, splitPaneContextMenu, splitPaneMenu); + makeSplitSubMenu(profileName, profileIcon, SplitType::Manual, args); } makeMenuItem(RS_(L"SplitPaneText"), L"\xF246", splitPaneMenu, menu); @@ -5665,7 +5675,7 @@ namespace winrt::TerminalApp::implementation // Only wire up "Close Pane" if there's multiple panes. if (_GetFocusedTabImpl()->GetLeafPaneCount() > 1) { - MUX::Controls::CommandBarFlyout swapPaneMenu{}; + WUX::Controls::MenuFlyout swapPaneMenu{}; const auto rootPane = _GetFocusedTabImpl()->GetRootPane(); const auto mruPanes = _GetFocusedTabImpl()->GetMruPanes(); auto activePane = _GetFocusedTabImpl()->GetActivePane(); @@ -5681,22 +5691,22 @@ namespace winrt::TerminalApp::implementation if (auto neighbor = rootPane->NavigateDirection(activePane, FocusDirection::Down, mruPanes)) { - makeItem(RS_(L"SwapPaneDownText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Down } }, swapPaneMenu); + makeMenuFlyoutItem(RS_(L"SwapPaneDownText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Down } }, swapPaneMenu); } if (auto neighbor = rootPane->NavigateDirection(activePane, FocusDirection::Right, mruPanes)) { - makeItem(RS_(L"SwapPaneRightText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Right } }, swapPaneMenu); + makeMenuFlyoutItem(RS_(L"SwapPaneRightText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Right } }, swapPaneMenu); } if (auto neighbor = rootPane->NavigateDirection(activePane, FocusDirection::Up, mruPanes)) { - makeItem(RS_(L"SwapPaneUpText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Up } }, swapPaneMenu); + makeMenuFlyoutItem(RS_(L"SwapPaneUpText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Up } }, swapPaneMenu); } if (auto neighbor = rootPane->NavigateDirection(activePane, FocusDirection::Left, mruPanes)) { - makeItem(RS_(L"SwapPaneLeftText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Left } }, swapPaneMenu); + makeMenuFlyoutItem(RS_(L"SwapPaneLeftText"), neighbor->GetProfile().Icon().Resolved(), ActionAndArgs{ ShortcutAction::SwapPane, SwapPaneArgs{ FocusDirection::Left } }, swapPaneMenu); } makeMenuItem(RS_(L"SwapPaneText"), L"\xF1CB", swapPaneMenu, menu);