1 /* 2 * Copyright © 2009 Apple Inc. All rights reserved. 3 */ 4 5 TKLyricsController.inherits = TKController; 6 TKLyricsController.synthetizes = ['currentSong', 'previousSongButton', 'nextSongButton']; 7 8 /** 9 * @class 10 * 11 * <p>A lyrics controller is designed to make it easy to flip through a collection of lyrics. This controller type automatically wires the left and 12 * right keys to navigate between songs, and the author should leverage the {@link TKController#scrollableElement} property to identify the container 13 * for the scrolling lyrics region. Loading of new song content should be done using the {@link #songDidChange} method.</p> 14 * 15 * @extends TKController 16 * @since TuneKit 1.0 17 * 18 * @param {Object} data A hash of properties to use as this object is initialized. 19 */ 20 function TKLyricsController (data) { 21 /** 22 * The number of songs that the controller will be flipping through. 23 * @type int 24 */ 25 this.numberOfSongs = 0; 26 this.defaultToFirstSong = false; 27 this._currentSong = null; 28 this._previousSongButton = null; 29 this._nextSongButton = null; 30 // 31 this.callSuper(data); 32 }; 33 34 /* ==================== View Processing ==================== */ 35 36 TKLyricsController.prototype.processView = function () { 37 this.callSuper(); 38 // restore properties that have not been set yet since construction 39 this.restoreProperty('previousSongButton'); 40 this.restoreProperty('nextSongButton'); 41 this.restoreProperty('currentSong'); 42 // default to first song 43 if (this.defaultToFirstSong && this._currentSong === null) { 44 this.currentSong = 0; 45 } 46 }; 47 48 /* ==================== Keyboard Navigation ==================== */ 49 50 TKLyricsController.prototype.wantsToHandleKey = function (key) { 51 return (key == KEYBOARD_LEFT || key == KEYBOARD_RIGHT) ? true : this.callSuper(key); 52 }; 53 54 TKLyricsController.prototype.keyWasPressed = function (key) { 55 // default action is move, so wire that up 56 TKSpatialNavigationManager.soundToPlay = SOUND_MOVED; 57 // left should go to the previous song 58 if (key == KEYBOARD_LEFT) { 59 this.goToPreviousSong(); 60 } 61 // right should go to the next song 62 else if (key == KEYBOARD_RIGHT) { 63 this.goToNextSong(); 64 } 65 // let the default behavior happen too 66 this.callSuper(key); 67 }; 68 69 /* ==================== Previous / Next Buttons ==================== */ 70 71 /** 72 * @name TKLyricsController.prototype 73 * @property {String} previousSongButton The CSS selector for the element acting as the trigger to navigate to the previous song. 74 */ 75 TKLyricsController.prototype.setPreviousSongButton = function (previousSongButton) { 76 if (previousSongButton === null || IS_APPLE_TV) { 77 return; 78 } 79 // forget old button 80 if (this._previousSongButton) { 81 this.removeNavigableElement(this._previousSongButton); 82 } 83 // process new one 84 if (previousSongButton !== null) { 85 this._previousSongButton = this.view.querySelector(previousSongButton); 86 if (this._previousSongButton !== null) { 87 this.addNavigableElement(this._previousSongButton); 88 } 89 } 90 }; 91 92 /** 93 * @name TKLyricsController.prototype 94 * @property {String} nextSongButton The CSS selector for the element acting as the trigger to navigate to the next song. 95 */ 96 TKLyricsController.prototype.setNextSongButton = function (nextSongButton) { 97 if (nextSongButton === null || IS_APPLE_TV) { 98 return; 99 } 100 // forget old button 101 if (this._nextSongButton) { 102 this.removeNavigableElement(this._nextSongButton); 103 } 104 // process new one 105 if (nextSongButton !== null) { 106 this._nextSongButton = this.view.querySelector(nextSongButton); 107 if (this._nextSongButton !== null) { 108 this.addNavigableElement(this._nextSongButton); 109 } 110 } 111 }; 112 113 TKLyricsController.prototype.elementWasActivated = function (element) { 114 // previous page button pressed 115 if (element === this._previousSongButton) { 116 this.goToPreviousSong(); 117 } 118 // next page button pressed 119 else if (element === this._nextSongButton) { 120 this.goToNextSong(); 121 } 122 // fall back to default behavior 123 else { 124 this.callSuper(element); 125 } 126 }; 127 128 /* ==================== Page Navigation ==================== */ 129 130 /** 131 * Shows the previous song. 132 */ 133 TKLyricsController.prototype.goToPreviousSong = function () { 134 this.currentSong = ((this._currentSong + this.numberOfSongs) - 1) % this.numberOfSongs; 135 }; 136 137 /** 138 * Shows the next song. 139 */ 140 TKLyricsController.prototype.goToNextSong = function () { 141 this.currentSong = (this._currentSong + 1) % this.numberOfSongs; 142 }; 143 144 /** 145 * @name TKLyricsController.prototype 146 * @property {int} currentSong The index of the current song. Whenever this value changes, the {@link #songDidChange} method is called. 147 */ 148 TKLyricsController.prototype.setCurrentSong = function (song) { 149 if (song === null || song < 0 || song >= this.numberOfSongs) { 150 return; 151 } 152 // track what song we're on 153 this._currentSong = song; 154 // let our instance know that we've moved to a new song 155 this.songDidChange(song); 156 }; 157 158 /** 159 * Triggered when a new song is displayed by the controller. 160 */ 161 TKLyricsController.prototype.songDidChange = function (song) {}; 162 163 /* ==================== Archival ==================== */ 164 165 TKLyricsController.prototype.archive = function () { 166 var archive = this.callSuper(); 167 archive.currentSong = this.currentSong; 168 return archive; 169 }; 170 171 TKClass(TKLyricsController); 172