r79560 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r79559‎ | r79560 | r79561 >
Date:04:58, 4 January 2011
Author:dale
Status:deferred
Tags:
Comment:
* stubs for sequencer clickable timeline gui
* some buffred seek cleanup and log clarity
Modified paths:
  • /branches/MwEmbedStandAlone/modules/MiroSubs/mw.MiroSubsConfig.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsSequence.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/Sequencer/css/mw.style.Sequencer.css (modified) (history)
  • /branches/MwEmbedStandAlone/modules/Sequencer/mw.Sequencer.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerTimeline.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/Sequencer/tools/mw.SequencerToolEditTemplate.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/Sequencer/tools/mw.SequencerToolLayout.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/Sequencer/tools/mw.SequencerTools.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/SmilPlayer/mw.EmbedPlayerSmil.js (modified) (history)
  • /branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBuffer.js (modified) (history)
  • /branches/MwEmbedStandAlone/mwEmbed.js (modified) (history)

Diff [purge]

Index: branches/MwEmbedStandAlone/mwEmbed.js
@@ -2623,16 +2623,17 @@
26242624 if( options['class'] ) {
26252625 $button.addClass( options['class'] );
26262626 }
2627 -
2628 -
 2627+
26292628 // return the button:
26302629 $button.append(
26312630 $j('<span />').addClass( 'ui-icon ui-icon-' + options.icon ),
26322631 $j('<span />').addClass( 'btnText' )
2633 - .text( options.text )
26342632 )
26352633 .buttonHover(); // add buttonHover binding;
2636 - if( !options.text ){
 2634+
 2635+ if( options.text ){
 2636+ $button.find('.btnText').text( options.text );
 2637+ } else {
26372638 $button.css('padding', '1em');
26382639 }
26392640 return $button;
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.EmbedPlayerSmil.js
@@ -86,7 +86,7 @@
8787 if( !hideLoader ){
8888 if( $j('#loadingSpinner_' + this.id ).length == 0 ){
8989 $j( this ).getAbsoluteOverlaySpinner()
90 - .attr('id', 'loadingSpinner_' + this.id )
 90+ .attr('id', 'loadingSpinner_' + this.id );
9191 }
9292 }
9393 // Start seek
@@ -122,7 +122,7 @@
123123 mw.log("EmbedPlayerSmil:: seek done");
124124 _this.seeking = false;
125125 _this.monitor();
126 - })
 126+ });
