Initial WebUI design and structure with JSON sample function (#170)

* Initial WebUI with sample functions

* Changed folder structure

* Light Reset Button and Translation fixing in Links

* Indentation fixed

* Reorganized menu and new function for setting effects

* Styling fix
This commit is contained in:
b1rdhous3
2016-08-13 20:05:01 +02:00
committed by redPanther
parent 5a902add81
commit 1ff8528597
570 changed files with 41576 additions and 995 deletions

View File

@@ -0,0 +1,64 @@
/**
* hyperion remote
* MIT License
*/
define(['lib/stapes'], function (Stapes) {
'use strict';
return Stapes.subclass(/** @lends EffectsView.prototype */{
/**
* @class EffectsView
* @constructs
*/
constructor: function () {
this.bindEventHandlers();
},
/**
* @private
*/
bindEventHandlers: function () {
window.addClickHandler(document.querySelector('#effects ul'), function (event) {
var selected = event.target.parentNode.querySelector('.selected');
if (selected) {
selected.classList.remove('selected');
}
event.target.classList.add('selected');
this.emit('effectSelected', event.target.dataset.id);
}.bind(this));
},
/**
* Clear the list
*/
clear: function () {
document.querySelector('#effects ul').innerHTML = '';
document.querySelector('#effects .info').classList.add('hidden');
},
/**
* Fill the list
* @param {object} effects - Object containing effect information
*/
fillList: function (effects) {
var dom, el, i;
dom = document.createDocumentFragment();
for (i = 0; i < effects.length; i++) {
el = document.createElement('li');
el.innerHTML = effects[i].name;
el.dataset.id = effects[i].id;
dom.appendChild(el);
}
document.querySelector('#effects ul').appendChild(dom);
if (effects.length === 0) {
document.querySelector('#effects .info').classList.remove('hidden');
}
}
});
});

View File

@@ -0,0 +1,402 @@
define([
'lib/stapes',
'lib/tinycolor',
'utils/Tools',
'views/Slider'
], function (Stapes, Tinycolor, tools, Slider) {
'use strict';
var timer;
function showMessageField (text, type) {
var dom, wrapper;
dom = document.querySelector('.work .msg');
if (!dom) {
dom = document.createElement('div');
dom.classList.add('msg');
dom.classList.add(type);
wrapper = document.createElement('div');
wrapper.classList.add('wrapper_msg');
wrapper.classList.add('invisible');
wrapper.appendChild(dom);
document.querySelector('.work').appendChild(wrapper);
setTimeout(function () {
wrapper.classList.remove('invisible');
}, 0);
}
if (!dom.classList.contains(type)) {
dom.className = 'msg';
dom.classList.add(type);
}
dom.innerHTML = text;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
var error = document.querySelector('.work .wrapper_msg');
if (error) {
error.parentNode.removeChild(error);
}
}, 1600);
}
return Stapes.subclass(/** @lends MainView.prototype*/{
pointer: null,
colorpicker: null,
slider: null,
sliderinput: null,
cpradius: 0,
cpcenter: 0,
drag: false,
color: null,
brightness: 1.0,
inputbox: null,
/**
* @class MainView
* @construct
* @fires barClick
* @fires colorChange
*/
constructor: function () {
var ev;
this.pointer = document.querySelector('#colorpicker #pointer');
this.colorpicker = document.querySelector('#colorpicker #colorwheelbg');
this.slider = new Slider({
element: document.getElementById('brightness'),
min: 0,
max: 1,
step: 0.02,
value: 1
});
this.inputbox = document.querySelector('#color input.value');
this.cpradius = this.colorpicker.offsetWidth / 2;
this.cpcenter = this.colorpicker.offsetLeft + this.cpradius;
this.bindEventHandlers();
ev = document.createEvent('Event');
ev.initEvent('resize', true, true);
window.dispatchEvent(ev);
},
/**
* @private
*/
bindEventHandlers: function () {
var cptouchrect;
window.addEventListener('resize', function () {
var attrW, attrH, side, w = this.colorpicker.parentNode.clientWidth, h = this.colorpicker.parentNode.clientHeight;
attrW = this.colorpicker.getAttribute('width');
attrH = this.colorpicker.getAttribute('height');
side = attrW === 'auto' ? attrH : attrW;
if (w > h) {
if (attrH !== side) {
this.colorpicker.setAttribute('height', side);
this.colorpicker.setAttribute('width', 'auto');
}
} else if (attrW !== side) {
this.colorpicker.setAttribute('height', 'auto');
this.colorpicker.setAttribute('width', side);
}
this.cpradius = this.colorpicker.offsetWidth / 2;
this.cpcenter = this.colorpicker.offsetLeft + this.cpradius;
if (this.color) {
this.updatePointer();
}
}.bind(this));
window.addClickHandler(document.querySelector('.footer'), function (event) {
this.emit('barClick', event.target.parentNode.dataset.area);
}.bind(this));
this.slider.on('changeValue', function (value) {
this.brightness = value.value;
this.updateInput();
this.fireColorEvent();
}, this);
this.inputbox.addEventListener('input', function (event) {
var bright, rgb = new Tinycolor(event.target.value).toRgb();
if (rgb.r === 0 && rgb.g === 0 && rgb.b === 0) {
this.brightness = 0;
this.color = new Tinycolor({
r: 0xff,
g: 0xff,
b: 0xff
});
} else {
bright = Math.max(rgb.r, rgb.g, rgb.b) / 256;
rgb.r = Math.round(rgb.r / bright);
rgb.g = Math.round(rgb.g / bright);
rgb.b = Math.round(rgb.b / bright);
this.brightness = bright;
this.color = new Tinycolor(rgb);
}
this.fireColorEvent();
this.updatePointer();
this.updateSlider();
}.bind(this), false);
this.inputbox.addEventListener('keydown', function (event) {
switch (event.keyCode) {
case 8:
case 9:
case 16:
case 37:
case 38:
case 39:
case 40:
case 46:
break;
default:
{
if (event.target.value.length >= 6 && (event.target.selectionEnd - event.target.selectionStart) === 0) {
event.preventDefault();
event.stopPropagation();
} else if (event.keyCode < 48 || event.keyCode > 71) {
event.preventDefault();
event.stopPropagation();
}
}
}
});
cptouchrect = document.querySelector('#colorpicker .touchrect');
window.addPointerDownHandler(cptouchrect, function (event) {
this.leaveInput();
this.drag = true;
this.handleEvent(event);
}.bind(this));
window.addPointerMoveHandler(cptouchrect, function (event) {
if (this.drag) {
this.handleEvent(event);
event.preventDefault();
}
}.bind(this));
window.addPointerUpHandler(cptouchrect, function () {
this.drag = false;
}.bind(this));
window.addClickHandler(document.querySelector('#clear_button'), function () {
this.emit('clear');
}.bind(this));
window.addClickHandler(document.querySelector('#clearall_button'), function () {
this.emit('clearall');
}.bind(this));
},
/**
* @private
* @param event
*/
handleEvent: function (event) {
var point, x, y;
if (event.touches) {
x = event.touches[0].clientX;
y = event.touches[0].clientY;
} else {
x = event.clientX;
y = event.clientY;
}
point = this.getCirclePoint(x, y);
this.color = this.getColorFromPoint(point);
this.updatePointer();
this.updateSlider();
this.updateInput();
this.fireColorEvent();
},
/**
* @private
* @param {number} x
* @param {number} y
* @returns {{x: number, y: number}}
*/
getCirclePoint: function (x, y) {
var p = {
x: x,
y: y
}, c = {
x: this.colorpicker.offsetLeft + this.cpradius,
y: this.colorpicker.offsetTop + this.cpradius
}, n;
n = Math.sqrt(Math.pow((x - c.x), 2) + Math.pow((y - c.y), 2));
if (n > this.cpradius) {
p.x = (c.x) + this.cpradius * ((x - c.x) / n);
p.y = (c.y) + this.cpradius * ((y - c.y) / n);
}
return p;
},
/**
* @private
* @param {{x: number, y: number}} p
* @returns {Tinycolor}
*/
getColorFromPoint: function (p) {
var h, t, s, x, y;
x = p.x - this.colorpicker.offsetLeft - this.cpradius;
y = this.cpradius - p.y + this.colorpicker.offsetTop;
t = Math.atan2(y, x);
h = (t * (180 / Math.PI) + 360) % 360;
s = Math.min(Math.sqrt(x * x + y * y) / this.cpradius, 1);
return new Tinycolor({
h: h,
s: s,
v: 1
});
},
/**
* @private
* @param color
* @returns {{x: number, y: number}}
*/
getPointFromColor: function (color) {
var t, x, y, p = {};
t = color.h * (Math.PI / 180);
y = Math.sin(t) * this.cpradius * color.s;
x = Math.cos(t) * this.cpradius * color.s;
p.x = Math.round(x + this.colorpicker.offsetLeft + this.cpradius);
p.y = Math.round(this.cpradius - y + this.colorpicker.offsetTop);
return p;
},
/**
* @private
*/
fireColorEvent: function () {
var rgb = this.color.toRgb();
rgb.r = Math.round(rgb.r * this.brightness);
rgb.g = Math.round(rgb.g * this.brightness);
rgb.b = Math.round(rgb.b * this.brightness);
this.emit('colorChange', rgb);
},
/**
*
* @param rgb
*/
setColor: function (rgb) {
var bright;
if (rgb.r === 0 && rgb.g === 0 && rgb.b === 0) {
this.brightness = 0;
this.color = new Tinycolor({
r: 0xff,
g: 0xff,
b: 0xff
});
} else {
bright = Math.max(rgb.r, rgb.g, rgb.b) / 256;
rgb.r = Math.round(rgb.r / bright);
rgb.g = Math.round(rgb.g / bright);
rgb.b = Math.round(rgb.b / bright);
this.brightness = bright;
this.color = new Tinycolor(rgb);
}
this.updatePointer();
this.updateSlider();
this.updateInput();
},
/**
* @private
*/
updateSlider: function () {
this.slider.setValue(this.brightness);
this.slider.dom.style.backgroundImage = '-webkit-linear-gradient(left, #000000 0%, ' + this.color.toHexString() + ' 100%)';
},
/**
* @private
*/
updatePointer: function () {
var point = this.getPointFromColor(this.color.toHsv());
this.pointer.style.left = (point.x - this.pointer.offsetWidth / 2) + 'px';
this.pointer.style.top = (point.y - this.pointer.offsetHeight / 2) + 'px';
this.pointer.style.backgroundColor = this.color.toHexString();
},
/**
* @private
*/
updateInput: function () {
var rgb = this.color.toRgb();
rgb.r = Math.round(rgb.r * this.brightness);
rgb.g = Math.round(rgb.g * this.brightness);
rgb.b = Math.round(rgb.b * this.brightness);
this.inputbox.value = this.inputbox.style.backgroundColor = (
'#'
+ tools.b2hexstr(rgb.r)
+ tools.b2hexstr(rgb.g)
+ tools.b2hexstr(rgb.b)
);
this.inputbox.style.color = (rgb.r + rgb.g + rgb.b) < 384 ? '#fff' : '#000';
},
/**
* Scroll to the specific tab content
* @param {string} id - Id of the tab to scroll to
*/
scrollToArea: function (id) {
var area, index;
document.querySelector('.footer .selected').classList.remove('selected');
document.querySelector('.footer .button[data-area =' + id + ']').classList.add('selected');
area = document.getElementById(id);
index = area.offsetLeft / area.clientWidth;
area.parentNode.style.left = (-index * 100) + '%';
},
/**
* Shows a status message
* @param {string} message - Text to show
*/
showStatus: function (message) {
showMessageField(message, 'status');
},
/**
* Shows the error text
* @param {string} error - Error message
*/
showError: function (error) {
showMessageField(error, 'error');
},
/**
* @private
*/
leaveInput: function () {
this.inputbox.blur();
}
});
});

