Added a monochrome mode: ALT+M to toggle
TODO: Still needs a way to represent clickable text
This commit is contained in:
parent
819a29c8b6
commit
bb313f568a
|
@ -16,6 +16,7 @@ export default class FrameBuilder extends BaseBuilder{
|
||||||
// ID for element we place in the DOM to measure the size of a single monospace
|
// ID for element we place in the DOM to measure the size of a single monospace
|
||||||
// character.
|
// character.
|
||||||
this._measuring_box_id = 'browsh_em_measuring_box';
|
this._measuring_box_id = 'browsh_em_measuring_box';
|
||||||
|
this._is_graphics_mode = true;
|
||||||
this._setupInit();
|
this._setupInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +131,11 @@ export default class FrameBuilder extends BaseBuilder{
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleUserInput(input) {
|
_handleUserInput(input) {
|
||||||
|
this._handleSpecialKeys(input);
|
||||||
|
this._handleCharBasedKeys(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
_handleSpecialKeys(input) {
|
||||||
switch (input.key) {
|
switch (input.key) {
|
||||||
case 65517: // up arow
|
case 65517: // up arow
|
||||||
window.scrollBy(0, -20);
|
window.scrollBy(0, -20);
|
||||||
|
@ -156,6 +162,16 @@ export default class FrameBuilder extends BaseBuilder{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_handleCharBasedKeys(input) {
|
||||||
|
switch (input.char) {
|
||||||
|
case 'M':
|
||||||
|
if (input.mod === 1) {
|
||||||
|
this._is_graphics_mode = !this._is_graphics_mode;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_mouseAction(type, x, y) {
|
_mouseAction(type, x, y) {
|
||||||
const [dom_x, dom_y] = this._getDOMCoordsFromMouseCoords(x, y);
|
const [dom_x, dom_y] = this._getDOMCoordsFromMouseCoords(x, y);
|
||||||
const element = document.elementFromPoint(dom_x, dom_y);
|
const element = document.elementFromPoint(dom_x, dom_y);
|
||||||
|
@ -316,45 +332,63 @@ export default class FrameBuilder extends BaseBuilder{
|
||||||
// However we can't just write random pixels to a TTY screen, we must collate 2 rows
|
// However we can't just write random pixels to a TTY screen, we must collate 2 rows
|
||||||
// of native pixels for every row of the terminal.
|
// of native pixels for every row of the terminal.
|
||||||
_buildTtyRow(bg_row, fg_row, y) {
|
_buildTtyRow(bg_row, fg_row, y) {
|
||||||
let tty_index, char, x_shoved;
|
let tty_index;
|
||||||
let row = [];
|
let row = [];
|
||||||
let char_width_debt = 0;
|
this._char_width_debt = 0;
|
||||||
const tty_row = parseInt(y / 2);
|
const tty_row = parseInt(y / 2);
|
||||||
for (let x = 0; x < this.frame_width; x++) {
|
for (let x = 0; x < this.frame_width; x++) {
|
||||||
if (x + char_width_debt >= this.frame_width) {
|
if (x + this._char_width_debt >= this.frame_width) {
|
||||||
// Ideally this shouldn't happen because the CSS 'should' deal with wide
|
// Ideally this shouldn't happen because the CSS 'should' deal with wide
|
||||||
// characters.
|
// characters.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tty_index = (tty_row * this.frame_width) + x;
|
tty_index = (tty_row * this.frame_width) + x;
|
||||||
if (this._doesCellHaveACharacter(tty_index)) {
|
if (this._doesCellHaveACharacter(tty_index)) {
|
||||||
char = this.formatted_text[tty_index];
|
row = this._addCharacter(row, x, tty_index);
|
||||||
char_width_debt = this._calculateCharWidthDebt(char_width_debt, char[0]);
|
|
||||||
// Don't display a wide character in the final column
|
|
||||||
if (x + char_width_debt >= this.frame_width) char[0] = ' ';
|
|
||||||
row.push(utils.ttyPixel(char[1], char[2], char[0]));
|
|
||||||
} else {
|
} else {
|
||||||
// Wide characters take up more than one cell, so we might not always be
|
row = this._addGraphicsBlock(row, x, fg_row, bg_row);
|
||||||
// iterating by 1.
|
|
||||||
x_shoved = x + char_width_debt;
|
|
||||||
row.push(utils.ttyPixel(fg_row[x_shoved], bg_row[x_shoved], '▄'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_addCharacter(row, x, tty_index) {
|
||||||
|
const char = this.formatted_text[tty_index];
|
||||||
|
this._calculateCharWidthDebt(char[0]);
|
||||||
|
// Don't display a wide character in the final column
|
||||||
|
if (x + this._char_width_debt >= this.frame_width) char[0] = ' ';
|
||||||
|
if (this._is_graphics_mode) {
|
||||||
|
row.push(utils.ttyPixel(char[1], char[2], char[0]));
|
||||||
|
} else {
|
||||||
|
// TODO: Somehow communicate clickable text
|
||||||
|
row.push(char[0]);
|
||||||
|
}
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
_addGraphicsBlock(row, x, fg_row, bg_row) {
|
||||||
|
// Wide characters take up more than one cell, so we might not always be
|
||||||
|
// iterating by 1.
|
||||||
|
const x_shoved = x + this._char_width_debt;
|
||||||
|
if (this._is_graphics_mode) {
|
||||||
|
row.push(utils.ttyPixel(fg_row[x_shoved], bg_row[x_shoved], '▄'));
|
||||||
|
} else {
|
||||||
|
row.push(' ');
|
||||||
|
}
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
// Deal with UTF8 characters that take up more than a single cell in the TTY.
|
// Deal with UTF8 characters that take up more than a single cell in the TTY.
|
||||||
// TODO:
|
// TODO:
|
||||||
// 1. Do all terminals deal with wide characters the same?
|
// 1. Do all terminals deal with wide characters the same?
|
||||||
// 2. Use CSS or JS so that wide characters actually flow in the DOM as 2
|
// 2. Use CSS or JS so that wide characters actually flow in the DOM as 2
|
||||||
// monospaced characters. This will allow pages of nothing but wide
|
// monospaced characters. This will allow pages of nothing but wide
|
||||||
// characters to properly display.
|
// characters to properly display.
|
||||||
_calculateCharWidthDebt(current_debt, char) {
|
_calculateCharWidthDebt(char) {
|
||||||
const char_width_in_tty = charWidthInTTY(char);
|
const char_width_in_tty = charWidthInTTY(char);
|
||||||
if (char_width_in_tty > 1) {
|
if (char_width_in_tty > 1) {
|
||||||
current_debt += char_width_in_tty - 1;
|
this._char_width_debt += char_width_in_tty - 1;
|
||||||
}
|
}
|
||||||
return current_debt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need to know this because we want all empty cells to be 'transparent'
|
// We need to know this because we want all empty cells to be 'transparent'
|
||||||
|
|
Loading…
Reference in a new issue