127127 },
128128
129129 /**
@@ -155,8 +155,8 @@
156156 var _this = this;
157157 mw.log(" EmbedPlayerSmil::play " + _this.smilPlayTime + ' to ' + playSegmentEndTime + ' pause time: ' + this.smilPauseTime );
158158
159 - // Update clock start time
160 - _this.clockStartTime = new Date().getTime()
 159+ // Update clock start time;
 160+ _this.clockStartTime = new Date().getTime();
161161
162162 // Update the interface
163163 this.parent_play();
@@ -203,7 +203,7 @@
204204 _this.smil.startBuffer();
205205 // Start up monitor:
206206 _this.monitor();
207 - })
 207+ });
208208 },
209209
210210 stop: function(){
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBuffer.js
@@ -4,7 +4,7 @@
55
66 mw.SmilBuffer = function( smilObject ){
77 return this.init( smilObject );
8 -}
 8+};
99
1010 mw.SmilBuffer.prototype = {
1111
@@ -42,7 +42,7 @@
4343 }
4444
4545 // Search for elements from the prevBufferPercent
46 - var bufferedStartTime = this.prevBufferPercent * _this.smil.getDuration()
 46+ var bufferedStartTime = this.prevBufferPercent * _this.smil.getDuration();
4747
4848 //mw.log("getBufferedPercent:: bufferedStartTime: " + bufferedStartTime );
4949
@@ -125,7 +125,7 @@
126126 // Start loading active assets
127127 _this.loadElement( smilElement );
128128 }
129 - })
 129+ });
130130 // Loop on loading until all elements are loaded
131131 setTimeout( function(){
132132 if( _this.getBufferedPercent() == 1 ){
@@ -231,7 +231,7 @@
232232 if( eventData.loaded && eventData.total ) {
233233 _this.mediaLoadedPercent[assetId] = eventData.loaded / eventData.total;
234234 }
235 - })
 235+ });
236236 }
237237
238238 // Set up reference to media object:
@@ -305,15 +305,17 @@
306306 mw.log("SmilBuffer::bufferedSeekRelativeTime:" + this.smil.getSmilElementPlayerID( smilElement ) + ' relativeTime: ' + relativeTime + ' absoluteTime:' + absoluteTime );
307307
308308 $j( smilElement ).data('activeSeek', true);
309 - var instanceCallback = function(){
310 - mw.log("SmilBuffer::bufferedSeekRelativeTime: DONE ");
 309+ var instanceCallback = function(){
311310 $j( smilElement ).data('activeSeek', false);
312311 callback();
313 - }
 312+ };
314313 switch( this.smil.getRefType( smilElement ) ){
315314 case 'video':
316 - case 'audio':
317 - this.mediaBufferSeek( smilElement, absoluteTime, instanceCallback );
 315+ case 'audio':
 316+ this.mediaBufferSeek( smilElement, absoluteTime, function(){
 317+ mw.log("SmilBuffer::bufferedSeekRelativeTime: callback time: " + absoluteTime + ' ready ');
 318+ instanceCallback();
 319+ });
318320 break;
319321 case 'img':
320322 this.loadImageCallback( smilElement, instanceCallback );
@@ -425,57 +427,67 @@
426428
427429 mw.log("SmilBuffer::mediaBufferSeek: " + assetId + ' ctime:' + media.currentTime + ' seekTime:' + seekTime );
428430 var mediaLoadedFlag = false;
429 - var mediaMetaLoaded = function(){
 431+ var mediaMetaLoaded = function(){
430432 mw.log("SmilBuffer::mediaBufferSeek: Bind against: " + $media.parent().attr('id') );
431433 // check if we need to issue a seek
432434 if( media.currentTime == seekTime ){
433435 mw.log("SmilBuffer::mediaBufferSeek: Already at target time:" + assetId + ' time:' + seekTime );
434 - callback();
 436+ if( callback )
 437+ callback();
435438 callback = null;
436439 return ;
437440 }
438441
439442 // Register the seeked callback ( throw away any timed out seek request )
440 - $media.unbind('seeked').bind('seeked', function(){
 443+ $media.unbind('seeked.smilBuffer').bind('seeked.smilBuffer', function(){
441444 mw.log("SmilBuffer::mediaBufferSeek: DONE for:" + assetId + ' time:' + media.currentTime );
442 - callback();
 445+
 446+ // TODO Would be great if browsers supported a mode to "stop" loading once we reach a given time
 447+
 448+ if( callback )
 449+ callback();
443450 callback = null;
444451 });
445 - $media.unbind('seeking').bind( 'seeking', function(){
 452+
 453+ $media.unbind('seeking.smilBuffer').bind( 'seeking.smilBuffer', function(){
446454 mw.log("SmilBuffer::mediaBufferSeek: SEEKING:" + assetId );
447 - // add a timeout re-try
 455+ media.pause();
 456+ // Add a timeout to seek request to try again
448457 setTimeout(function(){
449458 // if the callback has not been called retry:
450459 if( callback ){
451 - mw.log("SmilBuffer::mediaBufferSeek: SEEK TimeOut ( retry ) " + assetId );
 460+ mw.log("SmilBuffer::mediaBufferSeek:seeking TimeOut ( retry ) " + assetId );
452461 mediaMetaLoaded();
453462 } else{
454 - mw.log( "SmilBuffer::mediaBufferSeek: ct: " + media.currentTime + ' st:' + seekTime);
 463+ mw.log( "SmilBuffer::mediaBufferSeek:seeking OK currentTime: " + media.currentTime + ' seekTime:' + seekTime);
455464 }
456 - }, 1000 );
457 - })
458 - // issue a play ( makes seeks work more consistently )
 465+ }, 2000 );
 466+ });
 467+ // issue a play ( makes seeks work more consistently than just load )
459468 media.play();
460469 setTimeout(function(){
461 - mw.log("SmilBuffer::mediaBufferSeek: set: " + assetId + ' to: ' + seekTime);
 470+ mw.log("SmilBuffer::mediaBufferSeek: SET: " + assetId + ' to: ' + seekTime);
462471 // Issue the seek
463472 try{
464473 media.pause();
465474 media.currentTime = seekTime;
 475+ media.play();
466476 } catch ( e ){
467 - mw.log( 'Error: in SmilBuffer could not set currentTime' );
 477+ mw.log( 'Error: in SmilBuffer could not set currentTime for ' + assetId );
468478 }
469479 }, 10 ); // give the browser 10ms to make sure the video tag is " really ready "
470 - }
471 - mw.log("SmilBuffer::mediaBufferSeek: READY State: " + $media.attr('readyState') );
 480+ };
 481+ mw.log("SmilBuffer::mediaBufferSeek: " + assetId + " READY State: " + $media.attr('readyState') );
472482 // Read the video state: http://www.w3.org/TR/html5/video.html#dom-media-have_nothing
473483 if( $media.attr('readyState') === 0 ){ // HAVE_NOTHING
474484 // Check that we have metadata ( so we can issue the seek )
475 - $media.bind( 'loadedmetadata', function(){
476 - $media.unbind( 'loadedmetadata' );
 485+ $media.bind( 'loadedmetadata.smilBuffer', function(){
 486+ media.pause();
 487+ $media.unbind( 'loadedmetadata.smilBuffer' );
477488 mediaMetaLoaded();
478489 } );
479490 media.load();
 491+ media.play();
480492 }else {
481493 // Already have metadata directly issue the seek with callback
482494 mediaMetaLoaded();
@@ -544,4 +556,4 @@
545557 runSeekCallback();
546558 }
547559 }*/
548 -}
\ No newline at end of file
 560+};