View File

@@ -0,0 +1,199 @@
define(['lib/stapes'], function (Stapes) {
'use strict';
/**
*
* @param params
* @returns {HTMLElement}
*/
function buildDom (params) {
var dom, label, ul, li, i, header;
dom = document.createElement('div');
dom.classList.add('grouplist');
dom.id = params.id;
header = document.createElement('div');
header.classList.add('header');
dom.appendChild(header);
label = document.createElement('div');
label.innerHTML = params.label;
label.classList.add('title');
header.appendChild(label);
label = document.createElement('div');
label.innerHTML = '&#xe804;';
label.classList.add('callout');
header.appendChild(label);
ul = document.createElement('ul');
dom.appendChild(ul);
if (params.list) {
for (i = 0; i < params.list.length; i++) {
li = createLine(params.list[i]);
ul.appendChild(li);
}
}
return dom;
}
function createLine (params) {
var dom, el, horiz, box, touch;
dom = document.createDocumentFragment();
horiz = document.createElement('div');
horiz.classList.add('horizontal');
dom.appendChild(horiz);
touch = document.createElement('div');
touch.classList.add('horizontal');
horiz.appendChild(touch);
el = document.createElement('div');
el.classList.add('checkbox');
touch.appendChild(el);
box = document.createElement('div');
box.classList.add('titlebox');
touch.appendChild(box);
el = document.createElement('label');
el.classList.add('title');
el.innerHTML = params.title || '';
box.appendChild(el);
el = document.createElement('label');
el.classList.add('subtitle');
el.innerHTML = params.subtitle;
box.appendChild(el);
el = document.createElement('div');
el.classList.add('touchrect');
touch.appendChild(el);
el = document.createElement('div');
el.classList.add('edit_icon');
el.innerHTML = '&#xe801;';
horiz.appendChild(el);
el = document.createElement('div');
el.classList.add('delete_icon');
el.innerHTML = '&#xe612;';
horiz.appendChild(el);
return dom;
}
return Stapes.subclass(/** @lends ServerList.prototype */{
/**
* @private
* @type {HTMLElement}
*/
dom: null,
/**
* @class ServerList
* @constructs
* @param {object} params - List parameter
* @param {string} params.id - List id
* @param {string} params.label - List title
* @param {{title: string, subtitle: string, c}[]} [params.list] - List elements
*
* @fires add
* @fires remove
* @fires select
* @fires edit
*/
constructor: function (params) {
this.dom = buildDom(params || {});
this.bindEventHandlers();
},
/**
* @private
*/
bindEventHandlers: function () {
window.addClickHandler(this.dom.querySelector('.callout'), function () {
this.emit('add');
}.bind(this));
window.addClickHandler(this.dom.querySelector('ul'), function (event) {
if (event.target.classList.contains('delete_icon')) {
this.emit('remove', event.target.parentNode.parentNode.id);
} else if (event.target.classList.contains('edit_icon')) {
this.emit('edit', event.target.parentNode.parentNode.id);
} else if (event.target.classList.contains('touchrect')) {
this.emit('select', event.target.parentNode.parentNode.parentNode.id);
}
}.bind(this));
},
/**
* Returns the DOM of the list
* @returns {HTMLElement}
*/
getDom: function () {
return this.dom;
},
/**
* Append a line
* @param id
* @param selected
* @param element
*/
append: function (id, selected, element) {
var li = document.createElement('li');
li.id = id;
if (selected) {
li.classList.add('selected');
}
li.appendChild(element);
this.dom.querySelector('ul').appendChild(li);
},
/**
* Replace a line
* @param index
* @param element
*/
replace: function (index, element) {
var child = this.dom.querySelector('ul li:nth-child(' + (index + 1) + ')'), li;
if (child) {
li = document.createElement('li');
li.appendChild(element);
this.dom.querySelector('ul').replaceChild(li, child);
}
},
/**
* Add a line
* @param lineParam
*/
addLine: function (lineParam) {
var line = createLine(lineParam);
this.append(lineParam.id, lineParam.selected, line);
},
/**
* Clear the list
*/
clear: function () {
this.dom.querySelector('ul').innerHTML = '';
},
/**
* Hide or show the Add button in the header
* @param {boolean} show - True to show, false to hide
*/
showAddButton: function (show) {
if (show) {
this.dom.querySelector('.callout').classList.remove('invisible');
} else {
this.dom.querySelector('.callout').classList.add('invisible');
}
}
});
});

