diff --git a/js/browser.js b/js/browser.js index d46e10e9..f49114ef 100644 --- a/js/browser.js +++ b/js/browser.js @@ -1,9 +1,6 @@ -define([], function() { - return function(base) { - var supportsAudioApi = !!(base.AudioContext || base.webkitAudioContext); - var supportsCanvas = !!(base.document.createElement('canvas').getContext); - - this.isCompatible = supportsAudioApi && supportsCanvas; - }; -}); +module.exports = function(base) { + var supportsAudioApi = !!(base.AudioContext || base.webkitAudioContext); + var supportsCanvas = !!(base.document.createElement('canvas').getContext); + this.isCompatible = supportsAudioApi && supportsCanvas; +}; diff --git a/js/context.js b/js/context.js index 3c49e208..46cfea28 100644 --- a/js/context.js +++ b/js/context.js @@ -1,50 +1,45 @@ -define([ - 'my-file' -], function( - MyFile -) { - var Context = function(winamp) { - this.winamp = winamp; +import MyFile from './my-file'; +var Context = function(winamp) { + this.winamp = winamp; - var el = { - option: document.getElementById('option'), - playFile: document.getElementById('context-play-file'), - loadSkin: document.getElementById('context-load-skin'), - exit: document.getElementById('context-exit'), - skinOptions: document.getElementsByClassName('skin-select') - }; - - // Click anywhere to close the context menu - document.addEventListener('click', function() { - el.option.classList.remove('selected'); - }); - - // Click the context menu to close it - el.option.addEventListener('click', function(e) { - el.option.classList.toggle('selected'); - e.stopPropagation(); - }); - - // Bind to each of the various skin options - for (var i = 0; i < el.skinOptions.length; i++) { - el.skinOptions[i].addEventListener('click', function(e) { - this.loadSkin(e.target.dataset.skinUrl); - }.bind(this)); - } - - // Play file and load skin both just spawn the file opener - el.playFile.addEventListener('click', winamp.openFileDialog); - el.loadSkin.addEventListener('click', winamp.openFileDialog); - - // Close all of Winamp - el.exit.addEventListener('click', winamp.close); + var el = { + option: document.getElementById('option'), + playFile: document.getElementById('context-play-file'), + loadSkin: document.getElementById('context-load-skin'), + exit: document.getElementById('context-exit'), + skinOptions: document.getElementsByClassName('skin-select') }; - Context.prototype.loadSkin = function(url) { - var skinFile = new MyFile(); - skinFile.setUrl(url); - this.winamp.setSkin(skinFile); - }; + // Click anywhere to close the context menu + document.addEventListener('click', function() { + el.option.classList.remove('selected'); + }); - return Context; -}); + // Click the context menu to close it + el.option.addEventListener('click', function(e) { + el.option.classList.toggle('selected'); + e.stopPropagation(); + }); + + // Bind to each of the various skin options + for (var i = 0; i < el.skinOptions.length; i++) { + el.skinOptions[i].addEventListener('click', function(e) { + this.loadSkin(e.target.dataset.skinUrl); + }.bind(this)); + } + + // Play file and load skin both just spawn the file opener + el.playFile.addEventListener('click', winamp.openFileDialog); + el.loadSkin.addEventListener('click', winamp.openFileDialog); + + // Close all of Winamp + el.exit.addEventListener('click', winamp.close); +}; + +Context.prototype.loadSkin = function(url) { + var skinFile = new MyFile(); + skinFile.setUrl(url); + this.winamp.setSkin(skinFile); +}; + +module.exports = Context; diff --git a/js/font.js b/js/font.js index 65e36ec6..0365e1f7 100644 --- a/js/font.js +++ b/js/font.js @@ -1,63 +1,60 @@ // Manage rendering text from this skin's text.bmp file -define([], function(){ - var Font = function() { +module.exports = function() { - // Fill a node with a
containing character
s - this.setNodeToString = function(node, string) { - var stringElement = document.createElement('div'); - for (var i = 0, len = string.length; i < len; i++) { - var char = string[i].toLowerCase(); - stringElement.appendChild(this.characterNode(char)); - } - node.innerHTML = ''; - node.appendChild(stringElement); - }; - - // Get a
containing char - this.characterNode = function(char) { - return this.displayCharacterInNode(char, document.createElement('div')); - }; - - // Style/populate a
to display a character - this.displayCharacterInNode = function(character, node) { - var position = this._fontLookup[character] || this._fontLookup[' ']; - var verticalOffset = position[0] * 6; - var horizontalOffset = position[1] * 5; - - var x = '-' + horizontalOffset + 'px'; - var y = '-' + verticalOffset + 'px'; - node.style.backgroundPosition = x + ' ' + y; - node.classList.add('character'); - - node.innerHTML = character; - return node; - }; - - // Get a
containing a digit - this.digitNode = function(digit) { - var div = document.createElement('div'); - div.classList.add('digit'); - div.classList.add('digit-' + digit); - return div; - }; - - /* TODO: There are too many " " and "_" characters */ - this._fontLookup = { - 'a': [0, 0], 'b': [0, 1], 'c': [0, 2], 'd': [0, 3], 'e': [0, 4], 'f': [0, 5], - 'g': [0, 6], 'h': [0, 7], 'i': [0, 8], 'j': [0, 9], 'k': [0, 10], - 'l': [0, 11], 'm': [0, 12], 'n': [0, 13], 'o': [0, 14], 'p': [0, 15], - 'q': [0, 16], 'r': [0, 17], 's': [0, 18], 't': [0, 19], 'u': [0, 20], - 'v': [0, 21], 'w': [0, 22], 'x': [0, 23], 'y': [0, 24], 'z': [0, 25], - '"': [0, 26], '@': [0, 27], '0': [1, 0], '1': [1, 1], - '2': [1, 2], '3': [1, 3], '4': [1, 4], '5': [1, 5], '6': [1, 6], '7': [1, 7], - '8': [1, 8], '9': [1, 9], '_': [1, 11], ':': [1, 12], - '(': [1, 13], ')': [1, 14], '-': [1, 15], "'": [1, 16], '!': [1, 17], - '+': [1, 19], '\\': [1, 20], '/': [1, 21], '[': [1, 22], - ']': [1, 23], '^': [1, 24], '&': [1, 25], '%': [1, 26], '.': [1, 27], - '=': [1, 28], '$': [1, 29], '#': [1, 30], 'Å': [2, 0], 'Ö': [2, 1], - 'Ä': [2, 2], '?': [2, 3], '*': [2, 4], ' ': [2, 5], '<': [1, 22], - '>': [1, 23], '{': [1, 22], '}': [1, 23] - }; + // Fill a node with a
containing character
s + this.setNodeToString = function(node, string) { + var stringElement = document.createElement('div'); + for (var i = 0, len = string.length; i < len; i++) { + var char = string[i].toLowerCase(); + stringElement.appendChild(this.characterNode(char)); + } + node.innerHTML = ''; + node.appendChild(stringElement); }; - return Font; -}); + + // Get a
containing char + this.characterNode = function(char) { + return this.displayCharacterInNode(char, document.createElement('div')); + }; + + // Style/populate a
to display a character + this.displayCharacterInNode = function(character, node) { + var position = this._fontLookup[character] || this._fontLookup[' ']; + var verticalOffset = position[0] * 6; + var horizontalOffset = position[1] * 5; + + var x = '-' + horizontalOffset + 'px'; + var y = '-' + verticalOffset + 'px'; + node.style.backgroundPosition = x + ' ' + y; + node.classList.add('character'); + + node.innerHTML = character; + return node; + }; + + // Get a
containing a digit + this.digitNode = function(digit) { + var div = document.createElement('div'); + div.classList.add('digit'); + div.classList.add('digit-' + digit); + return div; + }; + + /* TODO: There are too many " " and "_" characters */ + this._fontLookup = { + 'a': [0, 0], 'b': [0, 1], 'c': [0, 2], 'd': [0, 3], 'e': [0, 4], 'f': [0, 5], + 'g': [0, 6], 'h': [0, 7], 'i': [0, 8], 'j': [0, 9], 'k': [0, 10], + 'l': [0, 11], 'm': [0, 12], 'n': [0, 13], 'o': [0, 14], 'p': [0, 15], + 'q': [0, 16], 'r': [0, 17], 's': [0, 18], 't': [0, 19], 'u': [0, 20], + 'v': [0, 21], 'w': [0, 22], 'x': [0, 23], 'y': [0, 24], 'z': [0, 25], + '"': [0, 26], '@': [0, 27], '0': [1, 0], '1': [1, 1], + '2': [1, 2], '3': [1, 3], '4': [1, 4], '5': [1, 5], '6': [1, 6], '7': [1, 7], + '8': [1, 8], '9': [1, 9], '_': [1, 11], ':': [1, 12], + '(': [1, 13], ')': [1, 14], '-': [1, 15], "'": [1, 16], '!': [1, 17], + '+': [1, 19], '\\': [1, 20], '/': [1, 21], '[': [1, 22], + ']': [1, 23], '^': [1, 24], '&': [1, 25], '%': [1, 26], '.': [1, 27], + '=': [1, 28], '$': [1, 29], '#': [1, 30], 'Å': [2, 0], 'Ö': [2, 1], + 'Ä': [2, 2], '?': [2, 3], '*': [2, 4], ' ': [2, 5], '<': [1, 22], + '>': [1, 23], '{': [1, 22], '}': [1, 23] + }; +}; diff --git a/js/hotkeys.js b/js/hotkeys.js index aa032c4e..7c85c130 100644 --- a/js/hotkeys.js +++ b/js/hotkeys.js @@ -1,49 +1,46 @@ -define([], function() { - var Hotkeys = function(winamp) { - var keylog = []; - var trigger = [78, 85, 76, 27, 76, 27, 83, 79, 70, 84]; - document.addEventListener('keyup', function(e){ - if (e.ctrlKey) { // Is CTRL depressed? - switch (e.keyCode) { - case 68: winamp.toggleDoubledMode(); break; // CTRL+D - // XXX FIXME - case 76: winamp.openOptionMenu(); break; // CTRL+L - case 84: winamp.toggleTimeMode(); break; // CTRL+T - } - } else { - switch (e.keyCode) { - case 37: winamp.seekForwardBy(-5); break; // left arrow - case 38: winamp.incrementVolumeBy(1); break; // up arrow - case 39: winamp.seekForwardBy(5); break; // right arrow - case 40: winamp.incrementVolumeBy(-1); break; // down arrow - case 66: winamp.next(); break; // B - case 67: winamp.pause(); break; // C - case 76: winamp.openFileDialog(); break; // L - case 82: winamp.toggleRepeat(); break; // R - case 83: winamp.toggleShuffle(); break; // S - case 86: winamp.stop(); break; // V - case 88: winamp.play(); break; // X - case 90: winamp.previous(); break; // Z - case 96: winamp.openFileDialog(); break; // numpad 0 - case 97: winamp.previous(10); break; // numpad 1 - case 98: winamp.incrementVolumeBy(-1); break; // numpad 2 - case 99: winamp.next(10); break; // numpad 3 - case 100: winamp.previous(); break; // numpad 4 - case 101: winamp.play(); break; // numpad 5 - case 102: winamp.next(); break; // numpad 6 - case 103: winamp.seekForwardBy(-5); break; // numpad 7 - case 104: winamp.incrementVolumeBy(1); break; // numpad 8 - case 105: winamp.seekForwardBy(5); break; // numpad 9 - } +module.exports = function(winamp) { + var keylog = []; + var trigger = [78, 85, 76, 27, 76, 27, 83, 79, 70, 84]; + document.addEventListener('keyup', function(e){ + if (e.ctrlKey) { // Is CTRL depressed? + switch (e.keyCode) { + case 68: winamp.toggleDoubledMode(); break; // CTRL+D + // XXX FIXME + case 76: winamp.openOptionMenu(); break; // CTRL+L + case 84: winamp.toggleTimeMode(); break; // CTRL+T } + } else { + switch (e.keyCode) { + case 37: winamp.seekForwardBy(-5); break; // left arrow + case 38: winamp.incrementVolumeBy(1); break; // up arrow + case 39: winamp.seekForwardBy(5); break; // right arrow + case 40: winamp.incrementVolumeBy(-1); break; // down arrow + case 66: winamp.next(); break; // B + case 67: winamp.pause(); break; // C + case 76: winamp.openFileDialog(); break; // L + case 82: winamp.toggleRepeat(); break; // R + case 83: winamp.toggleShuffle(); break; // S + case 86: winamp.stop(); break; // V + case 88: winamp.play(); break; // X + case 90: winamp.previous(); break; // Z + case 96: winamp.openFileDialog(); break; // numpad 0 + case 97: winamp.previous(10); break; // numpad 1 + case 98: winamp.incrementVolumeBy(-1); break; // numpad 2 + case 99: winamp.next(10); break; // numpad 3 + case 100: winamp.previous(); break; // numpad 4 + case 101: winamp.play(); break; // numpad 5 + case 102: winamp.next(); break; // numpad 6 + case 103: winamp.seekForwardBy(-5); break; // numpad 7 + case 104: winamp.incrementVolumeBy(1); break; // numpad 8 + case 105: winamp.seekForwardBy(5); break; // numpad 9 + } + } - // Easter Egg - keylog.push(e.keyCode); - keylog = keylog.slice(-10); - if (keylog.toString() === trigger.toString()) { - winamp.toggleLlama(); - } - }); - }; - return Hotkeys; -}); + // Easter Egg + keylog.push(e.keyCode); + keylog = keylog.slice(-10); + if (keylog.toString() === trigger.toString()) { + winamp.toggleLlama(); + } + }); +}; diff --git a/js/main-window-dom.js b/js/main-window-dom.js index 6936e82c..dd50660e 100644 --- a/js/main-window-dom.js +++ b/js/main-window-dom.js @@ -1,111 +1,109 @@ -define([], function() { - function el(tagName, attributes, content) { - tagName = tagName || 'div'; - attributes = attributes || {}; - content = content || []; - var tag = document.createElement(tagName); - if (typeof content === 'string') { - content = [content]; - } - for (var attr in attributes) { - tag.setAttribute(attr, attributes[attr]); - } - for (var i = 0; i < content.length; i++) { - if (typeof content[i] === 'string') { - tag.appendChild(document.createTextNode(content[i])); - } else { - tag.appendChild(content[i]); - } - } - return tag; +function el(tagName, attributes, content) { + tagName = tagName || 'div'; + attributes = attributes || {}; + content = content || []; + var tag = document.createElement(tagName); + if (typeof content === 'string') { + content = [content]; } + for (var attr in attributes) { + tag.setAttribute(attr, attributes[attr]); + } + for (var i = 0; i < content.length; i++) { + if (typeof content[i] === 'string') { + tag.appendChild(document.createTextNode(content[i])); + } else { + tag.appendChild(content[i]); + } + } + return tag; +} - return el('div', {id: 'main-window', class: 'loading stop'}, [ - el('div', {id: 'loading'}, 'Loading...'), - el('div', {id: 'title-bar', class: 'selected'}, [ - el('div', {id: 'option'}, [ - el('ul', {id: 'context-menu'}, [ - el('li', {}, [ - el('a', {href: 'https://github.com/captbaritone/winamp2-js', target: '_blank'}, 'Winamp2-js...') +module.exports = el('div', {id: 'main-window', class: 'loading stop'}, [ + el('div', {id: 'loading'}, 'Loading...'), + el('div', {id: 'title-bar', class: 'selected'}, [ + el('div', {id: 'option'}, [ + el('ul', {id: 'context-menu'}, [ + el('li', {}, [ + el('a', {href: 'https://github.com/captbaritone/winamp2-js', target: '_blank'}, 'Winamp2-js...') + ]), + el('li', {class: 'hr'}, [ el('hr') ]), + el('li', {id: 'context-play-file'}, 'Play File...'), + el('li', {class: 'parent'}, [ + el('ul', {}, [ + el('li', {id: 'context-load-skin'}, 'Load Skin...'), + el('li', {class: 'hr'}, [ el('hr') ]), + el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/base-2.91.wsz'}, ''), + el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/MacOSXAqua1-5.wsz'}, 'Mac OSX v1.5 (Aqua)'), + el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/TopazAmp1-2.wsz'}, 'TopazAmp'), + el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/Vizor1-01.wsz'}, 'Vizor'), + el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/XMMS-Turquoise.wsz'}, 'XMMS Turquoise '), + el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/ZaxonRemake1-0.wsz'}, 'Zaxon Remake') + // More here ]), - el('li', {class: 'hr'}, [ el('hr') ]), - el('li', {id: 'context-play-file'}, 'Play File...'), - el('li', {class: 'parent'}, [ - el('ul', {}, [ - el('li', {id: 'context-load-skin'}, 'Load Skin...'), - el('li', {class: 'hr'}, [ el('hr') ]), - el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/base-2.91.wsz'}, ''), - el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/MacOSXAqua1-5.wsz'}, 'Mac OSX v1.5 (Aqua)'), - el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/TopazAmp1-2.wsz'}, 'TopazAmp'), - el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/Vizor1-01.wsz'}, 'Vizor'), - el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/XMMS-Turquoise.wsz'}, 'XMMS Turquoise '), - el('li', {'class': 'skin-select', 'data-skin-url': 'https://cdn.rawgit.com/captbaritone/winamp-skins/master/v2/ZaxonRemake1-0.wsz'}, 'Zaxon Remake') - // More here - ]), - 'Skins' - ]), - el('li', {class: 'hr'}, [ el('hr') ]), - el('li', {id: 'context-exit'}, 'Exit') - ]) - ]), - el('div', {id: 'shade-time'}, [ - el('div', {id: 'shade-minus-sign'}), - el('div', {id: 'shade-minute-first-digit', class: 'character'}), - el('div', {id: 'shade-minute-second-digit', class: 'character'}), - el('div', {id: 'shade-second-first-digit', class: 'character'}), - el('div', {id: 'shade-second-second-digit', class: 'character'}) - ]), - el('div', {id: 'minimize'}), - el('div', {id: 'shade'}), - el('div', {id: 'close'}) - ]), - el('div', {class: 'status'}, [ - el('div', {id: 'clutter-bar'}, [ - el('div', {id: 'button-o'}), - el('div', {id: 'button-a'}), - el('div', {id: 'button-i'}), - el('div', {id: 'button-d'}), - el('div', {id: 'button-v'}) - ]), - el('div', {id: 'play-pause'}), - el('div', {id: 'work-indicator'}), - el('div', {id: 'time'}, [ - el('div', {id: 'minus-sign'}), - el('div', {id: 'minute-first-digit'}), - el('div', {id: 'minute-second-digit'}), - el('div', {id: 'second-first-digit'}), - el('div', {id: 'second-second-digit'}) - ]), - el('canvas', {id: 'visualizer', width: '152', height: '32'}) - ]), - el('div', {class: 'media-info'}, [ - el('div', {id: 'song-title', class: 'text'}), - el('div', {id: 'kbps'}), - el('div', {id: 'khz'}), - el('div', {class: 'mono-stereo'}, [ - el('div', {id: 'mono'}), - el('div', {id: 'stereo'}) + 'Skins' + ]), + el('li', {class: 'hr'}, [ el('hr') ]), + el('li', {id: 'context-exit'}, 'Exit') ]) ]), - el('input', {id: 'volume', type: 'range', min: '0', max: '100', step: '1', value: '50'}), - el('input', {id: 'balance', type: 'range', min: '-100', max: '100', step: '2', value: '0'}), - el('div', {class: 'windows'}, [ - el('div', {id: 'equalizer-button'}), - el('div', {id: 'playlist-button'}) + el('div', {id: 'shade-time'}, [ + el('div', {id: 'shade-minus-sign'}), + el('div', {id: 'shade-minute-first-digit', class: 'character'}), + el('div', {id: 'shade-minute-second-digit', class: 'character'}), + el('div', {id: 'shade-second-first-digit', class: 'character'}), + el('div', {id: 'shade-second-second-digit', class: 'character'}) ]), - el('input', {id: 'position', type: 'range', min: '0', max: '100', step: '1', value: '0'}), - el('div', {class: 'actions'}, [ - el('div', {id: 'previous'}), - el('div', {id: 'play'}), - el('div', {id: 'pause'}), - el('div', {id: 'stop'}), - el('div', {id: 'next'}) + el('div', {id: 'minimize'}), + el('div', {id: 'shade'}), + el('div', {id: 'close'}) + ]), + el('div', {class: 'status'}, [ + el('div', {id: 'clutter-bar'}, [ + el('div', {id: 'button-o'}), + el('div', {id: 'button-a'}), + el('div', {id: 'button-i'}), + el('div', {id: 'button-d'}), + el('div', {id: 'button-v'}) ]), - el('div', {id: 'eject'}), - el('div', {class: 'shuffle-repeat'}, [ - el('div', {id: 'shuffle'}), - el('div', {id: 'repeat'}) + el('div', {id: 'play-pause'}), + el('div', {id: 'work-indicator'}), + el('div', {id: 'time'}, [ + el('div', {id: 'minus-sign'}), + el('div', {id: 'minute-first-digit'}), + el('div', {id: 'minute-second-digit'}), + el('div', {id: 'second-first-digit'}), + el('div', {id: 'second-second-digit'}) ]), - el('a', {id: 'about', target: 'blank', href: 'https://github.com/captbaritone/winamp2-js'}) - ]); -}); + el('canvas', {id: 'visualizer', width: '152', height: '32'}) + ]), + el('div', {class: 'media-info'}, [ + el('div', {id: 'song-title', class: 'text'}), + el('div', {id: 'kbps'}), + el('div', {id: 'khz'}), + el('div', {class: 'mono-stereo'}, [ + el('div', {id: 'mono'}), + el('div', {id: 'stereo'}) + ]) + ]), + el('input', {id: 'volume', type: 'range', min: '0', max: '100', step: '1', value: '50'}), + el('input', {id: 'balance', type: 'range', min: '-100', max: '100', step: '2', value: '0'}), + el('div', {class: 'windows'}, [ + el('div', {id: 'equalizer-button'}), + el('div', {id: 'playlist-button'}) + ]), + el('input', {id: 'position', type: 'range', min: '0', max: '100', step: '1', value: '0'}), + el('div', {class: 'actions'}, [ + el('div', {id: 'previous'}), + el('div', {id: 'play'}), + el('div', {id: 'pause'}), + el('div', {id: 'stop'}), + el('div', {id: 'next'}) + ]), + el('div', {id: 'eject'}), + el('div', {class: 'shuffle-repeat'}, [ + el('div', {id: 'shuffle'}), + el('div', {id: 'repeat'}) + ]), + el('a', {id: 'about', target: 'blank', href: 'https://github.com/captbaritone/winamp2-js'}) +]); diff --git a/js/main-window.js b/js/main-window.js index bdf234c5..3e5bbd42 100644 --- a/js/main-window.js +++ b/js/main-window.js @@ -1,428 +1,423 @@ -define([ - 'multi-display', - 'font' -], function( - MultiDisplay, - Font -) { - return { - init: function(winamp) { - this.winamp = winamp; - this.nodes = { - close: document.getElementById('close'), - shade: document.getElementById('shade'), - buttonD: document.getElementById('button-d'), - position: document.getElementById('position'), - volumeMessage: document.getElementById('volume-message'), - balanceMessage: document.getElementById('balance-message'), - positionMessage: document.getElementById('position-message'), - songTitle: document.getElementById('song-title'), - time: document.getElementById('time'), - shadeTime: document.getElementById('shade-time'), - shadeMinusSign: document.getElementById('shade-minus-sign'), - visualizer: document.getElementById('visualizer'), - previous: document.getElementById('previous'), - play: document.getElementById('play'), - pause: document.getElementById('pause'), - stop: document.getElementById('stop'), - next: document.getElementById('next'), - eject: document.getElementById('eject'), - repeat: document.getElementById('repeat'), - shuffle: document.getElementById('shuffle'), - volume: document.getElementById('volume'), - kbps: document.getElementById('kbps'), - khz: document.getElementById('khz'), - mono: document.getElementById('mono'), - stereo: document.getElementById('stereo'), - balance: document.getElementById('balance'), - workIndicator: document.getElementById('work-indicator'), - titleBar: document.getElementById('title-bar'), - window: document.getElementById('main-window') - }; +import MultiDisplay from './multi-display'; +import Font from './font'; - this.handle = document.getElementById('title-bar'); - this.body = this.nodes.window; +module.exports = { + init: function(winamp) { + this.winamp = winamp; + this.nodes = { + close: document.getElementById('close'), + shade: document.getElementById('shade'), + buttonD: document.getElementById('button-d'), + position: document.getElementById('position'), + volumeMessage: document.getElementById('volume-message'), + balanceMessage: document.getElementById('balance-message'), + positionMessage: document.getElementById('position-message'), + songTitle: document.getElementById('song-title'), + time: document.getElementById('time'), + shadeTime: document.getElementById('shade-time'), + shadeMinusSign: document.getElementById('shade-minus-sign'), + visualizer: document.getElementById('visualizer'), + previous: document.getElementById('previous'), + play: document.getElementById('play'), + pause: document.getElementById('pause'), + stop: document.getElementById('stop'), + next: document.getElementById('next'), + eject: document.getElementById('eject'), + repeat: document.getElementById('repeat'), + shuffle: document.getElementById('shuffle'), + volume: document.getElementById('volume'), + kbps: document.getElementById('kbps'), + khz: document.getElementById('khz'), + mono: document.getElementById('mono'), + stereo: document.getElementById('stereo'), + balance: document.getElementById('balance'), + workIndicator: document.getElementById('work-indicator'), + titleBar: document.getElementById('title-bar'), + window: document.getElementById('main-window') + }; - this.textDisplay = new MultiDisplay(this.nodes.songTitle); - this.textDisplay.addRegister('songTitle'); - this.textDisplay.addRegister('position'); - this.textDisplay.addRegister('volume'); - this.textDisplay.addRegister('balance'); - this.textDisplay.addRegister('message'); // General purpose + this.handle = document.getElementById('title-bar'); + this.body = this.nodes.window; - this.textDisplay.showRegister('songTitle'); + this.textDisplay = new MultiDisplay(this.nodes.songTitle); + this.textDisplay.addRegister('songTitle'); + this.textDisplay.addRegister('position'); + this.textDisplay.addRegister('volume'); + this.textDisplay.addRegister('balance'); + this.textDisplay.addRegister('message'); // General purpose - this.textDisplay.startRegisterMarquee('songTitle'); + this.textDisplay.showRegister('songTitle'); - this._registerListeners(); - return this; - }, + this.textDisplay.startRegisterMarquee('songTitle'); - _registerListeners: function() { - var self = this; + this._registerListeners(); + return this; + }, - this.nodes.close.onclick = function() { - self.winamp.close(); - }; + _registerListeners: function() { + var self = this; - this.nodes.shade.onclick = function() { - self.nodes.window.classList.toggle('shade'); - }; + this.nodes.close.onclick = function() { + self.winamp.close(); + }; - this.nodes.buttonD.onmousedown = function() { - if (self.nodes.window.classList.contains('doubled')) { - self.textDisplay.setRegisterText('message', 'Disable doublesize mode'); - } else { - self.textDisplay.setRegisterText('message', 'Enable doublesize mode'); - } - self.textDisplay.showRegister('message'); - }; + this.nodes.shade.onclick = function() { + self.nodes.window.classList.toggle('shade'); + }; - this.nodes.buttonD.onmouseup = function() { - self.textDisplay.showRegister('songTitle'); - }; - - this.nodes.buttonD.onclick = function() { - self.winamp.toggleDoubledMode(); - }; - - this.nodes.play.onclick = function() { - self.winamp.play(); - }; - - this.nodes.songTitle.onmousedown = function() { - self.textDisplay.pauseRegisterMarquee('songTitle'); - }; - - this.nodes.songTitle.onmouseup = function() { - setTimeout(function() { - self.textDisplay.startRegisterMarquee('songTitle'); - }, 1000); - }; - - this.nodes.position.onmousedown = function() { - if (!self.nodes.window.classList.contains('stop')){ - self.textDisplay.showRegister('position'); - self.nodes.window.classList.add('setting-position'); - } - }; - - this.nodes.position.onmouseup = function() { - self.textDisplay.showRegister('songTitle'); - self.nodes.window.classList.remove('setting-position'); - }; - - this.nodes.position.oninput = function() { - var newPercentComplete = self.nodes.position.value; - var newFractionComplete = newPercentComplete / 100; - var newElapsed = self._timeString(self.winamp.getDuration() * newFractionComplete); - var duration = self._timeString(self.winamp.getDuration()); - var message = 'Seek to: ' + newElapsed + '/' + duration + ' (' + newPercentComplete + '%)'; - self.textDisplay.setRegisterText('position', message); - }; - - this.nodes.position.onchange = function() { - if (self.winamp.getState() !== 'stop'){ - self.winamp.seekToPercentComplete(this.value); - } - }; - - this.nodes.previous.onclick = function() { - self.winamp.previous(); - }; - - this.nodes.next.onclick = function() { - self.winamp.next(); - }; - - this.nodes.pause.onclick = function() { - self.winamp.pause(); - }; - - this.nodes.stop.onclick = function() { - self.winamp.stop(); - }; - - this.nodes.eject.onclick = function() { - self.winamp.openFileDialog(); - }; - - this.nodes.repeat.onclick = function() { - self.winamp.toggleRepeat(); - }; - - this.nodes.shuffle.onclick = function() { - self.winamp.toggleShuffle(); - }; - - this.nodes.shadeTime.onclick = function() { - self.winamp.toggleTimeMode(); - }; - - this.nodes.volume.onmousedown = function() { - self.textDisplay.showRegister('volume'); - }; - - this.nodes.volume.onmouseup = function() { - self.textDisplay.showRegister('songTitle'); - }; - - this.nodes.volume.oninput = function() { - self.winamp.setVolume(this.value); - }; - - this.nodes.time.onclick = function() { - self.winamp.toggleTimeMode(); - }; - - this.nodes.balance.onmousedown = function() { - self.textDisplay.showRegister('balance'); - }; - - this.nodes.balance.onmouseup = function() { - self.textDisplay.showRegister('songTitle'); - }; - - this.nodes.balance.oninput = function() { - if (Math.abs(this.value) < 25) { - this.value = 0; - } - self.winamp.setBalance(this.value); - }; - - this.nodes.visualizer.onclick = function() { - self.winamp.toggleVisualizer(); - }; - - window.addEventListener('timeUpdated', function() { - self.updateTime(); - }); - window.addEventListener('startWaiting', function() { - self.setWorkingIndicator(); - }); - window.addEventListener('stopWaiting', function() { - self.unsetWorkingIndicator(); - }); - window.addEventListener('startLoading', function() { - self.setLoadingState(); - }); - window.addEventListener('stopLoading', function() { - self.unsetLoadingState(); - }); - window.addEventListener('toggleTimeMode', function() { - self.toggleTimeMode(); - }); - window.addEventListener('changeState', function() { - self.changeState(); - }); - window.addEventListener('titleUpdated', function() { - self.updateTitle(); - }); - window.addEventListener('channelCountUpdated', function() { - self.updateChannelCount(); - }); - window.addEventListener('volumeChanged', function() { - self.updateVolume(); - }); - window.addEventListener('balanceChanged', function() { - self.setBalance(); - }); - window.addEventListener('doubledModeToggled', function() { - self.toggleDoubledMode(); - }); - window.addEventListener('repeatToggled', function() { - self.toggleRepeat(); - }); - window.addEventListener('llamaToggled', function() { - self.toggleLlama(); - }); - window.addEventListener('close', function() { - self.close(); - }); - - this.nodes.window.addEventListener('dragenter', this.dragenter.bind(this)); - this.nodes.window.addEventListener('dragover', this.dragover.bind(this)); - this.nodes.window.addEventListener('drop', this.drop.bind(this)); - }, - - toggleDoubledMode: function() { - this.nodes.buttonD.classList.toggle('selected'); - this.nodes.window.classList.toggle('doubled'); - }, - - close: function() { - this.nodes.window.classList.add('closed'); - }, - - updatePosition: function() { - if (!this.nodes.window.classList.contains('setting-position')) { - this.nodes.position.value = this.winamp.getPercentComplete(); - } - }, - - // In shade mode, the position slider shows up differently depending on if - // it's near the start, middle or end of its progress - updateShadePositionClass: function() { - var position = this.nodes.position; - - position.removeAttribute('class'); - if (position.value <= 33) { - position.classList.add('left'); - } else if (position.value >= 66) { - position.classList.add('right'); - } - }, - - updateTime: function() { - this.updateShadePositionClass(); - this.updatePosition(); - - var shadeMinusCharacter = ' '; - var digits = null; - if (this.nodes.time.classList.contains('countdown')) { - digits = this.winamp._timeObject(this.winamp.getTimeRemaining()); - shadeMinusCharacter = '-'; + this.nodes.buttonD.onmousedown = function() { + if (self.nodes.window.classList.contains('doubled')) { + self.textDisplay.setRegisterText('message', 'Disable doublesize mode'); } else { - digits = this.winamp._timeObject(this.winamp.getTimeElapsed()); + self.textDisplay.setRegisterText('message', 'Enable doublesize mode'); } - this.winamp.skin.font.displayCharacterInNode(shadeMinusCharacter, this.nodes.shadeMinusSign); + self.textDisplay.showRegister('message'); + }; - var digitNodes = [ - document.getElementById('minute-first-digit'), - document.getElementById('minute-second-digit'), - document.getElementById('second-first-digit'), - document.getElementById('second-second-digit') - ]; - var shadeDigitNodes = [ - document.getElementById('shade-minute-first-digit'), - document.getElementById('shade-minute-second-digit'), - document.getElementById('shade-second-first-digit'), - document.getElementById('shade-second-second-digit') - ]; + this.nodes.buttonD.onmouseup = function() { + self.textDisplay.showRegister('songTitle'); + }; - // For each digit/node - for (var i = 0; i < 4; i++) { - var digit = digits[i]; - var digitNode = digitNodes[i]; - var shadeNode = shadeDigitNodes[i]; - digitNode.innerHTML = ''; - digitNode.appendChild(this.winamp.skin.font.digitNode(digit)); - this.winamp.skin.font.displayCharacterInNode(digit, shadeNode); + this.nodes.buttonD.onclick = function() { + self.winamp.toggleDoubledMode(); + }; + + this.nodes.play.onclick = function() { + self.winamp.play(); + }; + + this.nodes.songTitle.onmousedown = function() { + self.textDisplay.pauseRegisterMarquee('songTitle'); + }; + + this.nodes.songTitle.onmouseup = function() { + setTimeout(function() { + self.textDisplay.startRegisterMarquee('songTitle'); + }, 1000); + }; + + this.nodes.position.onmousedown = function() { + if (!self.nodes.window.classList.contains('stop')){ + self.textDisplay.showRegister('position'); + self.nodes.window.classList.add('setting-position'); } - }, + }; - setWorkingIndicator: function() { - this.nodes.workIndicator.classList.add('selected'); - }, + this.nodes.position.onmouseup = function() { + self.textDisplay.showRegister('songTitle'); + self.nodes.window.classList.remove('setting-position'); + }; - unsetWorkingIndicator: function() { - this.nodes.workIndicator.classList.remove('selected'); - }, + this.nodes.position.oninput = function() { + var newPercentComplete = self.nodes.position.value; + var newFractionComplete = newPercentComplete / 100; + var newElapsed = self._timeString(self.winamp.getDuration() * newFractionComplete); + var duration = self._timeString(self.winamp.getDuration()); + var message = 'Seek to: ' + newElapsed + '/' + duration + ' (' + newPercentComplete + '%)'; + self.textDisplay.setRegisterText('position', message); + }; - setLoadingState: function() { - this.nodes.window.classList.add('loading'); - }, - - unsetLoadingState: function() { - this.nodes.window.classList.remove('loading'); - }, - - toggleTimeMode: function() { - this.nodes.time.classList.toggle('countdown'); - this.updateTime(); - }, - - updateVolume: function() { - var volume = this.winamp.getVolume(); - var percent = volume / 100; - var sprite = Math.round(percent * 28); - var offset = (sprite - 1) * 15; - this.nodes.volume.style.backgroundPosition = '0 -' + offset + 'px'; - - var message = 'Volume: ' + volume + '%'; - this.textDisplay.setRegisterText('volume', message); - - // This shouldn't trigger an infinite loop with volume.onchange(), - // since the value will be the same - this.nodes.volume.value = volume; - }, - - setBalance: function() { - var balance = this.winamp.getBalance(); - var string = ''; - if (balance === 0) { - string = 'Balance: Center'; - } else if (balance > 0) { - string = 'Balance: ' + balance + '% Right'; - } else { - string = 'Balance: ' + Math.abs(balance) + '% Left'; + this.nodes.position.onchange = function() { + if (self.winamp.getState() !== 'stop'){ + self.winamp.seekToPercentComplete(this.value); } - this.textDisplay.setRegisterText('balance', string); - balance = Math.abs(balance) / 100; - var sprite = Math.round(balance * 28); - var offset = (sprite - 1) * 15; - this.nodes.balance.style.backgroundPosition = '0px -' + offset + 'px'; - }, + }; - changeState: function() { - var state = this.winamp.getState(); - var stateOptions = ['play', 'stop', 'pause']; - for (var i = 0; i < stateOptions.length; i++) { - this.nodes.window.classList.remove(stateOptions[i]); + this.nodes.previous.onclick = function() { + self.winamp.previous(); + }; + + this.nodes.next.onclick = function() { + self.winamp.next(); + }; + + this.nodes.pause.onclick = function() { + self.winamp.pause(); + }; + + this.nodes.stop.onclick = function() { + self.winamp.stop(); + }; + + this.nodes.eject.onclick = function() { + self.winamp.openFileDialog(); + }; + + this.nodes.repeat.onclick = function() { + self.winamp.toggleRepeat(); + }; + + this.nodes.shuffle.onclick = function() { + self.winamp.toggleShuffle(); + }; + + this.nodes.shadeTime.onclick = function() { + self.winamp.toggleTimeMode(); + }; + + this.nodes.volume.onmousedown = function() { + self.textDisplay.showRegister('volume'); + }; + + this.nodes.volume.onmouseup = function() { + self.textDisplay.showRegister('songTitle'); + }; + + this.nodes.volume.oninput = function() { + self.winamp.setVolume(this.value); + }; + + this.nodes.time.onclick = function() { + self.winamp.toggleTimeMode(); + }; + + this.nodes.balance.onmousedown = function() { + self.textDisplay.showRegister('balance'); + }; + + this.nodes.balance.onmouseup = function() { + self.textDisplay.showRegister('songTitle'); + }; + + this.nodes.balance.oninput = function() { + if (Math.abs(this.value) < 25) { + this.value = 0; } - this.nodes.window.classList.add(state); - }, + self.winamp.setBalance(this.value); + }; - toggleLlama: function() { - this.nodes.window.classList.toggle('llama'); - }, + this.nodes.visualizer.onclick = function() { + self.winamp.toggleVisualizer(); + }; - updateTitle: function() { - var duration = this._timeString(this.winamp.getDuration()); - var name = this.winamp.fileName + ' (' + duration + ') *** '; - this.textDisplay.setRegisterText('songTitle', name); - }, + window.addEventListener('timeUpdated', function() { + self.updateTime(); + }); + window.addEventListener('startWaiting', function() { + self.setWorkingIndicator(); + }); + window.addEventListener('stopWaiting', function() { + self.unsetWorkingIndicator(); + }); + window.addEventListener('startLoading', function() { + self.setLoadingState(); + }); + window.addEventListener('stopLoading', function() { + self.unsetLoadingState(); + }); + window.addEventListener('toggleTimeMode', function() { + self.toggleTimeMode(); + }); + window.addEventListener('changeState', function() { + self.changeState(); + }); + window.addEventListener('titleUpdated', function() { + self.updateTitle(); + }); + window.addEventListener('channelCountUpdated', function() { + self.updateChannelCount(); + }); + window.addEventListener('volumeChanged', function() { + self.updateVolume(); + }); + window.addEventListener('balanceChanged', function() { + self.setBalance(); + }); + window.addEventListener('doubledModeToggled', function() { + self.toggleDoubledMode(); + }); + window.addEventListener('repeatToggled', function() { + self.toggleRepeat(); + }); + window.addEventListener('llamaToggled', function() { + self.toggleLlama(); + }); + window.addEventListener('close', function() { + self.close(); + }); - updateChannelCount: function() { - var channels = this.winamp.getChannelCount(); - this.nodes.mono.classList.remove('selected'); - this.nodes.stereo.classList.remove('selected'); - if (channels === 1) { - this.nodes.mono.classList.add('selected'); - } else if (channels === 2) { - this.nodes.stereo.classList.add('selected'); - } - }, + this.nodes.window.addEventListener('dragenter', this.dragenter.bind(this)); + this.nodes.window.addEventListener('dragover', this.dragover.bind(this)); + this.nodes.window.addEventListener('drop', this.drop.bind(this)); + }, - toggleRepeat: function() { - this.nodes.repeat.classList.toggle('selected'); - }, + toggleDoubledMode: function() { + this.nodes.buttonD.classList.toggle('selected'); + this.nodes.window.classList.toggle('doubled'); + }, - toggleShuffle: function() { - this.nodes.shuffle.classList.toggle('selected'); - }, + close: function() { + this.nodes.window.classList.add('closed'); + }, - dragenter: function(e) { - e.stopPropagation(); - e.preventDefault(); - }, - - dragover: function(e) { - e.stopPropagation(); - e.preventDefault(); - }, - - drop: function(e) { - e.stopPropagation(); - e.preventDefault(); - var dt = e.dataTransfer; - var file = dt.files[0]; - this.winamp.loadFromFileReference(file); - }, - - _timeString: function(time) { - var timeObject = this.winamp._timeObject(time); - return timeObject[0] + timeObject[1] + ':' + timeObject[2] + timeObject[3]; + updatePosition: function() { + if (!this.nodes.window.classList.contains('setting-position')) { + this.nodes.position.value = this.winamp.getPercentComplete(); } - }; -}); + }, + + // In shade mode, the position slider shows up differently depending on if + // it's near the start, middle or end of its progress + updateShadePositionClass: function() { + var position = this.nodes.position; + + position.removeAttribute('class'); + if (position.value <= 33) { + position.classList.add('left'); + } else if (position.value >= 66) { + position.classList.add('right'); + } + }, + + updateTime: function() { + this.updateShadePositionClass(); + this.updatePosition(); + + var shadeMinusCharacter = ' '; + var digits = null; + if (this.nodes.time.classList.contains('countdown')) { + digits = this.winamp._timeObject(this.winamp.getTimeRemaining()); + shadeMinusCharacter = '-'; + } else { + digits = this.winamp._timeObject(this.winamp.getTimeElapsed()); + } + this.winamp.skin.font.displayCharacterInNode(shadeMinusCharacter, this.nodes.shadeMinusSign); + + var digitNodes = [ + document.getElementById('minute-first-digit'), + document.getElementById('minute-second-digit'), + document.getElementById('second-first-digit'), + document.getElementById('second-second-digit') + ]; + var shadeDigitNodes = [ + document.getElementById('shade-minute-first-digit'), + document.getElementById('shade-minute-second-digit'), + document.getElementById('shade-second-first-digit'), + document.getElementById('shade-second-second-digit') + ]; + + // For each digit/node + for (var i = 0; i < 4; i++) { + var digit = digits[i]; + var digitNode = digitNodes[i]; + var shadeNode = shadeDigitNodes[i]; + digitNode.innerHTML = ''; + digitNode.appendChild(this.winamp.skin.font.digitNode(digit)); + this.winamp.skin.font.displayCharacterInNode(digit, shadeNode); + } + }, + + setWorkingIndicator: function() { + this.nodes.workIndicator.classList.add('selected'); + }, + + unsetWorkingIndicator: function() { + this.nodes.workIndicator.classList.remove('selected'); + }, + + setLoadingState: function() { + this.nodes.window.classList.add('loading'); + }, + + unsetLoadingState: function() { + this.nodes.window.classList.remove('loading'); + }, + + toggleTimeMode: function() { + this.nodes.time.classList.toggle('countdown'); + this.updateTime(); + }, + + updateVolume: function() { + var volume = this.winamp.getVolume(); + var percent = volume / 100; + var sprite = Math.round(percent * 28); + var offset = (sprite - 1) * 15; + this.nodes.volume.style.backgroundPosition = '0 -' + offset + 'px'; + + var message = 'Volume: ' + volume + '%'; + this.textDisplay.setRegisterText('volume', message); + + // This shouldn't trigger an infinite loop with volume.onchange(), + // since the value will be the same + this.nodes.volume.value = volume; + }, + + setBalance: function() { + var balance = this.winamp.getBalance(); + var string = ''; + if (balance === 0) { + string = 'Balance: Center'; + } else if (balance > 0) { + string = 'Balance: ' + balance + '% Right'; + } else { + string = 'Balance: ' + Math.abs(balance) + '% Left'; + } + this.textDisplay.setRegisterText('balance', string); + balance = Math.abs(balance) / 100; + var sprite = Math.round(balance * 28); + var offset = (sprite - 1) * 15; + this.nodes.balance.style.backgroundPosition = '0px -' + offset + 'px'; + }, + + changeState: function() { + var state = this.winamp.getState(); + var stateOptions = ['play', 'stop', 'pause']; + for (var i = 0; i < stateOptions.length; i++) { + this.nodes.window.classList.remove(stateOptions[i]); + } + this.nodes.window.classList.add(state); + }, + + toggleLlama: function() { + this.nodes.window.classList.toggle('llama'); + }, + + updateTitle: function() { + var duration = this._timeString(this.winamp.getDuration()); + var name = this.winamp.fileName + ' (' + duration + ') *** '; + this.textDisplay.setRegisterText('songTitle', name); + }, + + updateChannelCount: function() { + var channels = this.winamp.getChannelCount(); + this.nodes.mono.classList.remove('selected'); + this.nodes.stereo.classList.remove('selected'); + if (channels === 1) { + this.nodes.mono.classList.add('selected'); + } else if (channels === 2) { + this.nodes.stereo.classList.add('selected'); + } + }, + + toggleRepeat: function() { + this.nodes.repeat.classList.toggle('selected'); + }, + + toggleShuffle: function() { + this.nodes.shuffle.classList.toggle('selected'); + }, + + dragenter: function(e) { + e.stopPropagation(); + e.preventDefault(); + }, + + dragover: function(e) { + e.stopPropagation(); + e.preventDefault(); + }, + + drop: function(e) { + e.stopPropagation(); + e.preventDefault(); + var dt = e.dataTransfer; + var file = dt.files[0]; + this.winamp.loadFromFileReference(file); + }, + + _timeString: function(time) { + var timeObject = this.winamp._timeObject(time); + return timeObject[0] + timeObject[1] + ':' + timeObject[2] + timeObject[3]; + } +}; diff --git a/js/media.js b/js/media.js index 04ca0818..04e27dfc 100644 --- a/js/media.js +++ b/js/media.js @@ -1,5 +1,5 @@ /* Emulate the native