Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sash double clicks #4702

Merged
merged 8 commits into from
Apr 15, 2016
Merged

Sash double clicks #4702

merged 8 commits into from
Apr 15, 2016

Conversation

mquandalle
Copy link
Contributor

Start implementing #4660.

The provided code defines a new event that is fired when a “stash” is double-clicked, and two usages of it—the first one on the spitted editor frontiers, and the second one on the bottom panel border. It is easier to review this PR commit per commit.

The capture below demonstrates the feature on the spitted editor:

vscode-resize

I may want in implement the “sidebar optimal sizing” that originally motivated #4660, but I would like to have some guidance on the code structure:

  • Is IViewletView the right place to implement an optional getOptimalWidth method? [edit: I’ve chosen IViewlet instead]
  • What is the best way to perform the HTML elements width measurement? [edit: I’ve found DOM.getTotalWidth and DOM.getRelativeLeft]
  • How do I get the current viewlet in vs/workbench/layout.ts? [edit: the viewlet service]
  • Where and how should I write some tests?

Thank you in advance for considering this contribution :-)

@msftclas
Copy link

Hi @mquandalle, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!

In order for us to evaluate and accept your PR, we ask that you sign a contribution license agreement. It's all electronic and will take just minutes. I promise there's no faxing. https://cla.microsoft.com.

TTYL, MSBOT;

@msftclas
Copy link

@mquandalle, Thanks for signing the contribution license agreement so quickly! Actual humans will now validate the agreement and then evaluate the PR.

Thanks, MSBOT;

@bpasero
Copy link
Member

bpasero commented Mar 29, 2016

@mquandalle I would just suggest to make the side bar size to its minimal width. Since we never show horizontal scrollbars, every size is good enough to show the contents within. Minimal width is defined in https://github.com/Microsoft/vscode/blob/master/src/vs/workbench/browser/layout.ts#L20

@mquandalle
Copy link
Contributor Author

That would be pretty easy but if you look at Sublime and Atom they both have a smarter implementation that measures the width of the explorer items and uses the larger one as the sidebar width. Do the test! For example if you have an opened sidebar at its “optimal width” and you open some folder that contains longer file names, double clicking on the sidebar border will re-calculate a larger width. As described in #4660 I’d like to have the same behavior on VSCode.

So the idea was to use a static width (like indeed DEFAULT_MIN_PART_WIDTH) on the search and debugger viewlets, and let the file-explorer and the git-commiter viewlets implement a method that returns their optimal width.

@bpasero
Copy link
Member

bpasero commented Mar 29, 2016

@mquandalle I see, there is currently no API to compute the optimal width of the explorer tree to prevent truncating of words, but maybe @joaomoreno could chime in on that topic.

@joaomoreno joaomoreno changed the title Stash double clicks Sash double clicks Mar 29, 2016
@joaomoreno
Copy link
Member

Renamed stash to sash in the title.

@bpasero @mquandalle It can be done, but it is non-trivial.

@mquandalle mquandalle changed the title Sash double clicks [WIP] Sash double clicks Mar 29, 2016
@mquandalle
Copy link
Contributor Author

I got a first version of explorer optimal resizing working in 9da61e8.

@bpasero
Copy link
Member

bpasero commented Mar 29, 2016

@mquandalle cool, I think it would make somewhat more sense that every viewlet can implement a function to provide its optimal width. That way, the double click works with all viewlets. If a viewlet decides to not provide optimal width, it should just fallback to the minimal view width as indicated before.

I think you also need to take into account some other aspects: The working files view to the top also has labels that might get truncated. However, I would not expect that the full path of a working file gets revealed, only its label 👍

@mquandalle
Copy link
Contributor Author

I think it would make somewhat more sense that every viewlet can implement a function to provide its optimal width. That way, the double click works with all viewlets. If a viewlet decides to not provide optimal width, it should just fallback to the minimal view width as indicated before.

Yes, that’s exactly how I implemented it.

I think you also need to take into account some other aspects: The working files view to the top also has labels that might get truncated. However, I would not expect that the full path of a working file gets revealed, only its label

Sure, currently I only take into account the explorer tree width but adding the working view as you say makes total sense.

}

.horizontal-cursor-container * {
cursor: ns-resize !important;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

@bpasero
Copy link
Member

bpasero commented Mar 30, 2016

I added some comments to the code

@bpasero bpasero added this to the April 2016 milestone Mar 30, 2016
@mquandalle mquandalle force-pushed the stash-dblclick branch 6 times, most recently from a4fa580 to 76a8ce0 Compare April 1, 2016 16:42
@mquandalle
Copy link
Contributor Author

Also note that the current DOM measurement strategy has two important drawbacks:

  1. getOptimalWidth() doesn’t work if the sidebar is closed, ie you can’t double click on the closed sash to open the sidebar to its optimal width, which is expected;
  2. if the explorer list is too long, VS renderer will break the list into multiple “tiles” that won’t be displayed concurrently, thus getOptimalWidth() will only consider visible elements and not the entire list.

For comparison both Atom and Sublime handle (2) correctly and don’t have problem (1) as they don’t allow sidebar opening using the mouse.

@bpasero
Copy link
Member

bpasero commented Apr 8, 2016

@mquandalle thanks, can you resolve the merge conflicts in this PR? I will have a look soon and provide feedback.

@bpasero
Copy link
Member

bpasero commented Apr 9, 2016

@mquandalle actually much easier to review your change without merging master back in. just let it be :)

