From 61c3027ee0d256cfc9859ae424c3748896b422e1 Mon Sep 17 00:00:00 2001 From: rlx <0x0073@0x2620.org> Date: Thu, 22 Dec 2011 12:40:01 +0000 Subject: [PATCH] add settings control to video player --- source/Ox.UI/js/Video/Ox.VideoPlayer.js | 225 ++++++++++++++---------- 1 file changed, 135 insertions(+), 90 deletions(-) diff --git a/source/Ox.UI/js/Video/Ox.VideoPlayer.js b/source/Ox.UI/js/Video/Ox.VideoPlayer.js index 4e08efd4..78d9ad59 100644 --- a/source/Ox.UI/js/Video/Ox.VideoPlayer.js +++ b/source/Ox.UI/js/Video/Ox.VideoPlayer.js @@ -14,9 +14,9 @@ Ox.VideoPlayer Generic Video Player text Text censored Array of censored ranges controlsBottom <[s]|[]> Bottom controls, from left to right - Can be 'fullscreen', 'scale', 'title', 'find', 'menu', 'play', 'playInToOut', - 'previous', 'next', 'mute', 'volume', 'size', 'timeline', 'space', - 'position', 'resolution', 'settings'. The 'space' control is just + Can be 'close', fullscreen', 'scale', 'title', 'find', 'menu', + 'play', 'playInToOut', 'previous', 'next', 'mute', 'volume', 'size', + 'timeline', 'space', 'position', 'settings'. The 'space' control is empty space that separates left-aligned from right-aligned controls. controlsTop <[s]|[]> Top controls, from left to right duration Duration (sec) @@ -84,11 +84,13 @@ Ox.VideoPlayer = function(options, self) { controlsBottom: [], controlsTop: [], duration: 0, + enableDownload: false, enableFind: false, enableFullscreen: false, enableKeyboard: false, enableMouse: false, enablePosition: false, + enableSubtitles: false, enableTimeline: false, externalControls: false, find: '', @@ -474,7 +476,7 @@ Ox.VideoPlayer = function(options, self) { ---------------------------------------------------------------------------- */ - if (self.options.subtitles.length || true) { // fixme + if (self.options.subtitles.length || true) { // FIXME self.$subtitle = $('
') .addClass('OxSubtitle') .appendTo(self.$videoContainer); @@ -538,7 +540,7 @@ Ox.VideoPlayer = function(options, self) { style: 'symbol', tooltip: ['Enter Fullscreen', 'Exit Fullscreen'], type: 'image', - value: self.options.fullscreen ? 'shrink' : 'grow' + value: self.options.fullscreen ? 'shrink' : 'grow', values: ['grow', 'shrink'] }) .bindEvent({ @@ -696,70 +698,6 @@ Ox.VideoPlayer = function(options, self) { }) .appendTo(self['$controls' + titleCase]); - } else if (control == 'resolution') { - - self.$resolutionButton = Ox.Element({ - tooltip: 'Resolution' - }) - .addClass('OxResolutionButton') - .html(self.options.resolution + 'p') - .bind({ - click: function() { - self.$resolution.toggle(); - } - }) - .appendTo(self['$controls' + titleCase]); - - self.$resolution = $('
') - .addClass('OxResolution') - .css({ - height: (self.resolutions.length * 16) + 'px' - }) - .bind({ - click: function(e) { - var resolution = $(e.target).parent().data('resolution'); - self.$resolution.hide(); - if (resolution != self.options.resolution) { - self.$resolution.children().each(function() { - var $this = $(this); - $this.children()[1].src = - $this.data('resolution') == resolution - ? Ox.UI.getImageURL('symbolCheck') - : Ox.UI.PATH + 'png/transparent.png' - }); - self.$resolutionButton.html(resolution + 'p'); - self.options.resolution = resolution - setResolution(); - } - } - }) - .appendTo(that.$element); - self.resolutions.forEach(function(resolution, i) { - var $item = $('
') - .data({ - resolution: resolution - }) - .bind({ - mouseenter: function() { - $(this).addClass('OxSelected'); - }, - mouseleave: function() { - $(this).removeClass('OxSelected'); - } - }) - .appendTo(self.$resolution); - $('
') - .html(resolution + 'p') - .appendTo($item); - $('') - .attr({ - src: resolution == self.options.resolution ? - Ox.UI.getImageURL('symbolCheck', 'modern') : - Ox.UI.PATH + 'png/transparent.png' - }) - .appendTo($item); - }); - } else if (control == 'scale') { self.$scaleButton = Ox.Button({ @@ -769,7 +707,7 @@ Ox.VideoPlayer = function(options, self) { value: self.options.scaleToFill ? 'fit' : 'fill', values: ['fill', 'fit'] }) - .bindEvent('click', function() { + .bindEvent('change', function() { toggleScale('button'); }) .appendTo(self['$controls' + titleCase]); @@ -787,6 +725,23 @@ Ox.VideoPlayer = function(options, self) { }) .appendTo(self['$controls' + titleCase]); + } else if (control == 'settings') { + + self.$settingsButton = Ox.Button({ + style: 'symbol', + title: 'set', + tooltip: 'Settings', + type: 'image' + }) + .bindEvent({ + click: function() { + self.$settings.toggle(); + } + }) + .appendTo(self['$controls' + titleCase]); + + self.$settings = renderSettings().appendTo(that.$element); + } else if (control == 'size') { self.$sizeButton = Ox.Button({ @@ -796,7 +751,7 @@ Ox.VideoPlayer = function(options, self) { value: self.options.sizeIsLarge ? 'shrink' : 'grow', values: ['grow', 'shrink'] }) - .bindEvent('click', toggleSize) + .bindEvent('change', toggleSize) .appendTo(self['$controls' + titleCase]); } else if (control == 'space') { @@ -993,7 +948,7 @@ Ox.VideoPlayer = function(options, self) { self.$muteButton = Ox.Button({ style: 'symbol', tooltip: ['Mute', 'Unmute'], - type: 'image' + type: 'image', value: self.options.muted ? 'unmute' : 'mute', values: ['mute', 'unmute'] }) @@ -1313,7 +1268,7 @@ Ox.VideoPlayer = function(options, self) { function getSubtitle() { var subtitle = ''; - Ox.forEach(self.options.subtitles, function(v) { + self.options.enableSubtitles && Ox.forEach(self.options.subtitles, function(v) { if ( v['in'] <= self.options.position && v.out >= self.options.position @@ -1384,8 +1339,7 @@ Ox.VideoPlayer = function(options, self) { self.options.controlsBottom.reduce(function(prev, curr) { return prev + ( curr == 'timeline' || curr == 'space' ? 0 : - curr == 'position' ? self.positionWidth : - curr == 'resolution' ? 36 : 16 + curr == 'position' ? self.positionWidth : 16 ); }, 0); } @@ -1471,7 +1425,7 @@ Ox.VideoPlayer = function(options, self) { } function hideControlMenus() { - ['find', 'volume', 'resolution'].forEach(function(element) { + ['find', 'settings', 'volume'].forEach(function(element) { var $element = self['$' + element]; $element && $element.is(':visible') && $element.animate({ opacity: 0 @@ -1698,6 +1652,99 @@ Ox.VideoPlayer = function(options, self) { }); } + function renderSettings() { + var $settings = $('
') + .addClass('OxSettings') + .bind({ + click: function(e) { + var $target = $(e.target), resolution, title; + self.$settings.hide(); + if (!$target.is('.OxLine') && !$target.is('.OxSpace')) { + title = $(e.target).parent().children()[0].innerHTML; + if (title == 'Download') { + that.triggerEvent('download'); + } else if (title == 'Subtitles') { + self.options.enableSubtitles = !self.options.enableSubtitles; + setSubtitle(); + that.triggerEvent('subtitles', { + subtitles: self.options.enableSubtitles + }); + } else { + resolution = parseInt(title); + if (resolution != self.options.resolution) { + self.options.resolution = resolution; + setResolution(); + } + } + self.$settings.children('.OxItem').each(function() { + var children = $(this).children(), + title = children[0].innerHTML, + checked = ( + title == 'Subtitles' + && self.options.enableSubtitles + ) || ( + Ox.last(title) == 'p' + && parseInt(title) == self.options.resolution + ); + $(children[1]).attr({ + src: Ox.UI.getImageURL( + 'symbol' + (checked ? 'Check' : 'None') + ) + }); + }); + } + } + }), + items = Ox.merge( + self.resolutions.map(function(resolution) { + return { + checked: resolution == self.options.resolution, + title: resolution + 'p' + } + }), + self.options.subtitles + ? [{}, { + checked: self.options.enableSubtitles, + title: 'Subtitles' + }] + : [], + self.options.enableDownload + ? [{}, {title: 'Download'}] + : [] + ), + height = 0; + items.forEach(function(item) { + var $item; + if (item.title) { + $item = $('
') + .addClass('OxItem') + .bind({ + mouseenter: function() { + $(this).addClass('OxSelected'); + }, + mouseleave: function() { + $(this).removeClass('OxSelected'); + } + }) + .appendTo($settings); + $('
').html(item.title).appendTo($item); + $('').attr({ + src: Ox.UI.getImageURL( + 'symbol' + (item.checked ? 'Check' : 'None') + ) + }).appendTo($item); + height += 16; + } else { + $('
').addClass('OxSpace').appendTo($settings); + $('
').addClass('OxLine').appendTo($settings); + $('
').addClass('OxSpace').appendTo($settings); + height += 1 + } + }); + $settings.css({height: height + 'px'}); + return $settings; + } + function rewind() { setTimeout(function() { setPosition(self.options.playInToOut ? self.options['in'] : 0); @@ -1754,7 +1801,7 @@ Ox.VideoPlayer = function(options, self) { */ self.options.paused && self.options.showMarkers && setMarkers(); self.options.censored.length && setCensored(); - self.$subtitle && setSubtitle(); + self.options.enableSubtitles && self.$subtitle && setSubtitle(); self.$position && self.$position.html(formatPosition()); if (self.options.type == 'play') { if (self.loadedMetadata && from != 'video') { @@ -1880,10 +1927,11 @@ Ox.VideoPlayer = function(options, self) { function setSubtitleText() { //Ox.Log('Video', 'setSubTx', self.subtitle, self.options.find) self.$subtitle.html( - self.subtitle ? - Ox.highlight(self.subtitle, self.options.find, 'OxHighlight') - .replace(/\n/g, '
') : ' 
 ' - // FIXME: weird bug, only in fullscreen, only in chrome + self.subtitle + ? Ox.highlight(self.subtitle, self.options.find, 'OxHighlight') + .replace(/\n/g, '
') + : ' 
 ' + // FIXME: weird bug, only in fullscreen, only in chrome ); //Ox.Log('Video', '?!?', self.$subtitle.css('bottom'), self.$subtitle.height()) } @@ -1937,15 +1985,12 @@ Ox.VideoPlayer = function(options, self) { self.$controlsBottom && self.$controlsBottom.animate({ opacity: 1 }, 250); - self.$find && self.$find.is(':visible') && self.$find.animate({ - opacity: 1 - }, 250); - self.$volume && self.$volume.is(':visible') && self.$volume.animate({ - opacity: 1 - }, 250); - self.$resolution && self.$resolution.is(':visible') && self.$resolution.animate({ - opacity: 1 - }, 250); + ['find', 'settings', 'volume'].forEach(function(element) { + var $element = self['$' + element]; + $element && $element.is(':visible') && $element.animate({ + opacity: 1 + }, 250); + }); self.$logo && self.$logo.animate({ top: getCSS('logo').top, opacity: 0.5