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
38 changes: 13 additions & 25 deletions src/vs/base/browser/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -637,46 +637,34 @@ export function getTotalHeight(element: HTMLElement): number {
return element.offsetHeight + margin;
}

// Adapted from WinJS
// Gets the left coordinate of the specified element relative to the specified parent.
export function getRelativeLeft(element: HTMLElement, parent: HTMLElement): number {
if (element === null) {
return 0;
}

let left = element.offsetLeft;
let e = <HTMLElement>element.parentNode;
while (e !== null) {
left -= e.offsetLeft;

if (e === parent) {
break;
}
e = <HTMLElement>e.parentNode;
}

return left;
let elementPosition = getTopLeftOffset(element);
let parentPosition = getTopLeftOffset(parent);
return elementPosition.left - parentPosition.left;
}

// Adapted from WinJS
// Gets the top coordinate of the element relative to the specified parent.
export function getRelativeTop(element: HTMLElement, parent: HTMLElement): number {
if (element === null) {
return 0;
}

let top = element.offsetTop;
let e = <HTMLElement>element.parentNode;
while (e !== null) {
top -= e.offsetTop;

if (e === parent) {
break;
}
e = <HTMLElement>e.parentNode;
}
let elementPosition = getTopLeftOffset(element);
let parentPosition = getTopLeftOffset(parent);
return parentPosition.top - elementPosition.top;
}

return top;
export function getLargestChildWidth(parent: HTMLElement, children: HTMLElement[]): number {
let childWidths = children.map((child) => {
return getTotalWidth(child) + getRelativeLeft(child, parent) || 0;
});
let maxWidth = Math.max(...childWidths);
return maxWidth;
}

// ----------------------------------------------------------------------------------------
Expand Down
8 changes: 8 additions & 0 deletions src/vs/base/browser/ui/sash/sash.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@

.monaco-sash.disabled {
cursor: default;
}

.vertical-cursor-container * {
cursor: ew-resize !important;
}

.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?

}
24 changes: 10 additions & 14 deletions src/vs/base/browser/ui/sash/sash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,12 @@ export class Sash extends EventEmitter {

this.gesture = new Gesture(this.$e.getHTMLElement());

this.$e.on('mousedown', (e: MouseEvent) => { this.onMouseDown(e); });
this.$e.on(DOM.EventType.MOUSE_DOWN, (e: MouseEvent) => { this.onMouseDown(e); });
this.$e.on(DOM.EventType.DBLCLICK, (e: MouseEvent) => { this.emit('reset', e); });
this.$e.on(EventType.Start, (e: GestureEvent) => { this.onTouchStart(e); });

this.orientation = options.orientation || Orientation.VERTICAL;
this.$e.addClass(this.orientation === Orientation.HORIZONTAL ? 'horizontal' : 'vertical');
this.$e.addClass(this.getOrientation());

this.size = options.baseSize || 5;

Expand All @@ -91,6 +92,10 @@ export class Sash extends EventEmitter {
return this.$e.getHTMLElement();
}

private getOrientation(): 'horizontal' | 'vertical' {
return this.orientation === Orientation.HORIZONTAL ? 'horizontal' : 'vertical';
}

private onMouseDown(e: MouseEvent): void {
DOM.EventHelper.stop(e, false);

Expand All @@ -112,17 +117,8 @@ export class Sash extends EventEmitter {
this.$e.addClass('active');
this.emit('start', startEvent);

let overlayDiv = $('div').style({
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
zIndex: 1000000,
cursor: this.orientation === Orientation.VERTICAL ? 'ew-resize' : 'ns-resize'
});

let $window = $(window);
Copy link
Member

Choose a reason for hiding this comment

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

Can you explain why the changes in sash are needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I provided some explanations in the corresponding commit message, 0636b55e2ed8422f16ed7196db1ebdf33b6ac5ed. I can explain more if that’s not clear.

let containerCssClass = `${this.getOrientation()}-cursor-container`;

let lastCurrentX = startX;
let lastCurrentY = startY;
Expand All @@ -148,10 +144,10 @@ export class Sash extends EventEmitter {
this.emit('end');

$window.off('mousemove');
overlayDiv.destroy();
document.body.classList.remove(containerCssClass);
});

overlayDiv.appendTo(document.body);
document.body.classList.add(containerCssClass);
}

private onTouchStart(event: GestureEvent): void {
Expand Down
19 changes: 13 additions & 6 deletions src/vs/editor/browser/widget/diffEditorWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1327,9 +1327,10 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
this._sash.disable();
}

this._sash.on('start', () => this._onSashDragStart());
this._sash.on('change', (e: ISashEvent) => this._onSashDrag(e));
this._sash.on('end', () => this._onSashDragEnd());
this._sash.on('start', () => this.onSashDragStart());
this._sash.on('change', (e: ISashEvent) => this.onSashDrag(e));
this._sash.on('end', () => this.onSashDragEnd());
this._sash.on('reset', () => this.onSashReset());
}