Index: branches/MwEmbedStandAlone/modules/MiroSubs/mw.MiroSubsConfig.js
@@ -41,8 +41,8 @@
4242
4343 // Check both the user name and subtitles have been set:
4444 var isConfigReady = function(){
45 - if( _this.config.username
46 - &&
 45+ if( _this.config.username
 46+ &&
4747 _this.config.subtitles
4848 ){
4949 callback( _this.config );
@@ -90,8 +90,8 @@
9191 });
9292 }
9393 },
94 - /*
95 - * present a language selection dialog
 94+ /**
 95+ * Present a language selection dialog
9696 *
9797 * issue the callback with the selected language code.
9898 * @param {function} callback
@@ -125,13 +125,6 @@
126126 });
127127 },
128128
129 - /**
130 - * Present a dialog to get the target language
131 - */
132 - getTargetLanguageDialog: function( callback ){
133 -
134 - },
135 -
136129 getDefaultConfig: function(){
137130 var _this = this;
138131 return {
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.Sequencer.js
@@ -317,7 +317,7 @@
318318
319319 /* timeline container */
320320 'south__minSize' : 160,
321 - 'south__size' : 200,
 321+ 'south__size' : 220,
322322 'south__onresize' : function(){
323323 _this.getTimeline().resizeTimeline();
324324 }
Index: branches/MwEmbedStandAlone/modules/Sequencer/css/mw.style.Sequencer.css
@@ -9,11 +9,25 @@
1010 .mwe-sequencer .trackNameContainer{
1111 overflow:hidden;
1212 }
 13+.mwe-sequencer .trackNamesTools {
 14+ margin: 3px;
 15+ background-color: #CCC;
 16+}
 17+.mwe-sequencer .clickableTimeline{
 18+ background-color: #CCC;
 19+ position: relative;
 20+ cursor : crosshair;
 21+}
 22+
1323 .mwe-sequencer .clipTrackSetContainer{
1424 overflow-x: scroll;
1525 overflow-y: hidden !important;
1626 }
1727
 28+.mwe-sequencer .clipTrackSetContainer, .mwe-sequencer .trackNamesContainer{
 29+ padding-top:2px !important;;
 30+}
 31+
1832 .mwe-sequencer .clipTrackSet{
1933 background-color: #EEE;
2034 border: solid thin #999;
Index: branches/MwEmbedStandAlone/modules/Sequencer/tools/mw.SequencerToolLayout.js
@@ -50,16 +50,38 @@
5151 // Register the change for undo redo
5252 _this.sequencer.getActionsEdit().registerEdit();
5353 },
54 -
 54+ /**
 55+ * TODO should combine with onPanzoomChange above
 56+ */
5557 'onRotateChange': function( _this, smilElement ){
5658 var rotateVal = $j('#' +_this.getEditToolInputId( 'layout', 'rotate')).val();
 59+ // Update smil value:
 60+ $j(smilElement).attr( 'rotate', rotateVal );
 61+
 62+ // Update rotate display
 63+ _this.sequencer.getSmil()
 64+ .getLayout()
 65+ .rotateLayout(
 66+ smilElement
 67+ );
 68+
 69+ // Update the timeline clip display
 70+ var $thumbTraget = $j( '#' + _this.sequencer.getTimeline().getTimelineClipId( smilElement ) ).find('.thumbTraget');
 71+ _this.sequencer.getSmil()
 72+ .getLayout()
 73+ .rotateLayout(
 74+ smilElement,
 75+ $thumbTraget,
 76+ $thumbTraget.find('img').get(0)
 77+ );
 78+
5779 // Register the change for undo redo
5880 _this.sequencer.getActionsEdit().registerEdit();
5981 },
6082
6183 //Rest layout button? ( restores default position )
6284 // presently NOT CALLED.
63 - 'getRestLayoutBtn': function(){
 85+ 'getRestLayoutBtn': function( _this, smilElement ){
6486 $j.button({
6587 'icon' : 'arrow-4',
6688 'text' : gM( 'mwe-sequencer-tools-panzoomhelper-resetlayout' )
@@ -68,13 +90,7 @@
6991 .css('float', 'left')
7092 .hide()
7193 .click(function(){
72 - // Restore default SMIL setting
73 - _this.editableTypes['display'].update(
74 - _this,
75 - smilElement,
76 - 'panzoom',
77 - _this.editableAttributes['panzoom'].defaultValue
78 - );
 94+ // TODO: Restore default SMIL setting
7995 });
8096 },
8197 'getOrginalHelperCss': function( _this ){
@@ -286,7 +302,7 @@
287303 $playerUI.find('.layoutHelper').hide();
288304 }
289305
290 - $j(_this).bind('toolSelect', function(){
 306+ $j( _this ).bind('toolSelect.seqTools', function(){
291307 if( _this.getCurrentToolId() == 'layout'){
292308 $playerUI.find('.layoutHelper').fadeIn('fast');
293309 } else {
Index: branches/MwEmbedStandAlone/modules/Sequencer/tools/mw.SequencerToolEditTemplate.js
@@ -89,8 +89,6 @@
9090 .css('clear', 'both')
9191 );
9292 }
93 -
94 -
9593 });
9694 }
9795 }
Index: branches/MwEmbedStandAlone/modules/Sequencer/tools/mw.SequencerTools.js
@@ -43,7 +43,7 @@
4444 update: function( _this, smilElement, paramName, value){
4545 // Check if the param already exists
4646 $paramNode = $j( smilElement ).find( "[name='"+ paramName + "']" );
47 - if( $paramNode.length == 0){
 47+ if( $paramNode.length == 0 ){
4848 $j( smilElement ).append(
4949 $j('<param />').attr({
5050 'name': paramName,
@@ -225,7 +225,7 @@
226226 var _this = this;
227227
228228 // If tools are displayed update them
229 - if( this.sequencer.getEditToolTarget().find('.editToolsContainer').lenght ){
 229+ if( this.sequencer.getEditToolTarget().find('.editToolsContainer').length ){
230230 this.drawClipEditTools();
231231 };
232232
@@ -243,7 +243,7 @@
244244 },
245245 drawClipEditTools: function( smilElement, selectedToolId ){
246246 var _this = this;
247 -
 247+ mw.log( "SequencerTool:: drawClipEditTools:" + smilElement + ' :' + selectedToolId );
248248 // Update the current clip and tool :
249249 if( smilElement ){
250250 this.setCurrentsmilElement( smilElement );
@@ -275,14 +275,13 @@
276276 this.getCurrentsmilElement()
277277 )
278278 );
279 - mw.log( 'Adding ' + toolSet.length + ' tools for ' +
 279+ mw.log( 'SequencerTools::drawClipEditTools: Adding ' + toolSet.length + ' tools for ' +
280280 this.sequencer.getSmil().getRefType( this.getCurrentsmilElement() ) +
281281 ' current tool: ' + _this.getCurrentToolId()
282282 );
283 -
 283+
284284 var toolTabIndex = 0;
285285 $j.each( toolSet, function( inx, toolId ){
286 -
287286 var tool = _this.tools[ toolId ];
288287 if( _this.getCurrentToolId() == toolId){
289288 toolTabIndex = inx;
@@ -333,7 +332,7 @@
334333 .attr('id', 'editWidgets_' + editWidgetId)
335334 );
336335 // Draw the binded widget:
337 - _this.editWidgets[editWidgetId].draw(
 336+ _this.editWidgets[ editWidgetId ].draw(
338337 _this,
339338 $j( '#editWidgets_' + editWidgetId ),
340339 smilElement
@@ -343,17 +342,18 @@
344343 }
345344 }
346345 });
347 -
 346+
348347 // Add tab bindings
349348 $toolsContainer.tabs({
350349 select: function( event, ui ) {
351350 _this.setCurrentToolId( $j( ui.tab ).attr('href').replace('#tooltab_', '') );
352 - // trigger select tool event:
353 - $j( _this ).trigger( 'toolSelect' );
354351 },
355352 selected : toolTabIndex
356353 });
357354
 355+ // Update the selected tool
 356+ _this.setCurrentToolId( toolSet[ toolTabIndex ] );
 357+
358358 var $editActions = $j('<div />')
359359 .css({
360360 'position' : 'absolute',
@@ -391,6 +391,7 @@
392392 },
393393 setCurrentToolId: function( toolId ){
394394 this.currentToolId = toolId;
 395+ $j( this ).trigger( 'toolSelect' );
395396 },
396397
397398 getEditAction: function( smilElement, editActionId ){
@@ -410,7 +411,7 @@
411412 })
412413 .click( function(){
413414 return editAction.action( this, _this, smilElement );
414 - })
 415+ });
415416 return $actionButton;
416417 },
417418 /* get the editiable attribute input html */
@@ -458,7 +459,7 @@
459460 $j( this ).val()
460461 );
461462 }
462 - })
 463+ });
463464 },
464465 getInputBox: function( config ){
465466 var _this = this;
Index: branches/MwEmbedStandAlone/modules/Sequencer/actions/mw.SequencerActionsSequence.js
@@ -99,7 +99,6 @@
100100 .sequencerInput( _this.sequencer )
101101 );
102102 // XXX todo we should have an autocomplete on sequence name!
103 -
104103 var buttons = {};
105104 buttons[ gM('mwe-cancel') ] = function(){ $j( this ).dialog( 'cancel' ); };
106105
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerTimeline.js
@@ -14,12 +14,17 @@
1515 // Pointer to the track layout
1616 trackLayout: null,
1717
18 - //Default height width of timeline clip:
19 - timelineThumbSize: {
 18+ // Default height width and spacing timeline clip:
 19+ timelineThumbLayout: {
2020 'height': 90,
21 - 'width' : 120
 21+ 'width' : 120,
 22+ 'spacing': 14
2223 },
23 -
 24+
 25+ // The timeline layout mode
 26+ // Can be "clip" ( like iMovie ) or "time" ( like finalCut )
 27+ timelineMode: 'clip',
 28+
2429 // Store the max track length
2530 maxTrackLength: 0,
2631
@@ -31,6 +36,7 @@
3237 return this.sequencer.getContainer().find('.mwseq-timeline');
3338 },
3439
 40+
3541 /**
3642 * Get the timelineTracksContainer
3743 */
@@ -45,7 +51,7 @@
4652 .addClass( 'ui-layout-west trackNamesContainer'),
4753
4854 $j('<div />')
49 - .addClass( 'ui-layout-center clipTrackSetContainer')
 55+ .addClass( 'ui-layout-center clipTrackSetContainer')
5056 )
5157 .css( 'height', this.getTimelineContainerHeight() )
5258 );
@@ -58,58 +64,194 @@
5965 'west__maxSize' : 325
6066 } );
6167 }
 68+
