diff --git a/static/js/pandora/editPanel.js b/static/js/pandora/editPanel.js index 1cccd03d..275f8cff 100644 --- a/static/js/pandora/editPanel.js +++ b/static/js/pandora/editPanel.js @@ -2,255 +2,245 @@ pandora.ui.editPanel = function() { - var that = Ox.SplitPanel({ - elements: [ - {element: Ox.Element(), size: 24}, - {element: Ox.Element()}, - {element: Ox.Element(), size: 16} - ], - orientation: 'vertical' - }); + var ui = pandora.user.ui, + edit, + listSizes = [ + 144 + Ox.UI.SCROLLBAR_SIZE, + 280 + Ox.UI.SCROLLBAR_SIZE, + 416 + Ox.UI.SCROLLBAR_SIZE + ], + listSize = listSizes[ui.clipColumns], + smallTimelineCanvas, + smallTimelineContext, + that = Ox.Element(); - pandora.user.ui.edit && render(); + ui.edit && render(); + + function editPointsKey(key) { + return 'editPoints.' + ui.edit.replace(/\./g, '\\.') + '.' + key; + } + + function getSmallTimelineURL() { + var fps = 25, + width = Math.floor(edit.duration * fps), + height = 64; + smallTimelineCanvas = Ox.$('').attr({width: width, height: height})[0]; + smallTimelineContext = smallTimelineCanvas.getContext('2d'); + return smallTimelineCanvas.toDataURL(); + } + + function getVideos() { + return Ox.flatten(edit.clips.map(function(clip) { + return pandora.getClipVideos(clip); + })); + } function render() { pandora.api.getEdit({id: pandora.user.ui.edit}, function(result) { - - var edit = result.data; - - var $toolbar = Ox.Bar({size: 24}), - - $editMenu, - - $viewSelect = Ox.Select({ - items: [ - {'id': 'list', 'title': Ox._('View as List')}, - {'id': 'player', 'title': Ox._('View as Player')}, - ], - value: 'list', - width: 128 - }) - .css({ - float: 'left', - margin: '4px 0 0 4px' + edit = result.data; + // fixme: duration should come from backend + edit.duration = 0; + edit.clips.forEach(function(clip) { + clip.position = edit.duration; + edit.duration += clip.duration; + }); + //Ox.print('EDIT', edit) + pandora.$ui.mainPanel.replaceElement(1, + that = Ox.VideoEditPanel({ + clips: edit.clips, + clipsSize: listSize, + clipSort: ui.clipSort, + clipSortOptions: [/*...*/], + clipView: ui.clipView, + cuts: [], + duration: edit.duration, + editable: edit.editable, + enableSubtitles: ui.videoSubtitles, + fullscreen: false, + getLargeTimelineURL: function(type, i, callback) { + pandora.getLargeEditTimelineURL(edit, type, i, callback); + }, + height: pandora.$ui.appPanel.size(1), + 'in': ui.editPoints[ui.edit]['in'], + loop: ui.videoLoop, + muted: ui.videoMuted, + out: ui.editPoints[ui.edit].out, + position: ui.editPoints[ui.edit].position, + resolution: ui.videoResolution, + scaleToFill: ui.videoScale == 'fill', + // selected: ... + showClips: ui.showClips, + showTimeline: ui.showTimeline, + smallTimelineURL: getSmallTimelineURL(), + sort: ui.clipSort, + sortOptions: [ + {key: 'index', title: Ox._('Sort Manually'), operator: '+'} + ].concat( + pandora.site.clipKeys.map(function(key) { + return Ox.extend(Ox.clone(key), { + title: Ox._(('Sort by Clip {0}'), [Ox._(key.title)]) + }); + }) + ).concat( + pandora.site.sortKeys.map(function(key) { + return Ox.extend(Ox.clone(key), { + title: Ox._('Sort by {0}', [Ox._(key.title)]) + }); + }) + ), + timeline: ui.videoTimeline, + video: getVideos(), + volume: ui.videoVolume, + width: pandora.$ui.document.width() - pandora.$ui.mainPanel.size(0) - 1 }) .bindEvent({ - change: function(data) { - $panel.replaceElement(0, pandora.$ui.edit = pandora.ui[ - data.value == 'player' ? 'editPlayer' : 'editList' - ](edit)); + clipssort: function(data) { + pandora.UI.set({clipSort: data.sort}); }, - }).appendTo($toolbar), - - $statusbar = Ox.Bar({size: 16}), - - $panel = Ox.SplitPanel({ - elements: [ - { - element: pandora.$ui.edit = pandora.ui.editList(edit) - }, - { - element: Ox.Element(), - size: 0, - resizable: false + copy: function(data) { + + }, + cut: function(data) { + + }, + edit: function(data) { + var args = {id: data.id}, + index = Ox.getIndexById(edit.clips, data.id), + clip = edit.clips[index]; + if (data.key == 'duration') { + data.key = 'out'; + data.value += clip['in']; } - ], - orientation: 'horizontal' - }); - - that.replaceElement(0, $toolbar); - that.replaceElement(1, $panel); - that.replaceElement(2, $statusbar); - }); - } - - that.reload = function() { - render(); - } - - return that; - -}; - -pandora.ui.editList = function(edit) { - - var height = getHeight(), - width = getWidth(), - - that = Ox.Element() - .css({ - 'overflow-y': 'auto' - }); - - self.$list = Ox.TableList({ - columns: [ - { - align: 'left', - id: 'index', - operator: '+', - title: Ox._('Index'), - visible: false, - width: 60 - }, - { - align: 'left', - id: 'id', - operator: '+', - title: Ox._('ID'), - visible: false, - width: 60 - }, - { - align: 'left', - id: 'item', - operator: '+', - title: Ox._(pandora.site.itemName.singular), - visible: true, - width: 360 - }, - { - editable: true, - id: 'in', - operator: '+', - title: Ox._('In'), - visible: true, - width: 60 - }, - { - editable: true, - id: 'out', - operator: '+', - title: Ox._('Out'), - visible: true, - width: 60 - }, - { - id: 'duration', - operator: '+', - title: Ox._('Duration'), - visible: true, - width: 60 - } - ], - columnsMovable: true, - columnsRemovable: true, - columnsResizable: true, - columnsVisible: true, - items: edit.clips, - scrollbarVisible: true, - sort: [{key: 'index', operator: '+'}], - sortable: true, - unique: 'id' - }) - .appendTo(that) - .bindEvent({ - add: function(data) { - if(pandora.user.ui.item) { - pandora.api.addClip({ - edit: pandora.user.ui.edit, - item: pandora.user.ui.item, - 'in': pandora.user.ui.videoPoints[pandora.user.ui.item]['in'], - out: pandora.user.ui.videoPoints[pandora.user.ui.item].out, - }, function(result) { - Ox.Request.clearCache(); - pandora.$ui.rightPanel.reload() - }); - } - }, - 'delete': function(data) { - if (data.ids.length > 0 && edit.editable) { - pandora.api.removeClip({ - ids: data.ids, - edit: pandora.user.ui.edit - }, function(result) { - Ox.Request.clearCache(); - pandora.$ui.rightPanel.reload(); - }); - } - }, - move: function(data) { - Ox.Request.clearCache(); - pandora.api.sortClips({ - edit: pandora.user.ui.edit, - ids: data.ids + pandora.api.get({id: clip.item, keys: ['duration']}, function(result) { + data.value = Math.min(data.value, result.data.duration); + args[data.key] = data.value; + if (data.key == 'in' && data.value > clip.out) { + args.out = args['in']; + } else if (data.key == 'out' && data.value < clip['in']) { + args['in'] = args.out; + } + pandora.api.editClip(args, function(result) { + edit.clips[index] = result.data; + that.updateClip(data.id, result.data); + }); + }); + }, + move: function(data) { + pandora.api.sortClips({ + edit: edit.id, + ids: data.ids + }, function() { + Ox.Request.clearCache('getEdit'); + }); + }, + muted: function(data) { + pandora.UI.set('videoMuted', data.muted); + }, + paste: function() { + if (Ox.Clipboard.type() == 'clip') { + pandora.api.addClips({ + clips: Ox.Clipboard.paste(), + edit: pandora.user.ui.edit + }, function(result) { + updateClips(edit.clips.concat(result.data.clips)); + }); + } + }, + playing: function(data) { + pandora.UI.set(editPointsKey('position'), data.position); + }, + position: function(data) { + pandora.UI.set(editPointsKey('position'), data.position); + }, + remove: function(data) { + if (edit.editable) { + pandora.api.removeClips({ + ids: data.ids, + edit: pandora.user.ui.edit + }, function(result) { + updateClips(result.data.clips); + }); + } + }, + resizeclips: function(data) { + pandora.UI.set('clipsSize', data.clipsSize); + }, + resolution: function(data) { + pandora.UI.set('videoResolution', data.resolution); + }, + scale: function(data) { + pandora.UI.set('videoScale', data.scale); + }, + select: function(data) { + pandora.UI.set(editPointsKey('clip'), data.ids[0]); + }, + subtitles: function(data) { + pandora.UI.set('videoSubtitles', data.subtitles); + }, + timeline: function(data) { + pandora.UI.set('videoTimeline', data.timeline); + }, + toggleclips: function(data) { + pandora.UI.set('showAnnotations', data.showAnnotations); + }, + toggletimeline: function(data) { + pandora.UI.set('showTimeline', data.showTimeline); + }, + volume: function(data) { + pandora.UI.set('videoVolume', data.volume); + }, + pandora_showannotations: function(data) { + that.options({showAnnotations: data.value}); + }, + pandora_showtimeline: function(data) { + that.options({showTimeline: data.value}); + }, + pandora_videotimeline: function(data) { + that.options({timeline: data.value}); + } }) - }, - select: function(data) { - }, - submit: function(data) { - var value = self.$list.value(data.id, data.key); - if (data.value != value && !(data.value === '' && value === null)) { - self.$list.value(data.id, data.key, data.value || null); - var edit = { - id: data.id, - }; - edit[data.key] = parseFloat(data.value); - pandora.api.editClip(edit, function(result) { - self.$list.value(data.id, data.key, result.data[data.key]); - self.$list.value(data.id, 'duration', result.data.duration); - }); - } - } + ); + updateSmallTimelineURL(); }); - - function getHeight() { - // 24 menu + 24 toolbar + 16 statusbar + 32 title + 32 margins - // + 1px to ge trid of scrollbar - return window.innerHeight - 128 -1; } - function getWidth() { - return window.innerWidth - - pandora.user.ui.showSidebar * pandora.user.ui.sidebarSize - 1 - - pandora.user.ui.embedSize - 1 - - 32; - } - - that.update = function() { - $text.options({ - maxHeight: getHeight(), - width: getWidth() + function updateClips(clips) { + Ox.Request.clearCache(); + edit.clips = clips; + edit.duration = 0; + edit.clips.forEach(function(clip) { + clip.position = edit.duration; + edit.duration += clip.duration; }); - return that; - }; + that.options({ + clips: clips, + smallTimelineURL: getSmallTimelineURL(), + video: getVideos() + }); + updateSmallTimelineURL(); + + } + that.updateSmallTimelineURL = updateSmallTimelineURL; + function updateSmallTimelineURL() { + var fps = 25; + Ox.serialForEach(edit.clips, function(clip) { + var callback = Ox.last(arguments); + pandora.getLargeClipTimelineURL(clip.item, clip['in'], clip.out, ui.videoTimeline, function(url) { + var image = Ox.$('') + .on({ + load: function() { + smallTimelineContext.drawImage(image, Math.floor(clip.position * fps), 0); + that.options({smallTimelineURL: smallTimelineCanvas.toDataURL()}); + callback(); + } + }) + .attr({ + src: url + })[0]; + }); + }); + } return that; }; - -pandora.ui.editPlayer = function(edit) { - - var that = Ox.Element() - .css({ - overflowY: 'auto' - }); - - self.$player = Ox.VideoPlayer({ - controlsBottom: ['play', 'volume', 'previous', 'next', 'loop', 'scale', 'space', 'position'], - controlsTop: ['fullscreen', 'space', 'open'], - enableKeyboard: true, - enableMouse: true, - enablePosition: true, - enableTimeline: true, - height: getHeight(), - paused: true, - position: 0, - video: Ox.flatten(edit.clips.map(function(clip) { - return pandora.getClipVideos(clip); - })), - width: getWidth() - }).appendTo(that); - - function getHeight() { - // 24 menu + 24 toolbar + 16 statusbar + 32 title + 32 margins - // + 1px to ge trid of scrollbar - return window.innerHeight - 128 -1; - } - - function getWidth() { - return window.innerWidth - - pandora.user.ui.showSidebar * pandora.user.ui.sidebarSize - 1; - } - - return that; -};