terminal icon indicating copy to clipboard operation
terminal copied to clipboard

Add support for resizing panes with mouse

Open zadjii-msft opened this issue 1 year ago • 10 comments

Summary of the Pull Request

Adds support for resizing panes by dragging with the mouse.

ManipulationDelta is the WinUI event we're using to determine if a pane border was dragged. ManipulationDelta is kinda a wacky event in WinUI, but so is the entire Pane structure we've built. The important things to know about this PR are:

  • Leaf panes are the only panes that actually have a Border.
  • We only handle ManipulationDelta events directly on leaf panes.
  • Parent panes, however, are the only ones that actually control the position of a split. So we use a special ManipulationRequested event to bubble the request from the leaf pane that was clicked on, to the ancestor pane that actually owns the border on the side of the pane.
  • We can't just add a ManipulationDelta event handler on the border itself - the event covers all drags in the entire bounding rect of the border. So we've got to use additional logic to make sure that drags originated on a border, not just on content within the border.

Closes #992

other PRs

  • #16170
    • #16171
      • #16172
        • #16895 <-- you are here
        • #16914

todo from 06-04 bugbash

  • [ ] Pane resize does not snap to cell
  • [ ] Pane resize causes a crash(? not sure if this is from that build in general, or specific to this PR)

zadjii-msft avatar Mar 18 '24 21:03 zadjii-msft

Demo:

992-resize-panes

zadjii-msft avatar Mar 18 '24 21:03 zadjii-msft

Can we get the mouse cursor to change to ↔️ or ↕️ depending on what border is hovered? How about the omnidirectional arrow in case of an intersection of 4? (Will panes move that way? Can I grab the middle of a + and resize all 4 panes?) Can we get a hover color effect to indicate that there is something actionable here? This is pretty hidden at the minute 🙂

DHowett avatar Mar 19 '24 15:03 DHowett

Can we get the mouse cursor to change to ↔️ or ↕️ depending on what border is hovered

maybe but you know first hand how hard that is

zadjii-msft avatar Mar 19 '24 15:03 zadjii-msft

maybe but you know first hand how hard that is

Random thought: Make the specific border bolder when the mouse is hovering and the border can be dragged to resize.

Need a visual cue so user is confident that dragging will initiate a resize.

tusharsnx avatar Apr 01 '24 14:04 tusharsnx

I'm still interested in the QoL/discoverability improvements above - are you going to look into those before this merges?

DHowett avatar Apr 03 '24 14:04 DHowett

I'm not sure whether this is the best way to go about it, in particular the bubbling of events to figure out which divider gets dragged seems somewhat... off? I feel like iterating through the tree should accomplish the same thing but be much faster

Would it though? With bubbling, we start at the leaf that is at least adjacent to the border being resized, and only have to iterate O(log(n)) times upwards till at worst, the root, to find the pane that owns the border. Going top down, we'd have to check basically every pane till we found two on opposite sides of the click (right?)

zadjii-msft avatar Apr 03 '24 17:04 zadjii-msft

I believe if we go top-down we can similarly decide whether descending in a sub-tree is necessary by checking if the pointer position falls into the current node's rect.

However, I estimate that a single WinRT object instantiation is roughly equivalent to iterating something in the order of dozens of Pane instances, so I believe we could just check all panes if that makes it easier to implement. The position checks are likely to be very cheap. After a divider has initially been grabbed I would suggest saving a weak reference to it so that dragging it doesn't need to walk through the tree at all. This may also double as a "is currently being dragged" state which I imagine may be useful to change the cursor, or the color of the divider, etc., in the future.

lhecker avatar Apr 03 '24 18:04 lhecker

Sorry we didn't land this for 1.21 - I was looking over Leonard's concerns and I'm wondering if there's a nice middle ground we can strike!

DHowett avatar May 02 '24 23:05 DHowett

Just sticking this in here because I'm sure I'll lose it in this notebook after the next couple weeks: image

I had tried to mock out what Leonard's approach would be. I was pretty sure there wasn't a middle approach between the two, but doing it top-down would be entirely different.

I'll probably come back to try this after Build

zadjii-msft avatar May 03 '24 10:05 zadjii-msft

discussion notes:

  • skip the top down implementation for now
  • add resize handles ala https://github.com/microsoft/terminal/pull/5028

zadjii-msft avatar Jul 22 '24 21:07 zadjii-msft