View File

@@ -0,0 +1,259 @@
define(['lib/stapes', 'views/ServerList'], function (Stapes, ServerList) {
'use strict';
function createLabelInputLine (params) {
var dom, el;
dom = document.createElement('div');
dom.classList.add('inputline');
dom.id = params.id;
el = document.createElement('label');
el.innerHTML = params.label;
dom.appendChild(el);
el = document.createElement('input');
if (typeof params.value === 'number') {
el.type = 'number';
}
el.value = params.value || '';
el.autocomplete='off';
el.autocorrect='off';
el.autocapitalize='off';
dom.appendChild(el);
return dom;
}
function createButtonLine (params) {
var dom, el;
dom = document.createElement('div');
dom.classList.add('inputline');
el = document.createElement('button');
el.innerHTML = params.label;
el.classList.add('OK');
dom.appendChild(el);
el = document.createElement('button');
el.innerHTML = 'Cancel';
el.classList.add('CANCEL');
dom.appendChild(el);
return dom;
}
function createDetectLine () {
var dom, el;
dom = document.createElement('div');
dom.classList.add('line');
el = document.createElement('button');
el.id = 'detect_button';
el.innerHTML = 'Detect';
dom.appendChild(el);
el = document.createElement('div');
el.classList.add('spinner');
el.classList.add('hidden');
dom.appendChild(el);
return dom;
}
return Stapes.subclass(/** @lends SettingsView.prototype */{
dom: null,
serverList: null,
/**
* @class SettingsView
* @classdesc View for the settings
* @constructs
*/
constructor: function () {
var list = [], el;
this.dom = document.querySelector('#settings');
this.serverList = new ServerList({
id: 'serverList',
label: 'Server',
list: list
});
this.serverList.on({
add: function () {
var line, box;
this.enableDetectButton(false);
this.lockList(true);
box = document.createDocumentFragment();
line = createLabelInputLine({id: 'name', label: 'Name:'});
box.appendChild(line);
line = createLabelInputLine({id: 'address', label: 'Address:'});
box.appendChild(line);
line = createLabelInputLine({id: 'port', label: 'Port:', value: 19444});
box.appendChild(line);
line = createLabelInputLine({id: 'priority', label: 'Priority:', value: 50});
box.appendChild(line);
line = createLabelInputLine({id: 'duration', label: 'Duration (sec):', value: 0});
box.appendChild(line);
line = createButtonLine({label: 'Add'});
window.addClickHandler(line.firstChild, function (event) {
var server = {}, i, inputs = event.target.parentNode.parentNode.querySelectorAll('input');
for (i = 0; i < inputs.length; i++) {
server[inputs[i].parentNode.id] = inputs[i].value;
}
server.port = parseInt(server.port);
server.priority = parseInt(server.priority);
server.duration = parseInt(server.duration);
this.emit('serverAdded', server);
}.bind(this));
window.addClickHandler(line.lastChild, function () {
this.emit('serverAddCanceled');
}.bind(this));
box.appendChild(line);
this.serverList.append(null, false, box);
},
select: function (id) {
if (!this.dom.classList.contains('locked')) {
this.emit('serverSelected', parseInt(id.replace('server_', '')));
}
},
remove: function (id) {
this.emit('serverRemoved', parseInt(id.replace('server_', '')));
},
edit: function (id) {
this.emit('editServer', parseInt(id.replace('server_', '')));
}
}, this);
this.dom.appendChild(this.serverList.getDom());
el = createDetectLine();
window.addClickHandler(el.querySelector('button'), function () {
this.emit('detect');
}.bind(this));
this.dom.appendChild(el);
},
/**
* Fills the list of known servers
* @param {Array} servers
*/
fillServerList: function (servers) {
var i, server, params;
this.serverList.clear();
for (i = 0; i < servers.length; i++) {
server = servers[i];
params = {id: 'server_' + i, title: server.name, subtitle: server.address + ':' + server.port};
if (server.selected) {
params.selected = true;
}
this.serverList.addLine(params);
}
this.serverList.showAddButton(true);
},
/**
* Shows or hides the spinner as progress indicator
* @param {boolean} show True to show, false to hide
*/
showWaiting: function (show) {
if (show) {
this.dom.querySelector('.spinner').classList.remove('hidden');
} else {
this.dom.querySelector('.spinner').classList.add('hidden');
}
},
/**
* Enables or disables the detect button
* @param {Boolean} enabled True to enable, false to disable
*/
enableDetectButton: function (enabled) {
if (enabled) {
this.dom.querySelector('#detect_button').classList.remove('hidden');
} else {
this.dom.querySelector('#detect_button').classList.add('hidden');
}
},
/**
* Locks the list for editing/deleting
* @param {Boolean} lock True to lock, false to unlock
*/
lockList: function (lock) {
if (!lock) {
this.dom.classList.remove('locked');
this.serverList.showAddButton(true);
} else {
this.dom.classList.add('locked');
this.serverList.showAddButton(false);
}
},
editServer: function (serverInfo) {
var line, box;
this.lockList(true);
this.enableDetectButton(false);
box = document.createDocumentFragment();
line = createLabelInputLine({id: 'name', label: 'Name:', value: serverInfo.server.name});
box.appendChild(line);
line = createLabelInputLine({id: 'address', label: 'Address:', value: serverInfo.server.address});
box.appendChild(line);
line = createLabelInputLine({id: 'port', label: 'Port:', value: serverInfo.server.port});
box.appendChild(line);
line = createLabelInputLine({id: 'priority', label: 'Priority:', value: serverInfo.server.priority});
box.appendChild(line);
line = createLabelInputLine({id: 'duration', label: 'Duration (sec):', value: serverInfo.server.duration});
box.appendChild(line);
line = createButtonLine({label: 'Done'});
window.addClickHandler(line.querySelector('button.OK'), function (event) {
var server = {}, i, inputs = event.target.parentNode.parentNode.querySelectorAll('input');
for (i = 0; i < inputs.length; i++) {
server[inputs[i].parentNode.id] = inputs[i].value;
}
server.port = parseInt(server.port);
server.priority = parseInt(server.priority);
server.duration = parseInt(server.duration);
if (serverInfo.server.selected) {
server.selected = true;
}
this.emit('serverChanged', {index: serverInfo.index, server: server});
}.bind(this));
window.addClickHandler(line.querySelector('button.CANCEL'), function () {
this.emit('serverEditCanceled');
}.bind(this));
box.appendChild(line);
window.addClickHandler(box.querySelector('input'), function (event) {
event.stopPropagation();
});
this.serverList.replace(serverInfo.index, box);
}
});
});

