diff --git a/css/playlist.css b/css/playlist.css
index 70726f78..c5de9a0e 100644
--- a/css/playlist.css
+++ b/css/playlist.css
@@ -34,6 +34,10 @@
#playlist #tracks li {
white-space: nowrap;
color: lightgreen;
+ font-size: 8px;
+}
+#playlist #tracks li.selected {
+ background-color: red;
}
#playlist .top {
@@ -135,3 +139,11 @@
width: 150px;
background-position: -126px -72px;
}
+
+#playlist #playlist-resize-handle {
+ position: absolute;
+ width: 20px;
+ height: 20px;
+ bottom: 0px;
+ right: 0px;
+}
diff --git a/index.html b/index.html
index 91a7e612..f69f9e48 100755
--- a/index.html
+++ b/index.html
@@ -104,18 +104,7 @@
-
- - 1. track one is very long and if you don't cut it off it
- causes some problems
- - 2. track two
- - 2. track two
- - 2. track two
- - 2. track two
- - 2. track two
- - 2. track two
- - 2. track two
- - 2. track two
-
+
@@ -132,8 +121,9 @@
diff --git a/js/main-window.js b/js/main-window.js
index 4d2febe3..296a5f5f 100644
--- a/js/main-window.js
+++ b/js/main-window.js
@@ -206,6 +206,8 @@ MainWindow = {
window.addEventListener('doubledModeToggled', function() { self.toggleDoubledMode(); });
window.addEventListener('repeatToggled', function() { self.toggleRepeat(); });
window.addEventListener('llamaToggled', function() { self.toggleLlama(); });
+ window.addEventListener('openPlaylist', function() { self.nodes.playlistButton.classList.add('selected'); });
+ window.addEventListener('closePlaylist', function() { self.nodes.playlistButton.classList.remove('selected'); });
this.nodes.window.addEventListener('dragenter', this.dragenter.bind(this));
this.nodes.window.addEventListener('dragover', this.dragover.bind(this));
@@ -373,11 +375,6 @@ MainWindow = {
togglePlaylist: function() {
this.winamp.togglePlaylist();
- if(this.winamp.playlistIsClosed()) {
- this.nodes.playlistButton.classList.remove('selected');
- } else {
- this.nodes.playlistButton.classList.add('selected');
- }
},
dragenter: function(e) {
diff --git a/js/playlist-window.js b/js/playlist-window.js
index cae254f0..e0a0ea26 100644
--- a/js/playlist-window.js
+++ b/js/playlist-window.js
@@ -5,13 +5,17 @@ PlaylistWindow = {
'window': document.getElementById('playlist'),
'top': document.querySelector('#playlist .top'),
'shade': document.getElementById('playlist-shade'),
- 'close': document.getElementById('playlist-close')
+ 'close': document.getElementById('playlist-close'),
+ 'tracks': document.getElementById('tracks'),
+ 'resizeHandle': document.getElementById('playlist-resize-handle')
};
this.closed = this.nodes.window.classList.contains('closed');
this.handle = this.nodes.top;
this.body = this.nodes.window;
+ this.resizeHandle = this.nodes.resizeHandle;
+
this._registerListeners();
return this;
@@ -20,9 +24,18 @@ PlaylistWindow = {
_registerListeners: function() {
var self = this;
+ window.addEventListener('openPlaylist', function() { self.open(); });
+ window.addEventListener('closePlaylist', function() { self.close(); });
+ window.addEventListener('tracksUpdated', function() { self.updateTracks(); });
+ window.addEventListener('currentTrackChanged', function() { self.updateCurrentTrack(); });
+
this.nodes.close.onclick = function() {
- self.close();
+ self.winamp.closePlaylist();
}
+
+ 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));
},
close: function() {
@@ -45,6 +58,32 @@ PlaylistWindow = {
}
},
+ updateTracks: function() {
+ var tracks = this.nodes.tracks;
+ while (tracks.firstChild) {
+ tracks.removeChild(tracks.firstChild);
+ }
+
+ for(i = 0; i < this.winamp.playlist.length; i++) {
+ var li = document.createElement('li');
+ li.innerHTML = "
" + (i+1) + ". " + this.winamp.playlist[i].name + "";
+ tracks.appendChild(li);
+ }
+
+ this.updateCurrentTrack();
+ },
+
+ updateCurrentTrack: function() {
+ var tracks = this.nodes.tracks.children;
+ for(i = 0; i < tracks.length; i++) {
+ if(i == this.winamp.currentTrack) {
+ tracks[i].classList.add('selected');
+ } else {
+ tracks[i].classList.remove('selected');
+ }
+ }
+ },
+
dragenter: function(e) {
e.stopPropagation();
e.preventDefault();
@@ -60,7 +99,7 @@ PlaylistWindow = {
e.preventDefault();
var dt = e.dataTransfer;
var file = dt.files[0];
- this.winamp.loadFromFileReference(file);
+ this.winamp.enqueueFromFileReference(file, 0);
}
}
diff --git a/js/winamp.js b/js/winamp.js
index abfc1bd7..f790c8b2 100755
--- a/js/winamp.js
+++ b/js/winamp.js
@@ -13,6 +13,9 @@ Winamp = {
this.mainWindow = MainWindow.init(this);
this.playlistWindow = PlaylistWindow.init(this);
+ this.playlist = [];
+ this.currentTrack = null;
+
this.events = {
timeUpdated: new Event('timeUpdated'),
startWaiting: new Event('startWaiting'),
@@ -27,7 +30,11 @@ Winamp = {
balanceChanged: new Event('balanceChanged'),
doubledModeToggled: new Event('doubledModeToggled'),
repeatToggled: new Event('repeatToggled'),
- llamaToggled: new Event('llamaToggled')
+ llamaToggled: new Event('llamaToggled'),
+ openPlaylist: new Event('openPlaylist'),
+ closePlaylist: new Event('closePlaylist'),
+ tracksUpdated: new Event('tracksUpdated'),
+ currentTrackChanged: new Event('currentTrackChanged')
};
this.setVolume(options.volume);
@@ -117,8 +124,11 @@ Winamp = {
},
previous: function(num) {
- // Jump back num tracks
- // Not yet supported
+ if(this.currentTrack > 0) {
+ this.currentTrack = this.currentTrack - 1;
+ window.dispatchEvent(this.events.currentTrackChanged);
+ this.playFromFileReference(this.playlist[this.currentTrack]);
+ }
},
play: function() {
@@ -139,14 +149,19 @@ Winamp = {
this.setState('pause');
}
},
+
stop: function() {
this.media.stop();
this.setState('stop');
},
next: function(num) {
- // Jump back num tracks
- // Not yet supported
+ this.currentTrack++;
+ if(this.currentTrack == this.playlist.length) {
+ this.currentTrack = 0;
+ }
+ window.dispatchEvent(this.events.currentTrackChanged);
+ this.playFromFileReference(this.playlist[this.currentTrack]);
},
// From 0-100
@@ -203,12 +218,20 @@ Winamp = {
this.setState('stop'); // Currently unneeded
},
- togglePlaylist: function() {
- this.playlistWindow.toggle();
+ openPlaylist: function() {
+ window.dispatchEvent(this.events.openPlaylist);
},
- playlistIsClosed: function() {
- return this.playlistWindow.isClosed();
+ closePlaylist: function() {
+ window.dispatchEvent(this.events.closePlaylist);
+ },
+
+ togglePlaylist: function() {
+ if(this.playlistWindow.isClosed()) {
+ this.openPlaylist();
+ } else {
+ this.closePlaylist();
+ }
},
openFileDialog: function() {
@@ -221,12 +244,24 @@ Winamp = {
if(new RegExp("(wsz|zip)$", 'i').test(fileReference.name)) {
this.skin.setSkinByFile(file);
} else {
- this.media.autoPlay = true;
- this.fileName = fileReference.name;
- file.processBuffer(this._loadBuffer.bind(this));
+ this.playlist = [];
+ this.enqueueFromFileReference(fileReference);
+ this.currentTrack = 0;
+ this.playFromFileReference(this.playlist[0]);
}
},
+ playFromFileReference: function(fileReference) {
+ this.media.autoPlay = true;
+ this.fileName = fileReference.name;
+ this.fileManager.bufferFromFileReference(fileReference, this._loadBuffer.bind(this));
+ },
+
+ enqueueFromFileReference: function(fileReference, position) {
+ this.playlist.push(fileReference);
+ window.dispatchEvent(this.events.tracksUpdated);
+ },
+
// Used only for the initial load, since it must have a CORS header
loadFromUrl: function(url, fileName) {
this.fileName = fileName;
diff --git a/js/window-manager.js b/js/window-manager.js
index 382534df..c2dc455e 100644
--- a/js/window-manager.js
+++ b/js/window-manager.js
@@ -2,6 +2,7 @@ WindowManager = {
registerWindow: function(win) {
var body = win.body;
var handle = win.handle;
+ var resizeHandle = win.resizeHandle;
// Make window dragable
handle.addEventListener('mousedown',function(e){
@@ -54,5 +55,56 @@ WindowManager = {
window.addEventListener('mousemove',handleMove);
window.addEventListener('mouseup',handleUp);
});
+
+ if (typeof resizeHandle == 'undefined') return;
+
+ // Make window resizeable
+ resizeHandle.addEventListener('mousedown',function(e){
+ var winStartHeight = body.offsetHeight,
+ winStartWidth = body.offsetWidth;
+
+ // Get starting mouse position
+ var mouseStartLeft = e.clientX,
+ mouseStartTop = e.clientY;
+
+ // Mouse move handler function while mouse is down
+ function handleResize(e) {
+ // Get current mouse position
+ var mouseLeft = e.clientX,
+ mouseTop = e.clientY;
+
+ // Calculate difference offsets
+ var diffLeft = mouseLeft-mouseStartLeft,
+ diffTop = mouseTop-mouseStartTop;
+
+ var newWidth = (winStartWidth+diffLeft),
+ newHeight = (winStartHeight+diffTop);
+
+ // Enforce resizing by 25px
+ newWidth = Math.ceil(newWidth / 25.0) * 25;
+ newHeight = Math.ceil(newHeight / 29.0) * 29;
+
+ // Enforce minimum size
+ newWidth = Math.max(newWidth, 275);
+ newHeight = Math.max(newHeight, 116);
+
+ // Resize window
+ body.style.width = newWidth +"px";
+ body.style.height = newHeight +"px";
+ }
+
+ // Mouse button up
+ function handleUp() {
+ removeListeners();
+ }
+
+ function removeListeners() {
+ window.removeEventListener('mousemove',handleResize);
+ window.removeEventListener('mouseup',handleUp);
+ }
+
+ window.addEventListener('mousemove',handleResize);
+ window.addEventListener('mouseup',handleUp);
+ });
}
};