mirror of
https://github.com/openstf/stf
synced 2025-10-05 10:39:25 +02:00
All services and controllers are implemented.
This commit is contained in:
parent
ffce3d5beb
commit
3a284eca1f
12 changed files with 256 additions and 19 deletions
|
@ -3,6 +3,37 @@ module.exports = function ControlServiceFactory($rootScope, socket) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function ControlService(channel) {
|
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) {
|
function touchSender(type) {
|
||||||
return function (x, y) {
|
return function (x, y) {
|
||||||
socket.emit(type, channel, {
|
socket.emit(type, channel, {
|
||||||
|
@ -11,13 +42,16 @@ module.exports = function ControlServiceFactory($rootScope, socket) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function keySender(type) {
|
function keySender(type, fixedKey) {
|
||||||
return function (key) {
|
return function (key) {
|
||||||
|
var mapped = fixedKey || keyCodes[key]
|
||||||
|
if (mapped) {
|
||||||
socket.emit(type, channel, {
|
socket.emit(type, channel, {
|
||||||
key: key
|
key: mapped
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.touchDown = touchSender('input.touchDown')
|
this.touchDown = touchSender('input.touchDown')
|
||||||
this.touchMove = touchSender('input.touchMove')
|
this.touchMove = touchSender('input.touchMove')
|
||||||
|
@ -28,17 +62,9 @@ module.exports = function ControlServiceFactory($rootScope, socket) {
|
||||||
this.keyUp = keySender('input.keyUp')
|
this.keyUp = keySender('input.keyUp')
|
||||||
this.keyPress = keySender('input.keyPress')
|
this.keyPress = keySender('input.keyPress')
|
||||||
|
|
||||||
this.home = function () {
|
this.home = keySender('input.keyPress', 3)
|
||||||
socket.emit('input.home', channel)
|
this.menu = keySender('input.keyPress', 93)
|
||||||
}
|
this.back = keySender('input.keyPress', 4)
|
||||||
|
|
||||||
this.menu = function () {
|
|
||||||
socket.emit('input.menu', channel)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.back = function () {
|
|
||||||
socket.emit('input.back', channel)
|
|
||||||
}
|
|
||||||
|
|
||||||
this.type = function (text) {
|
this.type = function (text) {
|
||||||
socket.emit('input.type', channel, {
|
socket.emit('input.type', channel, {
|
||||||
|
|
4
res/app/components/stf/screen/index.js
Normal file
4
res/app/components/stf/screen/index.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = angular.module('stf/screen', [
|
||||||
|
require('stf/screen/scaling').name
|
||||||
|
])
|
||||||
|
.factory('DeviceScreenDirective', require('./screen-directive'));
|
122
res/app/components/stf/screen/screen-directive.js
Normal file
122
res/app/components/stf/screen/screen-directive.js
Normal file
|
@ -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()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
res/app/components/stf/screen/screen.jade
Normal file
4
res/app/components/stf/screen/screen.jade
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
canvas(ng-show='ready')
|
||||||
|
div(ng-if='displayError') Screen error
|
||||||
|
textarea(tabindex='-1')
|
||||||
|
span.finger
|
11
res/app/device-control/device-control-controller.js
Normal file
11
res/app/device-control/device-control-controller.js
Normal file
|
@ -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
|
||||||
|
})
|
||||||
|
}
|
39
res/app/device-control/device-control.css
Normal file
39
res/app/device-control/device-control.css
Normal file
|
@ -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;
|
||||||
|
}
|
8
res/app/device-control/device-control.jade
Normal file
8
res/app/device-control/device-control.jade
Normal file
|
@ -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
|
|
@ -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'))
|
9
res/app/device-screen/device-screen-controller.js
Normal file
9
res/app/device-screen/device-screen-controller.js
Normal file
|
@ -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
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
/**
|
module.exports = angular.module('device-screen-controller', [
|
||||||
* Created by A12907 on 2/14/14.
|
require('stf/screen/scaling').name
|
||||||
*/
|
])
|
||||||
|
.controller('DeviceScreenCtrl', require('./device-screen-controller'))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue