libretime/legacy/public/js/waveformplaylist/controls.js

562 lines
12 KiB
JavaScript

'use strict';
var AudioControls = function() {
};
AudioControls.prototype.groups = {
"audio-select": ["btns_audio_tools", "btns_fade"]
};
AudioControls.prototype.classes = {
"btn-state-active": "btn btn-mini active",
"btn-state-default": "btn btn-mini",
"disabled": "disabled",
"active": "active"
};
AudioControls.prototype.events = {
"btn_rewind": {
click: "rewindAudio"
},
"btn_play": {
click: "playAudio"
},
"btn_stop": {
click: "stopAudio"
},
"btn_cursor": {
click: "changeState"
},
"btn_select": {
click: "changeState"
},
"btn_shift": {
click: "changeState"
},
"btn_fadein": {
click: "changeState"
},
"btn_fadeout": {
click: "changeState"
},
"btns_fade": {
click: "createFade"
},
"btn_save": {
click: "save"
},
"btn_open": {
click: "open"
},
"btn_trim_audio": {
click: "trimAudio"
},
"time_format": {
change: "changeTimeFormat"
},
"audio_start": {
blur: "validateCueIn"
},
"audio_end": {
blur: "validateCueOut"
},
"audio_pos": {
},
"audio_resolution": {
change: "changeResolution"
}
};
AudioControls.prototype.validateCue = function(value) {
var validators,
regex,
result;
validators = {
"seconds": /^\d+$/,
"thousandths": /^\d+\.\d{3}$/,
"hh:mm:ss": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]$/,
"hh:mm:ss.u": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]\.\d{1}$/,
"hh:mm:ss.uu": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]\.\d{2}$/,
"hh:mm:ss.uuu": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]\.\d{3}$/
};
regex = validators[this.timeFormat];
result = regex.test(value);
return result;
};
AudioControls.prototype.cueToSeconds = function(value) {
var converter,
func,
seconds;
function clockConverter(value) {
var data = value.split(":"),
hours = parseInt(data[0], 10) * 3600,
mins = parseInt(data[1], 10) * 60,
secs = parseFloat(data[2]),
seconds;
seconds = hours + mins + secs;
return seconds;
}
converter = {
"seconds": function(value) {
return parseInt(value, 10);
},
"thousandths": function(value) {
return parseFloat(value);
},
"hh:mm:ss": function(value) {
return clockConverter(value);
},
"hh:mm:ss.u": function(value) {
return clockConverter(value);
},
"hh:mm:ss.uu": function(value) {
return clockConverter(value);
},
"hh:mm:ss.uuu": function(value) {
return clockConverter(value);
}
};
func = converter[this.timeFormat];
seconds = func(value);
return seconds;
};
AudioControls.prototype.cueFormatters = function(format) {
function clockFormat(seconds, decimals) {
var hours,
minutes,
secs,
result;
hours = parseInt(seconds / 3600, 10) % 24;
minutes = parseInt(seconds / 60, 10) % 60;
secs = seconds % 60;
secs = secs.toFixed(decimals);
result = (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes) + ":" + (secs < 10 ? "0" + secs : secs);
return result;
}
var formats = {
"seconds": function (seconds) {
return seconds.toFixed(0);
},
"thousandths": function (seconds) {
return seconds.toFixed(3);
},
"hh:mm:ss": function (seconds) {
return clockFormat(seconds, 0);
},
"hh:mm:ss.u": function (seconds) {
return clockFormat(seconds, 1);
},
"hh:mm:ss.uu": function (seconds) {
return clockFormat(seconds, 2);
},
"hh:mm:ss.uuu": function (seconds) {
return clockFormat(seconds, 3);
}
};
return formats[format];
};
AudioControls.prototype.init = function(config) {
var that = this,
className,
event,
events = this.events,
tmpEl,
func,
state,
container,
tmpBtn;
makePublisher(this);
this.ctrls = {};
this.config = config;
container = this.config.getContainer();
state = this.config.getState();
tmpBtn = document.getElementsByClassName("btn_"+state)[0];
if (tmpBtn) {
this.activateButton(tmpBtn);
}
for (className in events) {
tmpEl = container.getElementsByClassName(className)[0];
this.ctrls[className] = tmpEl;
for (event in events[className]) {
if (tmpEl) {
func = that[events[className][event]].bind(that);
tmpEl.addEventListener(event, func);
}
}
}
if (this.ctrls["time_format"]) {
this.ctrls["time_format"].value = this.config.getTimeFormat();
}
if (this.ctrls["audio_resolution"]) {
this.ctrls["audio_resolution"].value = this.config.getResolution();
}
this.timeFormat = this.config.getTimeFormat();
//Kept in seconds so time format change can update fields easily.
this.currentSelectionValues = undefined;
this.onCursorSelection({
start: 0,
end: 0
});
};
AudioControls.prototype.changeTimeFormat = function(e) {
var format = e.target.value,
func, start, end;
format = (this.cueFormatters(format) !== undefined) ? format : "hh:mm:ss";
this.config.setTimeFormat(format);
this.timeFormat = format;
if (this.currentSelectionValues !== undefined) {
func = this.cueFormatters(format);
start = this.currentSelectionValues.start;
end = this.currentSelectionValues.end;
if (this.ctrls["audio_start"]) {
this.ctrls["audio_start"].value = func(start);
}
if (this.ctrls["audio_end"]) {
this.ctrls["audio_end"].value = func(end);
}
}
};
AudioControls.prototype.changeResolution = function(e) {
var res = parseInt(e.target.value, 10);
this.config.setResolution(res);
this.fire("changeresolution", res);
};
AudioControls.prototype.validateCueIn = function(e) {
var value = e.target.value,
end,
startSecs;
if (this.validateCue(value)) {
end = this.currentSelectionValues.end;
startSecs = this.cueToSeconds(value);
if (startSecs <= end) {
this.notifySelectionUpdate(startSecs, end);
this.currentSelectionValues.start = startSecs;
return;
}
}
//time entered was otherwise invalid.
e.target.value = this.cueFormatters(this.timeFormat)(this.currentSelectionValues.start);
};
AudioControls.prototype.validateCueOut = function(e) {
var value = e.target.value,
start,
endSecs;
if (this.validateCue(value)) {
start = this.currentSelectionValues.start;
endSecs = this.cueToSeconds(value);
if (endSecs >= start) {
this.notifySelectionUpdate(start, endSecs);
this.currentSelectionValues.end = endSecs;
return;
}
}
//time entered was otherwise invalid.
e.target.value = this.cueFormatters(this.timeFormat)(this.currentSelectionValues.end);
};
AudioControls.prototype.activateButtonGroup = function(id) {
var el = document.getElementById(id),
btns,
classes = this.classes,
i, len;
if (el === null) {
return;
}
btns = el.getElementsByTagName("a");
for (i = 0, len = btns.length; i < len; i++) {
btns[i].classList.remove(classes["disabled"]);
}
};
AudioControls.prototype.deactivateButtonGroup = function(id) {
var el = document.getElementById(id),
btns,
classes = this.classes,
i, len;
if (el === null) {
return;
}
btns = el.getElementsByTagName("a");
for (i = 0, len = btns.length; i < len; i++) {
btns[i].classList.add(classes["disabled"]);
}
};
AudioControls.prototype.activateAudioSelection = function() {
var ids = this.groups["audio-select"],
i, len;
for (i = 0, len = ids.length; i < len; i++) {
this.activateButtonGroup(ids[i]);
}
};
AudioControls.prototype.deactivateAudioSelection = function() {
var ids = this.groups["audio-select"],
i, len;
for (i = 0, len = ids.length; i < len; i++) {
this.deactivateButtonGroup(ids[i]);
}
};
AudioControls.prototype.save = function() {
this.fire('playlistsave', this);
};
AudioControls.prototype.open = function() {
this.fire('playlistrestore', this);
};
AudioControls.prototype.rewindAudio = function() {
this.fire('rewindaudio', this);
};
AudioControls.prototype.playAudio = function() {
this.fire('playaudio', this);
};
AudioControls.prototype.stopAudio = function() {
this.fire('stopaudio', this);
};
AudioControls.prototype.activateButton = function(el) {
if (el) {
el.classList.add(this.classes["active"]);
}
};
AudioControls.prototype.deactivateButton = function(el) {
if (el) {
el.classList.remove(this.classes["active"]);
}
};
AudioControls.prototype.enableButton = function(el) {
if (el) {
el.classList.remove(this.classes["disabled"]);
}
};
AudioControls.prototype.disableButton = function(el) {
if (el) {
el.classList.add(this.classes["disabled"]);
}
};
AudioControls.prototype.changeState = function(e) {
var el = e.currentTarget,
prevEl = el.parentElement.getElementsByClassName('active')[0],
state = el.dataset.state;
this.deactivateButton(prevEl);
this.activateButton(el);
this.config.setState(state);
this.fire('changestate', this);
};
AudioControls.prototype.zeroCrossing = function(e) {
var el = e.target,
disabled,
classes = this.classes;
disabled = el.classList.contains(classes["disabled"]);
if (!disabled) {
this.fire('trackedit', {
type: "zeroCrossing"
});
}
};
AudioControls.prototype.trimAudio = function(e) {
var el = e.target,
disabled,
classes = this.classes;
disabled = el.classList.contains(classes["disabled"]);
if (!disabled) {
this.fire('trackedit', {
type: "trimAudio"
});
}
};
AudioControls.prototype.removeAudio = function(e) {
var el = e.target,
disabled,
classes = this.classes;
disabled = el.classList.contains(classes["disabled"]);
if (!disabled) {
this.fire('trackedit', {
type: "removeAudio"
});
}
};
AudioControls.prototype.createFade = function(e) {
var el = e.target,
shape = el.dataset.shape,
type = el.dataset.type,
disabled,
classes = this.classes;
disabled = el.classList.contains(classes["disabled"]);
if (!disabled) {
this.fire('trackedit', {
type: "createFade",
args: {
type: type,
shape: shape
}
});
}
};
AudioControls.prototype.onAudioSelection = function() {
this.activateAudioSelection();
};
AudioControls.prototype.onAudioDeselection = function() {
this.deactivateAudioSelection();
};
/*
start, end in seconds
*/
AudioControls.prototype.notifySelectionUpdate = function(start, end) {
this.fire('changeselection', {
start: start,
end: end
});
};
/*
start, end in seconds
*/
AudioControls.prototype.onCursorSelection = function(args) {
var startFormat = this.cueFormatters(this.timeFormat)(args.start),
endFormat = this.cueFormatters(this.timeFormat)(args.end),
start = this.cueToSeconds(startFormat),
end = this.cueToSeconds(endFormat);
this.currentSelectionValues = {
start: start,
end:end
};
if (this.ctrls["audio_start"]) {
this.ctrls["audio_start"].value = startFormat;
}
if (this.ctrls["audio_end"]) {
this.ctrls["audio_end"].value = endFormat;
}
};
/*
args {seconds, pixels}
*/
AudioControls.prototype.onAudioUpdate = function(args) {
if (this.ctrls["audio_pos"]) {
this.ctrls["audio_pos"].innerHTML = this.cueFormatters(this.timeFormat)(args.seconds);
}
};