mirror of
https://github.com/NuSkooler/enigma-bbs.git
synced 2025-07-31 15:06:15 +02:00
* Mostly notes & toying around with MultiLineTextEditView
This commit is contained in:
parent
3bf34487d7
commit
159cdcb763
2 changed files with 148 additions and 34 deletions
|
@ -9,28 +9,52 @@ var ansi = require('./ansi_term.js');
|
|||
var assert = require('assert');
|
||||
var _ = require('lodash');
|
||||
|
||||
|
||||
//
|
||||
// General Design
|
||||
//
|
||||
// * Take any existing input & word wrap into lines[] preserving
|
||||
// formatting characters.
|
||||
// * When drawing, formatting characters are processed but not shown
|
||||
// or processed directly in many cases. E.g., \n is processed but simply
|
||||
// causes us to go to our "next line" visibly.
|
||||
// * Empty/blank lines = \n
|
||||
//
|
||||
exports.MultiLineEditTextView = MultiLineEditTextView;
|
||||
|
||||
//
|
||||
// Some resources & comparisons
|
||||
//
|
||||
// Enthral
|
||||
// * https://github.com/M-griffin/Enthral/blob/master/src/msg_fse.cpp
|
||||
// Enthral @ https://github.com/M-griffin/Enthral/blob/master/src/msg_fse.cpp
|
||||
// * Tabs are ignored
|
||||
// * Preview/reading mode processes colors, otherwise just text (e.g. editor)
|
||||
//
|
||||
// x84
|
||||
// * https://github.com/jquast/x84/blob/master/x84/bbs/editor.py
|
||||
// x84 @ https://github.com/jquast/x84/blob/master/x84/bbs/editor.py
|
||||
//
|
||||
//
|
||||
// Syncronet
|
||||
//
|
||||
|
||||
|
||||
function MultiLineEditTextView(options) {
|
||||
|
||||
if(!_.isBoolean(options.acceptsFocus)) {
|
||||
options.acceptsFocus = true;
|
||||
}
|
||||
|
||||
if(!_.isBoolean(this.acceptsInput)) {
|
||||
options.acceptsInput = true;
|
||||
}
|
||||
|
||||
View.call(this, options);
|
||||
|
||||
var self = this;
|
||||
|
||||
this.lines = []; // a given line is text...until EOL
|
||||
this.lines = []; // a given line is text...until EOL
|
||||
this.topLineIndex = 0;
|
||||
this.cursorPos = { x : 0, y : 0 }; // relative to view window
|
||||
|
||||
this.drawViewableText = function() {
|
||||
/*
|
||||
this.redrawViewableText = function() {
|
||||
//
|
||||
// v--- position.x/y
|
||||
// +-----------------------------------+ <--- x + width
|
||||
|
@ -38,48 +62,100 @@ function MultiLineEditTextView(options) {
|
|||
// | |
|
||||
// | |
|
||||
// +-----------------------------------+
|
||||
// ^--- position.y + height
|
||||
// ^--- position.x + height
|
||||
//
|
||||
// A given line in lines[] may need to take up 1:n physical lines
|
||||
// due to wrapping / available space.
|
||||
//
|
||||
var x = self.position.x;
|
||||
var bottom = x + self.dimens.height;
|
||||
var lines;
|
||||
var idx = self.topLineIndex;
|
||||
var x = self.position.x;
|
||||
var bottom = x + self.dimens.height;
|
||||
var idx = self.topLineIndex;
|
||||
|
||||
self.client.term.write(self.getSGR());
|
||||
|
||||
while(x < bottom) {
|
||||
lines = self.getWordWrapLines(self.lines[idx]);
|
||||
for(var y = 0; y < lines.length && x < bottom; ++y) {
|
||||
self.client.term.write(ansi.goto(x, this.position.y));
|
||||
self.client.term.write(lines[y]);
|
||||
var lines;
|
||||
while(idx < self.lines.length && x < bottom) {
|
||||
if(0 === self.lines[idx].length) {
|
||||
++x;
|
||||
} else {
|
||||
lines = self.wordWrap(self.lines[idx]);
|
||||
for(var y = 0; y < lines.length && x < bottom; ++y) {
|
||||
self.client.term.write(ansi.goto(x, this.position.y));
|
||||
self.client.term.write(lines[y]);
|
||||
++x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
++idx;
|
||||
}
|
||||
};
|
||||
*/
|
||||
this.redrawViewableText = function() {
|
||||
var x = self.position.x;
|
||||
var bottom = x + self.dimens.height;
|
||||
var index = self.topLineIndex;
|
||||
|
||||
self.client.term.write(self.getSGR());
|
||||
|
||||
while(index < self.lines.length && x < bottom) {
|
||||
self.client.term.write(ansi.goto(x, this.position.y));
|
||||
self.writeLine(self.lines[index]);
|
||||
console.log(self.lines[index])
|
||||
++x;
|
||||
++index;
|
||||
}
|
||||
};
|
||||
|
||||
this.getWordWrapLines = function(line) {
|
||||
this.wordWrap = function(line) {
|
||||
//
|
||||
// Similar implementations:
|
||||
// Other implementations:
|
||||
// * http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/
|
||||
// * http://james.padolsey.com/snippets/wordwrap-for-javascript/
|
||||
// * http://phpjs.org/functions/wordwrap/
|
||||
// * https://github.com/jonschlinkert/word-wrap
|
||||
//
|
||||
/*
|
||||
var re = new RegExp(
|
||||
'(.{1,' + self.dimens.width + '}(\\s|$)|.{' + self.dimens.width + '}|.+$)',
|
||||
'g');
|
||||
*/
|
||||
|
||||
var re = new RegExp('.{1,' + self.dimens.width + '}(\\s+|$)|\\S+?(\\s+|$)', 'g');
|
||||
|
||||
//return line.split(re);
|
||||
'.{1,' + self.dimens.width + '}(\\s+|$)|\\S+?(\\s+|$)', 'g');
|
||||
return line.match(re) || [];
|
||||
};
|
||||
|
||||
this.writeLine = function(s) {
|
||||
//
|
||||
// Hello, World\n
|
||||
// \tThis is a test, it is only a test!
|
||||
//
|
||||
// Loop through |s| finding control characters & processing them
|
||||
// with our own internal handling.
|
||||
|
||||
var clean = s.replace(/[\x00-\x1F\x7F-\x9F]/g, '');
|
||||
self.client.term.write(clean);
|
||||
};
|
||||
|
||||
this.scrollUp = function(count) {
|
||||
|
||||
};
|
||||
|
||||
this.scrollDown = function(count) {
|
||||
|
||||
};
|
||||
|
||||
this.keyUp = function() {
|
||||
if(self.cursorPos.x > 0) {
|
||||
self.cursorPos.x--;
|
||||
console.log(self.lines[self.getLineIndex()])
|
||||
} else if(self.topLineIndex > 0) {
|
||||
// :TODO: scroll
|
||||
}
|
||||
|
||||
|
||||
|
||||
// :TODO: if there is text @ cursor y position we're ok, otherwise,
|
||||
// jump to the end of the line
|
||||
};
|
||||
|
||||
this.getLineIndex = function() {
|
||||
return self.topLineIndex + self.cursorPos.x;
|
||||
};
|
||||
}
|
||||
|
||||
require('util').inherits(MultiLineEditTextView, View);
|
||||
|
@ -87,12 +163,33 @@ require('util').inherits(MultiLineEditTextView, View);
|
|||
MultiLineEditTextView.prototype.redraw = function() {
|
||||
MultiLineEditTextView.super_.prototype.redraw.call(this);
|
||||
|
||||
this.drawViewableText();
|
||||
}
|
||||
this.redrawViewableText();
|
||||
};
|
||||
|
||||
/*MultiLineEditTextView.prototype.setFocus = function(focused) {
|
||||
|
||||
MultiLineEditTextView.super_.prototype.setFocus.call(this, focused);
|
||||
};
|
||||
*/
|
||||
|
||||
MultiLineEditTextView.prototype.setText = function(text) {
|
||||
// :TODO: text.split(/\r\n|\n|\r/))
|
||||
this.lines = text.split(/\r?\n/);
|
||||
//this.lines = text.split(/\r?\n/);
|
||||
|
||||
//this.cursorPos.x = this.position.x + this.dimens.height;
|
||||
this.lines = this.wordWrap(text);
|
||||
}
|
||||
|
||||
MultiLineEditTextView.prototype.onSpecialKeyPress = function(keyName) {
|
||||
if(this.isSpecialKeyMapped('up', keyName)) {
|
||||
this.keyUp();
|
||||
} else if(this.isSpecialKeyMapped('down', keyName)) {
|
||||
|
||||
} else if(this.isSpecialKeyMapped('left', keyName)) {
|
||||
|
||||
} else if(this.isSpecialKeyMapped('right', keyName)) {
|
||||
|
||||
}
|
||||
|
||||
MultiLineEditTextView.super_.prototype.onSpecialKeyPress.call(this, keyName);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue