From e7108332f72a3c14c72a65484d091c4e79ab28b2 Mon Sep 17 00:00:00 2001 From: Schuyler Rosefield Date: Mon, 2 Aug 2021 17:04:57 -0400 Subject: [PATCH] Add the ability to toggle a pane's split direction (#10713) ## Summary of the Pull Request Add the ability to toggle a pane's split direction - Switch from horizontal to vertical split (and vice versa) - Propogate new borders through to children. ## References #10665 ## PR Checklist * [x] Closes #10665 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [x] Schema updated. * [ ] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed Ran terminal, created multiple panes in different orientations, ran command through command palate and verified that they displayed properly in the new orientation. --- doc/cascadia/profiles.schema.json | 1 + .../TerminalApp/AppActionHandlers.cpp | 7 ++ src/cascadia/TerminalApp/Pane.cpp | 66 ++++++++++- src/cascadia/TerminalApp/Pane.h | 2 + src/cascadia/TerminalApp/TerminalPage.cpp | 15 +++ src/cascadia/TerminalApp/TerminalPage.h | 1 + src/cascadia/TerminalApp/TerminalTab.cpp | 12 ++ src/cascadia/TerminalApp/TerminalTab.h | 1 + .../TerminalSettingsModel/ActionAndArgs.cpp | 2 + .../AllShortcutActions.h | 107 +++++++++--------- .../Resources/en-US/Resources.resw | 3 + .../TerminalSettingsModel/defaults.json | 1 + 12 files changed, 159 insertions(+), 59 deletions(-) diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 96e7c6cfce8..2b078d00d5e 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -271,6 +271,7 @@ "toggleFocusMode", "toggleFullscreen", "togglePaneZoom", + "toggleSplitOrientation", "toggleReadOnlyMode", "toggleShaderEffects", "wt", diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 8535d88fefe..60401122cc7 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -161,6 +161,13 @@ namespace winrt::TerminalApp::implementation } } + void TerminalPage::_HandleToggleSplitOrientation(const IInspectable& /*sender*/, + const ActionEventArgs& args) + { + _ToggleSplitOrientation(); + args.Handled(true); + } + void TerminalPage::_HandleTogglePaneZoom(const IInspectable& /*sender*/, const ActionEventArgs& args) { diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index a2c0711464b..59dacf6b904 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -1449,8 +1449,26 @@ void Pane::_UpdateBorders() _border.BorderThickness(ThicknessHelper::FromLengths(left, top, right, bottom)); } +// Method Description: +// - Find the borders for the leaf pane, or the shared borders for child panes. +// Arguments: +// - +// Return Value: +// - +Borders Pane::_GetCommonBorders() +{ + if (_IsLeaf()) + { + return _borders; + } + + return _firstChild->_GetCommonBorders() & _secondChild->_GetCommonBorders(); +} + // Method Description: // - Sets the row/column of our child UI elements, to match our current split type. +// - In case the split definition or parent borders were changed, this recursively +// updates the children as well. // Arguments: // - // Return Value: @@ -1466,9 +1484,8 @@ void Pane::_ApplySplitDefinitions() _secondChild->_borders = _borders | Borders::Left; _borders = Borders::None; - _UpdateBorders(); - _firstChild->_UpdateBorders(); - _secondChild->_UpdateBorders(); + _firstChild->_ApplySplitDefinitions(); + _secondChild->_ApplySplitDefinitions(); } else if (_splitState == SplitState::Horizontal) { @@ -1479,10 +1496,10 @@ void Pane::_ApplySplitDefinitions() _secondChild->_borders = _borders | Borders::Top; _borders = Borders::None; - _UpdateBorders(); - _firstChild->_UpdateBorders(); - _secondChild->_UpdateBorders(); + _firstChild->_ApplySplitDefinitions(); + _secondChild->_ApplySplitDefinitions(); } + _UpdateBorders(); } // Method Description: @@ -1743,6 +1760,43 @@ std::pair, std::shared_ptr> Pane::Split(SplitState s return _Split(splitType, splitSize, profile, control); } +// Method Description: +// - Toggle the split orientation of the currently focused pane +// Arguments: +// - +// Return Value: +// - true if a split was changed +bool Pane::ToggleSplitOrientation() +{ + // If we are a leaf there is no split to toggle. + if (_IsLeaf()) + { + return false; + } + + // Check if either our first or second child is the currently focused leaf. + // If they are then switch the split orientation on the current pane. + const bool firstIsFocused = _firstChild->_IsLeaf() && _firstChild->_lastActive; + const bool secondIsFocused = _secondChild->_IsLeaf() && _secondChild->_lastActive; + if (firstIsFocused || secondIsFocused) + { + // Switch the split orientation + _splitState = _splitState == SplitState::Horizontal ? SplitState::Vertical : SplitState::Horizontal; + + // then update the borders and positioning on ourselves and our children. + _borders = _GetCommonBorders(); + // Since we changed if we are using rows/columns, make sure we remove the old definitions + _root.ColumnDefinitions().Clear(); + _root.RowDefinitions().Clear(); + _CreateRowColDefinitions(); + _ApplySplitDefinitions(); + + return true; + } + + return _firstChild->ToggleSplitOrientation() || _secondChild->ToggleSplitOrientation(); +} + // Method Description: // - Converts an "automatic" split type into either Vertical or Horizontal, // based upon the current dimensions of the Pane. diff --git a/src/cascadia/TerminalApp/Pane.h b/src/cascadia/TerminalApp/Pane.h index a8bc3f44307..eed685d322a 100644 --- a/src/cascadia/TerminalApp/Pane.h +++ b/src/cascadia/TerminalApp/Pane.h @@ -69,6 +69,7 @@ class Pane : public std::enable_shared_from_this const float splitSize, const GUID& profile, const winrt::Microsoft::Terminal::Control::TermControl& control); + bool ToggleSplitOrientation(); float CalcSnappedDimension(const bool widthOrHeight, const float dimension) const; std::optional PreCalculateAutoSplit(const std::shared_ptr target, const winrt::Windows::Foundation::Size parentSize) const; @@ -146,6 +147,7 @@ class Pane : public std::enable_shared_from_this void _ApplySplitDefinitions(); void _SetupEntranceAnimation(); void _UpdateBorders(); + Borders _GetCommonBorders(); bool _Resize(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction); diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 653ae691594..fc552d76769 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1316,6 +1316,21 @@ namespace winrt::TerminalApp::implementation CATCH_LOG(); } + // Method Description: + // - Switches the split orientation of the currently focused pane. + // Arguments: + // - + // Return Value: + // - + void TerminalPage::_ToggleSplitOrientation() + { + if (const auto terminalTab{ _GetFocusedTabImpl() }) + { + _UnZoomIfNeeded(); + terminalTab->ToggleSplitOrientation(); + } + } + // Method Description: // - Attempt to move a separator between panes, as to resize each child on // either size of the separator. See Pane::ResizePane for details. diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index ea068a89440..aa2db95295c 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -255,6 +255,7 @@ namespace winrt::TerminalApp::implementation const float splitSize = 0.5f, const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr); void _ResizePane(const Microsoft::Terminal::Settings::Model::ResizeDirection& direction); + void _ToggleSplitOrientation(); void _ScrollPage(ScrollDirection scrollDirection); void _ScrollToBufferEdge(ScrollDirection scrollDirection); diff --git a/src/cascadia/TerminalApp/TerminalTab.cpp b/src/cascadia/TerminalApp/TerminalTab.cpp index 9590fcd3f6e..4e420c5c29c 100644 --- a/src/cascadia/TerminalApp/TerminalTab.cpp +++ b/src/cascadia/TerminalApp/TerminalTab.cpp @@ -440,6 +440,17 @@ namespace winrt::TerminalApp::implementation _UpdateActivePane(second); } + // Method Description: + // - Find the currently active pane, and then switch the split direction of + // its parent. E.g. switch from Horizontal to Vertical. + // Return Value: + + // - + void TerminalTab::ToggleSplitOrientation() + { + _rootPane->ToggleSplitOrientation(); + } + // Method Description: // - See Pane::CalcSnappedDimension float TerminalTab::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const @@ -1222,6 +1233,7 @@ namespace winrt::TerminalApp::implementation EnterZoom(); } } + void TerminalTab::EnterZoom() { _zoomedPane = _activePane; diff --git a/src/cascadia/TerminalApp/TerminalTab.h b/src/cascadia/TerminalApp/TerminalTab.h index 68c041ab18c..3ef93536400 100644 --- a/src/cascadia/TerminalApp/TerminalTab.h +++ b/src/cascadia/TerminalApp/TerminalTab.h @@ -38,6 +38,7 @@ namespace winrt::TerminalApp::implementation const GUID& profile, winrt::Microsoft::Terminal::Control::TermControl& control); + void ToggleSplitOrientation(); winrt::fire_and_forget UpdateIcon(const winrt::hstring iconPath); winrt::fire_and_forget HideIcon(const bool hide); diff --git a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp index f6c397605ac..0bd4b174a62 100644 --- a/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp @@ -49,6 +49,7 @@ static constexpr std::string_view ToggleCommandPaletteKey{ "commandPalette" }; static constexpr std::string_view ToggleFocusModeKey{ "toggleFocusMode" }; static constexpr std::string_view ToggleFullscreenKey{ "toggleFullscreen" }; static constexpr std::string_view TogglePaneZoomKey{ "togglePaneZoom" }; +static constexpr std::string_view ToggleSplitOrientationKey{ "toggleSplitOrientation" }; static constexpr std::string_view LegacyToggleRetroEffectKey{ "toggleRetroEffect" }; static constexpr std::string_view ToggleShaderEffectsKey{ "toggleShaderEffects" }; static constexpr std::string_view MoveTabKey{ "moveTab" }; @@ -349,6 +350,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation { ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") }, { ShortcutAction::ToggleFullscreen, RS_(L"ToggleFullscreenCommandKey") }, { ShortcutAction::TogglePaneZoom, RS_(L"TogglePaneZoomCommandKey") }, + { ShortcutAction::ToggleSplitOrientation, RS_(L"ToggleSplitOrientationCommandKey") }, { ShortcutAction::ToggleShaderEffects, RS_(L"ToggleShaderEffectsCommandKey") }, { ShortcutAction::MoveTab, L"" }, // Intentionally omitted, must be generated by GenerateName { ShortcutAction::BreakIntoDebugger, RS_(L"BreakIntoDebuggerCommandKey") }, diff --git a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h index ca795bf6cda..71c74fccb56 100644 --- a/src/cascadia/TerminalSettingsModel/AllShortcutActions.h +++ b/src/cascadia/TerminalSettingsModel/AllShortcutActions.h @@ -23,59 +23,60 @@ // each action. This is _NOT_ something that should be used when any individual // case should be customized. -#define ALL_SHORTCUT_ACTIONS \ - ON_ALL_ACTIONS(CopyText) \ - ON_ALL_ACTIONS(PasteText) \ - ON_ALL_ACTIONS(OpenNewTabDropdown) \ - ON_ALL_ACTIONS(DuplicateTab) \ - ON_ALL_ACTIONS(NewTab) \ - ON_ALL_ACTIONS(CloseWindow) \ - ON_ALL_ACTIONS(CloseTab) \ - ON_ALL_ACTIONS(ClosePane) \ - ON_ALL_ACTIONS(NextTab) \ - ON_ALL_ACTIONS(PrevTab) \ - ON_ALL_ACTIONS(SendInput) \ - ON_ALL_ACTIONS(SplitPane) \ - ON_ALL_ACTIONS(TogglePaneZoom) \ - ON_ALL_ACTIONS(SwitchToTab) \ - ON_ALL_ACTIONS(AdjustFontSize) \ - ON_ALL_ACTIONS(ResetFontSize) \ - ON_ALL_ACTIONS(ScrollUp) \ - ON_ALL_ACTIONS(ScrollDown) \ - ON_ALL_ACTIONS(ScrollUpPage) \ - ON_ALL_ACTIONS(ScrollDownPage) \ - ON_ALL_ACTIONS(ScrollToTop) \ - ON_ALL_ACTIONS(ScrollToBottom) \ - ON_ALL_ACTIONS(ResizePane) \ - ON_ALL_ACTIONS(MoveFocus) \ - ON_ALL_ACTIONS(MovePane) \ - ON_ALL_ACTIONS(Find) \ - ON_ALL_ACTIONS(ToggleShaderEffects) \ - ON_ALL_ACTIONS(ToggleFocusMode) \ - ON_ALL_ACTIONS(ToggleFullscreen) \ - ON_ALL_ACTIONS(ToggleAlwaysOnTop) \ - ON_ALL_ACTIONS(OpenSettings) \ - ON_ALL_ACTIONS(SetColorScheme) \ - ON_ALL_ACTIONS(SetTabColor) \ - ON_ALL_ACTIONS(OpenTabColorPicker) \ - ON_ALL_ACTIONS(RenameTab) \ - ON_ALL_ACTIONS(OpenTabRenamer) \ - ON_ALL_ACTIONS(ExecuteCommandline) \ - ON_ALL_ACTIONS(ToggleCommandPalette) \ - ON_ALL_ACTIONS(CloseOtherTabs) \ - ON_ALL_ACTIONS(CloseTabsAfter) \ - ON_ALL_ACTIONS(TabSearch) \ - ON_ALL_ACTIONS(MoveTab) \ - ON_ALL_ACTIONS(BreakIntoDebugger) \ - ON_ALL_ACTIONS(TogglePaneReadOnly) \ - ON_ALL_ACTIONS(FindMatch) \ - ON_ALL_ACTIONS(NewWindow) \ - ON_ALL_ACTIONS(IdentifyWindow) \ - ON_ALL_ACTIONS(IdentifyWindows) \ - ON_ALL_ACTIONS(RenameWindow) \ - ON_ALL_ACTIONS(OpenWindowRenamer) \ - ON_ALL_ACTIONS(GlobalSummon) \ - ON_ALL_ACTIONS(QuakeMode) \ +#define ALL_SHORTCUT_ACTIONS \ + ON_ALL_ACTIONS(CopyText) \ + ON_ALL_ACTIONS(PasteText) \ + ON_ALL_ACTIONS(OpenNewTabDropdown) \ + ON_ALL_ACTIONS(DuplicateTab) \ + ON_ALL_ACTIONS(NewTab) \ + ON_ALL_ACTIONS(CloseWindow) \ + ON_ALL_ACTIONS(CloseTab) \ + ON_ALL_ACTIONS(ClosePane) \ + ON_ALL_ACTIONS(NextTab) \ + ON_ALL_ACTIONS(PrevTab) \ + ON_ALL_ACTIONS(SendInput) \ + ON_ALL_ACTIONS(SplitPane) \ + ON_ALL_ACTIONS(ToggleSplitOrientation) \ + ON_ALL_ACTIONS(TogglePaneZoom) \ + ON_ALL_ACTIONS(SwitchToTab) \ + ON_ALL_ACTIONS(AdjustFontSize) \ + ON_ALL_ACTIONS(ResetFontSize) \ + ON_ALL_ACTIONS(ScrollUp) \ + ON_ALL_ACTIONS(ScrollDown) \ + ON_ALL_ACTIONS(ScrollUpPage) \ + ON_ALL_ACTIONS(ScrollDownPage) \ + ON_ALL_ACTIONS(ScrollToTop) \ + ON_ALL_ACTIONS(ScrollToBottom) \ + ON_ALL_ACTIONS(ResizePane) \ + ON_ALL_ACTIONS(MoveFocus) \ + ON_ALL_ACTIONS(MovePane) \ + ON_ALL_ACTIONS(Find) \ + ON_ALL_ACTIONS(ToggleShaderEffects) \ + ON_ALL_ACTIONS(ToggleFocusMode) \ + ON_ALL_ACTIONS(ToggleFullscreen) \ + ON_ALL_ACTIONS(ToggleAlwaysOnTop) \ + ON_ALL_ACTIONS(OpenSettings) \ + ON_ALL_ACTIONS(SetColorScheme) \ + ON_ALL_ACTIONS(SetTabColor) \ + ON_ALL_ACTIONS(OpenTabColorPicker) \ + ON_ALL_ACTIONS(RenameTab) \ + ON_ALL_ACTIONS(OpenTabRenamer) \ + ON_ALL_ACTIONS(ExecuteCommandline) \ + ON_ALL_ACTIONS(ToggleCommandPalette) \ + ON_ALL_ACTIONS(CloseOtherTabs) \ + ON_ALL_ACTIONS(CloseTabsAfter) \ + ON_ALL_ACTIONS(TabSearch) \ + ON_ALL_ACTIONS(MoveTab) \ + ON_ALL_ACTIONS(BreakIntoDebugger) \ + ON_ALL_ACTIONS(TogglePaneReadOnly) \ + ON_ALL_ACTIONS(FindMatch) \ + ON_ALL_ACTIONS(NewWindow) \ + ON_ALL_ACTIONS(IdentifyWindow) \ + ON_ALL_ACTIONS(IdentifyWindows) \ + ON_ALL_ACTIONS(RenameWindow) \ + ON_ALL_ACTIONS(OpenWindowRenamer) \ + ON_ALL_ACTIONS(GlobalSummon) \ + ON_ALL_ACTIONS(QuakeMode) \ ON_ALL_ACTIONS(FocusPane) #define ALL_SHORTCUT_ACTIONS_WITH_ARGS \ diff --git a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw index 99af72c2365..ad8762ed34a 100644 --- a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw @@ -387,6 +387,9 @@ Toggle fullscreen + + Toggle pane split orientation + Toggle pane zoom diff --git a/src/cascadia/TerminalSettingsModel/defaults.json b/src/cascadia/TerminalSettingsModel/defaults.json index 1cc6b31627c..6d8cdceb710 100644 --- a/src/cascadia/TerminalSettingsModel/defaults.json +++ b/src/cascadia/TerminalSettingsModel/defaults.json @@ -350,6 +350,7 @@ { "command": { "action": "movePane", "direction": "up" } }, { "command": { "action": "movePane", "direction": "previous"} }, { "command": "togglePaneZoom" }, + { "command": "toggleSplitOrientation" }, { "command": "toggleReadOnlyMode" }, // Clipboard Integration