From: riccardo Date: Wed, 27 Apr 2011 14:32:02 +0000 (+0200) Subject: added click on an image, still to implement transparent background for bug in IE X-Git-Tag: 1.1~278 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=77b76de864ecf9ba150d782fa54cf827fcd9bcff;p=telemeta.git added click on an image, still to implement transparent background for bug in IE --- diff --git a/telemeta/htdocs/js/application.js b/telemeta/htdocs/js/application.js index f4272476..498cda73 100644 --- a/telemeta/htdocs/js/application.js +++ b/telemeta/htdocs/js/application.js @@ -447,7 +447,6 @@ var popup={ //field must be a dictionary of label:defaultValues (both strings) //callbackOnOk is the callback to be executed on ok, if null ok will simply hide the dialog - //otherwise it must be a function accepting createDivDialog : function(field,callbackOnOk){ var $J = this._cfg_.jQuery; @@ -513,7 +512,6 @@ var popup={ //popupDialog(element,table,onOk); return $J('
').append(table).append(subdiv); } - } /** @@ -616,4 +614,399 @@ function consolelog(text){ c.log(text); } } -} \ No newline at end of file +} + + +//var PopupClass=function(innerHTML,event){ +// var $J = jQuery; //reference to jQuery +// var className = 'component'; //the optional div class name +// var div = $J('
').css({ //create the div (the popup) +// position: 'absolute', +// overflow:'auto', //necessary to properly display the content +// display: 'none', +// zIndex:1000 +// }); +// if(className){ +// div.addClass(className); +// }; +// +// if(content instanceof $J){ +// div.append(content); +// }else{ +// div.html(content); +// } +// //create the div shadow +// var divShadow = div.clone(false,false).empty().css({'zIndex':999,'borderColor':'#000','display':'none','backgroundColor':'#000'}).insertAfter(div); +// //append to the body +// var body = $J('body'); +// body.append(div); +// divShadow.insertAfter(div); +// div = div.add(divShadow); +// //set the id +// var time = new Date().getTime(); +// div.attr('id','popup_'+time); +// divShadow.attr('id','popupshadow_'+time); +// //make thid class a jQuery object: +// $J.extend(this,div); +// //override some methods: +// // +// //private function which binds/unbinds click and key events +// var toggleBind = function(element, callback){ +// var clickNamespace = "click.popup__"+time; +// var keydownNamespace = "keyup.popup__"+time; +// element.unbind(clickNamespace); +// element.unbind(keydownNamespace); +// if(callback){ +// element.bind(clickNamespace, callback); +// element.bind(keydownNamespace,callback); +// } +// }; +// +// var doc = $J(document); //reference to the document +// +// //hide: +// var hide = this.hide; +// this.hide = function(){ +// toggleBind(doc); +// }; +// +// //remove: +// var me = this; +// var remove = this.remove; +// this.remove = function(){ +// me.hide(); +// remove.apply(me,arguments); +// }; +// +// //show: +// var shadowOffset = 5; //the shadow offset, change to increment/ decrement +// var show = this.show; +// +// this.show = function(){ +// place($J(me[0]),event); +// var position = $J(me[0]).offset(); +// $J(me[1]).css({ +// 'top': (position.top + shadowOffset), +// 'left': (position.left + shadowOffset), +// 'width': div.outerWidth(true), +// 'height': div.outerHeight(true) +// }); +// toggleBind(doc, me.hide); +// +// if(arguments.length>0){ +// var oldCallback = arguments[arguments.length-1]; +// arguments[arguments.length-1] = function(){ +// $J(me[1]).fadeTo(0,0.4,oldCallback); +// } +// show.apply(me, arguments); +// }else{ +// show.apply(me); +// $J(me[1]).fadeTo(0,0.4); +// } +// +// }; +// +// +// +// +// +// _cfg_:{ +// jQuery:jQuery, +// div: function(){ +// var div = this.jQuery('
').css({ //this is _cfg_ +// position: 'absolute', +// overflow:'auto', //necessary to properly display the content +// display: 'none', +// border: '1px solid #e1e1e1', +// zIndex:1000 +// }); +// if(this.className){ +// div.addClass(this.className); +// } +// return div; +// }, +// className: 'component', +// // mouseDownNamespace : "mousedown.popup__", +// // keyDownNamespace : "keydown.popup__", +// +// //namespace: 'popup__', //used for namespaces when binding click to document +// handlersToRestore: [], +// event: null, +// divsToDelete:null, +// toggleBind: function(element, functionE){ +// var clickNamespace = "click.popup__"; +// var keydownNamespace = "keyup.popup__"; +// element.unbind(clickNamespace); +// element.unbind(keydownNamespace); +// if(functionE){ +// element.bind(clickNamespace, functionE); +// element.bind(keydownNamespace,functionE); +// } +// } +// }, +// +// isShowing: function(){ +// return this._cfg_.divsToDelete ? true : false; +// }, +// +// +// hide: function(){ +// var toggleBind = this._cfg_.toggleBind; +// +// var $J = this._cfg_.jQuery; +// +// toggleBind($J(document)); +// if(this._cfg_.divsToDelete){ +// for(var i=0; i < this._cfg_.divsToDelete.length; i++){ +// this._cfg_.divsToDelete[i].empty().remove(); +// } +// } +// if(this._cfg_.event && this._cfg_.handlersToRestore){ +// var type = this._cfg_.event.type; //which should be the same as h.type below, without namespaces? +// var invokerElement = this._cfg_.event.target; +// if(invokerElement){ +// var e = $J(invokerElement); +// toggleBind(e); +// if(type){ +// //e.unbind(type); +// for(var i=0; i0){ +// namespace="."+namespace; +// } +// var what = h.type+ namespace; +// e.bind(what, functionCode); +// } +// } +// } +// } +// this._cfg_.event=null; +// this._cfg_.handlersToRestore=null; +// }, +// +// show:function(content, optionalEvent){ +// consolelog("showing popup:"+optionalEvent); +// //if showing, hide +// if(this.isShowing()){ +// this.hide(); +// } +// +// var $J = this._cfg_.jQuery; +// var div = this._cfg_.div(); +// //toggleBind sets the functions to hiding/keep shown the popup when clicking or +// //using the keyboard keys +// var toggleBind = this._cfg_.toggleBind; +// +// //remove the callback on invoker so that clicking on invoker does nothing +// //moreover, toggleBind on invoker so that clicking invoker doesn't hide the popup +// this.oldCallback = undefined; +// var oldHandlers=[]; +// var invokerElement = optionalEvent && optionalEvent.target ? $J(optionalEvent.target) : undefined; +// if(invokerElement){ +// optionalEvent.stopPropagation(); //othewrwise the popup hides immediately +// //cause the event is catched from the document click (added later, see below) +// // but apparently as soon as we add it it catches even the current event) +// var type = optionalEvent.type; +// var clickEvents =invokerElement.data("events")[type]; +// $J.each(clickEvents, function(key, value) { +// oldHandlers.push(value); +// }) +// invokerElement.unbind(type); //remove (temporarily) the binding to the event. +// //for instance, if we show the popup by clicking invoker, when the popup is shown do nothing +// //on clicking invoker until popup.hide is called +// toggleBind(invokerElement,function(e){ //add bindings to stop cancel the popup in case the invoker is clicked again +// e.stopPropagation(); +// return false; +// }); +// } +// //store the functions removed from invoker, if any, to restore them in this.hide +// this._cfg_.handlersToRestore = oldHandlers; +// this._cfg_.event = optionalEvent; +// +// //toggleBind on each child of content so that clicking and pressing keys on +// //a child doesn't hide the popup +// var children = $J(content).find('*'); +// $J(children).each(function(){ +// toggleBind($(this),function(e){ +// e.stopPropagation(); +// return false; +// }); +// }); +// //showing +// var doc = $J(document); +// $J('body').append(div); +// +// content.css('position','static'); //this is really important to place the content in the normal flow +// //within the div. static is the default +// content.show(); //in case the div is display:none +// div.append(content); +// +// //positioning div: center of the screen if no invoker, below the invoker otherwise +// var wdow = $J(window); //reference the window object (doing it once speeds up a bit performances) +// var windowH = wdow.height(); +// var windowW = wdow.width(); +// var position = div.offset(); +// var shadowOffset=5; +// var size = { +// width:div.outerWidth(true)+shadowOffset, +// height:div.outerHeight(true)+shadowOffset +// }; +// if(invokerElement){ +// position = invokerElement.offset(); +// position.top+= invokerElement.outerHeight(true); +// }else{ +// position.top = wdow.scrollTop()+ (windowH-size.height)/2; +// position.left = wdow.scrollLeft()+(windowW-size.width)/2; +// } +// //position div. This must be done immediately cause here below we want to get the div offset +// //(div position in absolute - ie, document's - coordinates) +// div.css({ +// 'top': position.top, +// 'left': position.left, +// 'right': 'auto', //in case right has been set by some css class rule +// 'bottom': 'auto' //see above... +// }); +// //set the maximum size +// //due to overflow:auto a scrollbar will automatically appear +// var max = Math.max; //reference max immediately (speeds up performances a bit) +// var maxSize = { +// width: max(20,windowW + wdow.scrollLeft() -position.left-shadowOffset), +// height: max(20, (windowH + wdow.scrollTop() -position.top- shadowOffset)) +// } +// //position div and size: +// var divPadding = { +// left: div.outerWidth()-div.width(), +// top:div.outerHeight()-div.height() +// }; //setting width on a div means the width(), +// //but calculations here are made according to outerWidth(true), so we need this variable (se below) +// +// //the shadow in the background will be created according to the actual div size +// //However, since we do not specify neither width nor height, the calculation of the div size +// //works if maxWidth and maxHeight do set a width and height. In order to do so, they +// //must be lower or equal to the actual div width and height. That's why the "min" here below:' +// div.css({ +// 'maxWidth': Math.min(div.width(), maxSize.width-divPadding.left), +// 'maxHeight': Math.min(div.height(), maxSize.height-divPadding.top) +// }); +// +// //last thing: if invoker element exist, set width at least invoker element width +// if(invokerElement){ +// var iEw = invokerElement.outerWidth(); //no margins considered +// if(iEwdiv.outerWidth()){ +// div.css({ +// 'minWidth':iEw-divPadding.left +// }); +// } +// } +// //now we can build the divShadow +// var divShadow = div.clone(false,false).empty().css({'zIndex':999,'borderColor':'#000','display':'none','backgroundColor':'#000'}).insertAfter(div); +// //store the divs to be removed +// this._cfg_.divsToDelete = [div,divShadow]; +// //add a listener to the document. If one of the content children is clicked/keypressed, +// //we won't come here. Otherwise hide popup +// var me = this; +// var hide = this.hide; +// toggleBind(doc,function(e){ +// hide.apply(me); +// e.stopPropagation(); +// }); +// div.show(300, function(){ //basically in between fast (200) and slow (600) +// //position div shadow: +// divShadow.show(); +// consolelog(div.outerHeight(true)+" "+div.outerHeight(false)); +// consolelog(divShadow.outerHeight(true)+" "+divShadow.outerHeight(false)); +// +// //set focus to the first input component, if any. Otherwise try with anchors, otherwise do nothing +// var inputs = $J(div).find(':input'); +// if(inputs && inputs[0]){ +// inputs[0].focus(); +// }else{ +// inputs = $J(div).find('a'); +// if(inputs && inputs[0]){ +// inputs[0].focus(); +// } +// } +// +// divShadow.fadeTo(0,0.4, function(){ +// divShadow.css({ +// 'top': (position.top+shadowOffset), +// 'left': (position.left+shadowOffset), +// 'width': div.outerWidth(true), +// 'height': div.outerHeight(true) +// }); +// +// }); +// }); +// return false; //to avoid scrolling if we clicked on an anchor +// }, +// +// //field must be a dictionary of label:defaultValues (both strings) +// //callbackOnOk is the callback to be executed on ok, if null ok will simply hide the dialog +// createDivDialog : function(field,callbackOnOk){ +// +// var $J = this._cfg_.jQuery; +// var table = $J(''); +// var fieldElms = {}; +// for(var label in field){ +// var input = $('') +// .attr('type','text').val(field[label]).attr("name",label); +// table.append($J('') +// .append($J('
').html(label)) +// .append($J('').append(input))); +// fieldElms[label]=input; +// } +// +// var p = this; +// var onCancel= function(){ +// p.hide(); +// return false; +// }; +// +// var onOk= function(){ +// if(callbackOnOk){ +// var ret = {}; +// var inputs = table.find("input"); +// $J.each(inputs, function(key,value){ +// var v = $J(value); +// ret[v.attr('name')] = v.val(); +// }); +// callbackOnOk(ret); +// return false; +// }else{ +// return onCancel(); +// } +// }; +// var subdiv = $J('
').css({ +// 'padding':'1ex', +// 'float':'right' +// }). +// append( +// $J(''). +// html('Ok'). +// addClass('component_icon'). +// addClass('button'). +// addClass('icon_ok'). +// attr('href','#'). +// click(function(){ +// return onOk(); +// }) +// ); +// if(callbackOnOk){ +// subdiv.append( +// $J(''). +// html('Cancel'). +// addClass('component_icon'). +// addClass('button'). +// addClass('icon_cancel'). +// attr('href','#'). +// click(function(){ +// return onCancel(); +// }) +// ); +// } +// //popupDialog(element,table,onOk); +// return $J('
').append(table).append(subdiv); +// } +//} \ No newline at end of file diff --git a/telemeta/htdocs/timeside/src/divmarker.js b/telemeta/htdocs/timeside/src/divmarker.js index 98e293d0..72f0178f 100644 --- a/telemeta/htdocs/timeside/src/divmarker.js +++ b/telemeta/htdocs/timeside/src/divmarker.js @@ -133,7 +133,7 @@ var MarkerMapDiv = TimesideArray.extend({ setFocus: function(index,value){ this.each(function(i,div){ if(i==index && value){ - div.css('backgroundColor','#f5cf23'); //'#efc823' + div.css('backgroundColor','#E65911'); //'#f5cf23' }else{ div.css('backgroundColor',''); } diff --git a/telemeta/htdocs/timeside/src/player.js b/telemeta/htdocs/timeside/src/player.js index f5224759..b3427560 100644 --- a/telemeta/htdocs/timeside/src/player.js +++ b/telemeta/htdocs/timeside/src/player.js @@ -82,7 +82,10 @@ var Player = TimesideClass.extend({ var map = player.getMarkerMap(); var indexToShow = map.insertionIndex(player.getSoundPosition()); - var mydiv = this.$J('
').addClass('markerDiv').css({'position':'absolute','zIndex':1000}); + var mydiv = this.$J('
').addClass('markerDiv').css({ + 'position':'absolute', + 'zIndex':1000 + }); var ruler = player.getRuler(); @@ -234,18 +237,10 @@ var Player = TimesideClass.extend({ // }); var me=this; //attaching event to the image. Note that attaching an event to a transparent div is buggy in IE -// if($J.browser.msie){ -// -// } - consolelog('ope'); - consolelog(jQueryObjs.find('.ts-image').length); - jQueryObjs.find('.ts-image').click(function(event){ - alert('g'); - consolelog(event); - -// me.setSoundPosition( me.getSoundDuration()/$J(this).width()); - }); - + // if($J.browser.msie){ + // + // } + var rewind_ = this.rewind; var forward_ = this.forward; @@ -324,6 +319,18 @@ var Player = TimesideClass.extend({ return false; }); + //binds click for the pointer: TODO: change this way of getting the tsviweer!!!! + var v = $J('#player').find('.ts-viewer'); + v.unbind('click').click(function(evt){ + var w = v.width(); + var x = evt.pageX - v.offset().left; //using absolute coordinates allows us to + //avoid checking whether or not we are clicking on a vertical marker line, on a subdiv etcetera + var sd = me.getSoundDuration(); + me.setSoundPosition(sd*x/w); + ruler.movePointer(ruler.toSoundPosition(x)); + }); + + //finally, load markers and bind events for markers (see method below): this.loadMarkers(isInteractive); @@ -377,10 +384,10 @@ var Player = TimesideClass.extend({ getImageUrl: function(){ return this.$J('#visualizer_id').get(0).value; }, - refreshImage: function(optionalImgTagElm){ + refreshImage: function(optionalImgJQueryElm){ var image; - if(optionalImgTagElm){ - image = optionalImgTagElm; + if(optionalImgJQueryElm){ + image = optionalImgJQueryElm; }else{ image = this.getElements().find('.ts-image'); } @@ -487,6 +494,7 @@ var Player = TimesideClass.extend({ loadMarkers: function(isInteractive_){ //ruler.bind('markermoved',this.markerMoved,this); + var $J = this.$J; //reference to jQuery var itemId = ITEM_PUBLIC_ID; @@ -526,9 +534,13 @@ var Player = TimesideClass.extend({ // //add binding to the setMarker button (html anchor): var setMarkerButton = player.getElements().find('.ts-set-marker'); + var tab = $J('#tab_markers'); if(setMarkerButton){ if(isInteractive_){ setMarkerButton.show().attr('href','#').unbind('click').bind('click', function(){ + if(tab && tab.length){ + tab.trigger('click'); + } map.add(player.getSoundPosition()); return false; }); @@ -599,8 +611,8 @@ var Player = TimesideClass.extend({ // setUpPlayerTabs([jQuery('#tab_analysis'), jQuery('#tab_markers')], // [jQuery('#analyzer_div_id'), jQuery('#markers_div_id')], tabIndex, // 'tab_selected','tab_unselected'); - setUpPlayerTabs(jQuery('#tab_analysis').add(jQuery('#tab_markers')), - [jQuery('#analyzer_div_id'), jQuery('#markers_div_id')], tabIndex, + setUpPlayerTabs($J('#tab_analysis').add($J('#tab_markers')), + [$J('#analyzer_div_id'), $J('#markers_div_id')], tabIndex, 'tab_selected','tab_unselected'); }; json([itemId],"telemeta.get_markers", onSuccess); diff --git a/telemeta/htdocs/timeside/src/ruler.js b/telemeta/htdocs/timeside/src/ruler.js index 0cad0338..34250a5a 100644 --- a/telemeta/htdocs/timeside/src/ruler.js +++ b/telemeta/htdocs/timeside/src/ruler.js @@ -381,8 +381,8 @@ var Ruler = TimesideArray.extend({ //note that setText is called BEFORE move as move must have the proper label width this.each(indexIfMarker, function(i,rulermarker){ rulermarker.setIndex(i,i!=indexIfMarker); - //rulermarker.setIndex.apply(rulermarker, [i,i!=indexIfMarker]); //update label width only if it is not this marker added - //as for this marker we update the position below (move) + //rulermarker.setIndex.apply(rulermarker, [i,i!=indexIfMarker]); //update label width only if it is not this marker added + //as for this marker we update the position below (move) }); this.debug('added marker at index '+indexIfMarker+' offset: '+markerObjOrOffset.offset); }else{ @@ -394,6 +394,13 @@ var Ruler = TimesideArray.extend({ //pointer.setText(markerClass== 'pointer' ? this.makeTimeLabel(0) : this.length); + //click on labels stop propagating. Always: + var lbl = pointer.getLabel(); + lbl.bind('click', function(evt){ + evt.stopPropagation(); + return false; + }); + //if there are no events to associate, return it. if(!isMovable){ return pointer; @@ -402,7 +409,6 @@ var Ruler = TimesideArray.extend({ //namespace for jquery event: var eventId = 'markerclicked'; var doc = $J(document); - var lbl = pointer.getLabel(); var me = this; @@ -411,8 +417,12 @@ var Ruler = TimesideArray.extend({ ismovingpointer = value; } //TODO: this method below private, but how to let him see in the bind below??? - this.setPointerMovingFromMouse = function(value){setmovingpointer(value);} - this.isPointerMovingFromMouse = function(){ return ismovingpointer;}; + this.setPointerMovingFromMouse = function(value){ + setmovingpointer(value); + } + this.isPointerMovingFromMouse = function(){ + return ismovingpointer; + }; //functions to set if we are moving the pointer (for player when playing) lbl.bind('mousedown.'+eventId,function(evt) { @@ -424,7 +434,7 @@ var Ruler = TimesideArray.extend({ var startX = evt.pageX; //lbl.position().left-container.position().left; var startPos = lbl.position().left+lbl.width()/2; - evt.stopPropagation(); //dont notify the ruler; + evt.stopPropagation(); //dont notify the ruler or other elements; var newPos = startPos; doc.bind('mousemove.'+eventId, function(evt){ var x = evt.pageX; @@ -437,23 +447,24 @@ var Ruler = TimesideArray.extend({ return false; }); - lbl.bind('click.'+eventId, function(){ - return false; - }); //to avoid scrolling + //to avoid scrolling //TODO: what happens if the user releases the mouse OUTSIDE the browser???? var mouseup = function(evt_){ doc.unbind('mousemove.'+eventId); doc.unbind('mouseup.'+eventId); evt_.stopPropagation(); - //TODO: fire event marker moved (with the class name) + if(markerClass=='pointer'){ + me.setPointerMovingFromMouse(false); + } + if(newPos == startPos){ + consolelog('NOT MOVED!!!!'); + return false; + } var data = { 'markerElement':pointer, 'soundPosition': me.toSoundPosition.apply(me,[newPos]), 'markerClass':markerClass }; - if(markerClass=='pointer'){ - me.setPointerMovingFromMouse(false); - } me.fire('markermoved',data); return false; }; diff --git a/telemeta/templates/telemeta_default/mediaitem_detail.html b/telemeta/templates/telemeta_default/mediaitem_detail.html index 12ddabdf..6c6111ed 100644 --- a/telemeta/templates/telemeta_default/mediaitem_detail.html +++ b/telemeta/templates/telemeta_default/mediaitem_detail.html @@ -34,7 +34,7 @@ var anchor = jQuery('#_add_to_playlist'); if(anchor.length){ anchor.click(function(evtObj_){ - p.showPopupAddToPlaylist(evtObj_,'item','{{item.public_id}}','item added to selected playlist');return false; + p.showPopupAddToPlaylist(evtObj_,'item','{{item.public_id}}',gettext('item added to selected playlist'));return false; }); } {% endif %}