* Fix EtherTerm backspace key
* Better WIP apply art / module * Better WIP 'enter' and 'leave' events from VC
This commit is contained in:
parent
b0103cb178
commit
77600d3dde
|
@ -14,6 +14,8 @@ var assert = require('assert');
|
|||
var binary = require('binary');
|
||||
var miscUtil = require('./misc_util.js');
|
||||
|
||||
exports.getFGColorValue = getFGColorValue;
|
||||
exports.getBGColorValue = getBGColorValue;
|
||||
exports.sgr = sgr;
|
||||
exports.clearScreen = clearScreen;
|
||||
exports.resetScreen = resetScreen;
|
||||
|
@ -69,7 +71,7 @@ var CONTROL = {
|
|||
// Select Graphics Rendition
|
||||
// See http://cvs.synchro.net/cgi-bin/viewcvs.cgi/*checkout*/src/conio/cterm.txt
|
||||
//
|
||||
var SGR = {
|
||||
var SGRValues = {
|
||||
reset : 0,
|
||||
bold : 1,
|
||||
dim : 2,
|
||||
|
@ -96,11 +98,21 @@ var SGR = {
|
|||
greenBG : 42,
|
||||
yellowBG : 43,
|
||||
blueBG : 44,
|
||||
magentaBG : 45,
|
||||
|
||||
cyanBG : 47,
|
||||
whiteBG : 47,
|
||||
};
|
||||
|
||||
function getFGColorValue(name) {
|
||||
return SGRValues[name];
|
||||
}
|
||||
|
||||
function getBGColorValue(name) {
|
||||
return SGRValues[name + 'BG'];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// See http://cvs.synchro.net/cgi-bin/viewcvs.cgi/*checkout*/src/conio/cterm.txt
|
||||
// :TODO: document
|
||||
var SYNC_TERM_FONTS = [
|
||||
|
@ -162,8 +174,8 @@ Object.keys(CONTROL).forEach(function onControlName(name) {
|
|||
});
|
||||
|
||||
// Create various color methods such as white(), yellowBG(), reset(), ...
|
||||
Object.keys(SGR).forEach(function onSgrName(name) {
|
||||
var code = SGR[name];
|
||||
Object.keys(SGRValues).forEach(function onSgrName(name) {
|
||||
var code = SGRValues[name];
|
||||
|
||||
exports[name] = function() {
|
||||
return ESC_CSI + code + 'm';
|
||||
|
@ -173,7 +185,7 @@ Object.keys(SGR).forEach(function onSgrName(name) {
|
|||
function sgr() {
|
||||
//
|
||||
// - Allow an single array or variable number of arguments
|
||||
// - Each element can be either a integer or string found in SGR
|
||||
// - Each element can be either a integer or string found in SGRValues
|
||||
// which in turn maps to a integer
|
||||
//
|
||||
if(arguments.length <= 0) {
|
||||
|
@ -187,11 +199,11 @@ function sgr() {
|
|||
var args = Array.isArray(arguments[0]) ? arguments[0] : arguments;
|
||||
for(var i = 0; i < args.length; i++) {
|
||||
if(typeof args[i] === 'string') {
|
||||
if(args[i] in SGR) {
|
||||
if(args[i] in SGRValues) {
|
||||
if(result.length > 0) {
|
||||
result += ';';
|
||||
}
|
||||
result += SGR[args[i]];
|
||||
result += SGRValues[args[i]];
|
||||
}
|
||||
} else if(typeof args[i] === 'number') {
|
||||
if(result.length > 0) {
|
||||
|
|
37
core/view.js
37
core/view.js
|
@ -13,7 +13,7 @@ exports.VIEW_SPECIAL_KEY_MAP_DEFAULT = VIEW_SPECIAL_KEY_MAP_DEFAULT;
|
|||
var VIEW_SPECIAL_KEY_MAP_DEFAULT = {
|
||||
accept : [ 'enter' ],
|
||||
exit : [ 'esc' ],
|
||||
backspace : [ 'backspace' ],
|
||||
backspace : [ 'backspace', 'del' ],
|
||||
del : [ 'del' ],
|
||||
next : [ 'tab' ],
|
||||
up : [ 'up arrow' ],
|
||||
|
@ -89,6 +89,10 @@ View.prototype.setId = function(id) {
|
|||
this.id = id;
|
||||
};
|
||||
|
||||
View.prototype.getId = function() {
|
||||
return this.id;
|
||||
};
|
||||
|
||||
View.prototype.setPosition = function(pos) {
|
||||
//
|
||||
// We allow [x, y], { x : x, y : y }, or (x, y)
|
||||
|
@ -116,18 +120,35 @@ View.prototype.setPosition = function(pos) {
|
|||
'Y position ' + this.position.y + ' out of terminal range ' + this.client.term.termWidth);
|
||||
};
|
||||
|
||||
View.prototype.setColor = function(fg, bg, flags) {
|
||||
if(fg) {
|
||||
this.color.fg = fg;
|
||||
View.prototype.setColor = function(color, bgColor, flags) {
|
||||
if(_.isObject(color)) {
|
||||
assert(_.has(color, 'fg'));
|
||||
assert(_.has(color, 'bg'));
|
||||
assert(_.has(color, 'flags'));
|
||||
|
||||
this.color = color;
|
||||
} else {
|
||||
if(color) {
|
||||
this.color.fg = color;
|
||||
}
|
||||
|
||||
if(bg) {
|
||||
this.color.bg = bg;
|
||||
if(bgColor) {
|
||||
this.color.bg = bgColor;
|
||||
}
|
||||
|
||||
if('undefined' !== typeof flags) {
|
||||
if(_.isNumber(flags)) {
|
||||
this.color.flags = flags;
|
||||
}
|
||||
}
|
||||
|
||||
// allow strings such as 'red', 'black', etc. to be passed
|
||||
if(_.isString(this.color.fg)) {
|
||||
this.color.fg = ansi.getFGColorValue(this.color.fg);
|
||||
}
|
||||
|
||||
if(_.isString(this.color.bg)) {
|
||||
this.color.bg = ansi.getBGColorValue(this.color.bg);
|
||||
}
|
||||
};
|
||||
|
||||
View.prototype.getColor = function() {
|
||||
|
@ -147,8 +168,6 @@ View.prototype.setFocus = function(focused) {
|
|||
|
||||
this.hasFocus = focused;
|
||||
this.client.term.write('show' === this.cursor ? ansi.showCursor() : ansi.hideCursor());
|
||||
|
||||
this.emit(focused ? 'enter' : 'leave');
|
||||
};
|
||||
|
||||
View.prototype.onKeyPress = function(key, isSpecial) {
|
||||
|
|
|
@ -15,14 +15,17 @@ var _ = require('lodash');
|
|||
|
||||
exports.ViewController = ViewController;
|
||||
|
||||
function ViewController(client, formId) {
|
||||
function ViewController(options) {
|
||||
assert(_.isObject(options));
|
||||
assert(_.isObject(options.client));
|
||||
|
||||
events.EventEmitter.call(this);
|
||||
|
||||
var self = this;
|
||||
|
||||
this.client = client;
|
||||
this.client = options.client;
|
||||
this.views = {}; // map of ID -> view
|
||||
this.formId = formId || 0;
|
||||
this.formId = options.formId || 0;
|
||||
|
||||
this.onClientKeyPress = function(key, isSpecial) {
|
||||
if(isSpecial) {
|
||||
|
@ -95,6 +98,16 @@ function ViewController(client, formId) {
|
|||
self.emit('submit', formData);
|
||||
};
|
||||
|
||||
this.switchFocusEvent = function(event, view) {
|
||||
if(self.emitSwitchFocus) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.emitSwitchFocus = true;
|
||||
self.emit(event, view);
|
||||
self.emitSwitchFocus = false;
|
||||
};
|
||||
|
||||
this.attachClientEvents();
|
||||
}
|
||||
|
||||
|
@ -146,16 +159,17 @@ ViewController.prototype.getFocusedView = function() {
|
|||
|
||||
ViewController.prototype.switchFocus = function(id) {
|
||||
if(this.focusedView && this.focusedView.acceptsFocus) {
|
||||
this.switchFocusEvent('leave', this.focusedView);
|
||||
this.focusedView.setFocus(false);
|
||||
}
|
||||
|
||||
var view = this.getView(id);
|
||||
if(view && view.acceptsFocus) {
|
||||
this.switchFocusEvent('enter', view);
|
||||
|
||||
this.focusedView = view;
|
||||
this.focusedView.setFocus(true);
|
||||
}
|
||||
|
||||
// :TODO: Probably log here
|
||||
};
|
||||
|
||||
ViewController.prototype.nextFocus = function() {
|
||||
|
@ -234,7 +248,7 @@ ViewController.prototype.loadFromMCIMapAndConfig = function(options, cb) {
|
|||
if(err) {
|
||||
// :TODO: fix logging of err here:
|
||||
Log.warn(
|
||||
{ err : err, mci : Object.keys(options.mciMap), formIdKey : formIdKey } ,
|
||||
{ err : err.toString(), mci : Object.keys(options.mciMap), formIdKey : formIdKey } ,
|
||||
'Unable to load menu configuration');
|
||||
}
|
||||
|
||||
|
|
|
@ -27,10 +27,8 @@ function ApplyModule(menuConfig) {
|
|||
|
||||
var self = this;
|
||||
|
||||
this.clearForm = function() {
|
||||
[ 1, 2, ].forEach(function onId(id) {
|
||||
self.viewController.getView(id).clearText();
|
||||
});
|
||||
this.menuMethods.submitApplication = function(args) {
|
||||
console.log('do submit')
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -49,46 +47,63 @@ ApplyModule.prototype.mciReady = function(mciMap) {
|
|||
|
||||
var self = this;
|
||||
|
||||
self.viewController = self.addViewController(new ViewController(self.client));
|
||||
self.viewController = self.addViewController(new ViewController({ client : self.client } ));
|
||||
self.viewController.loadFromMCIMapAndConfig( { mciMap : mciMap, menuConfig : self.menuConfig }, function onViewReady(err) {
|
||||
|
||||
var usernameView = self.viewController.getView(1);
|
||||
var userExistsView = self.viewController.getView(10);
|
||||
usernameView.on('leave', function leave() {
|
||||
user.getUserIdAndName(usernameView.getViewData(), function userIdAndName(err) {
|
||||
if(!err) {
|
||||
userExistsView.setText('That username already exists!');
|
||||
var passwordView = self.viewController.getView(9);
|
||||
var pwConfirmView = self.viewController.getView(10);
|
||||
var statusView = self.viewController.getView(11);
|
||||
|
||||
self.viewController.on('leave', function leaveView(view) {
|
||||
switch(view.getId()) {
|
||||
case 1 :
|
||||
user.getUserIdAndName(view.getViewData(), function userIdAndName(err) {
|
||||
var alreadyExists = !err;
|
||||
if(alreadyExists) {
|
||||
statusView.setText('Username unavailable!');
|
||||
self.viewController.switchFocus(1); // don't allow to leave
|
||||
} else {
|
||||
userExistsView.setText('');
|
||||
}
|
||||
//if(11 !== self.viewController.getFocusedView()) {
|
||||
statusView.setText('');
|
||||
self.viewController.switchFocus(2);
|
||||
//}
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
var pwView = self.viewController.getView(8);
|
||||
var pwConfirmView = self.viewController.getView(9);
|
||||
var pwSecureView = self.viewController.getView(11);
|
||||
var pwConfirmNoticeView = self.viewController.getView(12);
|
||||
|
||||
// :TODO: show a secure meter here instead
|
||||
pwView.on('leave', function pwLeave() {
|
||||
if(pwView.getViewData().length > 3) {
|
||||
pwSecureView.setColor(32);
|
||||
pwSecureView.setText('Secure');
|
||||
/*
|
||||
usernameView.on('leave', function leaveUsername() {
|
||||
user.getUserIdAndName(usernameView.getViewData(), function userIdAndName(err) {
|
||||
var alreadyExists = !err;
|
||||
if(alreadyExists) {
|
||||
statusView.setText('Username unavailable!');
|
||||
self.viewController.switchFocus(1); // don't allow to leave
|
||||
} else {
|
||||
pwSecureView.setColor(31);
|
||||
pwSecureView.setText('Insecure!');
|
||||
statusView.setText('');
|
||||
self.viewController.switchFocus(2);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
passwordView.on('leave', function leavePw() {
|
||||
if(passwordView.getViewData().length < 3) {
|
||||
statusView.setText('Password too short!');
|
||||
self.viewController.switchFocus(9);
|
||||
} else {
|
||||
statusView.setText('');
|
||||
}
|
||||
});
|
||||
|
||||
pwConfirmView.on('leave', function confirmPwLeave() {
|
||||
if(pwView.getViewData() !== pwConfirmView.getViewData()) {
|
||||
pwConfirmNoticeView.setText('Passwords must match!');
|
||||
pwConfirmView.on('leave', function leavePwConfirm() {
|
||||
if(passwordView.getViewData() !== pwConfirmView.getViewData()) {
|
||||
statusView.setText('Passwords must match!');
|
||||
self.viewController.switchFocus(9);
|
||||
} else {
|
||||
pwConfirmNoticeView.setText('');
|
||||
statusView.setText('');
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
|
||||
});
|
||||
};
|
Binary file not shown.
|
@ -1,4 +1,7 @@
|
|||
{
|
||||
"name" : "Nu Mayan",
|
||||
"author" : "NuSkooler"
|
||||
"author" : "NuSkooler",
|
||||
"config" : {
|
||||
"passwordChar" : "*"
|
||||
}
|
||||
}
|
|
@ -80,7 +80,7 @@ LoginModule.prototype.mciReady = function(mciMap) {
|
|||
|
||||
var self = this;
|
||||
|
||||
self.viewController = self.addViewController(new ViewController(self.client));
|
||||
self.viewController = self.addViewController(new ViewController( { client : self.client } ));
|
||||
self.viewController.loadFromMCIMapAndConfig( { mciMap : mciMap, menuConfig : self.menuConfig }, function onViewReady(err) {
|
||||
});
|
||||
};
|
|
@ -66,7 +66,7 @@ MatrixModule.prototype.mciReady = function(mciMap) {
|
|||
// 2 - Bye!
|
||||
//
|
||||
//var vc = new ViewController(client);
|
||||
var vc = self.addViewController(new ViewController(self.client));
|
||||
var vc = self.addViewController(new ViewController({ client : self.client } ));
|
||||
|
||||
vc.on('submit', function onSubmit(form) {
|
||||
console.log(form);
|
||||
|
|
|
@ -105,17 +105,44 @@
|
|||
"module" : "apply",
|
||||
"form" : {
|
||||
"0" : {
|
||||
"BN13BN14ET1ET2ET3ET4ET5ET6ET7ET8ET9TL10TL11TL12" : {
|
||||
"BN12BN13ET1ET10ET2ET3ET4ET5ET6ET7ET8ET9TL11" : {
|
||||
"mci" : {
|
||||
"ET1" : {
|
||||
"focus" : true
|
||||
},
|
||||
"BN13" : {
|
||||
"BN12" : {
|
||||
"submit" : true,
|
||||
"text" : "Apply"
|
||||
},
|
||||
"BN14" : {
|
||||
"BN13" : {
|
||||
"submit" : true,
|
||||
"text" : "Cancel"
|
||||
}
|
||||
},
|
||||
"submit" : {
|
||||
"12" : [ // Apply
|
||||
{
|
||||
"value" : { "12" : null },
|
||||
"action" : "@method:submitApplication",
|
||||
"args" : {
|
||||
"username" : "{1}",
|
||||
"realName" : "{2}",
|
||||
"age" : "{3}",
|
||||
"sex" : "{4}",
|
||||
"location" : "{5}",
|
||||
"affils" : "{6}",
|
||||
"email" : "{7}",
|
||||
"web" : "{8}",
|
||||
"password" : "{9}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"13" : [ // Cancel
|
||||
{
|
||||
"value" : { "13" : null },
|
||||
"action" : "@menu:matrix"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ StandardMenuModule.prototype.mciReady = function(mciMap) {
|
|||
|
||||
var self = this;
|
||||
|
||||
var vc = self.addViewController(new ViewController(self.client));
|
||||
var vc = self.addViewController(new ViewController({ client : self.client } ));
|
||||
vc.loadFromMCIMapAndConfig( { mciMap : mciMap, menuConfig : self.menuConfig }, function onViewReady(err) {
|
||||
if(err) {
|
||||
console.log(err);
|
||||
|
|
Loading…
Reference in New Issue