Add events to TermScreen; use correct cursor

http-comm
cpsdqs 7 years ago committed by Ondřej Hruška
parent bee99b4c55
commit d57ed19c42
  1. 107
      html_orig/jssrc/term_screen.js
  2. 23
      html_orig/sass/pages/_term.scss

@ -97,6 +97,9 @@ class TermScreen {
this.mouseMode = { clicks: false, movement: false }; this.mouseMode = { clicks: false, movement: false };
// event listeners
this._listeners = {};
const self = this; const self = this;
this.window = new Proxy(this._window, { this.window = new Proxy(this._window, {
set (target, key, value, receiver) { set (target, key, value, receiver) {
@ -159,21 +162,68 @@ class TermScreen {
e.deltaY > 0 ? 1 : -1); e.deltaY > 0 ? 1 : -1);
// prevent page scrolling // prevent page scrolling
e.preventDefault() e.preventDefault();
} }
}); });
this.canvas.addEventListener('contextmenu', e => {
// prevent mouse keys getting stuck
e.preventDefault();
})
// bind ctrl+shift+c to copy // bind ctrl+shift+c to copy
key('⌃+⇧+c', e => { key('⌃+⇧+c', e => {
e.preventDefault(); e.preventDefault();
this.copySelectionToClipboard() this.copySelectionToClipboard()
}) });
}
on (event, listener) {
if (!this._listeners[event]) this._listeners[event] = [];
this._listeners[event].push({ listener });
}
once (event, listener) {
if (!this._listeners[event]) this._listeners[event] = [];
this._listeners[event].push({ listener, once: true });
}
off (event, listener) {
let listeners = this._listeners[event];
if (listeners) {
for (let i in listeners) {
if (listeners[i].listener === listener) {
listeners.splice(i, 1);
break;
}
}
}
}
emit (event, ...args) {
let listeners = this._listeners[event];
if (listeners) {
let remove = [];
for (let listener of listeners) {
try {
listener.listener(...args);
if (listener.once) remove.push(listener);
} catch (err) {
console.error(err);
}
}
// this needs to be done in this roundabout way because for loops
// do not like arrays with changing lengths
for (let listener of remove) {
listeners.splice(listeners.indexOf(listener), 1);
}
}
} }
get colors () { return this._colors } get colors () { return this._colors }
set colors (theme) { set colors (theme) {
this._colors = theme; this._colors = theme;
this.scheduleDraw() this.scheduleDraw();
} }
// schedule a draw in the next tick // schedule a draw in the next tick
@ -197,6 +247,15 @@ class TermScreen {
} }
} }
getCellSize () {
let charSize = this.getCharSize();
return {
width: Math.ceil(charSize.width * this.window.gridScaleX),
height: Math.ceil(charSize.height * this.window.gridScaleY)
}
}
updateSize () { updateSize () {
this._window.devicePixelRatio = window.devicePixelRatio || 1; this._window.devicePixelRatio = window.devicePixelRatio || 1;
@ -212,15 +271,12 @@ class TermScreen {
const { const {
width, height, devicePixelRatio, gridScaleX, gridScaleY width, height, devicePixelRatio, gridScaleX, gridScaleY
} = this.window; } = this.window;
const charSize = this.getCharSize(); const cellSize = this.getCellSize();
this.canvas.width = width * devicePixelRatio * charSize.width * gridScaleX; this.canvas.width = width * devicePixelRatio * cellSize.width;
this.canvas.style.width = `${Math.ceil(width * charSize.width * this.canvas.style.width = `${width * cellSize.width}px`;
gridScaleX)}px`; this.canvas.height = height * devicePixelRatio * cellSize.height;
this.canvas.height = height * devicePixelRatio * charSize.height * this.canvas.style.height = `${height * cellSize.height}px`
gridScaleY;
this.canvas.style.height = `${Math.ceil(height * charSize.height *
gridScaleY)}px`
} }
} }
@ -311,16 +367,20 @@ class TermScreen {
} }
screenToGrid (x, y) { screenToGrid (x, y) {
let charSize = this.getCharSize(); let cellSize = this.getCellSize();
let cellWidth = charSize.width * this.window.gridScaleX;
let cellHeight = charSize.height * this.window.gridScaleY;
return [ return [
Math.floor((x + cellWidth / 2) / cellWidth), Math.floor((x + cellSize.width / 2) / cellSize.width),
Math.floor(y / cellHeight) Math.floor(y / cellSize.height)
]; ];
} }
gridToScreen (x, y) {
let cellSize = this.getCellSize();
return [ x * cellSize.width, y * cellSize.height ];
}
drawCell ({ x, y, charSize, cellWidth, cellHeight, text, fg, bg, attrs }, drawCell ({ x, y, charSize, cellWidth, cellHeight, text, fg, bg, attrs },
compositeAbove = false) { compositeAbove = false) {
const ctx = this.ctx; const ctx = this.ctx;
@ -377,8 +437,7 @@ class TermScreen {
} = this.window; } = this.window;
const charSize = this.getCharSize(); const charSize = this.getCharSize();
const cellWidth = charSize.width * gridScaleX; const { width: cellWidth, height: cellHeight } = this.getCellSize();
const cellHeight = charSize.height * gridScaleY;
const screenWidth = width * cellWidth; const screenWidth = width * cellWidth;
const screenHeight = height * cellHeight; const screenHeight = height * cellHeight;
const screenLength = width * height; const screenLength = width * height;
@ -456,7 +515,10 @@ class TermScreen {
this.cursor.x = cursorX; this.cursor.x = cursorX;
this.cursor.y = cursorY; this.cursor.y = cursorY;
if (cursorMoved) this.resetCursorBlink(); if (cursorMoved) {
this.resetCursorBlink();
this.emit('cursor-moved');
}
// attributes // attributes
let attributes = parse2B(str, i); let attributes = parse2B(str, i);
@ -476,6 +538,7 @@ class TermScreen {
Input.setMouseMode(trackMouseClicks, trackMouseMovement); Input.setMouseMode(trackMouseClicks, trackMouseMovement);
this.selection.selectable = !trackMouseMovement; this.selection.selectable = !trackMouseMovement;
$(this.canvas).toggleClass('selectable', !trackMouseMovement);
this.mouseMode = { this.mouseMode = {
clicks: trackMouseClicks, clicks: trackMouseClicks,
movement: trackMouseMovement movement: trackMouseMovement
@ -545,7 +608,7 @@ class TermScreen {
} }
this.scheduleDraw(); this.scheduleDraw();
if (this.onload) this.onload() this.emit('load');
} }
/** Apply labels to buttons and screen title (leading T removed already) */ /** Apply labels to buttons and screen title (leading T removed already) */
@ -622,7 +685,7 @@ class TermScreen {
const Screen = new TermScreen(); const Screen = new TermScreen();
let didAddScreen = false; let didAddScreen = false;
Screen.onload = function () { Screen.on('load', () => {
if (didAddScreen) return; if (didAddScreen) return;
didAddScreen = true; didAddScreen = true;
qs('#screen').appendChild(Screen.canvas); qs('#screen').appendChild(Screen.canvas);
@ -631,4 +694,4 @@ Screen.onload = function () {
Screen.colors = themes[item.substr(6)] Screen.colors = themes[item.substr(6)]
} }
} }
}; });

@ -25,27 +25,8 @@ body.term {
font-size: 20px; // some font heights cause visual glitches with some font renderers. This should be configurable. font-size: 20px; // some font heights cause visual glitches with some font renderers. This should be configurable.
font-family: $screen-stack; font-family: $screen-stack;
span { canvas.selectable {
white-space: pre; cursor: text;
}
> span {
position: relative;
cursor: pointer;
&::before {
content: " ";
}
> span {
position:absolute;
left: 0;
z-index: 1;
}
}
&.noselect {
@include noselect();
} }
} }

Loading…
Cancel
Save