From ad59db9a8a52d448f173304c5a22cac944301264 Mon Sep 17 00:00:00 2001 From: meganrogge Date: Wed, 2 Feb 2022 22:33:05 -0600 Subject: [PATCH] try --- demo/style.css | 6 --- src/browser/Terminal.ts | 28 ++++++++++++- src/browser/services/DecorationsService.ts | 47 +++++++++++++++------- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/demo/style.css b/demo/style.css index 1abcf08d..cebd08e0 100644 --- a/demo/style.css +++ b/demo/style.css @@ -76,12 +76,6 @@ pre { background-color: #ddd; } -.button-buffer-decoration:hover, -.button-buffer-decoration:focus { - box-shadow: 0 0.5em 0.5em -0.4em var(--hover); - transform: translateY(-0.25em); -} - /* Create an active/current tablink class */ .tab button.active { background-color: #ccc; diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 7757e0b7..e9259266 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -569,8 +569,11 @@ export class Terminal extends CoreTerminal implements ITerminal { this.register(this._onScroll.event(ev => { this.viewport!.syncScrollArea(); this._selectionService!.refresh(); + this._decorationsService!.refresh(ev.position); + })); + this.register(addDisposableDomListener(this._viewportElement, 'scroll', () => { + this._selectionService!.refresh(); })); - this.register(addDisposableDomListener(this._viewportElement, 'scroll', () => this._selectionService!.refresh())); this._mouseZoneManager = this._instantiationService.createInstance(MouseZoneManager, this.element, this.screenElement); this.register(this._mouseZoneManager); @@ -1003,7 +1006,28 @@ export class Terminal extends CoreTerminal implements ITerminal { } public registerDecoration(decorationOptions: IBufferDecorationOptions): IDecoration | undefined { - return this._decorationsService?.registerDecoration(decorationOptions); + if (!this._renderService) { + throw new Error('cannot register a decoration without a render service'); + } + + if (!this._decorationsService) { + throw new Error('cannot register a decoration without a decorations service'); + } + + const { actualCellWidth, actualCellHeight } = this._renderService.dimensions; + if (actualCellWidth) { + decorationOptions.width = decorationOptions.width ? decorationOptions.width * actualCellWidth : actualCellWidth; + } else { + throw new Error('unknown cell width'); + } + + if (actualCellHeight) { + decorationOptions.height = decorationOptions.height ? decorationOptions.height * actualCellHeight : actualCellHeight; + } else { + throw new Error('unknown cell height'); + } + + return this._decorationsService.registerDecoration(decorationOptions, actualCellWidth, actualCellHeight); } /** * Gets whether the terminal has an active selection. diff --git a/src/browser/services/DecorationsService.ts b/src/browser/services/DecorationsService.ts index d168e39b..eb1b766b 100644 --- a/src/browser/services/DecorationsService.ts +++ b/src/browser/services/DecorationsService.ts @@ -3,15 +3,16 @@ * @license MIT */ -import { IRenderDimensions } from 'browser/renderer/Types'; import { EventEmitter, IEvent } from 'common/EventEmitter'; import { Disposable } from 'common/Lifecycle'; import { createDecorator } from 'common/services/ServiceRegistry'; +import { IBufferService } from 'common/services/Services'; import { IDisposable } from 'common/Types'; import { IBufferDecorationOptions, IDecoration, IMarker } from 'xterm'; export interface IDecorationsService extends IDisposable { - registerDecoration(decorationOptions: IBufferDecorationOptions): IDecoration | undefined; + registerDecoration(decorationOptions: IBufferDecorationOptions, cellWidth: number, cellHeight: number): IDecoration | undefined; + refresh(y: number): void; } const enum DefaultButton { @@ -19,14 +20,34 @@ const enum DefaultButton { } export class DecorationsService extends Disposable implements IDecorationsService { - constructor(private readonly _screenElement: HTMLElement) { + private _decorations: BufferDecoration[] = []; + private _cellWidth: number = 0; + private _cellHeight: number = 0; + constructor(private readonly _screenElement: HTMLElement, @IBufferService private readonly _bufferService: IBufferService) { super(); } - public registerDecoration(decorationOptions: IBufferDecorationOptions): IDecoration | undefined { + public registerDecoration(decorationOptions: IBufferDecorationOptions, cellWidth: number, cellHeight: number): IDecoration | undefined { if (decorationOptions.marker.isDisposed) { return undefined; } - return new BufferDecoration(decorationOptions, this._screenElement); + this._cellWidth = cellWidth; + this._cellHeight = cellHeight; + const bufferDecoration = new BufferDecoration(decorationOptions, this._screenElement, this._bufferService.buffers.active.y!); + this._decorations.push(bufferDecoration); + return bufferDecoration; + } + + public refresh(y: number): void { + for (const decoration of this._decorations) { + if (decoration.marker.line < y) { + console.log(decoration.marker.line, y); + console.log('scrolled', y); + console.log('y', this._bufferService.buffers.active.y); + console.log('ybase', this._bufferService.buffers.active.ybase); + decoration.element.style.bottom = `${(this._bufferService.buffers.active.ybase - decoration.marker.line)*this._cellHeight}px`; + decoration.element.style.top = ''; + } + } } @@ -51,25 +72,21 @@ class BufferDecoration extends Disposable implements IDecoration { constructor( decorationOptions: IBufferDecorationOptions, - private readonly _container: HTMLElement + private readonly _container: HTMLElement, + y: number ) { super(); this._marker = decorationOptions.marker; - const color = DefaultButton.COLOR; this._element = document.createElement('div'); - this._element.classList.add('button-buffer-decoration'); - this._element.id = 'button-buffer-decoration-' + this._id; - this._element.style.background = color; - this._element.style.width = '32px'; - this._element.style.height = '32px'; - this._element.style.borderRadius = '64px'; - this._element.style.border = `4px solid white`; + this._element.style.width = `${decorationOptions.width}px`; + this._element.style.height = `${decorationOptions.height}px`; this._element.style.zIndex = '6'; + this._element.style.top = `${this._marker.line*decorationOptions.height!}px`; this._element.style.position = 'absolute'; if (decorationOptions.anchor === 'right') { this._element.style.right = decorationOptions.x ? `${decorationOptions.x}px` : '5px'; } else { - this._element.style.right = decorationOptions.x ? `${decorationOptions.x}px` : '5px'; + this._element.style.left = decorationOptions.x ? `${decorationOptions.x}px` : '5px'; } if (this._container && this._element) { this._container.append(this._element);