Skip to content

Commit

Permalink
snapping now uses an interface, so that it's not TermControl-specific
Browse files Browse the repository at this point in the history
  • Loading branch information
zadjii-msft committed Jul 18, 2023
1 parent 84df819 commit 7c9ffb0
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 31 deletions.
12 changes: 12 additions & 0 deletions src/cascadia/TerminalApp/IPaneContent.idl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ namespace TerminalApp
// event CloseRequested(...);

event Windows.Foundation.TypedEventHandler<Object, Object> CloseRequested;
};


enum PaneSnapDirection
{
Width,
Height
};

interface ISnappable
{
Single SnapDownToGrid(PaneSnapDirection direction, Single sizeToSnap);
Windows.Foundation.Size GridSize { get; };
};
}
69 changes: 39 additions & 30 deletions src/cascadia/TerminalApp/Pane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<TermControl>() };
const auto direction{ widthOrHeight ? PaneSnapDirection::Width : PaneSnapDirection::Height };

if (_IsLeaf())
{
if (!termControl)
const auto& snappable{ _content.try_as<ISnappable>() };
if (!snappable)
{
return { dimension, dimension };
}
Expand All @@ -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;
Expand All @@ -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 };
}
}
Expand Down Expand Up @@ -2873,36 +2877,41 @@ Pane::SnapSizeResult Pane::_CalcSnappedDimension(const bool widthOrHeight, const
// Return Value:
// - <none>
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<TermControl>() };
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<ISnappable>() };
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
Expand Down
9 changes: 9 additions & 0 deletions src/cascadia/TerminalApp/TerminalPaneContent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
3 changes: 3 additions & 0 deletions src/cascadia/TerminalApp/TerminalPaneContent.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<TerminalApp::TerminalPaneContent, winrt::Windows::Foundation::IInspectable> RestartTerminalRequested;
til::typed_event<> CloseRequested;

Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/TerminalPaneContent.idl
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down

0 comments on commit 7c9ffb0

Please sign in to comment.