Simon Hunt

GUI -- Added KeyService and FnService; implemented 'T' key for toggle theme.

Change-Id: I6ae3cb76aaa5c72422eac180cb46d604ead21afc
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
ONOS GUI -- General Purpose Functions
@author Simon Hunt
*/
(function (onos) {
'use strict';
onos.factory('FnService', [function () {
return {
isF: function (f) {
return $.isFunction(f) ? f : null;
},
isA: function (a) {
return $.isArray(a) ? a : null;
},
isS: function (s) {
return typeof s === 'string' ? s : null;
},
isO: function (o) {
return $.isPlainObject(o) ? o : null;
}
};
}]);
}(ONOS));
/*
* Copyright 2014 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
ONOS GUI -- Key Handler Service
@author Simon Hunt
*/
(function (onos) {
'use strict';
// references to injected services
var f;
// internal state
var keyHandler = {
globalKeys: {},
maskedKeys: {},
viewKeys: {},
viewFn: null,
viewGestures: []
},
theme = 'light';
// TODO: we need to have the concept of view token here..
function getViewToken() {
return 'NotYetAViewToken';
}
function whatKey(code) {
switch (code) {
case 13: return 'enter';
case 16: return 'shift';
case 17: return 'ctrl';
case 18: return 'alt';
case 27: return 'esc';
case 32: return 'space';
case 37: return 'leftArrow';
case 38: return 'upArrow';
case 39: return 'rightArrow';
case 40: return 'downArrow';
case 91: return 'cmdLeft';
case 93: return 'cmdRight';
case 187: return 'equals';
case 189: return 'dash';
case 191: return 'slash';
case 192: return 'backQuote';
case 220: return 'backSlash';
default:
if ((code >= 48 && code <= 57) ||
(code >= 65 && code <= 90)) {
return String.fromCharCode(code);
} else if (code >= 112 && code <= 123) {
return 'F' + (code - 111);
}
return '.';
}
}
function keyIn() {
var event = d3.event,
keyCode = event.keyCode,
key = whatKey(keyCode),
kh = keyHandler,
gk = kh.globalKeys[key],
gcb = f.isF(gk) || (f.isA(gk) && f.isF(gk[0])),
vk = kh.viewKeys[key],
vcb = f.isF(vk) || (f.isA(vk) && f.isF(vk[0])) || f.isF(kh.viewFn),
token = getViewToken();
// global callback?
if (gcb && gcb(token, key, keyCode, event)) {
// if the event was 'handled', we are done
return;
}
// otherwise, let the view callback have a shot
if (vcb) {
vcb(token, key, keyCode, event);
}
}
function setupGlobalKeys() {
$.extend(keyHandler, {
globalKeys: {
backSlash: [quickHelp, 'Show / hide Quick Help'],
slash: [quickHelp, 'Show / hide Quick Help'],
esc: [escapeKey, 'Dismiss dialog or cancel selections'],
T: [toggleTheme, "Toggle theme"]
},
globalFormat: ['backSlash', 'slash', 'esc', 'T'],
// Masked keys are global key handlers that always return true.
// That is, the view will never see the event for that key.
maskedKeys: {
slash: true,
backSlash: true,
T: true
}
});
}
function quickHelp(view, key, code, ev) {
// TODO: show quick help
//libApi.quickHelp.show(keyHandler);
console.log('QUICK-HELP');
return true;
}
function escapeKey(view, key, code, ev) {
// TODO: plumb in handling of alerts and quick help dismissal
/*
if (alerts.open) {
closeAlerts();
return true;
}
if (libApi.quickHelp.hide()) {
return true;
}
*/
console.log('ESCAPE');
return false;
}
function toggleTheme(view, key, code, ev) {
var body = d3.select('body');
theme = (theme === 'light') ? 'dark' : 'light';
body.classed('light dark', false);
body.classed(theme, true);
// TODO: emit theme-change event to current view...
//theme(view);
return true;
}
onos.factory('KeyService', ['FnService', function (fs) {
f = fs;
return {
init: function () {
console.log('initializing keydown handler....');
d3.select('body').on('keydown', keyIn);
setupGlobalKeys();
}
};
}]);
}(ONOS));
......@@ -27,13 +27,13 @@
<script src="../tp/d3.js"></script>
<script src="../tp/topojson.v1.min.js"></script>
<!-- NOTE: We are going to see if we can dispense with jQuery... -->
<!--<script src="../tp/jquery-2.1.1.min.js"></script>-->
<script src="../tp/jquery-2.1.1.min.js"></script>
<!-- ONOS UI Framework included here -->
<!-- TODO: use a single catenated-minified file here -->
<script src="onos.js"></script>
<script src="fw/lib/fn.js"></script>
<script src="fw/lib/keys.js"></script>
<script src="fw/mast/mast.js"></script>
<!-- Framework and library stylesheets included here -->
......@@ -50,16 +50,18 @@
<!-- TODO: inject style-sheet refs server-side -->
</head>
<body class="light" ng-app="onosApp">
<div id="mast"
ng-controller="MastCtrl as mastCtrl"
ng-include="'fw/mast/mast.html'"></div>
<div id="frame" ng-controller="OnosCtrl as onosCtrl">
<div id="mast"
ng-controller="MastCtrl as mastCtrl"
ng-include="'fw/mast/mast.html'"></div>
<div id="view" ng-view></div>
<div id="view" ng-view></div>
<div id="floatpanels"></div>
<div id="alerts"></div>
<div id="flash"></div>
<div id="quickhelp"></div>
<div id="deathmask"></div>
<div id="floatpanels"></div>
<div id="alerts"></div>
<div id="flash"></div>
<div id="quickhelp"></div>
<div id="deathmask"></div>
</div>
</body>
</html>
......
......@@ -19,13 +19,17 @@
@author Simon Hunt
*/
// our one global variable
var ONOS;
(function () {
'use strict';
angular.module('onosApp', ['onosMast'])
.controller('OnosCtrl', [function () {
// controller logic here
ONOS = angular.module('onosApp', ['onosMast'])
.controller('OnosCtrl', ['KeyService', function (ks) {
console.log('OnosCtrl has been created');
ks.init();
}]);
}());
......