GUI -- Added KeyService and FnService; implemented 'T' key for toggle theme.
Change-Id: I6ae3cb76aaa5c72422eac180cb46d604ead21afc
diff --git a/web/gui/src/main/webapp/app/fw/lib/fn.js b/web/gui/src/main/webapp/app/fw/lib/fn.js
new file mode 100644
index 0000000..15a8843
--- /dev/null
+++ b/web/gui/src/main/webapp/app/fw/lib/fn.js
@@ -0,0 +1,42 @@
+/*
+ * 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));
diff --git a/web/gui/src/main/webapp/app/fw/lib/keys.js b/web/gui/src/main/webapp/app/fw/lib/keys.js
new file mode 100644
index 0000000..3c0a26a
--- /dev/null
+++ b/web/gui/src/main/webapp/app/fw/lib/keys.js
@@ -0,0 +1,158 @@
+/*
+ * 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));
diff --git a/web/gui/src/main/webapp/app/index.html b/web/gui/src/main/webapp/app/index.html
index d820b96..6084854 100644
--- a/web/gui/src/main/webapp/app/index.html
+++ b/web/gui/src/main/webapp/app/index.html
@@ -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>
diff --git a/web/gui/src/main/webapp/app/onos.js b/web/gui/src/main/webapp/app/onos.js
index ea29256..631464b 100644
--- a/web/gui/src/main/webapp/app/onos.js
+++ b/web/gui/src/main/webapp/app/onos.js
@@ -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();
}]);
}());