public dispose(): void {
Expand Down Expand Up @@ -1378,11 +1379,11 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
return this._sashPosition;
}

private _onSashDragStart(): void {
private onSashDragStart(): void {
this._startSashPosition = this._sashPosition;
}

private _onSashDrag(e:ISashEvent): void {
private onSashDrag(e:ISashEvent): void {
var w = this._dataSource.getWidth();
var contentWidth = w - DiffEditorWidget.ENTIRE_DIFF_OVERVIEW_WIDTH;
var sashPosition = this.layout((this._startSashPosition + (e.currentX - e.startX)) / contentWidth);
Expand All @@ -1392,7 +1393,13 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd
this._dataSource.relayoutEditors();
}

private _onSashDragEnd(): void {
private onSashDragEnd(): void {
this._sash.layout();
}

private onSashReset(): void {
this._sashRatio = 0.5;
this._dataSource.relayoutEditors();
this._sash.layout();
}

Expand Down
21 changes: 20 additions & 1 deletion src/vs/workbench/browser/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {Sash, ISashEvent, IVerticalSashLayoutProvider, IHorizontalSashLayoutProv
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
import {IPartService, Position} from 'vs/workbench/services/part/common/partService';
import {IWorkspaceContextService} from 'vs/workbench/services/workspace/common/contextService';
import {IViewletService} from 'vs/workbench/services/viewlet/common/viewletService';
import {IStorageService, StorageScope} from 'vs/platform/storage/common/storage';
import {IContextViewService} from 'vs/platform/contextview/browser/contextView';
import {IEventService} from 'vs/platform/event/common/event';
Expand Down Expand Up @@ -94,6 +95,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IPartService private partService: IPartService,
@IViewletService private viewletService: IViewletService,
@IThemeService themeService: IThemeService
) {
this.parent = parent;
Expand Down Expand Up @@ -190,7 +192,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal
let dragCompensation = DEFAULT_MIN_PANEL_PART_HEIGHT - HIDE_PANEL_HEIGHT_THRESHOLD;
this.partService.setPanelHidden(true);
startY = Math.min(this.sidebarHeight - this.computedStyles.statusbar.height, e.currentY + dragCompensation);
this.panelHeight = this.startPanelHeight; // when restoring panel, restore to the panel width we started from
this.panelHeight = this.startPanelHeight; // when restoring panel, restore to the panel height we started from
}

// Otherwise size the panel accordingly
Expand All @@ -217,9 +219,26 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal
this.sashX.addListener('end', () => {
this.storageService.store(WorkbenchLayout.sashXWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL);
});

this.sashY.addListener('end', () => {
this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL);
});

this.sashY.addListener('reset', () => {
this.panelHeight = DEFAULT_MIN_PANEL_PART_HEIGHT;
this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL);
this.partService.setPanelHidden(false);
this.layout();
});

this.sashX.addListener('reset', () => {
let activeViewlet = this.viewletService.getActiveViewlet();
let optimalWidth = activeViewlet && activeViewlet.getOptimalWidth();
this.sidebarWidth = Math.max(DEFAULT_MIN_PART_WIDTH, optimalWidth || 0);
this.storageService.store(WorkbenchLayout.sashXWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL);
this.partService.setSideBarHidden(false);
this.layout();
});
}

private onEditorInputChanging(e: EditorEvent): void {
Expand Down
7 changes: 7 additions & 0 deletions src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export class BinaryResourceDiffEditor extends BaseEditor implements IVerticalSas
this.sash.addListener('start', () => this.onSashDragStart());
this.sash.addListener('change', (e: ISashEvent) => this.onSashDrag(e));
this.sash.addListener('end', () => this.onSashDragEnd());
this.sash.addListener('reset', () => this.onSashReset());

// Right Container for Binary
let rightBinaryContainerElement = document.createElement('div');
Expand Down Expand Up @@ -199,6 +200,12 @@ export class BinaryResourceDiffEditor extends BaseEditor implements IVerticalSas
this.sash.layout();
}

private onSashReset(): void {
this.leftContainerWidth = this.dimension.width / 2;
this.layoutContainers();
this.sash.layout();
}

public getVerticalSashTop(sash: Sash): number {
return 0;
}
Expand Down
20 changes: 20 additions & 0 deletions src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,7 @@ export class SideBySideEditorControl extends EventEmitter implements IVerticalSa
this.leftSash.addListener('start', () => this.onLeftSashDragStart());
this.leftSash.addListener('change', (e: ISashEvent) => this.onLeftSashDrag(e));
this.leftSash.addListener('end', () => this.onLeftSashDragEnd());
this.leftSash.addListener('reset', () => this.onLeftSashReset());
this.leftSash.hide();

// Center Container
Expand All @@ -738,6 +739,7 @@ export class SideBySideEditorControl extends EventEmitter implements IVerticalSa
this.rightSash.addListener('start', () => this.onRightSashDragStart());
this.rightSash.addListener('change', (e: ISashEvent) => this.onRightSashDrag(e));
this.rightSash.addListener('end', () => this.onRightSashDragEnd());
this.rightSash.addListener('reset', () => this.onRightSashReset());
this.rightSash.hide();

