From 207c4cf961c76f809166099fe548238a15cff4b8 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Fri, 19 May 2017 19:57:52 -0700 Subject: [PATCH] More work on SelectionManager --- src/SelectionManager.ts | 39 ++++++++++++++++++++++++++++++++++++++- src/utils/CircularList.ts | 1 + src/xterm.css | 12 ++++++++++++ src/xterm.js | 8 +++++++- 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 4d4533f2..3c99ef66 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -12,12 +12,14 @@ export class SelectionManager { private _buffer: CircularList; private _rowContainer: HTMLElement; + private _selectionContainer: HTMLElement; private _charMeasure: CharMeasure; private _mouseMoveListener: EventListener; - constructor(buffer: CircularList, rowContainer: HTMLElement, charMeasure: CharMeasure) { + constructor(buffer: CircularList, rowContainer: HTMLElement, selectionContainer: HTMLElement, charMeasure: CharMeasure) { this._rowContainer = rowContainer; + this._selectionContainer = selectionContainer; this._buffer = buffer; this._charMeasure = charMeasure; this._attachListeners(); @@ -38,10 +40,43 @@ export class SelectionManager { return ''; } + /** + * Redraws the selection. + */ + public refresh(): void { + console.log(`Selection: Start: (${this._selectionStart[0]}, ${this._selectionStart[1]}), End: (${this._selectionEnd[0]}, ${this._selectionEnd[1]})`); + this._selectionContainer.innerHTML = `


`; + } + + /** + * Handle the buffer being trimmed, adjust the selection position. + * @param amount The amount the buffer is being trimmed. + */ private _onTrim(amount: number) { // TODO: Somehow map the selection coordinates with the list that is constantly being trimmed // Maybe we need an ID in the CircularList that starts from 0 for the first entry and increments console.log('trimmed: ' + amount); + + // Adjust the selection position based on the trimmed amount. + this._selectionStart[0] -= amount; + this._selectionEnd[0] -= amount; + + // The selection has moved off the buffer, clear it. + if (this._selectionEnd[0] < 0) { + this._selectionStart = null; + this._selectionEnd = null; + this.refresh(); + return; + } + + // If the selection start is trimmed, ensure the start column is 0. + if (this._selectionStart[0] < 0) { + this._selectionStart[1] = 0; + } + + // Maybe SelectionManager could maintain it's own ID concept from 0 (top of + // buffer) to n (size of buffer). On trim just increment the selection if + // necessary. This would reduce complexity and potentially not need the } private _getMouseBufferCoords(event: MouseEvent) { @@ -58,6 +93,8 @@ export class SelectionManager { private _onMouseMove(event: MouseEvent) { this._selectionEnd = this._getMouseBufferCoords(event); + // TODO: Only draw here if the selection changes + this.refresh(); } private _onMouseUp(event: MouseEvent) { diff --git a/src/utils/CircularList.ts b/src/utils/CircularList.ts index bc693260..b6fafe7c 100644 --- a/src/utils/CircularList.ts +++ b/src/utils/CircularList.ts @@ -6,6 +6,7 @@ */ import { EventEmitter } from '../EventEmitter'; +// TODO: Do we need the ID here? interface ListEntry { id: number; value: T; diff --git a/src/xterm.css b/src/xterm.css index 8f78741d..54f53316 100644 --- a/src/xterm.css +++ b/src/xterm.css @@ -181,6 +181,18 @@ left: -9999em; } +.terminal .xterm-selection { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; +} + +.terminal .xterm-selection div { + background-color: #777; +} + /* * Determine default colors for xterm.js */ diff --git a/src/xterm.js b/src/xterm.js index 3b340b6f..8aa51b73 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -642,6 +642,12 @@ Terminal.prototype.open = function(parent, focus) { this.viewportScrollArea.classList.add('xterm-scroll-area'); this.viewportElement.appendChild(this.viewportScrollArea); + // Create the selection container. This needs to be added before the + // rowContainer as the selection must be below the text. + this.selectionContainer = document.createElement('div'); + this.selectionContainer.classList.add('xterm-selection'); + this.element.appendChild(this.selectionContainer); + // Create the container that will hold the lines of the terminal and then // produce the lines the lines. this.rowContainer = document.createElement('div'); @@ -691,7 +697,7 @@ Terminal.prototype.open = function(parent, focus) { this.viewport = new Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasure); this.renderer = new Renderer(this); - this.selectionManager = new SelectionManager(this.lines, this.rowContainer, this.charMeasure); + this.selectionManager = new SelectionManager(this.lines, this.rowContainer, this.selectionContainer, this.charMeasure); // Setup loop that draws to screen this.refresh(0, this.rows - 1);