6269 return this.getTimelineContainer().find( '.timelineTrackContainer');
6370 },
64 -
 71+ getTrackNamesContainer: function(){
 72+ return this.getTracksContainer().find('.trackNamesContainer');
 73+ },
 74+ getClipTrackSetContainer: function(){
 75+ return this.getTracksContainer().find('.clipTrackSetContainer');
 76+ },
6577 /**
6678 * Gets a clickable timeline
6779 */
6880 getClickableTimeline: function(){
69 - if( this.getTimelineContainer().find('.clickableTimeline').length == 0 ){
70 - this.getTimelineContainer().append(
71 - $j('<div />')
72 - .addClass('clickableTimeline')
 81+ if( this.getClipTrackSetContainer().find('.clickableTimeline').length == 0 ){
 82+ this.getClipTrackSetContainer().append(
 83+ $j('<ul />')
 84+ .addClass( 'clickableTimeline' )
7385 .css({
74 - 'width' : this.getTrackWidth( trackIndex )
 86+ 'height' : '16px',
 87+ 'width' : this.getLongestTrackWidth()
7588 })
7689 );
77 - }
78 - return this.getTimelineContainer().find('.clickableTimeline');
 90+ }
 91+ return this.getClipTrackSetContainer().find('.clickableTimeline');
7992 },
80 - drawClickableTimeline: function(){
81 - // Append the timeline to the clickable timeline:
82 - this.getClickableTimeline().append(
83 - // get the duration
 93+ drawTimelineTools: function(){
 94+ var _this = this;
 95+
 96+ // Some tool icons
 97+ this.getTrackNamesContainer().append(
 98+ this.getTrackNamesTools()
8499 );
85100
 101+ // Clickable timeline
86102 var updateClickableTimeline = function(){
87 - // update the clickable timeline
 103+ var timelineWidth = _this.getLongestTrackWidth();
 104+ _this.setupClickableTimeline( timelineWidth );
 105+ };
 106+ // Bind the update event to every time the duration is re-calculated
 107+ $j( this.sequencer.getEmbedPlayer() ).bind( 'durationchange', updateClickableTimeline );
 108+ updateClickableTimeline();
 109+ },
 110+
 111+ /**
 112+ * TrackNameTools ( should refactor into a new class ( once we have more interactive tools )
 113+ */
 114+ trackNamesTools:{
 115+ 'save': {
 116+ 'icon' : 'disk',
 117+ 'title' : gM('mwe-sequencer-menu-sequence-save-desc'),
 118+ 'action': function(_this ){
 119+ _this.sequencer.getActionsSequence().save();
 120+ }
88121 }
89 - // Bind the update event to every time the duration is re-calculated
90 - $j( this.sequencer.getEmbedPlayer() ).bind( 'durationchange', updateClickableTimeline )
91 - updateClickableTimeline();
 122+ },
 123+ getTrackNamesTools: function(){
 124+ var _this = this;
 125+ // For now just a save button:
 126+ var $trackTools = $j('<div />')
 127+ .addClass('trackNamesTools');
92128
 129+ $j.each(this.trackNamesTools, function(toolId, tool){
 130+ $trackTools.append(
 131+ $j.button({
 132+ 'icon': tool.icon
 133+ })
 134+ .attr('title', tool.title)
 135+ // Turn it into a mini-button
 136+ .css({
 137+ 'padding-top': 0,
 138+ 'padding-bottom': 0,
 139+ 'height' : 16
 140+ })
 141+ .click(function(){
 142+ tool.action( _this )
 143+ })
 144+ )
 145+ });
 146+
 147+ return $trackTools;
93148 },
94149
 150+ updateTimelinePlayMarker: function( playTime ){
 151+ var $timelinePlayMarker = _this.getClickableTimeline().find( '.timelinePlayMarker' );
 152+ },
 153+
 154+ timelineOffset2Time: function( pixleOffset ){
 155+ pixleOffset - 10 / ( _this.timelineThumbLayout.width + 14 )
 156+ },
 157+
 158+ setupClickableTimeline: function( timelineWidth ){
 159+ var _this = this;
 160+ var smil = this.sequencer.getSmil();
 161+ // Get the Get Clickable Timeline
 162+ var $clickTimeline = _this.getClickableTimeline().empty()
 163+ .css( 'width', timelineWidth );
 164+
 165+
 166+ // Setup click binding
 167+ $clickTimeline.click(function( event ){
 168+ var timelineOffset = event.pageX - $clickTimeline.offset().left;
 169+ // Get the mouse offset get which clip we are associated with
 170+ mw.log("clicked: " + timelineOffset );
 171+ _this.updateTimelinePlayMarker(
 172+ timelineOffset2Time( timelineOffset )
 173+ )
 174+ });
 175+
 176+ // Add TimelinePlayMarker
 177+ $clickTimeline.append(
 178+ $j('<div />')
 179+ .addClass('timelinePlayMarker')
 180+ .css({
 181+ 'height': this.getTimelineContainerHeight(),
 182+ 'left' : 10,
 183+ 'position' : 'absolute',
 184+ 'width' : 2,
 185+ 'z-index' : 2
 186+ })
 187+ .append(
 188+ $j('<span />')
 189+ .addClass( 'ui-icon ui-icon-triangle-1-s' )
 190+ .css({
 191+ 'position' : 'absolute',
 192+ 'left' : '-8px',
 193+ 'top' : '10px',
 194+ 'z-index' : 3
 195+ }),
 196+
 197+ $j('<div />')
 198+ .css({
 199+ 'position' : 'absolute',
 200+ 'top' : '10px',
 201+ 'height' : '100%',
 202+ 'width' : 2,
 203+ 'background-color' : '#AAF'
 204+ })
 205+ )
 206+ );
 207+
 208+ // For now base the timeline
 209+ if( this.timelineMode == 'clip' ){
 210+ // xxx TODO better support multiple tracks
 211+ var smilSequenceTracks = this.sequencer.getSmil().getBody().getSeqElements();
 212+
 213+ // Output a time for each clip ( right now just assume first track ( 0 )
 214+ var clipInx = 0;
 215+ var startOffset = 0;
 216+ smil.getBody().getRefElementsRecurse( smilSequenceTracks[0], startOffset, function( smilElement ){
 217+ mw.log(" offset:" + startOffset + ' clipDur: ' + smil.getBody().getClipDuration( smilElement ) + ' so:' + $j( smilElement ).data( 'startOffset' ) );
 218+ $j('<span />')
 219+ .css({
 220+ 'position': 'absolute',
 221+ 'border-left' : 'solid thin #999',
 222+ 'left' : 10 + ( _this.timelineThumbLayout.width + 14 ) * clipInx
 223+ })
 224+ .text(
 225+ mw.seconds2npt(
 226+ $j( smilElement ).data( 'startOffset' )
 227+ )
 228+ )
 229+ .appendTo( $clickTimeline );
 230+
 231+ clipInx++;
 232+ });
 233+ }
 234+ },
 235+
95236 resizeTimeline: function(){
96237 this.trackLayout.resizeAll();
97238 },
98239 getTimelineContainerHeight: function(){
99240 var _this = this;
100241 // Start with vertical space for one more track + timeline
101 - var timelineHeight = 60;
 242+ var timelineHeight = 80;
102243 var smilSequenceTracks = this.sequencer.getSmil().getBody().getSeqElements();
103244 $j.each(smilSequenceTracks, function( trackIndex, smilSequenceTrack ){
104 - timelineHeight+= _this.getSequenceTrackHeight( smilSequenceTrack )
105 - })
 245+ timelineHeight+= _this.getSequenceTrackHeight( smilSequenceTrack );
 246+ });
106247 return timelineHeight;
107248 },
 249+
108250 // xxx may need to refactor to store collapsed expanded state info
109251 getSequenceTrackHeight: function( smilSequenceTrack ){
110252 if( $j( smilSequenceTrack).attr('tracktype') == 'audio' ){
111 - return mw.getConfig( 'Sequencer.TimelineColapsedTrackSize')
 253+ return mw.getConfig( 'Sequencer.TimelineColapsedTrackSize');
112254 }else{
113 - return mw.getConfig( 'Sequencer.TimelineTrackHeight' )
 255+ return mw.getConfig( 'Sequencer.TimelineTrackHeight' );
114256 }
115257 },
116258 /*
@@ -140,8 +282,8 @@
141283 var _this = this;
142284
143285 // draw clickable timeline
 286+ _this.drawTimelineTools();
144287
145 -
146288 // xxx TODO better support multiple tracks :::
147289 var smilSequenceTracks = this.sequencer.getSmil().getBody().getSeqElements();
148290
@@ -155,7 +297,7 @@
156298 callback();
157299 }
158300 });
159 - })
 301+ });
160302 },
161303
162304 drawSequenceTrack: function( trackIndex, smilSequenceTrack, callback){
@@ -167,10 +309,10 @@
168310
169311 // Add sequence track name if not present
170312 var $clipTrackName = $j( '#' + this.getTrackNameInterfaceId( trackIndex ) );
171 - if( $clipTrackName.length == 0 ) {
172 - this.getTracksContainer().find('.trackNamesContainer').append(
 313+ if( $clipTrackName.length == 0 ) {
 314+ this.getTrackNamesContainer().append(
173315 this.getTrackNameInterface( trackIndex, smilSequenceTrack )
174 - )
 316+ );
175317 $clipTrackName = $j( '#' + this.getTrackNameInterfaceId( trackIndex ) );
176318 }
177319
@@ -182,20 +324,20 @@
183325 mw.seconds2npt(
184326 _this.sequencer.getSmil().getBody().getClipDuration( $j( smilSequenceTrack ) )
185327 )
186 - ).fadeIn( 'slow')
187 - })
188 - }
 328+ ).fadeIn( 'slow');
 329+ });
 330+ };
189331 // Bind the update event to every time the duration is re-calculated
190 - $j( this.sequencer.getEmbedPlayer() ).bind( 'durationchange', updateTrackDuration )
 332+ $j( this.sequencer.getEmbedPlayer() ).bind( 'durationchange', updateTrackDuration );
191333 updateTrackDuration();
192334
193335 // Add Sequence track container if not present
194 - var $clipTrackSet = $j( '#' + this.getTrackSetId( trackIndex ))
 336+ var $clipTrackSet = $j( '#' + this.getTrackSetId( trackIndex ));
195337 mw.log( "SequenceTimeline::drawSequenceTrack: id: " + $clipTrackSet.length );
196338 if( $clipTrackSet.length == 0 ) {
197 - this.getTracksContainer().find('.clipTrackSetContainer').append(
 339+ this.getClipTrackSetContainer().append(
198340 this.getClipTrackSet( trackIndex , smilSequenceTrack)
199 - )
 341+ );
200342 $clipTrackSet = $j( '#' + this.getTrackSetId( trackIndex ));
201343 }
202344 // Draw sequence track clips ( checks for dom updates to smilSequenceTrack )
@@ -226,7 +368,7 @@
227369 mw.log("SequncerTimeline:: drawTrackClips node type: " + $j(smilElement).get(0).nodeName.toLowerCase() );
228370 var reRenderThumbFlag = false;
229371 // Draw the node onto the timeline if the clip is not already there:
230 - var $timelineClip = $clipTrackSet.find( '#' + _this.getTimelineClipId( smilElement ) )
 372+ var $timelineClip = $clipTrackSet.find( '#' + _this.getTimelineClipId( smilElement ) );
231373 if( $timelineClip.length == 0 ){
232374 mw.log("SequencerTimeline::drawTrackClips: ADD: " + _this.getTimelineClipId( smilElement ) + ' to ' + $clipTrackSet.attr('id') );
233375 $timelineClip = _this.getTimelineClip( smilSequenceTrack, smilElement );
@@ -236,7 +378,7 @@
237379 if( $previusClip ){
238380 $previusClip.after(
239381 $timelineClip
240 - )
 382+ );
241383 } else {
242384 // Add to the start of the track set:
243385 $clipTrackSet.prepend(
@@ -280,7 +422,7 @@
281423 if( reOrderTimelineFlag ){
282424 // move every node in-order to the end.
283425 smil.getBody().getRefElementsRecurse( smilSequenceTrack, startOffset, function( $node ){
284 - var $timelineClip = $clipTrackSet.find('#' + _this.getTimelineClipId( $node ) )
 426+ var $timelineClip = $clipTrackSet.find('#' + _this.getTimelineClipId( $node ) );
285427 $timelineClip.appendTo( $clipTrackSet );
286428 });
287429 // Update the order for all clips
@@ -296,7 +438,7 @@
297439 var keyBindings = this.sequencer.getKeyBindings();
298440 $j( keyBindings ).bind('escape', function(){
299441 // If a clips are selected deselect
300 - var selectedClips = _this.getTimelineContainer().find( '.selectedClip' )
 442+ var selectedClips = _this.getTimelineContainer().find( '.selectedClip' );
301443 if( selectedClips.length ){
302444 selectedClips.removeClass( 'selectedClip' );
303445 return false;
@@ -342,13 +484,13 @@
343485 cursor: 'move',
344486 helper: function( event, helper ){
345487 // xxx might need some fixes for multi-track
346 - var $selected = _this.getTimelineContainer().find( '.selectedClip' )
 488+ var $selected = _this.getTimelineContainer().find( '.selectedClip' );
347489 if ( $selected.length === 0 || $selected.length == 1) {
348490 return $j( helper );
349491 }
350492 return $j('<ul />')
351493 .css({
352 - 'width' : (_this.timelineThumbSize.width + 16) * $selected.length
 494+ 'width' : (_this.timelineThumbLayout.width + 16) * $selected.length
353495 })
354496 .append( $selected.clone() );
355497 },
@@ -364,21 +506,22 @@
365507 _this.handleReorder( ui.item );
366508 }
367509 }
368 - })
 510+ });
369511 },
370512 // expand the track size by clip length + 1
371513 expandTrackSetSize: function ( trackIndex ){
372 - //mw.log("SequencerTimeline::expandTrackSetSize: " + this.timelineThumbSize.width + ' tcc: ' + trackClipCount + ' ::' + ( ( this.timelineThumbSize.width + 16) * (trackClipCount + 2) ) );
 514+ //mw.log("SequencerTimeline::expandTrackSetSize: " + this.timelineThumbLayout.width + ' tcc: ' + trackClipCount + ' ::' + ( ( this.timelineThumbLayout.width + 16) * (trackClipCount + 2) ) );
373515 this.getTracksContainer().find('.clipTrackSet').css({
374516 'width' : this.getTrackWidth( trackIndex, 2 ) + 'px'
375517 });
376518 },
 519+
377520 /**
378521 * Get the width of a given sequence track
379522 * @param {Number} trackIndex
380523 * the track to get the width for
381524 * @param {Number=} extraClips
382 - * Optional how many extra clips to
 525+ * Optional how many extra clips to give the width
383526 */
384527 getTrackWidth: function( trackIndex, extraClips ){
385528 if( !extraClips ){
@@ -386,12 +529,31 @@
387530 }
388531 // TOOD make this use the trackIndex
389532 var trackClipCount = this.getTimelineContainer().find( '.clipTrackSet' ).children().length;
390 - return ( (this.timelineThumbSize.width + 16) * (trackClipCount + extraClips ) )
 533+ return ( (this.timelineThumbLayout.width + 16) * (trackClipCount + extraClips ) );
391534 },
 535+
 536+ /**
 537+ * Get the longest track width
 538+ * @return
 539+ * @type number
 540+ */
 541+ getLongestTrackWidth: function(){
 542+ var _this = this;
 543+ var smilSequenceTracks = this.sequencer.getSmil().getBody().getSeqElements();
 544+ // Find the longest track:
 545+ var longestWidth = 0;
 546+ $j.each(smilSequenceTracks, function( trackIndex, smilSequenceTrack ){
 547+ var curTrackWidth = _this.getTrackWidth( trackIndex )
 548+ if( curTrackWidth > longestWidth )
 549+ longestWidth = curTrackWidth;
 550+ });
 551+ return longestWidth;
 552+ },
 553+
392554 restoreTrackSetSize: function ( trackIndex ){
393555 var trackClipCount = this.getTimelineContainer().find( '.clipTrackSet' ).children().length;
394556 this.getTracksContainer().find('.clipTrackSet').css({
395 - 'width' : ( ( this.timelineThumbSize.width + 16) * trackClipCount) + 'px'
 557+ 'width' : ( ( this.timelineThumbLayout.width + 16) * trackClipCount) + 'px'
396558 });
397559 },
398560 getTimelineClip: function( smilSequenceTrack, $node ){
@@ -410,12 +572,12 @@
411573 },
412574 // calls the edit interface passing in the selected clip:
413575 editClip: function( selectedClip ){
 576+ mw.log("SequencerTimeline::editClip" + $j( selectedClip ).data('smilId') );
414577 // commit any input changes
415578 $j( document.activeElement ).change();
416579
417 - var smil = this.sequencer.getSmil();
418 - // get the smil element for the edit tool:
419 - var smilElement = smil.$dom.find( '#' + $j( selectedClip ).data('smilId') );
 580+ // Get the smil element for the edit tool:
 581+ var smilElement = this.sequencer.getSmil().$dom.find( '#' + $j( selectedClip ).data('smilId') );
420582 this.sequencer.getTools().drawClipEditTools( smilElement );
421583 },
422584
@@ -491,11 +653,11 @@
492654 if( typeof clipIndex == 'undefined' || clipIndex >= $smilSequenceTrack.children().length ){
493655 $smilSequenceTrack.append(
494656 $j( smilElement ).get(0)
495 - )
 657+ );
496658 } else {
497659 $smilSequenceTrack.children().eq( clipIndex ).before(
498660 $j( smilElement ).get(0)
499 - )
 661+ );
