mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge render layer interface types
This commit is contained in:
+1
-4
@@ -761,10 +761,7 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
|
||||
|
||||
this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure);
|
||||
this.renderer = new Renderer(this);
|
||||
this.on('cursormove', () => {
|
||||
console.log('cursormove fired');
|
||||
this.renderer.onCursorMove();
|
||||
});
|
||||
this.on('cursormove', () => this.renderer.onCursorMove());
|
||||
this.on('resize', () => this.renderer.onResize(this.cols, this.rows));
|
||||
this.charMeasure.on('charsizechanged', () => {
|
||||
this.renderer.onCharSizeChanged(this.charMeasure.width, this.charMeasure.height);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { IDataRenderLayer, IColorSet } from './Interfaces';
|
||||
import { IColorSet } from './Interfaces';
|
||||
import { IBuffer, ICharMeasure, ITerminal } from '../Interfaces';
|
||||
import { CHAR_DATA_ATTR_INDEX } from '../Buffer';
|
||||
import { GridCache } from './GridCache';
|
||||
import { FLAGS } from './Types';
|
||||
import { BaseRenderLayer } from './BaseRenderLayer';
|
||||
|
||||
export class BackgroundRenderLayer extends BaseRenderLayer implements IDataRenderLayer {
|
||||
export class BackgroundRenderLayer extends BaseRenderLayer {
|
||||
private _state: GridCache<number>;
|
||||
|
||||
constructor(container: HTMLElement, zIndex: number, colors: IColorSet) {
|
||||
@@ -23,7 +23,7 @@ export class BackgroundRenderLayer extends BaseRenderLayer implements IDataRende
|
||||
this.clearAll();
|
||||
}
|
||||
|
||||
public render(terminal: ITerminal, startRow: number, endRow: number): void {
|
||||
public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {
|
||||
for (let y = startRow; y <= endRow; y++) {
|
||||
let row = y + terminal.buffer.ydisp;
|
||||
let line = terminal.buffer.lines.get(row);
|
||||
|
||||
@@ -29,6 +29,8 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
||||
// TODO: Should this do anything?
|
||||
public onOptionsChanged(terminal: ITerminal): void {}
|
||||
public onCursorMove(terminal: ITerminal): void {}
|
||||
public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {}
|
||||
public onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void {}
|
||||
|
||||
public onThemeChanged(terminal: ITerminal, colorSet: IColorSet): void {
|
||||
this._charAtlas = null;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IDataRenderLayer, IColorSet } from './Interfaces';
|
||||
import { IColorSet } from './Interfaces';
|
||||
import { IBuffer, ICharMeasure, ITerminal, ITerminalOptions } from '../Interfaces';
|
||||
import { CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer';
|
||||
import { GridCache } from './GridCache';
|
||||
@@ -12,7 +12,7 @@ import { COLOR_CODES } from './ColorManager';
|
||||
*/
|
||||
const BLINK_INTERVAL = 600;
|
||||
|
||||
export class CursorRenderLayer extends BaseRenderLayer implements IDataRenderLayer {
|
||||
export class CursorRenderLayer extends BaseRenderLayer {
|
||||
private _state: [number, number];
|
||||
private _cursorRenderers: {[key: string]: (terminal: ITerminal, x: number, y: number, charData: CharData) => void};
|
||||
private _cursorBlinkStateManager: CursorBlinkStateManager;
|
||||
@@ -62,7 +62,7 @@ export class CursorRenderLayer extends BaseRenderLayer implements IDataRenderLay
|
||||
}
|
||||
}
|
||||
|
||||
public render(terminal: ITerminal, startRow: number, endRow: number): void {
|
||||
public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {
|
||||
// Only render if the animation frame is not active
|
||||
if (!this._cursorBlinkStateManager) {
|
||||
this._render(terminal, false);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IDataRenderLayer, IColorSet } from './Interfaces';
|
||||
import { IColorSet } from './Interfaces';
|
||||
import { IBuffer, ICharMeasure, ITerminal } from '../Interfaces';
|
||||
import { CHAR_DATA_ATTR_INDEX, CHAR_DATA_CODE_INDEX, CHAR_DATA_CHAR_INDEX, CHAR_DATA_WIDTH_INDEX } from '../Buffer';
|
||||
import { FLAGS } from './Types';
|
||||
@@ -6,7 +6,7 @@ import { GridCache } from './GridCache';
|
||||
import { CharData } from '../Types';
|
||||
import { BaseRenderLayer } from './BaseRenderLayer';
|
||||
|
||||
export class ForegroundRenderLayer extends BaseRenderLayer implements IDataRenderLayer {
|
||||
export class ForegroundRenderLayer extends BaseRenderLayer {
|
||||
private _state: GridCache<CharData>;
|
||||
|
||||
constructor(container: HTMLElement, zIndex: number, colors: IColorSet) {
|
||||
@@ -24,7 +24,7 @@ export class ForegroundRenderLayer extends BaseRenderLayer implements IDataRende
|
||||
this.clearAll();
|
||||
}
|
||||
|
||||
public render(terminal: ITerminal, startRow: number, endRow: number): void {
|
||||
public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {
|
||||
// TODO: Ensure that the render is eventually performed
|
||||
// Don't bother render until the atlas bitmap is ready
|
||||
// TODO: Move this to BaseRenderLayer?
|
||||
|
||||
@@ -4,6 +4,8 @@ export interface IRenderLayer {
|
||||
onCursorMove(terminal: ITerminal): void;
|
||||
onOptionsChanged(terminal: ITerminal): void;
|
||||
onThemeChanged(terminal: ITerminal, colorSet: IColorSet): void;
|
||||
onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void;
|
||||
onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void;
|
||||
|
||||
/**
|
||||
* Resize the render layer.
|
||||
@@ -16,20 +18,6 @@ export interface IRenderLayer {
|
||||
reset(terminal: ITerminal): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* A render layer that renders when there is a data change.
|
||||
*/
|
||||
export interface IDataRenderLayer extends IRenderLayer {
|
||||
render(terminal: ITerminal, startRow: number, endRow: number): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* A render layer that renders when there is a selection change.
|
||||
*/
|
||||
export interface ISelectionRenderLayer extends IRenderLayer {
|
||||
render(terminal: ITerminal, start: [number, number], end: [number, number]): void;
|
||||
}
|
||||
|
||||
|
||||
export interface IColorSet {
|
||||
foreground: string;
|
||||
|
||||
+15
-48
@@ -6,48 +6,41 @@ import { ITerminal, ITheme } from '../Interfaces';
|
||||
import { DomElementObjectPool } from '../utils/DomElementObjectPool';
|
||||
import { CHAR_DATA_WIDTH_INDEX, CHAR_DATA_CHAR_INDEX } from '../Buffer';
|
||||
import { createBackgroundFillData } from './Canvas';
|
||||
import { IDataRenderLayer, ISelectionRenderLayer } from './Interfaces';
|
||||
import { BackgroundRenderLayer } from './BackgroundRenderLayer';
|
||||
import { ForegroundRenderLayer } from './ForegroundRenderLayer';
|
||||
import { SelectionRenderLayer } from './SelectionRenderLayer';
|
||||
import { CursorRenderLayer } from './CursorRenderLayer';
|
||||
import { ColorManager } from './ColorManager';
|
||||
import { BaseRenderLayer } from './BaseRenderLayer';
|
||||
import { IRenderLayer } from './Interfaces';
|
||||
|
||||
export class Renderer {
|
||||
/** A queue of the rows to be refreshed */
|
||||
private _refreshRowsQueue: {start: number, end: number}[] = [];
|
||||
private _refreshAnimationFrame = null;
|
||||
|
||||
private _dataRenderLayers: IDataRenderLayer[];
|
||||
private _selectionRenderLayers: ISelectionRenderLayer[];
|
||||
private _renderLayers: IRenderLayer[];
|
||||
|
||||
private _colorManager: ColorManager;
|
||||
|
||||
constructor(private _terminal: ITerminal) {
|
||||
this._colorManager = new ColorManager();
|
||||
this._dataRenderLayers = [
|
||||
this._renderLayers = [
|
||||
new BackgroundRenderLayer(this._terminal.element, 0, this._colorManager.colors),
|
||||
new SelectionRenderLayer(this._terminal.element, 1, this._colorManager.colors),
|
||||
new ForegroundRenderLayer(this._terminal.element, 2, this._colorManager.colors),
|
||||
new CursorRenderLayer(this._terminal.element, 3, this._colorManager.colors)
|
||||
];
|
||||
this._selectionRenderLayers = [
|
||||
new SelectionRenderLayer(this._terminal.element, 1, this._colorManager.colors)
|
||||
];
|
||||
}
|
||||
|
||||
public setTheme(theme: ITheme): void {
|
||||
console.log('setTheme');
|
||||
this._colorManager.setTheme(theme);
|
||||
// Clear layers and force a full render
|
||||
for (let i = 0; i < this._dataRenderLayers.length; i++) {
|
||||
this._dataRenderLayers[i].onThemeChanged(this._terminal, this._colorManager.colors);
|
||||
this._dataRenderLayers[i].reset(this._terminal);
|
||||
}
|
||||
for (let i = 0; i < this._selectionRenderLayers.length; i++) {
|
||||
this._selectionRenderLayers[i].onThemeChanged(this._terminal, this._colorManager.colors);
|
||||
this._selectionRenderLayers[i].reset(this._terminal);
|
||||
}
|
||||
this._renderLayers.forEach(l => {
|
||||
l.onThemeChanged(this._terminal, this._colorManager.colors);
|
||||
l.reset(this._terminal);
|
||||
});
|
||||
|
||||
// TODO: This is currently done for every single terminal, but it's static so it's wasting time
|
||||
this._terminal.refresh(0, this._terminal.rows - 1);
|
||||
@@ -56,53 +49,29 @@ export class Renderer {
|
||||
public onResize(cols: number, rows: number): void {
|
||||
const width = this._terminal.charMeasure.width * this._terminal.cols;
|
||||
const height = this._terminal.charMeasure.height * this._terminal.rows;
|
||||
for (let i = 0; i < this._dataRenderLayers.length; i++) {
|
||||
this._dataRenderLayers[i].resize(this._terminal, width, height, false);
|
||||
}
|
||||
this._renderLayers.forEach(l => l.resize(this._terminal, width, height, false));
|
||||
}
|
||||
|
||||
public onCharSizeChanged(charWidth: number, charHeight: number): void {
|
||||
const width = charWidth * this._terminal.cols;
|
||||
const height = charHeight * this._terminal.rows;
|
||||
for (let i = 0; i < this._dataRenderLayers.length; i++) {
|
||||
this._dataRenderLayers[i].resize(this._terminal, width, height, true);
|
||||
}
|
||||
for (let i = 0; i < this._selectionRenderLayers.length; i++) {
|
||||
this._selectionRenderLayers[i].resize(this._terminal, width, height, true);
|
||||
}
|
||||
this._renderLayers.forEach(l => l.resize(this._terminal, width, height, true));
|
||||
}
|
||||
|
||||
public onSelectionChanged(start: [number, number], end: [number, number]): void {
|
||||
for (let i = 0; i < this._selectionRenderLayers.length; i++) {
|
||||
this._selectionRenderLayers[i].render(this._terminal, start, end);
|
||||
}
|
||||
this._renderLayers.forEach(l => l.onSelectionChanged(this._terminal, start, end));
|
||||
}
|
||||
|
||||
public onCursorMove(): void {
|
||||
for (let i = 0; i < this._dataRenderLayers.length; i++) {
|
||||
this._dataRenderLayers[i].onCursorMove(this._terminal);
|
||||
}
|
||||
for (let i = 0; i < this._selectionRenderLayers.length; i++) {
|
||||
this._selectionRenderLayers[i].onCursorMove(this._terminal);
|
||||
}
|
||||
this._renderLayers.forEach(l => l.onCursorMove(this._terminal));
|
||||
}
|
||||
|
||||
public onOptionsChanged(): void {
|
||||
for (let i = 0; i < this._dataRenderLayers.length; i++) {
|
||||
this._dataRenderLayers[i].onOptionsChanged(this._terminal);
|
||||
}
|
||||
for (let i = 0; i < this._selectionRenderLayers.length; i++) {
|
||||
this._selectionRenderLayers[i].onOptionsChanged(this._terminal);
|
||||
}
|
||||
this._renderLayers.forEach(l => l.onOptionsChanged(this._terminal));
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
for (let i = 0; i < this._dataRenderLayers.length; i++) {
|
||||
this._dataRenderLayers[i].reset(this._terminal);
|
||||
}
|
||||
for (let i = 0; i < this._selectionRenderLayers.length; i++) {
|
||||
this._selectionRenderLayers[i].reset(this._terminal);
|
||||
}
|
||||
this._renderLayers.forEach(l => l.reset(this._terminal));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,9 +115,7 @@ export class Renderer {
|
||||
this._refreshAnimationFrame = null;
|
||||
|
||||
// Render
|
||||
for (let i = 0; i < this._dataRenderLayers.length; i++) {
|
||||
this._dataRenderLayers[i].render(this._terminal, start, end);
|
||||
}
|
||||
this._renderLayers.forEach(l => l.onGridChanged(this._terminal, start, end));
|
||||
this._terminal.emit('refresh', {start, end});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { ISelectionRenderLayer, IColorSet } from './Interfaces';
|
||||
import { IColorSet } from './Interfaces';
|
||||
import { IBuffer, ICharMeasure, ITerminal } from '../Interfaces';
|
||||
import { CHAR_DATA_ATTR_INDEX } from '../Buffer';
|
||||
import { GridCache } from './GridCache';
|
||||
import { FLAGS } from './Types';
|
||||
import { BaseRenderLayer } from './BaseRenderLayer';
|
||||
|
||||
export class SelectionRenderLayer extends BaseRenderLayer implements ISelectionRenderLayer {
|
||||
export class SelectionRenderLayer extends BaseRenderLayer {
|
||||
private _state: {start: [number, number], end: [number, number]};
|
||||
|
||||
constructor(container: HTMLElement, zIndex: number, colors: IColorSet) {
|
||||
@@ -26,7 +26,7 @@ export class SelectionRenderLayer extends BaseRenderLayer implements ISelectionR
|
||||
}
|
||||
}
|
||||
|
||||
public render(terminal: ITerminal, start: [number, number], end: [number, number]): void {
|
||||
public onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number]): void {
|
||||
// Selection has not changed
|
||||
if (this._state.start === start || this._state.end === end) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user