diff --git a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts index dc7b26053be..3a3718ac2b0 100644 --- a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts +++ b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts @@ -219,6 +219,7 @@ export class ViewZones extends ViewPart { // TODO@Alex: change `newOrdinal` too if (changed) { + zone.delegate.onComputedHeight(props.heightInPx); this.setShouldRender(); } } diff --git a/src/vs/editor/contrib/referenceSearch/browser/referenceSearchWidget.ts b/src/vs/editor/contrib/referenceSearch/browser/referenceSearchWidget.ts index 343acc6c34d..7d911ec760e 100644 --- a/src/vs/editor/contrib/referenceSearch/browser/referenceSearchWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/browser/referenceSearchWidget.ts @@ -397,7 +397,7 @@ export class ReferenceWidget extends PeekViewWidget { instantiationService: IInstantiationService, editor: ICodeEditor ) { - super(editor, keybindingService, ReferenceWidget.INNER_EDITOR_CONTEXT_KEY, { frameColor: '#007ACC', showFrame: false, showArrow: true }); + super(editor, keybindingService, ReferenceWidget.INNER_EDITOR_CONTEXT_KEY, { frameColor: '#007ACC', showFrame: false, showArrow: true, isResizeable: true }); this._editorService = editorService; this._contextService = contextService; this._instantiationService = instantiationService.createChild(new ServiceCollection([IPeekViewService, this])); diff --git a/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts b/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts index 8b906df291f..6db8565964f 100644 --- a/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts +++ b/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts @@ -9,6 +9,7 @@ import 'vs/css!./zoneWidget'; import {Disposables} from 'vs/base/common/lifecycle'; import * as objects from 'vs/base/common/objects'; import * as dom from 'vs/base/browser/dom'; +import {Sash, Orientation, IHorizontalSashLayoutProvider, ISashEvent} from 'vs/base/browser/ui/sash/sash'; import {EventType, IEditorLayoutInfo, IPosition, IRange} from 'vs/editor/common/editorCommon'; import {Range} from 'vs/editor/common/core/range'; import {Position} from 'vs/editor/common/core/position'; @@ -20,6 +21,7 @@ export interface IOptions { frameColor?: string; className?: string; isAccessible?: boolean; + isResizeable?: boolean; } var defaultOptions: IOptions = { @@ -34,13 +36,18 @@ var WIDGET_ID = 'vs.editor.contrib.zoneWidget'; class ViewZoneDelegate implements IViewZone { public domNode: HTMLElement; + public id: number; public afterLineNumber: number; public afterColumn: number; public heightInLines: number; + private _onDomNodeTop: (top: number) => void; private _onComputedHeight: (height: number) => void; - constructor(domNode: HTMLElement, afterLineNumber: number, afterColumn: number, heightInLines: number, onDomNodeTop: (top: number) => void, onComputedHeight: (height: number) => void) { + constructor(domNode: HTMLElement, afterLineNumber: number, afterColumn: number, heightInLines: number, + onDomNodeTop: (top: number) => void, + onComputedHeight: (height: number) => void + ) { this.domNode = domNode; this.afterLineNumber = afterLineNumber; this.afterColumn = afterColumn; @@ -82,10 +89,11 @@ class OverlayWidgetDelegate implements IOverlayWidget { } -export class ZoneWidget { +export class ZoneWidget implements IHorizontalSashLayoutProvider { - private _zoneId: number = -1; + private _viewZone: ViewZoneDelegate = null; private _overlayWidget: OverlayWidgetDelegate = null; + private _sash: Sash; private _disposables = new Disposables(); public container: HTMLElement = null; @@ -118,8 +126,9 @@ export class ZoneWidget { this.container = document.createElement('div'); dom.addClass(this.container, 'zone-widget-container'); this.domNode.appendChild(this.container); - this.fillContainer(this.container); + + this._initSash(); } private _getWidth(info: IEditorLayoutInfo = this.editor.getLayoutInfo()): number { @@ -131,8 +140,13 @@ export class ZoneWidget { } private _onViewZoneHeight(height: number): void { - this.domNode.style.height = height + 'px'; - this.doLayout(height - this._decoratingElementsHeight()); + this.domNode.style.height = `${height}px`; + + let containerHeight = height - this._decoratingElementsHeight(); + this.container.style.height = `${containerHeight}px`; + this.doLayout(containerHeight); + + this._sash.layout(); } public show(rangeOrPos: IRange | IPosition, heightInLines: number): void { @@ -198,15 +212,15 @@ export class ZoneWidget { // insert zone widget this.editor.changeViewZones((accessor: IViewZoneChangeAccessor) => { - if (this._zoneId !== -1) { - accessor.removeZone(this._zoneId); + if (this._viewZone) { + accessor.removeZone(this._viewZone.id); } if (this._overlayWidget) { this.editor.removeOverlayWidget(this._overlayWidget); this._overlayWidget = null; } this.domNode.style.top = '-1000px'; - var viewZone = new ViewZoneDelegate( + this._viewZone = new ViewZoneDelegate( viewZoneDomNode, position.lineNumber, position.column, @@ -214,8 +228,8 @@ export class ZoneWidget { (top: number) => this._onViewZoneTop(top), (height: number) => this._onViewZoneHeight(height) ); - this._zoneId = accessor.addZone(viewZone); - this._overlayWidget = new OverlayWidgetDelegate(WIDGET_ID + this._zoneId, this.domNode); + this._viewZone.id = accessor.addZone(this._viewZone); + this._overlayWidget = new OverlayWidgetDelegate(WIDGET_ID + this._viewZone.id, this.domNode); this.editor.addOverlayWidget(this._overlayWidget); }); @@ -253,10 +267,10 @@ export class ZoneWidget { this._overlayWidget = null; } - if (this._zoneId !== -1) { - this.editor.changeViewZones((accessor) => { - accessor.removeZone(this._zoneId); - this._zoneId = -1; + if (this._viewZone) { + this.editor.changeViewZones(accessor => { + accessor.removeZone(this._viewZone.id); + this._viewZone = null; }); } } @@ -272,5 +286,57 @@ export class ZoneWidget { public doLayout(heightInPixel: number): void { // implement in subclass } + + // --- sash + + private _initSash(): void{ + this._sash = new Sash(this.domNode, this, { orientation: Orientation.HORIZONTAL }); + + if (!this.options.isResizeable) { + this._sash.hide(); + this._sash.disable(); + } + + let data: { startY: number; heightInLines: number; }; + this._disposables.add(this._sash.addListener2('start', (e: ISashEvent) => { + if (this._viewZone) { + data = { + startY: e.startY, + heightInLines: this._viewZone.heightInLines, + }; + } + })); + + this._disposables.add(this._sash.addListener2('end', () => { + data = undefined; + })); + + this._disposables.add(this._sash.addListener2('change', (evt: ISashEvent) => { + if (data) { + let lineDelta = (evt.currentY - data.startY) / this.editor.getConfiguration().lineHeight; + let roundedLineDelta = lineDelta < 0 ? Math.ceil(lineDelta) : Math.floor(lineDelta); + let newHeightInLines = data.heightInLines + roundedLineDelta; + + if (newHeightInLines > 5 && newHeightInLines < 35) { + this.editor.changeViewZones(accessor => { + this._viewZone.heightInLines = newHeightInLines; + accessor.layoutZone(this._viewZone.id); + }); + } + } + })); + } + + getHorizontalSashLeft() { + return 0; + } + + getHorizontalSashTop() { + return parseInt(this.domNode.style.height) - (this._decoratingElementsHeight() / 2); + } + + getHorizontalSashWidth() { + return this.editor.getLayoutInfo().width; + } }