_onMarkerMapMoved:function(e, data){
var from = data.fromIndex;
var to = data.toIndex;
-// if(from===to){
-// //just update the div in order to show the new time offset
-// //and start edit
-// this.cfg.divmarkers[from].setIndex(to);
-// return;
-// }
+ // if(from===to){
+ // //just update the div in order to show the new time offset
+ // //and start edit
+ // this.cfg.divmarkers[from].setIndex(to);
+ // return;
+ // }
this.cfg.divmarkers.move(from,to);
this.cfg.player.ruler.markers.move(from,to);
-// realIndex might not be equal to to
+ // realIndex might not be equal to to
this.updateIndices(from,data.newIndex);
+ this.divFocus(data.newIndex);
},
+ divFocus: function(divIndex){
+ if(this.cfg.divmarkers){
+ var max = this.cfg.divmarkers.length;
+ for (var i = 0; i < max; i++) {
+ if(i==divIndex){
+ this.cfg.divmarkers[i].focusOn();
+ }else{
+ this.cfg.divmarkers[i].focusOff();
+ }
+ }
+ }
+ },
//called whenever a marker is added to the ruler BUT NOT in the map
_onMarkerAdd: function(e, data) {
if (this.cfg.map) {
//which btw adds a new div to divmarkers
//now update the indices for the div (which also sets the event bindings as clicks etc...
this.updateIndices(idx);
+ this.divFocus(idx);
}
},
//fired from markermap, attached as listener above in
//var divMarker = new $N.DivMarker(this.cfg.map);
this.cfg.divmarkers.splice(idx,0, new $N.DivMarker(this.cfg.map));
this.cfg.player.ruler.onMapAdd(data.marker, idx);
- //this.cfg.player.ruler.add(data.marker, idx);
+ //this.cfg.player.ruler.add(data.marker, idx);
}
},
this.cfg.player.ruler.remove(idx);
//if(idx<this.cfg.divmarkers.length){
- //we might have removed the last index, in this case idx==this.cfg.divmarkers.length
- //no need to update and to enter this if
+ //we might have removed the last index, in this case idx==this.cfg.divmarkers.length
+ //no need to update and to enter this if
this.updateIndices(idx);
- //}
+ //}
}
},
var okB = this.e_okButton;
var utw = this.updateTitleWidth;
var divmarker = this;
- this.e_editButton.unbind('click').click( function(){
+ var eB = this.e_editButton;
+ var startEdit = function(){
marker.isModified = true;
dText.removeAttr('readonly').removeClass('markersdivUneditable').show();
tText.removeAttr('readonly').removeClass('markersdivUneditable').show();
okB.show();
- $(this).hide();
+ eB.hide();
utw.apply(divmarker,[tText]);
- tText.select();
+ };
+
+ this.e_editButton.unbind('click').click( function(){
+ startEdit();
+ divmarker.focusOn();
return false; //avoid scrolling of the page on anchor click
});
- var eB = this.e_editButton;
+
//action for ok button
this.e_okButton.unbind('click').click( function(){
//if(marker.desc !== descriptionText.val()){ //strict equality needed. See note below
});
if(isEditing){
- this.e_editButton.trigger('click');
- //which also calls this.updateTitleWidth();
+ startEdit();
}else{
this.updateTitleWidth();
}
},
+ focusOn: function(){
+ this.me.css('backgroundColor','#f5f5c2');
+ this.e_titleText.select();
+ },
+
+ focusOff: function(){
+ this.me.css('backgroundColor','');
+ },
+
updateTitleWidth: function(tText){
if(!(tText)){
tText = this.e_titleText;
+++ /dev/null
-/**
- * TimeSide - Web Audio Components
- * Copyright (c) 2008-2009 Samalyse
- * Author: Olivier Guilyardi <olivier samalyse com>
- * License: GNU General Public License version 2.0
- */
-
-TimeSide(function($N, $J) {
-
- $N.Class.create("Marker", $N.Core, {
- id: null,
- painter: null,
- visible: false,
- position: 0,
- label: null,
- blinking: false,
- nodes: null,
- mouseDown: false,
- blinkAnimation: null,
-
- initialize: function($super, cfg) {
- $super();
- //sets the fields required???? see ruler.js createPointer
- this.configure(cfg, {
- rulerLayout: [null, 'required'],
- viewer: [null, 'required'],
- fontSize: 10,
- zIndex: null,
- className: [null, 'required'],
- index: null,
- tooltip: null,
- canMove: false
- });
- this.cfg.rulerLayout = $J(this.cfg.rulerLayout);
- this.cfg.viewer = $J(this.cfg.viewer);
-
- this.width = this.cfg.viewer.width();
- this.painter = new jsGraphics(this.cfg.viewer.get(0));
- this._create();
- if(this.cfg.canMove){
- this._observeMouseEvents();
- }
- //if it is the pointer, cfg.index is undefined
- if(cfg.index !== undefined && cfg.className!='pointer'){
- this.setIndex(cfg.index);
- }
- },
-
- setIndex: function(index){
- this.index = index;
- this.setText(index+1);
- },
-
- free: function($super) {
- this.cfg.rulerLayout = null;
- this.cfg.viewer = null;
- $super();
- },
-
- clear: function() {
- this.painter.clear();
- $J(this.painter.cnv).remove();
- this.label.remove();
- return this;
- },
-
- _create: function() {
- this.debug('create marker');
- var y = this.cfg.rulerLayout.find('.' + $N.cssPrefix + 'label').outerHeight();
- this.label = $J('<a/>')
- .css({
- display: 'block',
- width: '10px',
- textAlign: 'center',
- position: 'absolute',
- fontSize: this.cfg.fontSize + 'px',
- fontFamily: 'monospace',
- top: y + 'px'
- })
- .attr('href', '#')
- .addClass($N.cssPrefix + this.cfg.className)
- .append('<span />')
- .hide();
-
- if (this.cfg.tooltip){
- this.label.attr('title', this.cfg.tooltip);
- }
- this.cfg.rulerLayout.append(this.label);
-
- var height = this.cfg.viewer.height();
- var x = 0;
- this.painter.drawLine(x, 0, x, height);
- x = [-4, 4, 0];
- var y = [0, 0, 4];
- this.painter.fillPolygon(x, y);
- this.painter.paint();
- this.nodes = $J(this.painter.cnv).children();
-
- var style = {};
- if (this.cfg.zIndex) {
- style.zIndex = this.cfg.zIndex;
- this.label.css(style);
- }
- style.backgroundColor = '';
-
- this.nodes.hide().css(style).addClass($N.cssPrefix + this.cfg.className)
- .each(function(i, node) {
- node.originalPosition = parseInt($J(node).css('left'));
- });
- },
-
- setText: function(text) {
- if (this.label) {
- text += '';
- var labelWidth = this._textWidth(text, this.cfg.fontSize) + 10;
- labelWidth += 'px';
- if (this.label.css('width') != labelWidth) {
- this.label.css({
- width: labelWidth
- });
- }
- this.label.find('span').html(text);
- }
- return this;
- },
-
- move: function(pixelOffset) {
- if (this.position != pixelOffset) {
- if (pixelOffset < 0) {
- pixelOffset = 0;
- } else if (pixelOffset >= this.width) {
- pixelOffset = this.width - 1;
- }
- this.nodes.each(function(i, node) {
- $J(node).css('left', Math.round(node.originalPosition + pixelOffset) + 'px');
- });
- var labelWidth = this.label.width();
- var labelPixelOffset = pixelOffset - labelWidth / 2;
- if (labelPixelOffset < 0)
- labelPixelOffset = 0;
- else if (labelPixelOffset + labelWidth > this.width)
- labelPixelOffset = this.width - labelWidth;
- this.label.css({
- left: Math.round(labelPixelOffset) + 'px'
- });
- this.position = pixelOffset;
- }
- return this;
- },
-
- show: function(offset) {
- if (!this.visible) {
- this.nodes.show();
- this.label.show();
- this.visible = true;
- }
- return this;
- },
-
- hide: function() {
- this.nodes.hide();
- this.label.hide();
- this.visible = false;
- return this;
- },
-
- isVisible: function() {
- return this.visible;
- },
-
- blink: function(state) {
- var speed = 200;
- if (this.label && this.blinking != state) {
- var span = this.label.find('span');
-
- span.stop();
-
- function fade(on) {
- if (on) {
- span.animate({
- opacity: 1
- }, speed, null,
- function() {
- fade(false)
- });
- } else {
- span.animate({
- opacity: 0.4
- }, speed, null,
- function() {
- fade(true)
- })
- }
- }
-
- if (state) {
- fade();
- } else {
- span.animate({
- opacity: 1
- }, speed);
- }
-
- this.blinking = state;
- }
- return this;
- },
-
- _onMouseDown: function(evt) {
- this.mouseDown = true;
- this._onMouseMove(evt);
- return false;
- },
-
- _onMouseMove: function(evt) {
- if (this.mouseDown) {
- var offset = (evt.pageX - this.cfg.rulerLayout.offset().left);
- this.move(offset);
- this.fire('move', { //calls move (see above)
- offset: this.position,
- finish: false
- });
- return false;
- }
- },
-
- _onMouseUp: function(evt) {
- if (this.mouseDown) {
- this.mouseDown = false;
- this.fire('move', {
- index: this.index,
- offset: this.position,
- finish: true
- });
- return false;
- }
- },
-
- _observeMouseEvents: function() {
- this.label.mousedown(this.attachWithEvent(this._onMouseDown))
- .bind('click dragstart', function() {
- return false;
- });
- this.cfg.rulerLayout.mousemove(this.attachWithEvent(this._onMouseMove));
- this.cfg.rulerLayout.mouseup(this.attachWithEvent(this._onMouseUp));
- $J(document).mouseup(this.attachWithEvent(this._onMouseUp));
- }
-
- // _toString: function() {
- // return "<marker id="+id+" position="+position+" description=\""+
- // +description+"\"/>";
- // }
-
-
- });
-
- $N.notifyScriptLoad();
-
-});
add: function(obj) {
var marker = this.createMarker(obj);
- var idx = this.indexOf(marker);
-
- //adding the div
- //marker.div = this.createDiv(marker,idx);
- //setting focus and label description
- //set label description
- //this.setLabelDescription(marker);
- //finally, set the focus to the text
- //this.getHtmElm(marker,this.MHE_DESCRIPTION_TEXT).focus();
+ var idx = this.insertionIndex(marker);
+ //if exists (ix>0) add it AFTER the existing item
+ idx = idx<0 ? -idx-1 : idx+1;
this.markers.splice(idx,0,marker);
//notifies controller.onMarkerMapAdd
//argument is either an object loaded from server or a number specifying the marker offset
createMarker: function(argument){
var marker = null;
+ if(typeof argument == 'string'){
+ argument = parseFloat(argument);
+ }
if(typeof argument == 'object'){
var editable = CURRENT_USER_NAME === argument.author;
marker = {
--- /dev/null
+/**
+ * TimeSide - Web Audio Components
+ * Copyright (c) 2008-2009 Samalyse
+ * Author: Olivier Guilyardi <olivier samalyse com>
+ * License: GNU General Public License version 2.0
+ */
+
+TimeSide(function($N, $J) {
+
+ $N.Class.create("Marker", $N.Core, {
+ id: null,
+ painter: null,
+ visible: false,
+ position: 0,
+ label: null,
+ blinking: false,
+ nodes: null,
+ mouseDown: false,
+ blinkAnimation: null,
+
+ initialize: function($super, cfg) {
+ $super();
+ //sets the fields required???? see ruler.js createPointer
+ this.configure(cfg, {
+ rulerLayout: [null, 'required'],
+ viewer: [null, 'required'],
+ fontSize: 10,
+ zIndex: null,
+ className: [null, 'required'],
+ index: null,
+ tooltip: null,
+ canMove: false
+ });
+ this.cfg.rulerLayout = $J(this.cfg.rulerLayout);
+ this.cfg.viewer = $J(this.cfg.viewer);
+
+ this.width = this.cfg.viewer.width();
+ this.painter = new jsGraphics(this.cfg.viewer.get(0));
+ this._create();
+ if(this.cfg.canMove){
+ this._observeMouseEvents();
+ }
+ //if it is the pointer, cfg.index is undefined
+ if(cfg.index !== undefined && cfg.className!='pointer'){
+ this.setIndex(cfg.index);
+ }
+ },
+
+ setIndex: function(index){
+ this.index = index;
+ this.setText(index+1);
+ },
+
+ free: function($super) {
+ this.cfg.rulerLayout = null;
+ this.cfg.viewer = null;
+ $super();
+ },
+
+ clear: function() {
+ this.painter.clear();
+ $J(this.painter.cnv).remove();
+ this.label.remove();
+ return this;
+ },
+
+ _create: function() {
+ this.debug('create marker');
+ var y = this.cfg.rulerLayout.find('.' + $N.cssPrefix + 'label').outerHeight();
+ //added by me:================
+ if(this.cfg.className == "pointer"){
+ y = 0;
+ }
+ //==========================
+ this.label = $J('<a/>')
+ .css({
+ display: 'block',
+ width: '10px',
+ textAlign: 'center',
+ position: 'absolute',
+ fontSize: this.cfg.fontSize + 'px',
+ fontFamily: 'monospace',
+ top: y + 'px'
+ })
+ .attr('href', '#')
+ .addClass($N.cssPrefix + this.cfg.className)
+ .append('<span />')
+ .hide();
+
+ if (this.cfg.tooltip){
+ this.label.attr('title', this.cfg.tooltip);
+ }
+ this.cfg.rulerLayout.append(this.label);
+
+ var height = this.cfg.viewer.height();
+ var x = 0;
+ this.painter.drawLine(x, 0, x, height);
+ x = [-4, 4, 0];
+ y = [0, 0, 4];
+
+ this.painter.fillPolygon(x, y);
+ this.painter.paint();
+ this.nodes = $J(this.painter.cnv).children();
+
+ var style = {};
+ if (this.cfg.zIndex) {
+ style.zIndex = this.cfg.zIndex;
+ this.label.css(style);
+ }
+ style.backgroundColor = '';
+
+ this.nodes.hide().css(style).addClass($N.cssPrefix + this.cfg.className)
+ .each(function(i, node) {
+ node.originalPosition = parseInt($J(node).css('left'));
+ });
+ },
+
+ setText: function(text) {
+ if (this.label) {
+ text += '';
+ var labelWidth = this._textWidth(text, this.cfg.fontSize) + 10;
+ labelWidth += 'px';
+ if (this.label.css('width') != labelWidth) {
+ this.label.css({
+ width: labelWidth
+ });
+ }
+ this.label.find('span').html(text);
+ }
+ return this;
+ },
+
+ move: function(pixelOffset) {
+ if (this.position != pixelOffset) {
+ if (pixelOffset < 0) {
+ pixelOffset = 0;
+ } else if (pixelOffset >= this.width) {
+ pixelOffset = this.width - 1;
+ }
+ this.nodes.each(function(i, node) {
+ $J(node).css('left', Math.round(node.originalPosition + pixelOffset) + 'px');
+ });
+ var labelWidth = this.label.width();
+ var labelPixelOffset = pixelOffset - labelWidth / 2;
+ if (labelPixelOffset < 0)
+ labelPixelOffset = 0;
+ else if (labelPixelOffset + labelWidth > this.width)
+ labelPixelOffset = this.width - labelWidth;
+ this.label.css({
+ left: Math.round(labelPixelOffset) + 'px'
+ });
+ this.position = pixelOffset;
+ }
+ return this;
+ },
+
+ show: function(offset) {
+ if (!this.visible) {
+ this.nodes.show();
+ this.label.show();
+ this.visible = true;
+ }
+ return this;
+ },
+
+ hide: function() {
+ this.nodes.hide();
+ this.label.hide();
+ this.visible = false;
+ return this;
+ },
+
+ isVisible: function() {
+ return this.visible;
+ },
+
+ blink: function(state) {
+ var speed = 200;
+ if (this.label && this.blinking != state) {
+ var span = this.label.find('span');
+
+ span.stop();
+
+ function fade(on) {
+ if (on) {
+ span.animate({
+ opacity: 1
+ }, speed, null,
+ function() {
+ fade(false)
+ });
+ } else {
+ span.animate({
+ opacity: 0.4
+ }, speed, null,
+ function() {
+ fade(true)
+ })
+ }
+ }
+
+ if (state) {
+ fade();
+ } else {
+ span.animate({
+ opacity: 1
+ }, speed);
+ }
+
+ this.blinking = state;
+ }
+ return this;
+ },
+
+ _onMouseDown: function(evt) {
+ this.mouseDown = true;
+ this._onMouseMove(evt);
+ return false;
+ },
+
+ _onMouseMove: function(evt) {
+ if (this.mouseDown) {
+ var offset = (evt.pageX - this.cfg.rulerLayout.offset().left);
+ this.move(offset);
+ this.fire('move', { //calls move (see above)
+ offset: this.position,
+ finish: false
+ });
+ return false;
+ }
+ },
+
+ _onMouseUp: function(evt) {
+ if (this.mouseDown) {
+ this.mouseDown = false;
+ this.fire('move', {
+ index: this.index,
+ offset: this.position,
+ finish: true
+ });
+ return false;
+ }
+ },
+
+ _observeMouseEvents: function() {
+ this.label.mousedown(this.attachWithEvent(this._onMouseDown))
+ .bind('click dragstart', function() {
+ return false;
+ });
+ this.cfg.rulerLayout.mousemove(this.attachWithEvent(this._onMouseMove));
+ this.cfg.rulerLayout.mouseup(this.attachWithEvent(this._onMouseUp));
+ $J(document).mouseup(this.attachWithEvent(this._onMouseUp));
+ }
+
+ // _toString: function() {
+ // return "<marker id="+id+" position="+position+" description=\""+
+ // +description+"\"/>";
+ // }
+
+
+ });
+
+ $N.notifyScriptLoad();
+
+});
TimeSide(function($N) {
-$N.Class.create("SoundProvider", $N.Core, {
- sound: null,
- timer: null,
- buggyPosition: null,
- isDurationForced: false,
- state: {
- position: null,
- duration: null,
- playing: false,
- buffering: false
- },
- lastState: null,
-
- initialize: function($super, cfg) {
- $super();
- this.configure(cfg, {
- source: null,
- duration: null
- });
- this.sound = this.cfg.source;
- if (this.cfg.duration) {
- this.forceDuration(this.cfg.duration);
- }
- this.state.position = 0;
- this.update = this.attach(this._update);
- this.timer = setInterval(this.update, 43);
- },
-
- free: function($super) {
- this.sound = null;
- $super();
- },
-
- play: function() {
- if (this.sound) {
- if (!this.sound.playState) {
- this.sound.play();
- } else if (this.sound.paused) {
- this.sound.resume();
+ $N.Class.create("SoundProvider", $N.Core, {
+ sound: null,
+ timer: null,
+ buggyPosition: null,
+ isDurationForced: false,
+ state: {
+ position: null,
+ duration: null,
+ playing: false,
+ buffering: false
+ },
+ lastState: null,
+
+ initialize: function($super, cfg) {
+ $super();
+ this.configure(cfg, {
+ source: null,
+ duration: null
+ });
+ this.sound = this.cfg.source;
+ if (this.cfg.duration) {
+ this.forceDuration(this.cfg.duration);
}
- }
- return this;
- },
-
- pause: function() {
- if (this.sound)
- this.sound.pause();
- return this;
- },
-
- seek: function(offset) {
- if (this.sound) {
- this.sound.setPosition(offset * 1000);
- if (!this.state.playing) {
- this.buggyPosition = this.sound.position / 1000;
- this.state.position = offset;
+ this.state.position = 0;
+ this.update = this.attach(this._update);
+ this.timer = setInterval(this.update, 43);
+ },
+
+ free: function($super) {
+ this.sound = null;
+ $super();
+ },
+
+ play: function() {
+ if (this.sound) {
+ if (!this.sound.playState) {
+ this.sound.play();
+ } else if (this.sound.paused) {
+ this.sound.resume();
+ }
}
- }
- return this;
- },
+ return this;
+ },
+
+ pause: function() {
+ if (this.sound)
+ this.sound.pause();
+ return this;
+ },
+
+ seek: function(offset) {
+ if (this.sound) {
+ this.sound.setPosition(offset * 1000);
+ if (!this.state.playing) {
+ //it's not always a number. When not playing it is a string
+ //(sound manager?)
+ var offs = typeof offset == "number" ? offset : parseFloat(offset);
+ this.buggyPosition = this.sound.position / 1000;
+ this.state.position = offs;
+ }
+ }
+ return this;
+ },
- isPlaying: function() {
- return this.state.playing;
- },
+ isPlaying: function() {
+ return this.state.playing;
+ },
- getPosition: function() {
- if (this.state.position == null)
- this._retrieveState();
- return this.state.position;
- },
+ getPosition: function() {
+ if (this.state.position == null){
+ this._retrieveState();
+ }
+ return this.state.position;
+ },
- getDuration: function() {
- if (this.state.duration == null)
- this._retrieveState();
- return this.state.duration;
- },
-
- forceDuration: function(duration) {
- this.state.duration = duration;
- this.isDurationForced = true;
- },
-
- isBuffering: function() {
- return this.state.buffering;
- },
-
- _retrieveState: function() {
- if (this.sound) {
- this.state.playing = (this.sound.playState && !this.sound.paused);
- if (this.state.playing) {
- var position = this.sound.position / 1000;
- if (position != this.buggyPosition) {
- this.state.position = position;
- this.buggyPosition = null;
- }
+ getDuration: function() {
+ if (this.state.duration == null){
+ this._retrieveState();
}
- if (!this.isDurationForced) {
- if (this.sound.readyState == 1) {
- this.state.duration = this.sound.durationEstimate / 1000;
- } else {
- this.state.duration = this.sound.duration / 1000;
+ return this.state.duration;
+ },
+
+ forceDuration: function(duration) {
+ this.state.duration = duration;
+ this.isDurationForced = true;
+ },
+
+ isBuffering: function() {
+ return this.state.buffering;
+ },
+
+ _retrieveState: function() {
+ if (this.sound) {
+ this.state.playing = (this.sound.playState && !this.sound.paused);
+ if (this.state.playing) {
+ var position = this.sound.position / 1000;
+ if (position != this.buggyPosition) {
+ this.state.position = position;
+ this.buggyPosition = null;
+ }
}
+ if (!this.isDurationForced) {
+ if (this.sound.readyState == 1) {
+ this.state.duration = this.sound.durationEstimate / 1000;
+ } else {
+ this.state.duration = this.sound.duration / 1000;
+ }
+ }
+ this.state.buffering = (this.sound.readyState == 1 && this.state.position > this.sound.duration / 1000);
}
- this.state.buffering = (this.sound.readyState == 1 && this.state.position > this.sound.duration / 1000);
- }
- },
-
- _update: function() {
- this._retrieveState();
- var updated = false;
- if (this.lastState) {
- for (k in this.state) {
- if (this.state[k] != this.lastState[k]) {
- updated = true;
- break;
+ },
+
+ _update: function() {
+ this._retrieveState();
+ var updated = false;
+ if (this.lastState) {
+ for (k in this.state) {
+ if (this.state[k] != this.lastState[k]) {
+ updated = true;
+ break;
+ }
}
+ } else {
+ this.lastState = {};
+ updated = true;
}
- } else {
- this.lastState = {};
- updated = true;
- }
- if (updated) {
- for (k in this.state) {
- this.lastState[k] = this.state[k];
+ if (updated) {
+ for (k in this.state) {
+ this.lastState[k] = this.state[k];
+ }
+ this.fire('update');
}
- this.fire('update');
- }
- },
+ },
- setSource: function(source) {
- this.debug("setting source");
- this.sound = source;
- return this;
- }
+ setSource: function(source) {
+ this.debug("setting source");
+ this.sound = source;
+ return this;
+ }
-});
+ });
-$N.notifyScriptLoad();
+ $N.notifyScriptLoad();
});
$N.loadScripts(root, ['core.js'], function() {
$N.loadScripts(root, ['util.js'], function() {
- var scripts = ['controller.js', 'marker.js', 'markerlist.js',
+ var scripts = ['controller.js', 'rulermarker.js', //'markerlist.js',
'markermap.js', 'player.js', 'ruler.js','divmarker.js',
'soundprovider.js'];
{% load telemeta_utils %}
{% load i18n %}
+{% block extra_javascript %}
+<script src="{% url telemeta-timeside "src/playlist.js" %}" type="text/javascript"></script>
+{% endblock %}
+
+
{% block content %}
<div class="module-set">