mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Basic fetching of coordinates
This commit is contained in:
+1
-4
@@ -53,14 +53,11 @@ export class EventEmitter {
|
||||
return this.on(type, on);
|
||||
}
|
||||
|
||||
public emit(type): void {
|
||||
public emit(type: string, ...args: any[]): void {
|
||||
if (!this._events[type]) {
|
||||
return;
|
||||
}
|
||||
|
||||
let args = Array.prototype.slice.call(arguments, 1);
|
||||
let obj = this._events[type];
|
||||
|
||||
for (let i = 0; i < obj.length; i++) {
|
||||
obj[i].apply(this, args);
|
||||
}
|
||||
|
||||
+6
-5
@@ -471,6 +471,8 @@ export class Parser {
|
||||
case ParserState.DCS:
|
||||
if (ch === C0.ESC || ch === C0.BEL) {
|
||||
if (ch === C0.ESC) this._position++;
|
||||
let pt;
|
||||
let valid;
|
||||
|
||||
switch (this._terminal.prefix) {
|
||||
// User-Defined Keys (DECUDK).
|
||||
@@ -480,8 +482,8 @@ export class Parser {
|
||||
// Request Status String (DECRQSS).
|
||||
// test: echo -e '\eP$q"p\e\\'
|
||||
case '$q':
|
||||
let pt = this._terminal.currentParam
|
||||
, valid = false;
|
||||
pt = this._terminal.currentParam;
|
||||
valid = false;
|
||||
|
||||
switch (pt) {
|
||||
// DECSCA
|
||||
@@ -526,9 +528,8 @@ export class Parser {
|
||||
// This can cause a small glitch in vim.
|
||||
// test: echo -ne '\eP+q6b64\e\\'
|
||||
case '+q':
|
||||
// TODO: Don't declare pt twice
|
||||
/*let*/ pt = this._terminal.currentParam
|
||||
, valid = false;
|
||||
pt = this._terminal.currentParam;
|
||||
valid = false;
|
||||
|
||||
this._terminal.send(C0.ESC + 'P' + +valid + '+r' + pt + C0.ESC + '\\');
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { CharMeasure } from './utils/CharMeasure';
|
||||
import { CircularList } from './utils/CircularList';
|
||||
import * as Mouse from './utils/Mouse';
|
||||
|
||||
export class SelectionManager {
|
||||
private _selectionStart: [number, number];
|
||||
private _selectionEnd: [number, number];
|
||||
|
||||
private _buffer: CircularList<any>;
|
||||
private _rowContainer: HTMLElement;
|
||||
private _charMeasure: CharMeasure;
|
||||
|
||||
private _mouseMoveListener: EventListener;
|
||||
|
||||
constructor(buffer: CircularList<any>, rowContainer: HTMLElement, charMeasure: CharMeasure) {
|
||||
this._rowContainer = rowContainer;
|
||||
this._buffer = buffer;
|
||||
this._charMeasure = charMeasure;
|
||||
this._attachListeners();
|
||||
}
|
||||
|
||||
private _attachListeners() {
|
||||
this._mouseMoveListener = event => this._onMouseMove(<MouseEvent>event);
|
||||
|
||||
this._buffer.on('trim', amount => this._onTrim(amount));
|
||||
this._rowContainer.addEventListener('mousedown', event => this._onMouseDown(event));
|
||||
this._rowContainer.addEventListener('mouseup', event => this._onMouseUp(event));
|
||||
}
|
||||
|
||||
public get selectionText(): string {
|
||||
if (!this._selectionStart || !this._selectionEnd) {
|
||||
return null;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
private _onTrim(amount: number) {
|
||||
console.log('trimmed: ' + amount);
|
||||
}
|
||||
|
||||
private _onMouseDown(event: MouseEvent) {
|
||||
this._selectionStart = Mouse.getCoords(event, this._rowContainer, this._charMeasure);
|
||||
if (this._selectionStart) {
|
||||
this._rowContainer.addEventListener('mousemove', this._mouseMoveListener);
|
||||
}
|
||||
}
|
||||
|
||||
private _onMouseMove(event: MouseEvent) {
|
||||
this._selectionEnd = Mouse.getCoords(event, this._rowContainer, this._charMeasure);
|
||||
}
|
||||
|
||||
private _onMouseUp(event: MouseEvent) {
|
||||
console.log('mouseup');
|
||||
console.log('start', this._selectionStart);
|
||||
console.log('end', this._selectionEnd);
|
||||
if (!this._selectionStart) {
|
||||
return;
|
||||
}
|
||||
this._rowContainer.removeEventListener('mousemove', this._mouseMoveListener);
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,15 @@
|
||||
* @module xterm/utils/CircularList
|
||||
* @license MIT
|
||||
*/
|
||||
export class CircularList<T> {
|
||||
import { EventEmitter } from '../EventEmitter';
|
||||
|
||||
export class CircularList<T> extends EventEmitter {
|
||||
private _array: T[];
|
||||
private _startIndex: number;
|
||||
private _length: number;
|
||||
|
||||
constructor(maxLength: number) {
|
||||
super();
|
||||
this._array = new Array<T>(maxLength);
|
||||
this._startIndex = 0;
|
||||
this._length = 0;
|
||||
@@ -83,6 +86,7 @@ export class CircularList<T> {
|
||||
if (this._startIndex === this.maxLength) {
|
||||
this._startIndex = 0;
|
||||
}
|
||||
this.emit('trim', 1);
|
||||
} else {
|
||||
this._length++;
|
||||
}
|
||||
@@ -121,8 +125,10 @@ export class CircularList<T> {
|
||||
}
|
||||
|
||||
if (this._length + items.length > this.maxLength) {
|
||||
this._startIndex += (this._length + items.length) - this.maxLength;
|
||||
const countToTrim = (this._length + items.length) - this.maxLength;
|
||||
this._startIndex += countToTrim;
|
||||
this._length = this.maxLength;
|
||||
this.emit('trim', countToTrim);
|
||||
} else {
|
||||
this._length += items.length;
|
||||
}
|
||||
@@ -139,6 +145,7 @@ export class CircularList<T> {
|
||||
}
|
||||
this._startIndex += count;
|
||||
this._length -= count;
|
||||
this.emit('trim', count);
|
||||
}
|
||||
|
||||
public shiftElements(start: number, count: number, offset: number): void {
|
||||
@@ -162,6 +169,7 @@ export class CircularList<T> {
|
||||
while (this._length > this.maxLength) {
|
||||
this._length--;
|
||||
this._startIndex++;
|
||||
this.emit('trim', 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { CharMeasure } from './CharMeasure';
|
||||
|
||||
export function getCoords(event: MouseEvent, rowContainer: HTMLElement, charMeasure: CharMeasure): [number, number] {
|
||||
// ignore browsers without pageX for now
|
||||
if (event.pageX == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let x = event.pageX;
|
||||
let y = event.pageY;
|
||||
let el = rowContainer;
|
||||
|
||||
// should probably check offsetParent
|
||||
// but this is more portable
|
||||
while (el && el !== self.document.documentElement) {
|
||||
x -= el.offsetLeft;
|
||||
y -= el.offsetTop;
|
||||
el = 'offsetParent' in el ? <HTMLElement>el.offsetParent : <HTMLElement>el.parentElement;
|
||||
}
|
||||
|
||||
// convert to cols/rows
|
||||
x = Math.ceil(x / charMeasure.width);
|
||||
y = Math.ceil(y / charMeasure.height);
|
||||
|
||||
return [x, y];
|
||||
}
|
||||
@@ -41,6 +41,7 @@
|
||||
font-family: courier-new, courier, monospace;
|
||||
font-feature-settings: "liga" 0;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.terminal.focus,
|
||||
|
||||
+41
-38
@@ -20,9 +20,10 @@ import { InputHandler } from './InputHandler';
|
||||
import { Parser } from './Parser';
|
||||
import { Renderer } from './Renderer';
|
||||
import { Linkifier } from './Linkifier';
|
||||
import { SelectionManager } from './SelectionManager';
|
||||
import { CharMeasure } from './utils/CharMeasure';
|
||||
import * as Browser from './utils/Browser';
|
||||
import * as Keyboard from './utils/Keyboard';
|
||||
import * as Mouse from './utils/Mouse';
|
||||
import { CHARSETS } from './Charsets';
|
||||
|
||||
/**
|
||||
@@ -219,6 +220,7 @@ function Terminal(options) {
|
||||
this.parser = new Parser(this.inputHandler, this);
|
||||
// Reuse renderer if the Terminal is being recreated via a Terminal.reset call.
|
||||
this.renderer = this.renderer || null;
|
||||
this.selectionManager = this.selectionManager || null;
|
||||
this.linkifier = this.linkifier || new Linkifier();
|
||||
|
||||
// user input states
|
||||
@@ -689,6 +691,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);
|
||||
|
||||
// Setup loop that draws to screen
|
||||
this.refresh(0, this.rows - 1);
|
||||
@@ -787,7 +790,7 @@ Terminal.prototype.bindMouse = function() {
|
||||
button = getButton(ev);
|
||||
|
||||
// get mouse coordinates
|
||||
pos = getCoords(ev);
|
||||
pos = Mouse.getCoords(ev, this.rowContainer, this.charMeasure);
|
||||
if (!pos) return;
|
||||
|
||||
sendEvent(button, pos);
|
||||
@@ -815,7 +818,7 @@ Terminal.prototype.bindMouse = function() {
|
||||
var button = pressed
|
||||
, pos;
|
||||
|
||||
pos = getCoords(ev);
|
||||
pos = Mouse.getCoords(ev, this.rowContainer, this.charMeasure);
|
||||
if (!pos) return;
|
||||
|
||||
// buttons marked as motions
|
||||
@@ -991,48 +994,48 @@ Terminal.prototype.bindMouse = function() {
|
||||
}
|
||||
|
||||
// mouse coordinates measured in cols/rows
|
||||
function getCoords(ev) {
|
||||
var x, y, w, h, el;
|
||||
// function getCoords(ev) {
|
||||
// var x, y, w, h, el;
|
||||
|
||||
// ignore browsers without pageX for now
|
||||
if (ev.pageX == null) return;
|
||||
// // ignore browsers without pageX for now
|
||||
// if (ev.pageX == null) return;
|
||||
|
||||
x = ev.pageX;
|
||||
y = ev.pageY;
|
||||
el = self.element;
|
||||
// x = ev.pageX;
|
||||
// y = ev.pageY;
|
||||
// el = self.rowContainer;
|
||||
|
||||
// should probably check offsetParent
|
||||
// but this is more portable
|
||||
while (el && el !== self.document.documentElement) {
|
||||
x -= el.offsetLeft;
|
||||
y -= el.offsetTop;
|
||||
el = 'offsetParent' in el
|
||||
? el.offsetParent
|
||||
: el.parentNode;
|
||||
}
|
||||
// // should probably check offsetParent
|
||||
// // but this is more portable
|
||||
// while (el && el !== self.document.documentElement) {
|
||||
// x -= el.offsetLeft;
|
||||
// y -= el.offsetTop;
|
||||
// el = 'offsetParent' in el
|
||||
// ? el.offsetParent
|
||||
// : el.parentNode;
|
||||
// }
|
||||
|
||||
// convert to cols/rows
|
||||
x = Math.ceil(x / self.charMeasure.width);
|
||||
y = Math.ceil(y / self.charMeasure.height);
|
||||
// // convert to cols/rows
|
||||
// x = Math.ceil(x / self.charMeasure.width);
|
||||
// y = Math.ceil(y / self.charMeasure.height);
|
||||
|
||||
// be sure to avoid sending
|
||||
// bad positions to the program
|
||||
if (x < 0) x = 0;
|
||||
if (x > self.cols) x = self.cols;
|
||||
if (y < 0) y = 0;
|
||||
if (y > self.rows) y = self.rows;
|
||||
// // be sure to avoid sending
|
||||
// // bad positions to the program
|
||||
// if (x < 0) x = 0;
|
||||
// if (x > self.cols) x = self.cols;
|
||||
// if (y < 0) y = 0;
|
||||
// if (y > self.rows) y = self.rows;
|
||||
|
||||
// xterm sends raw bytes and
|
||||
// starts at 32 (SP) for each.
|
||||
x += 32;
|
||||
y += 32;
|
||||
// // xterm sends raw bytes and
|
||||
// // starts at 32 (SP) for each.
|
||||
// x += 32;
|
||||
// y += 32;
|
||||
|
||||
return {
|
||||
x: x,
|
||||
y: y,
|
||||
type: 'wheel'
|
||||
};
|
||||
}
|
||||
// return {
|
||||
// x: x,
|
||||
// y: y,
|
||||
// type: 'wheel'
|
||||
// };
|
||||
// }
|
||||
|
||||
on(el, 'mousedown', function(ev) {
|
||||
if (!self.mouseEvents) return;
|
||||
|
||||
Reference in New Issue
Block a user