From dd478ed6ba2f4025fb94ca7fa5bbc618fe9623f7 Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Fri, 24 Jul 2015 18:33:59 -0600 Subject: [PATCH] * displayArtAsset is now part of asset * Work on generalizing some things so they can be used for pause/etc. --- core/asset.js | 46 +++++++++++++++++++++++++++++++++++++++++++++ core/menu_module.js | 34 +++++++++++++++++++++++++-------- core/theme.js | 34 ++++++++++++++++++++++++--------- mods/fse.js | 30 +++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+), 17 deletions(-) diff --git a/core/asset.js b/core/asset.js index 8a99aecf..4a9af043 100644 --- a/core/asset.js +++ b/core/asset.js @@ -2,6 +2,7 @@ 'use strict'; var Config = require('./config.js').config; +var theme = require('./theme.js'); var _ = require('lodash'); var assert = require('assert'); @@ -10,6 +11,7 @@ exports.parseAsset = parseAsset; exports.getArtAsset = getArtAsset; exports.resolveConfigAsset = resolveConfigAsset; exports.getViewPropertyAsset = getViewPropertyAsset; +exports.displayArtAsset = displayArtAsset; var ALL_ASSETS = [ 'art', @@ -83,3 +85,47 @@ function getViewPropertyAsset(src) { return parseAsset(src); }; + +function displayArtAsset(assetSpec, client, options, cb) { + assert(_.isObject(client)); + + // options are... optional + if(3 === arguments.length) { + cb = options; + options = {}; + } + + var artAsset = getArtAsset(assetSpec); + if(!artAsset) { + cb(new Error('Asset not found: ' + assetSpec)); + return; + } + + var dispOpts = { + name : artAsset.asset, + client : client, + font : options.font, + }; + + switch(artAsset.type) { + case 'art' : + theme.displayThemeArt(dispOpts, function displayed(err, artData) { + cb(err, err ? null : { mciMap : artData.mciMap, height : artData.extraInfo.height } ); + }); + break; + + case 'method' : + // :TODO: fetch & render via method + break; + + case 'inline ' : + // :TODO: think about this more in relation to themes, etc. How can this come + // from a theme (with override from menu.json) ??? + // look @ client.currentTheme.inlineArt[name] -> menu/prompt[name] + break; + + default : + cb(new Error('Unsupported art asset type: ' + artAsset.type)); + break; + } +} \ No newline at end of file diff --git a/core/menu_module.js b/core/menu_module.js index 22341470..320ab311 100644 --- a/core/menu_module.js +++ b/core/menu_module.js @@ -26,6 +26,8 @@ function MenuModule(options) { this.menuMethods = {}; // methods called from @method's this.viewControllers = {}; // name->vc + // :TODO: Move this elsewhere + /* this.displayArtAsset = function(assetSpec, cb) { var artAsset = asset.getArtAsset(assetSpec); @@ -64,6 +66,7 @@ function MenuModule(options) { break; } }; + */ this.initSequence = function() { var mciData = { }; @@ -76,12 +79,23 @@ function MenuModule(options) { }, function displayMenuArt(callback) { if(_.isString(self.menuConfig.art)) { - self.displayArtAsset(self.menuConfig.art, function displayed(err, artData) { + asset.displayArtAsset( + self.menuConfig.art, + self.client, + { font : self.menuConfig.font }, + function displayed(err, artData) + { + if(!err) { + mciData.menu = artData.mciMap; + } + callback(err); + }); + /*self.displayArtAsset(self.menuConfig.art, function displayed(err, artData) { if(!err) { mciData.menu = artData.mciMap; } callback(err); - }); + });*/ } else { callback(null); } @@ -104,12 +118,16 @@ function MenuModule(options) { // Prompts *must* have art. If it's missing it's an error // :TODO: allow inline prompts in the future, e.g. @inline:memberName -> { "memberName" : { "text" : "stuff", ... } } var promptConfig = self.menuConfig.promptConfig; - self.displayArtAsset(promptConfig.art, function displayed(err, artData) { - if(!err) { - mciData.prompt = artData.mciMap; - } - callback(err); - }); + asset.displayArtAsset( + promptConfig.art, + self.client, + { font : self.menuConfig.font }, + function displayed(err, artData) { + if(!err) { + mciData.prompt = artData.mciMap; + } + callback(err); + }); } else { callback(null); } diff --git a/core/theme.js b/core/theme.js index 8be357a5..d1afae52 100644 --- a/core/theme.js +++ b/core/theme.js @@ -189,6 +189,9 @@ function displayThemeArt(options, cb) { }); } +// +// Pause prompts are a special prompt by the name 'pause'. +// function displayThemePause(options, cb) { // // options.client @@ -203,8 +206,8 @@ function displayThemePause(options, cb) { // :TODO: Support animated pause prompts. Probably via MCI with AnimatedView // :TODO: support prompts with a height > 1 // :TODO: Prompt should support MCI codes in general - // ...this will be more complex due to cursor movement. Will need to track where teh cusor - // was before the prompt + filling MCI, then move back and erase correct # of lines + + var artInfo; async.waterfall( [ @@ -222,13 +225,20 @@ function displayThemePause(options, cb) { }); }, function displayPausePrompt(pausePrompt, callback) { - displayThemeArt( { client : options.client, name : pausePrompt.art }, function pauseDisplayed(err, mciMap, extraInfo) { - if(extraInfo) { - pauseHeight = extraInfo.height; - } - callback(null); + // :TODO: use displayArtAsset() + displayThemeArt( { client : options.client, name : pausePrompt.art }, function pauseDisplayed(err, artData) { + artInfo = artData; + callback(err); }); }, + function discoverCursorPosition(callback) { + options.client.once('cursor position report', function cpr(pos) { + artInfo.startRow = pos[0] - artInfo.extraInfo.height; + callback(null); + }); + options.client.term.rawWrite(ansi.queryPos()); + }, + // :TODO: use view Controller loadFromPromptConfig() with 'noInput' option or such function pauseForUserInput(callback) { options.client.waitForKeyPress(function keyPressed() { callback(null); @@ -236,16 +246,22 @@ function displayThemePause(options, cb) { }, function clearPauseArt(callback) { if(options.clearPrompt) { - options.client.term.write(ansi.up(1) + ansi.deleteLine()); + if(artInfo.startRow) { + options.client.term.rawWrite(ansi.goto(artInfo.startRow, 1)); + options.client.term.rawWrite(ansi.deleteLine(artInfo.extraInfo.height)); + } else { + options.client.term.rawWrite(ansi.up(1) + ansi.deleteLine()); + } } callback(null); } + /* , function debugPause(callback) { setTimeout(function to() { callback(null); }, 4000); } - +*/ ], function complete(err) { if(err) { diff --git a/mods/fse.js b/mods/fse.js index 84c6264a..d32c7d24 100644 --- a/mods/fse.js +++ b/mods/fse.js @@ -7,6 +7,7 @@ var ansi = require('../core/ansi_term.js'); var theme = require('../core/theme.js'); var MultiLineEditTextView = require('../core/multi_line_edit_text_view.js').MultiLineEditTextView; var Message = require('../core/message.js'); +var asset = require('../core/asset.js'); var async = require('async'); var assert = require('assert'); @@ -102,9 +103,19 @@ function FullScreenEditorModule(options) { function displayFooterArt(callback) { var footerArt = self.menuConfig.config.art[options.footerName]; + asset.displayArtAsset( + footerArt, + self.client, + function displayed(err, artData) + { + callback(err, artData); + }); + + /* self.displayArtAsset(footerArt, function artDisplayed(err, artData) { callback(err, artData); }); +*/ } ], function complete(err, artData) { @@ -123,9 +134,18 @@ function FullScreenEditorModule(options) { [ function displayHeaderAndBody(callback) { async.eachSeries( comps, function dispArt(n, next) { + asset.displayArtAsset( + art[n], + self.client, + function displayed(err, artData) { + next(err); + }); + + /* self.displayArtAsset(art[n], function artDisplayed(err, artData) { next(err); }); + */ }, function complete(err) { callback(err); }); @@ -198,10 +218,20 @@ function FullScreenEditorModule(options) { assert(_.isString(art.body)); async.eachSeries( [ 'header', 'body' ], function dispArt(n, next) { + asset.displayArtAsset( + art[n], + self.client, + function displayed(err, artData) { + mciData[n] = artData; + next(err); + }); + + /* self.displayArtAsset(art[n], function artDisplayed(err, artData) { mciData[n] = artData; next(err); }); + */ }, function complete(err) { callback(err); });