Path: blob/main/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { GlobalPointerMoveMonitor } from '../../globalPointerMoveMonitor.js';6import { Widget } from '../widget.js';7import { TimeoutTimer } from '../../../common/async.js';8import { ThemeIcon } from '../../../common/themables.js';9import * as dom from '../../dom.js';1011/**12* The arrow image size.13*/14export const ARROW_IMG_SIZE = 11;1516export interface ScrollbarArrowOptions {17onActivate: () => void;18className: string;19icon: ThemeIcon;2021bgWidth: number;22bgHeight: number;2324top?: number;25left?: number;26bottom?: number;27right?: number;28}2930export class ScrollbarArrow extends Widget {3132private _onActivate: () => void;33public bgDomNode: HTMLElement;34public domNode: HTMLElement;35private _pointerdownRepeatTimer: dom.WindowIntervalTimer;36private _pointerdownScheduleRepeatTimer: TimeoutTimer;37private _pointerMoveMonitor: GlobalPointerMoveMonitor;3839constructor(opts: ScrollbarArrowOptions) {40super();41this._onActivate = opts.onActivate;4243this.bgDomNode = document.createElement('div');44this.bgDomNode.className = 'arrow-background';45this.bgDomNode.style.position = 'absolute';46this.bgDomNode.style.width = opts.bgWidth + 'px';47this.bgDomNode.style.height = opts.bgHeight + 'px';48if (typeof opts.top !== 'undefined') {49this.bgDomNode.style.top = '0px';50}51if (typeof opts.left !== 'undefined') {52this.bgDomNode.style.left = '0px';53}54if (typeof opts.bottom !== 'undefined') {55this.bgDomNode.style.bottom = '0px';56}57if (typeof opts.right !== 'undefined') {58this.bgDomNode.style.right = '0px';59}6061this.domNode = document.createElement('div');62this.domNode.className = opts.className;63this.domNode.classList.add(...ThemeIcon.asClassNameArray(opts.icon));6465this.domNode.style.position = 'absolute';66this.domNode.style.width = ARROW_IMG_SIZE + 'px';67this.domNode.style.height = ARROW_IMG_SIZE + 'px';68if (typeof opts.top !== 'undefined') {69this.domNode.style.top = opts.top + 'px';70}71if (typeof opts.left !== 'undefined') {72this.domNode.style.left = opts.left + 'px';73}74if (typeof opts.bottom !== 'undefined') {75this.domNode.style.bottom = opts.bottom + 'px';76}77if (typeof opts.right !== 'undefined') {78this.domNode.style.right = opts.right + 'px';79}8081this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());82this._register(dom.addStandardDisposableListener(this.bgDomNode, dom.EventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));83this._register(dom.addStandardDisposableListener(this.domNode, dom.EventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));8485this._pointerdownRepeatTimer = this._register(new dom.WindowIntervalTimer());86this._pointerdownScheduleRepeatTimer = this._register(new TimeoutTimer());87}8889private _arrowPointerDown(e: PointerEvent): void {90if (!e.target || !(e.target instanceof Element)) {91return;92}93const scheduleRepeater = () => {94this._pointerdownRepeatTimer.cancelAndSet(() => this._onActivate(), 1000 / 24, dom.getWindow(e));95};9697this._onActivate();98this._pointerdownRepeatTimer.cancel();99this._pointerdownScheduleRepeatTimer.cancelAndSet(scheduleRepeater, 200);100101this._pointerMoveMonitor.startMonitoring(102e.target,103e.pointerId,104e.buttons,105(pointerMoveData) => { /* Intentional empty */ },106() => {107this._pointerdownRepeatTimer.cancel();108this._pointerdownScheduleRepeatTimer.cancel();109}110);111112e.preventDefault();113}114}115116117