From 3a284eca1fc43cc4a5d6346aa72d30751bdc1168 Mon Sep 17 00:00:00 2001 From: Gunther Brunner Date: Wed, 19 Feb 2014 15:46:31 +0900 Subject: [PATCH] All services and controllers are implemented. --- .../components/stf/control/control-service.js | 58 ++++++--- res/app/components/stf/screen/index.js | 4 + .../stf/{control => screen}/scaling/index.js | 0 .../scaling/scaling-service.js | 0 .../components/stf/screen/screen-directive.js | 122 ++++++++++++++++++ res/app/components/stf/screen/screen.jade | 4 + .../device-control-controller.js | 11 ++ res/app/device-control/device-control.css | 39 ++++++ res/app/device-control/device-control.jade | 8 ++ res/app/device-control/index.js | 13 ++ .../device-screen/device-screen-controller.js | 9 ++ res/app/device-screen/index.js | 7 +- 12 files changed, 256 insertions(+), 19 deletions(-) create mode 100644 res/app/components/stf/screen/index.js rename res/app/components/stf/{control => screen}/scaling/index.js (100%) rename res/app/components/stf/{control => screen}/scaling/scaling-service.js (100%) create mode 100644 res/app/components/stf/screen/screen-directive.js create mode 100644 res/app/components/stf/screen/screen.jade create mode 100644 res/app/device-control/device-control-controller.js create mode 100644 res/app/device-control/device-control.css create mode 100644 res/app/device-control/device-control.jade create mode 100644 res/app/device-screen/device-screen-controller.js diff --git a/res/app/components/stf/control/control-service.js b/res/app/components/stf/control/control-service.js index ec78cf90..1f27979b 100644 --- a/res/app/components/stf/control/control-service.js +++ b/res/app/components/stf/control/control-service.js @@ -3,6 +3,37 @@ module.exports = function ControlServiceFactory($rootScope, socket) { } function ControlService(channel) { + var keyCodes = { + 8: 8 // backspace + , 13: 13 // enter + , 20: 20 // caps lock + , 27: 27 // esc + , 33: 33 // page up + , 34: 34 // page down + , 35: 35 // end + , 36: 36 // home + , 37: 37 // left arrow + , 38: 38 // up arrow + , 39: 39 // right arrow + , 40: 40 // down arrow + , 45: 45 // insert + , 46: 46 // delete + , 93: 93 // windows menu key + , 112: 112 // f1 + , 113: 113 // f2 + , 114: 114 // f3 + , 115: 115 // f4 + , 116: 116 // f5 + , 117: 117 // f6 + , 118: 118 // f7 + , 119: 119 // f8 + , 120: 120 // f9 + , 121: 121 // f10 + , 122: 122 // f11 + , 123: 123 // f12 + , 144: 144 // num lock + } + function touchSender(type) { return function (x, y) { socket.emit(type, channel, { @@ -11,11 +42,14 @@ module.exports = function ControlServiceFactory($rootScope, socket) { } } - function keySender(type) { + function keySender(type, fixedKey) { return function (key) { - socket.emit(type, channel, { - key: key - }) + var mapped = fixedKey || keyCodes[key] + if (mapped) { + socket.emit(type, channel, { + key: mapped + }) + } } } @@ -28,17 +62,9 @@ module.exports = function ControlServiceFactory($rootScope, socket) { this.keyUp = keySender('input.keyUp') this.keyPress = keySender('input.keyPress') - this.home = function () { - socket.emit('input.home', channel) - } - - this.menu = function () { - socket.emit('input.menu', channel) - } - - this.back = function () { - socket.emit('input.back', channel) - } + this.home = keySender('input.keyPress', 3) + this.menu = keySender('input.keyPress', 93) + this.back = keySender('input.keyPress', 4) this.type = function (text) { socket.emit('input.type', channel, { @@ -52,4 +78,4 @@ module.exports = function ControlServiceFactory($rootScope, socket) { } return controlService -} +} \ No newline at end of file diff --git a/res/app/components/stf/screen/index.js b/res/app/components/stf/screen/index.js new file mode 100644 index 00000000..a9d228a5 --- /dev/null +++ b/res/app/components/stf/screen/index.js @@ -0,0 +1,4 @@ +module.exports = angular.module('stf/screen', [ + require('stf/screen/scaling').name +]) + .factory('DeviceScreenDirective', require('./screen-directive')); diff --git a/res/app/components/stf/control/scaling/index.js b/res/app/components/stf/screen/scaling/index.js similarity index 100% rename from res/app/components/stf/control/scaling/index.js rename to res/app/components/stf/screen/scaling/index.js diff --git a/res/app/components/stf/control/scaling/scaling-service.js b/res/app/components/stf/screen/scaling/scaling-service.js similarity index 100% rename from res/app/components/stf/control/scaling/scaling-service.js rename to res/app/components/stf/screen/scaling/scaling-service.js diff --git a/res/app/components/stf/screen/screen-directive.js b/res/app/components/stf/screen/screen-directive.js new file mode 100644 index 00000000..94902bb3 --- /dev/null +++ b/res/app/components/stf/screen/screen-directive.js @@ -0,0 +1,122 @@ +module.exports = function DeviceScreenDirective($document, ScalingService) { + return { + restrict: 'E', + template: require('./screen.jade'), + link: function ($scope, element, attrs) { + $scope.promiseOfDevice.then(function (device) { + var loader = new Image() + , canvas = element.find('canvas')[0] + , finger = element.find('span') + , g = canvas.getContext('2d') + , displayWidth = 0 + , displayHeight = 0 + , scaler = ScalingService.coordinator( + device.display.width + , device.display.height + ) + + function updateDisplaySize() { + displayWidth = element[0].offsetWidth + displayHeight = element[0].offsetHeight + + // Developer error, let's try to reduce debug time + if (!displayWidth || !displayHeight) { + throw new Error( + 'Unable to update display size; container must have dimensions' + ) + } + } + + function loadScreen() { + loader.src = device.display.url + + '?width=' + displayWidth + + '&height=' + displayHeight + + '&time=' + Date.now() + } + + loader.onload = function () { + var size = scaler.projectedSize(displayWidth, displayHeight) + + // Make sure we're rendering pixels 1 to 1 + canvas.width = this.width + canvas.height = this.height + + // Perhaps we have a massive screen but not enough pixels. Let's + // scale up + canvas.style.width = size.width + 'px' + canvas.style.height = size.height + 'px' + + // Draw the image + g.drawImage(this, 0, 0) + + // Reset error, if any + if ($scope.displayError) { + $scope.$apply(function () { + $scope.displayError = false + }) + } + + // Next please + loadScreen() + } + + loader.onerror = function () { + $scope.$apply(function () { + $scope.displayError = true + }) + } + + function sendTouch(type, e) { + var scaled = scaler.coords( + displayWidth + , displayHeight + , e.offsetX + , e.offsetY + ) + + finger[0].style.webkitTransform = + 'translate3d(' + e.offsetX + 'px,' + e.offsetY + 'px,0)' + + $scope.control[type]( + scaled.xP * device.display.width + , scaled.yP * device.display.height + ) + } + + function downListener(e) { + e.preventDefault() + element.addClass('fingering') + sendTouch('touchDown', e) + element.bind('mousemove', moveListener) + $document.bind('mouseup', upListener) + $document.bind('mouseleave', upListener) + } + + function moveListener(e) { + sendTouch('touchMove', e) + } + + function upListener(e) { + sendTouch('touchUp', e) + stop() + } + + function stop() { + element.removeClass('fingering') + element.unbind('mousemove', moveListener) + $document.unbind('mouseup', upListener) + $document.unbind('mouseleave', upListener) + } + + $scope.$on('$destroy', function () { + loader.onload = loader.onerror = null + stop() + }) + + element.bind('mousedown', downListener) + updateDisplaySize() + loadScreen() + }) + } + } +} \ No newline at end of file diff --git a/res/app/components/stf/screen/screen.jade b/res/app/components/stf/screen/screen.jade new file mode 100644 index 00000000..837b8f53 --- /dev/null +++ b/res/app/components/stf/screen/screen.jade @@ -0,0 +1,4 @@ +canvas(ng-show='ready') +div(ng-if='displayError') Screen error +textarea(tabindex='-1') +span.finger \ No newline at end of file diff --git a/res/app/device-control/device-control-controller.js b/res/app/device-control/device-control-controller.js new file mode 100644 index 00000000..ec85a27f --- /dev/null +++ b/res/app/device-control/device-control-controller.js @@ -0,0 +1,11 @@ +module.exports = function DeviceControlCtrl($scope, $routeParams, DeviceService, ControlService) { + $scope.device = null + $scope.control = null + + $scope.promiseOfDevice = DeviceService.get($routeParams.serial) + .then(function (device) { + $scope.device = device + $scope.control = ControlService.forChannel(device.channel) + return device + }) +} \ No newline at end of file diff --git a/res/app/device-control/device-control.css b/res/app/device-control/device-control.css new file mode 100644 index 00000000..26b89808 --- /dev/null +++ b/res/app/device-control/device-control.css @@ -0,0 +1,39 @@ +device-screen { + position: relative; + display: block; +} + +device-screen canvas { + position: absolute; + margin: auto; + top: 0; + right: 0; + bottom: 0; + left: 0; + pointer-events: none; /* MUST HAVE */ +} + +device-screen .finger { + position: absolute; + border-radius: 50%; + background: lime; + opacity: 0.5; + width: 6mm; + height: 6mm; + top: -3mm; + left: -3mm; + pointer-events: none; + display: none; +} + +device-screen.fingering .finger { + display: block; +} + +device-screen textarea { + position: absolute; + z-index: 10; + outline: none; + pointer-events: none; + opacity: 0; +} \ No newline at end of file diff --git a/res/app/device-control/device-control.jade b/res/app/device-control/device-control.jade new file mode 100644 index 00000000..e0c587e2 --- /dev/null +++ b/res/app/device-control/device-control.jade @@ -0,0 +1,8 @@ +h1 {{ device.serial }} + +div(ng-controller='DeviceScreenCtrl') + device-screen(style='width: 400px; height: 600px; background: gray') + +button(ng-click='control.menu()') Menu +button(ng-click='control.home()') Home +button(ng-click='control.back()') Back \ No newline at end of file diff --git a/res/app/device-control/index.js b/res/app/device-control/index.js index e69de29b..cfcdfded 100644 --- a/res/app/device-control/index.js +++ b/res/app/device-control/index.js @@ -0,0 +1,13 @@ +require('./device-control.css') + +module.exports = angular.module('device-control', [ + require('stf/device').name, + require('stf/control').name +]) + .config(['$routeProvider', function ($routeProvider) { + $routeProvider.when('/devices/:serial', { + template: require('./device-control.jade'), + controller: 'DeviceControlCtrl' + }) + }]) + .controller('DeviceControlCtrl', require('./device-control-controller')) diff --git a/res/app/device-screen/device-screen-controller.js b/res/app/device-screen/device-screen-controller.js new file mode 100644 index 00000000..148375d3 --- /dev/null +++ b/res/app/device-screen/device-screen-controller.js @@ -0,0 +1,9 @@ +module.exports = function DeviceScreenCtrl($scope, ScalingService) { + $scope.ready = false + $scope.displayError = false + $scope.ScalingService = ScalingService + + $scope.promiseOfDevice.then(function () { + $scope.ready = true + }) +} diff --git a/res/app/device-screen/index.js b/res/app/device-screen/index.js index 7ec795a2..3deb5002 100644 --- a/res/app/device-screen/index.js +++ b/res/app/device-screen/index.js @@ -1,3 +1,4 @@ -/** - * Created by A12907 on 2/14/14. - */ +module.exports = angular.module('device-screen-controller', [ + require('stf/screen/scaling').name +]) + .controller('DeviceScreenCtrl', require('./device-screen-controller'))