Skip to content

Commit

Permalink
Basic fetching of coordinates
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyriar committed May 6, 2017
1 parent 64d3c08 commit 70fda99
Showing 7 changed files with 160 additions and 55 deletions.
5 changes: 1 addition & 4 deletions src/EventEmitter.ts
Original file line number Diff line number Diff line change
@@ -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);
}
11 changes: 6 additions & 5 deletions src/Parser.ts
Original file line number Diff line number Diff line change
@@ -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;
65 changes: 65 additions & 0 deletions src/SelectionManager.ts
Original file line number Diff line number Diff line change
@@ -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);
}
}
12 changes: 10 additions & 2 deletions src/utils/CircularList.ts
Original file line number Diff line number Diff line change
@@ -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 {
30 changes: 30 additions & 0 deletions src/utils/Mouse.ts
Original file line number Diff line number Diff line change
@@ -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];
}
1 change: 1 addition & 0 deletions src/xterm.css
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@
font-family: courier-new, courier, monospace;
font-feature-settings: "liga" 0;
position: relative;
user-select: none;
}

.terminal.focus,
91 changes: 47 additions & 44 deletions src/xterm.js
Original file line number Diff line number Diff line change
@@ -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;

// ignore browsers without pageX for now
if (ev.pageX == null) return;

x = ev.pageX;
y = ev.pageY;
el = self.element;

// 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;
}
// function getCoords(ev) {
// var x, y, w, h, el;

// // ignore browsers without pageX for now
// if (ev.pageX == null) return;

// 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;
// }

// 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;

// xterm sends raw bytes and
// starts at 32 (SP) for each.
x += 32;
y += 32;

return {
x: x,
y: y,
type: 'wheel'
};
}
// // 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;

// // xterm sends raw bytes and
// // starts at 32 (SP) for each.
// x += 32;
// y += 32;

// return {
// x: x,
// y: y,
// type: 'wheel'
// };
// }

on(el, 'mousedown', function(ev) {
if (!self.mouseEvents) return;

0 comments on commit 70fda99

Please sign in to comment.