// Right Container
Expand Down Expand Up @@ -1212,6 +1214,14 @@ export class SideBySideEditorControl extends EventEmitter implements IVerticalSa
this.editorActionsToolbar[position].setActions([], [])();
}

private centerSash(a: Position, b: Position): void {
let sumWidth = this.containerWidth[a] + this.containerWidth[b];
let meanWidth = sumWidth / 2;
this.containerWidth[a] = meanWidth;
this.containerWidth[b] = sumWidth - meanWidth;
this.layoutContainers();
}

private onLeftSashDragStart(): void {
this.startLeftContainerWidth = this.containerWidth[Position.LEFT];
}
Expand Down Expand Up @@ -1301,6 +1311,11 @@ export class SideBySideEditorControl extends EventEmitter implements IVerticalSa
this.focusNextNonMinimized();
}

private onLeftSashReset(): void {
this.centerSash(Position.LEFT, Position.CENTER);
this.leftSash.layout();
}

private onRightSashDragStart(): void {
this.startRightContainerWidth = this.containerWidth[Position.RIGHT];
}
Expand Down Expand Up @@ -1358,6 +1373,11 @@ export class SideBySideEditorControl extends EventEmitter implements IVerticalSa
this.focusNextNonMinimized();
}

private onRightSashReset(): void {
this.centerSash(Position.CENTER, Position.RIGHT);
this.rightSash.layout();
}

public getVerticalSashTop(sash: Sash): number {
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/browser/parts/sidebar/sidebarPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class SidebarPart extends CompositePart<Viewlet> implements IViewletServi
}

public getActiveViewlet(): IViewlet {
return this.getActiveComposite();
return <IViewlet>this.getActiveComposite();
}

public getLastActiveViewletId(): string {
Expand Down
6 changes: 5 additions & 1 deletion src/vs/workbench/browser/viewlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ import {IContextMenuService} from 'vs/platform/contextview/browser/contextView';
import {IMessageService} from 'vs/platform/message/common/message';
import {StructuredSelection} from 'vs/platform/selection/common/selection';

export abstract class Viewlet extends Composite implements IViewlet { }
export abstract class Viewlet extends Composite implements IViewlet {
public getOptimalWidth(): number {
return null;
}
}

/**
* Helper subtype of viewlet for those that use a tree inside.
Expand Down
7 changes: 6 additions & 1 deletion src/vs/workbench/common/viewlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@

import {IComposite} from 'vs/workbench/common/composite';

export interface IViewlet extends IComposite { }
export interface IViewlet extends IComposite {
/**
* Returns the minimal width needed to avoid any content horizontal truncation
*/
getOptimalWidth(): number;
}
9 changes: 9 additions & 0 deletions src/vs/workbench/parts/files/browser/explorerViewlet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,15 @@ export class ExplorerViewlet extends Viewlet {
return this.actionRunner;
}

public getOptimalWidth(): number {
let additionalMargin = 16;
let workingFilesViewWidth = this.getWorkingFilesView().getOptimalWidth();
let explorerView = this.getExplorerView();
let explorerViewWidth = explorerView ? explorerView.getOptimalWidth() : 0;
let optimalWidth = Math.max(workingFilesViewWidth, explorerViewWidth);
return optimalWidth + additionalMargin;
}

public shutdown(): void {
this.views.forEach((view) => view.shutdown());

Expand Down
8 changes: 7 additions & 1 deletion src/vs/workbench/parts/files/browser/views/explorerView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {FileEditorInput} from 'vs/workbench/parts/files/browser/editors/fileEdit
import {FileDragAndDrop, FileFilter, FileSorter, FileController, FileRenderer, FileDataSource, FileViewletState, FileAccessibilityProvider} from 'vs/workbench/parts/files/browser/views/explorerViewer';
import lifecycle = require('vs/base/common/lifecycle');
import {IEditor} from 'vs/platform/editor/common/editor';
import DOM = require('vs/base/browser/dom');
import * as DOM from 'vs/base/browser/dom';
import {CollapseAction, CollapsibleViewletView} from 'vs/workbench/browser/viewlet';
import {FileStat} from 'vs/workbench/parts/files/common/explorerViewModel';
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
Expand Down Expand Up @@ -348,6 +348,12 @@ export class ExplorerView extends CollapsibleViewletView {
return this.explorerViewer;
}

public getOptimalWidth(): number {
let parentNode = this.explorerViewer.getHTMLElement();
let childNodes = [].slice.call(parentNode.querySelectorAll('.explorer-item-label > a'));
return DOM.getLargestChildWidth(parentNode, childNodes);
}

private onLocalFileChange(e: LocalFileChangeEvent): void {
let modelElement: FileStat;
let parent: FileStat;
Expand Down
Loading