diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index a9cc144fe3321bcf36f2d431c6375cf47be049e9..8914672b297e0ea25639cbced8021b6b4bdd3358 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -29,6 +29,7 @@ import { registerThemingParticipant } from 'vs/platform/theme/common/themeServic import { ModelDecorationMinimapOptions } from 'vs/editor/common/model/textModel'; import { Selection } from 'vs/editor/common/core/selection'; import { Color } from 'vs/base/common/color'; +import { GestureEvent, EventType, Gesture } from 'vs/base/browser/touch'; function getMinimapLineHeight(renderMinimap: RenderMinimap): number { if (renderMinimap === RenderMinimap.Large) { @@ -208,6 +209,10 @@ class MinimapLayout { return Math.round(desiredSliderPosition / this._computedSliderRatio); } + public getDesiredScrollTopFromTouchLocation(pageY: number): number { + return Math.round((pageY - this.sliderHeight / 2) / this._computedSliderRatio); + } + public static create( options: MinimapOptions, viewportStartLineNumber: number, @@ -451,12 +456,16 @@ export class Minimap extends ViewPart { private readonly _mouseDownListener: IDisposable; private readonly _sliderMouseMoveMonitor: GlobalMouseMoveMonitor; private readonly _sliderMouseDownListener: IDisposable; + private readonly _sliderTouchStartListener: IDisposable; + private readonly _sliderTouchMoveListener: IDisposable; + private readonly _sliderTouchEndListener: IDisposable; private _options: MinimapOptions; private _lastRenderData: RenderData | null; private _selections: Selection[] = []; private _selectionColor: Color | undefined; private _renderDecorations: boolean = false; + private _gestureInProgress: boolean = false; private _buffers: MinimapBuffers | null; constructor(context: ViewContext) { @@ -566,12 +575,49 @@ export class Minimap extends ViewPart { ); } }); + + Gesture.addTarget(this._domNode.domNode); + this._sliderTouchStartListener = dom.addDisposableListener(this._domNode.domNode, EventType.Start, (e: GestureEvent) => { + e.preventDefault(); + e.stopPropagation(); + if (this._lastRenderData) { + this._slider.toggleClassName('active', true); + this._gestureInProgress = true; + this.scrollDueToTouchEvent(e); + } + }); + + this._sliderTouchMoveListener = dom.addStandardDisposableListener(this._domNode.domNode, EventType.Change, (e: GestureEvent) => { + e.preventDefault(); + e.stopPropagation(); + if (this._lastRenderData && this._gestureInProgress) { + this.scrollDueToTouchEvent(e); + } + }); + + this._sliderTouchEndListener = dom.addStandardDisposableListener(this._domNode.domNode, EventType.End, (e: GestureEvent) => { + e.preventDefault(); + e.stopPropagation(); + this._gestureInProgress = false; + this._slider.toggleClassName('active', false); + }); + } + + private scrollDueToTouchEvent(touch: GestureEvent) { + const startY = this._domNode.domNode.getBoundingClientRect().top; + const scrollTop = this._lastRenderData!.renderedLayout.getDesiredScrollTopFromTouchLocation(touch.pageY - startY); + this._context.viewLayout.setScrollPositionNow({ + scrollTop: scrollTop + }); } public dispose(): void { this._mouseDownListener.dispose(); this._sliderMouseMoveMonitor.dispose(); this._sliderMouseDownListener.dispose(); + this._sliderTouchStartListener.dispose(); + this._sliderTouchMoveListener.dispose(); + this._sliderTouchEndListener.dispose(); super.dispose(); }