diff --git a/examples/ui/audio_player/css/example.css b/examples/ui/audio_player/css/example.css
index ffd0bb06..0046c2e8 100644
--- a/examples/ui/audio_player/css/example.css
+++ b/examples/ui/audio_player/css/example.css
@@ -1,4 +1,9 @@
-.OxTableList .OxItem .OxCell > img.playing {
+.OxTableList .OxItem .OxCell > img.image {
+ width: 14px;
+ height: 14px;
+ margin: 0 0 0 -3px;
+}
+.OxTableList .OxItem .OxCell > img.symbol {
width: 10px;
height: 10px;
margin: 2px 0 0 -1px;
diff --git a/examples/ui/audio_player/js/example.js b/examples/ui/audio_player/js/example.js
index e089f1fe..8e56c9b2 100644
--- a/examples/ui/audio_player/js/example.js
+++ b/examples/ui/audio_player/js/example.js
@@ -1,17 +1,163 @@
/*
-...
+Demo application using Ox.AudioPlayer.
*/
'use strict';
Ox.load('UI', function() {
- var paused = true,
+ var columns = [
+ {
+ format: function(value) {
+ return value
+ ? Ox.Element('')
+ .addClass('symbol')
+ .attr({src: Ox.UI.getImageURL(
+ paused ? 'symbolUnmute' : 'symbolMute'
+ )})
+ : Ox.Element();
+ },
+ id: 'playing',
+ removable: false,
+ title: 'Playing',
+ titleImage: 'mute',
+ visible: true,
+ width: 16
+ },
+ {
+ format: function(value) {
+ return value
+ ? Ox.Element('
')
+ .addClass('symbol')
+ .attr({src: Ox.UI.getImageURL(
+ 'symbolCheck'
+ )})
+ : Ox.Element();
+ },
+ id: 'checked',
+ removable: false,
+ title: 'Checked',
+ titleImage: 'check',
+ visible: true,
+ width: 16
+ },
+ {
+ format: function(value) {
+ return value
+ ? Ox.Element('
')
+ .addClass('image')
+ .attr({src: value})
+ : Ox.Element()
+ },
+ id: 'artwork',
+ operator: '+',
+ title: 'Artwork',
+ titleImage: 'icon',
+ visible: true,
+ width: 16
+ },
+ {
+ align: 'right',
+ id: 'disc',
+ operator: '+',
+ title: 'Disc',
+ titleImage: 'circle',
+ width: 32
+ },
+ {
+ align: 'right',
+ id: 'track',
+ operator: '+',
+ title: 'Track',
+ titleImage: 'square',
+ width: 32
+ },
+ {
+ id: 'title',
+ operator: '+',
+ removable: false,
+ title: 'Title',
+ visible: true,
+ width: 192
+ },
+ {
+ id: 'artist',
+ operator: '+',
+ removable: false,
+ title: 'Artist',
+ visible: true,
+ width: 192
+ },
+ {
+ id: 'album',
+ operator: '+',
+ removable: false,
+ title: 'Album',
+ visible: true,
+ width: 192
+ },
+ {
+ align: 'right',
+ id: 'year',
+ operator: '+',
+ title: 'Year',
+ visible: true,
+ width: 64
+ },
+ {
+ align: 'right',
+ format: function(value) {
+ return Ox.formatDuration(value).substr(4);
+ },
+ id: 'duration',
+ operator: '-',
+ title: 'Time',
+ visible: true,
+ width: 64
+ },
+ {
+ align: 'right',
+ format: function(value) {
+ return Ox.formatValue(value, 'B');
+ },
+ id: 'size',
+ operator: '-',
+ title: 'Size',
+ visible: true,
+ width: 64
+ },
+ {
+ align: 'right',
+ format: function(value) {
+ return Math.round(value) + ' kbps'
+ },
+ id: 'bitrate',
+ operator: '-',
+ title: 'Bitrate',
+ visible: true,
+ width: 64
+ },
+ {
+ id: 'genre',
+ operator: '+',
+ title: 'Genre',
+ visible: true,
+ width: 128
+ }
+ ],
+ paused = true,
+ sort = [
+ {key: 'artist', operator: '+'},
+ {key: 'year', operator: '+'},
+ {key: 'disc', operator: '+'},
+ {key: 'track', operator: '+'}
+ ],
track = 0,
tracks = [
{
album: 'The Grey Album',
artist: 'Danger Mouse',
+ artwork: 'mp3/Danger Mouse/2004 The Grey Album/artwork.png',
bitrate: 128,
checked: true,
disc: 1,
@@ -27,6 +173,7 @@ Ox.load('UI', function() {
{
album: 'No Love Deep Web',
artist: 'Death Grips',
+ artwork: 'mp3/Death Grips/2012 No Love Deep Web/artwork.png',
bitrate: 128,
checked: true,
disc: 1,
@@ -42,6 +189,7 @@ Ox.load('UI', function() {
{
album: 'No Love Deep Web',
artist: 'Death Grips',
+ artwork: 'mp3/Death Grips/2012 No Love Deep Web/artwork.png',
bitrate: 128,
checked: true,
disc: 1,
@@ -55,23 +203,28 @@ Ox.load('UI', function() {
year: '2012'
}
],
+ artists = getArtists(tracks),
+ albums = getAlbums(artists),
+ view = 'albums',
$toolbar = Ox.Bar({size: 39}),
$audioPlayer = Ox.AudioPlayer({
audio: tracks,
paused: true,
- width: window.innerWidth - 205
+ width: window.innerWidth - 190
})
.css({left: '4px', top: '4px'})
.bindEvent({
paused: function(data) {
paused = data.paused;
+ $musicList.value(tracks[track].file, 'playing', false);
+ $musicList.value(tracks[track].file, 'playing', true);
},
track: function(data) {
- $list.value(tracks[track].file, 'playing', false);
+ $musicList.value(tracks[track].file, 'playing', false);
track = data.track;
- $list.value(tracks[track].file, 'playing', true);
+ $musicList.value(tracks[track].file, 'playing', true);
}
})
.appendTo($toolbar)
@@ -80,25 +233,24 @@ Ox.load('UI', function() {
$viewLabel = Ox.Label({
textAlign: 'center',
title: 'Tracks',
- width: 61
+ width: 50
})
.css({
position: 'absolute',
right: '136px',
top: '4px',
- paddingTop: '1px',
+ padding: '1px 4px 0 4px',
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
- fontSize: '10px'
+ fontSize: '9px'
})
.appendTo($toolbar),
$viewButtons = Ox.ButtonGroup({
buttons: [
{id: 'tracks', title: 'list', tooltip: 'View Tracks'},
- {id: 'albums', title: 'iconlist', tooltip: 'View Albums'},
- {id: 'grid', title: 'grid', tooltip: 'View Grid'},
- {id: 'columns', title: 'columns', tooltip: 'View Columns'}
+ {id: 'albums', title: 'grid', tooltip: 'View Albums'},
+ {id: 'artists', title: 'columns', tooltip: 'View Artists'}
],
max: 1,
min: 1,
@@ -112,7 +264,9 @@ Ox.load('UI', function() {
})
.bindEvent({
change: function(data) {
- $viewLabel.options({title: Ox.toTitleCase(data.value)});
+ view = data.value;
+ $viewLabel.options({title: Ox.toTitleCase(view)});
+ $listPanel.replaceElement(1, musicList(view));
}
})
.appendTo($toolbar),
@@ -151,7 +305,7 @@ Ox.load('UI', function() {
paddingTop: '1px',
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
- fontSize: '10px'
+ fontSize: '9px'
})
.appendTo($toolbar),
@@ -167,143 +321,164 @@ Ox.load('UI', function() {
})
.appendTo($toolbar),
- $list = Ox.TableList({
+ $listList = Ox.TableList({
columns: [
{
format: function(value) {
- return value
- ? Ox.Element('
')
- .addClass('playing')
- .attr({src: Ox.UI.getImageURL(
- paused ? 'symbolUnmute' : 'symbolMute'
- )})
- : Ox.Element();
+ return Ox.Element('
')
+ .addClass('symbol')
+ .attr({src: Ox.UI.getImageURL(
+ 'symbol' + Ox.toTitleCase(value)
+ )});
},
- id: 'playing',
- removable: false,
- title: 'Playing',
- titleImage: 'mute',
+ id: 'icon',
+ title: 'icon',
visible: true,
width: 16
},
- {
- format: function(value) {
- return value
- ? Ox.Element('
')
- .addClass('playing')
- .attr({src: Ox.UI.getImageURL(
- 'symbolCheck'
- )})
- : Ox.Element();
- },
- id: 'checked',
- removable: false,
- title: 'Checked',
- titleImage: 'check',
- visible: true,
- width: 16
- },
- {
- align: 'right',
- id: 'disc',
- operator: '+',
- title: 'Disc',
- titleImage: 'circle',
- width: 32
- },
- {
- align: 'right',
- id: 'track',
- operator: '+',
- title: 'Track',
- titleImage: 'square',
- width: 32
- },
{
id: 'title',
- operator: '+',
- removable: false,
title: 'Title',
visible: true,
- width: 192
- },
- {
- id: 'artist',
- operator: '+',
- removable: false,
- title: 'Artist',
- visible: true,
- width: 192
- },
- {
- id: 'album',
- operator: '+',
- removable: false,
- title: 'Album',
- visible: true,
- width: 192
+ width: 136
},
{
align: 'right',
- id: 'year',
- operator: '+',
- title: 'Year',
+ id: 'items',
+ title: 'Items',
visible: true,
- width: 64
- },
- {
- align: 'right',
- format: function(value) {
- return Ox.formatDuration(value).substr(4);
- },
- id: 'duration',
- operator: '-',
- title: 'Time',
- visible: true,
- width: 64
- },
- {
- align: 'right',
- format: function(value) {
- return Ox.formatValue(value, 'B');
- },
- id: 'size',
- operator: '-',
- title: 'Size',
- visible: true,
- width: 64
- },
- {
- align: 'right',
- format: function(value) {
- return Math.round(value) + ' kbps'
- },
- id: 'bitrate',
- operator: '-',
- title: 'Bitrate',
- visible: true,
- width: 64
- },
- {
- id: 'genre',
- operator: '+',
- title: 'Genre',
- visible: true,
- width: 128
+ width: 40
}
],
+ items: [
+ {icon: 'audio', index: '0', items: 3, title: 'Music'},
+ {icon: 'playlist', index: '1', items: 0, title: 'Playing'},
+ {icon: 'click', index: '1', items: 0, title: 'Favorites'},
+ {icon: 'find', index: '1', items: 1, title: 'Hip-Hop'}
+ ],
+ max: 1,
+ selected: ['0'],
+ sort: [{key: 'index', operator: '+'}],
+ unique: 'index'
+ }),
+
+ $musicList,
+
+ $listPanel = Ox.SplitPanel({
+ elements: [
+ {
+ collapsible: true,
+ element: $listList,
+ resizable: true,
+ resize: [128, 192, 256, 320, 384],
+ size: 192
+ },
+ {
+ element: $musicList = musicList(view)
+ }
+ ],
+ orientation: 'horizontal'
+ }),
+
+ $appPanel = Ox.SplitPanel({
+ elements: [
+ {element: $toolbar, size: 39},
+ {element: $listPanel}
+ ],
+ orientation: 'vertical'
+ })
+ .appendTo(Ox.$body);
+
+ $($viewButtons.find('.OxButton')[0]).css({borderTopLeftRadius: 0});
+ $($viewButtons.find('.OxButton')[2]).css({borderTopRightRadius: 0});
+ $findInput.find('input').css({borderTopLeftRadius: 0, borderTopRightRadius: 0});
+ $findInput.find('.OxButton').css({borderTopRightRadius: 0});
+
+ Ox.print('ARTISTS', artists, 'ALBUMS', albums);
+
+ function getAlbums(artists) {
+ var albums = []
+ artists.forEach(function(artist) {
+ artist.items.forEach(function(album) {
+ albums.push(Ox.extend(album, {artist: artist.name}));
+ });
+ });
+ return albums;
+ }
+
+ function getArtists(tracks) {
+ var artists = [], tree = {};
+ tracks.forEach(function(track, index) {
+ var artist = track.artist,
+ album = track.year + ' ' + track.album,
+ title = Ox.pad(track.disc, 2) + '\n' + Ox.pad(track.track, 2)
+ + '\n' + track.title;
+ if (!tree[artist]) {
+ tree[artist] = {};
+ }
+ if (!tree[artist][album]) {
+ tree[artist][album] = {};
+ }
+ if (!tree[artist][album][title]) {
+ tree[artist][album][title] = track;
+ }
+ });
+ Ox.forEach(tree, function(albums, artist) {
+ artist = {
+ albums: Ox.len(albums),
+ id: artist,
+ items: [],
+ name: artist,
+ tracks: 0,
+ years: []
+ };
+ Ox.forEach(albums, function(tracks, id) {
+ var title = id.substr(5),
+ year = id.substr(0, 4);
+ artist.items.push({
+ artwork: tracks[Object.keys(tracks)[0]].artwork,
+ duration: Ox.values(tracks).reduce(function(r, v, i) {
+ return r + v.duration;
+ }, 0),
+ id: [artist.name, year, title].join('\n'),
+ items: [],
+ title: title,
+ tracks: Ox.len(tracks),
+ year: year
+ });
+ Ox.forEach(tracks, function(track, id) {
+ artist.items[artist.items.length - 1].items.push({
+ artist: track.artist,
+ bitrate: track.bitrate,
+ checked: track.checked,
+ disc: track.disc,
+ duration: track.duration,
+ id: id,
+ genre: track.genre,
+ playing: track.playing,
+ size: track.size,
+ title: track.title,
+ track: track.track
+ });
+ });
+ });
+ artists.push(artist);
+ });
+ return artists;
+ }
+
+ function musicList(view) {
+ var $list;
+ if (view == 'tracks') {
+ $list = Ox.TableList({
+ columns: columns,
columnsMovable: true,
columnsRemovable: true,
columnsResizable: true,
columnsVisible: true,
items: tracks,
max: 1,
- sort: [
- {key: 'artist', operator: '+'},
- {key: 'year', operator: '+'},
- {key: 'disc', operator: '+'},
- {key: 'track', operator: '+'}
- ],
+ sort: Ox.clone(sort, true),
unique: 'file'
})
.bindEvent({
@@ -327,20 +502,115 @@ Ox.load('UI', function() {
$audioPlayer.options({paused: paused});
$list.closePreview();
}
- }),
-
- $panel = Ox.SplitPanel({
- elements: [
- {element: $toolbar, size: 39},
- {element: $list}
- ],
- orientation: 'vertical'
+ });
+ } else if (view == 'albums') {
+ $list = Ox.IconList({
+ fixedRatio: 1,
+ item: function(data, sort, size) {
+ var key = Ox.contains(['artist', 'title'], sort[0].key)
+ ? 'year' : sort[0].key,
+ column = Ox.getObjectById(columns, key),
+ info = (column.format || Ox.identity)(data[key]);
+ return {
+ height: size,
+ id: data.id,
+ info: info,
+ title: [data.artist, data.title].join(' — '),
+ url: data.artwork,
+ width: size
+ }
+ },
+ items: albums,
+ max: 1,
+ pageLength: 120,
+ query: {conditions: [], operator: '&'},
+ selected: [],
+ size: 128,
+ sort: Ox.clone(sort, true),
+ unique: 'id'
})
- .appendTo(Ox.$body);
-
- $($viewButtons.find('.OxButton')[0]).css({borderTopLeftRadius: 0});
- $($viewButtons.find('.OxButton')[3]).css({borderTopRightRadius: 0});
- $findInput.find('input').css({borderTopLeftRadius: 0, borderTopRightRadius: 0});
- $findInput.find('.OxButton').css({borderTopRightRadius: 0});
+ .bindEvent({
+
+ });
+ } else if (view == 'artists') {
+ $list = Ox.ColumnList({
+ columns: [
+ {
+ id: 'artist',
+ width: 256
+ },
+ {
+ id: 'album',
+ width: 256
+ },
+ {
+ id: 'track'
+ }
+ ]
+ })
+ .bindEvent({
+
+ });
+ $list = Ox.CustomList({
+ item: function(data) {
+ Ox.print('itemdata::', data)
+ data.artwork = data.artwork || '';
+ data.tracks = data.tracks || [{duration: 0}];
+ data.year = data.year || '????';
+ var $item = $('