From: yomguy Date: Tue, 15 Mar 2011 15:15:54 +0000 (+0000) Subject: update UI from Telemeta rev539 to rev638 X-Git-Tag: 0.3.2~67 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=23c8277e6446b94293250187dbe2e04df77d58a5;p=timeside.git update UI from Telemeta rev539 to rev638 --- diff --git a/timeside/ui/css/timeside.css b/timeside/ui/css/timeside.css index cadc79a..014ae61 100755 --- a/timeside/ui/css/timeside.css +++ b/timeside/ui/css/timeside.css @@ -15,6 +15,10 @@ position: relative; } +.ts-image-container { + background-color: #000000; +} + .ts-player .ts-wave .ts-image { position: absolute; left: 0; diff --git a/timeside/ui/skins/lab/img/controlbg.png b/timeside/ui/skins/lab/img/controlbg.png index 57840d0..edaf9fc 100755 Binary files a/timeside/ui/skins/lab/img/controlbg.png and b/timeside/ui/skins/lab/img/controlbg.png differ diff --git a/timeside/ui/skins/lab/img/forward.png b/timeside/ui/skins/lab/img/forward.png index 86485d0..66f6232 100755 Binary files a/timeside/ui/skins/lab/img/forward.png and b/timeside/ui/skins/lab/img/forward.png differ diff --git a/timeside/ui/skins/lab/img/pause.png b/timeside/ui/skins/lab/img/pause.png index d09ad51..103357f 100755 Binary files a/timeside/ui/skins/lab/img/pause.png and b/timeside/ui/skins/lab/img/pause.png differ diff --git a/timeside/ui/skins/lab/img/play.png b/timeside/ui/skins/lab/img/play.png index ccb87e8..9a89b4f 100755 Binary files a/timeside/ui/skins/lab/img/play.png and b/timeside/ui/skins/lab/img/play.png differ diff --git a/timeside/ui/skins/lab/img/rewind.png b/timeside/ui/skins/lab/img/rewind.png index ec45b38..550263f 100755 Binary files a/timeside/ui/skins/lab/img/rewind.png and b/timeside/ui/skins/lab/img/rewind.png differ diff --git a/timeside/ui/skins/lab/img/setmarker.png b/timeside/ui/skins/lab/img/setmarker.png index b642e82..af79be5 100644 Binary files a/timeside/ui/skins/lab/img/setmarker.png and b/timeside/ui/skins/lab/img/setmarker.png differ diff --git a/timeside/ui/skins/lab/style.css b/timeside/ui/skins/lab/style.css index 5dcd353..003f5a6 100755 --- a/timeside/ui/skins/lab/style.css +++ b/timeside/ui/skins/lab/style.css @@ -2,7 +2,7 @@ background: #3c4251; padding-top: 10px; padding-bottom: 10px; - border: dotted #b2b2b2 1px; + border: solid #b2b2b2 1px; } .ts-skin-lab .ts-player .ts-viewer { @@ -47,28 +47,28 @@ .ts-skin-lab .ts-player .ts-control { background: url('img/controlbg.png'); height: 28px; - border-top: dotted #b2b2b2 1px; +/* border-top: dotted #b2b2b2 1px; */ } .ts-skin-lab .ts-player .ts-control .ts-layout { margin-left: 12px; margin-right: 12px; - padding-top: 4px; + padding-top: 0px; } .ts-skin-lab .ts-player .ts-control .ts-playback a { display: block; float: left; - width: 21px; - padding: 21px 0 0 0; + width: 30px; + padding: 28px 0 0 0; overflow: hidden; height: 0px !important; - height /**/:21px; /* for IE5/Win only */ - margin-right: 1px; + height /**/:28px; /* for IE5/Win only */ + margin-right: 0px; } .ts-skin-lab .ts-player .ts-control .ts-playback a:hover { - background-position: 0 -21px; + background-position: 0 -28px; } .ts-skin-lab .ts-player .ts-control .ts-playback .ts-play { @@ -95,10 +95,10 @@ .ts-skin-lab .ts-player .ts-marker-control .ts-set-marker { display: block; width: 89px; - padding: 21px 0 0 0; + padding: 28px 0 0 0; overflow: hidden; height: 0px !important; - height /**/:21px; /* for IE5/Win only */ + height /**/:28px; /* for IE5/Win only */ background-image: url('img/setmarker.gif'); margin: 5px auto 0 auto; } @@ -114,3 +114,5 @@ height: 30px; } + + diff --git a/timeside/ui/src/controller.js b/timeside/ui/src/controller.js index ba0870b..ddd0d3e 100644 --- a/timeside/ui/src/controller.js +++ b/timeside/ui/src/controller.js @@ -7,51 +7,194 @@ TimeSide(function($N) { -$N.Class.create("Controller", $N.Core, { - - initialize: function($super, cfg) { - $super(); - this.configure(cfg, { - player: null, - soundProvider: null, - map: null - }); - if (this.cfg.player && !$N.isInstanceOf(this.cfg.player, 'Player')) { - this.cfg.player = new $N.Player(this.cfg.player); - } - this._setupPlayer(); - }, + $N.Class.create("Controller", $N.Core, { + + initialize: function($super, cfg) { + $super(); + this.configure(cfg, { + player: null, + soundProvider: null, + map: null, + divmarkers:[] + }); + if (this.cfg.player && !$N.isInstanceOf(this.cfg.player, 'Player')) { + this.cfg.player = new $N.Player(this.cfg.player); + } + this._setupPlayer(); + //setting the divmarkers + //this.cfg.map.observe('add') + + }, - _setupPlayer: function() { - this.cfg.player + _setupPlayer: function() { + + this.cfg.player .setSoundProvider(this.cfg.soundProvider) .setMarkerMap(this.cfg.map) .observe('play', $N.attachFunction(this.cfg.soundProvider, this.cfg.soundProvider.play)) .observe('pause', $N.attachFunction(this.cfg.soundProvider, this.cfg.soundProvider.pause)) .observe('move', this.attach(this._onMove)) .observe('markeradd', this.attach(this._onMarkerAdd)) + //player markermove listens for changes of ruler markermove which listens + //foir changes in each marker move .observe('markermove', this.attach(this._onMarkerMove)) + .draw(); - }, + this.loadHTTP(); - _onMove: function(e, data) { - this.cfg.soundProvider.seek(data.offset); - }, + this.cfg.map.observe('add',this.attach(this._onMarkerMapAdd)); + this.cfg.map.observe('remove',this.attach(this._onMarkerMapRemove)); + this.cfg.map.observe('moved',this.attach(this._onMarkerMapMoved)); + + }, - _onMarkerMove: function(e, data) { - if (this.cfg.map) { - this.cfg.map.move(this.cfg.map.byId(data.id), data.offset); - } - }, - _onMarkerAdd: function(e, data) { - if (this.cfg.map) { - this.cfg.map.add(data.offset, 'marker at ' + data.offset); + _onMove: function(e, data) { + this.cfg.soundProvider.seek(data.offset); + }, + + //called whenever a marker is moved in the ruler BUT NOT in the map + _onMarkerMove: function(e, data) { + if (this.cfg.map) { + $N.Util.selectMarkerTab(); //defined in utils.js + this.cfg.map.move(data.index, data.offset); + //this will fire the method below + } + }, + + _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; + } + this.cfg.player.ruler.move(from,to); + var m = this.cfg.divmarkers.splice(from,1)[0]; //remove + this.cfg.divmarkers.splice(to,0,m); //add + this.updateIndices(from,to); + }, + + //called whenever a marker is added to the ruler BUT NOT in the map + _onMarkerAdd: function(e, data) { + if (this.cfg.map) { + $N.Util.selectMarkerTab(); //defined in mediaitem|_detail.html + var idx = this.cfg.map.add(data.offset); //this will call the method below _onMarkerMapAdd, + //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); + } + }, + //fired from markermap, attached as listener above in + //this.cfg.map.observe('add',this.attach(this._onMarkerMapAdd)); + //this method basically adds the html elements, but updateIndices must be called elsewhere after this function + //(see _onMarkerAdd and loadHTTP) + _onMarkerMapAdd: function(e, data) { + if (this.cfg.map) { + //$N.Util.selectMarkerTab(); //defined in mediaitem|_detail.html + //this.refreshMarkersText(this.cfg.map); + //var idx = this.cfg.map.add(data.offset); + //alert('df'); + var idx = data.index; + var divMarker = new $N.DivMarker(this.cfg.map); + this.cfg.divmarkers.splice(idx,0, divMarker); + this.cfg.player.ruler.add(data.marker, idx); + } + }, + + //fired from markermap, attached as listener above in + //this.cfg.map.observe('add',this.attach(this._onMarkerMapAdd)); + _onMarkerMapRemove: function(e, data) { + if (this.cfg.map) { + //$N.Util.selectMarkerTab(); //defined in mediaitem|_detail.html + //this.refreshMarkersText(this.cfg.map); + //var idx = this.cfg.map.add(data.offset); + //alert('df'); + var idx = data.index; + var divRemoved = this.cfg.divmarkers.splice(idx,1)[0]; //there is only one element removed + divRemoved.remove(); + this.cfg.player.ruler.remove(idx); + this.updateIndices(idx); + } + }, + + updateIndices: function(from, to){ + if(from===undefined || from==null){ + from = 0; + } + var len = this.cfg.divmarkers.length-1; + if(from>len){ + //it might happen when we remove the last element + //suppose [0,1,2], we remove [2] then we call + //updateIndices[2] but array till 1 (there is nothing to update) + return; + } + if(to==undefined || to ==null){ + to = len; + } + if(to0){ + var result = data.result; + + for(var i =0; i< result.length; i++){ + map.add(result[i]); + } + //we call now updateindices + update.apply(me); + + } + + } + //We call mediaitem_detail.setUpTabs from controller once all markers have been loaded + //this because setLabelDescription, which sets the label text according to the div width, + //needs to have all elements visible. + $N.Util.setUpTabs(); + //setUpTabs(); //which hides the marker div. Call with argument 1 to set up marker div + //as visible as startup + } + }); + //var g = 9; } - } -}); + + + }); -$N.notifyScriptLoad(); + $N.notifyScriptLoad(); }); diff --git a/timeside/ui/src/core.js b/timeside/ui/src/core.js index 3f48121..e86b691 100644 --- a/timeside/ui/src/core.js +++ b/timeside/ui/src/core.js @@ -7,265 +7,287 @@ TimeSide(function($N, $J) { -$N.extend = function(destination, source) { - for (var property in source) - destination[property] = source[property]; - return destination; -}; - -$N.objectKeys = function(object) { - var keys = []; - for (var property in object) - keys.push(property); - return keys; -}; - -$N.argumentNames = function(method) { - var names = method.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1] - .replace(/\s+/g, '').split(','); - return names.length == 1 && !names[0] ? [] : names; -}; - -$N.argsToArray = function(args) { - var length = args.length || 0, result = new Array(length); - while (length--) result[length] = args[length]; - return result; -}; - -$N.wrapFunction = function(wrapper, method) { - return function() { - var args = $N.argsToArray(arguments); - return wrapper.apply(this, [$N.attachFunction(this, method)].concat(args)); - } -}; - -$N.attachFunction = function() { - if (arguments.length < 3 && (typeof arguments[1] == 'undefined')) return arguments[0]; - var args = $N.argsToArray(arguments); - var object = args.shift(); - var method = args.shift(); - return function() { - var _args = $N.argsToArray(arguments); - return method.apply(object, args.concat(_args)); - } -}; + $N.extend = function(destination, source) { + for (var property in source){ + destination[property] = source[property]; + } + return destination; + }; -$N.attachAsEventListener = function() { - var args = $N.argsToArray(arguments), object = args.shift(); - var method = args.shift(); - return function(event) { - return method.apply(object, [event || window.event].concat(args)); - } -}; + $N.objectKeys = function(object) { + var keys = []; + for (var property in object){ + keys.push(property); + } + return keys; + }; + + $N.argumentNames = function(method) { + var names = method.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1] + .replace(/\s+/g, '').split(','); + return names.length == 1 && !names[0] ? [] : names; + }; + + $N.argsToArray = function(args) { + var length = args.length || 0, result = new Array(length); + while (length--){ + result[length] = args[length]; + } + return result; + }; -$N.isInstanceOf = function(obj, className) { - if (typeof obj == 'object' && obj.__class__) { - var c = obj.__class__; - if (c.__name__ == className) { - return true; + $N.wrapFunction = function(wrapper, method) { + return function() { + var args = $N.argsToArray(arguments); + return wrapper.apply(this, [$N.attachFunction(this, method)].concat(args)); } - while (c = c.__super__) { + }; + + $N.attachFunction = function() { + if (arguments.length < 3 && (typeof arguments[1] == 'undefined')){ + return arguments[0]; + } + var args = $N.argsToArray(arguments); + var object = args.shift(); + var method = args.shift(); + return function() { + var _args = $N.argsToArray(arguments); + return method.apply(object, args.concat(_args)); + } + }; + + $N.attachAsEventListener = function() { + var args = $N.argsToArray(arguments), object = args.shift(); + var method = args.shift(); + return function(event) { + return method.apply(object, [event || window.event].concat(args)); + } + }; + + $N.isInstanceOf = function(obj, className) { + if (typeof obj == 'object' && obj.__class__) { + var c = obj.__class__; if (c.__name__ == className) { return true; } + while (c = c.__super__) { + if (c.__name__ == className) { + return true; + } + } } + return false; } - return false; -} - -$N.Class = { - create: function() { - var parent = null, className = null; - var properties = $N.argsToArray(arguments) - if (typeof properties[0] == "string") - className = properties.shift(); - if (typeof properties[0] == "function") - parent = properties.shift(); - - function klass() { - this.initialize.apply(this, arguments); - } + + $N.Class = { + create: function() { + var parent = null, className = null; + var properties = $N.argsToArray(arguments) + if (typeof properties[0] == "string"){ + className = properties.shift(); + } + if (typeof properties[0] == "function"){ + parent = properties.shift(); + } - $N.extend(klass, $N.Class.Methods); - klass.__name__ = className; - klass.__super__ = parent; - klass.__subclasses__ = []; + function klass() { + this.initialize.apply(this, arguments); + } + //Merge the contents of $N.Class.Methods into klass: + $N.extend(klass, $N.Class.Methods); + klass.__name__ = className; + klass.__super__ = parent; + klass.__subclasses__ = []; - if (parent) { - var subclass = function() { }; - subclass.prototype = parent.prototype; - klass.prototype = new subclass; - parent.__subclasses__.push(klass); - } + if (parent) { + var subclass = function() { }; + subclass.prototype = parent.prototype; + klass.prototype = new subclass; + parent.__subclasses__.push(klass); + } - klass.prototype.__class__ = klass; - for (var i = 0; i < properties.length; i++) - klass.addMethods(properties[i]); + klass.prototype.__class__ = klass; + for (var i = 0; i < properties.length; i++){ + klass.addMethods(properties[i]); + } - if (!klass.prototype.initialize) - klass.prototype.initialize = function () {}; + if (!klass.prototype.initialize){ + klass.prototype.initialize = function () {}; + + } - klass.prototype.constructor = klass; + klass.prototype.constructor = klass; - if (className) { - $N[className] = klass; - } - return klass; - } -}; + if (className) { + $N[className] = klass; + } + return klass; + } + }; -$N.Class.Methods = { - addMethods: function(source) { - var ancestor = this.__super__ && this.__super__.prototype; - var properties = $N.objectKeys(source); - - if (!$N.objectKeys({ toString: true }).length) - properties.push("toString", "valueOf"); + $N.Class.Methods = { + addMethods: function(source) { + var ancestor = this.__super__ && this.__super__.prototype; + var properties = $N.objectKeys(source); - for (var i = 0, length = properties.length; i < length; i++) { - var property = properties[i], value = source[property]; - if (ancestor && (typeof value == 'function') && - $N.argumentNames(value)[0] == "$super") { - var method = value; - value = $N.wrapFunction(method, (function(m) { - return function() { return ancestor[m].apply(this, arguments) }; - })(property)); + if (!$N.objectKeys({ + toString: true + }).length){ + properties.push("toString", "valueOf"); + } + for (var i = 0, length = properties.length; i < length; i++) { + var property = properties[i], value = source[property]; + if (ancestor && (typeof value == 'function') && + $N.argumentNames(value)[0] == "$super") { + var method = value; + value = $N.wrapFunction(method, (function(m) { + return function() { + return ancestor[m].apply(this, arguments) + }; + })(property)); - value.valueOf = $N.attachFunction(method, method.valueOf); - value.toString = $N.attachFunction(method, method.toString); - } - this.prototype[property] = value; - } + value.valueOf = $N.attachFunction(method, method.valueOf); + value.toString = $N.attachFunction(method, method.toString); + } + this.prototype[property] = value; + } - return this; - } -}; + return this; + } + }; -$N.Core = $N.Class.create("Core", { - eventContainer: null, - eventPrefix: '', - cfg: {}, - - initialize: function() { - this.debug("new instance"); - $N.registerInstance(this); - this.eventContainer = $J('
'); - this.forwardEvent = this.attach(this._forwardEvent); - }, - - free: function() { - this.eventContainer = null; - }, - - configure: function(config, defaults) { - if (!config) - config = {}; - for (k in defaults) { - var value = null, flags = []; - - if (defaults[k] && typeof defaults[k][0] !== 'undefined') { - value = defaults[k][0]; - if (defaults[k][1]) { - flags = defaults[k][1].split(","); - } - } else { - value = defaults[k]; + $N.Core = $N.Class.create("Core", { + eventContainer: null, + eventPrefix: '', + cfg: {}, + + initialize: function() { + this.debug("new instance"); + $N.registerInstance(this); + this.eventContainer = $J('
'); + this.forwardEvent = this.attach(this._forwardEvent); + }, + + free: function() { + this.eventContainer = null; + }, + + configure: function(config, defaults) { + if (!config){ + config = {}; + } + for (k in defaults) { + var value = null, flags = []; - if (typeof config[k] !== 'undefined') - value = config[k]; + if (defaults[k] && typeof defaults[k][0] !== 'undefined') { + value = defaults[k][0]; + if (defaults[k][1]) { + flags = defaults[k][1].split(","); + } + } else { + value = defaults[k]; + } - var source = this; - $J(flags).each(function(i, flag) { - switch (flag) { - case 'required': - if (value === null) - throw new $N.RequiredOptionError(source, k); - break; - /* + if (typeof config[k] !== 'undefined'){ + value = config[k]; + } + + var source = this; + $J(flags).each(function(i, flag) { + switch (flag) { + case 'required': + if (value === null) + throw new $N.RequiredOptionError(source, k); + break; + /* case 'element': value = $J(value); break; */ - } - }); + } + }); - this.cfg[k] = value; - } - return this; - }, - - observe: function(eventName, handler) { - this.eventContainer.bind(this.eventPrefix + eventName, handler); - return this; - }, - - fire: function(eventName, data) { - if (!data) - data = {}; - this.eventContainer.trigger(this.eventPrefix + eventName, data); - return this; - }, - - _forwardEvent: function(e, data) { - if (!data) - data = {}; - this.eventContainer.trigger(e.type, data); - return this; - }, - - _textWidth: function(text, fontSize) { - var ratio = 3/5; - return text.length * ratio * fontSize; - }, - - debug: function(message) { - if ($N.debugging && typeof console != 'undefined' && console.log) { - console.log('TimeSide.' + this.__class__.__name__ + ': ' + message); - } - }, + this.cfg[k] = value; + } + return this; + }, - attach: function(method) { - return $N.attachFunction(this, method); - }, + observe: function(eventName, handler) { + this.eventContainer.bind(this.eventPrefix + eventName, handler); + return this; + }, - attachWithEvent: function(method) { - return $N.attachAsEventListener(this, method); - }, + fire: function(eventName, data) { + if (!data){ + data = {}; - uniqid: function() { - d = new Date(); - return new String(d.getTime() + '' + Math.floor(Math.random() * 1000000)).substr(0, 18); - } -}); + } + this.eventContainer.trigger(this.eventPrefix + eventName, data); + return this; + }, + + _forwardEvent: function(e, data) { + if (!data){ + data = {}; -$N.Class.create("Exception", { - _source: null, - _message: null, + } + this.eventContainer.trigger(e.type, data); + return this; + }, + + _textWidth: function(text, fontSize) { + var ratio = 3/5; + return text.length * ratio * fontSize; + }, + + debug: function(message) { + if ($N.debugging && typeof console != 'undefined' && console.log) { + console.log('TimeSide.' + this.__class__.__name__ + ': ' + message); + } + }, + + attach: function(method) { + return $N.attachFunction(this, method); + }, + + attachWithEvent: function(method) { + return $N.attachAsEventListener(this, method); + }, + + uniqid: function() { + d = new Date(); + return new String(d.getTime() + '' + Math.floor(Math.random() * 1000000)).substr(0, 18); + } + }); + + $N.Class.create("Exception", { + _source: null, + _message: null, - initialize: function(source, message) { - this._source = source; - this._message = message; - }, - toString: function() { - return this.__class__.__name__ + " from TimeSide." + this._source.__class__.__name__ + initialize: function(source, message) { + this._source = source; + this._message = message; + }, + toString: function() { + return this.__class__.__name__ + " from TimeSide." + this._source.__class__.__name__ + ": " + this._message; - } -}); + } + }); -$N.Class.create("RequiredOptionError", $N.Exception, { - initialize: function($super, source, optionName) { - $super(source, "missing '" + optionName + "' required option"); - } -}); + $N.Class.create("RequiredOptionError", $N.Exception, { + initialize: function($super, source, optionName) { + $super(source, "missing '" + optionName + "' required option"); + } + }); -$N.Class.create("RequiredArgumentError", $N.Exception, { - initialize: function($super, source, optionName) { - $super(source, "missing '" + optionName + "' required argument"); - } -}); + $N.Class.create("RequiredArgumentError", $N.Exception, { + initialize: function($super, source, optionName) { + $super(source, "missing '" + optionName + "' required argument"); + } + }); -$N.notifyScriptLoad(); + $N.notifyScriptLoad(); }); diff --git a/timeside/ui/src/marker.js b/timeside/ui/src/marker.js index 32f7443..bd54550 100644 --- a/timeside/ui/src/marker.js +++ b/timeside/ui/src/marker.js @@ -7,55 +7,67 @@ 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(); - this.configure(cfg, { - rulerLayout: [null, 'required'], - viewer: [null, 'required'], - fontSize: 10, - zIndex: null, - className: [null, 'required'], - id: null, - tooltip: null - }); - this.cfg.rulerLayout = $J(this.cfg.rulerLayout); - this.cfg.viewer = $J(this.cfg.viewer); - - this.id = cfg.id; - this.width = this.cfg.viewer.width(); - this.painter = new jsGraphics(this.cfg.viewer.get(0)); - this._create(); - this._observeMouseEvents(); - }, - - 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('') + $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('') .css({ display: 'block', width: '10px', @@ -70,150 +82,178 @@ $N.Class.create("Marker", $N.Core, { .append('') .hide(); - if (this.cfg.tooltip) - this.label.attr('title', this.cfg.tooltip); - - this.cfg.rulerLayout.append(this.label); + 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 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 = ''; + 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) + 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 }); + }, + + 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); } - 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; + 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; } - 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) }); + 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: 0.4}, speed, null, - function() { fade(true) }) + span.animate({ + opacity: 1 + }, speed); } - } - if (state) { - fade(); - } else { - span.animate({opacity: 1}, speed); + this.blinking = state; } + return this; + }, - 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', {offset: this.position, finish: false}); + _onMouseDown: function(evt) { + this.mouseDown = true; + this._onMouseMove(evt); return false; - } - }, + }, - _onMouseUp: function(evt) { - if (this.mouseDown) { - this.mouseDown = false; - this.fire('move', {id: this.id, offset: this.position, finish: true}); - 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)); } - }, - _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 ""; + // } -}); + }); -$N.notifyScriptLoad(); + $N.notifyScriptLoad(); }); diff --git a/timeside/ui/src/markermap.js b/timeside/ui/src/markermap.js index 543fb2e..367f09c 100644 --- a/timeside/ui/src/markermap.js +++ b/timeside/ui/src/markermap.js @@ -1,122 +1,265 @@ /** * TimeSide - Web Audio Components * Copyright (c) 2008-2009 Samalyse - * Author: Olivier Guilyardi + * Author: Olivier Guilyardi and Riccardo Zaccarelli * License: GNU General Public License version 2.0 */ TimeSide(function($N, $J) { -$N.Class.create("MarkerMap", $N.Core, { - markers: null, - - initialize: function($super, markers) { - $super(); - if (!markers) - markers = []; - this.markers = markers; - }, - - toArray: function() { - return [].concat(this.markers); - }, - - byIndex: function(index) { - return this.markers[index]; - }, - - byId: function(id) { - var marker = null; - for (var i in this.markers) { - if (this.markers[i].id == id) { - marker = this.markers[i]; - break; + $N.Class.create("MarkerMap", $N.Core, { + markers: null, + //the main div container: + divContainer: $J("#markers_div_id"), + initialize: function($super, markers) { + $super(); + if (!markers){ + markers = []; } - } - return marker; - }, - - indexOf: function(marker) { - var index = null; - for (var i in this.markers) { - if (this.markers[i].id == marker.id) { - index = parseInt(i); - break; + this.markers = markers; + }, + + get: function(index){ + return this.markers[index]; + + }, + + + 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(); + + + this.markers.splice(idx,0,marker); + //notifies controller.onMarkerMapAdd + this.fire('add', { + marker: marker, + index: idx + }); + //this.fireRefreshLabels(idx+1,this.markers.length); + //this._reorder(marker.offset); + //this.fireEditMode(marker); + return idx; + }, + //argument is either an object loaded from server or a number specifying the marker offset + createMarker: function(argument){ + var marker = null; + if(typeof argument == 'object'){ + var editable = CURRENT_USER_NAME === argument.author; + marker = { + id: argument.public_id, + offset: argument.time, + desc: argument.description, + title: argument.title, + author: argument.author, + isEditable: editable, + isSaved: true + + }; + }else if(typeof argument == 'number'){ + marker = { + id: undefined, //before was: this.uniqid(), + //now an undefined id means: not saved on server (see sendHTTP below) + offset: parseFloat(argument), + desc: "", + title: "", + author: CURRENT_USER_NAME, + isEditable: true, + isSaved: false + }; } - } - return index; - }, + return marker; - _reorder: function() { - this.markers.sort(this.compare); - for (var i in this.markers) { - this.fire('indexchange', {marker: this.markers[i], index: parseInt(i)}); - } - }, - - add: function(offset, desc) { - var id = this.uniqid(); - var marker = {id: id, offset: offset, desc: desc}; - var i = this.markers.push(marker) - 1; - this.fire('add', {marker: marker, index: i}); - this._reorder(); - return marker; - }, - - remove: function(marker) { - if (marker) { - var i = this.indexOf(marker); - this.markers.splice(i, 1); - this.fire('remove', {marker: marker}); - this._reorder(); - } - return marker; - }, - - compare: function(marker1, marker2) { - if (marker1.offset > marker2.offset) - return 1; - if (marker1.offset < marker2.offset) - return -1; - return 0; - }, - - move: function(marker, offset) { - oldMarkers = [].concat(this.markers); - marker.offset = offset; - this._reorder(); - }, - - getPrevious: function(offset, skip) { - var marker = null; - if (!skip) skip = 0; - markers = [].concat(this.markers).reverse(); - $J(markers).each(function(i, m) { - if (offset > m.offset && !(skip--)) { - marker = m; - return false; + }, + + remove: function(index) { + var marker = this.get(index); + if (marker) { + if(marker.isSaved){ + this.removeHTTP(marker); + } + this.markers.splice(index, 1); + //notifies controller.js + this.fire('remove', { + index: index + }); + } + return marker; + }, + + move: function(markerIndex, newOffset){ + var newIndex = this.indexOf(newOffset); + + //if we moved left to right, the insertion index is actually + //newIndex-1, as we must also consider to remove the current index markerIndex, so: + if(newIndex>markerIndex){ + newIndex--; + } + //this way, we are sure that if markerIndex==newIndex we do not have to move, + //and we can safely first remove the marker then add it at the newIndex without + //checking if we moved left to right or right to left + var marker = this.markers[markerIndex]; + marker.offset = newOffset; + marker.isSaved = marker.isEditable ? false : true; + if(newIndex != markerIndex){ + this.markers.splice(markerIndex,1); + this.markers.splice(newIndex,0,marker); } - }); - return marker; - }, - - getNext: function(offset, skip) { - var marker = null; - if (!skip) skip = 0; - $J(this.markers).each(function(i, m) { - if (offset < m.offset && !(skip--)) { - marker = m; - return false; + this.fire('moved', { + fromIndex: markerIndex, + toIndex: newIndex + }); + }, + // + //The core search index function: returns insertionIndex if object is found according to comparatorFunction, + //(-insertionIndex-1) if object is not found. This assures that if the returned + //number is >=0, the array contains the element, otherwise not and the element can be inserted at + //-insertionIndex-1 + insertionIndex: function(object){ + var offset; + if(typeof object == 'object'){ + offset = object.offset; + }else if(typeof object == 'number'){ + offset = object; + }else{ //to be sure... + offset = parseFloat(object); } - }); - return marker; - }, + var pInt = parseInt; //reference to parseInt (to increase algorithm performances) + var comparatorFunction = function(a,b){ + return (ab ? 1 : 0)); + }; + var data = this.markers; + var low = 0; + var high = data.length-1; - each: function(callback) { - $J(this.markers).each(callback); - } -}); + while (low <= high) { + //int mid = (low + high) >>> 1; + var mid = pInt((low + high)/2); + var midVal = data[mid]; + var cmp = comparatorFunction(midVal.offset,offset); + if (cmp < 0){ + low = mid + 1; + }else if (cmp > 0){ + high = mid - 1; + }else{ + return mid; // key found + } + } + return -(low + 1); // key not found + }, + //indexOf is the same as insertionIndex, but returns a positive number. + //in other words, it is useful when we do not want to know if obj is already present + //in the map, but only WHERE WOULD be inserted obj in the map. obj can be a marker + //or an offset (time). In the latter case a dummy marker with that offset will be considered + indexOf: function(obj){ + var idx = this.insertionIndex(obj); + return idx<0 ? -idx-1 : idx; + }, + each: function(callback) { + $J(this.markers).each(callback); + }, + // length: function(){ + // return this.markers ? this.markers.length : 0; + // }, + + + sendHTTP: function(marker, functionOnSuccess, showAlertOnError){ + + //itemid is the item (spund file) name + var sPath = window.location.pathname; + //remove last "/" or last "/#", if any... + sPath = sPath.replace(/\/#*$/,""); + var itemid = sPath.substring(sPath.lastIndexOf('/') + 1); + + //WARNING: use single quotes for the whole string!! + //see http://stackoverflow.com/questions/4809157/i-need-to-pass-a-json-object-to-a-javascript-ajax-method-for-a-wcf-call-how-can + // var data2send = '{"id":"jsonrpc", "params":[{"item_id":"'+ itemid+'", "public_id": "'+marker.id+'", "time": "'+ + // marker.offset+'","description": "'+marker.desc+'"}], "method":"telemeta.add_marker","jsonrpc":"1.0"}'; + + var isSaved = marker.id !== undefined; + if(!isSaved){ + marker.id=this.uniqid(); //defined in core; + } + var method = isSaved ? "telemeta.update_marker" : "telemeta.add_marker"; + + var s = this.jsonify; + var data2send = '{"id":"jsonrpc", "params":[{"item_id":"'+ s(itemid)+ + '", "public_id": "'+s(marker.id)+'", "time": "'+s(marker.offset)+ + '", "author": "'+s(marker.author)+ + '", "title": "'+s(marker.title)+ + '","description": "'+s(marker.desc)+'"}], "method":"'+method+'","jsonrpc":"1.0"}'; + + $.ajax({ + type: "POST", + url: '/json/', + contentType: "application/json", + data: data2send, + success: function(){ + if(!isSaved){ + marker.isSaved = true; + } + if(functionOnSuccess){ + functionOnSuccess(); + } + }, + error: function(jqXHR, textStatus, errorThrown){ + if(showAlertOnError){ + var details = "\n(no further info available)"; + if(jqXHR) { + details="\nThe server responded witha status of "+jqXHR.status+" ("+ + jqXHR.statusText+")\n\nDetails (request responseText):\n"+jqXHR.responseText; + } + alert("ERROR: Failed to save marker"+details); + } + } + }); + + + }, + + jsonify: function(string){ + var s = string; + if(typeof string == "string"){ + s = string.replace(/\\/g,"\\\\") + .replace(/\n/g,"\\n") + .replace(/"/g,"\\\""); + } + return s; + }, + removeHTTP: function(marker){ + + // //itemid is the item (spund file) name + // var sPath = window.location.pathname; + // //remove last "/" or last "/#", if any... + // sPath = sPath.replace(/\/#*$/,""); + // var itemid = sPath.substring(sPath.lastIndexOf('/') + 1); + var public_id = marker.id; + //WARNING: use single quotes for the whole string!! + //see http://stackoverflow.com/questions/4809157/i-need-to-pass-a-json-object-to-a-javascript-ajax-method-for-a-wcf-call-how-can + var data2send = '{"id":"jsonrpc","params":["'+public_id+'"], "method":"telemeta.del_marker","jsonrpc":"1.0"}'; + // var map = this.cfg.map; + // var me = this; + $.ajax({ + type: "POST", + url: '/json/', + contentType: "application/json", + data: data2send, + dataType: "json" + + }); + var g = 9; + } + + }); -$N.notifyScriptLoad(); + $N.notifyScriptLoad(); }); diff --git a/timeside/ui/src/player.js b/timeside/ui/src/player.js index 04df2f6..793b2a2 100644 --- a/timeside/ui/src/player.js +++ b/timeside/ui/src/player.js @@ -7,98 +7,107 @@ TimeSide(function($N, $J) { -$N.Class.create("Player", $N.Core, { - skeleton: { - 'div.viewer': { - 'div.ruler': {}, - 'div.wave': { - 'div.image-canvas': {}, - 'div.image-container': ['img.image'] - } + $N.Class.create("Player", $N.Core, { + skeleton: { + 'div.viewer': { + 'div.ruler': {}, + 'div.wave': { + 'div.image-canvas': {}, + 'div.image-container': ['img.image'] + } + }, + 'div.control': { + 'div.layout': { + 'div.playback': ['a.play', 'a.pause', 'a.rewind', 'a.forward', 'a.set-marker'] + //,'input.textMarker'] + } + }/*, + 'div.marker-control': ['a.set-marker']*/ }, - 'div.control': { - 'div.layout': { - 'div.playback': ['a.play', 'a.pause', 'a.rewind', 'a.forward', 'a.set-marker'] + defaultContents: { + play: 'Play', + pause: 'Pause', + rewind: 'Rewind', + forward: 'Forward', + 'set-marker': 'Set marker' + //,'text-marker' : 'textmarker' + }, + elements: {}, + ruler: null, + soundProvider: null, + map: null, + container: null, + imageWidth: null, + imageHeight: null, + + initialize: function($super, container, cfg) { + $super(); + if (!container) + throw new $N.RequiredArgumentError(this, 'container'); + this.container = $J(container); + this.configure(cfg, { + image: null + }); + }, + + free: function($super) { + this.elements = null; + this.container = null; + $super(); + }, + + setSoundProvider: function(soundProvider) { + this.soundProvider = soundProvider; + return this; + }, + + setMarkerMap: function(map) { + this.map = map; + return this; + }, + + setImage: function(expr) { + this.cfg.image = expr; + this.refreshImage(); + }, + + refreshImage: function() { + var src = null; + if (typeof this.cfg.image == 'function') { + src = this.cfg.image(this.imageWidth, this.imageHeight); + } else if (typeof this.cfg.image == 'string') { + src = this.cfg.image; } - }/*, - 'div.marker-control': ['a.set-marker']*/ - }, - defaultContents: { - play: 'Play', - pause: 'Pause', - rewind: 'Rewind', - forward: 'Forward', - 'set-marker': 'Set marker' - }, - elements: {}, - ruler: null, - soundProvider: null, - map: null, - container: null, - imageWidth: null, - imageHeight: null, - - initialize: function($super, container, cfg) { - $super(); - if (!container) - throw new $N.RequiredArgumentError(this, 'container'); - this.container = $J(container); - this.configure(cfg, { - image: null - }); - }, - - free: function($super) { - this.elements = null; - this.container = null; - $super(); - }, - - setSoundProvider: function(soundProvider) { - this.soundProvider = soundProvider; - return this; - }, - - setMarkerMap: function(map) { - this.map = map; - return this; - }, - - setImage: function(expr) { - this.cfg.image = expr; - this.refreshImage(); - }, - - refreshImage: function() { - var src = null; - if (typeof this.cfg.image == 'function') { - src = this.cfg.image(this.imageWidth, this.imageHeight); - } else if (typeof this.cfg.image == 'string') { - src = this.cfg.image; - } - if (src) - this.elements.image.attr('src', src); - }, - - draw: function() { - this.debug('drawing'); - $N.domReady(this.attach(this._setupInterface)); - return this; - }, - - _setupInterface: function() { - this.elements = $N.Util.loadUI(this.container, this.skeleton, this.defaultContents); - - // IE apparently doesn't send the second mousedown on double click: - var jump = $J.browser.msie ? 'mousedown dblclick' : 'mousedown'; - this.elements.rewind.attr('href', '#').bind(jump, this.attach(this._onRewind)) - .click(function() {return false; }); - this.elements.forward.attr('href', '#').bind(jump, this.attach(this._onForward)) - .click(function() {return false; }); - this.elements.pause.attr('href', '#').bind('click', this.attach(this._onPause)); - this.elements.play.attr('href', '#').bind('click', this.attach(this._onPlay)); - this.elements.control.find('a').add(this.elements.setMarker) + if (src) { + this.elements.image.attr('src', src); + } + }, + + draw: function() { + this.debug('drawing'); + $N.domReady(this.attach(this._setupInterface)); + return this; + }, + + _setupInterface: function() { + this.elements = $N.Util.loadUI(this.container, this.skeleton, this.defaultContents); + + // IE apparently doesn't send the second mousedown on double click: + var jump = $J.browser.msie ? 'mousedown dblclick' : 'mousedown'; + this.elements.rewind.attr('href', '#').bind(jump, this.attach(this._onRewind)) + .click(function() { + return false; + }); + this.elements.forward.attr('href', '#').bind(jump, this.attach(this._onForward)) + .click(function() { + return false; + }); + this.elements.pause.attr('href', '#').bind('click', this.attach(this._onPause)); + this.elements.play.attr('href', '#').bind('click', this.attach(this._onPlay)); + + //assigning title string to all anchors??????? + this.elements.control.find('a').add(this.elements.setMarker) .attr('href', '#') .each(function(i, a){ a = $J(a); @@ -106,117 +115,158 @@ $N.Class.create("Player", $N.Core, { a.attr('title', a.text()); }); - //this.elements.markerControl.find('a').attr('href', '#'); - if (this.map) { - this.elements.setMarker.bind('click', this.attach(this._onSetMarker)); - } else { - this.elements.setMarker.remove(); - } - this.ruler = new $N.Ruler({ - viewer: this.elements.viewer, - map: this.map, - soundProvider: this.soundProvider - }); - this.ruler + //this.elements.markerControl.find('a').attr('href', '#'); + if (this.map && CURRENT_USER_NAME) { + //configureMarkersDiv(); + this.elements.setMarker.bind('click', this.attach(this._onSetMarker)); + //this.elements.setMarker2.bind('click', this.attach(this._onSetMarker2)); + //this.elements.textMarker.attr('type', 'text'); + //this.elements.textMarker.bind('click', this.attach(this._onSetMarker2)); + + } else { + this.elements.setMarker.remove(); + } + //creating the ruler + this.ruler = new $N.Ruler({ + viewer: this.elements.viewer, + //map: this.map, + soundProvider: this.soundProvider + }); + //bind events to the ruler (see function observe in core.js, I guess, + //which overrides jQuery bind function): + //the first arg is basically the event name, the second + //arg is a function to execute each time the event is triggered + this.ruler .observe('markermove', this.forwardEvent) .observe('markeradd', this.forwardEvent) .observe('move', this.forwardEvent) .draw(); - this.refreshImage(); - this.resize(); - var resizeTimer = null; - $J(window).resize(this.attach(function() { - if (resizeTimer) - clearTimeout(resizeTimer); - resizeTimer = setTimeout(this.attach(this.resize), 100); - })); + this.refreshImage(); + this.resize(); + var resizeTimer = null; + $J(window).resize(this.attach(function() { + if (resizeTimer) + clearTimeout(resizeTimer); + resizeTimer = setTimeout(this.attach(this.resize), 100); + })); //this.container.resize(this.attach(this.resize)); // Can loop ? - }, - - resize: function(overrideHeight) { - this.debug("resizing"); - var height; - if (overrideHeight === true) { - this.debug("override height"); - height = this.elements.image.css('height', 'auto').height(); - } else { - height = this.elements.wave.height(); - this.debug("wave height:" + height); - if (!height) { - this.elements.image.one('load', this.attach(function() { - this.resize(true); - this.debug("image loaded"); - })); - height = this.elements.image.height(); + }, + + resize: function(overrideHeight) { + this.debug("resizing"); + var height; + if (overrideHeight === true) { + this.debug("override height"); + height = this.elements.image.css('height', 'auto').height(); + } else { + height = this.elements.wave.height(); + this.debug("wave height:" + height); + if (!height) { + this.elements.image.one('load', this.attach(function() { + this.resize(true); + this.debug("image loaded"); + })); + height = this.elements.image.height(); + } } - } - var elements = this.elements.image + var elements = this.elements.image .add(this.elements.imageContainer) .add(this.elements.imageCanvas); - elements.css('width', 'auto'); // for IE6 + elements.css('width', 'auto'); // for IE6 - if (!height) - height = 200; - var style = { - width: this.elements.wave.width(), - height: height - } - elements.css(style); - this.imageWidth = style.width; - this.imageHeight = style.height; - this.refreshImage(); - this.ruler.resize(); - return this; - }, - - _onRewind: function() { - var offset = 0; - if (this.map) { - var position = this.soundProvider.getPosition(); - var marker = this.map.getPrevious(position); - if (marker && this.soundProvider.isPlaying() - && position - marker.offset < this.ruler.getUnitDuration()) - marker = this.map.getPrevious(marker.offset) - if (marker) { - offset = marker.offset; + if (!height){ + height = 200; } - } - this.fire('move', {offset: offset}); - return false; - }, - - _onForward: function() { - var offset = this.soundProvider.getDuration(); - if (this.map) { - var marker = this.map.getNext(this.soundProvider.getPosition()); - if (marker) { - offset = marker.offset; + var style = { + width: this.elements.wave.width(), + height: height } + elements.css(style); + this.imageWidth = style.width; + this.imageHeight = style.height; + this.refreshImage(); + this.ruler.resize(); + return this; + }, + + _onRewind: function() { + var offset = 0; + if (this.map) { + var position = parseFloat(this.soundProvider.getPosition()); + // var marker = this.map.getPrevious(position); + // if (marker && this.soundProvider.isPlaying() + // && position - marker.offset < this.ruler.getUnitDuration()) + // marker = this.map.getPrevious(marker.offset) + // if (marker) { + // offset = marker.offset; + // } + // + var idx = this.map.indexOf(position)-1; + if(idx>=0){ + var marker = this.map.get(idx); + if(marker){ + offset = marker.offset; + } + } + } + this.fire('move', { + offset: offset + }); + return false; + }, + + _onForward: function() { + var offset = this.soundProvider.getDuration(); + if (this.map) { + var position = parseFloat(this.soundProvider.getPosition()); + var idx = this.map.insertionIndex(position); + if(idx>=0){ //the pointer is exactly on a marker, increase by one + //otherwise the index is the marker itself and we wouldn't move ahead + idx++; + }else{ + //we are not on a pointer, get the index of the marker + //(see markermap insertionindex) + idx = -idx-1; + } + if(idx>=0){ + var marker = this.map.get(idx); + if(marker){ + offset = marker.offset; + } + } + // var marker = this.map.getNext(this.soundProvider.getPosition()); + // if (marker) { + // offset = marker.offset; + // } + } + this.fire('move', { + offset: offset + }); + return false; + }, + + _onPlay: function() { + this.fire('play'); + return false; + }, + + _onPause: function() { + this.fire('pause'); + return false; + }, + + _onSetMarker: function() { + if (this.map) { + this.fire('markeradd', { + offset: this.soundProvider.getPosition() + }); + } + return false; } - this.fire('move', {offset: offset}); - return false; - }, - - _onPlay: function() { - this.fire('play'); - return false; - }, - - _onPause: function() { - this.fire('pause'); - return false; - }, - - _onSetMarker: function() { - if (this.map) { - this.fire('markeradd', {offset: this.soundProvider.getPosition()}); - } - return false; - } -}); + }); -$N.notifyScriptLoad(); + $N.notifyScriptLoad(); }); diff --git a/timeside/ui/src/ruler.js b/timeside/ui/src/ruler.js index 5932c43..e5697e4 100644 --- a/timeside/ui/src/ruler.js +++ b/timeside/ui/src/ruler.js @@ -7,275 +7,313 @@ TimeSide(function($N, $J) { -$N.Class.create("Ruler", $N.Core, { + $N.Class.create("Ruler", $N.Core, { - fullSectionDuration: 60, - sectionSubDivision: 10, - sectionSteps: [[5, 1], [10, 1], [20, 2], [30, 5], [60, 10], [120, 20], [300, 30], + fullSectionDuration: 60, + sectionSubDivision: 10, + sectionSteps: [[5, 1], [10, 1], [20, 2], [30, 5], [60, 10], [120, 20], [300, 30], [600, 60], [1800, 300], [3600, 600]], - sectionsNum: 0, - timeLabelWidth: 0, - pointerPos: 0, - layout: null, - width: null, - mouseDown: false, - pointer: null, - markers: new Array(), - duration: 0, - container: null, - waveContainer: null, - - initialize: function($super, cfg) { - $super(); - this.configure(cfg, { - viewer: [null, 'required'], - fontSize: 10, - map: null, - soundProvider: [null, 'required'] - }); - this.cfg.viewer = $J(this.cfg.viewer); - this.container = this.cfg.viewer.find('.' + $N.cssPrefix + 'ruler'); - this.waveContainer = this.cfg.viewer.find('.' + $N.cssPrefix + 'image-canvas'); - this._setDuration(this.cfg.soundProvider.getDuration()); - var imgContainer = this.cfg.viewer.find('.' + $N.cssPrefix + 'image-container'); // for IE - this._observeMouseEvents(this.waveContainer.add(imgContainer)); - if (this.cfg.map) { - this.cfg.map - .observe('add', this.attach(this._onMapAdd)) - .observe('remove', this.attach(this._onMapRemove)) - .observe('indexchange', this.attach(this._onMapIndexChange)); - } - this.cfg.soundProvider.observe('update', this.attach(this._onSoundProviderUpdate)); - }, - - free: function($super) { - this.layout = null; - this.container = null; - this.waveContainer = null; - this.cfg.viewer = null; - $super(); - }, - - _computeLayout: function() { - this.width = this.waveContainer.width(); + sectionsNum: 0, + timeLabelWidth: 0, + pointerPos: 0, + layout: null, + width: null, + mouseDown: false, + pointer: null, + markers: new Array(), + duration: 0, + container: null, + waveContainer: null, + + initialize: function($super, cfg) { + $super(); + this.configure(cfg, { + viewer: [null, 'required'], + fontSize: 10, + //map: null, + soundProvider: [null, 'required'] + }); + this.cfg.viewer = $J(this.cfg.viewer); + this.container = this.cfg.viewer.find('.' + $N.cssPrefix + 'ruler'); + this.waveContainer = this.cfg.viewer.find('.' + $N.cssPrefix + 'image-canvas'); + this._setDuration(this.cfg.soundProvider.getDuration()); + var imgContainer = this.cfg.viewer.find('.' + $N.cssPrefix + 'image-container'); // for IE + + this._observeMouseEvents(this.waveContainer.add(imgContainer)); + //if (this.cfg.map) { + // this.cfg.map + //.observe('add', this.attach(this._onMapAdd)) + //.observe('remove', this.attach(this._onMapRemove)) + //.observe('indexchange', this.attach(this._onMapIndexChange)); + //} + + this.cfg.soundProvider.observe('update', this.attach(this._onSoundProviderUpdate)); + }, + + free: function($super) { + this.layout = null; + this.container = null; + this.waveContainer = null; + this.cfg.viewer = null; + $super(); + }, + + _computeLayout: function() { + this.width = this.waveContainer.width(); - this.debug('container width: ' + this.width); - var i, ii = this.sectionSteps.length; - this.timeLabelWidth = this._textWidth('00:00', this.cfg.fontSize); - for (i = 0; i < ii; i++) { - var duration = this.sectionSteps[i][0]; - var subDivision = this.sectionSteps[i][1]; - var labelsNum = Math.floor(this.duration / duration); - if ((i == ii - 1) || (this.width / labelsNum > this.timeLabelWidth * 2)) { - this.fullSectionDuration = duration; - this.sectionSubDivision = subDivision; - this.sectionsNum = Math.floor(this.duration / this.fullSectionDuration); - break; + this.debug('container width: ' + this.width); + var i, ii = this.sectionSteps.length; + this.timeLabelWidth = this._textWidth('00:00', this.cfg.fontSize); + for (i = 0; i < ii; i++) { + var duration = this.sectionSteps[i][0]; + var subDivision = this.sectionSteps[i][1]; + var labelsNum = Math.floor(this.duration / duration); + if ((i == ii - 1) || (this.width / labelsNum > this.timeLabelWidth * 2)) { + this.fullSectionDuration = duration; + this.sectionSubDivision = subDivision; + this.sectionsNum = Math.floor(this.duration / this.fullSectionDuration); + break; + } } - } - }, + }, - getUnitDuration: function() { - return this.sectionSubDivision; - }, + getUnitDuration: function() { + return this.sectionSubDivision; + }, - resize: function() { - var pointerVisible = this.pointer && this.pointer.isVisible(); - this._computeLayout(); - this.draw(); - if (pointerVisible) { - this.setPosition(this.cfg.soundProvider.getPosition()); - this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying()); - this.pointer.show(); - } - }, - - _setDuration: function(duration) { - this.duration = duration; - this._computeLayout(); - }, - - setDuration: function(duration) { - if (duration == 0) - duration = 60; - if (this.duration != duration) { - this._setDuration(duration); + resize: function() { + var pointerVisible = this.pointer && this.pointer.isVisible(); + this._computeLayout(); this.draw(); - } - }, + if (pointerVisible) { + this.setPosition(this.cfg.soundProvider.getPosition()); + this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying()); + this.pointer.show(); + } + }, + + _setDuration: function(duration) { + this.duration = duration; + this._computeLayout(); + }, + + setDuration: function(duration) { + if (duration == 0) + duration = 60; + if (this.duration != duration) { + this._setDuration(duration); + this.draw(); + } + }, - _createSection: function(timeOffset, pixelWidth) { - var section = $J('
') + _createSection: function(timeOffset, pixelWidth) { + var section = $J('
') .addClass($N.cssPrefix + 'section') .css({ - fontSize: this.cfg.fontSize + 'px', + fontSize: this.cfg.fontSize + 'px', fontFamily: 'monospace', width: pixelWidth, overflow: 'hidden' }) .append($J('
').addClass($N.cssPrefix + 'canvas')); - var topDiv = $J('
') + var topDiv = $J('
') .addClass($N.cssPrefix + 'label') .appendTo(section); - var bottomDiv = $J('
') + var bottomDiv = $J('
') .addClass($N.cssPrefix + 'lines') .appendTo(section); - var empty = $J('').css({visibility: 'hidden'}).text(' '); - if (pixelWidth > this.timeLabelWidth) { - var text = $J('') + var empty = $J('').css({ + visibility: 'hidden' + }).text(' '); + if (pixelWidth > this.timeLabelWidth) { + var text = $J('') .text($N.Util.makeTimeLabel(timeOffset)) - .bind('mousedown selectstart', function() {return false;}); - } else { - var text = empty.clone(); - } - topDiv.append(text); - bottomDiv.append(empty); - return section; - }, - - _drawSectionRuler: function(section, drawFirstMark) { - var j; - var jg = new jsGraphics(section.find('.' + $N.cssPrefix + 'canvas').get(0)); - jg.setColor(this.layout.find('.' + $N.cssPrefix + 'lines').css('color')); - var height = section.height(); - var ypos; - for (j = 0; j < section.duration; j += this.sectionSubDivision) { - if (j == 0) { - if (drawFirstMark) { - ypos = 0; + .bind('mousedown selectstart', function() { + return false; + }); + } else { + var text = empty.clone(); + } + topDiv.append(text); + bottomDiv.append(empty); + return section; + }, + + _drawSectionRuler: function(section, drawFirstMark) { + var j; + var jg = new jsGraphics(section.find('.' + $N.cssPrefix + 'canvas').get(0)); + jg.setColor(this.layout.find('.' + $N.cssPrefix + 'lines').css('color')); + var height = section.height(); + var ypos; + for (j = 0; j < section.duration; j += this.sectionSubDivision) { + if (j == 0) { + if (drawFirstMark) { + ypos = 0; + } else { + continue; + } } else { - continue; + ypos = (j == section.duration / 2) ? 1/2 + 1/8 : 3/4; } - } else { - ypos = (j == section.duration / 2) ? 1/2 + 1/8 : 3/4; + var x = j / this.duration * this.width; + jg.drawLine(x, height * ypos, x, height - 1); } - var x = j / this.duration * this.width; - jg.drawLine(x, height * ypos, x, height - 1); - } - jg.paint(); - }, + jg.paint(); + }, - getHeight: function() { - return this.container.find('' + $N.cssPrefix + '.section').height(); - }, + getHeight: function() { + return this.container.find('' + $N.cssPrefix + '.section').height(); + }, - draw: function() { - if (!this.duration) { - this.debug("Can't draw ruler with a duration of 0"); - return; - } - this.debug("draw ruler, duration: " + this.duration); - if (this.layout) - this.layout.remove(); - this.layout = $J('
') + draw: function() { + if (!this.duration) { + this.debug("Can't draw ruler with a duration of 0"); + return; + } + this.debug("draw ruler, duration: " + this.duration); + if (this.layout){ + this.layout.remove(); + } + this.layout = $J('
') .addClass($N.cssPrefix + 'layout') - .css({position: 'relative'}) // bugs on IE when resizing + .css({ + position: 'relative' + }) // bugs on IE when resizing .bind('dblclick', this.attachWithEvent(this._onDoubleClick)) //.bind('resize', this.attachWithEvent(this.resize)) // Can loop ? .appendTo(this.container); - //this.container.html(this.layout); + //this.container.html(this.layout); - var sections = new Array(); - var currentWidth = 0; - var i; - for (i = 0; i <= this.sectionsNum; i++) { - if (i < this.sectionsNum) { - var duration = this.fullSectionDuration; - var width = Math.floor(duration / this.duration * this.width); - } else { - var duration = this.duration - i * this.fullSectionDuration; - var width = this.width - currentWidth; + var sections = new Array(); + var currentWidth = 0; + var i; + for (i = 0; i <= this.sectionsNum; i++) { + if (i < this.sectionsNum) { + var duration = this.fullSectionDuration; + var width = Math.floor(duration / this.duration * this.width); + } else { + var duration = this.duration - i * this.fullSectionDuration; + var width = this.width - currentWidth; - } - var section = this._createSection(i * this.fullSectionDuration, width); - if (i > 0) { - section.css({left: currentWidth, top: 0, position: 'absolute'}); + } + var section = this._createSection(i * this.fullSectionDuration, width); + if (i > 0) { + section.css({ + left: currentWidth, + top: 0, + position: 'absolute' + }); + } + section.duration = duration; + this.layout.append(section); + currentWidth += section.width(); + sections[i] = section; } - section.duration = duration; - this.layout.append(section); - currentWidth += section.width(); - sections[i] = section; - } - - for (i = 0; i <= this.sectionsNum; i++) { - this._drawSectionRuler(sections[i], (i > 0)); - } - this._createPointer(); - this._drawMarkers(); - }, + for (i = 0; i <= this.sectionsNum; i++) { + this._drawSectionRuler(sections[i], (i > 0)); + } - _createPointer: function() { - if (this.pointer) { - this.pointer.clear(); - } - this.pointer = new $N.Marker({ - rulerLayout: this.layout.get(0), - viewer: this.waveContainer, - fontSize: this.cfg.fontSize, - zIndex: 1000, - className: 'pointer', - tooltip: 'Move head' - }); - this.pointer + this._createPointer(); + //draw markers + if (this.cfg.map) { + $J(this.markers).each(function(i, m) { + m.clear(); + }); + this.markers = new Array(); + this.cfg.map.each(this.attach(function(i, m) { + this.markers.push(this._drawMarker(m, i)); + })); + } + //this._drawMarkers(); + }, + + // _drawMarkers: function() { + // if (this.cfg.map) { + // $J(this.markers).each(function(i, m) { + // m.clear(); + // }); + // this.markers = new Array(); + // this.cfg.map.each(this.attach(function(i, m) { + // this.markers.push(this._drawMarker(m, i)); + // })); + // } + // }, + + _createPointer: function() { + if (this.pointer) { + this.pointer.clear(); + } + this.pointer = new $N.Marker({ + rulerLayout: this.layout.get(0), + viewer: this.waveContainer, + fontSize: this.cfg.fontSize, + zIndex: 1000, + top:0, + className: 'pointer', + tooltip: 'Move head', + canMove: true + }); + // //create the label + // var tsMainLabel = $.find('.' + $N.cssPrefix + 'label'); + // if(tsMainLabel){ + // var label = tsMainLabel.find('#' + $N.cssPrefix + 'pointerOffset'); + // if(!label){ + // label = $("").id('#' + $N.cssPrefix + 'pointerOffset').css('zIndex','10').appendTo(tsMainLabel); + // this.pointer.label = label; + // } + // } + + this.pointer + //.setText("+") .setText($N.Util.makeTimeLabel(0)) .observe('move', this.attach(this._onPointerMove)); - }, + }, - _drawMarkers: function() { - if (this.cfg.map) { - $J(this.markers).each(function(i, m) {m.clear();}); - this.markers = new Array(); - this.cfg.map.each(this.attach(function(i, m) { - this.markers.push(this._drawMarker(m, i)); - })); - } - }, - - _movePointer: function(offset) { - if (offset < 0) - offset = 0; - else if (offset > this.duration) - offset = this.duration; - - pixelOffset = offset / this.duration * this.width; - if (this.pointer) { - this.pointer.move(pixelOffset); - this.pointer.setText($N.Util.makeTimeLabel(offset)); - } - this.pointerPos = offset; - }, + _movePointer: function(offset) { + if (offset < 0){ + offset = 0; + }else if (offset > this.duration){ + offset = this.duration; + } + pixelOffset = offset / this.duration * this.width; + if (this.pointer) { + this.pointer.move(pixelOffset); + this.pointer.setText($N.Util.makeTimeLabel(offset)); + } + this.pointerPos = offset; + }, - _setPosition: function(offset) { - this._movePointer(offset); - if (this.pointer) { - this.pointer.show(); - } - }, + _setPosition: function(offset) { + this._movePointer(offset); + if (this.pointer) { + this.pointer.show(); + } + }, - setPosition: function(offset) { - if (!this.mouseDown) { - this._setPosition(offset); - } - }, + setPosition: function(offset) { + if (!this.mouseDown) { + this._setPosition(offset); + } + }, - shiftPosition: function(delta) { - this.setPosition(this.pointerPos + delta); - }, + shiftPosition: function(delta) { + this.setPosition(this.pointerPos + delta); + }, - hidePointer: function() { - if (this.pointer) - this.pointer.hide(); - }, + hidePointer: function() { + if (this.pointer) + this.pointer.hide(); + }, - setBuffering: function(state) { - if (this.pointer) { - this.pointer.blink(state); - } - }, -/* + setBuffering: function(state) { + if (this.pointer) { + this.pointer.blink(state); + } + }, + /* _onClick: function(evt) { var offset = (evt.pageX - this.container.offset().left) / this.width * this.duration; @@ -283,116 +321,162 @@ $N.Class.create("Ruler", $N.Core, { this.fire('move', {offset: offset}); }, */ - _onMouseDown: function(evt) { - this.mouseDown = true; - this._onMouseMove(evt); - evt.preventDefault(); - }, - - _onPointerMove: function(evt, data) { - this.mouseDown = true; - this._setPosition(data.offset / this.width * this.duration); - if(data.finish) { - this.fire('move', {offset: this.pointerPos}); - this.mouseDown = false; - } - return false; - }, - - _onMouseMove: function(evt) { - if (this.mouseDown) { - var pixelOffset = evt.pageX - this.container.offset().left; - this._setPosition(pixelOffset / this.width * this.duration); + _onMouseDown: function(evt) { + this.mouseDown = true; + this._onMouseMove(evt); + evt.preventDefault(); + }, + + _onPointerMove: function(evt, data) { + this.mouseDown = true; + this._setPosition(data.offset / this.width * this.duration); + if(data.finish) { + this.fire('move', { + offset: this.pointerPos + }); + this.mouseDown = false; + } return false; - } - }, + }, - _onMouseUp: function(evt) { - if (this.mouseDown) { - this.mouseDown = false; - this.fire('move', {offset: this.pointerPos}); - return false; - } - }, + _onMouseMove: function(evt) { + if (this.mouseDown) { + var pixelOffset = evt.pageX - this.container.offset().left; + this._setPosition(pixelOffset / this.width * this.duration); + return false; + } + }, + + _onMouseUp: function(evt) { + + if (this.mouseDown) { + this.mouseDown = false; + this.fire('move', { + offset: this.pointerPos + }); + return false; + } + }, - _observeMouseEvents: function(element) { - element - .bind('click dragstart', function() {return false;}) + _observeMouseEvents: function(element) { + if(!(CURRENT_USER_NAME)){ + return; + } + element + .bind('click dragstart', function() { + return false; + }) .bind('mousedown', this.attachWithEvent(this._onMouseDown)) .bind('mousemove', this.attachWithEvent(this._onMouseMove)) .bind('mouseup', this.attachWithEvent(this._onMouseUp)); - $J(document) + $J(document) .bind('mousemove', this.attachWithEvent(this._onMouseMove)); - }, + }, - _drawMarker: function(marker, index) { - if (marker.offset < 0) - marker.offset = 0; - else if (marker.offset > this.duration) - marker.offset = this.duration; + _drawMarker: function(marker, index) { + if (marker.offset < 0){ + marker.offset = 0; + }else if (marker.offset > this.duration){ + marker.offset = this.duration; + } - pixelOffset = marker.offset / this.duration * this.width; - - m = new $N.Marker({ - rulerLayout: this.layout.get(0), - viewer: this.waveContainer, - fontSize: this.cfg.fontSize, - className: 'marker', - id: marker.id, - tooltip: 'Move marker' - }); - m.observe('move', this.attach(this._onMarkerMove)) - .setText(index + 1) + pixelOffset = marker.offset / this.duration * this.width; + + m = new $N.Marker({ + rulerLayout: this.layout.get(0), + viewer: this.waveContainer, + fontSize: this.cfg.fontSize, + className: 'marker', + index: index, + tooltip: 'Move marker', + canMove: marker.isEditable + }); + if(marker.isEditable){ + m.observe('move', this.attach(this._onMarkerMove)) + } + //m.observe('move', this.attach(this._onMarkerMove)) + m + //.setText(index + 1) .move(pixelOffset) .show(); - return m; - }, - - _onMarkerMove: function(e, data) { - if (data.finish) { - var offset = data.offset / this.width * this.duration; - this.fire('markermove', {id: data.id, offset: offset}); - } - }, - - _onMapAdd: function(e, data) { - this.markers.push(this._drawMarker(data.marker, data.index)); - }, - - - _onMapRemove: function(e, data) { - $J(this.markers).each(this.attach(function(i, m) { - if (m.id == data.marker.id) { - m.clear(); - this.markers.splice(i, 1); + return m; + }, + + _onMarkerMove: function(e, data) { + if (data.finish) { + var offset = data.offset / this.width * this.duration; + this.fire('markermove', { + index: data.index, + offset: offset + }); } - })); - }, - - _onMapIndexChange: function(e, data) { - $J(this.markers).each(this.attach(function(i, m) { - if (m.id == data.marker.id) { - m.setText(data.index + 1); - return false; + }, + + add: function(marker, index){ + this.markers.splice(index, 0, this._drawMarker(marker, index)); + //this.markers.push(this._drawMarker(marker, index)); + }, + + // _onMapAdd2: function(e, data) { + // this.markers.push(this._drawMarker(data.marker, data.index)); + // }, + + remove: function(index){ + var rulermarker = this.markers[index]; + rulermarker.clear(); + this.markers.splice(index, 1); + }, + + //it is assured that fromIndex!=toIndex and fromIndex!=toIndex+1 (see markermap.move) + move: function(fromIndex, toIndex){ + var m = this.markers.splice(fromIndex,1)[0]; //remove + this.markers.splice(toIndex,0,m); //add + }, + + updateMarkerIndices:function(fromIndex, toIndex){ + for(var i=fromIndex; i<=toIndex; i++){ + this.markers[i].setIndex(i); } - })); - }, + }, - _onDoubleClick: function(evt) { - if (this.cfg.map) { - var offset = (evt.pageX - this.container.offset().left) + _onDoubleClick: function(evt) { + if (CURRENT_USER_NAME) { + var offset = (evt.pageX - this.container.offset().left) / this.width * this.duration; - this.fire('markeradd', {offset: offset}); - } - }, + this.fire('markeradd', { + offset: offset + }); + } + }, - _onSoundProviderUpdate: function(e) { - this.setDuration(this.cfg.soundProvider.getDuration()); - this.setPosition(this.cfg.soundProvider.getPosition()); - this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying()); - } -}); + _onSoundProviderUpdate: function(e) { + this.setDuration(this.cfg.soundProvider.getDuration()); + this.setPosition(this.cfg.soundProvider.getPosition()); + this.setBuffering(this.cfg.soundProvider.isBuffering() && this.cfg.soundProvider.isPlaying()); + } + }); -$N.notifyScriptLoad(); + $N.notifyScriptLoad(); }); + +// _onMapRemove: function(e, data) { + // $J(this.markers).each(this.attach(function(i, m) { + // if (m.id == data.marker.id) { + // m.clear(); + // this.markers.splice(i, 1); + // } + // })); + // }, + + // onMapMove: function(fromIndex, toIndex) { + // var min = Math.min(fromIndex, toIndex); + // var max = Math.max(fromIndex, toIndex); + // this.updateMarkerIndices(min,max); + //// $J(this.markers).each(this.attach(function(i, m) { + //// if (m.id == data.marker.id) { + //// m.setText(data.index + 1); + //// return false; + //// } + //// })); + // }, diff --git a/timeside/ui/src/timeside.js b/timeside/ui/src/timeside.js index 95b0f51..fe4cf97 100644 --- a/timeside/ui/src/timeside.js +++ b/timeside/ui/src/timeside.js @@ -5,120 +5,127 @@ * License: GNU General Public License version 2.0 */ -var TimeSide = function() { +//this global variable SEEMS to do a check on the variable jQuery, then +//simply executes the argument (which is a function) +var TimeSide = function() { + //arguments is an array-like object corresponding to the arguments passed to a function if (arguments[0]) { var toolkit = null; - if (typeof jQuery != 'undefined') + if (typeof jQuery != 'undefined'){ toolkit = jQuery; + } + //call arguments[0] (a function) with arguments this and jQuery (arguments[0])(TimeSide, toolkit) } }; - +//this is the first function instantiated. It SEEMS to check the document status and +//load synchronously all the scripts TimeSide(function($N, $J) { -$N.isDomLoaded = false; -$N.isLoaded = false; -$N.isLoading = false; -$N.onLoadCallbacks = []; -$N.cssPrefix = 'ts-'; -$N.debugging = false; - -$J(document).ready(function () { - $N.isDomLoaded = true; -}); + $N.isDomLoaded = false; + $N.isLoaded = false; + $N.isLoading = false; + $N.onLoadCallbacks = []; + $N.cssPrefix = 'ts-'; + $N.debugging = false; -$N.domReady = function(callback) { - // simply calling jQuery.ready() *after* the DOM is loaded doesn't work reliably, - // at least with jQuery 1.2.6 - if ($N.isDomLoaded) - callback(); - else - $J(document).ready(callback); -} - -$N.instances = []; -$N.registerInstance = function(obj) { - $N.instances.push(obj); -} - -$N.free = function() { - $J($N.instances).each(function(i, obj) { - obj.free(); + $J(document).ready(function () { + $N.isDomLoaded = true; }); -} -$J(window).unload($N.free); + $N.domReady = function(callback) { + // simply calling jQuery.ready() *after* the DOM is loaded doesn't work reliably, + // at least with jQuery 1.2.6 + if ($N.isDomLoaded) { + callback(); + } else{ + $J(document).ready(callback); + } + } -$N.loadScriptsNum = 0; -$N.loadScriptsCallback = null; -$N.loadScripts = function(root, scripts, callback) { - if ($N.loadScriptsCallback) { - throw "Timeside loader error: concurrent script loading"; + $N.instances = []; + $N.registerInstance = function(obj) { + $N.instances.push(obj); } - $N.loadScriptsNum = scripts.length; - $N.loadScriptsCallback = callback; + $N.free = function() { + $J($N.instances).each(function(i, obj) { + obj.free(); + }); + } + + $J(window).unload($N.free); + + $N.loadScriptsNum = 0; + $N.loadScriptsCallback = null; + $N.loadScripts = function(root, scripts, callback) { + if ($N.loadScriptsCallback) { + throw "Timeside loader error: concurrent script loading"; + } + + $N.loadScriptsNum = scripts.length; + $N.loadScriptsCallback = callback; - var head= document.getElementsByTagName('head')[0]; - for (i = 0; i < scripts.length; i++) { + var head= document.getElementsByTagName('head')[0]; + for (i = 0; i < scripts.length; i++) { - var script = document.createElement('script'); - script.type = 'text/javascript'; - var debug = $N.debugging ? '?rand=' + Math.random() : ''; - script.src = root + scripts[i] + debug; - head.appendChild(script); + var script = document.createElement('script'); + script.type = 'text/javascript'; + var debug = $N.debugging ? '?rand=' + Math.random() : ''; + script.src = root + scripts[i] + debug; + head.appendChild(script); + } } -} -$N.notifyScriptLoad = function() { - if (--$N.loadScriptsNum == 0 && $N.loadScriptsCallback) { - var callback = $N.loadScriptsCallback; - $N.loadScriptsCallback = null; - callback(); + $N.notifyScriptLoad = function() { + if (--$N.loadScriptsNum == 0 && $N.loadScriptsCallback) { + var callback = $N.loadScriptsCallback; + $N.loadScriptsCallback = null; + callback(); + } } -} - -$N.debug = function(state) { - $N.debugging = state; -} - -$N.load = function(callback) { - $N.domReady(function() { - if ($N.isLoaded) { - if (callback) - callback(); - } else { - if (callback) - $N.onLoadCallbacks.push(callback); - - if (!$N.isLoading) { - $N.isLoading = true; - var re = /(.*)timeside.js/; - var root = ''; - $J('head script').each(function(i, e) { - if (match = re.exec(e.src)) { - root = match[1]; - } - }); - - $N.loadScripts(root, ['core.js'], function() { - $N.loadScripts(root, ['util.js'], function() { - var scripts = ['controller.js', 'marker.js', 'markerlist.js', - 'markermap.js', 'player.js', 'ruler.js', - 'soundprovider.js']; + + $N.debug = function(state) { + $N.debugging = state; + } + + $N.load = function(callback) { + $N.domReady(function() { + if ($N.isLoaded) { + if (callback) + callback(); + } else { + if (callback) + $N.onLoadCallbacks.push(callback); + + if (!$N.isLoading) { + $N.isLoading = true; + var re = /(.*)timeside.js/; + var root = ''; + $J('head script').each(function(i, e) { + if ((match = re.exec(e.src))) { + root = match[1]; + } + }); + + $N.loadScripts(root, ['core.js'], function() { + $N.loadScripts(root, ['util.js'], function() { + var scripts = ['controller.js', 'marker.js', 'markerlist.js', + 'markermap.js', 'player.js', 'ruler.js','divmarker.js', + 'soundprovider.js']; - $N.loadScripts(root, scripts, function() { - $N.isLoaded = true; - $N.isLoading = false; - $J($N.onLoadCallbacks).each(function(i, callback) { - callback(); + $N.loadScripts(root, scripts, function() { + $N.isLoaded = true; + $N.isLoading = false; + $J($N.onLoadCallbacks).each(function(i, callback) { + callback(); + }); }); }); }); - }); + } } - } - }); -} + }); + } }); diff --git a/timeside/ui/src/util.js b/timeside/ui/src/util.js index 94c42dc..2b7c800 100755 --- a/timeside/ui/src/util.js +++ b/timeside/ui/src/util.js @@ -7,77 +7,213 @@ TimeSide(function($N, $J) { -$N.Util = { - _loadChild: function(container, tag, className, index, contents) { - var p = $N.cssPrefix; - var element = container.find('.' + p + className); - if (!element.length) { - element = $J(document.createElement(tag)).addClass(p + className); - if (contents[className]) { - element.text(contents[className]); - } - var children = container.children(); - if (index < children.length) { - children.eq(index).before(element); - } else { - container.append(element); + $N.Util = { + _loadChild: function(container, tag, className, index, contents) { + var p = $N.cssPrefix; + var element = container.find('.' + p + className); + if (!element.length) { + element = $J(document.createElement(tag)).addClass(p + className); + if (contents[className]) { + element.text(contents[className]); + } + var children = container.children(); + if (index < children.length) { + children.eq(index).before(element); + } else { + container.append(element); + } } - } - return element; - }, - - _loadUI: function(container, skeleton, contents) { - var i = 0; - var elements = {}; - with ($N.Util) { - if (skeleton[0]) { - $J(skeleton).each((function(i, selector) { - var s = selector.split('.'); - elements[$N.Util.camelize(s[1])] = _loadChild(container, s[0], s[1], i++, contents); - })); - } else { - for (key in skeleton) { - var s = key.split('.'); - var e = _loadChild(container, s[0], s[1], i++, contents); - elements[$N.Util.camelize(s[1])] = e; - $N.extend(elements, _loadUI(e, skeleton[key], contents)); + return element; + }, + + _loadUI: function(container, skeleton, contents) { + var i = 0; + var elements = {}; + with ($N.Util) { + if (skeleton[0]) { + $J(skeleton).each((function(i, selector) { + var s = selector.split('.'); + elements[$N.Util.camelize(s[1])] = _loadChild(container, s[0], s[1], i++, contents); + })); + } else { + for (key in skeleton) { + var s = key.split('.'); + var e = _loadChild(container, s[0], s[1], i++, contents); + elements[$N.Util.camelize(s[1])] = e; + $N.extend(elements, _loadUI(e, skeleton[key], contents)); + } + } + } + return elements; + }, + + loadUI: function(container, skeleton, contents) { + return $N.Util._loadUI($J(container), skeleton, contents); + }, + + makeTimeLabel: function(offset) { + var minutes = Math.floor(offset / 60); + if (minutes < 10) + minutes = '0' + minutes; + var seconds = Math.floor(offset % 60); + if (seconds < 10) + seconds = '0' + seconds; + return minutes + ':' + seconds; + }, + + camelize: function(str) { + var parts = str.split('-'), len = parts.length; + if (len == 1) return parts[0]; + + var camelized = str.charAt(0) == '-' + ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) + : parts[0]; + + for (var i = 1; i < len; i++) + camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); + + return camelized; + }, + + setUpTabs:function(selIndex) {//called from within controller.js once all markers have been loaded. + //this is because we need all divs to be visible to calculate size. selIndex is optional, it defaults to 0 + // + //declare variables: + var tabContainerHeight = '5ex'; //height for the tab container + var tabHeight = '3.5ex'; //height for the tab. Must be lower than tabContainerHeight + var tabPaddingTop ='.8ex'; //padding top of each tab. Increasing it will increase also the tab height, so + //compensate by decreasing tabHeight, in case. In any case, must be lower or equal to tabContainerHeight-tabHeight + var tabWidth = '10ex'; //width of each tab. Each tab from index 1 to n will be at left=n*tabWidth + var tabBottom ='-1px'; //bottom of each tab. Must be equal and opposite to the border of the div below the tab + + //retrieve tab container: + var tabContainer = $("#tabs_container"); //change if tabContainer has to be retrieved diferently + //retrieve the tabs by checking the elements whose class name starts with "tab_" + //var tabs = $('a[class^="tab_"]'); //change if the tabs have to be determined differently. + var tabs = tabContainer.find('a[id^="tab_"]'); + //function that retrieves the div relative to a tab (the div will be set visible.invisible according to tab click): + var tab2div = function(tab){ + return $("#"+tab.attr("name")); + //ie, returns the element whose id is equal to the tab name. + //change here if div has to be determined differently + }; + var selectedTabClassName = "tab_selected"; //change if needed + var unselectedTabClassName = "tab_unselected"; //change if needed + var tabClicked = function(index) { + for(var i=0; i