View File

@@ -0,0 +1,134 @@
define(['lib/stapes'], function (Stapes) {
'use strict';
function syncView (slider) {
var left = (slider.value - slider.min) * 100 / (slider.max - slider.min);
slider.dom.lastElementChild.style.left = left + '%';
}
function handleEvent(event, slider) {
var x, left, ratio, value, steppedValue;
if (event.touches) {
x = event.touches[0].clientX;
} else {
x = event.clientX;
}
left = x - slider.dom.getBoundingClientRect().left;
ratio = left / slider.dom.offsetWidth;
value = (slider.max - slider.min) * ratio;
steppedValue = (value - slider.min) % slider.step;
if (steppedValue <= slider.step / 2) {
value = value - steppedValue;
} else {
value = value + (slider.step - steppedValue);
}
value = Math.max(value, slider.min);
value = Math.min(value, slider.max);
slider.value = value;
slider.emit('changeValue', {
'value': value,
'target': slider.dom
});
}
return Stapes.subclass(/** @lends Slider.prototype */{
/**
* @private
* @type {Element}
*/
dom: null,
/**
* @private
* @type {Number}
*/
min: 0,
/**
* @private
* @type {Number}
*/
max: 100,
/**
* @private
* @type {Number}
*/
value: 0,
/**
* @private
* @type {Number}
*/
step: 1,
/**
* @class Slider
* @constructs
* @fires change
*/
constructor: function (params) {
this.dom = params.element;
this.setValue(params.value);
this.setMin(params.min);
this.setMax(params.max);
this.setStep(params.step);
this.bindEventHandlers();
},
/**
* @private
*/
bindEventHandlers: function () {
var that = this;
function pointerMoveEventHandler(event) {
if (that.drag) {
handleEvent(event, that);
syncView(that);
event.preventDefault();
}
}
function pointerUpEventHandler() {
that.drag = false;
syncView(that);
window.removePointerMoveHandler(document, pointerMoveEventHandler);
window.removePointerUpHandler(document, pointerUpEventHandler);
}
window.addPointerDownHandler(this.dom, function (event) {
this.drag = true;
handleEvent(event, this);
syncView(this);
window.addPointerMoveHandler(document, pointerMoveEventHandler);
window.addPointerUpHandler(document, pointerUpEventHandler);
}.bind(this));
},
setValue: function(value) {
this.value = value || 0;
syncView(this);
},
setMin: function(value) {
this.min = value || 0;
syncView(this);
},
setMax: function(value) {
this.max = value || 100;
syncView(this);
},
setStep: function(value) {
this.step = value || 1;
syncView(this);
}
});
});

