mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
535 lines
20 KiB
JavaScript
535 lines
20 KiB
JavaScript
|
/*global define */
|
||
|
define([
|
||
|
'lib/stapes', 'views/MainView', 'models/Settings', 'views/SettingsView', 'views/EffectsView', 'views/TransformView', 'data/ServerControl', 'api/Socket', 'api/Network'
|
||
|
], function (Stapes, MainView, Settings, SettingsView, EffectsView, TransformView, ServerControl, Socket, Network) {
|
||
|
'use strict';
|
||
|
var network = new Network();
|
||
|
|
||
|
return Stapes.subclass(/** @lends AppController.prototype */{
|
||
|
/**
|
||
|
* @type MainView
|
||
|
*/
|
||
|
mainView: null,
|
||
|
/**
|
||
|
* @type SettingsView
|
||
|
*/
|
||
|
settingsView: null,
|
||
|
/**
|
||
|
* @type EffectsView
|
||
|
*/
|
||
|
effectsView: null,
|
||
|
/**
|
||
|
* @type TransformView
|
||
|
*/
|
||
|
transformView: null,
|
||
|
/**
|
||
|
* @type Settings
|
||
|
*/
|
||
|
settings: null,
|
||
|
/**
|
||
|
* @type ServerControl
|
||
|
*/
|
||
|
serverControl: null,
|
||
|
color: {
|
||
|
r: 25,
|
||
|
g: 25,
|
||
|
b: 25
|
||
|
},
|
||
|
effects: [],
|
||
|
transform: {},
|
||
|
selectedServer: null,
|
||
|
|
||
|
/**
|
||
|
* @class AppController
|
||
|
* @constructs
|
||
|
*/
|
||
|
constructor: function () {
|
||
|
this.mainView = new MainView();
|
||
|
this.settingsView = new SettingsView();
|
||
|
this.effectsView = new EffectsView();
|
||
|
this.transformView = new TransformView();
|
||
|
|
||
|
this.settings = new Settings();
|
||
|
|
||
|
this.bindEventHandlers();
|
||
|
this.mainView.setColor(this.color);
|
||
|
|
||
|
if (!network.canDetectLocalAddress()) {
|
||
|
this.settingsView.enableDetectButton(false);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Do initialization
|
||
|
*/
|
||
|
init: function () {
|
||
|
this.settings.load();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
bindEventHandlers: function () {
|
||
|
this.settings.on({
|
||
|
'loaded': function () {
|
||
|
var i;
|
||
|
|
||
|
for (i = 0; i < this.settings.servers.length; i++) {
|
||
|
if (this.settings.servers[i].selected) {
|
||
|
this.selectedServer = this.settings.servers[i];
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.settingsView.fillServerList(this.settings.servers);
|
||
|
|
||
|
if (!this.selectedServer) {
|
||
|
this.gotoArea('settings');
|
||
|
} else {
|
||
|
this.connectToServer(this.selectedServer);
|
||
|
}
|
||
|
},
|
||
|
'error': function (message) {
|
||
|
this.showError(message);
|
||
|
},
|
||
|
'serverAdded': function (server) {
|
||
|
var i;
|
||
|
for (i = 0; i < this.settings.servers.length; i++) {
|
||
|
if (this.settings.servers[i].selected) {
|
||
|
this.selectedServer = this.settings.servers[i];
|
||
|
this.connectToServer(server);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.settingsView.fillServerList(this.settings.servers);
|
||
|
},
|
||
|
'serverChanged': function (server) {
|
||
|
var i;
|
||
|
for (i = 0; i < this.settings.servers.length; i++) {
|
||
|
if (this.settings.servers[i].selected) {
|
||
|
this.selectedServer = this.settings.servers[i];
|
||
|
this.connectToServer(server);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.settingsView.fillServerList(this.settings.servers);
|
||
|
this.connectToServer(server);
|
||
|
},
|
||
|
'serverRemoved': function () {
|
||
|
var i, removedSelected = true;
|
||
|
this.settingsView.fillServerList(this.settings.servers);
|
||
|
|
||
|
for (i = 0; i < this.settings.servers.length; i++) {
|
||
|
if (this.settings.servers[i].selected) {
|
||
|
removedSelected = false;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (removedSelected) {
|
||
|
this.selectedServer = null;
|
||
|
if (this.serverControl) {
|
||
|
this.serverControl.disconnect();
|
||
|
}
|
||
|
this.effectsView.clear();
|
||
|
this.transformView.clear();
|
||
|
}
|
||
|
}
|
||
|
}, this);
|
||
|
|
||
|
this.mainView.on({
|
||
|
'barClick': function (id) {
|
||
|
if (id !== 'settings') {
|
||
|
if (!this.selectedServer) {
|
||
|
this.showError('No server selected');
|
||
|
} else if (!this.serverControl) {
|
||
|
this.connectToServer(this.selectedServer);
|
||
|
}
|
||
|
}
|
||
|
this.gotoArea(id);
|
||
|
},
|
||
|
'colorChange': function (color) {
|
||
|
this.color = color;
|
||
|
|
||
|
if (!this.selectedServer) {
|
||
|
this.showError('No server selected');
|
||
|
} else if (!this.serverControl) {
|
||
|
this.connectToServer(this.selectedServer, function () {
|
||
|
this.serverControl.setColor(color, this.selectedServer.duration);
|
||
|
}.bind(this));
|
||
|
} else {
|
||
|
this.serverControl.setColor(color, this.selectedServer.duration);
|
||
|
}
|
||
|
},
|
||
|
'clear': function () {
|
||
|
if (!this.selectedServer) {
|
||
|
this.showError('No server selected');
|
||
|
} else if (!this.serverControl) {
|
||
|
this.connectToServer(this.selectedServer, function () {
|
||
|
this.serverControl.clear();
|
||
|
}.bind(this));
|
||
|
} else {
|
||
|
this.serverControl.clear();
|
||
|
}
|
||
|
},
|
||
|
'clearall': function () {
|
||
|
if (!this.selectedServer) {
|
||
|
this.showError('No server selected');
|
||
|
} else if (!this.serverControl) {
|
||
|
this.connectToServer(this.selectedServer, function () {
|
||
|
this.serverControl.clearall();
|
||
|
this.mainView.setColor({r: 0, g: 0, b: 0});
|
||
|
}.bind(this));
|
||
|
} else {
|
||
|
this.serverControl.clearall();
|
||
|
this.mainView.setColor({r: 0, g: 0, b: 0});
|
||
|
}
|
||
|
}
|
||
|
}, this);
|
||
|
|
||
|
this.settingsView.on({
|
||
|
'serverAdded': function (server) {
|
||
|
if (server.address && server.port) {
|
||
|
server.priority = server.priority || 50;
|
||
|
this.settings.addServer(server);
|
||
|
this.lockSettingsView(false);
|
||
|
} else {
|
||
|
this.showError('Invalid server data');
|
||
|
}
|
||
|
},
|
||
|
'serverAddCanceled': function () {
|
||
|
this.lockSettingsView(false);
|
||
|
this.settingsView.fillServerList(this.settings.servers);
|
||
|
},
|
||
|
'serverEditCanceled': function () {
|
||
|
this.lockSettingsView(false);
|
||
|
this.settingsView.fillServerList(this.settings.servers);
|
||
|
},
|
||
|
'serverSelected': function (index) {
|
||
|
this.lockSettingsView(false);
|
||
|
this.settings.setSelectedServer(index);
|
||
|
},
|
||
|
'serverRemoved': function (index) {
|
||
|
this.settings.removeServer(index);
|
||
|
},
|
||
|
'serverChanged': function (data) {
|
||
|
if (data.server.address && data.server.port) {
|
||
|
data.server.priority = data.server.priority || 50;
|
||
|
this.settings.updateServer(data.index, data.server);
|
||
|
this.lockSettingsView(false);
|
||
|
} else {
|
||
|
this.showError('Invalid server data');
|
||
|
}
|
||
|
},
|
||
|
'editServer': function (index) {
|
||
|
var server = this.settings.servers[index];
|
||
|
this.settingsView.editServer({index: index, server: server});
|
||
|
},
|
||
|
'durationChanged': function (value) {
|
||
|
this.settings.duration = value;
|
||
|
this.settings.save();
|
||
|
},
|
||
|
'detect': function () {
|
||
|
this.lockSettingsView(true);
|
||
|
this.settingsView.showWaiting(true);
|
||
|
this.searchForServer(function (server) {
|
||
|
this.settings.addServer(server);
|
||
|
}.bind(this), function () {
|
||
|
this.lockSettingsView(false);
|
||
|
this.settingsView.showWaiting(false);
|
||
|
}.bind(this));
|
||
|
}
|
||
|
}, this);
|
||
|
|
||
|
this.effectsView.on({
|
||
|
'effectSelected': function (effectId) {
|
||
|
if (!this.serverControl) {
|
||
|
this.connectToServer(this.selectedServer, function () {
|
||
|
this.serverControl.runEffect(this.effects[parseInt(effectId)]);
|
||
|
}.bind(this));
|
||
|
} else {
|
||
|
this.serverControl.runEffect(this.effects[parseInt(effectId)]);
|
||
|
}
|
||
|
}
|
||
|
}, this);
|
||
|
|
||
|
this.transformView.on({
|
||
|
'gamma': function (data) {
|
||
|
if (data.r) {
|
||
|
this.transform.gamma[0] = data.r;
|
||
|
} else if (data.g) {
|
||
|
this.transform.gamma[1] = data.g;
|
||
|
} else if (data.b) {
|
||
|
this.transform.gamma[2] = data.b;
|
||
|
}
|
||
|
|
||
|
if (this.serverControl) {
|
||
|
this.serverControl.setTransform(this.transform);
|
||
|
}
|
||
|
},
|
||
|
'whitelevel': function (data) {
|
||
|
if (data.r) {
|
||
|
this.transform.whitelevel[0] = data.r;
|
||
|
} else if (data.g) {
|
||
|
this.transform.whitelevel[1] = data.g;
|
||
|
} else if (data.b) {
|
||
|
this.transform.whitelevel[2] = data.b;
|
||
|
}
|
||
|
|
||
|
if (this.serverControl) {
|
||
|
this.serverControl.setTransform(this.transform);
|
||
|
}
|
||
|
},
|
||
|
'blacklevel': function (data) {
|
||
|
if (data.r) {
|
||
|
this.transform.blacklevel[0] = data.r;
|
||
|
} else if (data.g) {
|
||
|
this.transform.blacklevel[1] = data.g;
|
||
|
} else if (data.b) {
|
||
|
this.transform.blacklevel[2] = data.b;
|
||
|
}
|
||
|
|
||
|
if (this.serverControl) {
|
||
|
this.serverControl.setTransform(this.transform);
|
||
|
}
|
||
|
},
|
||
|
'threshold': function (data) {
|
||
|
if (data.r) {
|
||
|
this.transform.threshold[0] = data.r;
|
||
|
} else if (data.g) {
|
||
|
this.transform.threshold[1] = data.g;
|
||
|
} else if (data.b) {
|
||
|
this.transform.threshold[2] = data.b;
|
||
|
}
|
||
|
|
||
|
if (this.serverControl) {
|
||
|
this.serverControl.setTransform(this.transform);
|
||
|
}
|
||
|
},
|
||
|
'hsv': function (data) {
|
||
|
if (data.valueGain) {
|
||
|
this.transform.valueGain = data.valueGain;
|
||
|
} else if (data.saturationGain) {
|
||
|
this.transform.saturationGain = data.saturationGain;
|
||
|
}
|
||
|
|
||
|
if (this.serverControl) {
|
||
|
this.serverControl.setTransform(this.transform);
|
||
|
}
|
||
|
}
|
||
|
}, this);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* @param id
|
||
|
*/
|
||
|
gotoArea: function (id) {
|
||
|
this.mainView.scrollToArea(id);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* @param server
|
||
|
*/
|
||
|
connectToServer: function (server, onConnected) {
|
||
|
if (this.serverControl) {
|
||
|
if (this.serverControl.isConnecting()) {
|
||
|
return;
|
||
|
}
|
||
|
this.serverControl.off();
|
||
|
this.serverControl.disconnect();
|
||
|
this.transformView.clear();
|
||
|
this.effectsView.clear();
|
||
|
}
|
||
|
|
||
|
this.serverControl = new ServerControl(server, Socket);
|
||
|
this.serverControl.on({
|
||
|
connected: function () {
|
||
|
this.serverControl.getServerInfo();
|
||
|
},
|
||
|
serverInfo: function (info) {
|
||
|
var index;
|
||
|
if (!this.selectedServer.name || this.selectedServer.name.length === 0) {
|
||
|
this.selectedServer.name = info.hostname;
|
||
|
index = this.settings.indexOfServer(this.selectedServer);
|
||
|
this.settings.updateServer(index, this.selectedServer);
|
||
|
this.settingsView.fillServerList(this.settings.servers);
|
||
|
}
|
||
|
this.effects = info.effects;
|
||
|
this.transform = info.transform[0];
|
||
|
this.updateView();
|
||
|
this.showStatus('Connected to ' + this.selectedServer.name);
|
||
|
if (onConnected) {
|
||
|
onConnected();
|
||
|
}
|
||
|
},
|
||
|
error: function (message) {
|
||
|
this.serverControl = null;
|
||
|
this.showError(message);
|
||
|
}
|
||
|
}, this);
|
||
|
this.serverControl.connect();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
updateView: function () {
|
||
|
var i, effects = [];
|
||
|
if (this.effects) {
|
||
|
for (i = 0; i < this.effects.length; i++) {
|
||
|
effects.push({id: i, name: this.effects[i].name});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.effectsView.clear();
|
||
|
this.effectsView.fillList(effects);
|
||
|
|
||
|
this.transformView.clear();
|
||
|
this.transformView.fillList(this.transform);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Shows the error text
|
||
|
* @param {string} error - Error message
|
||
|
*/
|
||
|
showError: function (error) {
|
||
|
this.mainView.showError(error);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Shows a message
|
||
|
* @param {string} message - Text to show
|
||
|
*/
|
||
|
showStatus: function (message) {
|
||
|
this.mainView.showStatus(message);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* @param lock
|
||
|
*/
|
||
|
lockSettingsView: function (lock) {
|
||
|
if (network.canDetectLocalAddress()) {
|
||
|
this.settingsView.enableDetectButton(!lock);
|
||
|
}
|
||
|
this.settingsView.lockList(lock);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* @param onFound
|
||
|
* @param onEnd
|
||
|
*/
|
||
|
searchForServer: function (onFound, onEnd) {
|
||
|
network.getLocalInterfaces(function (ips) {
|
||
|
if (ips.length === 0) {
|
||
|
onEnd();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
function checkInterface (localInterfaceAddress, ciOnFinished) {
|
||
|
var index, ipParts, addr;
|
||
|
|
||
|
index = 1;
|
||
|
ipParts = localInterfaceAddress.split('.');
|
||
|
ipParts[3] = index;
|
||
|
addr = ipParts.join('.');
|
||
|
|
||
|
function checkAddressRange (startAddress, count, carOnFinished) {
|
||
|
var ipParts, i, addr, cbCounter = 0, last;
|
||
|
|
||
|
function checkAddress (address, port, caOnFinished) {
|
||
|
var server = new ServerControl({'address': address, 'port': port}, Socket);
|
||
|
server.on({
|
||
|
'error': function () {
|
||
|
server.disconnect();
|
||
|
caOnFinished();
|
||
|
},
|
||
|
'connected': function () {
|
||
|
server.getServerInfo();
|
||
|
},
|
||
|
'serverInfo': function (result) {
|
||
|
var serverInfo = {
|
||
|
'address': address,
|
||
|
'port': port,
|
||
|
'priority': 50
|
||
|
};
|
||
|
server.disconnect();
|
||
|
|
||
|
if (result.hostname) {
|
||
|
serverInfo.name = result.hostname;
|
||
|
}
|
||
|
|
||
|
caOnFinished(serverInfo);
|
||
|
}
|
||
|
});
|
||
|
server.connect();
|
||
|
}
|
||
|
|
||
|
function checkAddressDoneCb (serverInfo) {
|
||
|
var ipParts, nextAddr;
|
||
|
|
||
|
if (serverInfo && onFound) {
|
||
|
onFound(serverInfo);
|
||
|
}
|
||
|
|
||
|
cbCounter++;
|
||
|
if (cbCounter === count) {
|
||
|
ipParts = startAddress.split('.');
|
||
|
ipParts[3] = parseInt(ipParts[3]) + count;
|
||
|
nextAddr = ipParts.join('.');
|
||
|
carOnFinished(nextAddr);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ipParts = startAddress.split('.');
|
||
|
last = parseInt(ipParts[3]);
|
||
|
|
||
|
for (i = 0; i < count; i++) {
|
||
|
ipParts[3] = last + i;
|
||
|
addr = ipParts.join('.');
|
||
|
|
||
|
checkAddress(addr, 19444, checkAddressDoneCb);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function checkAddressRangeCb (nextAddr) {
|
||
|
var ipParts, count = 64, lastPart;
|
||
|
|
||
|
ipParts = nextAddr.split('.');
|
||
|
lastPart = parseInt(ipParts[3]);
|
||
|
if (lastPart === 255) {
|
||
|
ciOnFinished();
|
||
|
return;
|
||
|
} else if (lastPart + 64 > 254) {
|
||
|
count = 255 - lastPart;
|
||
|
}
|
||
|
|
||
|
checkAddressRange(nextAddr, count, checkAddressRangeCb);
|
||
|
}
|
||
|
|
||
|
// do search in chunks because the dispatcher used in the ios socket plugin can handle only 64 threads
|
||
|
checkAddressRange(addr, 64, checkAddressRangeCb);
|
||
|
}
|
||
|
|
||
|
function checkInterfaceCb () {
|
||
|
if (ips.length === 0) {
|
||
|
onEnd();
|
||
|
} else {
|
||
|
checkInterface(ips.pop(), checkInterfaceCb);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
checkInterface(ips.pop(), checkInterfaceCb);
|
||
|
|
||
|
}.bind(this), function (error) {
|
||
|
this.showError(error);
|
||
|
}.bind(this));
|
||
|
}
|
||
|
});
|
||
|
});
|