Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilTransitions.js |
— | — | @@ -111,7 +111,7 @@ |
112 | 112 | // Run the transitionFunctionMap update: |
113 | 113 | this.transitionFunctionMap[ $transition.attr('type') ] |
114 | 114 | [ $transition.attr( 'subtype' ) ] |
115 | | - (this, percent, $transition, smilElement ) |
| 115 | + (this, percent, $transition, smilElement ) |
116 | 116 | }, |
117 | 117 | |
118 | 118 | /** |
— | — | @@ -139,11 +139,13 @@ |
140 | 140 | $j('<div />') |
141 | 141 | .attr('id', transitionOverlayId) |
142 | 142 | .addClass( 'smilFillWindow' ) |
143 | | - .addClass( 'smilTransitionOverlay' ) |
144 | | - .css( 'background-color', $transition.attr( 'fadeColor')) |
| 143 | + .addClass( 'smilTransitionOverlay' ) |
145 | 144 | ); |
146 | 145 | mw.log('fadeFromColor:: added: ' + transitionOverlayId); |
147 | 146 | } |
| 147 | + //mw.log(' SET COLOR:: ' + $transition.attr( 'fadeColor') ); |
| 148 | + // Update the color: |
| 149 | + $j( '#' + transitionOverlayId ).css( 'background-color', $transition.attr( 'fadeColor')) |
148 | 150 | |
149 | 151 | // Invert the percentage since we setting opacity from full color we are fading from |
150 | 152 | percent = 1 - percent; |
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.EmbedPlayerSmil.js |
— | — | @@ -143,6 +143,7 @@ |
144 | 144 | } |
145 | 145 | return this.$renderTarget; |
146 | 146 | }, |
| 147 | + |
147 | 148 | /** |
148 | 149 | * Smil play function |
149 | 150 | * @param {float=} playSegmentEndTime Optional duration to be played before pausing playback |
Index: branches/MwEmbedStandAlone/modules/SmilPlayer/mw.SmilBuffer.js |
— | — | @@ -129,7 +129,7 @@ |
130 | 130 | // Loop on loading until all elements are loaded |
131 | 131 | setTimeout( function(){ |
132 | 132 | if( _this.getBufferedPercent() == 1 ){ |
133 | | - mw.log( "smilBuffer::continueBufferLoad:: done loading buffer for " + bufferTime); |
| 133 | + //mw.log( "smilBuffer::continueBufferLoad:: done loading buffer for " + bufferTime); |
134 | 134 | return ; |
135 | 135 | } |
136 | 136 | // get the percentage buffered, translated into buffer time and call continueBufferLoad with a timeout |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerTools.js |
— | — | @@ -1,1248 +0,0 @@ |
2 | | -/** |
3 | | - * Handles the "tools" window top level component driver |
4 | | - */ |
5 | | - |
6 | | -// Wrap in mw closure to avoid global leakage |
7 | | -( function( mw ) { |
8 | | - |
9 | | -mw.SequencerTools = function( sequencer ) { |
10 | | - return this.init( sequencer ); |
11 | | -}; |
12 | | - |
13 | | -// Set up the mvSequencer object |
14 | | -mw.SequencerTools.prototype = { |
15 | | - init: function( sequencer ){ |
16 | | - this.sequencer = sequencer; |
17 | | - }, |
18 | | - |
19 | | - // The current smil clip ( lazy init ) |
20 | | - currentsmilElement: null, |
21 | | - |
22 | | - // The current selected tool ( lazy init ) |
23 | | - currentToolId: null, |
24 | | - |
25 | | - // JSON tools config |
26 | | - tools:{ |
27 | | - 'trim':{ |
28 | | - 'editWidgets' : [ 'trimTimeline' ], |
29 | | - 'editableAttributes' : ['clipBegin','dur' ], |
30 | | - 'contentTypes': ['video', 'audio'] |
31 | | - }, |
32 | | - 'duration':{ |
33 | | - 'editableAttributes' : [ 'dur' ], |
34 | | - 'contentTypes': ['img', 'cdata_html', 'mwtemplate'] |
35 | | - }, |
36 | | - 'panzoom' : { |
37 | | - 'editWidgets' : ['panzoom'], |
38 | | - 'editableAttributes' : [ 'panZoom' ], |
39 | | - 'contentTypes': [ 'img'], // xxx todo add video support |
40 | | - 'supportsKeyFrames' : 'true' |
41 | | - }, |
42 | | - 'templateedit' : { |
43 | | - 'editWidgets' : ['editTemplate'], |
44 | | - 'editableAttributes' : [ 'apititlekey' ], |
45 | | - 'contentTypes' : ['mwtemplate'] |
46 | | - }, |
47 | | - 'transitions' : { |
48 | | - 'editWidgets' : ['editTransitions'], |
49 | | - 'contentTypes': ['video', 'img', 'mwtemplate' ] |
50 | | - } |
51 | | - }, |
52 | | - editableAttributes:{ |
53 | | - 'clipBegin':{ |
54 | | - 'type': 'time', |
55 | | - 'title' : gM('mwe-sequencer-start-time' ) |
56 | | - }, |
57 | | - 'dur' :{ |
58 | | - 'type': 'time', |
59 | | - 'title' : gM('mwe-sequencer-clip-duration' ) |
60 | | - }, |
61 | | - 'panZoom' :{ |
62 | | - 'type' : 'string', |
63 | | - 'inputSize' : 15, |
64 | | - 'title' : gM('mwe-sequencer-clip-panzoom' ), |
65 | | - 'defaultValue' : '0%, 0%, 100%, 100%' |
66 | | - }, |
67 | | - 'apititlekey' : { |
68 | | - 'type' : 'string', |
69 | | - 'inputSize' : 30, |
70 | | - 'title' : gM('mwe-sequencer-template-name' ) |
71 | | - }, |
72 | | - // Special child node type |
73 | | - 'param' : { |
74 | | - 'type' : 'childParam', |
75 | | - 'inputSize' : 30 |
76 | | - } |
77 | | - }, |
78 | | - editableTypes: { |
79 | | - 'childParam': { |
80 | | - update: function( _this, smilElement, paramName, value){ |
81 | | - // Check if the param already exists |
82 | | - $paramNode = $j( smilElement ).find( "[name='"+ paramName + "']" ); |
83 | | - if( $paramNode.length == 0){ |
84 | | - $j( smilElement ).append( |
85 | | - $j('<param />').attr({ |
86 | | - 'name': paramName, |
87 | | - 'value' : value |
88 | | - }) |
89 | | - ) |
90 | | - } else { |
91 | | - // Update the param value |
92 | | - $paramNode.attr( 'value', value); |
93 | | - } |
94 | | - mw.log("editableTypes::Should have updated smilElement param: " + paramName |
95 | | - + ' to : ' + $j( smilElement ).find( "[name='"+ paramName + '"]' ).attr( 'value') ); |
96 | | - }, |
97 | | - getSmilVal: function( _this, smilElement, paramName ){ |
98 | | - $paramNode = $j( smilElement ).find( "[name='"+ paramName + "']" ); |
99 | | - if( $paramNode.length == 0){ |
100 | | - return ''; |
101 | | - } |
102 | | - return $paramNode.attr('value'); |
103 | | - } |
104 | | - }, |
105 | | - 'string': { |
106 | | - update: function( _this, smilElement, attributeName, value){ |
107 | | - $j( smilElement ).attr( attributeName, value); |
108 | | - // update the display |
109 | | - }, |
110 | | - getSmilVal : function( _this, smilElement, attributeName ){ |
111 | | - if( $j( smilElement ).attr( attributeName ) ){ |
112 | | - return $j( smilElement ).attr( attributeName ) |
113 | | - } |
114 | | - // Check for a default value |
115 | | - if( _this.editableAttributes[ attributeName ].defaultValue ){ |
116 | | - return _this.editableAttributes[ attributeName ].defaultValue; |
117 | | - } |
118 | | - return ''; |
119 | | - } |
120 | | - }, |
121 | | - 'time' : { |
122 | | - update : function( _this, smilElement, attributeName, value){ |
123 | | - // Validate time |
124 | | - var seconds = _this.sequencer.getSmil().parseTime( value ); |
125 | | - $j( smilElement ).attr( attributeName, mw.seconds2npt( seconds ) ); |
126 | | - // Update the clip duration : |
127 | | - _this.sequencer.getEmbedPlayer().getDuration( true ); |
128 | | - |
129 | | - // Seek to "this clip" |
130 | | - _this.sequencer.getEmbedPlayer().setCurrentTime( |
131 | | - $j( smilElement ).data('startOffset') |
132 | | - ); |
133 | | - }, |
134 | | - getSmilVal : function( _this, smilElement, attributeName ){ |
135 | | - var smil = _this.sequencer.getSmil(); |
136 | | - return mw.seconds2npt( |
137 | | - smil.parseTime( |
138 | | - $j( smilElement ).attr( attributeName ) |
139 | | - ) |
140 | | - ); |
141 | | - } |
142 | | - } |
143 | | - }, |
144 | | - editActions: { |
145 | | - 'sourcePage':{ |
146 | | - 'displayCheck': function( _this, smilElement ){ |
147 | | - if( _this.sequencer.getSmil().getTitleKey( smilElement ) |
148 | | - && |
149 | | - _this.sequencer.getServer().isConfigured() |
150 | | - ){ |
151 | | - return true; |
152 | | - } |
153 | | - return false; |
154 | | - }, |
155 | | - 'icon': 'info', |
156 | | - 'title': gM('mwe-sequencer-asset-source'), |
157 | | - 'action' : function( clickButton, _this, smilElement ){ |
158 | | - // Update the link |
159 | | - $j( clickButton ) |
160 | | - .attr({ |
161 | | - 'href': _this.sequencer.getServer().getAssetViewUrl( |
162 | | - _this.sequencer.getSmil().getTitleKey( smilElement ) |
163 | | - ) |
164 | | - , |
165 | | - 'target' : '_new' |
166 | | - }) |
167 | | - // follow the link the link |
168 | | - return true; |
169 | | - } |
170 | | - }, |
171 | | - 'preview' : { |
172 | | - 'icon' : 'play', |
173 | | - 'title' : gM('mwe-sequencer-preview'), |
174 | | - 'action': function( clickButton, _this, smilElement ){ |
175 | | - _this.sequencer.getPlayer().previewClip( smilElement, function(){ |
176 | | - // preview done, restore original state: |
177 | | - $j(clickButton).replaceWith ( |
178 | | - _this.getEditAction( smilElement, 'preview' ) |
179 | | - ) |
180 | | - }); |
181 | | - // xxx todo update preview button to "pause" / "play" |
182 | | - var doPause = function(){ |
183 | | - $j( clickButton ).find( '.ui-icon') |
184 | | - .removeClass( 'ui-icon-pause' ) |
185 | | - .addClass( 'ui-icon-play' ) |
186 | | - $j( clickButton ).find('.btnText').text( |
187 | | - gM('mwe-sequencer-preview-continue') |
188 | | - ) |
189 | | - _this.sequencer.getEmbedPlayer().pause(); |
190 | | - } |
191 | | - var doPlay = function(){ |
192 | | - // setup pause button: |
193 | | - $j( clickButton ).find( '.ui-icon') |
194 | | - .removeClass( 'ui-icon-play' ) |
195 | | - .addClass( 'ui-icon-pause' ) |
196 | | - $j( clickButton ).find('.btnText').text( |
197 | | - gM('mwe-sequencer-preview-pause') |
198 | | - ) |
199 | | - // keep the target preview end time: |
200 | | - // xxx should probably refactor this.. a bit of abstraction leak here: |
201 | | - _this.sequencer.getEmbedPlayer().play( |
202 | | - _this.sequencer.getEmbedPlayer().playSegmentEndTime |
203 | | - ); |
204 | | - } |
205 | | - $j( clickButton ).unbind().click(function(){ |
206 | | - if( _this.sequencer.getEmbedPlayer().paused ){ |
207 | | - doPlay(); |
208 | | - } else { |
209 | | - doPause(); |
210 | | - } |
211 | | - }) |
212 | | - doPlay(); |
213 | | - } |
214 | | - }, |
215 | | - 'cancel' : { |
216 | | - 'icon': 'close', |
217 | | - 'title' : gM('mwe-sequencer-clip-cancel-edit'), |
218 | | - 'action' : function(clickButton, _this, smilElement ){ |
219 | | - $j.each( |
220 | | - _this.getToolSet( |
221 | | - _this.sequencer.getSmil().getRefType( smilElement ) |
222 | | - ), |
223 | | - function( inx, toolId ){ |
224 | | - var tool = _this.tools[toolId]; |
225 | | - for( var i=0; i < tool.editableAttributes.length ; i++ ){ |
226 | | - var attributeName = tool.editableAttributes[i]; |
227 | | - var $editToolInput = $j('#' + _this.getEditToolInputId( toolId, attributeName ) ); |
228 | | - // Restore all original attribute values |
229 | | - smilElement.attr( attributeName, $editToolInput.data('initialValue') ); |
230 | | - } |
231 | | - } |
232 | | - ); |
233 | | - |
234 | | - // Update the clip duration : |
235 | | - _this.sequencer.getEmbedPlayer().getDuration( true ); |
236 | | - |
237 | | - // Update the embed player |
238 | | - _this.sequencer.getEmbedPlayer().setCurrentTime( |
239 | | - $j( smilElement ).data('startOffset') |
240 | | - ); |
241 | | - |
242 | | - // Close / empty the toolWindow |
243 | | - _this.setDefaultText(); |
244 | | - } |
245 | | - } |
246 | | - }, |
247 | | - editWidgets: { |
248 | | - 'editTransitions' : { |
249 | | - 'transitionTypes' : { |
250 | | - 'fade':{ |
251 | | - 'type' : { |
252 | | - 'value' : 'fade', |
253 | | - 'editType' : 'hidden' |
254 | | - }, |
255 | | - 'dur' : { |
256 | | - 'value' : '0:02', |
257 | | - 'editType' : 'time' |
258 | | - }, |
259 | | - }, |
260 | | - 'fadeColor':{ |
261 | | - 'extends':'fade', |
262 | | - 'fadeColor' : { |
263 | | - 'value' : '#000', |
264 | | - 'editType' : 'color' |
265 | | - } |
266 | | - }, |
267 | | - // Set high level select attribute default |
268 | | - 'fadeFromColor' : { |
269 | | - 'extends': 'fadeColor', |
270 | | - 'selectable' : ['transIn'], |
271 | | - 'subtype' : { |
272 | | - 'value' : 'fadeFromColor', |
273 | | - 'editType' : 'hidden' |
274 | | - } |
275 | | - }, |
276 | | - 'fadeToColor' : { |
277 | | - 'extends': 'fadeColor', |
278 | | - 'selectable' : ['transOut'], |
279 | | - 'subtype' : { |
280 | | - 'value' : 'fadeToColor', |
281 | | - 'editType' : 'hidden' |
282 | | - } |
283 | | - } |
284 | | - /*, |
285 | | - 'crossfade' : { |
286 | | - 'extends': 'fade', |
287 | | - 'selectable' : ['transIn', 'transOut'], |
288 | | - 'subtype' : { |
289 | | - 'value' : 'crossfade', |
290 | | - 'editType' : 'hidden' |
291 | | - } |
292 | | - }*/ |
293 | | - }, |
294 | | - buildAttributeSet: function( transitionType ){ |
295 | | - var attributes = {}; |
296 | | - for( var i in this.transitionTypes[ transitionType ] ){ |
297 | | - if( i == 'extends' ){ |
298 | | - $j.extend( attributes, this.buildAttributeSet( this.transitionTypes[ transitionType ][i] ) ); |
299 | | - } else { |
300 | | - attributes[ i ] = this.transitionTypes[ transitionType ][i]; |
301 | | - } |
302 | | - } |
303 | | - return attributes; |
304 | | - }, |
305 | | - |
306 | | - getTransitionId: function( smilElement, transitionType ){ |
307 | | - // Transition name is packed from attributeValue via striping the smilElement id |
308 | | - // This is a consequence of smil's strange transition dom placement in the head of the |
309 | | - // document instead of as child nodes. The idea with smil is the transition can be 'reused' |
310 | | - // but in the sequencer context we want unique transitions so that each can be customized |
311 | | - // independently. |
312 | | - return $j( smilElement ).attr('id') + '_' + transitionType; |
313 | | - }, |
314 | | - |
315 | | - // Get a transition element ( if it does not exist add it ) |
316 | | - getTransitionElement: function( _this, smilElement, transitionType ){ |
317 | | - var $smilDom = _this.sequencer.getSmil().$dom; |
318 | | - var transId = this.getTransitionId( smilElement, transitionType ); |
319 | | - if( $smilDom.find( '#' + transId ).length == 0 ){ |
320 | | - $smilDom.find('head').append( |
321 | | - $j('<transition />') |
322 | | - .attr('id', transId ) |
323 | | - ); |
324 | | - } |
325 | | - return $smilDom.find( '#' + transId ); |
326 | | - }, |
327 | | - |
328 | | - getSelectedTransitionType: function(smilElement, transitionDirection ){ |
329 | | - var attributeValue = $j( smilElement ).attr( transitionDirection ); |
330 | | - if( !attributeValue ) |
331 | | - return ''; |
332 | | - return attributeValue.replace( $j( smilElement ).attr('id') + '_', '' ); |
333 | | - }, |
334 | | - |
335 | | - getBindedTranstionEdit: function( _this, smilElement, transitionType ){ |
336 | | - var _editTransitions = this; |
337 | | - var $editTransitionsSet = $j('<div />'); |
338 | | - // return the empty div on empty transtionType |
339 | | - if( transitionType == '' ){ |
340 | | - return $editTransitionsSet |
341 | | - } |
342 | | - |
343 | | - // Get the smil transition element |
344 | | - var $smilTransitionElement = this.getTransitionElement( _this, smilElement, transitionType ) |
345 | | - // Get all the editable attributes for transitionName |
346 | | - var attributeSet = this.buildAttributeSet( transitionType ); |
347 | | - |
348 | | - $j.each( attributeSet, function( attributeKey, transitionAttribute ){ |
349 | | - // Skip setup attributes |
350 | | - if( attributeKey == 'extends' || attributeKey == 'selectable' ){ |
351 | | - return true; |
352 | | - } |
353 | | - var initialValue = $smilTransitionElement.attr( attributeKey ); |
354 | | - // Set to the default value if the transition attribute has no attribute key |
355 | | - if( !initialValue){ |
356 | | - initialValue = transitionAttribute.value |
357 | | - $smilTransitionElement.attr( attributeKey, transitionAttribute.value ) |
358 | | - } |
359 | | - |
360 | | - if( transitionAttribute.editType == 'time' ){ |
361 | | - $editTransitionsSet.append( |
362 | | - _this.getInputBox({ |
363 | | - 'title' : gM('mwe-sequencer-tools-duration'), |
364 | | - 'inputSize' : 5, |
365 | | - 'initialValue' :initialValue, |
366 | | - 'change': function(){ |
367 | | - // parse smil time |
368 | | - var time = _this.sequencer.getSmil().parseTime( $j(this).val() ); |
369 | | - |
370 | | - // Check if time > clip duration |
371 | | - if( time > $j( smilElement ).attr('dur') ){ |
372 | | - time = $j( smilElement ).attr('dur'); |
373 | | - } |
374 | | - if( time < 0 ) |
375 | | - time = 0; |
376 | | - |
377 | | - // Update the input value |
378 | | - $j( this ).val( mw.seconds2npt( time ) ); |
379 | | - // Update the smil attribute |
380 | | - $smilTransitionElement.attr( attributeKey, time ); |
381 | | - // run the onChange action |
382 | | - _editTransitions.onChange( _this, smilElement ); |
383 | | - } |
384 | | - }) |
385 | | - ) |
386 | | - } else if ( transitionAttribute.editType == 'color' ){ |
387 | | - // Add the color picker: |
388 | | - $editTransitionsSet.append( |
389 | | - _this.getInputBox({ |
390 | | - 'title' : gM('mwe-sequencer-tools-transitions-color'), |
391 | | - 'inputSize' : 8, |
392 | | - 'initialValue' : initialValue |
393 | | - }) |
394 | | - .addClass("jColorPicker") |
395 | | - ); |
396 | | - } |
397 | | - }) |
398 | | - return $editTransitionsSet; |
399 | | - }, |
400 | | - /** |
401 | | - * Could move to a more central location if we use the color picker other places |
402 | | - */ |
403 | | - colorPickerConfig: { |
404 | | - 'window' : { |
405 | | - 'expandable': true, |
406 | | - 'effects' : { |
407 | | - 'type' : 'fade' |
408 | | - } |
409 | | - }, |
410 | | - 'images' : { |
411 | | - 'clientPath' : mw.getMwEmbedPath() + 'modules/Sequencer/tools/jPicker/images/' |
412 | | - }, |
413 | | - 'localization' : { |
414 | | - 'text' : { |
415 | | - 'title' : gM('mwe-sequencer-color-picker-title'), |
416 | | - 'newColor' : gM('mwe-sequencer-menu-sequence-new'), |
417 | | - 'currentColor' : gM('mwe-sequencer-color-picker-current'), |
418 | | - 'ok' : gM('mwe-ok'), |
419 | | - 'cancel': gM('mwe-cancel') |
420 | | - }, |
421 | | - 'tooltips':{ |
422 | | - 'colors': |
423 | | - { |
424 | | - 'newColor': gM('mwe-sequencer-color-picker-new-color'), |
425 | | - 'currentColor': gM('mwe-sequencer-color-picker-currentColor') |
426 | | - }, |
427 | | - 'buttons': |
428 | | - { |
429 | | - ok: gM('mwe-sequencer-color-picker-commit' ), |
430 | | - cancel: gM('mwe-sequencer-color-picker-cancel-desc') |
431 | | - }, |
432 | | - 'hue': |
433 | | - { |
434 | | - radio: gM('mwe-sequencer-color-picker-hue-desc'), |
435 | | - textbox: gM('mwe-sequencer-color-picker-hue-textbox') |
436 | | - }, |
437 | | - 'saturation': |
438 | | - { |
439 | | - radio: gM('mwe-sequencer-color-picker-saturation-desc'), |
440 | | - textbox: gM('mwe-sequencer-color-picker-saturation-textbox') |
441 | | - }, |
442 | | - 'value': |
443 | | - { |
444 | | - radio: gM('mwe-sequencer-color-picker-value-desc'), |
445 | | - textbox: gM('mwe-sequencer-color-picker-value-textbox') |
446 | | - }, |
447 | | - 'red': |
448 | | - { |
449 | | - radio: gM('mwe-sequencer-color-picker-red-desc'), |
450 | | - textbox: gM('mwe-sequencer-color-picker-red-textbox') |
451 | | - }, |
452 | | - 'green': |
453 | | - { |
454 | | - radio: gM('mwe-sequencer-color-picker-green-desc'), |
455 | | - textbox: gM('mwe-sequencer-color-picker-green-textbox') |
456 | | - }, |
457 | | - 'blue': |
458 | | - { |
459 | | - radio: gM('mwe-sequencer-color-picker-blue-desc'), |
460 | | - textbox: gM('mwe-sequencer-color-picker-blue-textbox') |
461 | | - }, |
462 | | - 'alpha': |
463 | | - { |
464 | | - radio: gM('mwe-sequencer-color-picker-alpha-desc'), |
465 | | - textbox: gM('mwe-sequencer-color-picker-alpha-textbox') |
466 | | - }, |
467 | | - 'hex': |
468 | | - { |
469 | | - textbox: gM('mwe-sequencer-color-picker-hex-desc'), |
470 | | - alpha: gM('mwe-sequencer-color-picker-hex-textbox') |
471 | | - } |
472 | | - } |
473 | | - |
474 | | - } |
475 | | - }, |
476 | | - |
477 | | - 'onChange': function( _this, smilElement ){ |
478 | | - // Update the sequence duration : |
479 | | - _this.sequencer.getEmbedPlayer().getDuration( true ); |
480 | | - |
481 | | - // Seek to "this clip" |
482 | | - _this.sequencer.getEmbedPlayer().setCurrentTime( |
483 | | - $j( smilElement ).data('startOffset') |
484 | | - ); |
485 | | - }, |
486 | | - 'draw': function( _this, target, smilElement ){ |
487 | | - // draw the two attribute types |
488 | | - var _editTransitions = this; |
489 | | - var $transitionWidget = $j('<div />'); |
490 | | - |
491 | | - var transitionDirections = ['transIn', 'transOut']; |
492 | | - $j.each(transitionDirections, function( inx, transitionDirection ){ |
493 | | - $transitionWidget.append( |
494 | | - $j('<div />').css('clear', 'both') |
495 | | - , |
496 | | - $j('<h3 />').text( gM('mwe-sequencer-tools-transitions-' + transitionDirection )) |
497 | | - ) |
498 | | - // Output the top level empty select |
499 | | - $transSelect = $j('<select />').append( |
500 | | - $j('<option />') |
501 | | - .attr('value', '') |
502 | | - ); |
503 | | - var selectedTransitionType = _editTransitions.getSelectedTransitionType( smilElement, transitionDirection); |
504 | | - for( var transitionType in _editTransitions.transitionTypes ){ |
505 | | - if( _editTransitions.transitionTypes[ transitionType ].selectable |
506 | | - && |
507 | | - $j.inArray( transitionDirection, _editTransitions.transitionTypes[transitionType].selectable ) !== -1 ) |
508 | | - { |
509 | | - // Output the item if its selectable for the current transitionType |
510 | | - var $option = $j("<option />") |
511 | | - .attr('value', transitionType ) |
512 | | - .text( transitionType ) |
513 | | - // Add selected attribute if selected: |
514 | | - if( selectedTransitionType == transitionType ){ |
515 | | - $option.attr('selected', 'true'); |
516 | | - } |
517 | | - $transSelect.append( $option ); |
518 | | - } |
519 | | - } |
520 | | - $transSelect.change( function(){ |
521 | | - var transitionType = $j(this).val(); |
522 | | - $transitionWidget.find( '#' + transitionDirection + '_attributeContainer' ).html( |
523 | | - _editTransitions.getBindedTranstionEdit( |
524 | | - _this, smilElement, transitionType |
525 | | - ) |
526 | | - ) |
527 | | - // Update the smil attribute: |
528 | | - $j( smilElement ).attr( |
529 | | - transitionDirection, |
530 | | - _editTransitions.getTransitionId( smilElement, transitionType ) |
531 | | - ) |
532 | | - // Update the player on select change |
533 | | - _editTransitions.onChange( _this, smilElement ); |
534 | | - }); |
535 | | - |
536 | | - // Add the select to the $transitionWidget |
537 | | - $transitionWidget.append( $transSelect ); |
538 | | - |
539 | | - // Set up the transConfig container: |
540 | | - var $transConfig = $j('<span />') |
541 | | - .attr('id', transitionDirection + '_attributeContainer'); |
542 | | - |
543 | | - // If a given transition type is selected output is editable attributes |
544 | | - if( selectedTransitionType != '' ) { |
545 | | - $transConfig.append( |
546 | | - _editTransitions.getBindedTranstionEdit( |
547 | | - _this, smilElement, selectedTransitionType |
548 | | - ) |
549 | | - ) |
550 | | - } |
551 | | - $transitionWidget.append( $transConfig ); |
552 | | - |
553 | | - // update the player for the default selected set. |
554 | | - _editTransitions.onChange( _this, smilElement ); |
555 | | - }); |
556 | | - // add the transition widget to the target |
557 | | - $j( target ).append( $transitionWidget ); |
558 | | - |
559 | | - $j( target ).find('.jColorPicker input').jPicker( |
560 | | - _editTransitions.colorPickerConfig |
561 | | - ); |
562 | | - // adjust the position of the color button: |
563 | | - $j( target ).find('.jColorPicker .Icon').css('top', '-5px'); |
564 | | - |
565 | | - } |
566 | | - }, |
567 | | - 'editTemplate':{ |
568 | | - 'onChange' : function( _this, smilElement ){ |
569 | | - // Clear the smilElement template cache: |
570 | | - $j( smilElement ).data('templateHtmlCache', null); |
571 | | - // Re draw the smilElement in the player |
572 | | - var smil = _this.sequencer.getSmil(); |
573 | | - $playerTarget = $j('#' + smil.getSmilElementPlayerID( smilElement ) ); |
574 | | - $playerTarget.loadingSpinner(); |
575 | | - smil.getLayout().getSmilTemplateHtml( smilElement, $playerTarget, function(){ |
576 | | - mw.log("SequencerTools::editWidgets: smil template updated"); |
577 | | - }); |
578 | | - }, |
579 | | - 'draw': function( _this, target, smilElement ){ |
580 | | - // Parse the set of templates from the template text cache |
581 | | - $j( target ).loadingSpinner(); |
582 | | - |
583 | | - if( ! $j( smilElement).attr('apititlekey') ){ |
584 | | - mw.log("Error: can't grab template without title key") |
585 | | - return ; |
586 | | - } |
587 | | - // Get the template wikitext |
588 | | - _this.sequencer |
589 | | - .getServer() |
590 | | - .getTemplateText( $j( smilElement).attr('apititlekey'), function( templateText ){ |
591 | | - //mw.log("GotTemplateText: " + templateText ); |
592 | | - if( ! templateText || typeof templateText != 'string' ){ |
593 | | - mw.log("Error: could not get wikitext form titlekey: " + $j( smilElement).attr('apititlekey')) |
594 | | - return ; |
595 | | - } |
596 | | - $j( target ).empty().append( |
597 | | - $j('<h3 />').text( gM('mwe-sequencer-editTemplate-params') ) |
598 | | - ) |
599 | | - |
600 | | - // This is not supposed to be perfect .. |
601 | | - // just get you 'most' of the input vars 'most' of the time via the greedy regEx: |
602 | | - var templateVars = templateText.match(/\{\{\{([^\}]*)\}\}\}/gi); |
603 | | - var cleanTemplateParams = {}; |
604 | | - |
605 | | - for( i =0;i<templateVars.length; i++ ){ |
606 | | - var tVar = templateVars[i]; |
607 | | - // Remove all {{{ and }}} |
608 | | - tVar = tVar.replace(/\{\{\{/, '' ).replace( /\}\}\}/, ''); |
609 | | - // Check for | operator |
610 | | - if( tVar.indexOf("|") != -1 ){ |
611 | | - // Only the first version of the template var |
612 | | - tVar = tVar.split( '|')[0]; |
613 | | - } |
614 | | - cleanTemplateParams[ tVar ] = true; |
615 | | - } |
616 | | - // Output input boxes for each template var as a param |
617 | | - for( var paramName in cleanTemplateParams ){ |
618 | | - $j( target ).append( |
619 | | - _this.getEditableAttribute( |
620 | | - smilElement, |
621 | | - 'editTemplate', |
622 | | - 'param', |
623 | | - paramName |
624 | | - ) |
625 | | - .find('input') |
626 | | - // Bind the change event: |
627 | | - .change(function(){ |
628 | | - _this.editWidgets.editTemplate.onChange( |
629 | | - _this, |
630 | | - smilElement |
631 | | - ) |
632 | | - }) |
633 | | - .parent() |
634 | | - , |
635 | | - $j('<div />') |
636 | | - .css('clear', 'both') |
637 | | - ) |
638 | | - } |
639 | | - |
640 | | - |
641 | | - }); |
642 | | - } |
643 | | - }, |
644 | | - 'panzoom' : { |
645 | | - 'onChange': function( _this, smilElement ){ |
646 | | - var panZoomVal = $j('#' +_this.getEditToolInputId( 'panzoom', 'panZoom')).val(); |
647 | | - mw.log("panzoom change:" + panZoomVal ); |
648 | | - |
649 | | - // Update on the current smil clip display: |
650 | | - _this.sequencer.getSmil() |
651 | | - .getLayout() |
652 | | - .panZoomLayout( |
653 | | - smilElement |
654 | | - ); |
655 | | - var $thumbTraget = $j( '#' + _this.sequencer.getTimeline().getTimelineClipId( smilElement ) ).find('.thumbTraget'); |
656 | | - // Update the timeline clip display |
657 | | - // xxx this should be abstracted to timeline handler for clip updates |
658 | | - _this.sequencer.getSmil() |
659 | | - .getLayout() |
660 | | - .panZoomLayout( |
661 | | - smilElement, |
662 | | - $thumbTraget, |
663 | | - $thumbTraget.find('img').get(0) |
664 | | - ) |
665 | | - // Register the change for undo redo |
666 | | - _this.sequencer.getActionsEdit().registerEdit(); |
667 | | - }, |
668 | | - 'draw': function( _this, target, smilElement ){ |
669 | | - var orginalHelperCss = { |
670 | | - 'position' : 'absolute', |
671 | | - 'width' : 100, |
672 | | - 'height' : 75, |
673 | | - 'top' : 50, |
674 | | - 'left' : 70, |
675 | | - 'font-size' : 'x-small' |
676 | | - }; |
677 | | - // Add a input box binding: |
678 | | - $j('#' +_this.getEditToolInputId( 'panzoom', 'panZoom')) |
679 | | - .change(function(){ |
680 | | - _this.editWidgets.panzoom.onChange( _this, smilElement, target ); |
681 | | - }) |
682 | | - |
683 | | - $j( target ).append( |
684 | | - $j('<h3 />').html( |
685 | | - gM('mwe-sequencer-tools-panzoomhelper-desc') |
686 | | - ) |
687 | | - , |
688 | | - /*xxx Keep aspect button ?*/ |
689 | | - // Rest layout button ( restores default position ) |
690 | | - $j.button({ |
691 | | - 'icon' : 'arrow-4', |
692 | | - 'text' : gM( 'mwe-sequencer-tools-panzoomhelper-resetlayout' ) |
693 | | - }) |
694 | | - .attr('id', 'panzoomResetLayout') |
695 | | - .css('float', 'left') |
696 | | - .hide() |
697 | | - .click(function(){ |
698 | | - // Restore default SMIL setting |
699 | | - _this.editableTypes['display'].update( |
700 | | - _this, |
701 | | - smilElement, |
702 | | - 'panzoom', |
703 | | - _this.editableAttributes['panzoom'].defaultValue |
704 | | - ) |
705 | | - }) |
706 | | - , |
707 | | - $j('<div />') |
708 | | - .css({ |
709 | | - 'border' : '1px solid #DDDDDD', |
710 | | - 'float' : 'left', |
711 | | - 'position' : 'relative', |
712 | | - 'width': '240px', |
713 | | - 'height' : '180px', |
714 | | - 'overflow' : 'hidden' |
715 | | - }) |
716 | | - .append( |
717 | | - $j('<div />') |
718 | | - .css( orginalHelperCss ) |
719 | | - .attr({ |
720 | | - 'id': "panzoomHelper" |
721 | | - }) |
722 | | - .addClass("ui-widget-content") |
723 | | - .text( gM('mwe-sequencer-tools-panzoomhelper') ) |
724 | | - ) |
725 | | - ); |
726 | | - var startPanZoomVal = ''; |
727 | | - var setStartPanZoomVal = function(){ |
728 | | - startPanZoomVal = $j( smilElement ).attr( 'panZoom'); |
729 | | - if(! startPanZoomVal ){ |
730 | | - startPanZoomVal = _this.editableAttributes['panZoom'].defaultValue; |
731 | | - } |
732 | | - } |
733 | | - |
734 | | - var updatePanZoomFromUiValue = function( layout ){ |
735 | | - var pz = startPanZoomVal.split(','); |
736 | | - // Set the new percent offset to x/2 |
737 | | - if( layout.left ){ |
738 | | - pz[0] = ( parseInt( pz[0] ) - ( layout.left / 4 ) ) + '%'; |
739 | | - } |
740 | | - |
741 | | - if( layout.top ){ |
742 | | - pz[1] = ( parseInt( pz[1] ) - ( layout.top / 4 ) )+ '%'; |
743 | | - } |
744 | | - |
745 | | - if( layout.width ) { |
746 | | - pz[2] = ( parseInt( pz[2] ) - ( layout.width / 2) ) + '%' |
747 | | - |
748 | | - // right now only keep aspect is supported do size hack:: |
749 | | - pz[3] = parseInt( pz[2] ) * _this.sequencer.getSmil().getLayout().getTargetAspectRatio(); |
750 | | - // only have 2 significant digits |
751 | | - |
752 | | - } |
753 | | - // Trim and round all % values |
754 | | - for(var i=0; i < pz.length; i++){ |
755 | | - pz[i] = ( Math.round( parseInt( pz[i] ) * 1000 ) / 1000 ) + '%'; |
756 | | - pz[i] = $j.trim( pz[i] ); |
757 | | - } |
758 | | - var smilPanZoomValue = pz.join(', '); |
759 | | - |
760 | | - // Update the smil DOM: |
761 | | - $j( smilElement ).attr( 'panZoom', smilPanZoomValue ); |
762 | | - |
763 | | - // Update the user input tool input value: |
764 | | - $j('#' +_this.getEditToolInputId( 'panzoom', 'panZoom')).val( smilPanZoomValue ); |
765 | | - |
766 | | - // Animate the update on the current smil clip display: |
767 | | - _this.sequencer.getSmil() |
768 | | - .getLayout() |
769 | | - .panZoomLayout( |
770 | | - smilElement |
771 | | - ); |
772 | | - } |
773 | | - // Add bindings |
774 | | - $j('#panzoomHelper') |
775 | | - .draggable({ |
776 | | - containment: 'parent', |
777 | | - start: function( event, ui){ |
778 | | - setStartPanZoomVal(); |
779 | | - }, |
780 | | - drag: function( event, ui){ |
781 | | - updatePanZoomFromUiValue({ |
782 | | - 'top' : ( orginalHelperCss.top - ui.position.top ), |
783 | | - 'left' : ( orginalHelperCss.left - ui.position.left ) |
784 | | - }); |
785 | | - }, |
786 | | - stop: function( event, ui){ |
787 | | - // run the onChange ? |
788 | | - // Restore original css for the layout helper |
789 | | - $j(this).css( orginalHelperCss ) |
790 | | - // trigger the 'change' |
791 | | - _this.editWidgets.panzoom.onChange( _this, smilElement ); |
792 | | - } |
793 | | - }) |
794 | | - .css('cursor', 'move') |
795 | | - .resizable({ |
796 | | - handles : 'all', |
797 | | - maxWidth : 170, |
798 | | - maxHeight: 130, |
799 | | - aspectRatio: 4/3, |
800 | | - start: function( event, ui){ |
801 | | - setStartPanZoomVal(); |
802 | | - }, |
803 | | - resize : function(event, ui){ |
804 | | - updatePanZoomFromUiValue({ |
805 | | - 'width' : ( orginalHelperCss.width - ui.size.width ), |
806 | | - 'height' : ( orginalHelperCss.top - ui.size.height ) |
807 | | - }); |
808 | | - }, |
809 | | - stop: function( event, ui){ |
810 | | - // Restore original css |
811 | | - $j(this).css( orginalHelperCss ) |
812 | | - // trigger the change |
813 | | - _this.editWidgets.panzoom.onChange( _this, smilElement); |
814 | | - } |
815 | | - }) |
816 | | - |
817 | | - } |
818 | | - }, |
819 | | - 'trimTimeline' : { |
820 | | - 'onChange': function( _this, smilElement ){ |
821 | | - var smil = _this.sequencer.getSmil(); |
822 | | - // Update the preview thumbs |
823 | | - var $target = $j( '#editWidgets_trimTimeline' ); |
824 | | - // (local function so it can be updated after the start time is done with its draw ) |
825 | | - var updateDurationThumb = function(){ |
826 | | - // Check the duration: |
827 | | - var clipDur = $j('#editTool_trim_dur').val(); |
828 | | - if( clipDur ){ |
829 | | - // Render a thumbnail for the updated duration |
830 | | - smil.getLayout().drawSmilElementToTarget( |
831 | | - smilElement, |
832 | | - $target.find('.trimEndThumb'), |
833 | | - clipDur |
834 | | - ); |
835 | | - } |
836 | | - } |
837 | | - |
838 | | - var clipBeginTime = $j('#editTool_trim_clipBegin').val(); |
839 | | - if( !clipBeginTime ){ |
840 | | - $target.find('.trimStartThumb').hide(); |
841 | | - } else { |
842 | | - mw.log("Should update trimStartThumb::" + $j(smilElement).attr('clipBegin') ); |
843 | | - // Render a thumbnail for relative start time = 0 |
844 | | - smil.getLayout().drawSmilElementToTarget( |
845 | | - smilElement, |
846 | | - $target.find('.trimStartThumb'), |
847 | | - 0, |
848 | | - updateDurationThumb() |
849 | | - ) |
850 | | - } |
851 | | - }, |
852 | | - // Return the trimTimeline edit widget |
853 | | - 'draw': function( _this, target, smilElement ){ |
854 | | - var smil = _this.sequencer.getSmil(); |
855 | | - // check if thumbs are supported |
856 | | - if( _this.sequencer.getSmil().getRefType( smilElement ) == 'video' ){ |
857 | | - $j(target).append( |
858 | | - $j('<div />') |
859 | | - .addClass( 'trimStartThumb ui-corner-all' ), |
860 | | - $j('<div />') |
861 | | - .addClass( 'trimEndThumb ui-corner-all' ), |
862 | | - $j('<div />').addClass('ui-helper-clearfix') |
863 | | - ) |
864 | | - } |
865 | | - // The local scope fullClipDuration |
866 | | - var fullClipDuration = null; |
867 | | - |
868 | | - // Some slider functions |
869 | | - var sliderToTime = function( sliderval ){ |
870 | | - return parseInt( fullClipDuration * ( sliderval / 1000 ) ); |
871 | | - } |
872 | | - var timeToSlider = function( time ){ |
873 | | - return parseInt( ( time / fullClipDuration ) * 1000 ); |
874 | | - } |
875 | | - |
876 | | - |
877 | | - var onInputChange = function( sliderIndex, timeValue ){ |
878 | | - // Register the change |
879 | | - _this.editWidgets.trimTimeline.onChange( _this, smilElement ); |
880 | | - // Update the slider |
881 | | - if( fullClipDuration ){ |
882 | | - $j('#'+_this.sequencer.id + '_trimTimeline' ) |
883 | | - .slider( |
884 | | - "values", |
885 | | - sliderIndex, |
886 | | - timeToSlider( timeValue ) |
887 | | - ); |
888 | | - } |
889 | | - } |
890 | | - |
891 | | - // Add a trim binding: |
892 | | - $j('#' + _this.getEditToolInputId( 'trim', 'clipBegin') ) |
893 | | - .change( function(){ |
894 | | - var timeValue = smil.parseTime( $j(this).val() ); |
895 | | - onInputChange( 0, timeValue); |
896 | | - }); |
897 | | - |
898 | | - $j('#' + _this.getEditToolInputId( 'trim', 'dur') ) |
899 | | - .change( function(){ |
900 | | - var timeValue = smil.parseTime( $j(this).val() ) + |
901 | | - smil.parseTime( $j('#' + _this.getEditToolInputId( 'trim', 'clipBegin') ).val() ); |
902 | | - onInputChange( 1, timeValue ); |
903 | | - }); |
904 | | - |
905 | | - // Update the thumbnails: |
906 | | - _this.editWidgets.trimTimeline.onChange( _this, smilElement ); |
907 | | - |
908 | | - // Get the clip full duration to build out the timeline selector |
909 | | - smil.getBody().getClipAssetDuration( smilElement, function( clipDuration ) { |
910 | | - // update the local scope global |
911 | | - fullClipDuration = clipDuration; |
912 | | - |
913 | | - var startSlider = timeToSlider( smil.parseTime( $j('#editTool_trim_clipBegin').val() ) ); |
914 | | - var sliderValues = [ |
915 | | - startSlider, |
916 | | - startSlider + timeToSlider( smil.parseTime( $j('#editTool_trim_dur').val() ) ) |
917 | | - ]; |
918 | | - // Return a trim tool binded to smilElement id update value events. |
919 | | - $j(target).append( |
920 | | - $j('<div />') |
921 | | - .attr( 'id', _this.sequencer.id + '_trimTimeline' ) |
922 | | - .css({ |
923 | | - 'position': 'absolute', |
924 | | - 'left' : '25px', |
925 | | - 'right' : '35px', |
926 | | - 'margin': '5px' |
927 | | - }) |
928 | | - .slider({ |
929 | | - range: true, |
930 | | - min: 0, |
931 | | - max: 1000, |
932 | | - values: sliderValues, |
933 | | - slide: function(event, ui) { |
934 | | - |
935 | | - $j('#' + _this.getEditToolInputId( 'trim', 'clipBegin') ).val( |
936 | | - mw.seconds2npt( sliderToTime( ui.values[0] ), true ) |
937 | | - ); |
938 | | - $j('#' + _this.getEditToolInputId( 'trim', 'dur') ).val( |
939 | | - mw.seconds2npt( sliderToTime( ui.values[1] - ui.values[0] ), true ) |
940 | | - ); |
941 | | - }, |
942 | | - change: function( event, ui ) { |
943 | | - var attributeValue = 0, sliderIndex = 0; |
944 | | - |
945 | | - // Update clipBegin |
946 | | - _this.editableTypes['time'].update( _this, smilElement, 'clipBegin', sliderToTime( ui.values[ 0 ] ) ); |
947 | | - |
948 | | - // Update dur |
949 | | - _this.editableTypes['time'].update( _this, smilElement, 'dur', sliderToTime( ui.values[ 1 ]- ui.values[0] ) ); |
950 | | - |
951 | | - // update the widget display |
952 | | - _this.editWidgets.trimTimeline.onChange( _this, smilElement ); |
953 | | - |
954 | | - // Register the edit state for undo / redo |
955 | | - _this.sequencer.getActionsEdit().registerEdit(); |
956 | | - |
957 | | - } |
958 | | - }) |
959 | | - ); |
960 | | - }); |
961 | | - // On resize event |
962 | | - |
963 | | - // Fill in timeline images |
964 | | - |
965 | | - } |
966 | | - } |
967 | | - }, |
968 | | - getDefaultText: function(){ |
969 | | - return gM('mwe-sequencer-no_selected_resource'); |
970 | | - }, |
971 | | - setDefaultText: function(){ |
972 | | - this.sequencer.getEditToolTarget().html( |
973 | | - this.getDefaultText() |
974 | | - ) |
975 | | - }, |
976 | | - getEditToolInputId: function( toolId, attributeName){ |
977 | | - return 'editTool_' + toolId + '_' + attributeName.replace('/\s/', ''); |
978 | | - }, |
979 | | - /** |
980 | | - * update the current displayed tool ( when an undo, redo or history jump changes smil state ) |
981 | | - */ |
982 | | - updateToolDisplay: function(){ |
983 | | - var _this = this; |
984 | | - |
985 | | - // If tools are displayed update them |
986 | | - if( this.sequencer.getEditToolTarget().find('.editToolsContainer').lenght ){ |
987 | | - this.drawClipEditTools() |
988 | | - } |
989 | | - |
990 | | - }, |
991 | | - getToolSet: function( refType ){ |
992 | | - var toolSet = []; |
993 | | - for( var toolId in this.tools){ |
994 | | - if( this.tools[ toolId ].contentTypes){ |
995 | | - if( $j.inArray( refType, this.tools[ toolId ].contentTypes) != -1 ){ |
996 | | - toolSet.push( toolId ); |
997 | | - } |
998 | | - } |
999 | | - } |
1000 | | - return toolSet; |
1001 | | - }, |
1002 | | - drawClipEditTools: function( smilElement, selectedToolId ){ |
1003 | | - var _this = this; |
1004 | | - |
1005 | | - // Update the current clip and tool : |
1006 | | - if( smilElement ){ |
1007 | | - this.setCurrentsmilElement( smilElement ); |
1008 | | - } |
1009 | | - if( selectedToolId ){ |
1010 | | - this.setCurrentToolId( selectedToolId ); |
1011 | | - } |
1012 | | - |
1013 | | - $toolsContainer = $j('<div />') |
1014 | | - .addClass( 'editToolsContainer' ) |
1015 | | - .css( { |
1016 | | - 'overflow': 'auto', |
1017 | | - 'position':'absolute', |
1018 | | - 'top' : '0px', |
1019 | | - 'left': '0px', |
1020 | | - 'right': '0px', |
1021 | | - 'bottom': '37px' |
1022 | | - }) |
1023 | | - .append( |
1024 | | - $j('<ul />') |
1025 | | - ); |
1026 | | - |
1027 | | - this.sequencer.getEditToolTarget().empty().append( |
1028 | | - $toolsContainer |
1029 | | - ); |
1030 | | - // Get the entire tool set based on what "ref type" smilElement is: |
1031 | | - var toolSet = this.getToolSet( |
1032 | | - this.sequencer.getSmil().getRefType( |
1033 | | - this.getCurrentsmilElement() |
1034 | | - ) |
1035 | | - ); |
1036 | | - mw.log( 'Adding ' + toolSet.length + ' tools for ' + |
1037 | | - this.sequencer.getSmil().getRefType( this.getCurrentsmilElement() ) + |
1038 | | - ' current tool: ' + _this.getCurrentToolId() |
1039 | | - ); |
1040 | | - |
1041 | | - var toolTabIndex = 0; |
1042 | | - $j.each( toolSet, function( inx, toolId ){ |
1043 | | - |
1044 | | - var tool = _this.tools[ toolId ]; |
1045 | | - if( _this.getCurrentToolId() == toolId){ |
1046 | | - toolTabIndex = inx; |
1047 | | - } |
1048 | | - // Append the title to the ul list |
1049 | | - $toolsContainer.find( 'ul').append( |
1050 | | - $j('<li />').append( |
1051 | | - $j('<a />') |
1052 | | - .attr('href', '#tooltab_' + toolId ) |
1053 | | - .text( gM('mwe-sequencer-tools-' + toolId) ) |
1054 | | - ) |
1055 | | - ); |
1056 | | - |
1057 | | - // Append the tooltab container |
1058 | | - $toolsContainer.append( |
1059 | | - $j('<div />') |
1060 | | - .css({'height' : '100%' }) |
1061 | | - .attr('id', 'tooltab_' + toolId ) |
1062 | | - .append( |
1063 | | - $j('<h3 />').text( gM('mwe-sequencer-tools-' + toolId + '-desc') ) |
1064 | | - ) |
1065 | | - ) |
1066 | | - var $toolContainer = $toolsContainer.find( '#tooltab_' + toolId ); |
1067 | | - |
1068 | | - // Build out the attribute list for the given tool ( if the tool has directly editable attributes ) |
1069 | | - if( tool.editableAttributes ){ |
1070 | | - for( var i=0; i < tool.editableAttributes.length ; i++ ){ |
1071 | | - attributeName = tool.editableAttributes[i]; |
1072 | | - $toolContainer.append( |
1073 | | - _this.getEditableAttribute( smilElement, toolId, attributeName ) |
1074 | | - ); |
1075 | | - } |
1076 | | - } |
1077 | | - |
1078 | | - // Output a float divider: |
1079 | | - $toolContainer.append( $j('<div />').addClass('ui-helper-clearfix') ); |
1080 | | - |
1081 | | - // Build out tool widgets |
1082 | | - if( tool.editWidgets ){ |
1083 | | - for( var i =0 ; i < tool.editWidgets.length ; i ++ ){ |
1084 | | - var editWidgetId = tool.editWidgets[i]; |
1085 | | - if( ! _this.editWidgets[editWidgetId] ){ |
1086 | | - mw.log("Error: not recogonized widget: " + editWidgetId); |
1087 | | - continue; |
1088 | | - } |
1089 | | - // Append a target for the edit widget: |
1090 | | - $toolContainer.append( |
1091 | | - $j('<div />') |
1092 | | - .attr('id', 'editWidgets_' + editWidgetId) |
1093 | | - ); |
1094 | | - // Draw the binded widget: |
1095 | | - _this.editWidgets[editWidgetId].draw( |
1096 | | - _this, |
1097 | | - $j( '#editWidgets_' + editWidgetId ), |
1098 | | - smilElement |
1099 | | - ) |
1100 | | - // Output a float divider: |
1101 | | - $toolContainer.append( $j('<div />').addClass( 'ui-helper-clearfix' ) ); |
1102 | | - } |
1103 | | - } |
1104 | | - }); |
1105 | | - |
1106 | | - // Add tab bindings |
1107 | | - $toolsContainer.tabs({ |
1108 | | - select: function(event, ui) { |
1109 | | - _this.setCurrentToolId( $j( ui.tab ).attr('href').replace('#tooltab_', '') ); |
1110 | | - }, |
1111 | | - selected : toolTabIndex |
1112 | | - }); |
1113 | | - |
1114 | | - var $editActions = $j('<div />') |
1115 | | - .css({ |
1116 | | - 'position' : 'absolute', |
1117 | | - 'bottom' : '0px', |
1118 | | - 'height' : '37px', |
1119 | | - 'left' : '0px', |
1120 | | - 'right' : '0px', |
1121 | | - 'overflow' : 'auto' |
1122 | | - }); |
1123 | | - // Build out global edit Actions buttons after the container |
1124 | | - for( var editActionId in this.editActions ){ |
1125 | | - // Check if the edit action has a conditional display: |
1126 | | - var displayEidtAction = true; |
1127 | | - |
1128 | | - if( this.editActions[ editActionId ].displayCheck ){ |
1129 | | - displayEidtAction = this.editActions[ editActionId ].displayCheck( _this, smilElement ); |
1130 | | - } |
1131 | | - if( displayEidtAction ){ |
1132 | | - $editActions.append( |
1133 | | - this.getEditAction( smilElement, editActionId ) |
1134 | | - ) |
1135 | | - } |
1136 | | - } |
1137 | | - $j( this.sequencer.getEditToolTarget() ).append( $editActions ) |
1138 | | - }, |
1139 | | - getCurrentsmilElement: function(){ |
1140 | | - return this.currentsmilElement; |
1141 | | - }, |
1142 | | - setCurrentsmilElement: function( smilElement ){ |
1143 | | - this.currentsmilElement = smilElement; |
1144 | | - }, |
1145 | | - getCurrentToolId: function(){ |
1146 | | - return this.currentToolId; |
1147 | | - }, |
1148 | | - setCurrentToolId: function( toolId ){ |
1149 | | - this.currentToolId = toolId; |
1150 | | - }, |
1151 | | - |
1152 | | - getEditAction: function( smilElement, editActionId ){ |
1153 | | - if(! this.editActions[ editActionId ]){ |
1154 | | - mw.log("Error: getEditAction: " + editActionId + ' not found '); |
1155 | | - return ; |
1156 | | - } |
1157 | | - var _this = this; |
1158 | | - var editAction = this.editActions[ editActionId ]; |
1159 | | - $actionButton = $j.button({ |
1160 | | - icon: editAction.icon, |
1161 | | - text: editAction.title |
1162 | | - }) |
1163 | | - .css({ |
1164 | | - 'float': 'left', |
1165 | | - 'margin': '5px' |
1166 | | - }) |
1167 | | - .click( function(){ |
1168 | | - return editAction.action( this, _this, smilElement ); |
1169 | | - }) |
1170 | | - return $actionButton; |
1171 | | - }, |
1172 | | - /* get the editiable attribute input html */ |
1173 | | - getEditableAttribute: function( smilElement, toolId, attributeName, paramName ){ |
1174 | | - if( ! this.editableAttributes[ attributeName ] ){ |
1175 | | - mw.log("Error: editableAttributes : " + attributeName + ' not found'); |
1176 | | - return; |
1177 | | - } |
1178 | | - |
1179 | | - |
1180 | | - var _this = this; |
1181 | | - var editAttribute = this.editableAttributes[ attributeName ]; |
1182 | | - var editType = editAttribute.type; |
1183 | | - if( !_this.editableTypes[ editType ] ){ |
1184 | | - mw.log(" Error: No editableTypes interface for " + editType); |
1185 | | - return ; |
1186 | | - } |
1187 | | - |
1188 | | - // Set the update key to the paramName if provided: |
1189 | | - var updateKey = ( paramName ) ? paramName : attributeName; |
1190 | | - |
1191 | | - var initialValue = _this.editableTypes[ editType ].getSmilVal( |
1192 | | - _this, |
1193 | | - smilElement, |
1194 | | - updateKey |
1195 | | - ); |
1196 | | - // Set the default input size |
1197 | | - var inputSize = ( _this.editableAttributes[ attributeName ].inputSize)? |
1198 | | - _this.editableAttributes[ attributeName ].inputSize : 6; |
1199 | | - |
1200 | | - // Set paramName based attributes: |
1201 | | - var attributeTitle = ( editAttribute.title ) ? editAttribute.title : paramName + ':'; |
1202 | | - |
1203 | | - return _this.getInputBox({ |
1204 | | - 'title' : attributeTitle, |
1205 | | - 'inputId' : _this.getEditToolInputId( toolId, updateKey ), |
1206 | | - 'inputSize': inputSize, |
1207 | | - 'initialValue' : initialValue, |
1208 | | - 'change': function(){ |
1209 | | - // Run the editableType update function: |
1210 | | - _this.editableTypes[ editType ].update( |
1211 | | - _this, |
1212 | | - smilElement, |
1213 | | - updateKey, |
1214 | | - $j( this ).val() |
1215 | | - ); |
1216 | | - } |
1217 | | - }) |
1218 | | - }, |
1219 | | - getInputBox: function( config ){ |
1220 | | - var _this = this; |
1221 | | - return $j( '<div />' ) |
1222 | | - .css({ |
1223 | | - 'float': 'left', |
1224 | | - 'font-size': '12px', |
1225 | | - 'border': 'solid thin #999', |
1226 | | - 'background-color': '#EEE', |
1227 | | - 'padding' : '2px', |
1228 | | - 'margin' : '5px' |
1229 | | - }) |
1230 | | - .addClass('ui-corner-all') |
1231 | | - .append( |
1232 | | - $j('<span />') |
1233 | | - .css('margin', '5px') |
1234 | | - .text( config.title ), |
1235 | | - |
1236 | | - $j('<input />') |
1237 | | - .attr( { |
1238 | | - 'id' : config.inputId , |
1239 | | - 'size': config.inputSize |
1240 | | - }) |
1241 | | - .data('initialValue', config.initialValue ) |
1242 | | - .sequencerInput( _this.sequencer ) |
1243 | | - .val( config.initialValue ) |
1244 | | - .change( config.change ) |
1245 | | - ); |
1246 | | - } |
1247 | | -} |
1248 | | - |
1249 | | -} )( window.mw ); |
\ No newline at end of file |
Index: branches/MwEmbedStandAlone/modules/Sequencer/loader.js |
— | — | @@ -23,7 +23,7 @@ |
24 | 24 | "mw.SequencerPlayer" : "mw.SequencerPlayer.js", |
25 | 25 | "mw.SequencerTimeline" : "mw.SequencerTimeline.js", |
26 | 26 | "mw.SequencerKeyBindings" : "mw.SequencerKeyBindings.js", |
27 | | - "mw.SequencerTools" : "mw.SequencerTools.js", |
| 27 | + "mw.SequencerTools" : "tools/mw.SequencerTools.js", |
28 | 28 | "mw.SequencerMenu" : "mw.SequencerMenu.js", |
29 | 29 | |
30 | 30 | "mw.SequencerActionsSequence" : "actions/mw.SequencerActionsSequence.js", |
Index: branches/MwEmbedStandAlone/modules/Sequencer/tools/mw.SequencerTools.js |
— | — | @@ -0,0 +1,1260 @@ |
| 2 | +/** |
| 3 | + * Handles the "tools" window top level component driver |
| 4 | + */ |
| 5 | + |
| 6 | +// Wrap in mw closure to avoid global leakage |
| 7 | +( function( mw ) { |
| 8 | + |
| 9 | +mw.SequencerTools = function( sequencer ) { |
| 10 | + return this.init( sequencer ); |
| 11 | +}; |
| 12 | + |
| 13 | +// Set up the mvSequencer object |
| 14 | +mw.SequencerTools.prototype = { |
| 15 | + init: function( sequencer ){ |
| 16 | + this.sequencer = sequencer; |
| 17 | + }, |
| 18 | + |
| 19 | + // The current smil clip ( lazy init ) |
| 20 | + currentsmilElement: null, |
| 21 | + |
| 22 | + // The current selected tool ( lazy init ) |
| 23 | + currentToolId: null, |
| 24 | + |
| 25 | + // JSON tools config |
| 26 | + tools:{ |
| 27 | + 'trim':{ |
| 28 | + 'editWidgets' : [ 'trimTimeline' ], |
| 29 | + 'editableAttributes' : ['clipBegin','dur' ], |
| 30 | + 'contentTypes': ['video', 'audio'] |
| 31 | + }, |
| 32 | + 'duration':{ |
| 33 | + 'editableAttributes' : [ 'dur' ], |
| 34 | + 'contentTypes': ['img', 'cdata_html', 'mwtemplate'] |
| 35 | + }, |
| 36 | + 'panzoom' : { |
| 37 | + 'editWidgets' : ['panzoom'], |
| 38 | + 'editableAttributes' : [ 'panZoom' ], |
| 39 | + 'contentTypes': [ 'img'], // xxx todo add video support |
| 40 | + 'supportsKeyFrames' : 'true' |
| 41 | + }, |
| 42 | + 'templateedit' : { |
| 43 | + 'editWidgets' : ['editTemplate'], |
| 44 | + 'editableAttributes' : [ 'apititlekey' ], |
| 45 | + 'contentTypes' : ['mwtemplate'] |
| 46 | + }, |
| 47 | + 'transitions' : { |
| 48 | + 'editWidgets' : ['editTransitions'], |
| 49 | + 'contentTypes': ['video', 'img', 'mwtemplate' ] |
| 50 | + } |
| 51 | + }, |
| 52 | + editableAttributes:{ |
| 53 | + 'clipBegin':{ |
| 54 | + 'type': 'time', |
| 55 | + 'title' : gM('mwe-sequencer-start-time' ) |
| 56 | + }, |
| 57 | + 'dur' :{ |
| 58 | + 'type': 'time', |
| 59 | + 'title' : gM('mwe-sequencer-clip-duration' ) |
| 60 | + }, |
| 61 | + 'panZoom' :{ |
| 62 | + 'type' : 'string', |
| 63 | + 'inputSize' : 15, |
| 64 | + 'title' : gM('mwe-sequencer-clip-panzoom' ), |
| 65 | + 'defaultValue' : '0%, 0%, 100%, 100%' |
| 66 | + }, |
| 67 | + 'apititlekey' : { |
| 68 | + 'type' : 'string', |
| 69 | + 'inputSize' : 30, |
| 70 | + 'title' : gM('mwe-sequencer-template-name' ) |
| 71 | + }, |
| 72 | + // Special child node type |
| 73 | + 'param' : { |
| 74 | + 'type' : 'childParam', |
| 75 | + 'inputSize' : 30 |
| 76 | + } |
| 77 | + }, |
| 78 | + editableTypes: { |
| 79 | + 'childParam': { |
| 80 | + update: function( _this, smilElement, paramName, value){ |
| 81 | + // Check if the param already exists |
| 82 | + $paramNode = $j( smilElement ).find( "[name='"+ paramName + "']" ); |
| 83 | + if( $paramNode.length == 0){ |
| 84 | + $j( smilElement ).append( |
| 85 | + $j('<param />').attr({ |
| 86 | + 'name': paramName, |
| 87 | + 'value' : value |
| 88 | + }) |
| 89 | + ) |
| 90 | + } else { |
| 91 | + // Update the param value |
| 92 | + $paramNode.attr( 'value', value); |
| 93 | + } |
| 94 | + mw.log("editableTypes::Should have updated smilElement param: " + paramName |
| 95 | + + ' to : ' + $j( smilElement ).find( "[name='"+ paramName + '"]' ).attr( 'value') ); |
| 96 | + }, |
| 97 | + getSmilVal: function( _this, smilElement, paramName ){ |
| 98 | + $paramNode = $j( smilElement ).find( "[name='"+ paramName + "']" ); |
| 99 | + if( $paramNode.length == 0){ |
| 100 | + return ''; |
| 101 | + } |
| 102 | + return $paramNode.attr('value'); |
| 103 | + } |
| 104 | + }, |
| 105 | + 'string': { |
| 106 | + update: function( _this, smilElement, attributeName, value){ |
| 107 | + $j( smilElement ).attr( attributeName, value); |
| 108 | + // update the display |
| 109 | + }, |
| 110 | + getSmilVal : function( _this, smilElement, attributeName ){ |
| 111 | + if( $j( smilElement ).attr( attributeName ) ){ |
| 112 | + return $j( smilElement ).attr( attributeName ) |
| 113 | + } |
| 114 | + // Check for a default value |
| 115 | + if( _this.editableAttributes[ attributeName ].defaultValue ){ |
| 116 | + return _this.editableAttributes[ attributeName ].defaultValue; |
| 117 | + } |
| 118 | + return ''; |
| 119 | + } |
| 120 | + }, |
| 121 | + 'time' : { |
| 122 | + update : function( _this, smilElement, attributeName, value){ |
| 123 | + // Validate time |
| 124 | + var seconds = _this.sequencer.getSmil().parseTime( value ); |
| 125 | + $j( smilElement ).attr( attributeName, mw.seconds2npt( seconds ) ); |
| 126 | + // Update the clip duration : |
| 127 | + _this.sequencer.getEmbedPlayer().getDuration( true ); |
| 128 | + |
| 129 | + // Seek to "this clip" |
| 130 | + _this.sequencer.getEmbedPlayer().setCurrentTime( |
| 131 | + $j( smilElement ).data('startOffset') |
| 132 | + ); |
| 133 | + }, |
| 134 | + getSmilVal : function( _this, smilElement, attributeName ){ |
| 135 | + var smil = _this.sequencer.getSmil(); |
| 136 | + return mw.seconds2npt( |
| 137 | + smil.parseTime( |
| 138 | + $j( smilElement ).attr( attributeName ) |
| 139 | + ) |
| 140 | + ); |
| 141 | + } |
| 142 | + } |
| 143 | + }, |
| 144 | + editActions: { |
| 145 | + 'sourcePage':{ |
| 146 | + 'displayCheck': function( _this, smilElement ){ |
| 147 | + if( _this.sequencer.getSmil().getTitleKey( smilElement ) |
| 148 | + && |
| 149 | + _this.sequencer.getServer().isConfigured() |
| 150 | + ){ |
| 151 | + return true; |
| 152 | + } |
| 153 | + return false; |
| 154 | + }, |
| 155 | + 'icon': 'info', |
| 156 | + 'title': gM('mwe-sequencer-asset-source'), |
| 157 | + 'action' : function( clickButton, _this, smilElement ){ |
| 158 | + // Update the link |
| 159 | + $j( clickButton ) |
| 160 | + .attr({ |
| 161 | + 'href': _this.sequencer.getServer().getAssetViewUrl( |
| 162 | + _this.sequencer.getSmil().getTitleKey( smilElement ) |
| 163 | + ) |
| 164 | + , |
| 165 | + 'target' : '_new' |
| 166 | + }) |
| 167 | + // follow the link the link |
| 168 | + return true; |
| 169 | + } |
| 170 | + }, |
| 171 | + 'preview' : { |
| 172 | + 'icon' : 'play', |
| 173 | + 'title' : gM('mwe-sequencer-preview'), |
| 174 | + 'action': function( clickButton, _this, smilElement ){ |
| 175 | + _this.sequencer.getPlayer().previewClip( smilElement, function(){ |
| 176 | + // preview done, restore original state: |
| 177 | + $j(clickButton).replaceWith ( |
| 178 | + _this.getEditAction( smilElement, 'preview' ) |
| 179 | + ) |
| 180 | + }); |
| 181 | + // xxx todo update preview button to "pause" / "play" |
| 182 | + var doPause = function(){ |
| 183 | + $j( clickButton ).find( '.ui-icon') |
| 184 | + .removeClass( 'ui-icon-pause' ) |
| 185 | + .addClass( 'ui-icon-play' ) |
| 186 | + $j( clickButton ).find('.btnText').text( |
| 187 | + gM('mwe-sequencer-preview-continue') |
| 188 | + ) |
| 189 | + _this.sequencer.getEmbedPlayer().pause(); |
| 190 | + } |
| 191 | + var doPlay = function(){ |
| 192 | + // setup pause button: |
| 193 | + $j( clickButton ).find( '.ui-icon') |
| 194 | + .removeClass( 'ui-icon-play' ) |
| 195 | + .addClass( 'ui-icon-pause' ) |
| 196 | + $j( clickButton ).find('.btnText').text( |
| 197 | + gM('mwe-sequencer-preview-pause') |
| 198 | + ) |
| 199 | + // keep the target preview end time: |
| 200 | + // xxx should probably refactor this.. a bit of abstraction leak here: |
| 201 | + _this.sequencer.getEmbedPlayer().play( |
| 202 | + _this.sequencer.getEmbedPlayer().playSegmentEndTime |
| 203 | + ); |
| 204 | + } |
| 205 | + $j( clickButton ).unbind().click(function(){ |
| 206 | + if( _this.sequencer.getEmbedPlayer().paused ){ |
| 207 | + doPlay(); |
| 208 | + } else { |
| 209 | + doPause(); |
| 210 | + } |
| 211 | + }) |
| 212 | + doPlay(); |
| 213 | + } |
| 214 | + }, |
| 215 | + 'cancel' : { |
| 216 | + 'icon': 'close', |
| 217 | + 'title' : gM('mwe-sequencer-clip-cancel-edit'), |
| 218 | + 'action' : function(clickButton, _this, smilElement ){ |
| 219 | + $j.each( |
| 220 | + _this.getToolSet( |
| 221 | + _this.sequencer.getSmil().getRefType( smilElement ) |
| 222 | + ), |
| 223 | + function( inx, toolId ){ |
| 224 | + var tool = _this.tools[toolId]; |
| 225 | + for( var i=0; i < tool.editableAttributes.length ; i++ ){ |
| 226 | + var attributeName = tool.editableAttributes[i]; |
| 227 | + var $editToolInput = $j('#' + _this.getEditToolInputId( toolId, attributeName ) ); |
| 228 | + // Restore all original attribute values |
| 229 | + smilElement.attr( attributeName, $editToolInput.data('initialValue') ); |
| 230 | + } |
| 231 | + } |
| 232 | + ); |
| 233 | + |
| 234 | + // Update the clip duration : |
| 235 | + _this.sequencer.getEmbedPlayer().getDuration( true ); |
| 236 | + |
| 237 | + // Update the embed player |
| 238 | + _this.sequencer.getEmbedPlayer().setCurrentTime( |
| 239 | + $j( smilElement ).data('startOffset') |
| 240 | + ); |
| 241 | + |
| 242 | + // Close / empty the toolWindow |
| 243 | + _this.setDefaultText(); |
| 244 | + } |
| 245 | + } |
| 246 | + }, |
| 247 | + editWidgets: { |
| 248 | + 'editTransitions' : { |
| 249 | + 'transitionTypes' : { |
| 250 | + 'fade':{ |
| 251 | + 'type' : { |
| 252 | + 'value' : 'fade', |
| 253 | + 'editType' : 'hidden' |
| 254 | + }, |
| 255 | + 'dur' : { |
| 256 | + 'value' : '0:02', |
| 257 | + 'editType' : 'time' |
| 258 | + }, |
| 259 | + }, |
| 260 | + 'fadeColor':{ |
| 261 | + 'extends':'fade', |
| 262 | + 'fadeColor' : { |
| 263 | + 'value' : '#000', |
| 264 | + 'editType' : 'color' |
| 265 | + } |
| 266 | + }, |
| 267 | + // Set high level select attribute default |
| 268 | + 'fadeFromColor' : { |
| 269 | + 'extends': 'fadeColor', |
| 270 | + 'selectable' : ['transIn'], |
| 271 | + 'subtype' : { |
| 272 | + 'value' : 'fadeFromColor', |
| 273 | + 'editType' : 'hidden' |
| 274 | + } |
| 275 | + }, |
| 276 | + 'fadeToColor' : { |
| 277 | + 'extends': 'fadeColor', |
| 278 | + 'selectable' : ['transOut'], |
| 279 | + 'subtype' : { |
| 280 | + 'value' : 'fadeToColor', |
| 281 | + 'editType' : 'hidden' |
| 282 | + } |
| 283 | + } |
| 284 | + /*, |
| 285 | + 'crossfade' : { |
| 286 | + 'extends': 'fade', |
| 287 | + 'selectable' : ['transIn', 'transOut'], |
| 288 | + 'subtype' : { |
| 289 | + 'value' : 'crossfade', |
| 290 | + 'editType' : 'hidden' |
| 291 | + } |
| 292 | + }*/ |
| 293 | + }, |
| 294 | + buildAttributeSet: function( transitionType ){ |
| 295 | + var attributes = {}; |
| 296 | + for( var i in this.transitionTypes[ transitionType ] ){ |
| 297 | + if( i == 'extends' ){ |
| 298 | + $j.extend( attributes, this.buildAttributeSet( this.transitionTypes[ transitionType ][i] ) ); |
| 299 | + } else { |
| 300 | + attributes[ i ] = this.transitionTypes[ transitionType ][i]; |
| 301 | + } |
| 302 | + } |
| 303 | + return attributes; |
| 304 | + }, |
| 305 | + |
| 306 | + getTransitionId: function( smilElement, transitionType ){ |
| 307 | + // Transition name is packed from attributeValue via striping the smilElement id |
| 308 | + // This is a consequence of smil's strange transition dom placement in the head of the |
| 309 | + // document instead of as child nodes. The idea with smil is the transition can be 'reused' |
| 310 | + // but in the sequencer context we want unique transitions so that each can be customized |
| 311 | + // independently. |
| 312 | + return $j( smilElement ).attr('id') + '_' + transitionType; |
| 313 | + }, |
| 314 | + |
| 315 | + // Get a transition element ( if it does not exist add it ) |
| 316 | + getTransitionElement: function( _this, smilElement, transitionType ){ |
| 317 | + var $smilDom = _this.sequencer.getSmil().$dom; |
| 318 | + var transId = this.getTransitionId( smilElement, transitionType ); |
| 319 | + if( $smilDom.find( '#' + transId ).length == 0 ){ |
| 320 | + $smilDom.find('head').append( |
| 321 | + $j('<transition />') |
| 322 | + .attr('id', transId ) |
| 323 | + ); |
| 324 | + } |
| 325 | + return $smilDom.find( '#' + transId ); |
| 326 | + }, |
| 327 | + |
| 328 | + getSelectedTransitionType: function(smilElement, transitionDirection ){ |
| 329 | + var attributeValue = $j( smilElement ).attr( transitionDirection ); |
| 330 | + if( !attributeValue ) |
| 331 | + return ''; |
| 332 | + return attributeValue.replace( $j( smilElement ).attr('id') + '_', '' ); |
| 333 | + }, |
| 334 | + |
| 335 | + getBindedTranstionEdit: function( _this, smilElement, transitionType ){ |
| 336 | + var _editTransitions = this; |
| 337 | + var $editTransitionsSet = $j('<div />'); |
| 338 | + // return the empty div on empty transtionType |
| 339 | + if( transitionType == '' ){ |
| 340 | + return $editTransitionsSet |
| 341 | + } |
| 342 | + |
| 343 | + // Get the smil transition element |
| 344 | + var $smilTransitionElement = this.getTransitionElement( _this, smilElement, transitionType ) |
| 345 | + // Get all the editable attributes for transitionName |
| 346 | + var attributeSet = this.buildAttributeSet( transitionType ); |
| 347 | + |
| 348 | + $j.each( attributeSet, function( attributeKey, transitionAttribute ){ |
| 349 | + // Skip setup attributes |
| 350 | + if( attributeKey == 'extends' || attributeKey == 'selectable' ){ |
| 351 | + return true; |
| 352 | + } |
| 353 | + var initialValue = $smilTransitionElement.attr( attributeKey ); |
| 354 | + // Set to the default value if the transition attribute has no attribute key |
| 355 | + if( !initialValue){ |
| 356 | + initialValue = transitionAttribute.value |
| 357 | + $smilTransitionElement.attr( attributeKey, transitionAttribute.value ) |
| 358 | + } |
| 359 | + |
| 360 | + if( transitionAttribute.editType == 'time' ){ |
| 361 | + $editTransitionsSet.append( |
| 362 | + _this.getInputBox({ |
| 363 | + 'title' : gM('mwe-sequencer-tools-duration'), |
| 364 | + 'inputSize' : 5, |
| 365 | + 'initialValue' :initialValue, |
| 366 | + 'change': function(){ |
| 367 | + // parse smil time |
| 368 | + var time = _this.sequencer.getSmil().parseTime( $j(this).val() ); |
| 369 | + |
| 370 | + // Check if time > clip duration |
| 371 | + if( time > $j( smilElement ).attr('dur') ){ |
| 372 | + time = $j( smilElement ).attr('dur'); |
| 373 | + } |
| 374 | + if( time < 0 ) |
| 375 | + time = 0; |
| 376 | + |
| 377 | + // Update the input value |
| 378 | + $j( this ).val( mw.seconds2npt( time ) ); |
| 379 | + // Update the smil attribute |
| 380 | + $smilTransitionElement.attr( attributeKey, time ); |
| 381 | + // run the onChange action |
| 382 | + _editTransitions.onChange( _this, smilElement ); |
| 383 | + } |
| 384 | + }) |
| 385 | + ) |
| 386 | + } else if ( transitionAttribute.editType == 'color' ){ |
| 387 | + // Add the color picker: |
| 388 | + $editTransitionsSet.append( |
| 389 | + _this.getInputBox({ |
| 390 | + 'title' : gM('mwe-sequencer-tools-transitions-color'), |
| 391 | + 'inputSize' : 8, |
| 392 | + 'initialValue' : initialValue |
| 393 | + }) |
| 394 | + .addClass("jColorPicker") |
| 395 | + ); |
| 396 | + $editTransitionsSet.find('.jColorPicker input').jPicker( |
| 397 | + _editTransitions.colorPickerConfig, |
| 398 | + function(color){ |
| 399 | + // commit color ( update undo / redo ) |
| 400 | + |
| 401 | + }, |
| 402 | + function(color){ |
| 403 | + // live preview of selection ( update player ) |
| 404 | + //mw.log('update: ' + attributeKey + ' set to: #' + color.val('hex')); |
| 405 | + $smilTransitionElement.attr( attributeKey, '#' + color.val('hex') ); |
| 406 | + _editTransitions.onChange( _this, smilElement ); |
| 407 | + } |
| 408 | + ) |
| 409 | + // adjust the position of the color button: |
| 410 | + $editTransitionsSet.find('.jColorPicker .Icon').css('top', '-5px'); |
| 411 | + } |
| 412 | + }) |
| 413 | + return $editTransitionsSet; |
| 414 | + }, |
| 415 | + /** |
| 416 | + * Could move to a more central location if we use the color picker other places |
| 417 | + */ |
| 418 | + colorPickerConfig: { |
| 419 | + 'window' : { |
| 420 | + 'expandable': true, |
| 421 | + 'effects' : { |
| 422 | + 'type' : 'show' |
| 423 | + }, |
| 424 | + 'position' : { |
| 425 | + 'x' : '10px', |
| 426 | + 'y' : 'bottom' |
| 427 | + } |
| 428 | + }, |
| 429 | + 'images' : { |
| 430 | + 'clientPath' : mw.getMwEmbedPath() + 'modules/Sequencer/tools/jPicker/images/' |
| 431 | + }, |
| 432 | + 'localization' : { |
| 433 | + 'text' : { |
| 434 | + 'title' : gM('mwe-sequencer-color-picker-title'), |
| 435 | + 'newColor' : gM('mwe-sequencer-menu-sequence-new'), |
| 436 | + 'currentColor' : gM('mwe-sequencer-color-picker-current'), |
| 437 | + 'ok' : gM('mwe-ok'), |
| 438 | + 'cancel': gM('mwe-cancel') |
| 439 | + }, |
| 440 | + 'tooltips':{ |
| 441 | + 'colors': |
| 442 | + { |
| 443 | + 'newColor': gM('mwe-sequencer-color-picker-new-color'), |
| 444 | + 'currentColor': gM('mwe-sequencer-color-picker-currentColor') |
| 445 | + }, |
| 446 | + 'buttons': |
| 447 | + { |
| 448 | + ok: gM('mwe-sequencer-color-picker-commit' ), |
| 449 | + cancel: gM('mwe-sequencer-color-picker-cancel-desc') |
| 450 | + }, |
| 451 | + 'hue': |
| 452 | + { |
| 453 | + radio: gM('mwe-sequencer-color-picker-hue-desc'), |
| 454 | + textbox: gM('mwe-sequencer-color-picker-hue-textbox') |
| 455 | + }, |
| 456 | + 'saturation': |
| 457 | + { |
| 458 | + radio: gM('mwe-sequencer-color-picker-saturation-desc'), |
| 459 | + textbox: gM('mwe-sequencer-color-picker-saturation-textbox') |
| 460 | + }, |
| 461 | + 'value': |
| 462 | + { |
| 463 | + radio: gM('mwe-sequencer-color-picker-value-desc'), |
| 464 | + textbox: gM('mwe-sequencer-color-picker-value-textbox') |
| 465 | + }, |
| 466 | + 'red': |
| 467 | + { |
| 468 | + radio: gM('mwe-sequencer-color-picker-red-desc'), |
| 469 | + textbox: gM('mwe-sequencer-color-picker-red-textbox') |
| 470 | + }, |
| 471 | + 'green': |
| 472 | + { |
| 473 | + radio: gM('mwe-sequencer-color-picker-green-desc'), |
| 474 | + textbox: gM('mwe-sequencer-color-picker-green-textbox') |
| 475 | + }, |
| 476 | + 'blue': |
| 477 | + { |
| 478 | + radio: gM('mwe-sequencer-color-picker-blue-desc'), |
| 479 | + textbox: gM('mwe-sequencer-color-picker-blue-textbox') |
| 480 | + }, |
| 481 | + 'alpha': |
| 482 | + { |
| 483 | + radio: gM('mwe-sequencer-color-picker-alpha-desc'), |
| 484 | + textbox: gM('mwe-sequencer-color-picker-alpha-textbox') |
| 485 | + }, |
| 486 | + 'hex': |
| 487 | + { |
| 488 | + textbox: gM('mwe-sequencer-color-picker-hex-desc'), |
| 489 | + alpha: gM('mwe-sequencer-color-picker-hex-textbox') |
| 490 | + } |
| 491 | + } |
| 492 | + |
| 493 | + } |
| 494 | + }, |
| 495 | + |
| 496 | + 'onChange': function( _this, smilElement ){ |
| 497 | + // Update the sequence duration : |
| 498 | + _this.sequencer.getEmbedPlayer().getDuration( true ); |
| 499 | + |
| 500 | + // xxx we should re-display the current time |
| 501 | + _this.sequencer.getEmbedPlayer().setCurrentTime( |
| 502 | + $j( smilElement ).data('startOffset') |
| 503 | + ); |
| 504 | + }, |
| 505 | + 'draw': function( _this, target, smilElement ){ |
| 506 | + // draw the two attribute types |
| 507 | + var _editTransitions = this; |
| 508 | + var $transitionWidget = $j('<div />'); |
| 509 | + |
| 510 | + var transitionDirections = ['transIn', 'transOut']; |
| 511 | + $j.each(transitionDirections, function( inx, transitionDirection ){ |
| 512 | + $transitionWidget.append( |
| 513 | + $j('<div />').css('clear', 'both') |
| 514 | + , |
| 515 | + $j('<h3 />').text( gM('mwe-sequencer-tools-transitions-' + transitionDirection )) |
| 516 | + ) |
| 517 | + // Output the top level empty select |
| 518 | + $transSelect = $j('<select />').append( |
| 519 | + $j('<option />') |
| 520 | + .attr('value', '') |
| 521 | + ); |
| 522 | + var selectedTransitionType = _editTransitions.getSelectedTransitionType( smilElement, transitionDirection); |
| 523 | + for( var transitionType in _editTransitions.transitionTypes ){ |
| 524 | + if( _editTransitions.transitionTypes[ transitionType ].selectable |
| 525 | + && |
| 526 | + $j.inArray( transitionDirection, _editTransitions.transitionTypes[transitionType].selectable ) !== -1 ) |
| 527 | + { |
| 528 | + // Output the item if its selectable for the current transitionType |
| 529 | + var $option = $j("<option />") |
| 530 | + .attr('value', transitionType ) |
| 531 | + .text( transitionType ) |
| 532 | + // Add selected attribute if selected: |
| 533 | + if( selectedTransitionType == transitionType ){ |
| 534 | + $option.attr('selected', 'true'); |
| 535 | + } |
| 536 | + $transSelect.append( $option ); |
| 537 | + } |
| 538 | + } |
| 539 | + $transSelect.change( function(){ |
| 540 | + var transitionType = $j(this).val(); |
| 541 | + $transitionWidget.find( '#' + transitionDirection + '_attributeContainer' ).html( |
| 542 | + _editTransitions.getBindedTranstionEdit( |
| 543 | + _this, smilElement, transitionType |
| 544 | + ) |
| 545 | + ) |
| 546 | + // Update the smil attribute: |
| 547 | + $j( smilElement ).attr( |
| 548 | + transitionDirection, |
| 549 | + _editTransitions.getTransitionId( smilElement, transitionType ) |
| 550 | + ) |
| 551 | + // Update the player on select change |
| 552 | + _editTransitions.onChange( _this, smilElement ); |
| 553 | + }); |
| 554 | + |
| 555 | + // Add the select to the $transitionWidget |
| 556 | + $transitionWidget.append( $transSelect ); |
| 557 | + |
| 558 | + // Set up the transConfig container: |
| 559 | + var $transConfig = $j('<span />') |
| 560 | + .attr('id', transitionDirection + '_attributeContainer'); |
| 561 | + |
| 562 | + // If a given transition type is selected output is editable attributes |
| 563 | + if( selectedTransitionType != '' ) { |
| 564 | + $transConfig.append( |
| 565 | + _editTransitions.getBindedTranstionEdit( |
| 566 | + _this, smilElement, selectedTransitionType |
| 567 | + ) |
| 568 | + ) |
| 569 | + } |
| 570 | + $transitionWidget.append( $transConfig ); |
| 571 | + |
| 572 | + // update the player for the default selected set. |
| 573 | + _editTransitions.onChange( _this, smilElement ); |
| 574 | + }); |
| 575 | + // add the transition widget to the target |
| 576 | + $j( target ).append( $transitionWidget ); |
| 577 | + } |
| 578 | + }, |
| 579 | + 'editTemplate':{ |
| 580 | + 'onChange' : function( _this, smilElement ){ |
| 581 | + // Clear the smilElement template cache: |
| 582 | + $j( smilElement ).data('templateHtmlCache', null); |
| 583 | + // Re draw the smilElement in the player |
| 584 | + var smil = _this.sequencer.getSmil(); |
| 585 | + $playerTarget = $j('#' + smil.getSmilElementPlayerID( smilElement ) ); |
| 586 | + $playerTarget.loadingSpinner(); |
| 587 | + smil.getLayout().getSmilTemplateHtml( smilElement, $playerTarget, function(){ |
| 588 | + mw.log("SequencerTools::editWidgets: smil template updated"); |
| 589 | + }); |
| 590 | + }, |
| 591 | + 'draw': function( _this, target, smilElement ){ |
| 592 | + // Parse the set of templates from the template text cache |
| 593 | + $j( target ).loadingSpinner(); |
| 594 | + |
| 595 | + if( ! $j( smilElement).attr('apititlekey') ){ |
| 596 | + mw.log("Error: can't grab template without title key") |
| 597 | + return ; |
| 598 | + } |
| 599 | + // Get the template wikitext |
| 600 | + _this.sequencer |
| 601 | + .getServer() |
| 602 | + .getTemplateText( $j( smilElement).attr('apititlekey'), function( templateText ){ |
| 603 | + //mw.log("GotTemplateText: " + templateText ); |
| 604 | + if( ! templateText || typeof templateText != 'string' ){ |
| 605 | + mw.log("Error: could not get wikitext form titlekey: " + $j( smilElement).attr('apititlekey')) |
| 606 | + return ; |
| 607 | + } |
| 608 | + $j( target ).empty().append( |
| 609 | + $j('<h3 />').text( gM('mwe-sequencer-editTemplate-params') ) |
| 610 | + ) |
| 611 | + |
| 612 | + // This is not supposed to be perfect .. |
| 613 | + // just get you 'most' of the input vars 'most' of the time via the greedy regEx: |
| 614 | + var templateVars = templateText.match(/\{\{\{([^\}]*)\}\}\}/gi); |
| 615 | + var cleanTemplateParams = {}; |
| 616 | + |
| 617 | + for( i =0;i<templateVars.length; i++ ){ |
| 618 | + var tVar = templateVars[i]; |
| 619 | + // Remove all {{{ and }}} |
| 620 | + tVar = tVar.replace(/\{\{\{/, '' ).replace( /\}\}\}/, ''); |
| 621 | + // Check for | operator |
| 622 | + if( tVar.indexOf("|") != -1 ){ |
| 623 | + // Only the first version of the template var |
| 624 | + tVar = tVar.split( '|')[0]; |
| 625 | + } |
| 626 | + cleanTemplateParams[ tVar ] = true; |
| 627 | + } |
| 628 | + // Output input boxes for each template var as a param |
| 629 | + for( var paramName in cleanTemplateParams ){ |
| 630 | + $j( target ).append( |
| 631 | + _this.getEditableAttribute( |
| 632 | + smilElement, |
| 633 | + 'editTemplate', |
| 634 | + 'param', |
| 635 | + paramName |
| 636 | + ) |
| 637 | + .find('input') |
| 638 | + // Bind the change event: |
| 639 | + .change(function(){ |
| 640 | + _this.editWidgets.editTemplate.onChange( |
| 641 | + _this, |
| 642 | + smilElement |
| 643 | + ) |
| 644 | + }) |
| 645 | + .parent() |
| 646 | + , |
| 647 | + $j('<div />') |
| 648 | + .css('clear', 'both') |
| 649 | + ) |
| 650 | + } |
| 651 | + |
| 652 | + |
| 653 | + }); |
| 654 | + } |
| 655 | + }, |
| 656 | + 'panzoom' : { |
| 657 | + 'onChange': function( _this, smilElement ){ |
| 658 | + var panZoomVal = $j('#' +_this.getEditToolInputId( 'panzoom', 'panZoom')).val(); |
| 659 | + mw.log("panzoom change:" + panZoomVal ); |
| 660 | + |
| 661 | + // Update on the current smil clip display: |
| 662 | + _this.sequencer.getSmil() |
| 663 | + .getLayout() |
| 664 | + .panZoomLayout( |
| 665 | + smilElement |
| 666 | + ); |
| 667 | + var $thumbTraget = $j( '#' + _this.sequencer.getTimeline().getTimelineClipId( smilElement ) ).find('.thumbTraget'); |
| 668 | + // Update the timeline clip display |
| 669 | + // xxx this should be abstracted to timeline handler for clip updates |
| 670 | + _this.sequencer.getSmil() |
| 671 | + .getLayout() |
| 672 | + .panZoomLayout( |
| 673 | + smilElement, |
| 674 | + $thumbTraget, |
| 675 | + $thumbTraget.find('img').get(0) |
| 676 | + ) |
| 677 | + // Register the change for undo redo |
| 678 | + _this.sequencer.getActionsEdit().registerEdit(); |
| 679 | + }, |
| 680 | + 'draw': function( _this, target, smilElement ){ |
| 681 | + var orginalHelperCss = { |
| 682 | + 'position' : 'absolute', |
| 683 | + 'width' : 100, |
| 684 | + 'height' : 75, |
| 685 | + 'top' : 50, |
| 686 | + 'left' : 70, |
| 687 | + 'font-size' : 'x-small' |
| 688 | + }; |
| 689 | + // Add a input box binding: |
| 690 | + $j('#' +_this.getEditToolInputId( 'panzoom', 'panZoom')) |
| 691 | + .change(function(){ |
| 692 | + _this.editWidgets.panzoom.onChange( _this, smilElement, target ); |
| 693 | + }) |
| 694 | + |
| 695 | + $j( target ).append( |
| 696 | + $j('<h3 />').html( |
| 697 | + gM('mwe-sequencer-tools-panzoomhelper-desc') |
| 698 | + ) |
| 699 | + , |
| 700 | + /*xxx Keep aspect button ?*/ |
| 701 | + // Rest layout button ( restores default position ) |
| 702 | + $j.button({ |
| 703 | + 'icon' : 'arrow-4', |
| 704 | + 'text' : gM( 'mwe-sequencer-tools-panzoomhelper-resetlayout' ) |
| 705 | + }) |
| 706 | + .attr('id', 'panzoomResetLayout') |
| 707 | + .css('float', 'left') |
| 708 | + .hide() |
| 709 | + .click(function(){ |
| 710 | + // Restore default SMIL setting |
| 711 | + _this.editableTypes['display'].update( |
| 712 | + _this, |
| 713 | + smilElement, |
| 714 | + 'panzoom', |
| 715 | + _this.editableAttributes['panzoom'].defaultValue |
| 716 | + ) |
| 717 | + }) |
| 718 | + , |
| 719 | + $j('<div />') |
| 720 | + .css({ |
| 721 | + 'border' : '1px solid #DDDDDD', |
| 722 | + 'float' : 'left', |
| 723 | + 'position' : 'relative', |
| 724 | + 'width': '240px', |
| 725 | + 'height' : '180px', |
| 726 | + 'overflow' : 'hidden' |
| 727 | + }) |
| 728 | + .append( |
| 729 | + $j('<div />') |
| 730 | + .css( orginalHelperCss ) |
| 731 | + .attr({ |
| 732 | + 'id': "panzoomHelper" |
| 733 | + }) |
| 734 | + .addClass("ui-widget-content") |
| 735 | + .text( gM('mwe-sequencer-tools-panzoomhelper') ) |
| 736 | + ) |
| 737 | + ); |
| 738 | + var startPanZoomVal = ''; |
| 739 | + var setStartPanZoomVal = function(){ |
| 740 | + startPanZoomVal = $j( smilElement ).attr( 'panZoom'); |
| 741 | + if(! startPanZoomVal ){ |
| 742 | + startPanZoomVal = _this.editableAttributes['panZoom'].defaultValue; |
| 743 | + } |
| 744 | + } |
| 745 | + |
| 746 | + var updatePanZoomFromUiValue = function( layout ){ |
| 747 | + var pz = startPanZoomVal.split(','); |
| 748 | + // Set the new percent offset to x/2 |
| 749 | + if( layout.left ){ |
| 750 | + pz[0] = ( parseInt( pz[0] ) - ( layout.left / 4 ) ) + '%'; |
| 751 | + } |
| 752 | + |
| 753 | + if( layout.top ){ |
| 754 | + pz[1] = ( parseInt( pz[1] ) - ( layout.top / 4 ) )+ '%'; |
| 755 | + } |
| 756 | + |
| 757 | + if( layout.width ) { |
| 758 | + pz[2] = ( parseInt( pz[2] ) - ( layout.width / 2) ) + '%' |
| 759 | + |
| 760 | + // right now only keep aspect is supported do size hack:: |
| 761 | + pz[3] = parseInt( pz[2] ) * _this.sequencer.getSmil().getLayout().getTargetAspectRatio(); |
| 762 | + // only have 2 significant digits |
| 763 | + |
| 764 | + } |
| 765 | + // Trim and round all % values |
| 766 | + for(var i=0; i < pz.length; i++){ |
| 767 | + pz[i] = ( Math.round( parseInt( pz[i] ) * 1000 ) / 1000 ) + '%'; |
| 768 | + pz[i] = $j.trim( pz[i] ); |
| 769 | + } |
| 770 | + var smilPanZoomValue = pz.join(', '); |
| 771 | + |
| 772 | + // Update the smil DOM: |
| 773 | + $j( smilElement ).attr( 'panZoom', smilPanZoomValue ); |
| 774 | + |
| 775 | + // Update the user input tool input value: |
| 776 | + $j('#' +_this.getEditToolInputId( 'panzoom', 'panZoom')).val( smilPanZoomValue ); |
| 777 | + |
| 778 | + // Animate the update on the current smil clip display: |
| 779 | + _this.sequencer.getSmil() |
| 780 | + .getLayout() |
| 781 | + .panZoomLayout( |
| 782 | + smilElement |
| 783 | + ); |
| 784 | + } |
| 785 | + // Add bindings |
| 786 | + $j('#panzoomHelper') |
| 787 | + .draggable({ |
| 788 | + containment: 'parent', |
| 789 | + start: function( event, ui){ |
| 790 | + setStartPanZoomVal(); |
| 791 | + }, |
| 792 | + drag: function( event, ui){ |
| 793 | + updatePanZoomFromUiValue({ |
| 794 | + 'top' : ( orginalHelperCss.top - ui.position.top ), |
| 795 | + 'left' : ( orginalHelperCss.left - ui.position.left ) |
| 796 | + }); |
| 797 | + }, |
| 798 | + stop: function( event, ui){ |
| 799 | + // run the onChange ? |
| 800 | + // Restore original css for the layout helper |
| 801 | + $j(this).css( orginalHelperCss ) |
| 802 | + // trigger the 'change' |
| 803 | + _this.editWidgets.panzoom.onChange( _this, smilElement ); |
| 804 | + } |
| 805 | + }) |
| 806 | + .css('cursor', 'move') |
| 807 | + .resizable({ |
| 808 | + handles : 'all', |
| 809 | + maxWidth : 170, |
| 810 | + maxHeight: 130, |
| 811 | + aspectRatio: 4/3, |
| 812 | + start: function( event, ui){ |
| 813 | + setStartPanZoomVal(); |
| 814 | + }, |
| 815 | + resize : function(event, ui){ |
| 816 | + updatePanZoomFromUiValue({ |
| 817 | + 'width' : ( orginalHelperCss.width - ui.size.width ), |
| 818 | + 'height' : ( orginalHelperCss.top - ui.size.height ) |
| 819 | + }); |
| 820 | + }, |
| 821 | + stop: function( event, ui){ |
| 822 | + // Restore original css |
| 823 | + $j(this).css( orginalHelperCss ) |
| 824 | + // trigger the change |
| 825 | + _this.editWidgets.panzoom.onChange( _this, smilElement); |
| 826 | + } |
| 827 | + }) |
| 828 | + |
| 829 | + } |
| 830 | + }, |
| 831 | + 'trimTimeline' : { |
| 832 | + 'onChange': function( _this, smilElement ){ |
| 833 | + var smil = _this.sequencer.getSmil(); |
| 834 | + // Update the preview thumbs |
| 835 | + var $target = $j( '#editWidgets_trimTimeline' ); |
| 836 | + // (local function so it can be updated after the start time is done with its draw ) |
| 837 | + var updateDurationThumb = function(){ |
| 838 | + // Check the duration: |
| 839 | + var clipDur = $j('#editTool_trim_dur').val(); |
| 840 | + if( clipDur ){ |
| 841 | + // Render a thumbnail for the updated duration |
| 842 | + smil.getLayout().drawSmilElementToTarget( |
| 843 | + smilElement, |
| 844 | + $target.find('.trimEndThumb'), |
| 845 | + clipDur |
| 846 | + ); |
| 847 | + } |
| 848 | + } |
| 849 | + |
| 850 | + var clipBeginTime = $j('#editTool_trim_clipBegin').val(); |
| 851 | + if( !clipBeginTime ){ |
| 852 | + $target.find('.trimStartThumb').hide(); |
| 853 | + } else { |
| 854 | + mw.log("Should update trimStartThumb::" + $j(smilElement).attr('clipBegin') ); |
| 855 | + // Render a thumbnail for relative start time = 0 |
| 856 | + smil.getLayout().drawSmilElementToTarget( |
| 857 | + smilElement, |
| 858 | + $target.find('.trimStartThumb'), |
| 859 | + 0, |
| 860 | + updateDurationThumb() |
| 861 | + ) |
| 862 | + } |
| 863 | + }, |
| 864 | + // Return the trimTimeline edit widget |
| 865 | + 'draw': function( _this, target, smilElement ){ |
| 866 | + var smil = _this.sequencer.getSmil(); |
| 867 | + // check if thumbs are supported |
| 868 | + if( _this.sequencer.getSmil().getRefType( smilElement ) == 'video' ){ |
| 869 | + $j(target).append( |
| 870 | + $j('<div />') |
| 871 | + .addClass( 'trimStartThumb ui-corner-all' ), |
| 872 | + $j('<div />') |
| 873 | + .addClass( 'trimEndThumb ui-corner-all' ), |
| 874 | + $j('<div />').addClass('ui-helper-clearfix') |
| 875 | + ) |
| 876 | + } |
| 877 | + // The local scope fullClipDuration |
| 878 | + var fullClipDuration = null; |
| 879 | + |
| 880 | + // Some slider functions |
| 881 | + var sliderToTime = function( sliderval ){ |
| 882 | + return parseInt( fullClipDuration * ( sliderval / 1000 ) ); |
| 883 | + } |
| 884 | + var timeToSlider = function( time ){ |
| 885 | + return parseInt( ( time / fullClipDuration ) * 1000 ); |
| 886 | + } |
| 887 | + |
| 888 | + |
| 889 | + var onInputChange = function( sliderIndex, timeValue ){ |
| 890 | + // Register the change |
| 891 | + _this.editWidgets.trimTimeline.onChange( _this, smilElement ); |
| 892 | + // Update the slider |
| 893 | + if( fullClipDuration ){ |
| 894 | + $j('#'+_this.sequencer.id + '_trimTimeline' ) |
| 895 | + .slider( |
| 896 | + "values", |
| 897 | + sliderIndex, |
| 898 | + timeToSlider( timeValue ) |
| 899 | + ); |
| 900 | + } |
| 901 | + } |
| 902 | + |
| 903 | + // Add a trim binding: |
| 904 | + $j('#' + _this.getEditToolInputId( 'trim', 'clipBegin') ) |
| 905 | + .change( function(){ |
| 906 | + var timeValue = smil.parseTime( $j(this).val() ); |
| 907 | + onInputChange( 0, timeValue); |
| 908 | + }); |
| 909 | + |
| 910 | + $j('#' + _this.getEditToolInputId( 'trim', 'dur') ) |
| 911 | + .change( function(){ |
| 912 | + var timeValue = smil.parseTime( $j(this).val() ) + |
| 913 | + smil.parseTime( $j('#' + _this.getEditToolInputId( 'trim', 'clipBegin') ).val() ); |
| 914 | + onInputChange( 1, timeValue ); |
| 915 | + }); |
| 916 | + |
| 917 | + // Update the thumbnails: |
| 918 | + _this.editWidgets.trimTimeline.onChange( _this, smilElement ); |
| 919 | + |
| 920 | + // Get the clip full duration to build out the timeline selector |
| 921 | + smil.getBody().getClipAssetDuration( smilElement, function( clipDuration ) { |
| 922 | + // update the local scope global |
| 923 | + fullClipDuration = clipDuration; |
| 924 | + |
| 925 | + var startSlider = timeToSlider( smil.parseTime( $j('#editTool_trim_clipBegin').val() ) ); |
| 926 | + var sliderValues = [ |
| 927 | + startSlider, |
| 928 | + startSlider + timeToSlider( smil.parseTime( $j('#editTool_trim_dur').val() ) ) |
| 929 | + ]; |
| 930 | + // Return a trim tool binded to smilElement id update value events. |
| 931 | + $j(target).append( |
| 932 | + $j('<div />') |
| 933 | + .attr( 'id', _this.sequencer.id + '_trimTimeline' ) |
| 934 | + .css({ |
| 935 | + 'position': 'absolute', |
| 936 | + 'left' : '25px', |
| 937 | + 'right' : '35px', |
| 938 | + 'margin': '5px' |
| 939 | + }) |
| 940 | + .slider({ |
| 941 | + range: true, |
| 942 | + min: 0, |
| 943 | + max: 1000, |
| 944 | + values: sliderValues, |
| 945 | + slide: function(event, ui) { |
| 946 | + |
| 947 | + $j('#' + _this.getEditToolInputId( 'trim', 'clipBegin') ).val( |
| 948 | + mw.seconds2npt( sliderToTime( ui.values[0] ), true ) |
| 949 | + ); |
| 950 | + $j('#' + _this.getEditToolInputId( 'trim', 'dur') ).val( |
| 951 | + mw.seconds2npt( sliderToTime( ui.values[1] - ui.values[0] ), true ) |
| 952 | + ); |
| 953 | + }, |
| 954 | + change: function( event, ui ) { |
| 955 | + var attributeValue = 0, sliderIndex = 0; |
| 956 | + |
| 957 | + // Update clipBegin |
| 958 | + _this.editableTypes['time'].update( _this, smilElement, 'clipBegin', sliderToTime( ui.values[ 0 ] ) ); |
| 959 | + |
| 960 | + // Update dur |
| 961 | + _this.editableTypes['time'].update( _this, smilElement, 'dur', sliderToTime( ui.values[ 1 ]- ui.values[0] ) ); |
| 962 | + |
| 963 | + // update the widget display |
| 964 | + _this.editWidgets.trimTimeline.onChange( _this, smilElement ); |
| 965 | + |
| 966 | + // Register the edit state for undo / redo |
| 967 | + _this.sequencer.getActionsEdit().registerEdit(); |
| 968 | + |
| 969 | + } |
| 970 | + }) |
| 971 | + ); |
| 972 | + }); |
| 973 | + // On resize event |
| 974 | + |
| 975 | + // Fill in timeline images |
| 976 | + |
| 977 | + } |
| 978 | + } |
| 979 | + }, |
| 980 | + getDefaultText: function(){ |
| 981 | + return gM('mwe-sequencer-no_selected_resource'); |
| 982 | + }, |
| 983 | + setDefaultText: function(){ |
| 984 | + this.sequencer.getEditToolTarget().html( |
| 985 | + this.getDefaultText() |
| 986 | + ) |
| 987 | + }, |
| 988 | + getEditToolInputId: function( toolId, attributeName){ |
| 989 | + return 'editTool_' + toolId + '_' + attributeName.replace('/\s/', ''); |
| 990 | + }, |
| 991 | + /** |
| 992 | + * update the current displayed tool ( when an undo, redo or history jump changes smil state ) |
| 993 | + */ |
| 994 | + updateToolDisplay: function(){ |
| 995 | + var _this = this; |
| 996 | + |
| 997 | + // If tools are displayed update them |
| 998 | + if( this.sequencer.getEditToolTarget().find('.editToolsContainer').lenght ){ |
| 999 | + this.drawClipEditTools() |
| 1000 | + } |
| 1001 | + |
| 1002 | + }, |
| 1003 | + getToolSet: function( refType ){ |
| 1004 | + var toolSet = []; |
| 1005 | + for( var toolId in this.tools){ |
| 1006 | + if( this.tools[ toolId ].contentTypes){ |
| 1007 | + if( $j.inArray( refType, this.tools[ toolId ].contentTypes) != -1 ){ |
| 1008 | + toolSet.push( toolId ); |
| 1009 | + } |
| 1010 | + } |
| 1011 | + } |
| 1012 | + return toolSet; |
| 1013 | + }, |
| 1014 | + drawClipEditTools: function( smilElement, selectedToolId ){ |
| 1015 | + var _this = this; |
| 1016 | + |
| 1017 | + // Update the current clip and tool : |
| 1018 | + if( smilElement ){ |
| 1019 | + this.setCurrentsmilElement( smilElement ); |
| 1020 | + } |
| 1021 | + if( selectedToolId ){ |
| 1022 | + this.setCurrentToolId( selectedToolId ); |
| 1023 | + } |
| 1024 | + |
| 1025 | + $toolsContainer = $j('<div />') |
| 1026 | + .addClass( 'editToolsContainer' ) |
| 1027 | + .css( { |
| 1028 | + 'overflow': 'auto', |
| 1029 | + 'position':'absolute', |
| 1030 | + 'top' : '0px', |
| 1031 | + 'left': '0px', |
| 1032 | + 'right': '0px', |
| 1033 | + 'bottom': '37px' |
| 1034 | + }) |
| 1035 | + .append( |
| 1036 | + $j('<ul />') |
| 1037 | + ); |
| 1038 | + |
| 1039 | + this.sequencer.getEditToolTarget().empty().append( |
| 1040 | + $toolsContainer |
| 1041 | + ); |
| 1042 | + // Get the entire tool set based on what "ref type" smilElement is: |
| 1043 | + var toolSet = this.getToolSet( |
| 1044 | + this.sequencer.getSmil().getRefType( |
| 1045 | + this.getCurrentsmilElement() |
| 1046 | + ) |
| 1047 | + ); |
| 1048 | + mw.log( 'Adding ' + toolSet.length + ' tools for ' + |
| 1049 | + this.sequencer.getSmil().getRefType( this.getCurrentsmilElement() ) + |
| 1050 | + ' current tool: ' + _this.getCurrentToolId() |
| 1051 | + ); |
| 1052 | + |
| 1053 | + var toolTabIndex = 0; |
| 1054 | + $j.each( toolSet, function( inx, toolId ){ |
| 1055 | + |
| 1056 | + var tool = _this.tools[ toolId ]; |
| 1057 | + if( _this.getCurrentToolId() == toolId){ |
| 1058 | + toolTabIndex = inx; |
| 1059 | + } |
| 1060 | + // Append the title to the ul list |
| 1061 | + $toolsContainer.find( 'ul').append( |
| 1062 | + $j('<li />').append( |
| 1063 | + $j('<a />') |
| 1064 | + .attr('href', '#tooltab_' + toolId ) |
| 1065 | + .text( gM('mwe-sequencer-tools-' + toolId) ) |
| 1066 | + ) |
| 1067 | + ); |
| 1068 | + |
| 1069 | + // Append the tooltab container |
| 1070 | + $toolsContainer.append( |
| 1071 | + $j('<div />') |
| 1072 | + .css({'height' : '100%' }) |
| 1073 | + .attr('id', 'tooltab_' + toolId ) |
| 1074 | + .append( |
| 1075 | + $j('<h3 />').text( gM('mwe-sequencer-tools-' + toolId + '-desc') ) |
| 1076 | + ) |
| 1077 | + ) |
| 1078 | + var $toolContainer = $toolsContainer.find( '#tooltab_' + toolId ); |
| 1079 | + |
| 1080 | + // Build out the attribute list for the given tool ( if the tool has directly editable attributes ) |
| 1081 | + if( tool.editableAttributes ){ |
| 1082 | + for( var i=0; i < tool.editableAttributes.length ; i++ ){ |
| 1083 | + attributeName = tool.editableAttributes[i]; |
| 1084 | + $toolContainer.append( |
| 1085 | + _this.getEditableAttribute( smilElement, toolId, attributeName ) |
| 1086 | + ); |
| 1087 | + } |
| 1088 | + } |
| 1089 | + |
| 1090 | + // Output a float divider: |
| 1091 | + $toolContainer.append( $j('<div />').addClass('ui-helper-clearfix') ); |
| 1092 | + |
| 1093 | + // Build out tool widgets |
| 1094 | + if( tool.editWidgets ){ |
| 1095 | + for( var i =0 ; i < tool.editWidgets.length ; i ++ ){ |
| 1096 | + var editWidgetId = tool.editWidgets[i]; |
| 1097 | + if( ! _this.editWidgets[editWidgetId] ){ |
| 1098 | + mw.log("Error: not recogonized widget: " + editWidgetId); |
| 1099 | + continue; |
| 1100 | + } |
| 1101 | + // Append a target for the edit widget: |
| 1102 | + $toolContainer.append( |
| 1103 | + $j('<div />') |
| 1104 | + .attr('id', 'editWidgets_' + editWidgetId) |
| 1105 | + ); |
| 1106 | + // Draw the binded widget: |
| 1107 | + _this.editWidgets[editWidgetId].draw( |
| 1108 | + _this, |
| 1109 | + $j( '#editWidgets_' + editWidgetId ), |
| 1110 | + smilElement |
| 1111 | + ) |
| 1112 | + // Output a float divider: |
| 1113 | + $toolContainer.append( $j('<div />').addClass( 'ui-helper-clearfix' ) ); |
| 1114 | + } |
| 1115 | + } |
| 1116 | + }); |
| 1117 | + |
| 1118 | + // Add tab bindings |
| 1119 | + $toolsContainer.tabs({ |
| 1120 | + select: function(event, ui) { |
| 1121 | + _this.setCurrentToolId( $j( ui.tab ).attr('href').replace('#tooltab_', '') ); |
| 1122 | + }, |
| 1123 | + selected : toolTabIndex |
| 1124 | + }); |
| 1125 | + |
| 1126 | + var $editActions = $j('<div />') |
| 1127 | + .css({ |
| 1128 | + 'position' : 'absolute', |
| 1129 | + 'bottom' : '0px', |
| 1130 | + 'height' : '37px', |
| 1131 | + 'left' : '0px', |
| 1132 | + 'right' : '0px', |
| 1133 | + 'overflow' : 'auto' |
| 1134 | + }); |
| 1135 | + // Build out global edit Actions buttons after the container |
| 1136 | + for( var editActionId in this.editActions ){ |
| 1137 | + // Check if the edit action has a conditional display: |
| 1138 | + var displayEidtAction = true; |
| 1139 | + |
| 1140 | + if( this.editActions[ editActionId ].displayCheck ){ |
| 1141 | + displayEidtAction = this.editActions[ editActionId ].displayCheck( _this, smilElement ); |
| 1142 | + } |
| 1143 | + if( displayEidtAction ){ |
| 1144 | + $editActions.append( |
| 1145 | + this.getEditAction( smilElement, editActionId ) |
| 1146 | + ) |
| 1147 | + } |
| 1148 | + } |
| 1149 | + $j( this.sequencer.getEditToolTarget() ).append( $editActions ) |
| 1150 | + }, |
| 1151 | + getCurrentsmilElement: function(){ |
| 1152 | + return this.currentsmilElement; |
| 1153 | + }, |
| 1154 | + setCurrentsmilElement: function( smilElement ){ |
| 1155 | + this.currentsmilElement = smilElement; |
| 1156 | + }, |
| 1157 | + getCurrentToolId: function(){ |
| 1158 | + return this.currentToolId; |
| 1159 | + }, |
| 1160 | + setCurrentToolId: function( toolId ){ |
| 1161 | + this.currentToolId = toolId; |
| 1162 | + }, |
| 1163 | + |
| 1164 | + getEditAction: function( smilElement, editActionId ){ |
| 1165 | + if(! this.editActions[ editActionId ]){ |
| 1166 | + mw.log("Error: getEditAction: " + editActionId + ' not found '); |
| 1167 | + return ; |
| 1168 | + } |
| 1169 | + var _this = this; |
| 1170 | + var editAction = this.editActions[ editActionId ]; |
| 1171 | + $actionButton = $j.button({ |
| 1172 | + icon: editAction.icon, |
| 1173 | + text: editAction.title |
| 1174 | + }) |
| 1175 | + .css({ |
| 1176 | + 'float': 'left', |
| 1177 | + 'margin': '5px' |
| 1178 | + }) |
| 1179 | + .click( function(){ |
| 1180 | + return editAction.action( this, _this, smilElement ); |
| 1181 | + }) |
| 1182 | + return $actionButton; |
| 1183 | + }, |
| 1184 | + /* get the editiable attribute input html */ |
| 1185 | + getEditableAttribute: function( smilElement, toolId, attributeName, paramName ){ |
| 1186 | + if( ! this.editableAttributes[ attributeName ] ){ |
| 1187 | + mw.log("Error: editableAttributes : " + attributeName + ' not found'); |
| 1188 | + return; |
| 1189 | + } |
| 1190 | + |
| 1191 | + |
| 1192 | + var _this = this; |
| 1193 | + var editAttribute = this.editableAttributes[ attributeName ]; |
| 1194 | + var editType = editAttribute.type; |
| 1195 | + if( !_this.editableTypes[ editType ] ){ |
| 1196 | + mw.log(" Error: No editableTypes interface for " + editType); |
| 1197 | + return ; |
| 1198 | + } |
| 1199 | + |
| 1200 | + // Set the update key to the paramName if provided: |
| 1201 | + var updateKey = ( paramName ) ? paramName : attributeName; |
| 1202 | + |
| 1203 | + var initialValue = _this.editableTypes[ editType ].getSmilVal( |
| 1204 | + _this, |
| 1205 | + smilElement, |
| 1206 | + updateKey |
| 1207 | + ); |
| 1208 | + // Set the default input size |
| 1209 | + var inputSize = ( _this.editableAttributes[ attributeName ].inputSize)? |
| 1210 | + _this.editableAttributes[ attributeName ].inputSize : 6; |
| 1211 | + |
| 1212 | + // Set paramName based attributes: |
| 1213 | + var attributeTitle = ( editAttribute.title ) ? editAttribute.title : paramName + ':'; |
| 1214 | + |
| 1215 | + return _this.getInputBox({ |
| 1216 | + 'title' : attributeTitle, |
| 1217 | + 'inputId' : _this.getEditToolInputId( toolId, updateKey ), |
| 1218 | + 'inputSize': inputSize, |
| 1219 | + 'initialValue' : initialValue, |
| 1220 | + 'change': function(){ |
| 1221 | + // Run the editableType update function: |
| 1222 | + _this.editableTypes[ editType ].update( |
| 1223 | + _this, |
| 1224 | + smilElement, |
| 1225 | + updateKey, |
| 1226 | + $j( this ).val() |
| 1227 | + ); |
| 1228 | + } |
| 1229 | + }) |
| 1230 | + }, |
| 1231 | + getInputBox: function( config ){ |
| 1232 | + var _this = this; |
| 1233 | + return $j( '<div />' ) |
| 1234 | + .css({ |
| 1235 | + 'float': 'left', |
| 1236 | + 'font-size': '12px', |
| 1237 | + 'border': 'solid thin #999', |
| 1238 | + 'background-color': '#EEE', |
| 1239 | + 'padding' : '2px', |
| 1240 | + 'margin' : '5px' |
| 1241 | + }) |
| 1242 | + .addClass('ui-corner-all') |
| 1243 | + .append( |
| 1244 | + $j('<span />') |
| 1245 | + .css('margin', '5px') |
| 1246 | + .text( config.title ), |
| 1247 | + |
| 1248 | + $j('<input />') |
| 1249 | + .attr( { |
| 1250 | + 'id' : config.inputId , |
| 1251 | + 'size': config.inputSize |
| 1252 | + }) |
| 1253 | + .data('initialValue', config.initialValue ) |
| 1254 | + .sequencerInput( _this.sequencer ) |
| 1255 | + .val( config.initialValue ) |
| 1256 | + .change( config.change ) |
| 1257 | + ); |
| 1258 | + } |
| 1259 | +} |
| 1260 | + |
| 1261 | +} )( window.mw ); |
\ No newline at end of file |
Property changes on: branches/MwEmbedStandAlone/modules/Sequencer/tools/mw.SequencerTools.js |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 1262 | + native |
Added: svn:executable |
2 | 1263 | + * |
Index: branches/MwEmbedStandAlone/modules/Sequencer/mw.SequencerMenu.js |
— | — | @@ -185,7 +185,7 @@ |
186 | 186 | $j('<span />') |
187 | 187 | .css({ |
188 | 188 | 'float': 'right', |
189 | | - 'font-size': '12px' |
| 189 | + 'font-size': '10.5px' |
190 | 190 | }) |
191 | 191 | .append( |
192 | 192 | gM('mwe-sequencer-sequencer_credit_line', |
Index: branches/MwEmbedStandAlone/modules/Sequencer/remotes/mw.MediaWikiRemoteSequencer.js |
— | — | @@ -105,11 +105,8 @@ |
106 | 106 | } |
107 | 107 | |
108 | 108 | if(! $j( '#' + embedPlayerId ).siblings( '.kalturaEditOverlay' ).length ){ |
109 | | - var editLink = '#'; |
110 | | - if( mw.isLocalDomain( mw.getApiProviderURL( embedPlayer.apiProvider ) ) |
111 | | - && |
112 | | - embedPlayer.apiTitleKey ) |
113 | | - { |
| 109 | + var editLink = '#'; |
| 110 | + if( ! mw.isLocalDomain( mw.getApiProviderURL( embedPlayer.apiProvider ) ) ) { |
114 | 111 | var seqTitle = embedPlayer.apiTitleKey |
115 | 112 | .replace( 'Sequence-', 'Sequence:') |
116 | 113 | // strip the extension |
— | — | @@ -165,7 +162,7 @@ |
166 | 163 | 'href': editLink, |
167 | 164 | 'target': '_new' |
168 | 165 | }) |
169 | | - .click(function(){ |
| 166 | + .click(function(){ |
170 | 167 | // load the editor in-place if on the same domain as the sequence |
171 | 168 | if( editLink == '#' ){ |
172 | 169 | if( ! window.mwSequencerRemote ){ |