@bpasero
Copy link
Member

bpasero commented Apr 9, 2016

@mquandalle getting there, works very nice now. Some more feedback:

  • You can manage to move getOptimalWidth() into IViewlet by casting to IViewlet in the sidebarPart.ts#getActiveViewlet() method: return <IViewlet>this.getActiveComposite();
    This should fix all the compile errors and you can do the move out of IComposite into IViewlet and related implementations. The default implementation (returning null) can then go into the abstract Viewlet class.
  • Be careful in explorerViewlet#getOptimalWidth(). you expect the explorer view to be there, but if you don't have a folder open, explorer view is of kind EmptyView and does not have any optimal width.
  • the implementation of getOptimalWidth() seems very duplicate between explorerView and workingFilesView. I suggest to create a new method in DOM where you pass in the class name of the container you want to measure.

@mquandalle
Copy link
Contributor Author

Thank you for the feedback, I should be able to amend the PR soon. Do you have any comment on #4702 (comment)?

@bpasero
Copy link
Member

bpasero commented Apr 10, 2016

@mquandalle sure:

  1. I wonder if double click on the hidden sidebar should actually be a no-op? otherwise I am also fine to leave it as is, though I wonder if this is a use case in common scenarios.
  2. that is true and due to the fact that the tree is fully virtual and the DOM only contains what you see. I think that this is OK as is.

We had to implement a slight change in the sash drag "hack", by removing the
full cover transparent overlay (that was preventing clicks events from being
fired) and replacing it by a CSS `cursor` rule on the document.body.

The ideal solution for a clean dragging events implementation would be to use
the `Element.setCapture` API that is unfortunately not available in Chrome.
The calculus was plain wrong as showed in winjs/winjs#1621
This was probably unotified since this utility function wasn't used in the code base.
@mquandalle
Copy link
Contributor Author

mquandalle commented Apr 14, 2016

I rebased my branch on master` to solves the (trivial) merge conflict. I also added a commit to address your #4702 (comment) points.

Points 1 and 3 are fixed, but I have a doubt about 2. You say that I’m not handling the case when explorerViewlet#getExplorerView() returns EmptyView but the return type of this function is ExplorerView and not ExplorerView | EmptyView. Should I change that?

@bpasero
Copy link
Member

bpasero commented Apr 15, 2016

@mquandalle changes look good! you are right, getExplorerView() will return only the explorer view, but it can return null in case you did not open a folder (just try to File > Close Folder and doubleclick on the explorer sash).

@mquandalle
Copy link
Contributor Author

Ok, it's fixed.

This commit also moves the `getOptimalWidth` method from the `Composite` to the
`Viewlet` component. This partially addresses
microsoft#4702 (comment)
@bpasero bpasero merged commit 65bdaf3 into microsoft:master Apr 15, 2016
@bpasero
Copy link
Member

bpasero commented Apr 15, 2016

Thanks so much, merged to master!

@mquandalle mquandalle mentioned this pull request Apr 15, 2016
2 tasks
isidorn pushed a commit that referenced this pull request Apr 15, 2016
* Support double click on sashes

We had to implement a slight change in the sash drag "hack", by removing the
full cover transparent overlay (that was preventing clicks events from being
fired) and replacing it by a CSS `cursor` rule on the document.body.

The ideal solution for a clean dragging events implementation would be to use
the `Element.setCapture` API that is unfortunately not available in Chrome.

* Center the split editor frontier by double-clicking on it

* Reset the bottom panel size by double-clicking on it

* Implement sash reset on diff editors

* Fix a bug with DOM measurement

The calculus was plain wrong as showed in winjs/winjs#1621
This was probably unotified since this utility function wasn't used in the code base.

* Implement sidebar sash optimal resizing

Fixes #4660

* Abstract `getLargestChildWidth` into a DOM method

This commit also moves the `getOptimalWidth` method from the `Composite` to the
`Viewlet` component. This partially addresses
#4702 (comment)

* Calculate the sidebar optimal width correctly in case no folder is open
@Tyriar
Copy link
Member

Tyriar commented Apr 15, 2016

Thanks @mquandalle, I've been wanting this for a while! 🎆

@mquandalle mquandalle mentioned this pull request May 3, 2016
68 tasks
@github-actions github-actions bot locked and limited conversation to collaborators Mar 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants