diff --git a/examples/ui/audio_player/css/example.css b/examples/ui/audio_player/css/example.css index 0046c2e8..0bbcae98 100644 --- a/examples/ui/audio_player/css/example.css +++ b/examples/ui/audio_player/css/example.css @@ -1,3 +1,91 @@ +#artworkText { + padding-top: 1px; + text-align: center; +} +#findInput { + right: 4px; + top: 19px; + border-top-left-radius: 0; +} +#findInput > input { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +#findInput > .OxButton { + border-top-right-radius: 0; +} +#findLabel { + right: 20px; + top: 4px; + padding-top: 1px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + font-size: 9px; +} +#findSelect { + right: 4px; + top: 4px; + border-bottom-right-radius: 0; +} +#statusText { + padding-top: 3px; + font-size: 9px; + text-align: center; +} +#toolbar > * { + position: absolute; +} +#viewButtons > .OxButton:first-child { + border-top-left-radius: 0; +} +#viewButtons > .OxButton:last-child { + border-top-right-radius: 0; +} +#viewLabel { + right: 136px; + top: 4px; + padding: 1px 4px 0 4px; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + font-size: 9px; +} + +.item { + height: 32px; +} +.item > * { + position: relative; +} +.itemIcon { + left: 2px; + top: 2px; + width: 28px; + height: 28px; +} +.itemTitle { + left: 34px; + top: -28px; + height: 14px; + font-size: 13px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + cursor: default; +} +.itemInfo { + left: 34px; + top: -28px; + height: 10px; + font-size: 9px; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + cursor: default; +} + +.OxDialog > .OxContent { + padding: 24px; +} .OxTableList .OxItem .OxCell > img.image { width: 14px; height: 14px; diff --git a/examples/ui/audio_player/js/example.js b/examples/ui/audio_player/js/example.js index dbc2e90a..05fc7f40 100644 --- a/examples/ui/audio_player/js/example.js +++ b/examples/ui/audio_player/js/example.js @@ -6,249 +6,388 @@ Demo application using Ox.AudioPlayer. Ox.load('UI', function() { - var columns = [ - { - format: function(value) { - return value - ? Ox.Element('') + var app = { + $ui: {}, + data: {}, + site: { + listColumns: [ + { + format: function(value, data) { + return Ox.Element('') .addClass('symbol') .attr({src: Ox.UI.getImageURL( - paused ? 'symbolUnmute' : 'symbolMute' - )}) - : Ox.Element(); + 'symbol' + Ox.toTitleCase( + value || (data.query ? 'find ': 'click') + ) + )}); + }, + id: 'icon', + title: 'icon', + visible: true, + width: 16 }, - 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: 'title', + title: 'Title', + visible: true, + width: 136 }, - 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, - sidebarSize = 192, - sort = [ - {key: 'artist', operator: '+'}, - {key: 'year', operator: '+'}, - {key: 'disc', operator: '+'}, - {key: 'track', operator: '+'} - ], - track = 0, - tracklistSize = 256, - tracks = [ - { - album: 'The Grey Album', - artist: 'Danger Mouse', - artwork: 'mp3/Danger Mouse/2004 The Grey Album/artwork.png', - bitrate: 128, - checked: true, - disc: 1, - duration: 160.417, - file: 'mp3/Danger Mouse/2004 The Grey Album/03 Encore.mp3', - genre: 'Hip-Hop', - playing: false, - size: 2556502, - title: 'Encore', - track: 3, - year: '2004' - }, - { - 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, - duration: 303.960, - file: 'mp3/Death Grips/2012 No Love Deep Web/03 No Love.mp3', - genre: 'Electronic', - playing: false, - size: 4863327, - title: 'No Love', - track: 3, - year: '2012' - }, - { - 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, - duration: 138.370, - file: 'mp3/Death Grips/2012 No Love Deep Web/09 Deep Web.mp3', - genre: 'Electronic', - playing: false, - size: 2214303, - title: 'Deep Web', - track: 9, - year: '2012' - } - ], - artists = getArtists(tracks), - albums = getAlbums(artists), - view = 'tracks', - - $toolbar = Ox.Bar({size: 39}), - - $audioPlayer = Ox.AudioPlayer({ - audio: tracks, - paused: true, - 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) { - $musicList.value(tracks[track].file, 'playing', false); - track = data.track; - $musicList.value(tracks[track].file, 'playing', true); + { + align: 'right', + id: 'items', + title: 'Items', + visible: true, + width: 40 } - }) - .appendTo($toolbar) - .gainFocus(), + ], + lists: [ + {icon: 'audio', id: 'Music', index: 0, items: 3, title: 'Music'}, + {icon: 'playlist', id: 'Playing', index: 1, items: 0, title: 'Playing'} + ], + sort: [ + {key: 'artist', operator: '+'}, + {key: 'year', operator: '+'}, + {key: 'disc', operator: '+'}, + {key: 'track', operator: '+'} + ], + sums: ['duration', 'size'], + trackColumns: [ + { + format: function(value) { + return value + ? Ox.Element('') + .addClass('symbol') + .attr({src: Ox.UI.getImageURL( + app.user.ui.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 + } + ] + }, + ui: {}, + user: { + lists: [ + { + id: 'favorites', + index: 0, + items: 0, + title: 'Favorites', + type: 'static' + }, + { + id: 'hip-hop', + index: 1, + items: 1, + query: { + conditions: [ + {key: 'genre', operator: '==', value: 'Hip-Hop'} + ], + operator: '&' + }, + title: 'Hip-Hop' + } + ], + ui: { + artwork: 'selected', + coverSize: 64, + list: 'Music', + paused: true, + query: { + conditions: [], + operator: '&', + }, + selectedAlbum: [], + selectedArtist: [], + selectedTrack: [], + showSidebar: true, + sidebarSize: 192, + track: 0, + tracklistSize: 256, + view: 'tracks' + } + }, + utils: {} + }; - $viewLabel = Ox.Label({ + app.user.ui.sort = Ox.clone(app.site.sort, true); + + app.load = function() { + Ox.getJSON('json/music.json', function(data) { + app.data.tracks = data; + app.data.artists = app.utils.getArtists(); + app.data.albums = app.utils.getAlbums(); + app.$ui.appPanel = app.ui.appPanel().appendTo(Ox.$body); + Ox.$window.bind({resize: app.utils.resizeWindow}); + }); + }; + + app.UI = (function() { + var that = {}; + that.set = function() { + var args = Ox.makeObject(arguments), + keys = [], + previousUI = Ox.clone(app.user.ui, true); + Ox.forEach(args, function(value, key) { + if (!Ox.isEqual(value, previousUI[key])) { + app.user.ui[key] = value; + keys.push(key); + } + }); + keys.forEach(function(key) { + var data = { + previousValue: previousUI[key], + value: app.user.ui[key] + } + Ox.print('ui_' + key.toLowerCase(), JSON.stringify(app.user.ui[key])) + Ox.forEach(app.$ui, function($elements) { + Ox.makeArray($elements).forEach(function($element) { + $element.triggerEvent('ui_' + key.toLowerCase(), data); + }); + }); + }); + }; + return that; + }()); + + app.ui.appPanel = function() { + return Ox.SplitPanel({ + elements: [ + {element: app.$ui.mainMenu = app.ui.mainMenu(), size: 20}, + {element: app.$ui.mainPanel = app.ui.mainPanel()} + ], + orientation: 'vertical' + }); + }; + + app.ui.mainMenu = function() { + return Ox.MainMenu({ + menus: [ + { + id: '0xcd', + title: '0xCD', + items: [ + {id: 'about', title: 'About 0xCD'} + ] + } + ] + }) + .bindEvent({ + click: function(data) { + if (data.id == 'about') { + app.$ui.aboutDialog = ( + app.$ui.aboutDialog || app.ui.aboutDialog() + ).open(); + } + } + }); + }; + + app.ui.aboutDialog = function() { + var $element = Ox.Dialog({ + buttons: [ + Ox.Button({ + id: 'close', + title: 'Close' + }) + .bindEvent({ + click: function() { + $element.close(); + } + }) + ], + content: Ox.Element() + .html('Audio Player Example'), + height: 256, + keys: {enter: 'close', escape: 'close'}, + title: 'About 0xCD', + width: 512 + }); + return $element; + }; + + app.ui.mainPanel = function() { + return Ox.SplitPanel({ + elements: [ + {element: app.ui.$toolbar = app.ui.toolbar(), size: 39}, + {element: app.ui.$bothPanel = app.ui.bothPanel()} + ], + orientation: 'vertical' + }); + }; + + app.ui.toolbar = function() { + return Ox.Bar({size: 39}) + .attr({id: 'toolbar'}) + .append(app.$ui.audioPlayer = app.ui.audioPlayer()) + .append(app.$ui.viewLabel = app.ui.viewLabel()) + .append(app.$ui.viewButtons = app.ui.viewButtons()) + .append(app.$ui.findSelect = app.ui.findSelect()) + .append(app.$ui.findLabel = app.ui.findLabel()) + .append(app.$ui.findInput = app.ui.findInput()); + }; + + app.ui.audioPlayer = function() { + return Ox.AudioPlayer({ + audio: app.data.tracks, + paused: true, + width: window.innerWidth - 190 + }) + .css({left: '4px', top: '4px'}) + .bindEvent({ + paused: function(data) { + var id = app.data.tracks[app.user.ui.track].file + app.user.ui.paused = data.paused; + app.$ui.trackList.value(id, 'playing', false); + app.$ui.trackList.value(id, 'playing', true); + }, + track: function(data) { + var id = app.data.tracks[app.user.ui.track].file + app.$ui.trackList.value(id, 'playing', false); + app.user.ui.track = data.track; + $app.$ui.trackList.value(id, 'playing', true); + } + }); + }; + + app.ui.viewLabel = function() { + return Ox.Label({ textAlign: 'center', title: 'Tracks', width: 50 }) - .css({ - position: 'absolute', - right: '136px', - top: '4px', - padding: '1px 4px 0 4px', - borderBottomLeftRadius: 0, - borderBottomRightRadius: 0, - fontSize: '9px' - }) - .appendTo($toolbar), + .attr({id: 'viewLabel'}); + }; - $viewButtons = Ox.ButtonGroup({ + app.ui.viewButtons = function() { + return Ox.ButtonGroup({ buttons: [ {id: 'tracks', title: 'list', tooltip: 'View Tracks'}, {id: 'albums', title: 'grid', tooltip: 'View Albums'}, @@ -259,6 +398,7 @@ Ox.load('UI', function() { selectable: true, type: 'image' }) + .attr({id: 'viewButtons'}) .css({ position: 'absolute', right: '136px', @@ -266,223 +406,625 @@ Ox.load('UI', function() { }) .bindEvent({ change: function(data) { - view = data.value; - $viewLabel.options({title: Ox.toTitleCase(view)}); - $rightPanel.replaceElement(0, musicPanel(view)); + app.user.ui.view = data.value; + app.$ui.viewLabel.options({title: Ox.toTitleCase(app.user.ui.view)}); + app.$ui.rightPanel.replaceElement(0, app.$ui.musicPanel = app.ui.musicPanel()); } - }) - .appendTo($toolbar), + }); + }; - $findSelect = Ox.Select({ - items: [ - {id: 'all', title: 'Find: All'}, - {id: 'tracks', title: 'Find: Tracks'}, - {id: 'artists', title: 'Find: Artists'}, - {id: 'albums', title: 'Find: Albums'} - ], - overlap: 'left', - type: 'image' - }) - .css({ - position: 'absolute', - right: '4px', - top: '4px', - borderBottomRightRadius: 0 - }) - .bindEvent({ - change: function(data) { - $findLabel.options({title: data.title}); - } - }) - .appendTo($toolbar), - - $findLabel = Ox.Label({ + app.ui.findSelect = function() { + return Ox.Select({ + items: [ + {id: 'all', title: 'Find: All'}, + {id: 'tracks', title: 'Find: Tracks'}, + {id: 'artists', title: 'Find: Artists'}, + {id: 'albums', title: 'Find: Albums'} + ], + overlap: 'left', + type: 'image' + }) + .attr({id: 'findSelect'}) + .bindEvent({ + change: function(data) { + $findLabel.options({title: data.title}); + } + }); + }; + + app.ui.findLabel = function() { + return Ox.Label({ title: 'Find: All', width: 112 }) - .css({ - position: 'absolute', - right: '20px', - top: '4px', - paddingTop: '1px', - borderBottomLeftRadius: 0, - borderBottomRightRadius: 0, - fontSize: '9px' - }) - .appendTo($toolbar), + .attr({id: 'findLabel'}); + }; - $findInput = Ox.Input({ + app.ui.findInput = function() { + return Ox.Input({ clear: true, width: 128 }) - .css({ - position: 'absolute', - right: '4px', - top: '19px', - borderTopLeftRadius: 0 - }) - .appendTo($toolbar), + .attr({id: 'findInput'}); + }; - $listsList = Ox.TableList({ - columns: [ - { - format: function(value) { - return Ox.Element('') - .addClass('symbol') - .attr({src: Ox.UI.getImageURL( - 'symbol' + Ox.toTitleCase(value) - )}); - }, - id: 'icon', - title: 'icon', - visible: true, - width: 16 - }, - { - id: 'title', - title: 'Title', - visible: true, - width: 136 - }, - { - align: 'right', - id: 'items', - title: 'Items', - visible: true, - 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: '+'}], - sortable: true, - unique: 'index' - }), + app.ui.bothPanel = function() { + return Ox.SplitPanel({ + elements: [ + { + collapsible: true, + element: app.$ui.leftPanel = app.ui.leftPanel(), + resizable: true, + resize: [128, 192, 256, 320, 384], + size: app.user.ui.sidebarSize + }, + { + element: app.$ui.rightPanel = app.ui.rightPanel() + } + ], + orientation: 'horizontal' + }); + } - $artworkbar = Ox.Bar({size: 16}), - - $artworkText = Ox.Element() - .css({ - paddingTop: '1px', - textAlign: 'center' - }) - .html('Selected Item') - .appendTo($artworkbar), - - $artwork = Ox.Element('') - .attr({src: tracks[0].artwork}) - .css({ - width: sidebarSize + 'px', - height: sidebarSize + 'px' - }), - - $artworkPanel = Ox.SplitPanel({ - elements: [ - {element: $artworkbar, size: 16}, - {element: $artwork} - ], - orientation: 'vertical' - }), - - $leftPanel = Ox.SplitPanel({ + app.ui.leftPanel = function() { + return Ox.SplitPanel({ elements: [ { - element: $listsList + element: app.$ui.listsPanel = app.ui.listsPanel() }, { collapsible: true, - element: $artworkPanel, - size: sidebarSize + 16 + element: app.$ui.artworkPanel = app.ui.artworkPanel(), + size: app.user.ui.sidebarSize + 16 } ], orientation: 'vertical' }) .bindEvent({ resize: function(data) { - sidebarSize = data.size; - $listsList.setColumnWidth('title', sidebarSize - 56); - $leftPanel.size(1, sidebarSize + 16); - $artwork.css({ - width: sidebarSize + 'px', - height: sidebarSize + 'px' + app.user.ui.sidebarSize = data.size; + [app.$ui.siteLists, app.$ui.userLists].forEach(function($list) { + $list.setColumnWidth('title', app.user.ui.sidebarSize - 56); + }); + app.$ui.listsList + app.$ui.leftPanel.size(1, app.user.ui.sidebarSize + 16); + app.$ui.artwork.css({ + width: app.user.ui.sidebarSize + 'px', + height: app.user.ui.sidebarSize + 'px' }); //$musicList.size(); } - }), - - $musicList, - - $musicPanel = musicPanel(view), - - $statusbar = Ox.Bar({size: 16}), - - $status = Ox.Element().css({ - paddingTop: '3px', - fontSize: '9px', - textAlign: 'center' }) - .html('Loading...') - .appendTo($statusbar), + }; - $rightPanel = Ox.SplitPanel({ - elements: [ - {element: $musicPanel}, - {element: $statusbar, size: 16} - ], - orientation: 'vertical' - }), + app.ui.listsPanel = function() { + return Ox.SplitPanel({ + elements: [ + { + element: app.$ui.siteLists = app.ui.siteLists(), + size: app.site.lists.length * 16 + }, + { + element: app.$ui.userLists = app.ui.userLists() + } + ], + orientation: 'vertical' + }); + }; - $mainPanel = Ox.SplitPanel({ - elements: [ - { - collapsible: true, - element: $leftPanel, - resizable: true, - resize: [128, 192, 256, 320, 384], - size: sidebarSize - }, - { - element: $rightPanel + app.ui.siteLists = function() { + var $element = Ox.TableList({ + columns: app.site.listColumns, + items: app.site.lists, + max: 1, + selected: [app.user.ui.list], + sort: [{key: 'index', operator: '+'}], + unique: 'id' + }) + .bindEvent({ + select: function(data) { + app.UI.set({list: data.ids[0] || app.site.lists[0].id}); + }, + selectafter: function() { + app.UI.set({list: app.user.lists[0].id}); + app.$ui.userLists.gainFocus(); + }, + ui_list: function(data) { + $element.options({ + selected: data.value[0] == data.value[0].toUpperCase() + ? [data.value] : [] + }); + } + }); + $element.update = function() { + return $element.setColumnWidth('title', app.user.ui.sidebarSize - 56); + }; + return $element.update(); + }; + + app.ui.userLists = function() { + var $element = Ox.TableList({ + columns: app.site.listColumns, + items: app.user.lists, + max: 1, + selected: [app.user.ui.list], + sort: [{key: 'index', operator: '+'}], + sortable: true, + unique: 'id' + }) + .bindEvent({ + move: function(data) { + Ox.print('MOVE:', data); + }, + select: function(data) { + app.UI.set({list: data.ids[0] || app.site.lists[0].id}); + }, + selectbefore: function() { + app.UI.set({list: Ox.last(app.site.lists).id}); + app.$ui.siteLists.gainFocus(); + }, + ui_list: function(data) { + $element.options({ + selected: data.value[0] == data.value[0].toLowerCase() + ? [data.value] : [] + }); + } + }); + $element.update = function() { + return $element.setColumnWidth('title', app.user.ui.sidebarSize - 56); + }; + return $element.update(); + }; + + app.ui.artworkPanel = function() { + return Ox.SplitPanel({ + elements: [ + {element: app.$ui.artworkbar = app.ui.artworkbar(), size: 16}, + {element: app.$ui.artwork = app.ui.artwork()} + ], + orientation: 'vertical' + }); + }; + + app.ui.artworkbar = function() { + return Ox.Bar({size: 16}) + .append(app.$ui.artworkText = app.ui.artworkText()) + .bindEvent({ + anyclick: function() { + app.UI.set({ + artwork: app.user.ui.artwork == 'playing' + ? 'selected' : 'playing' + }); + } + }); + }; + + app.ui.artworkText = function() { + var $element = Ox.Element() + .attr({id: 'artworkText'}) + .bindEvent({ + ui_artwork: function() { + $element.update(); + } + }); + $element.update = function() { + $element.html( + app.user.ui.artwork == 'playing' + ? 'Now Playing' : 'Selected Item' + ); + return $element; + }; + return $element.update(); + }; + + app.ui.artwork = function() { + var $element = Ox.Element('') + .attr({src: app.data.tracks[0].artwork}) + .bindEvent({ + ui_selectedalbum: function(data) { + if (app.user.ui.artwork == 'selected') { + $element.attr({ + src: data.value.length + ? Ox.getObjectById(app.data.albums, data.value[0]).artwork + : '' + }); } - ], - orientation: 'horizontal' - }), + }, + ui_selectedartist: function(data) { + if (app.user.ui.artwork == 'selected') { + $element.attr({ + src: data.value.length + ? Ox.getObjectById(app.data.artists, data.value[0]).artwork + : '' + }); + } + }, + ui_selectedtrack: function(data) { + if (app.user.ui.artwork == 'selected') { + $element.attr({ + src: data.value.length + ? Ox.getObjectById(app.data.tracks, data.value[0]).artwork + : '' + }); + } + } + }); + $element.update = function() { + $element.css({ + width: app.user.ui.sidebarSize + 'px', + height: app.user.ui.sidebarSize + 'px' + }); + return $element; + }; + return $element.update(); + }; - $appPanel = Ox.SplitPanel({ - elements: [ - {element: $toolbar, size: 39}, - {element: $mainPanel} - ], - orientation: 'vertical' + app.ui.rightPanel = function() { + return Ox.SplitPanel({ + elements: [ + {element: app.$ui.musicPanel = app.ui.musicPanel()}, + {element: app.$ui.statusbar = app.ui.statusbar(), size: 16} + ], + orientation: 'vertical' + }); + }; + + app.ui.musicPanel = function() { + return app.ui[app.user.ui.view + 'Panel'](); + }; + + app.ui.tracksPanel = function() { + return Ox.SplitPanel({ + elements: [ + { + collapsible: true, + element: app.$ui.albumBrowser = app.ui.albumBrowser(), + size: 112 + Ox.UI.SCROLLBAR_SIZE + }, + { + element: app.$ui.trackList = app.ui.trackList() + } + ], + orientation: 'vertical' + }); + }; + + app.ui.albumBrowser = function() { + var $element = Ox.IconList({ + fixedRatio: 1, + item: function(data, sort, size) { + return { + height: size, + id: data.id, + info: data.year, + title: [data.artist, data.title].join(' — '), + url: data.artwork, + width: size + }; + }, + items: app.data.albums, + max: 1, + orientation: 'horizontal', + pageLength: 100, + query: {conditions: [], operator: '&'}, + selected: [], + size: 64, + sort: [{key: 'index', operator: '+'}], + unique: 'id' }) - .appendTo(Ox.$body); + .bindEvent({ + ui_sort: function() { + $element.update(); + } + }); + $element.update = function() { + app.utils.getTrackAlbums(function(albums) { + Ox.print('ALBUMS::::', albums) + $element.options({items: albums}); + }); + return $element; + } + return $element; + }; - $($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}); + app.ui.trackList = function() { + return Ox.TableList({ + columns: app.site.trackColumns, + columnsMovable: true, + columnsRemovable: true, + columnsResizable: true, + columnsVisible: true, + items: app.data.tracks, + scrollbarVisible: true, + sort: Ox.clone(app.user.ui.sort, true), + sums: app.site.sums, + unique: 'id' + }) + .bindEvent({ + init: function(data) { + app.$ui.statusText.update(data); + app.utils.getTrackAlbums(function(data) { + Ox.print('::::', data); + }); + }, + open: function(data) { + var file = data.ids[0], + id = app.data.tracks[app.user.ui.track].id, + index = Ox.getIndexById(app.data.tracks, id); + if (index == app.user.ui.track) { + app.$ui.trackList.value(id, 'playing', true); + app.$ui.audioPlayer.options({paused: false, position: 0}); + } else { + app.$ui.trackList.value(id, 'playing', false); + app.user.ui.track = index; + app.$ui.audioPlayer.options({paused: false, track: app.user.ui.track}); + app.$ui.trackList.value(id, 'playing', true); + } + }, + openpreview: function(data) { + app.user.ui.paused = !app.user.ui.paused; + app.$ui.audioPlayer.options({paused: app.user.ui.paused}); + app.$ui.trackList.closePreview(); + }, + select: function(data) { + app.UI.set({selectedTrack: data.ids}); + }, + sort: function(data) { + Ox.print('DDD', data); + app.UI.set({sort: [data]}); + } + }); + }; - // Ox.print('ARTISTS', artists, 'ALBUMS', albums); + app.ui.albumsPanel = function() { + return Ox.SplitPanel({ + elements: [ + { + element: app.$ui.albumList = app.ui.albumList() + }, + { + element: app.$ui.trackBrowser = app.ui.trackBrowser(), + resizable: true, + resize: [192, 256, 320], + size: app.user.ui.tracklistSize + } + ], + orientation: 'horizontal' + }); + }; - function getAlbums(artists) { + app.ui.albumList = function() { + return 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(app.site.trackColumns, 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: app.data.albums, + pageLength: 120, + query: {conditions: [], operator: '&'}, + selected: [], + size: 128, + sort: Ox.clone(app.user.ui.sort, true), + unique: 'id' + }) + .bindEvent({ + select: function(data) { + app.UI.set({selectedAlbum: data.ids}); + }, + openpreview: function() { + + } + }); + }; + + app.ui.trackBrowser = function() { + return Ox.TableList({ + columns: [ + Ox.getObjectById(app.site.trackColumns, 'playing'), + Ox.getObjectById(app.site.trackColumns, 'checked'), + Ox.getObjectById(app.site.trackColumns, 'artwork'), + Ox.extend( + Ox.getObjectById(app.site.trackColumns, 'track'), + {visible: true} + ), + Ox.extend( + Ox.getObjectById(app.site.trackColumns, 'title'), + {width: app.user.ui.tracklistSize - 144 - Ox.UI.SCROLLBAR_SIZE} + ), + Ox.getObjectById(app.site.trackColumns, 'duration') + ], + items: app.data.tracks, + query: {conditions: [], operator: '&'}, + scrollbarVisible: true, + selected: [], + sort: Ox.clone(app.site.sort, true), + unique: 'id' + }) + .bindEvent({ + resize: function(data) { + app.user.ui.tracklistSize = data.size; + app.$ui.trackBrowser.setColumnWidth( + 'title', app.user.ui.tracklistSize - 144 - Ox.UI.SCROLLBAR_SIZE + ); + }, + ui_selectedalbum: function(data) { + app.$ui.trackBrowser.options({ + items: data.value.length ? Ox.flatten( + data.value.map(function(id) { + return Ox.getObjectById(app.data.albums, id).items; + }) + ) : [] + }); + } + }); + }; + + app.ui.artistsPanel = function() { + return Ox.ColumnList({ + columns: [ + { + id: 'artists', + item: function(data, width) { + data.artwork = data.artwork || ''; + data.years = data.years || []; + var $item = $('