提交 9b893830 编写于 作者: J João Moreno

implement touch interaction in list

fixes #9338
上级 f5e9cb6d
......@@ -5,9 +5,11 @@
import { toObject, assign, getOrDefault } from 'vs/base/common/objects';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Gesture } from 'vs/base/browser/touch';
import { Gesture, EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
import * as DOM from 'vs/base/browser/dom';
import { domEvent } from 'vs/base/browser/event';
import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { ScrollEvent } from 'vs/base/common/scrollable';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { RangeMap, IRange, relativeComplement, each } from './rangeMap';
import { IDelegate, IRenderer } from './list';
......@@ -59,7 +61,7 @@ export class ListView<T> implements IDisposable {
private gesture: Gesture;
private rowsContainer: HTMLElement;
private scrollableElement: ScrollableElement;
private toDispose: IDisposable[];
private disposables: IDisposable[];
constructor(
container: HTMLElement,
......@@ -91,12 +93,13 @@ export class ListView<T> implements IDisposable {
saveLastScrollTimeOnClassName: 'monaco-list-row'
});
const listener = this.scrollableElement.onScroll(e => this.render(e.scrollTop, e.height));
this._domNode.appendChild(this.scrollableElement.getDomNode());
container.appendChild(this._domNode);
this.toDispose = [this.rangeMap, this.gesture, listener, this.scrollableElement];
this.disposables = [this.rangeMap, this.gesture, this.scrollableElement];
this.scrollableElement.onScroll(this.onScroll, this, this.disposables);
domEvent(this.rowsContainer, TouchEventType.Change)(this.onTouchChange, this, this.disposables);
this.layout();
}
......@@ -217,29 +220,61 @@ export class ListView<T> implements IDisposable {
this.scrollableElement.updateState({ scrollTop });
}
get scrollTop(): number {
return this.getScrollTop();
}
set scrollTop(scrollTop: number) {
this.setScrollTop(scrollTop);
}
// Events
addListener(type: string, handler: (event:any)=>void, useCapture?: boolean): IDisposable {
const userHandler = handler;
let domNode = this.domNode;
if (MouseEventTypes.indexOf(type) > -1) {
const userHandler = handler;
handler = (event: MouseEvent) => {
const index = this.getItemIndex(event);
handler = e => this.fireScopedEvent(userHandler, this.getItemIndexFromMouseEvent(e));
} else if (type === TouchEventType.Tap) {
domNode = this.rowsContainer;
handler = e => this.fireScopedEvent(userHandler, this.getItemIndexFromGestureEvent(e));
}
if (index < 0) {
return;
}
return DOM.addDisposableListener(domNode, type, handler, useCapture);
}
const element = this.items[index].element;
userHandler(assign(event, { element, index }));
};
private fireScopedEvent(handler: (event: any)=>void, index) {
if (index < 0) {
return;
}
return DOM.addDisposableListener(this.domNode, type, handler, useCapture);
const element = this.items[index].element;
handler(assign(event, { element, index }));
}
private getItemIndex(event: MouseEvent): number {
let target = event.target;
private onScroll(e: ScrollEvent): void {
this.render(e.scrollTop, e.height);
}
private onTouchChange(e: GestureEvent): void {
event.preventDefault();
event.stopPropagation();
this.scrollTop -= e.translationY;
}
// Util
private getItemIndexFromMouseEvent(event: MouseEvent): number {
return this.getItemIndexFromEventTarget(event.target);
}
private getItemIndexFromGestureEvent(event: GestureEvent): number {
return this.getItemIndexFromEventTarget(event.initialTarget);
}
private getItemIndexFromEventTarget(target: EventTarget): number {
while (target instanceof HTMLElement && target !== this.rowsContainer) {
const element = target as HTMLElement;
const rawIndex = element.getAttribute('data-index');
......@@ -275,6 +310,6 @@ export class ListView<T> implements IDisposable {
this._domNode = null;
}
this.toDispose = dispose(this.toDispose);
this.disposables = dispose(this.disposables);
}
}
......@@ -7,6 +7,7 @@ import 'vs/css!./list';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { isNumber } from 'vs/base/common/types';
import * as DOM from 'vs/base/browser/dom';
import { EventType as TouchEventType } from 'vs/base/browser/touch';
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import Event, { Emitter, mapEvent, EventBufferer, filterEvent } from 'vs/base/common/event';
......@@ -130,7 +131,8 @@ class Controller<T> implements IDisposable {
) {
this.disposables = [];
this.disposables.push(view.addListener('mousedown', e => this.onMouseDown(e)));
this.disposables.push(view.addListener('click', e => this.onClick(e)));
this.disposables.push(view.addListener('click', e => this.onPointer(e)));
this.disposables.push(view.addListener(TouchEventType.Tap, e => this.onPointer(e)));
const onRawKeyDown = domEvent(view.domNode, 'keydown');
const onKeyDown = mapEvent(onRawKeyDown, e => new StandardKeyboardEvent(e));
......@@ -146,7 +148,7 @@ class Controller<T> implements IDisposable {
e.stopPropagation();
}
private onClick(e: IListMouseEvent<T>) {
private onPointer(e: IListMouseEvent<T>) {
e.preventDefault();
e.stopPropagation();
this.view.domNode.focus();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册