View File

@@ -0,0 +1,375 @@
/**
* hyperion remote
* MIT License
*/
define([
'lib/stapes',
'views/Slider'
], function (Stapes, Slider) {
'use strict';
function onHeaderClick (event) {
var list = event.target.parentNode.parentNode.querySelector('ul');
if (list.clientHeight === 0) {
list.style.maxHeight = list.scrollHeight + 'px';
event.target.parentNode.parentNode.setAttribute('collapsed', 'false');
} else {
list.style.maxHeight = 0;
event.target.parentNode.parentNode.setAttribute('collapsed', 'true');
}
}
function createLine (id, type, icon, caption, value, min, max) {
var dom, el, el2, label, wrapper;
dom = document.createElement('li');
dom.className = type;
label = document.createElement('label');
label.innerHTML = caption;
dom.appendChild(label);
wrapper = document.createElement('div');
wrapper.classList.add('wrapper');
wrapper.id = id;
el = document.createElement('div');
el.classList.add('icon');
el.innerHTML = icon;
wrapper.appendChild(el);
el = document.createElement('div');
el.classList.add('slider');
el2 = document.createElement('div');
el2.classList.add('track');
el.appendChild(el2);
el2 = document.createElement('div');
el2.classList.add('thumb');
el.appendChild(el2);
el.dataset.min = min;
el.dataset.max = max;
el.dataset.value = value;
el.dataset.step = 0.01;
wrapper.appendChild(el);
el = document.createElement('input');
el.classList.add('value');
el.type = 'number';
el.min = min;
el.max = max;
el.step = 0.01;
el.value = parseFloat(Math.round(value * 100) / 100).toFixed(2);
wrapper.appendChild(el);
dom.appendChild(wrapper);
return dom;
}
function createGroup (groupInfo) {
var group, node, subnode, i, member;
group = document.createElement('div');
group.classList.add('group');
if (groupInfo.collapsed) {
group.setAttribute('collapsed', 'true');
}
group.id = groupInfo.id;
node = document.createElement('div');
node.classList.add('header');
group.appendChild(node);
subnode = document.createElement('label');
subnode.innerHTML = groupInfo.title;
node.appendChild(subnode);
subnode = document.createElement('label');
subnode.innerHTML = groupInfo.subtitle;
node.appendChild(subnode);
node = document.createElement('ul');
group.appendChild(node);
for (i = 0; i < groupInfo.members.length; i++) {
member = groupInfo.members[i];
subnode = createLine(member.id, member.type, member.icon, member.label, member.value, member.min,
member.max);
node.appendChild(subnode);
}
return group;
}
return Stapes.subclass(/** @lends TransformView.prototype */{
sliders: {},
/**
* @class TransformView
* @constructs
*/
constructor: function () {
},
/**
* Clear the list
*/
clear: function () {
document.querySelector('#transform .values').innerHTML = '';
},
/**
* @private
* @param change
*/
onSliderChange: function (event) {
var data = {}, idparts, value;
idparts = event.target.parentNode.id.split('_');
value = parseFloat(Math.round(parseFloat(event.value) * 100) / 100);
event.target.parentNode.querySelector('.value').value = value.toFixed(2);
data[idparts[1]] = value;
this.emit(idparts[0], data);
},
/**
* @private
* @param change
*/
onValueChange: function (event) {
var data = {}, idparts, value;
idparts = event.target.parentNode.id.split('_');
value = parseFloat(Math.round(parseFloat(event.target.value) * 100) / 100);
if (parseFloat(event.target.value) < parseFloat(event.target.min)) {
event.target.value = event.target.min;
} else if (parseFloat(event.target.value) > parseFloat(event.target.max)) {
event.target.value = event.target.max;
}
this.sliders[event.target.parentNode.id].setValue(value);
data[idparts[1]] = value;
this.emit(idparts[0], data);
},
/**
* fill the list
* @param {object} transform - Object containing transform information
*/
fillList: function (transform) {
var dom, group, els, i, slider;
if (!transform) {
document.querySelector('#transform .info').classList.remove('hidden');
return;
}
dom = document.createDocumentFragment();
group = createGroup({
collapsed: true,
id: 'HSV',
title: 'HSV',
subtitle: 'HSV color corrections',
members: [
{
id: 'hsv_saturationGain',
type: 'saturation',
icon: '&#xe806;',
label: 'Saturation gain',
value: transform.saturationGain,
min: 0,
max: 5
},
{
id: 'hsv_valueGain',
type: 'value',
icon: '&#xe805;',
label: 'Value gain',
value: transform.valueGain,
min: 0,
max: 5
}
]
});
dom.appendChild(group);
group = createGroup({
collapsed: true,
id: 'Gamma',
title: 'Gamma',
subtitle: 'Gamma correction',
members: [
{
id: 'gamma_r',
type: 'red',
icon: '&#xe800;',
label: 'Red',
value: transform.gamma[0],
min: 0,
max: 5
},
{
id: 'gamma_g',
type: 'green',
icon: '&#xe800;',
label: 'Green',
value: transform.gamma[1],
min: 0,
max: 5
},
{
id: 'gamma_b',
type: 'blue',
icon: '&#xe800;',
label: 'Blue',
value: transform.gamma[2],
min: 0,
max: 5
}
]
});
dom.appendChild(group);
group = createGroup({
collapsed: true,
id: 'Whitelevel',
title: 'Whitelevel',
subtitle: 'Value when RGB channel is fully on',
members: [
{
id: 'whitelevel_r',
type: 'red',
icon: '&#xe800;',
label: 'Red',
value: transform.whitelevel[0],
min: 0,
max: 1
},
{
id: 'whitelevel_g',
type: 'green',
icon: '&#xe800;',
label: 'Green',
value: transform.whitelevel[1],
min: 0,
max: 1
},
{
id: 'whitelevel_b',
type: 'blue',
icon: '&#xe800;',
label: 'Blue',
value: transform.whitelevel[2],
min: 0,
max: 1
}
]
});
dom.appendChild(group);
group = createGroup({
collapsed: true,
id: 'Blacklevel',
title: 'Blacklevel',
subtitle: 'Value when RGB channel is fully off',
members: [
{
id: 'blacklevel_r',
type: 'red',
icon: '&#xe800;',
label: 'Red',
value: transform.blacklevel[0],
min: 0,
max: 1
},
{
id: 'blacklevel_g',
type: 'green',
icon: '&#xe800;',
label: 'Green',
value: transform.blacklevel[1],
min: 0,
max: 1
},
{
id: 'blacklevel_b',
type: 'blue',
icon: '&#xe800;',
label: 'Blue',
value: transform.blacklevel[2],
min: 0,
max: 1
}
]
});
dom.appendChild(group);
group = createGroup({
collapsed: true,
id: 'Threshold',
title: 'Threshold',
subtitle: 'Threshold for a channel',
members: [
{
id: 'threshold_r',
type: 'red',
icon: '&#xe800;',
label: 'Red',
value: transform.threshold[0],
min: 0,
max: 1
},
{
id: 'threshold_g',
type: 'green',
icon: '&#xe800;',
label: 'Green',
value: transform.threshold[1],
min: 0,
max: 1
},
{
id: 'threshold_b',
type: 'blue',
icon: '&#xe800;',
label: 'Blue',
value: transform.threshold[2],
min: 0,
max: 1
}
]
});
dom.appendChild(group);
els = dom.querySelectorAll('.slider');
for (i = 0; i < els.length; i++) {
slider = new Slider({
element: els[i],
min: els[i].dataset.min,
max: els[i].dataset.max,
step: els[i].dataset.step,
value: els[i].dataset.value
});
slider.on('changeValue', this.onSliderChange, this);
this.sliders[els[i].parentNode.id] = slider;
}
els = dom.querySelectorAll('input');
for (i = 0; i < els.length; i++) {
els[i].addEventListener('input', this.onValueChange.bind(this), false);
}
els = dom.querySelectorAll('.header');
for (i = 0; i < els.length; i++) {
window.addClickHandler(els[i], onHeaderClick);
}
document.querySelector('#transform .info').classList.add('hidden');
document.querySelector('#transform .values').appendChild(dom);
}
});
});