From 5b1cec8789b22e8e436f9b86e3b5387db6354cd1 Mon Sep 17 00:00:00 2001 From: William Petit Date: Wed, 26 Aug 2015 17:53:46 +0200 Subject: [PATCH] Base categories --- css/style.css | 1 + default-profile.json | 18 +++++- index.html | 25 ++++++-- js/app.js | 141 ++++++++++++++++++++++++++++++++++++++----- 4 files changed, 162 insertions(+), 23 deletions(-) diff --git a/css/style.css b/css/style.css index b32143b..c4e93e9 100644 --- a/css/style.css +++ b/css/style.css @@ -43,6 +43,7 @@ li.app-item { transition: 150ms linear; position: relative; overflow: hidden; + min-width: 10%; } li.app-item::after { diff --git a/default-profile.json b/default-profile.json index 55345c0..0a8dc15 100644 --- a/default-profile.json +++ b/default-profile.json @@ -1,9 +1,21 @@ { "items": [ { - "label": "Chromium Browser", - "exec": "/usr/bin/chromium-browser", - "icon": "/usr/share/icons/Mint-X/apps/48/chromium-browser.png" + "label": "Root", + "icon": "/usr/share/icons/Mint-X/apps/48/chromium-browser.png", + "items": [ + { + "label": "Level 1", + "icon": "/usr/share/icons/Mint-X/apps/48/chromium-browser.png", + "items": [ + { + "label": "Chromium Browser", + "icon": "/usr/share/icons/Mint-X/apps/48/chromium-browser.png", + "exec": "/usr/bin/chromium-browser" + } + ] + } + ] } ] } diff --git a/index.html b/index.html index cc8e4f9..4d2e310 100644 --- a/index.html +++ b/index.html @@ -9,17 +9,32 @@
+ + + + + diff --git a/js/app.js b/js/app.js index 22f4644..b8f10e2 100644 --- a/js/app.js +++ b/js/app.js @@ -10,8 +10,12 @@ var gui = require('nw.gui'); var minimist = require('minimist'); - // Load templates - var itemsListTpl = Handlebars.compile(Pitaya.DOM.select('#items-list-tpl').innerHTML); + // Load templates... + var launcherViewTpl = Handlebars.compile(Pitaya.DOM.select('#launcher-view-tpl').innerHTML); + + // ... and partials + Handlebars.registerPartial('itemListTpl', Pitaya.DOM.select('#items-list-tpl').innerHTML); + Handlebars.registerPartial('itemTpl', Pitaya.DOM.select('#item-tpl').innerHTML); // Internal constants var DEFAULT_PROFILE = './default-profile.json'; @@ -34,6 +38,7 @@ .then(function() { return Pitaya; }) + .catch(Pitaya._onError) ; }; @@ -48,7 +53,7 @@ return Pitaya._loadJSONFile(profilePath) .then(function(profile) { Pitaya._profile = profile; - Pitaya.render(); + Pitaya.renderLauncherView(); return profile; }) ; @@ -59,10 +64,24 @@ * * @return Pitaya */ - Pitaya.render = function() { + Pitaya.renderLauncherView = function(currentItemPath) { + + console.log('render', currentItemPath); + + currentItemPath = Pitaya._normalizeItemPath(currentItemPath); var rootEl = Pitaya._rootEl; - var profile = Pitaya._profile; - rootEl.innerHTML = itemsListTpl(profile); + var currentItem = Pitaya._getItemByPath(currentItemPath); + + var data = { + currentItemPath: currentItemPath.join('.'), + currentItem: currentItem, + isRoot: currentItemPath.length === 0 + }; + + console.log('render data', data); + + rootEl.innerHTML = launcherViewTpl(data); + }; @@ -73,6 +92,7 @@ Pitaya._initListeners = function() { var rootEl = Pitaya._rootEl; rootEl.addEventListener('click', Pitaya._onItemClick); + rootEl.addEventListener('click', Pitaya._onGoBackClick); }; /** @@ -87,19 +107,105 @@ if( !appItemEl ) return; - var execPath = appItemEl.dataset.exec; + var itemPath = appItemEl.dataset.itemPath; + var item = Pitaya._getItemByPath(itemPath); - console.info('Launching application "'+execPath+'"...'); + console.log('item click',itemPath, item); - if(execPath) { - appItemEl.classList.add('loading'); - cp.exec(execPath, function(err) { - appItemEl.classList.remove('loading'); - if(err) return console.error(err.stack || err); - console.info('Application closed "'+execPath+'".'); - }); + if(!item) return; + + if('items' in item) { + return Pitaya.renderLauncherView(itemPath); } + if(item.exec) { + + console.info('Launching application "'+item.exec+'"...'); + appItemEl.classList.add('loading'); + + Pitaya._runApp(item.exec) + .then(function() { + appItemEl.classList.remove('loading'); + console.info('Application closed "'+item.exec+'".'); + }) + .catch(function(err) { + Pitaya._onError(err); + appItemEl.classList.remove('loading'); + }) + ; + + } + + }; + + /** + * GoBack button click handler + * @private + */ + Pitaya._onGoBackClick = function(evt) { + + var goBackEl = evt.srcElement.matches( '.goback') ? evt.srcElement : + Pitaya.DOM.getClosestAncestor(evt.srcElement, '.goback') + ; + + if(!goBackEl) return; + + var currentItemPath = goBackEl.dataset.itemPath; + var parentItemPath = Pitaya._normalizeItemPath(currentItemPath); + + parentItemPath.pop(); + + return Pitaya.renderLauncherView(parentItemPath); + + }; + + Pitaya._normalizeItemPath = function(itemPath) { + + if( Array.isArray(itemPath) ) return itemPath; + + if((typeof itemPath === 'string' && itemPath.length === 0) || !itemPath) return []; + + return itemPath.split('.').reduce(function(arr, index) { + if(index !== '') { + arr.push(+index); + } + return arr; + }, []); + + }; + + Pitaya._getItemByPath = function(itemPath, rootItem) { + + rootItem = rootItem || Pitaya._profile; + itemPath = Pitaya._normalizeItemPath(itemPath); + + var index = itemPath.slice(0,1)[0]; + + if(index === undefined) { + return rootItem; + } + + if(!('items' in rootItem)) { + return undefined; + } + + var subItem = rootItem.items[index]; + + if(itemPath.length === 0) { + return subItem; + } + + return Pitaya._getItemByPath(itemPath, subItem); + + }; + + Pitaya._runApp = function(execPath) { + return new Promise(function(resolve, reject) { + cp.exec(execPath, function(err) { + if(err) return reject(err); + return resolve(); + }); + }); }; /** @@ -123,4 +229,9 @@ }); }; + + Pitaya._onError = function(err) { + console.error(err.stack ? err.stack : err); + }; + }(window.Pitaya = window.Pitaya || {}, window));