Migrate UI code into libraries

This commit is contained in:
Matt 2016-05-16 10:41:11 -04:00
parent ae2c490afd
commit 9532c8cd8f
5 changed files with 610 additions and 1152 deletions

View File

@ -3046,14 +3046,14 @@ var remote = require('remote'),
humanizeDuration = require('humanize-duration')
ipcRenderer = require('electron').ipcRenderer,
mcopy = {},
light = {},
light = require('./lib/light-ui.js'),
proj = {},
cam = {},
nav = {},
seq = {},
seq = require('./lib/seq-ui.js'),
cmd = {},
gui = {},
log = {};
log = require('./lib/log-ui.js');
//console.log(ipcRenderer.sendSync('light', { 'fuck' : true }) );
mcopy.cfg = JSON.parse(fs.readFileSync('./data/cfg.json'), 'utf8');
@ -3095,224 +3095,6 @@ mcopy.state = {
}
};
log.time = 'MM/DD/YY-HH:mm:ss';
log.count = 0;
log.init = function () {
'use strict';
$('#log').w2grid({
name : 'log',
columns: [
{ field: 'time', caption: 'Time', size: '22%' },
{ field: 'action', caption: 'Action', size: '58%' },
{ field: 'service', caption: 'Service', size: '20%' },
{ field: 'status', caption: 'Status', size: '10%' },
],
records: []
});
//{ recid: 1, time: moment().format(log.time), action: 'Started app', service: 'MAIN', status: true }
log.info('Started app', 'MAIN', true);
log.listen();
};
log.listen = function () {
'use strict';
ipcRenderer.on('log', function (event, arg) {
log.display(arg.action, arg.service, arg.status, arg.time);
return event.returnValue = true;
});
};
log.display = function (action, service, status, time) {
'use strict';
var obj = {
recid : log.count++,
time : time,
action : action,
service : service,
status : status
}
if (typeof time === 'undefined') {
obj.time = moment().format(log.time);
}
w2ui['log'].add(obj);
if (nav.active === 'controls') {
w2ui['log'].scrollIntoView(log.count - 1);
w2ui['log'].selectNone();
w2ui['log'].select(log.count - 1);
}
return obj;
};
log.report = function (obj) {
'use strict';
ipcRenderer.sendSync('log', obj);
};
log.info = function (action, service, status, time) {
'use strict';
var obj = log.display(action, service, status, time);
log.report(obj);
//console.log(obj);
};
/******
Sequence Object
*******/
seq.i = 0;
mcopy.loop = 1;
mcopy.loopCount = 0;
seq.time = 0;
seq.stopState = false;
seq.run = function () {
var c = mcopy.state.sequence.arr[seq.i],
timeEnd = 0,
rgb,
action = function () {
setTimeout(function () {
seq.i++;
seq.run();
}, mcopy.cfg.arduino.sequenceDelay);
}
if (seq.stop()) {
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
//console.log('Sequence stepped');
log.info('Sequence stopped', 'SERIAL', true);
return false;
}
if (seq.i <= mcopy.state.sequence.arr.length && c !== undefined) {
log.info('Step ' + seq.i + ' command ' + c, 'SEQUENCE', true);
//gui action
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
$('.row input[x=' + seq.i + ']').addClass('h');
$('#numbers div[x=' + seq.i + ']').addClass('h');
if (c === 'CF'){
rgb = mcopy.state.sequence.light[seq.i].split(',');
cmd.cam_forward(rgb, action);
} else if (c === 'CB') {
rgb = mcopy.state.sequence.light[seq.i].split(',');
cmd.cam_backward(rgb, action);
} else if (c === 'PF') {
cmd.proj_forward(action);
} else if (c === 'PB') {
cmd.proj_backward(action);
} else if (c === 'BF') {
cmd.black_forward(action);
} else if (c === 'BB') {
cmd.black_backward(action);
}
} else {
mcopy.loopCount++;
if (mcopy.loopCount < mcopy.loop) {
log.info('Loop ' + mcopy.loopCount + ' completed', 'SEQUENCE', true);
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
seq.i = 0;
seq.run();
} else {
timeEnd = +new Date();
timeEnd = timeEnd - seq.time;
if (timeEnd < 2000) {
log.info('Sequence completed in ' + timeEnd + 'ms', 'SEQUENCE', true);
} else {
log.info('Sequence completed in ' + humanizeDuration(timeEnd), 'SEQUENCE', true);
}
gui.notify('Sequence done!', (mcopy.state.sequence.arr.length * mcopy.loop) + ' actions completed in ' + humanizeDuration(timeEnd));
//clear gui
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
seq.stats();
}
}
};
seq.stop = function (state) {
if (typeof state === 'undefined') {
return seq.stopState;
} else {
seq.stopState = state;
}
};
seq.init = function (start) {
if (typeof start === 'undefined') {
start = 0;
mcopy.loopCount = 0;
seq.time = +new Date();
}
seq.stop(false);
seq.i = start;
seq.run();
};
seq.stats = function () {
var ms = 0,
c = '',
cam_total = 0,
proj_total = 0,
real_total = mcopy.state.sequence.arr.filter(function (elem) {
if (elem === undefined) {
return false;
}
return true;
});
//timing
for (var i = 0; i < mcopy.state.sequence.arr.length; i++) {
c = mcopy.state.sequence.arr[i];
if (c === 'CF' || c === 'CB'){
ms += mcopy.cfg.arduino.cam.time;
ms += mcopy.cfg.arduino.cam.delay;
ms += mcopy.cfg.arduino.serialDelay;
}
if (c === 'PF' || c === 'PB'){
ms += mcopy.cfg.arduino.proj.time;
ms += mcopy.cfg.arduino.proj.delay;
ms += mcopy.cfg.arduino.serialDelay;
}
if (c === 'BF' || c === 'BB'){
ms += mcopy.cfg.arduino.black.before;
ms += mcopy.cfg.arduino.black.after;
ms += mcopy.cfg.arduino.cam.time;
ms += mcopy.cfg.arduino.cam.delay;
ms += mcopy.cfg.arduino.serialDelay;
}
ms += mcopy.cfg.arduino.sequenceDelay;
if (c === 'CF' || c === 'BF') {
cam_total++;
}
if (c === 'CB' || c === 'BB') {
cam_total--;
}
if (c === 'PF') {
proj_total++;
}
if (c === 'PB') {
proj_total--;
}
}
//timing
ms = ms * mcopy.loop;
if (ms < 2000) {
$('#seq_stats .timing span').text(ms + 'ms');
} else {
$('#seq_stats .timing span').text(humanizeDuration(ms));
}
//ending frames
cam_total = cam_total * mcopy.loop;
proj_total = proj_total * mcopy.loop;
$('#seq_stats .cam_end span').text(gui.fmtZero(mcopy.state.camera.pos + cam_total, 6));
$('#seq_stats .proj_end span').text(gui.fmtZero(mcopy.state.projector.pos + proj_total, 6));
//count
$('#seq_stats .seq_count span').text(real_total.length * mcopy.loop);
return ms;
};
seq.clear = function () {
mcopy.state.sequence.size = 24;
mcopy.state.sequence.arr = [];
};
//mcopy.gui.updateState();
cmd.proj_forward = function (callback) {
@ -3562,361 +3344,6 @@ cam.listen = function () {
});
};
//LIGHT
light.preview_state = false; //light is on/off for preview viewing
light.color = [255, 255, 255]; //default color
light.current = [0, 0, 0]; //last sent
light.icon = {};
light.swatches = [
{
rgb : [0, 0, 0],
name : 'off'
},
{
rgb : [255, 255, 255],
name : 'white (LED)'
},
{
rgb : chroma.kelvin(2500).rgb(),
name : '2500 kelvin'
},
{
rgb : chroma.kelvin(5600).rgb(),
name : '5600 kelvin'
},
{
rgb : chroma.kelvin(6500).rgb(),
name : '6500 kelvin'
},
{
rgb : light.color,
set : true,
default : true
}
];
light.queue = {};
light.lock = false;
light.init = function () {
'use strict';
//create dynamic style for displaying light across screens
light.icon = document.createElement('style');
light.icon.innerHTML = 'span.mcopy-light{background-color: #000;}';
document.body.appendChild(light.icon);
light.colorPickers();
light.swatch.init();
light.listen();
light.display(light.current);
$('#preview').on('change', function () {
light.preview_state = $(this).prop('checked');
if (light.preview_state) {
light.display(light.color);
light.set(light.color);
} else {
light.display([0,0,0]);
light.set([0,0,0]);
}
});
};
light.colorPickers = function () {
'use strict';
$('#colors-tabs').w2tabs({
name: 'colors',
active: 'kelvin',
tabs: [
{ id: 'kelvin', caption: 'Kelvin'},
{ id: 'cmy', caption: 'CMY'},
{ id: 'rgb', caption: 'RGB' }
],
onClick: function (event) {
$('.colors-page').hide();
$('#' + event.target + '-page').show();
if (event.target === 'rgb') {
light.rgb.page();
}
}
});
light.rgb.init();
light.kelvin.init();
};
light.set = function (rgb, callback) { //rgb = [0,0,0]
'use strict';
var obj;
if (light.lock) {
//potential for logging overlapping commands
return false;
}
obj = {
rgb : rgb,
id : uuid.v4()
};
ipcRenderer.sendSync('light', obj);
if (typeof callback !== 'undefined') {
obj.callback = callback;
}
light.queue[obj.id] = obj;
light.current = rgb;
light.lock = true;
};
light.end = function (id) {
'use strict';
if (typeof light.queue[id] !== 'undefined') {
if (typeof light.queue[id].callback !== 'undefined') {
light.queue[id].callback();
}
delete light.queue[id];
light.lock = false;
}
}
light.listen = function () {
'use strict';
ipcRenderer.on('light', function (event, arg) {
light.end(arg.id);
return event.returnValue = true;
});
};
light.preview = function (rgb, name) {
'use strict';
var rgbStr;
rgb = light.rgb.floor(rgb);
rgbStr = 'rgb(' + rgb.join(',') + ')';
light.color = rgb;
if (typeof name === 'undefined') {
name = rgbStr;
}
$('#light-swatches .swatch.set').css('background', rgbStr)
.attr('color', rgb.join(','))
.prop('title', name);
if (light.preview_state) {
light.display(rgb);
light.set(rgb);
}
};
light.display = function (rgb) { //display light active state
'use strict';
var str,
i;
rgb = light.rgb.floor(rgb);
for (i = 0; i < 3; i++) {
$('#light-status form input').eq(i).val(rgb[i]);
}
str = 'rgb(' + rgb.join(',') + ')';
$('#color').css('background-color', str);
light.icon = document.styleSheets[document.styleSheets.length - 1];
light.icon.deleteRule(0);
light.icon.insertRule('span.mcopy-light{background-color: ' + str + ';}', 0)
};
//KELVIN GUI
light.kelvin = {};
light.kelvin.steps = 348;
light.kelvin.min = light.kelvin.steps * 4;
light.kelvin.max = 20000;
light.kelvin.moving = false;
light.kelvin.init = function () {
'use strict';
$('#kelvin').on('change', light.kelvin.change);
$('#kelvin').on('keypup', function (e) {
var code = e.keyCode || e.which;
if (code === 13) {
light.kelvin.change();
}
});
$('#kelvin-slider').on('mousemove', function (event) {
if (light.kelvin.moving) {
light.kelvin.click(this, event);
}
});
$('#kelvin-slider').on('mousedown', function (event) {
light.kelvin.moving = true;
light.kelvin.click(this, event);
});
$(document).on('mouseup', function () {
light.kelvin.moving = false;
});
light.kelvin.scale();
light.kelvin.set(5600); //default value
};
light.kelvin.change = function () {
'use strict';
var val = $('#kelvin').val(),
rgb = chroma.kelvin(val).rgb();
light.kelvin.pos(val);
light.preview(rgb, val + ' kelvin');
};
light.kelvin.scale = function () {
'use strict';
var i,
min = light.kelvin.min,
max = light.kelvin.max,
steps = light.kelvin.steps,
rgb,
elem,
elemStr = '<span style="background: rgb(XXXX);"></span>'
for (i = 0; i < steps; i++) {
rgb = chroma.kelvin((i * ((max - min) / steps)) + min).rgb();
rgb = light.rgb.floor(rgb).join(',');
elem = $(elemStr.replace('XXXX', rgb));
$('#kelvin-scale').append(elem);
}
};
light.kelvin.pos = function (kelvin) {
'use strict';
var min = light.kelvin.min,
max = light.kelvin.max,
steps = light.kelvin.steps,
start = -1,
pos = Math.round((kelvin - min) / ( (max - min) / steps)) + start;
if (pos < start) {
pos = start;
}
if (pos > steps) {
pos = steps;
}
$('#kelvin-pos').css('left', pos + 'px');
};
light.kelvin.set = function (kelvin) {
'use strict';
$('#kelvin').val(kelvin);
light.kelvin.change();
};
light.kelvin.click = function (t, e) {
'use strict';
var parentOffset = $(t).parent().offset(),
relX = e.pageX - parentOffset.left - 31, //?
min = light.kelvin.min,
max = light.kelvin.max,
steps = light.kelvin.steps,
kelvin = Math.round((relX * ((max - min) / steps)) + min);
light.kelvin.set(kelvin);
};
//CMY GUI
light.cmy = {};
light.cmy.init = function () {
'use strict';
};
light.cmy.setDial = function (dial, val) {
'use strict';
var elem = $('#dial-' + dial);
};
//RGB GUI
light.rgb = {};
light.rgb.elem;
light.rgb.lock = true;
light.rgb.init = function () {
'use strict';
light.rgb.elem = jsColorPicker('#rgb', {
customBG: '#222',
readOnly: true,
size: 3,
appendTo : document.getElementById('rgb-page'),
// patch: false,
init: function(elm, colors) { // colors is a different instance (not connected to colorPicker)
elm.style.backgroundColor = elm.value;
elm.style.color = colors.rgbaMixCustom.luminance > 0.22 ? '#222' : '#ddd';
},
convertCallback: light.rgb.change
});
};
light.rgb.page = function () {
'use strict';
if (light.rgb.lock) {
$('#rgb').focus();
light.rgb.lock = false;
}
light.rgb.set(light.color);
};
light.rgb.change = function (colors, type) {
'use strict';
var a = colors.RND.rgb,
rgb = [a.r, a.g, a.b];
if (!light.rgb.lock) {
light.preview(rgb);
}
};
light.rgb.floor = function (rgb) {
'use strict';
return [
Math.floor(rgb[0]),
Math.floor(rgb[1]),
Math.floor(rgb[2])
];
};
light.rgb.set = function (rgb) {
'use strict';
var hex = chroma.rgb(rgb).hex();
light.rgb.elem.current.startRender();
light.rgb.elem.current.setColor(hex);
light.rgb.elem.current.stopRender();
};
//SWATCH GUI
light.swatch = {};
light.swatch.init = function () {
'use strict';
var number = 12,
add,
elem,
rgb,
i,
x;
for (i = 0; i < light.swatches.length; i++) {
light.swatches[i].rgb = light.rgb.floor(light.swatches[i].rgb);
rgb = 'rgb(' + light.swatches[i].rgb.join(',') + ')';
elem = $('<div class="swatch"></div>');
elem.css('background', rgb);
elem.attr('color', light.swatches[i].rgb.join(','));
if (typeof light.swatches[i].name !== 'undefined') {
elem.prop('title', light.swatches[i].name);
} else {
elem.prop('title', rgb);
}
if (light.swatches[i].default) {
elem.addClass('default');
}
if (light.swatches[i].set) {
elem.addClass('set');
}
$('#new-swatch').before(elem);
}
$('#new-swatch').on('click', light.swatch.add);
$(document.body).on('click', '#light-swatches .swatch', function () {
var rgb = $(this).attr('color');
if (typeof color !== 'undefined') {
rgb = rgb.split(',');
$('#light-swatches .swatch').removeClass('default set');
$(this).addClass('default set');
if (w2ui['colors'].active === 'rgb') {
light.rgb.set(light.color);
}
light.preview(rgb);
}
});
$(document.body).on('dblclick', '.swatch', function () {
});
};
light.swatch.add = function () {
'use strict';
var swatch = $('<div class="swatch default set"></div>');
$('#light-swatches .swatch').removeClass('default set');
$('#new-swatch').before(swatch);
light.preview(light.color);
};
//GUI
gui.fmtZero = function (val, len) {
var raw = val,

381
app/lib/light-ui.js Normal file
View File

@ -0,0 +1,381 @@
var light = {};
//LIGHT
light.preview_state = false; //light is on/off for preview viewing
light.color = [255, 255, 255]; //default color
light.current = [0, 0, 0]; //last sent
light.icon = {};
light.swatches = [
{
rgb : [0, 0, 0],
name : 'off'
},
{
rgb : [255, 255, 255],
name : 'white (LED)'
},
{
rgb : chroma.kelvin(2500).rgb(),
name : '2500 kelvin'
},
{
rgb : chroma.kelvin(5600).rgb(),
name : '5600 kelvin'
},
{
rgb : chroma.kelvin(6500).rgb(),
name : '6500 kelvin'
},
{
rgb : light.color,
set : true,
default : true
}
];
light.queue = {};
light.lock = false;
light.init = function () {
'use strict';
//create dynamic style for displaying light across screens
light.icon = document.createElement('style');
light.icon.innerHTML = 'span.mcopy-light{background-color: #000;}';
document.body.appendChild(light.icon);
light.colorPickers();
light.swatch.init();
light.listen();
light.display(light.current);
$('#preview').on('change', function () {
light.preview_state = $(this).prop('checked');
if (light.preview_state) {
light.display(light.color);
light.set(light.color);
} else {
light.display([0,0,0]);
light.set([0,0,0]);
}
});
};
light.colorPickers = function () {
'use strict';
$('#colors-tabs').w2tabs({
name: 'colors',
active: 'kelvin',
tabs: [
{ id: 'kelvin', caption: 'Kelvin'},
{ id: 'cmy', caption: 'CMY'},
{ id: 'rgb', caption: 'RGB' }
],
onClick: function (event) {
$('.colors-page').hide();
$('#' + event.target + '-page').show();
if (event.target === 'rgb') {
light.rgb.page();
}
}
});
light.rgb.init();
light.kelvin.init();
};
light.set = function (rgb, callback) { //rgb = [0,0,0]
'use strict';
var obj;
if (light.lock) {
//potential for logging overlapping commands
return false;
}
obj = {
rgb : rgb,
id : uuid.v4()
};
ipcRenderer.sendSync('light', obj);
if (typeof callback !== 'undefined') {
obj.callback = callback;
}
light.queue[obj.id] = obj;
light.current = rgb;
light.lock = true;
};
light.end = function (id) {
'use strict';
if (typeof light.queue[id] !== 'undefined') {
if (typeof light.queue[id].callback !== 'undefined') {
light.queue[id].callback();
}
delete light.queue[id];
light.lock = false;
}
}
light.listen = function () {
'use strict';
ipcRenderer.on('light', function (event, arg) {
light.end(arg.id);
return event.returnValue = true;
});
};
light.preview = function (rgb, name) {
'use strict';
var rgbStr;
rgb = light.rgb.floor(rgb);
rgbStr = 'rgb(' + rgb.join(',') + ')';
light.color = rgb;
if (typeof name === 'undefined') {
name = rgbStr;
}
$('#light-swatches .swatch.set').css('background', rgbStr)
.attr('color', rgb.join(','))
.prop('title', name);
if (light.preview_state) {
light.display(rgb);
light.set(rgb);
}
};
light.display = function (rgb) { //display light active state
'use strict';
var str,
i;
rgb = light.rgb.floor(rgb);
for (i = 0; i < 3; i++) {
$('#light-status form input').eq(i).val(rgb[i]);
}
str = 'rgb(' + rgb.join(',') + ')';
$('#color').css('background-color', str);
light.icon = document.styleSheets[document.styleSheets.length - 1];
light.icon.deleteRule(0);
light.icon.insertRule('span.mcopy-light{background-color: ' + str + ';}', 0)
};
//KELVIN GUI
light.kelvin = {};
light.kelvin.steps = 348;
light.kelvin.min = light.kelvin.steps * 4;
light.kelvin.max = 20000;
light.kelvin.moving = false;
light.kelvin.init = function () {
'use strict';
$('#kelvin').on('change', light.kelvin.change);
$('#kelvin').on('keypup', function (e) {
var code = e.keyCode || e.which;
if (code === 13) {
light.kelvin.change();
}
});
$('#kelvin-slider').on('mousemove', function (event) {
if (light.kelvin.moving) {
light.kelvin.click(this, event);
}
});
$('#kelvin-slider').on('mousedown', function (event) {
light.kelvin.moving = true;
light.kelvin.click(this, event);
});
$(document).on('mouseup', function () {
light.kelvin.moving = false;
});
light.kelvin.scale();
light.kelvin.set(5600); //default value
};
light.kelvin.change = function () {
'use strict';
var val = $('#kelvin').val(),
rgb = chroma.kelvin(val).rgb();
light.kelvin.preview(rgb);
light.kelvin.pos(val);
light.preview(rgb, val + ' kelvin');
};
light.kelvin.preview = function (rgb_float) {
'use strict';
var elem = $('#kelvin-preview'),
rgb = light.rgb.floor(rgb_float),
rgb_str = 'rgb(' + rgb.join(', ') + ')';
elem.css('background', rgb_str);
elem.text(rgb_str);
};
light.kelvin.scale = function () {
'use strict';
var i,
min = light.kelvin.min,
max = light.kelvin.max,
steps = light.kelvin.steps,
rgb,
elem,
elemStr = '<span style="background: rgb(XXXX);"></span>'
for (i = 0; i < steps; i++) {
rgb = chroma.kelvin((i * ((max - min) / steps)) + min).rgb();
rgb = light.rgb.floor(rgb).join(',');
elem = $(elemStr.replace('XXXX', rgb));
$('#kelvin-scale').append(elem);
}
};
light.kelvin.pos = function (kelvin) {
'use strict';
var min = light.kelvin.min,
max = light.kelvin.max,
steps = light.kelvin.steps,
start = -1,
pos = Math.round((kelvin - min) / ( (max - min) / steps)) + start;
if (pos < start) {
pos = start;
}
if (pos > steps) {
pos = steps;
}
$('#kelvin-pos').css('left', pos + 'px');
};
light.kelvin.set = function (kelvin) {
'use strict';
$('#kelvin').val(kelvin);
light.kelvin.change();
};
light.kelvin.click = function (t, e) {
'use strict';
var parentOffset = $(t).parent().offset(),
relX = e.pageX - parentOffset.left - 31, //?
min = light.kelvin.min,
max = light.kelvin.max,
steps = light.kelvin.steps,
kelvin = Math.round((relX * ((max - min) / steps)) + min);
light.kelvin.set(kelvin);
};
//CMY GUI
light.cmy = {};
light.cmy.init = function () {
'use strict';
};
light.cmy.set = function (rgb) {
};
light.cmy.setDial = function (dial, val) {
'use strict';
var elem = $('#dial-' + dial),
angle = Math.floor(360 * val);
elem.find('.dial-container1 .dial-wedge').css('transform', 'rotateZ(' + angle + 'deg)');
elem.find('.dial-end').css('transform', 'rotateZ(' + angle + 'deg)');
};
light.cmy.preview = function (rgb_float) {
'use strict';
var elem = $('#cmy-preview'),
rgb = light.rgb.floor(rgb_float),
rgb_str = 'rgb(' + rgb.join(', ') + ')';
elem.css('background', rgb_str);
elem.text(rgb_str);
};
//RGB GUI
light.rgb = {};
light.rgb.elem;
light.rgb.lock = true;
light.rgb.init = function () {
'use strict';
light.rgb.elem = jsColorPicker('#rgb', {
customBG: '#222',
readOnly: true,
size: 3,
appendTo : document.getElementById('rgb-page'),
// patch: false,
init: function(elm, colors) { // colors is a different instance (not connected to colorPicker)
elm.style.backgroundColor = elm.value;
elm.style.color = colors.rgbaMixCustom.luminance > 0.22 ? '#222' : '#ddd';
},
convertCallback: light.rgb.change
});
};
light.rgb.page = function () {
'use strict';
if (light.rgb.lock) {
$('#rgb').focus();
light.rgb.lock = false;
}
light.rgb.set(light.color);
};
light.rgb.change = function (colors, type) {
'use strict';
var a = colors.RND.rgb,
rgb = [a.r, a.g, a.b];
if (!light.rgb.lock) {
light.preview(rgb);
}
};
light.rgb.floor = function (rgb) {
'use strict';
return [
Math.floor(rgb[0]),
Math.floor(rgb[1]),
Math.floor(rgb[2])
];
};
light.rgb.set = function (rgb) {
'use strict';
var hex = chroma.rgb(rgb).hex();
light.rgb.elem.current.startRender();
light.rgb.elem.current.setColor(hex);
light.rgb.elem.current.stopRender();
};
//SWATCH GUI
light.swatch = {};
light.swatch.init = function () {
'use strict';
var number = 12,
add,
elem,
rgb,
i,
x;
for (i = 0; i < light.swatches.length; i++) {
light.swatches[i].rgb = light.rgb.floor(light.swatches[i].rgb);
rgb = 'rgb(' + light.swatches[i].rgb.join(',') + ')';
elem = $('<div class="swatch"></div>');
elem.css('background', rgb);
elem.attr('color', light.swatches[i].rgb.join(','));
if (typeof light.swatches[i].name !== 'undefined') {
elem.prop('title', light.swatches[i].name);
} else {
elem.prop('title', rgb);
}
if (light.swatches[i].default) {
elem.addClass('default');
}
if (light.swatches[i].set) {
elem.addClass('set');
}
$('#new-swatch').before(elem);
}
$('#new-swatch').on('click', light.swatch.add);
$(document.body).on('click', '#light-swatches .swatch', function () {
var rgb = $(this).attr('color');
if (typeof color !== 'undefined') {
rgb = rgb.split(',');
$('#light-swatches .swatch').removeClass('default set');
$(this).addClass('default set');
if (w2ui['colors'].active === 'rgb') {
light.rgb.set(light.color);
}
light.preview(rgb);
}
});
$(document.body).on('dblclick', '.swatch', function () {
});
};
light.swatch.add = function () {
'use strict';
var swatch = $('<div class="swatch default set"></div>');
$('#light-swatches .swatch').removeClass('default set');
$('#new-swatch').before(swatch);
light.preview(light.color);
};
module.exports = light;

60
app/lib/log-ui.js Normal file
View File

@ -0,0 +1,60 @@
var log = {};
log.time = 'MM/DD/YY-HH:mm:ss';
log.count = 0;
log.init = function () {
'use strict';
$('#log').w2grid({
name : 'log',
columns: [
{ field: 'time', caption: 'Time', size: '22%' },
{ field: 'action', caption: 'Action', size: '58%' },
{ field: 'service', caption: 'Service', size: '20%' },
{ field: 'status', caption: 'Status', size: '10%' },
],
records: []
});
//{ recid: 1, time: moment().format(log.time), action: 'Started app', service: 'MAIN', status: true }
log.info('Started app', 'MAIN', true);
log.listen();
};
log.listen = function () {
'use strict';
ipcRenderer.on('log', function (event, arg) {
log.display(arg.action, arg.service, arg.status, arg.time);
return event.returnValue = true;
});
};
log.display = function (action, service, status, time) {
'use strict';
var obj = {
recid : log.count++,
time : time,
action : action,
service : service,
status : status
}
if (typeof time === 'undefined') {
obj.time = moment().format(log.time);
}
w2ui['log'].add(obj);
if (nav.active === 'controls') {
w2ui['log'].scrollIntoView(log.count - 1);
w2ui['log'].selectNone();
w2ui['log'].select(log.count - 1);
}
return obj;
};
log.report = function (obj) {
'use strict';
ipcRenderer.sendSync('log', obj);
};
log.info = function (action, service, status, time) {
'use strict';
var obj = log.display(action, service, status, time);
log.report(obj);
//console.log(obj);
};
module.exports = log;

163
app/lib/seq-ui.js Normal file
View File

@ -0,0 +1,163 @@
var seq = {};
/******
Sequence Object
*******/
seq.i = 0;
mcopy.loop = 1;
mcopy.loopCount = 0;
seq.time = 0;
seq.stopState = false;
seq.run = function () {
var c = mcopy.state.sequence.arr[seq.i],
timeEnd = 0,
rgb,
action = function () {
setTimeout(function () {
seq.i++;
seq.run();
}, mcopy.cfg.arduino.sequenceDelay);
}
if (seq.stop()) {
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
//console.log('Sequence stepped');
log.info('Sequence stopped', 'SERIAL', true);
return false;
}
if (seq.i <= mcopy.state.sequence.arr.length && c !== undefined) {
log.info('Step ' + seq.i + ' command ' + c, 'SEQUENCE', true);
//gui action
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
$('.row input[x=' + seq.i + ']').addClass('h');
$('#numbers div[x=' + seq.i + ']').addClass('h');
if (c === 'CF'){
rgb = mcopy.state.sequence.light[seq.i].split(',');
cmd.cam_forward(rgb, action);
} else if (c === 'CB') {
rgb = mcopy.state.sequence.light[seq.i].split(',');
cmd.cam_backward(rgb, action);
} else if (c === 'PF') {
cmd.proj_forward(action);
} else if (c === 'PB') {
cmd.proj_backward(action);
} else if (c === 'BF') {
cmd.black_forward(action);
} else if (c === 'BB') {
cmd.black_backward(action);
}
} else {
mcopy.loopCount++;
if (mcopy.loopCount < mcopy.loop) {
log.info('Loop ' + mcopy.loopCount + ' completed', 'SEQUENCE', true);
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
seq.i = 0;
seq.run();
} else {
timeEnd = +new Date();
timeEnd = timeEnd - seq.time;
if (timeEnd < 2000) {
log.info('Sequence completed in ' + timeEnd + 'ms', 'SEQUENCE', true);
} else {
log.info('Sequence completed in ' + humanizeDuration(timeEnd), 'SEQUENCE', true);
}
gui.notify('Sequence done!', (mcopy.state.sequence.arr.length * mcopy.loop) + ' actions completed in ' + humanizeDuration(timeEnd));
//clear gui
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
seq.stats();
}
}
};
seq.stop = function (state) {
if (typeof state === 'undefined') {
return seq.stopState;
} else {
seq.stopState = state;
}
};
seq.init = function (start) {
if (typeof start === 'undefined') {
start = 0;
mcopy.loopCount = 0;
seq.time = +new Date();
}
seq.stop(false);
seq.i = start;
seq.run();
};
seq.stats = function () {
var ms = 0,
c = '',
cam_total = 0,
proj_total = 0,
real_total = mcopy.state.sequence.arr.filter(function (elem) {
if (elem === undefined) {
return false;
}
return true;
});
//timing
for (var i = 0; i < mcopy.state.sequence.arr.length; i++) {
c = mcopy.state.sequence.arr[i];
if (c === 'CF' || c === 'CB'){
ms += mcopy.cfg.arduino.cam.time;
ms += mcopy.cfg.arduino.cam.delay;
ms += mcopy.cfg.arduino.serialDelay;
}
if (c === 'PF' || c === 'PB'){
ms += mcopy.cfg.arduino.proj.time;
ms += mcopy.cfg.arduino.proj.delay;
ms += mcopy.cfg.arduino.serialDelay;
}
if (c === 'BF' || c === 'BB'){
ms += mcopy.cfg.arduino.black.before;
ms += mcopy.cfg.arduino.black.after;
ms += mcopy.cfg.arduino.cam.time;
ms += mcopy.cfg.arduino.cam.delay;
ms += mcopy.cfg.arduino.serialDelay;
}
ms += mcopy.cfg.arduino.sequenceDelay;
if (c === 'CF' || c === 'BF') {
cam_total++;
}
if (c === 'CB' || c === 'BB') {
cam_total--;
}
if (c === 'PF') {
proj_total++;
}
if (c === 'PB') {
proj_total--;
}
}
//timing
ms = ms * mcopy.loop;
if (ms < 2000) {
$('#seq_stats .timing span').text(ms + 'ms');
} else {
$('#seq_stats .timing span').text(humanizeDuration(ms));
}
//ending frames
cam_total = cam_total * mcopy.loop;
proj_total = proj_total * mcopy.loop;
$('#seq_stats .cam_end span').text(gui.fmtZero(mcopy.state.camera.pos + cam_total, 6));
$('#seq_stats .proj_end span').text(gui.fmtZero(mcopy.state.projector.pos + proj_total, 6));
//count
$('#seq_stats .seq_count span').text(real_total.length * mcopy.loop);
return ms;
};
seq.clear = function () {
mcopy.state.sequence.size = 24;
mcopy.state.sequence.arr = [];
};
module.exports = seq;

View File

@ -7,14 +7,14 @@ var remote = require('remote'),
humanizeDuration = require('humanize-duration')
ipcRenderer = require('electron').ipcRenderer,
mcopy = {},
light = {},
light = require('./lib/light-ui.js'),
proj = {},
cam = {},
nav = {},
seq = {},
seq = require('./lib/seq-ui.js'),
cmd = {},
gui = {},
log = {};
log = require('./lib/log-ui.js');
//console.log(ipcRenderer.sendSync('light', { 'fuck' : true }) );
mcopy.cfg = JSON.parse(fs.readFileSync('./data/cfg.json'), 'utf8');
@ -56,224 +56,6 @@ mcopy.state = {
}
};
log.time = 'MM/DD/YY-HH:mm:ss';
log.count = 0;
log.init = function () {
'use strict';
$('#log').w2grid({
name : 'log',
columns: [
{ field: 'time', caption: 'Time', size: '22%' },
{ field: 'action', caption: 'Action', size: '58%' },
{ field: 'service', caption: 'Service', size: '20%' },
{ field: 'status', caption: 'Status', size: '10%' },
],
records: []
});
//{ recid: 1, time: moment().format(log.time), action: 'Started app', service: 'MAIN', status: true }
log.info('Started app', 'MAIN', true);
log.listen();
};
log.listen = function () {
'use strict';
ipcRenderer.on('log', function (event, arg) {
log.display(arg.action, arg.service, arg.status, arg.time);
return event.returnValue = true;
});
};
log.display = function (action, service, status, time) {
'use strict';
var obj = {
recid : log.count++,
time : time,
action : action,
service : service,
status : status
}
if (typeof time === 'undefined') {
obj.time = moment().format(log.time);
}
w2ui['log'].add(obj);
if (nav.active === 'controls') {
w2ui['log'].scrollIntoView(log.count - 1);
w2ui['log'].selectNone();
w2ui['log'].select(log.count - 1);
}
return obj;
};
log.report = function (obj) {
'use strict';
ipcRenderer.sendSync('log', obj);
};
log.info = function (action, service, status, time) {
'use strict';
var obj = log.display(action, service, status, time);
log.report(obj);
//console.log(obj);
};
/******
Sequence Object
*******/
seq.i = 0;
mcopy.loop = 1;
mcopy.loopCount = 0;
seq.time = 0;
seq.stopState = false;
seq.run = function () {
var c = mcopy.state.sequence.arr[seq.i],
timeEnd = 0,
rgb,
action = function () {
setTimeout(function () {
seq.i++;
seq.run();
}, mcopy.cfg.arduino.sequenceDelay);
}
if (seq.stop()) {
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
//console.log('Sequence stepped');
log.info('Sequence stopped', 'SERIAL', true);
return false;
}
if (seq.i <= mcopy.state.sequence.arr.length && c !== undefined) {
log.info('Step ' + seq.i + ' command ' + c, 'SEQUENCE', true);
//gui action
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
$('.row input[x=' + seq.i + ']').addClass('h');
$('#numbers div[x=' + seq.i + ']').addClass('h');
if (c === 'CF'){
rgb = mcopy.state.sequence.light[seq.i].split(',');
cmd.cam_forward(rgb, action);
} else if (c === 'CB') {
rgb = mcopy.state.sequence.light[seq.i].split(',');
cmd.cam_backward(rgb, action);
} else if (c === 'PF') {
cmd.proj_forward(action);
} else if (c === 'PB') {
cmd.proj_backward(action);
} else if (c === 'BF') {
cmd.black_forward(action);
} else if (c === 'BB') {
cmd.black_backward(action);
}
} else {
mcopy.loopCount++;
if (mcopy.loopCount < mcopy.loop) {
log.info('Loop ' + mcopy.loopCount + ' completed', 'SEQUENCE', true);
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
seq.i = 0;
seq.run();
} else {
timeEnd = +new Date();
timeEnd = timeEnd - seq.time;
if (timeEnd < 2000) {
log.info('Sequence completed in ' + timeEnd + 'ms', 'SEQUENCE', true);
} else {
log.info('Sequence completed in ' + humanizeDuration(timeEnd), 'SEQUENCE', true);
}
gui.notify('Sequence done!', (mcopy.state.sequence.arr.length * mcopy.loop) + ' actions completed in ' + humanizeDuration(timeEnd));
//clear gui
$('.row input').removeClass('h');
$('#numbers div').removeClass('h');
seq.stats();
}
}
};
seq.stop = function (state) {
if (typeof state === 'undefined') {
return seq.stopState;
} else {
seq.stopState = state;
}
};
seq.init = function (start) {
if (typeof start === 'undefined') {
start = 0;
mcopy.loopCount = 0;
seq.time = +new Date();
}
seq.stop(false);
seq.i = start;
seq.run();
};
seq.stats = function () {
var ms = 0,
c = '',
cam_total = 0,
proj_total = 0,
real_total = mcopy.state.sequence.arr.filter(function (elem) {
if (elem === undefined) {
return false;
}
return true;
});
//timing
for (var i = 0; i < mcopy.state.sequence.arr.length; i++) {
c = mcopy.state.sequence.arr[i];
if (c === 'CF' || c === 'CB'){
ms += mcopy.cfg.arduino.cam.time;
ms += mcopy.cfg.arduino.cam.delay;
ms += mcopy.cfg.arduino.serialDelay;
}
if (c === 'PF' || c === 'PB'){
ms += mcopy.cfg.arduino.proj.time;
ms += mcopy.cfg.arduino.proj.delay;
ms += mcopy.cfg.arduino.serialDelay;
}
if (c === 'BF' || c === 'BB'){
ms += mcopy.cfg.arduino.black.before;
ms += mcopy.cfg.arduino.black.after;
ms += mcopy.cfg.arduino.cam.time;
ms += mcopy.cfg.arduino.cam.delay;
ms += mcopy.cfg.arduino.serialDelay;
}
ms += mcopy.cfg.arduino.sequenceDelay;
if (c === 'CF' || c === 'BF') {
cam_total++;
}
if (c === 'CB' || c === 'BB') {
cam_total--;
}
if (c === 'PF') {
proj_total++;
}
if (c === 'PB') {
proj_total--;
}
}
//timing
ms = ms * mcopy.loop;
if (ms < 2000) {
$('#seq_stats .timing span').text(ms + 'ms');
} else {
$('#seq_stats .timing span').text(humanizeDuration(ms));
}
//ending frames
cam_total = cam_total * mcopy.loop;
proj_total = proj_total * mcopy.loop;
$('#seq_stats .cam_end span').text(gui.fmtZero(mcopy.state.camera.pos + cam_total, 6));
$('#seq_stats .proj_end span').text(gui.fmtZero(mcopy.state.projector.pos + proj_total, 6));
//count
$('#seq_stats .seq_count span').text(real_total.length * mcopy.loop);
return ms;
};
seq.clear = function () {
mcopy.state.sequence.size = 24;
mcopy.state.sequence.arr = [];
};
//mcopy.gui.updateState();
cmd.proj_forward = function (callback) {
@ -523,361 +305,6 @@ cam.listen = function () {
});
};
//LIGHT
light.preview_state = false; //light is on/off for preview viewing
light.color = [255, 255, 255]; //default color
light.current = [0, 0, 0]; //last sent
light.icon = {};
light.swatches = [
{
rgb : [0, 0, 0],
name : 'off'
},
{
rgb : [255, 255, 255],
name : 'white (LED)'
},
{
rgb : chroma.kelvin(2500).rgb(),
name : '2500 kelvin'
},
{
rgb : chroma.kelvin(5600).rgb(),
name : '5600 kelvin'
},
{
rgb : chroma.kelvin(6500).rgb(),
name : '6500 kelvin'
},
{
rgb : light.color,
set : true,
default : true
}
];
light.queue = {};
light.lock = false;
light.init = function () {
'use strict';
//create dynamic style for displaying light across screens
light.icon = document.createElement('style');
light.icon.innerHTML = 'span.mcopy-light{background-color: #000;}';
document.body.appendChild(light.icon);
light.colorPickers();
light.swatch.init();
light.listen();
light.display(light.current);
$('#preview').on('change', function () {
light.preview_state = $(this).prop('checked');
if (light.preview_state) {
light.display(light.color);
light.set(light.color);
} else {
light.display([0,0,0]);
light.set([0,0,0]);
}
});
};
light.colorPickers = function () {
'use strict';
$('#colors-tabs').w2tabs({
name: 'colors',
active: 'kelvin',
tabs: [
{ id: 'kelvin', caption: 'Kelvin'},
{ id: 'cmy', caption: 'CMY'},
{ id: 'rgb', caption: 'RGB' }
],
onClick: function (event) {
$('.colors-page').hide();
$('#' + event.target + '-page').show();
if (event.target === 'rgb') {
light.rgb.page();
}
}
});
light.rgb.init();
light.kelvin.init();
};
light.set = function (rgb, callback) { //rgb = [0,0,0]
'use strict';
var obj;
if (light.lock) {
//potential for logging overlapping commands
return false;
}
obj = {
rgb : rgb,
id : uuid.v4()
};
ipcRenderer.sendSync('light', obj);
if (typeof callback !== 'undefined') {
obj.callback = callback;
}
light.queue[obj.id] = obj;
light.current = rgb;
light.lock = true;
};
light.end = function (id) {
'use strict';
if (typeof light.queue[id] !== 'undefined') {
if (typeof light.queue[id].callback !== 'undefined') {
light.queue[id].callback();
}
delete light.queue[id];
light.lock = false;
}
}
light.listen = function () {
'use strict';
ipcRenderer.on('light', function (event, arg) {
light.end(arg.id);
return event.returnValue = true;
});
};
light.preview = function (rgb, name) {
'use strict';
var rgbStr;
rgb = light.rgb.floor(rgb);
rgbStr = 'rgb(' + rgb.join(',') + ')';
light.color = rgb;
if (typeof name === 'undefined') {
name = rgbStr;
}
$('#light-swatches .swatch.set').css('background', rgbStr)
.attr('color', rgb.join(','))
.prop('title', name);
if (light.preview_state) {
light.display(rgb);
light.set(rgb);
}
};
light.display = function (rgb) { //display light active state
'use strict';
var str,
i;
rgb = light.rgb.floor(rgb);
for (i = 0; i < 3; i++) {
$('#light-status form input').eq(i).val(rgb[i]);
}
str = 'rgb(' + rgb.join(',') + ')';
$('#color').css('background-color', str);
light.icon = document.styleSheets[document.styleSheets.length - 1];
light.icon.deleteRule(0);
light.icon.insertRule('span.mcopy-light{background-color: ' + str + ';}', 0)
};
//KELVIN GUI
light.kelvin = {};
light.kelvin.steps = 348;
light.kelvin.min = light.kelvin.steps * 4;
light.kelvin.max = 20000;
light.kelvin.moving = false;
light.kelvin.init = function () {
'use strict';
$('#kelvin').on('change', light.kelvin.change);
$('#kelvin').on('keypup', function (e) {
var code = e.keyCode || e.which;
if (code === 13) {
light.kelvin.change();
}
});
$('#kelvin-slider').on('mousemove', function (event) {
if (light.kelvin.moving) {
light.kelvin.click(this, event);
}
});
$('#kelvin-slider').on('mousedown', function (event) {
light.kelvin.moving = true;
light.kelvin.click(this, event);
});
$(document).on('mouseup', function () {
light.kelvin.moving = false;
});
light.kelvin.scale();
light.kelvin.set(5600); //default value
};
light.kelvin.change = function () {
'use strict';
var val = $('#kelvin').val(),
rgb = chroma.kelvin(val).rgb();
light.kelvin.pos(val);
light.preview(rgb, val + ' kelvin');
};
light.kelvin.scale = function () {
'use strict';
var i,
min = light.kelvin.min,
max = light.kelvin.max,
steps = light.kelvin.steps,
rgb,
elem,
elemStr = '<span style="background: rgb(XXXX);"></span>'
for (i = 0; i < steps; i++) {
rgb = chroma.kelvin((i * ((max - min) / steps)) + min).rgb();
rgb = light.rgb.floor(rgb).join(',');
elem = $(elemStr.replace('XXXX', rgb));
$('#kelvin-scale').append(elem);
}
};
light.kelvin.pos = function (kelvin) {
'use strict';
var min = light.kelvin.min,
max = light.kelvin.max,
steps = light.kelvin.steps,
start = -1,
pos = Math.round((kelvin - min) / ( (max - min) / steps)) + start;
if (pos < start) {
pos = start;
}
if (pos > steps) {
pos = steps;
}
$('#kelvin-pos').css('left', pos + 'px');
};
light.kelvin.set = function (kelvin) {
'use strict';
$('#kelvin').val(kelvin);
light.kelvin.change();
};
light.kelvin.click = function (t, e) {
'use strict';
var parentOffset = $(t).parent().offset(),
relX = e.pageX - parentOffset.left - 31, //?
min = light.kelvin.min,
max = light.kelvin.max,
steps = light.kelvin.steps,
kelvin = Math.round((relX * ((max - min) / steps)) + min);
light.kelvin.set(kelvin);
};
//CMY GUI
light.cmy = {};
light.cmy.init = function () {
'use strict';
};
light.cmy.setDial = function (dial, val) {
'use strict';
var elem = $('#dial-' + dial);
};
//RGB GUI
light.rgb = {};
light.rgb.elem;
light.rgb.lock = true;
light.rgb.init = function () {
'use strict';
light.rgb.elem = jsColorPicker('#rgb', {
customBG: '#222',
readOnly: true,
size: 3,
appendTo : document.getElementById('rgb-page'),
// patch: false,
init: function(elm, colors) { // colors is a different instance (not connected to colorPicker)
elm.style.backgroundColor = elm.value;
elm.style.color = colors.rgbaMixCustom.luminance > 0.22 ? '#222' : '#ddd';
},
convertCallback: light.rgb.change
});
};
light.rgb.page = function () {
'use strict';
if (light.rgb.lock) {
$('#rgb').focus();
light.rgb.lock = false;
}
light.rgb.set(light.color);
};
light.rgb.change = function (colors, type) {
'use strict';
var a = colors.RND.rgb,
rgb = [a.r, a.g, a.b];
if (!light.rgb.lock) {
light.preview(rgb);
}
};
light.rgb.floor = function (rgb) {
'use strict';
return [
Math.floor(rgb[0]),
Math.floor(rgb[1]),
Math.floor(rgb[2])
];
};
light.rgb.set = function (rgb) {
'use strict';
var hex = chroma.rgb(rgb).hex();
light.rgb.elem.current.startRender();
light.rgb.elem.current.setColor(hex);
light.rgb.elem.current.stopRender();
};
//SWATCH GUI
light.swatch = {};
light.swatch.init = function () {
'use strict';
var number = 12,
add,
elem,
rgb,
i,
x;
for (i = 0; i < light.swatches.length; i++) {
light.swatches[i].rgb = light.rgb.floor(light.swatches[i].rgb);
rgb = 'rgb(' + light.swatches[i].rgb.join(',') + ')';
elem = $('<div class="swatch"></div>');
elem.css('background', rgb);
elem.attr('color', light.swatches[i].rgb.join(','));
if (typeof light.swatches[i].name !== 'undefined') {
elem.prop('title', light.swatches[i].name);
} else {
elem.prop('title', rgb);
}
if (light.swatches[i].default) {
elem.addClass('default');
}
if (light.swatches[i].set) {
elem.addClass('set');
}
$('#new-swatch').before(elem);
}
$('#new-swatch').on('click', light.swatch.add);
$(document.body).on('click', '#light-swatches .swatch', function () {
var rgb = $(this).attr('color');
if (typeof color !== 'undefined') {
rgb = rgb.split(',');
$('#light-swatches .swatch').removeClass('default set');
$(this).addClass('default set');
if (w2ui['colors'].active === 'rgb') {
light.rgb.set(light.color);
}
light.preview(rgb);
}
});
$(document.body).on('dblclick', '.swatch', function () {
});
};
light.swatch.add = function () {
'use strict';
var swatch = $('<div class="swatch default set"></div>');
$('#light-swatches .swatch').removeClass('default set');
$('#new-swatch').before(swatch);
light.preview(light.color);
};
//GUI
gui.fmtZero = function (val, len) {
var raw = val,