diff --git a/src/cascadia/TerminalApp/IPaneContent.idl b/src/cascadia/TerminalApp/IPaneContent.idl index 389f0e8cf31..734abe6896e 100644 --- a/src/cascadia/TerminalApp/IPaneContent.idl +++ b/src/cascadia/TerminalApp/IPaneContent.idl @@ -22,6 +22,18 @@ namespace TerminalApp // event CloseRequested(...); event Windows.Foundation.TypedEventHandler CloseRequested; + }; + + + enum PaneSnapDirection + { + Width, + Height + }; + interface ISnappable + { + Single SnapDownToGrid(PaneSnapDirection direction, Single sizeToSnap); + Windows.Foundation.Size GridSize { get; }; }; } diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index f3f5f87119b..beff22af2f4 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -2789,12 +2789,12 @@ float Pane::CalcSnappedDimension(const bool widthOrHeight, const float dimension // If requested size is already snapped, then both returned values equal this value. Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const float dimension) const { - // TODO!: Again, bad. We're special-casing that the content just so happens to have a TermControl - const auto& termControl{ _content.GetRoot().try_as() }; + const auto direction{ widthOrHeight ? PaneSnapDirection::Width : PaneSnapDirection::Height }; if (_IsLeaf()) { - if (!termControl) + const auto& snappable{ _content.try_as() }; + if (!snappable) { return { dimension, dimension }; } @@ -2809,8 +2809,10 @@ Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const return { minDimension, minDimension }; } - auto lower = termControl.SnapDimensionToGrid(widthOrHeight, dimension); - if (widthOrHeight) + auto lower = snappable.SnapDownToGrid(widthOrHeight ? PaneSnapDirection::Width : PaneSnapDirection::Height, + dimension); + + if (direction == PaneSnapDirection::Width) { lower += WI_IsFlagSet(_borders, Borders::Left) ? PaneBorderSize : 0; lower += WI_IsFlagSet(_borders, Borders::Right) ? PaneBorderSize : 0; @@ -2829,8 +2831,10 @@ Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const } else { - const auto cellSize = termControl.CharacterDimensions(); - const auto higher = lower + (widthOrHeight ? cellSize.Width : cellSize.Height); + const auto cellSize = snappable.GridSize(); + const auto higher = lower + (direction == PaneSnapDirection::Width ? + cellSize.Width : + cellSize.Height); return { lower, higher }; } } @@ -2873,36 +2877,41 @@ Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const // Return Value: // - void Pane::_AdvanceSnappedDimension(const bool widthOrHeight, LayoutSizeNode& sizeNode) const -{ // TODO!: Again, bad. We're special-casing that the content just so happens to have a TermControl - const auto& termControl{ _content.GetRoot().try_as() }; - if (_IsLeaf() && termControl) +{ + if (_IsLeaf()) { - // We're a leaf pane, so just add one more row or column (unless isMinimumSize - // is true, see below). - - if (sizeNode.isMinimumSize) + const auto& snappable{ _content.try_as() }; + if (snappable) { - // If the node is of its minimum size, this size might not be snapped (it might - // be, say, half a character, or fixed 10 pixels), so snap it upward. It might - // however be already snapped, so add 1 to make sure it really increases - // (not strictly necessary but to avoid surprises). - sizeNode.size = _CalcSnappedDimension(widthOrHeight, sizeNode.size + 1).higher; + // We're a leaf pane, so just add one more row or column (unless isMinimumSize + // is true, see below). + + if (sizeNode.isMinimumSize) + { + // If the node is of its minimum size, this size might not be snapped (it might + // be, say, half a character, or fixed 10 pixels), so snap it upward. It might + // however be already snapped, so add 1 to make sure it really increases + // (not strictly necessary but to avoid surprises). + sizeNode.size = _CalcSnappedDimension(widthOrHeight, + sizeNode.size + 1) + .higher; + } + else + { + const auto cellSize = snappable.GridSize(); + sizeNode.size += widthOrHeight ? cellSize.Width : cellSize.Height; + } } else { - const auto cellSize = termControl.CharacterDimensions(); - sizeNode.size += widthOrHeight ? cellSize.Width : cellSize.Height; + // If we're a leaf that didn't have a TermControl, then just increment + // by one. We have to increment by _some_ value, because this is used in + // a while() loop to find the next bigger size we can snap to. But since + // a non-terminal control doesn't really care what size it's snapped to, + // we can just say "one pixel larger is the next snap point" + sizeNode.size += 1; } } - else if (_IsLeaf()) - { - // If we're a leaf that didn't have a TermControl, then just increment - // by one. We have to increment by _some_ value, because this is used in - // a while() loop to find the next bigger size we can snap to. But since - // a non-terminal control doesn't really care what size it's snapped to, - // we can just say "one pixel larger is the next snap point" - sizeNode.size += 1; - } else { // We're a parent pane, so we have to advance dimension of our children panes. In diff --git a/src/cascadia/TerminalApp/TerminalPaneContent.cpp b/src/cascadia/TerminalApp/TerminalPaneContent.cpp index f499010f0ef..d2f89ea35a9 100644 --- a/src/cascadia/TerminalApp/TerminalPaneContent.cpp +++ b/src/cascadia/TerminalApp/TerminalPaneContent.cpp @@ -270,4 +270,13 @@ namespace winrt::TerminalApp::implementation { _isDefTermSession = true; } + + float TerminalPaneContent::SnapDownToGrid(const TerminalApp::PaneSnapDirection direction, const float sizeToSnap) + { + return _control.SnapDimensionToGrid(direction == PaneSnapDirection::Width, sizeToSnap); + } + Windows::Foundation::Size TerminalPaneContent::GridSize() + { + return _control.CharacterDimensions(); + } } diff --git a/src/cascadia/TerminalApp/TerminalPaneContent.h b/src/cascadia/TerminalApp/TerminalPaneContent.h index 9d68ffd9336..44ccba4ae2b 100644 --- a/src/cascadia/TerminalApp/TerminalPaneContent.h +++ b/src/cascadia/TerminalApp/TerminalPaneContent.h @@ -36,6 +36,9 @@ namespace winrt::TerminalApp::implementation uint64_t TaskbarProgress() { return _control.TaskbarProgress(); } bool ReadOnly() { return _control.ReadOnly(); } + float SnapDownToGrid(const TerminalApp::PaneSnapDirection direction, const float sizeToSnap); + Windows::Foundation::Size GridSize(); + til::typed_event RestartTerminalRequested; til::typed_event<> CloseRequested; diff --git a/src/cascadia/TerminalApp/TerminalPaneContent.idl b/src/cascadia/TerminalApp/TerminalPaneContent.idl index 43eb96739a5..1e39f41c168 100644 --- a/src/cascadia/TerminalApp/TerminalPaneContent.idl +++ b/src/cascadia/TerminalApp/TerminalPaneContent.idl @@ -5,7 +5,7 @@ import "IPaneContent.idl"; namespace TerminalApp { - [default_interface] runtimeclass TerminalPaneContent : IPaneContent + [default_interface] runtimeclass TerminalPaneContent : IPaneContent, ISnappable { Microsoft.Terminal.Control.TermControl GetTerminal();