+++ /dev/null
-/**
- * Copyright (c) 2017 The xterm.js authors. All rights reserved.
- * @license MIT
- */
-
-import { IRenderDimensions } from 'browser/renderer/Types';
-import { BaseRenderLayer } from 'browser/renderer/BaseRenderLayer';
-import { IColorSet } from 'browser/Types';
-import { IBufferService, IOptionsService } from 'common/services/Services';
-
-interface ISelectionState {
- start?: [number, number];
- end?: [number, number];
- columnSelectMode?: boolean;
- ydisp?: number;
-}
-
-export class SelectionRenderLayer extends BaseRenderLayer {
- private _state!: ISelectionState;
-
- constructor(
- container: HTMLElement,
- zIndex: number,
- colors: IColorSet,
- rendererId: number,
- readonly bufferService: IBufferService,
- readonly optionsService: IOptionsService
- ) {
- super(container, 'selection', zIndex, true, colors, rendererId, bufferService, optionsService);
- this._clearState();
- }
-
- private _clearState(): void {
- this._state = {
- start: undefined,
- end: undefined,
- columnSelectMode: undefined,
- ydisp: undefined
- };
- }
-
- public resize(dim: IRenderDimensions): void {
- super.resize(dim);
- // Resizing the canvas discards the contents of the canvas so clear state
- this._clearState();
- }
-
- public reset(): void {
- if (this._state.start && this._state.end) {
- this._clearState();
- this._clearAll();
- }
- }
-
- public onSelectionChanged(start: [number, number], end: [number, number], columnSelectMode: boolean): void {
- // Selection has not changed
- if (!this._didStateChange(start, end, columnSelectMode, this._bufferService.buffer.ydisp)) {
- return;
- }
-
- // Remove all selections
- this._clearAll();
-
- // Selection does not exist
- if (!start || !end) {
- this._clearState();
- return;
- }
-
- // Translate from buffer position to viewport position
- const viewportStartRow = start[1] - this._bufferService.buffer.ydisp;
- const viewportEndRow = end[1] - this._bufferService.buffer.ydisp;
- const viewportCappedStartRow = Math.max(viewportStartRow, 0);
- const viewportCappedEndRow = Math.min(viewportEndRow, this._bufferService.rows - 1);
-
- // No need to draw the selection
- if (viewportCappedStartRow >= this._bufferService.rows || viewportCappedEndRow < 0) {
- return;
- }
-
- this._ctx.fillStyle = this._colors.selection.css;
-
- if (columnSelectMode) {
- const startCol = start[0];
- const width = end[0] - startCol;
- const height = viewportCappedEndRow - viewportCappedStartRow + 1;
- this._fillCells(startCol, viewportCappedStartRow, width, height);
- } else {
- // Draw first row
- const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;
- const startRowEndCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : this._bufferService.cols;
- this._fillCells(startCol, viewportCappedStartRow, startRowEndCol - startCol, 1);
-
- // Draw middle rows
- const middleRowsCount = Math.max(viewportCappedEndRow - viewportCappedStartRow - 1, 0);
- this._fillCells(0, viewportCappedStartRow + 1, this._bufferService.cols, middleRowsCount);
-
- // Draw final row
- if (viewportCappedStartRow !== viewportCappedEndRow) {
- // Only draw viewportEndRow if it's not the same as viewportStartRow
- const endCol = viewportEndRow === viewportCappedEndRow ? end[0] : this._bufferService.cols;
- this._fillCells(0, viewportCappedEndRow, endCol, 1);
- }
- }
-
- // Save state for next render
- this._state.start = [start[0], start[1]];
- this._state.end = [end[0], end[1]];
- this._state.columnSelectMode = columnSelectMode;
- this._state.ydisp = this._bufferService.buffer.ydisp;
- }
-
- private _didStateChange(start: [number, number], end: [number, number], columnSelectMode: boolean, ydisp: number): boolean {
- return !this._areCoordinatesEqual(start, this._state.start) ||
- !this._areCoordinatesEqual(end, this._state.end) ||
- columnSelectMode !== this._state.columnSelectMode ||
- ydisp !== this._state.ydisp;
- }
-
- private _areCoordinatesEqual(coord1: [number, number] | undefined, coord2: [number, number] | undefined): boolean {
- if (!coord1 || !coord2) {
- return false;
- }
-
- return coord1[0] === coord2[0] && coord1[1] === coord2[1];
- }
-}