* Mostly notes & toying around with MultiLineTextEditView

This commit is contained in:
Bryan Ashby 2015-05-17 21:33:27 -06:00
parent 3bf34487d7
commit 159cdcb763
2 changed files with 148 additions and 34 deletions

View File

@ -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);
}

View File

@ -348,6 +348,14 @@
"text" : "< Back",
"submit" : [ "esc" ]
}
},
"submit" : {
"*" : [
{
"value" : 5,
"action" : "@menu:demoMain"
}
]
}
}
}
@ -361,14 +369,23 @@
"BT5MT1" : {
"mci" : {
"MT1" : {
"width" : 50,
"height" : 5,
"text" : "Now all the time I was watching this, I was beginning to get very aware of like not feeling all that well, but I tried to forget this, concentrating on the next film, which jumped right away on a young devotchka, who was being given the old in-out, in-out, first by one malchick, then another, then another. This seemed real, very real, though if you thought about it properly you couldn't imagine lewdies actually agreeing to having all this done to them in a film, and if these films were made by the good, or the State, you couldn't imagine them being allowed to take these films, without like interfering with what was going on.\nWhen it came to the sixth or seventh malchick, leering and smecking and then going into it, I began to feel really sick. But I could not shut my glazzies and even if I tried to move my glazballs about I still not get out of the line of fire of this picture."
"width" : 67,
"height" : 17,
"text" : "Hints:\n * Press CTRL-Y to clear a line\n * Arrow keys to move around\n\nTry editing the text below:\nLet me be sick... I want to get up. Get me something to be sick in... Stop the film... Please stop it... I can't stand it any more. Stop it please... please.\n\nWell, that was a very promising start. By my calculations, you should be starting to feel alright again. Yes? Dr. Brodsky's pleased with you. Now tomorrow there'll be two sessions, of course, morning and afternoon.\n\nYou mean, I have to viddy two sessions in one day?\n\nI imagine you'll be feeling a little bit limp by the end of the day. But we have to be hard on you. You have to be cured.\n",
"focus" : true
},
"BT5" : {
"text" : "< Back",
"submit" : [ "esc" ]
}
},
"submit" : {
"*" : [
{
"value" : 5,
"action" : "@menu:demoMain"
}
]
}
}
}