This commit is contained in:
meganrogge
2022-01-31 12:53:07 -06:00
parent 9b4801fb43
commit c5a0711f84
12 changed files with 135 additions and 118 deletions
+46 -33
View File
@@ -3,20 +3,19 @@
* @license MIT
*/
import { addDisposableDomListener } from 'browser/Lifecycle';
import { BaseRenderLayer } from 'browser/renderer/BaseRenderLayer';
import { IRequestRedrawEvent } from 'browser/renderer/Types';
import { IColorSet } from 'browser/Types';
import { Marker } from 'common/buffer/Marker';
import { EventEmitter, IEventEmitter } from 'common/EventEmitter';
import { Disposable } from 'common/Lifecycle';
import { IBufferService, IOptionsService } from 'common/services/Services';
import { IBufferDecorationOptions, IDecoration, IEvent, IGutterDecorationOptions } from 'xterm';
import { IBufferDecorationOptions, IDecoration, IEvent, IMarker } from 'xterm';
const enum DefaultButton {
COLOR = '#5DA5D5'
}
export class DecorationRenderLayer extends BaseRenderLayer {
private _decorations: IDecoration[] = [];
constructor(
container: HTMLElement,
zIndex: number,
@@ -27,33 +26,37 @@ export class DecorationRenderLayer extends BaseRenderLayer {
@IOptionsService optionsService: IOptionsService
) {
super(container, 'decoration', zIndex, true, colors, rendererId, bufferService, optionsService);
this.registerDecoration({ startMarker: new Marker(1), shape: 'button' });
// this.registerDecoration({ startMarker: new Marker(1), shape: 'button' });
}
public onGridChanged(startRow: number, endRow: number): void {
for (const decoration of this._decorations) {
(decoration as BufferDecoration).render();
}
}
public reset(): void {
}
public registerDecoration(decorationOptions: IBufferDecorationOptions | IGutterDecorationOptions): IDecoration {
if ('shape' in decorationOptions) {
return new BufferDecoration(decorationOptions, this._ctx.canvas);
public registerDecoration(decorationOptions: IBufferDecorationOptions): IDecoration | undefined {
if (decorationOptions.marker.isDisposed) {
return undefined;
}
throw new Error('Gutter decoration not yet implemented');
return new BufferDecoration(decorationOptions, this._ctx.canvas);
}
}
class BufferDecoration extends Disposable implements IDecoration {
private static _nextId = 1;
private _marker: IMarker;
private _element: HTMLElement | undefined;
private _id: number = BufferDecoration._nextId++;
private _line: number;
public isDisposed: boolean = false;
public get id(): number { return this._id; }
public get line(): number { return this._line; }
public get element(): HTMLElement { return this._element!; }
public get marker(): IMarker { return this._marker; }
private _onDispose = new EventEmitter<void>();
public get onDispose(): IEvent<void> { return this._onDispose.event; }
@@ -63,29 +66,29 @@ class BufferDecoration extends Disposable implements IDecoration {
constructor(
decorationOptions: IBufferDecorationOptions,
container: HTMLElement
private readonly _container: HTMLElement
) {
super();
this._line = decorationOptions.startMarker.line;
if (decorationOptions.shape === 'button') {
const color = decorationOptions.color || DefaultButton.COLOR;
this._element = document.createElement('menu');
this._element.classList.add('button-buffer-decoration');
this._element.id = 'button-buffer-decoration-' + this._id;
this._element.style.background = color;
this._element.style.width = '1px';
this._element.style.height = '32px';
this._element.style.borderRadius = '64px';
this._element.style.border = `4px solid white`;
this._element.style.zIndex = '6';
this._element.style.position = 'absolute';
this._element.style.top = '0px';
this._marker = decorationOptions.marker;
const color = DefaultButton.COLOR;
this._element = document.createElement('menu');
this._element.classList.add('button-buffer-decoration');
this._element.id = 'button-buffer-decoration-' + this._id;
this._element.style.background = color;
this._element.style.width = '1px';
this._element.style.height = '32px';
this._element.style.borderRadius = '64px';
this._element.style.border = `4px solid white`;
this._element.style.zIndex = '6';
this._element.style.position = 'absolute';
if (decorationOptions.anchor === 'right') {
this._element.style.right = '5px';
addDisposableDomListener(this._element, 'click', () => console.log('circle'));
container.parentElement!.append(this._element);
this._onRender.fire(this._element);
} else {
throw new Error('only shape that has been implemented so far is button');
this._element.style.left = '5px';
}
if (this._container.parentElement && this._element) {
this._container.parentElement.append(this._element);
}
}
@@ -94,9 +97,19 @@ class BufferDecoration extends Disposable implements IDecoration {
return;
}
this.isDisposed = true;
this._line = -1;
this._marker.dispose();
// Emit before super.dispose such that dispose listeners get a change to react
this._onDispose.fire();
super.dispose();
}
public render(): void {
if (!this._element) {
return;
}
if (this._container.parentElement && !this._container.parentElement.contains(this._element)) {
this._container.parentElement.append(this._element);
}
this._onRender.fire(this._element);
}
}
+2 -3
View File
@@ -15,7 +15,7 @@ import { IBufferService, IOptionsService, ICoreService, IInstantiationService }
import { removeTerminalFromCache } from 'browser/renderer/atlas/CharAtlasCache';
import { EventEmitter, IEvent } from 'common/EventEmitter';
import { DecorationRenderLayer } from 'browser/renderer/DecorationRenderLayer';
import { IBufferDecorationOptions, IGutterDecorationOptions, IDecoration } from 'xterm';
import { IBufferDecorationOptions, IDecoration } from 'xterm';
let nextRendererId = 1;
@@ -68,12 +68,11 @@ export class Renderer extends Disposable implements IRenderer {
this.onOptionsChanged();
}
public registerDecoration(decorationOptions: IBufferDecorationOptions | IGutterDecorationOptions): IDecoration {
public registerDecoration(decorationOptions: IBufferDecorationOptions): IDecoration | undefined {
const decorationLayer = this._renderLayers.find(l => l instanceof DecorationRenderLayer);
if (decorationLayer instanceof DecorationRenderLayer) {
return decorationLayer.registerDecoration(decorationOptions);
}
throw new Error('no decoration layer');
}
public dispose(): void {
+2 -2
View File
@@ -6,7 +6,7 @@
import { IDisposable } from 'common/Types';
import { IColorSet } from 'browser/Types';
import { IEvent } from 'common/EventEmitter';
import { IBufferDecorationOptions, IDecoration, IGutterDecorationOptions } from 'xterm';
import { IBufferDecorationOptions, IDecoration } from 'xterm';
export interface IRenderDimensions {
scaledCharWidth: number;
@@ -54,7 +54,7 @@ export interface IRenderer extends IDisposable {
clear(): void;
renderRows(start: number, end: number): void;
clearTextureAtlas?(): void;
registerDecoration(decorationOptions: IBufferDecorationOptions | IGutterDecorationOptions): IDecoration;
registerDecoration(decorationOptions: IBufferDecorationOptions): IDecoration | undefined;
}
export interface IRenderLayer extends IDisposable {
+2 -2
View File
@@ -14,7 +14,7 @@ import { EventEmitter, IEvent } from 'common/EventEmitter';
import { color } from 'browser/Color';
import { removeElementFromParent } from 'browser/Dom';
import { DecorationRenderLayer } from 'browser/renderer/DecorationRenderLayer';
import { IBufferDecorationOptions, IGutterDecorationOptions, IDecoration } from 'xterm';
import { IBufferDecorationOptions, IDecoration } from 'xterm';
const TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-';
const ROW_CONTAINER_CLASS = 'xterm-rows';
@@ -153,7 +153,7 @@ export class DomRenderer extends Disposable implements IRenderer {
this._injectCss();
}
public registerDecoration(decorationOptions: IBufferDecorationOptions | IGutterDecorationOptions): IDecoration {
public registerDecoration(decorationOptions: IBufferDecorationOptions): IDecoration {
// const decorationLayer = this._renderLayers.find(l => l instanceof DecorationRenderLayer);
// if (decorationLayer instanceof DecorationRenderLayer) {
// return decorationLayer.registerDecoration(decorationOptions);