500662 }
501663
502664 // Update the dom timeline
@@ -630,7 +792,7 @@
631793 // select all non-selected between max or min
632794 $target.find( '.timelineClip' ).each( function( inx, curClip) {
633795 if( inx > minOrder && inx < maxOrder ){
634 - $j(curClip).addClass( 'selectedClip')
 796+ $j(curClip).addClass( 'selectedClip');
635797 }
636798 });
637799 }
@@ -648,12 +810,12 @@
649811 $toolTarget.empty().append(
650812 gM( 'mwe-sequencer-no_selected_resource' ),
651813 $j('<div />').addClass('editToolsContainer')
652 - )
 814+ );
653815 } else if( $selectedClips.length > 1 ){
654816 $toolTarget.empty().append(
655817 gM( 'mwe-sequencer-error_edit_multiple' ),
656818 $j('<div />').addClass('editToolsContainer')
657 - )
 819+ );
658820 } else {
659821 // A single clip is selected edit that clip
660822 _this.editClip( clickClip );
@@ -717,7 +879,7 @@
718880 .buttonHover()
719881 .click( function(){
720882 _this.getTimelineContainer().find('.selectedClip').removeClass( 'selectedClip' );
721 - _this.editClip( $timelineClip )
 883+ _this.editClip( $timelineClip );
722884 $timelineClip.addClass( 'selectedClip' );
723885 // Seek to the edit clip
724886 _this.seekToStartOfClip( $timelineClip );
@@ -761,7 +923,7 @@
762924 if( smil.getRefType( smilElement ) == 'audio' ){
763925 smil.getLayout().drawSmilElementToTarget( smilElement, $thumbTarget, relativeTime, callback );
764926 } else {
765 - _this.drawClipThumbImage( $thumbTarget, smilElement, relativeTime, callback )
 927+ _this.drawClipThumbImage( $thumbTarget, smilElement, relativeTime, callback );
766928 }
767929 },
768930 /**
@@ -779,7 +941,7 @@
780942 'position' : 'absolute',
781943 'opacity' : '.9',
782944 'left': '0px',
783 - 'height': _this.timelineThumbSize.height
 945+ 'height': _this.timelineThumbLayout.height
784946 })
785947 .attr( 'src', smil.getAssetUrl( smilElement.attr('poster') ) )
786948 .load( function(){
@@ -812,7 +974,7 @@
813975 callback = null;
814976 }
815977 });
816 - })
 978+ });
817979 },
818980 /**
819981 * Gets an sequence track control interface
@@ -824,7 +986,7 @@
825987
826988 var $trackNameContainer = $j('<div />')
827989 .attr('id', this.getTrackNameInterfaceId( trackIndex ) )
828 - .addClass('trackNames ui-corner-all')
 990+ .addClass('trackNames ui-corner-all');
829991
830992 var $trackNameTitle =
831993 $j('<a />')
@@ -835,13 +997,13 @@
836998 $trackNameTitle.append(
837999 $j('<span />').addClass( 'ui-icon ui-icon-volume-on'),
8381000 $j('<span />').text( gM( 'mwe-sequencer-audio-track' ) )
839 - )
 1001+ );
8401002 } else {
8411003 // for now default to "video" tracktype
8421004 $trackNameTitle.append(
8431005 $j('<span />').addClass( 'ui-icon ui-icon-video'),
8441006 $j('<span />').text( gM( 'mwe-sequencer-video-track' ) )
845 - )
 1007+ );
8461008 }
8471009 // Set track name height
8481010 $trackNameContainer.css({
@@ -861,7 +1023,7 @@
8621024 ,
8631025 $j( '<span />').addClass('trackDuration')
8641026
865 - )
 1027+ );
8661028 // Wrap the track name in a box that matches the trackNames
8671029 return $trackNameContainer;
8681030 },
@@ -875,7 +1037,7 @@
8761038 }
8771039 return $j( smilSequenceTrack ).data('id');
8781040 }
879 -}
 1041+};
8801042
8811043
8821044 } )( window.mw );
\ No newline at end of file

Status & tagging log