PageRenderTime 50ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/src/flash/com/longtailvideo/jwplayer/view/components/PlaylistComponent.as

https://github.com/delaet/jwplayer
ActionScript | 780 lines | 641 code | 106 blank | 33 comment | 120 complexity | 19a5a1d1f27ad83e5caddb8fdbacfe47 MD5 | raw file
Possible License(s): CC-BY-3.0
  1. // TODO: remove font
  2. package com.longtailvideo.jwplayer.view.components {
  3. import com.longtailvideo.jwplayer.events.PlayerStateEvent;
  4. import com.longtailvideo.jwplayer.events.PlaylistEvent;
  5. import com.longtailvideo.jwplayer.events.ViewEvent;
  6. import com.longtailvideo.jwplayer.model.Color;
  7. import com.longtailvideo.jwplayer.model.PlaylistItem;
  8. import com.longtailvideo.jwplayer.player.IPlayer;
  9. import com.longtailvideo.jwplayer.player.IInstreamPlayer;
  10. import com.longtailvideo.jwplayer.player.PlayerState;
  11. import com.longtailvideo.jwplayer.utils.Draw;
  12. import com.longtailvideo.jwplayer.utils.Logger;
  13. import com.longtailvideo.jwplayer.utils.RootReference;
  14. import com.longtailvideo.jwplayer.utils.Stacker;
  15. import com.longtailvideo.jwplayer.utils.Stretcher;
  16. import com.longtailvideo.jwplayer.view.PlayerLayoutManager;
  17. import com.longtailvideo.jwplayer.view.interfaces.IPlaylistComponent;
  18. import com.longtailvideo.jwplayer.view.interfaces.ISkin;
  19. import flash.accessibility.AccessibilityProperties;
  20. import flash.display.DisplayObject;
  21. import flash.display.DisplayObjectContainer;
  22. import flash.display.Loader;
  23. import flash.display.LoaderInfo;
  24. import flash.display.MovieClip;
  25. import flash.display.Sprite;
  26. import flash.events.Event;
  27. import flash.events.IOErrorEvent;
  28. import flash.events.MouseEvent;
  29. import flash.geom.Rectangle;
  30. import flash.net.URLRequest;
  31. import flash.system.LoaderContext;
  32. import flash.text.TextField;
  33. import flash.text.TextFormat;
  34. import flash.utils.Dictionary;
  35. import flash.utils.clearInterval;
  36. import flash.utils.setInterval;
  37. public class PlaylistComponent extends CoreComponent implements IPlaylistComponent {
  38. /** Array with all button instances **/
  39. private var buttons:Array;
  40. /** All of the dividers **/
  41. private var dividers:Vector.<DisplayObject>;
  42. /** Height of a button (to calculate scrolling) **/
  43. private var buttonheight:Number;
  44. /** Currently active button. **/
  45. private var active:Number;
  46. /** Proportion between clip and mask. **/
  47. private var proportion:Number;
  48. /** Interval ID for scrolling **/
  49. private var scrollInterval:Number;
  50. /** Image dimensions. **/
  51. private var image:Array;
  52. /** Visual representation of a the playlist **/
  53. private var list:Sprite;
  54. /** Visual representation of a playlist item **/
  55. private var button:Sprite;
  56. /** The playlist mask **/
  57. private var listmask:Sprite;
  58. /** The playlist slider **/
  59. private var slider:Sprite;
  60. /** The playlist background **/
  61. private var background:Sprite;
  62. private var clicksActive:Boolean = true;
  63. /** Internal reference to the skin **/
  64. private var skin:ISkin;
  65. private var skinLoaded:Boolean = false;
  66. private var pendingResize:Rectangle;
  67. private var pendingBuild:Boolean = false;
  68. /** Map of images and loaders **/
  69. private var imageLoaderMap:Dictionary;
  70. private var isBasic:Boolean = false;
  71. public function PlaylistComponent(player:IPlayer) {
  72. super(player, "playlist");
  73. this.tabEnabled = false;
  74. this.tabChildren = false;
  75. imageLoaderMap = new Dictionary();
  76. buttons = [];
  77. dividers = new Vector.<DisplayObject>;
  78. if (!(player is IInstreamPlayer)) {
  79. player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_ITEM, itemHandler);
  80. player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_LOADED, playlistHandler);
  81. player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_UPDATED, playlistHandler);
  82. player.addEventListener(PlayerStateEvent.JWPLAYER_PLAYER_STATE, stateHandler);
  83. }
  84. skinLoaded = true;
  85. skin = _player.skin;
  86. isBasic = (_player.config.playlistlayout == "basic");
  87. continueSetup();
  88. }
  89. protected function continueSetup(evt:Event=null):void {
  90. skinLoaded = true;
  91. background = new Sprite();
  92. background.graphics.beginFill(backgroundColor.color, 1);
  93. background.graphics.drawRect(0, 0, 1, 1);
  94. background.graphics.endFill();
  95. background.name = "background";
  96. addElement(background);
  97. slider = buildSlider();
  98. slider.buttonMode = true;
  99. slider.mouseChildren = false;
  100. slider.addEventListener(MouseEvent.MOUSE_DOWN, sdownHandler);
  101. slider.visible = false;
  102. addElement(slider);
  103. listmask = getSkinElement("masker") as Sprite;
  104. if (!listmask) {
  105. listmask = new Sprite();
  106. listmask.graphics.beginFill(0xff0000, 1);
  107. listmask.graphics.drawRect(0, 0, 1, 1);
  108. listmask.graphics.endFill();
  109. }
  110. addElement(listmask);
  111. list = getSkinElement("list") as Sprite;
  112. if (!list) {
  113. list = new Sprite();
  114. button = buildButton() as Sprite;
  115. addElement(button, list);
  116. } else {
  117. button = list.getChildByName("button") as Sprite;
  118. }
  119. buttonheight = button.height;
  120. button.visible = false;
  121. list.mask = listmask;
  122. list.addEventListener(MouseEvent.CLICK, clickHandler);
  123. list.addEventListener(MouseEvent.MOUSE_OVER, overHandler);
  124. list.addEventListener(MouseEvent.MOUSE_OUT, outHandler);
  125. addElement(list);
  126. list.addEventListener(MouseEvent.MOUSE_WHEEL, wheelHandler);
  127. slider.addEventListener(MouseEvent.MOUSE_WHEEL, wheelHandler);
  128. try {
  129. image = new Array(button.getChildByName("image").width, button.getChildByName("image").height);
  130. } catch (err:Error) {
  131. }
  132. if (pendingBuild) {
  133. buildPlaylist(true);
  134. }
  135. if (pendingResize) {
  136. resize(pendingResize.width, pendingResize.height);
  137. }
  138. }
  139. private function buildSlider():Sprite {
  140. var newSlider:Sprite = new Sprite();
  141. var sliderRail:Sprite = buildSliderElement('rail', '', newSlider);
  142. var sliderRailTop:Sprite = buildSliderElement('railtop', 'sliderRailCapTop', sliderRail);
  143. var sliderRailMiddle:Sprite = buildSliderElement('railmiddle', 'sliderRail', sliderRail);
  144. var sliderRailBottom:Sprite = buildSliderElement('railbottom', 'sliderRailCapBottom', sliderRail);
  145. sliderRailMiddle.y = sliderRailTop.height;
  146. var sliderThumb:Sprite = buildSliderElement('icon', '', newSlider);
  147. var sliderThumbCapTop:Sprite = buildSliderElement('thumbTop', 'sliderThumbCapTop', sliderThumb);
  148. var sliderThumbCapMiddle:Sprite = buildSliderElement('thumbMiddle', 'sliderThumb', sliderThumb);
  149. var sliderThumbCapBottom:Sprite = buildSliderElement('thumbBottom', 'sliderThumbCapBottom', sliderThumb);
  150. sliderThumbCapMiddle.y = sliderThumbCapTop.height;
  151. var sliderCapTop:Sprite = buildSliderElement('captop', 'sliderCapTop', newSlider);
  152. var sliderCapBottom:Sprite = buildSliderElement('capbottom', 'sliderCapBottom', newSlider);
  153. return newSlider;
  154. }
  155. private function buildSliderElement(name:String, skinElementName:String, parent:Sprite):Sprite {
  156. var newElement:Sprite = getSkinElement(skinElementName) as Sprite;
  157. if (!newElement) {
  158. newElement = new Sprite();
  159. }
  160. newElement.name = name;
  161. if (parent) {
  162. parent.addChild(newElement);
  163. }
  164. return newElement;
  165. }
  166. private function buildButton():MovieClip {
  167. var btn:MovieClip = new MovieClip();
  168. var backActive:Sprite = getSkinElement("itemActive") as Sprite;
  169. if (backActive) {
  170. backActive.name = "backActive";
  171. backActive.visible = false;
  172. if (isBasic) { backActive.height = 32; }
  173. else { backActive.height = 76; }
  174. addElement(backActive, btn, 0, 0);
  175. }
  176. var backOver:Sprite = getSkinElement("itemOver") as Sprite;
  177. if (backOver) {
  178. backOver.name = "backOver";
  179. backOver.visible = false;
  180. if (isBasic) { backOver.height = 32; }
  181. else { backOver.height = 76; }
  182. addElement(backOver, btn, 0, 0);
  183. }
  184. var back:Sprite = getSkinElement("item") as Sprite;
  185. if (!back) {
  186. back = new Sprite();
  187. back.graphics.beginFill(0, 1);
  188. back.graphics.drawRect(0, 0, 470, 100);
  189. back.graphics.endFill();
  190. }
  191. back.name = "back";
  192. if (isBasic) { back.height = 32; }
  193. else { back.height = 76; }
  194. addElement(back, btn, 0, 0);
  195. var img:MovieClip = new MovieClip;
  196. var imgBG:Sprite = getSkinElement("itemImage") as Sprite;
  197. var imageOffset:Number = 5;
  198. img.name = "image";
  199. img.graphics.beginFill(0, 0);
  200. if (imgBG) {
  201. imgBG.name = "imageBackground";
  202. img.addChild(imgBG);
  203. imgBG.x = imgBG.y = (back.height - imgBG.height) / 2;
  204. img.graphics.drawRect(0, 0, imgBG.width + 2 * imgBG.x, back.height);
  205. imageOffset = 0;
  206. img.graphics.endFill();
  207. img['stacker.noresize'] = true;
  208. if (!isBasic) {
  209. addElement(img, btn, 0, 0);
  210. }
  211. }
  212. var titleTextFormat:TextFormat = new TextFormat();
  213. titleTextFormat.size = titleSize;
  214. titleTextFormat.font = "_sans";
  215. titleTextFormat.bold = (titleWeight == "bold");
  216. titleTextFormat.color = titleColor.color;
  217. var title:TextField = new TextField();
  218. title.name = "title";
  219. title.defaultTextFormat = titleTextFormat;
  220. title.wordWrap = true;
  221. title.multiline = true;
  222. title.width = 335;
  223. title.height = 20;
  224. if (!isBasic) {
  225. addElement(title, btn, img.width + imageOffset, imgBG ? imgBG.x - 5 : 5);
  226. }
  227. else {
  228. addElement(title, btn, 10, 5);
  229. }
  230. var descriptionTextFormat:TextFormat = new TextFormat();
  231. descriptionTextFormat.size = fontSize;
  232. descriptionTextFormat.leading = 1;
  233. descriptionTextFormat.font = "_sans";
  234. descriptionTextFormat.bold = (fontWeight == "bold");
  235. var description:TextField = new TextField();
  236. description.name = "description";
  237. description.wordWrap = true;
  238. description.multiline = true;
  239. description.width = 335;
  240. description.height = Math.max(0, back.height - 30);
  241. descriptionTextFormat.leading = 6;
  242. description.defaultTextFormat = descriptionTextFormat;
  243. if (isBasic) { description.height = 0};
  244. if(back.height <= 40) {
  245. description.visible = false;
  246. }
  247. addElement(description, btn, img.width + imageOffset, 30);
  248. back.width = btn.width;
  249. if (backOver) backOver.width = btn.width;
  250. if (backActive) backActive.width = btn.width;
  251. return btn;
  252. }
  253. private function addElement(doc:DisplayObject, parent:DisplayObjectContainer = null, x:Number = 0, y:Number = 0):void {
  254. if (!parent) {
  255. parent = this;
  256. }
  257. doc.x = x;
  258. parent.addChild(doc);
  259. doc.y = y;
  260. }
  261. override protected function get backgroundColor():Color {
  262. return getColor("backgroundcolor", 0x333333);
  263. }
  264. override protected function get fontSize():Number {
  265. return getConfigParam("fontsize") ? Number(getConfigParam("fontsize")) : 11;
  266. }
  267. override protected function get fontColor():Color {
  268. return getColor("fontcolor", 0x999999);
  269. }
  270. private function get overColor():Color {
  271. return getColor("overcolor", 0xcccccc);
  272. }
  273. private function get activeColor():Color {
  274. return getColor("activecolor", 0xcccccc);
  275. }
  276. private function get titleSize():Number {
  277. return getConfigParam("titlesize") ? Number(getConfigParam("titlesize")) : 13;
  278. }
  279. private function get titleWeight():String {
  280. return getConfigParam("titleweight") ? String(getConfigParam("titleweight")).toLowerCase() : "normal";
  281. }
  282. private function get titleColor():Color {
  283. return getColor("titlecolor", 0xcccccc);
  284. }
  285. private function get titleOverColor():Color {
  286. return getColor("titleovercolor", 0xffffff);
  287. }
  288. private function get titleActiveColor():Color {
  289. return getColor("titleactivecolor", 0xffffff);
  290. }
  291. private function getColor(id:String, defaultVal:uint):Color {
  292. return new Color(getConfigParam(id) != null ? String(getConfigParam(id)) : defaultVal);
  293. }
  294. /** Handle a button rollover. **/
  295. private function overHandler(evt:MouseEvent):void {
  296. var idx:Number = Number(evt.target.name);
  297. var button:Sprite = getButton(idx);
  298. if (!button) return;
  299. TextField(button.getChildByName("title")).textColor = titleOverColor.color;
  300. TextField(button.getChildByName("description")).textColor = overColor.color;
  301. var overClip:DisplayObject = button.getChildByName("backOver");
  302. var outClip:DisplayObject = button.getChildByName("back");
  303. var activeClip:DisplayObject = button.getChildByName("backActive");
  304. if (overClip) {
  305. overClip.visible = true;
  306. outClip.visible = false;
  307. if (activeClip) activeClip.visible = false;
  308. }
  309. }
  310. /** Handle a button rollover. **/
  311. private function outHandler(evt:MouseEvent):void {
  312. var idx:Number = Number(evt.target.name);
  313. var button:Sprite = getButton(idx);
  314. if (!button) return;
  315. TextField(button.getChildByName("title")).textColor = idx == active ? titleActiveColor.color : titleColor.color;
  316. TextField(button.getChildByName("description")).textColor = idx == active ? activeColor.color : fontColor.color;
  317. var overClip:DisplayObject = button.getChildByName("backOver");
  318. var outClip:DisplayObject = button.getChildByName("back");
  319. var activeClip:DisplayObject = button.getChildByName("backActive");
  320. if (overClip) {
  321. overClip.visible = false;
  322. if (activeClip) {
  323. outClip.visible = (idx != active);
  324. activeClip.visible = (idx == active);
  325. } else {
  326. outClip.visible = true;
  327. }
  328. }
  329. }
  330. private function get _playlist():Array {
  331. var arr:Array = [];
  332. for (var i:Number = 0; i < _player.playlist.length; i++) {
  333. arr.push(_player.playlist.getItemAt(i));
  334. }
  335. return arr;
  336. }
  337. private function translateUIToModelPlaylistIndex(index:Number):Number{
  338. for (var i:Number = 0; i < _player.playlist.length; i++) {
  339. if (index == 0){
  340. return i;
  341. }
  342. index--;
  343. }
  344. return 0;
  345. }
  346. /** Setup all buttons in the playlist **/
  347. private function buildPlaylist(clr:Boolean):void {
  348. if (!skinLoaded) {
  349. pendingBuild = true;
  350. return;
  351. }
  352. var wid:Number = getConfigParam("width");
  353. var hei:Number = getConfigParam("height");
  354. listmask.height = hei;
  355. listmask.width = wid;
  356. proportion = _playlist.length * buttonheight / hei;
  357. if (proportion > 1.01) {
  358. wid -= slider.width;
  359. layoutSlider();
  360. } else {
  361. slider.visible = false;
  362. }
  363. if (clr) {
  364. list.y = listmask.y;
  365. for (var j:Number = 0; j < buttons.length; j++) {
  366. list.removeChild(getButton(j));
  367. }
  368. while(dividers.length > 0) {
  369. var divider:DisplayObject = dividers.pop();
  370. if (divider.parent == list) list.removeChild(divider);
  371. }
  372. buttons = [];
  373. imageLoaderMap = new Dictionary();
  374. } else {
  375. if (proportion > 1) {
  376. scrollEase();
  377. }
  378. }
  379. for (var i:Number = 0; i < _playlist.length; i++) {
  380. var div:DisplayObject;
  381. if (clr || buttons.length == 0) {
  382. var btn:MovieClip;
  383. btn = buildButton();
  384. if (i > 0) {
  385. div = getSkinElement("divider");
  386. if (div) {
  387. div.y = i * buttonheight + (i-1) * div.height;
  388. div.width = wid;
  389. list.addChild(div);
  390. dividers.push(div);
  391. }
  392. }
  393. list.addChild(btn);
  394. var stc:Stacker = new Stacker(btn);
  395. btn.y = i * (buttonheight + (div ? div.height : 0));
  396. btn.buttonMode = true;
  397. btn.mouseChildren = false;
  398. btn.tabChildren = false;
  399. btn.tabEnabled = false;
  400. btn.name = i.toString();
  401. buttons.push({c: btn, s: stc});
  402. setContents(i);
  403. }
  404. if (buttons[i]) {
  405. (buttons[i].s as Stacker).rearrange(wid);
  406. }
  407. }
  408. for each (div in dividers) {
  409. div.width = wid;
  410. }
  411. }
  412. /** Setup the scrollbar component **/
  413. private function layoutSlider():void {
  414. slider.visible = true;
  415. slider.x = getConfigParam("width") - slider.width;
  416. var capTop:DisplayObject = slider.getChildByName("captop");
  417. var capBottom:DisplayObject = slider.getChildByName("capbottom");
  418. var thumb:Sprite = slider.getChildByName("icon") as Sprite;
  419. var rail:Sprite = slider.getChildByName("rail") as Sprite;
  420. var height:Number = Number(getConfigParam("height"))
  421. var thumbTop:DisplayObject = thumb.getChildByName('thumbTop');
  422. var thumbMiddle:DisplayObject = thumb.getChildByName('thumbMiddle');
  423. var thumbBottom:DisplayObject = thumb.getChildByName('thumbBottom');
  424. var railTop:DisplayObject = rail.getChildByName('railtop');
  425. var railMiddle:DisplayObject = rail.getChildByName('railmiddle');
  426. var railBottom:DisplayObject = rail.getChildByName('railbottom');
  427. rail.y = capTop.height;
  428. thumb.y = capTop.height;
  429. railMiddle.height = height - capBottom.height - capTop.height - railTop.height - railBottom.height;
  430. railBottom.y = railMiddle.y + railMiddle.height;
  431. thumbMiddle.height = Math.round(rail.height / proportion) - thumbTop.height - thumbBottom.height;
  432. thumbBottom.y = thumbMiddle.y + thumbMiddle.height;
  433. capBottom.y = height - capBottom.height;
  434. }
  435. /** Make sure the playlist is not out of range. **/
  436. private function scrollEase(ips:Number = -1, cps:Number = -1):void {
  437. if (ips == 0 && cps == 0) {
  438. clearInterval(scrollInterval);
  439. }
  440. var thumb:DisplayObject = slider.getChildByName("icon");
  441. var rail:DisplayObject = slider.getChildByName("rail");
  442. if (ips != -1) {
  443. thumb.y = Math.min(Math.max(rail.y, Math.round(ips - (ips - thumb.y) / 1.5)), rail.y + rail.height - thumb.height);
  444. list.y = Math.max(Math.min(-listmask.y, Math.round((cps - (cps - list.y) / 1.5))), listmask.y + listmask.height - list.height);
  445. }
  446. }
  447. /** Scrolling handler. **/
  448. private function scrollHandler():void {
  449. var yps:Number = slider.mouseY - slider.getChildByName("rail").y;
  450. var ips:Number = yps - slider.getChildByName("icon").height / 2;
  451. var cps:Number = listmask.y + listmask.height / 2 - proportion * yps;
  452. scrollEase(ips, cps);
  453. }
  454. /** Setup button elements **/
  455. private function setContents(idx:Number):void {
  456. var playlistItem:PlaylistItem = _playlist[idx];
  457. var btn:Sprite = getButton(idx);
  458. var title:TextField = btn.getChildByName("title") as TextField;
  459. var description:TextField = btn.getChildByName("description") as TextField;
  460. if (playlistItem.image || playlistItem['playlist.image']) {
  461. var imageFile:String = playlistItem['playlist.image'] ? playlistItem['playlist.image'] : playlistItem.image;
  462. //if (getConfigParam('thumbs') != false && _player.config.playlistposition != 'none') {
  463. if (_player.config.playlistposition != 'none') {
  464. var img:Sprite = btn.getChildByName("image") as Sprite;
  465. if (img) {
  466. img.alpha = 0;
  467. var ldr:Loader = new Loader();
  468. imageLoaderMap[ldr] = idx;
  469. ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderHandler);
  470. ldr.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
  471. ldr.load(new URLRequest(imageFile), new LoaderContext(true));
  472. }
  473. }
  474. }
  475. try {
  476. var acs:AccessibilityProperties = new AccessibilityProperties();
  477. acs.name = playlistItem.title;
  478. acs.description = playlistItem.description;
  479. btn.accessibilityProperties = acs;
  480. if (description) {
  481. description.htmlText = playlistItem.description;
  482. }
  483. if (title) {
  484. title.htmlText = "<b>" + playlistItem.title + "</b>";
  485. }
  486. if (description) { description.textColor = fontColor.color; }
  487. } catch (e:Error) {
  488. }
  489. img = btn.getChildByName("image") as MovieClip;
  490. // if (img && (!(playlistItem.image || playlistItem['playlist.image']) || getConfigParam('thumbs') == false)) {
  491. if (img && (!(playlistItem.image || playlistItem['playlist.image']))) {
  492. if (!img.getChildByName("imageBackground")) {
  493. btn.getChildByName("image").visible = false;
  494. }
  495. }
  496. }
  497. /** Loading of image completed; resume loading **/
  498. private function loaderHandler(evt:Event):void {
  499. try {
  500. var ldr:Loader = (evt.target as LoaderInfo).loader;
  501. if (ldr in imageLoaderMap) {
  502. var button:Sprite = getButton(imageLoaderMap[ldr]);
  503. delete imageLoaderMap[ldr];
  504. var img:Sprite = button.getChildByName("image") as Sprite;
  505. var bg:Sprite = img.getChildByName("imageBackground") as Sprite;
  506. img.alpha = 1;
  507. var msk:DisplayObject;
  508. if (bg) {
  509. msk = getSkinElement('itemImage');
  510. msk.x = bg.x;
  511. msk.y = bg.y;
  512. msk.cacheAsBitmap = true;
  513. if (!isBasic) {
  514. button.addChild(msk);
  515. }
  516. ldr.x = bg.x;
  517. ldr.y = bg.y;
  518. } else if (!isBasic) {
  519. msk = Draw.rect(button, '0xFF0000', img.width, img.height, img.x, img.y);
  520. }
  521. if (!isBasic) {
  522. Draw.smooth(ldr);
  523. img.addChild(ldr);
  524. img.cacheAsBitmap = true;
  525. img.mask = msk;
  526. Stretcher.stretch(ldr, image[0], image[1], Stretcher.FILL);
  527. }
  528. }
  529. } catch (err:Error) {
  530. Logger.log('Error loading playlist image: '+err.message);
  531. }
  532. }
  533. /** Loading of image failed; hide image **/
  534. private function errorHandler(evt:Event):void {
  535. var ldr:Loader;
  536. try {
  537. ldr = (evt.target as LoaderInfo).loader;
  538. var button:Sprite = getButton(imageLoaderMap[ldr]);
  539. if (button) {
  540. var img:Sprite = button.getChildByName("image") as Sprite;
  541. if (!img.getChildByName("imageBackground")) {
  542. img.visible = false;
  543. }
  544. if (proportion > 1.01) {
  545. (buttons[imageLoaderMap[ldr]].s as Stacker).rearrange(getConfigParam("width")-slider.width);
  546. } else {
  547. (buttons[imageLoaderMap[ldr]].s as Stacker).rearrange(getConfigParam("width"));
  548. }
  549. }
  550. } catch (err:Error) {
  551. Logger.log('Error loading playlist image '+ ldr.contentLoaderInfo.url+': '+err.message);
  552. }
  553. }
  554. private function wheelHandler(evt:MouseEvent):void {
  555. clearInterval(scrollInterval);
  556. var rail:DisplayObject = slider.getChildByName("rail");
  557. var thumb:DisplayObject = slider.getChildByName("icon");
  558. var ips:Number = Math.max(0, thumb.y + evt.delta * -1.5) - 4;
  559. var cps:Number = ips / (rail.height - thumb.height) * (listmask.height - list.height);
  560. scrollEase(ips, cps);
  561. }
  562. /** Start scrolling the playlist on mousedown. **/
  563. private function sdownHandler(evt:MouseEvent):void {
  564. clearInterval(scrollInterval);
  565. RootReference.stage.addEventListener(MouseEvent.MOUSE_UP, supHandler);
  566. scrollHandler();
  567. scrollInterval = setInterval(scrollHandler, 50);
  568. }
  569. /** Stop scrolling the playlist on mouseout. **/
  570. private function supHandler(evt:MouseEvent):void {
  571. clearInterval(scrollInterval);
  572. RootReference.stage.removeEventListener(MouseEvent.MOUSE_UP, supHandler);
  573. }
  574. /** Handle a click on a button. **/
  575. private function clickHandler(evt:MouseEvent):void {
  576. if (clicksActive) {
  577. var itemNumber:Number = translateUIToModelPlaylistIndex(Number(evt.target.name));
  578. dispatchEvent(new ViewEvent(ViewEvent.JWPLAYER_VIEW_ITEM, itemNumber));
  579. _player.playlistItem(itemNumber);
  580. }
  581. }
  582. /** Process resizing requests **/
  583. override public function resize(width:Number, height:Number):void {
  584. if (skinLoaded) {
  585. setConfigParam("width", width);
  586. setConfigParam("height", height);
  587. background.width = width;
  588. background.height = height;
  589. buildPlaylist(false);
  590. if (PlayerLayoutManager.testPosition(getConfigParam('position'))) {
  591. visible = true;
  592. } else if (getConfigParam('position') == "over") {
  593. stateHandler();
  594. } else {
  595. visible = false;
  596. }
  597. if (visible && getConfigParam('visible') === false) {
  598. visible = false;
  599. }
  600. } else {
  601. pendingResize = new Rectangle(0,0,width,height);
  602. }
  603. }
  604. /** Switch the currently active item */
  605. protected function itemHandler(evt:PlaylistEvent = null):void {
  606. if (_playlist.length == 0) {
  607. return;
  608. }
  609. var idx:Number = _player.playlist.currentIndex;
  610. var button:Sprite = getButton(idx);
  611. if (!skinLoaded) return;
  612. clearInterval(scrollInterval);
  613. if (proportion > 1.01) {
  614. scrollInterval = setInterval(scrollEase, 50, idx * buttonheight / proportion, -idx * buttonheight + listmask.y);
  615. }
  616. TextField(button.getChildByName("title")).textColor = titleActiveColor.color;
  617. TextField(button.getChildByName("description")).textColor = activeColor.color;
  618. if (!isNaN(active)) {
  619. var activeButton:Sprite = getButton(active);
  620. TextField(activeButton.getChildByName("title")).textColor = titleColor.color;
  621. TextField(activeButton.getChildByName("description")).textColor = fontColor.color;
  622. var prevOver:DisplayObject = activeButton.getChildByName("backOver");
  623. var prevOut:DisplayObject = activeButton.getChildByName("back");
  624. var prevActive:DisplayObject = activeButton.getChildByName("backActive");
  625. prevOut.visible = true;
  626. if (prevOver) prevOver.visible = false;
  627. if (prevActive) prevActive.visible = false;
  628. }
  629. active = idx;
  630. var overClip:DisplayObject = button.getChildByName("backOver");
  631. var outClip:DisplayObject = button.getChildByName("back");
  632. var activeClip:DisplayObject = button.getChildByName("backActive");
  633. if (activeClip) {
  634. activeClip.visible = true;
  635. outClip.visible = false;
  636. if (overClip) overClip.visible = false;
  637. }
  638. }
  639. public function removeClickHandler():void {
  640. clicksActive = false;
  641. }
  642. public function addClickHandler():void {
  643. clicksActive = true;
  644. }
  645. /** New playlist loaded: rebuild the playclip. **/
  646. protected function playlistHandler(evt:PlaylistEvent = null):void {
  647. clearInterval(scrollInterval);
  648. active = undefined;
  649. buildPlaylist(true);
  650. if (background) {
  651. resize(background.width, background.height);
  652. }
  653. }
  654. /** Process state changes **/
  655. protected function stateHandler(evt:PlayerStateEvent = null):void {
  656. if (getConfigParam('position') == "over") {
  657. if (player.state == PlayerState.PLAYING || player.state == PlayerState.PAUSED || player.state == PlayerState.BUFFERING) {
  658. visible = false;
  659. } else {
  660. visible = true;
  661. }
  662. }
  663. }
  664. private function getButton(id:Number):Sprite {
  665. if (buttons[id]) {
  666. return buttons[id].c as Sprite;
  667. }
  668. return null;
  669. }
  670. protected override function getSkinElement(element:String):DisplayObject {
  671. return skin.getSkinElement(_name,element);
  672. }
  673. }
  674. }