Front IDILL: V00.04
authorbastiena
Wed, 08 Aug 2012 18:40:40 +0200
changeset 77 205409da0f32
parent 76 eae52b187e29
child 78 52277fe2279c
Front IDILL: tablet interactions : zoom, unzoom, move, read a video, show markers for ipad but not android yet filter mosaic, draw curves but not search in video yet, show help
front_idill/src/defaults.js
front_idill/src/img/exitIcon.png
front_idill/src/img/homeIcon.png
front_idill/src/index.html
front_idill/src/index_kinect.html
front_idill/src/index_souris.html
front_idill/src/lang/en.json
front_idill/src/lang/fr.json
front_idill/src/mosaic/css/mosaic.less
front_idill/src/mosaic/js/mosaic.js
front_idill/src/mosaic/js/mouseInteractions.js
front_idill/src/mosaic/js/neighbours.js
front_idill/src/mosaic/js/notifications.js
front_idill/src/mosaic/js/pointers.js
front_idill/src/mosaic/js/search.js
front_idill/src/mosaic/js/touchInteractions.js
front_idill/src/mosaic/js/zoomInteractions.js
front_idill/src/player/metadataplayer/Timeline.js
front_idill/src/search/js/searchCanvas.js
--- a/front_idill/src/defaults.js	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/defaults.js	Wed Aug 08 18:40:40 2012 +0200
@@ -62,8 +62,9 @@
 	zoomedMargin : 42,
 	host : '127.0.0.1',
 	port : '8080',
+	touchUpDownDeltaTreshold : 100,
 	mouseUpDownDeltaTreshold : 15,
-	mouseUpDownDeltaTreshold : 100,
+	kinectUpDownDeltaTreshold : 100,
 	curveDictionaryMI : './dicoMI.json',
 	curveDictionaryKI : './dicoKI.json',
 	lang : navigator.language,
Binary file front_idill/src/img/exitIcon.png has changed
Binary file front_idill/src/img/homeIcon.png has changed
--- a/front_idill/src/index.html	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/index.html	Wed Aug 08 18:40:40 2012 +0200
@@ -36,6 +36,12 @@
         <script type="text/javascript">
             function loadMenu(textElements)
 			{
+				//Si on est sur une tablette, on passe directement dans le mode d'interaction tablette.
+				if('ontouchstart' in document.documentElement)
+				{
+					window.location.replace('./index_souris.html');
+				}
+				
 				var form = "<div id='choice'><p id='caution'>" + textElements.caution + "</p><input id='MI' type='button' /><br ><input id='KI' type='button' /></div>";
 				
 				$('body').css({
@@ -50,12 +56,21 @@
 					'font-size': '20px'
 				});
 				$('#MI').attr('value', textElements.mouse);
-				$('#MI').css('padding', '10px').click(function()
+				$('#MI').css(
+				{
+					'padding': '30px',
+					'font-size': '20px'
+				
+				}).click(function()
 				{
 					window.location.replace('./index_souris.html');
 				});
 				$('#KI').attr('value', textElements.kinect);
-				$('#KI').css('padding', '10px').click(function()
+				$('#KI').css(
+				{
+					'padding': '30px',
+					'font-size': '20px'
+				}).click(function()
 				{
 					window.location.replace('./index_kinect.html');
 				});
--- a/front_idill/src/index_kinect.html	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/index_kinect.html	Wed Aug 08 18:40:40 2012 +0200
@@ -32,6 +32,7 @@
         <script type="text/javascript" src="../lib/jquery.min.js"></script>
         <script type="text/javascript" src="../lib/jquery-ui.min.js"></script>
         <script type="text/javascript" src="../lib/jquery.mousewheel-2.0.0.min.js"></script>
+        <script type="text/javascript" src="../lib/cordova-2.0.0.js"></script>
         <script type="text/javascript" src="./defaults.js"></script>
         <script type="text/javascript" src="./mosaic/js/mosaic.js"></script>
         <script type="text/javascript" src="./mosaic/js/notifications.js"></script>
--- a/front_idill/src/index_souris.html	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/index_souris.html	Wed Aug 08 18:40:40 2012 +0200
@@ -25,6 +25,7 @@
         <!-- On inclut les styles et les scripts utilisés. -->
         <title>IDILL - Mode d'interaction souris</title>
         <meta charset="UTF-8" />
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
         <link rel="stylesheet" type="text/css" href="./mosaic/css/reset.css" />
         <link rel="stylesheet/less" type="text/css" href="./mosaic/css/mosaic.less" />
         <script type="text/javascript" src="../lib/less-1.3.0.min.js"></script>
@@ -32,8 +33,11 @@
         <script type="text/javascript" src="../lib/jquery.min.js"></script>
         <script type="text/javascript" src="../lib/jquery-ui.min.js"></script>
         <script type="text/javascript" src="../lib/jquery.mousewheel-2.0.0.min.js"></script>
+		<script type="text/javascript" src="../lib/cordova-2.0.0.js"></script>
         <script type="text/javascript" src="./defaults.js"></script>
         <script type="text/javascript" src="./mosaic/js/mosaic.js"></script>
+        <script type="text/javascript" src="./mosaic/js/mouseInteractions.js"></script>
+        <script type="text/javascript" src="./mosaic/js/touchInteractions.js"></script>
         <script type="text/javascript" src="./mosaic/js/notifications.js"></script>
         <script type="text/javascript" src="./mosaic/js/pointers.js"></script>
         <script type="text/javascript" src="./mosaic/js/zoomInteractions.js"></script>
@@ -59,6 +63,25 @@
         
         <!-- Scripts principaux. -->
         <script type="text/javascript">
+			function aa(w, h, l, t)
+			{
+				if($('#a').length == 0)
+				{
+					var a = '<div id="a"></div>';
+					$('body').append(a);
+					$('#a').css(
+					{
+						position: 'absolute',
+						'background-color': '#00F',
+						width: w,
+						height: h,
+						left: l,
+						top: t,
+						'z-index': 10000
+					});
+				}
+			}
+			
             var mos;
             //Si la page a chargé, on raffraichit la mosaïque.
             $(document).ready(function ()
--- a/front_idill/src/lang/en.json	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/lang/en.json	Wed Aug 08 18:40:40 2012 +0200
@@ -1,5 +1,5 @@
 {
-	"gesturesText":["fall", "jump", "spin", "group spin", "bend", "arm carriage", "knee up", "breakdance", "wave", "no motion", "contact"],
+	"gesturesText":["fall", "jump", "spin", "group spin", "bend", "arm carriage", "knee up", "breakdance", "wave", "no motion", "contact", "up-down", "large cast"],
 	"notificationStrings":{
 	"select":"Select", 
 	"confirm":"Confirm", 
--- a/front_idill/src/lang/fr.json	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/lang/fr.json	Wed Aug 08 18:40:40 2012 +0200
@@ -1,5 +1,5 @@
 {
-	"gesturesText":["chute", "saut", "rotation", "rotation de groupe", "penché", "port de bras", "levé de genou", "breakdance", "ondulations", "immobilité", "contact"],
+	"gesturesText":["chute", "saut", "rotation", "rotation de groupe", "penché", "port de bras", "levé de genou", "breakdance", "ondulations", "immobilité", "contact", "de haut en bas", "grand-jeté"],
 	"notificationStrings":{
 	"select":"Sélectionner", 
 	"confirm":"Confirmer", 
--- a/front_idill/src/mosaic/css/mosaic.less	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/mosaic/css/mosaic.less	Wed Aug 08 18:40:40 2012 +0200
@@ -204,6 +204,29 @@
 }
 
 /*
+ * Notifications affichées pendant une recherche en cours.
+*/
+.notification_curves
+{
+	position: relative;
+	float: left;
+	width: 200px;
+	height: 200px;
+	background-repeat: no-repeat;
+	background-position: 0px 0px;
+	background-size: 200px 200px;
+	opacity: 0;
+	margin: 15px;
+	z-index: 400;
+	text-align: center;
+	font-family: "DINMedium";
+    font-weight:10;
+    font-size:30px;
+	color: #fff;
+	padding-top: 5px;
+}
+
+/*
  * Style commun aux notifications lors d'une recherche par courbes en cours.
 */
 .notifications_inSearch
@@ -231,6 +254,15 @@
 }
 
 /*
+ * Container pour les notifications de courbes lors d'un tracé en cours.
+*/
+#notify_curves_container
+{
+	position: absolute;
+	width: 100%;
+}
+
+/*
  * Notification de sélection.
 */
 #notify_selection
@@ -443,7 +475,7 @@
 /*
  * Icone permettant d'afficher l'aide dans le mode d'interaction souris.
 */
-#helpIcon
+#helpIcon, #exitIcon, #homeIcon, #searchExitIcon
 {
 	width: 50px;
 	height: 50px;
--- a/front_idill/src/mosaic/js/mosaic.js	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/mosaic/js/mosaic.js	Wed Aug 08 18:40:40 2012 +0200
@@ -26,7 +26,7 @@
  */
 function Mosaic(config, default_conf)
 {
-    this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "knee-up", "right-angle", "wave", "slow", "hello", "no-motion", "contact", "up-down", "grand-jete"];
+    this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "knee-up", "right-angle", "wave", "no-motion", "contact", "up-down", "grand-jete"];
 
     //Chemin du fichier de configuration.
     this.config_path = config;
@@ -108,6 +108,8 @@
     this.mousePosLastY = null;
     //Valeur du déplacement entre un mouse up et un mouse down.
     this.mouseUpDownDelta = 0;
+    //Valeur du déplacement entre un touch start et un touch end.
+    this.touchUpDownDelta = 0;
 	//Coordonnées de la souris au dernier mouse down.
 	this.mouseDownPosX = null;
 	this.mouseDownPosY = null;
@@ -187,7 +189,12 @@
     this.actualCode = '';
     //Indique si l'utilisateur est entré dans la zone de recherche.
     this.isUserInSearchZone = false;
+	//Indique si on a fait un mouse down.
 	this.isMouseDown = false;
+	//Indique si on a fait un touch start.
+	this.isTouchStart = false;
+	//Indique si on a fait un touch move.
+	this.isTouchMove = false;
 	//Indique si on est en train de prézoomer.
 	this.isPrezooming = false;
 	//Indique si l'icone d'aide a été agrandie.
@@ -196,6 +203,9 @@
 	this.isHelpIconZooming = false;
 	//Indique à l'utilisateur s'il doit retirer ses mains pour refaire une recherche par courbes.
 	this.mustTakeOutHands = false;
+	
+	//Indique si on est sur une tablette.
+	this.isTablet = ('ontouchstart' in document.documentElement);
     
     //Timeout (attente) pour le zoom après un préZoom.
     this.zoomTimeout = null;
@@ -303,7 +313,7 @@
 	//On recharge la fenêtre si sa taille a changé.
 	$(window).resize(function()
 	{
-		_.debounce(window.location.reload(), _this.config.timeReloadAfterResize);
+		// _.debounce(window.location.reload(), _this.config.timeReloadAfterResize);
 	});
 	
     var initPanel = '<div id="initPanel"></div>';
@@ -339,7 +349,7 @@
             }
         }
         
-        return str + '<div id="ghostPanel"></div>';
+        return str;
     }
     else
     {
@@ -348,313 +358,6 @@
 }
 
 /*
- * Fonction appelée lors d'un mouse down en mode d'interaction souris.
- * Est appelé dans le fichier :
- * mosaic > fonction loadMosaic, attachée à l'événement jQuery mousedown.
-*/
-Mosaic.prototype.onMouseDown = function(e)
-{
-	this.isMouseDown = true;
-	
-	//Si on se trouve sur l'icone d'aide et qu'elle est zoomée.
-	if(this.isHelpIconZoomed)
-	{
-		//On affiche différentes aides en fonction de si on se trouve dans une vidéo ou non.
-		if(this.currentMode == 'SEARCH' || this.currentMode == 'VIDEO' || this.currentMode == 'TIMELINE')
-		{
-			this.notifyHelp(false);
-		}
-		else if(this.currentMode == 'FILTER' || this.currentMode == 'MOSAIC')
-		{
-			this.notifyHelp(true);
-		}
-	}
-	
-	//On met à jour les coordonnées de la souris au dernier mouse down.
-	this.mouseDownPosX = e.pageX;
-	this.mouseDownPosY = e.pageY;
-	
-	//Si on est sur une notification de gesture de recherche.
-	this.removeSearchNotificationIfOnIt(e.pageX, e.pageY);
-	this.isUserInSearchZone = true;
-	
-	//Si on est en mode de tracé de courbes, on indique qu'on a commencé à tracer au canvas.
-	if(this.isSearchByCurvesOn)
-	{
-		this.searchCanvas.onPointerIn(this.mousePosX, this.mousePosY, null, null);
-	}
-}
-
-/*
- * Fonction appelée lors d'un mouse move en mode d'interaction souris.
- * Est appelé dans le fichier :
- * mosaic > fonction loadMosaic, attachée à l'événement jQuery mousemove.
-*/
-Mosaic.prototype.onMouseMove = function(e)
-{
-	//On vérifie si la souris n'est pas sur l'icone d'aide.
-	if(this.isOnHelpIcon(this.mousePosX, this.mousePosY))
-	{
-		//On agrandit l'icone d'aide.
-		this.showBigHelp();
-	}
-	else
-	{
-		//On la rétrecit sinon.
-		this.showSmallHelp();
-	}
-	
-	//Si on n'a pas appuyé sur la souris avant, on part.
-	if(!this.isMouseDown)
-	{
-		return;
-	}
-	
-	var _this = this;
-	
-	//Si on est en mode de tracé de courbes, on met à jour la courbe.
-	if(this.isSearchByCurvesOn)
-	{
-		this.searchCanvas.onPointerMove(this.mousePosX, this.mousePosY - this.MPTop_margin, null, null);
-	}
-	
-	//On met à jour l'ancienne position de la souris si elle est nulle.
-	if(!this.mousePosLastX && this.mousePosLastX != 0)
-	{
-		this.mousePosLastX = this.mousePosX;
-	}
-	if(!this.mousePosLastY && this.mousePosLastY != 0)
-	{
-		this.mousePosLastY = this.mousePosY;
-	}
-	
-	//Le delta s'accroît si la souris bouge.
-	this.mouseUpDownDelta += Math.floor(Math.sqrt((this.mousePosLastX - e.pageX) * (this.mousePosLastX - e.pageX) + (this.mousePosLastY - e.pageY) * (this.mousePosLastY - e.pageY)));
-	
-	//On met à jour l'ancienne position de la souris.
-	if(this.mousePosLastX != this.mousePosX)
-	{
-		this.mousePosLastX = this.mousePosX;
-	}
-	if(this.mousePosLastY != this.mousePosY)
-	{
-		this.mousePosLastY = this.mousePosY;
-	}
-	
-	//Si la souris a parcouru une trop grande distance, on entre en recherche.
-	if(this.mouseUpDownDelta > this.config.mouseUpDownDeltaTreshold)
-	{
-		//Si on est en mosaique, on entre en filtrage.
-		if(this.currentMode == "MOSAIC")
-		{
-			this.preUnzoom();
-			this.currentMode = "FILTER";
-			this.isMosaicFiltered = true;
-		}
-		//Si on est en mode de filtrage, mais qu'on n'est pas en tracé de courbes.
-		else if(this.currentMode == "FILTER" && !this.isSearchByCurvesOn && this.isUserInSearchZone)
-		{
-			//On lance une nouvelle recherche pas courbes.
-			this.preUnzoom();
-		}
-		//Si on est dans une vidéo, on entre en recherche.
-		else if(this.currentMode == "VIDEO" || this.currentMode == "TIMELINE")
-		{
-			this.currentMode = "SEARCH";
-		}
-		//Si on est en mode recherche dans une vidéo, mais qu'on n'est pas en tracé de courbes.
-		/*else if(this.currentMode == "SEARCH" && !this.isSearchByCurvesOn)
-		{
-			//On lance une nouvelle recherche pas courbes.
-		}*/
-		
-		if(this.currentMode != "NO-USER" && this.currentMode.indexOf("INCOMING") == -1 && !this.isSearchByCurvesOn)
-		{
-			this.isSearchByCurvesOn = true;
-			this.startSearch();
-			this.searchCanvas.onPointerIn(this.mousePosX, this.mousePosY - this.MPTop_margin, null, null);
-		}
-		
-		//S'il n'est pas possible d'afficher l'aide.
-		if(!this.canNotifyHelp)
-		{
-			//On rend son affichage possible après un certain délai.
-			this.canNotifyHelpTimeout = setTimeout(function()
-			{
-				_this.canNotifyHelp = true;
-			}, this.config.timeoutCanNotifyHelp);
-		}
-	}
-}
-
-/*
- * Fonction appelée lors d'un mouse up en mode d'interaction souris.
- * Est appelé dans le fichier :
- * mosaic > fonction loadMosaic, attachée à l'événement jQuery mousemove.
-*/
-Mosaic.prototype.onMouseUp = function()
-{
-	this.isMouseDown = false;
-	
-	//Si on était en train de tracer une courbe.
-	if(this.isSearchByCurvesOn)
-	{
-		//On quitte la zone de recherche.
-		/*this.isUserInSearchZone = false;
-		
-		//On regarde si ce qu'on a tracé correspond à une courbe en particulier.
-		var gesture_match = this.gestureWithSameCode(this.actualCode);
-		this.actualCode = '';
-		
-		//Si oui.
-		if(gesture_match.length > 0)
-		{
-			//Si on est en mode recherche dans une vidéo et que le player est prêt.
-			if(this.currentMode == "SEARCH" && this.playerIsReady)
-			{
-				//On effectue une recherche dans cette vidéo.
-				this.player.widgets[0].searchByGesture(gesture_match);
-				this.isCurrentlyInASearchByGesture = this.player.widgets[0].isCurrentlyInASearchByGesture;
-				
-				//On va au premier marqueur trouvé.
-				if(this.player && this.player.widgets[0] && this.timeToGoAt[this.centerId] === 0 && this.player.widgets[0].atLeastOneSearchMarker(this.currentSearchGesture[this.centerId]))
-				{
-					this.player.widgets[0].goToFirstSearchedMarker(this.currentSearchGesture[this.centerId]);
-				}
-				
-				//On affiche la notification de gesture de recherche.
-				this.removeNotifications();
-				this.currentSearchGesture[this.centerId] = gesture_match;
-				this.searchGesture(gesture_match, 'valid');
-				this.curvesGesturesFound = false;
-			}
-			//Si on est en mode de filtrage de mosaique.
-			else if(this.currentMode == "FILTER")
-			{
-				if(this.isMosaicFiltered)
-				{
-					//On notifie la recherche par filtrage.
-					this.removeNotifications();
-					this.filterSearchedType = gesture_match;
-					this.filterGesture(gesture_match, 'valid');
-					//On filtre la mosaique.
-					this.searchFilter(gesture_match);
-					this.curvesGesturesFound = false;
-				}
-			}
-		}
-		//Si aucune gesture ne matche dans le dictionnaire.
-		else
-		{
-			//Si on était en mode filtrage de la mosaïque et qu'aucune gesture de filtrage n'avait été détectée avant ca, on revient en mode mosaïque.
-			if(this.currentMode == "FILTER" && this.filterSearchedType == "")
-			{
-				this.currentMode = "MOSAIC";
-				this.isMosaicFiltered = false;
-			}
-			//Sinon si on était en mode recherche dans une video et qu'aucune gesture n'avait été détectée avant ca, on revient en mode video.
-			if(this.currentMode == "SEARCH" && this.currentSearchGesture[this.centerId] == "")
-			{
-				this.currentMode = "VIDEO";
-			}
-		}*/
-		//On dit au module de recherche qu'on arrête de tracer des courbes.
-		this.searchCanvas.onPointerOut();
-	}
-	
-	this.mousePosLastX = null;
-	this.mousePosLastY = null;
-	
-	//Si la distance parcourue par la souris entre le mouse down et le mouse up est inférieure ou égale au seuil.
-	if(this.mouseUpDownDelta <= this.config.mouseUpDownDeltaTreshold)
-	{
-		//Si on est sur un snapshot prézoomé.
-		if(this.isOnAPrezoomSN && this.previousZoomedSN != '' && (this.currentMode == 'MOSAIC' || this.currentMode == 'FILTER') && !this.isPrezooming)
-		{
-			this.zoom();
-		}
-	}
-	
-	//On réinitialise le delta, on quitte la recherche par courbes.
-	this.mouseUpDownDelta = 0;
-	this.isSearchByCurvesOn = false;
-	this.leaveSearch();
-	
-	//Si on est en mode de filtrage et qu'on a une gesture de filtrage trouvée.
-	if(this.currentMode == 'FILTER' && this.filterSearchedType != '')
-	{
-		//On notifie.
-		this.removeNotifications();
-		this.filterGesture(this.filterSearchedType, 'valid');
-	}
-}
-
-/*
- * Fonction appelée lors d'un clic en mode d'interaction souris.
- * Est appelé dans le fichier :
- * mosaic > fonction loadMosaic.
-*/
-Mosaic.prototype.onClick = function(x, y)
-{
-	//Si la position de la souris entre le mouse down et le mouse up change de plus de 10px, on part.
-	if(!this.mouseDownPosX || !this.mouseDownPosY || Math.sqrt((this.mouseDownPosX - x) * (this.mouseDownPosX - x) + (this.mouseDownPosY - y) * (this.mouseDownPosY - y)) > 10)
-	{
-		return;
-	}
-	
-	//Si on est dans un mode autre qu'un mode zoomé et qu'on n'affiche pas l'aide, on part.
-	if(this.currentMode != "VIDEO" && this.currentMode != "SEARCH" && this.currentMode != "TIMELINE" && !this.helpDisplayed)
-	{
-		return;
-	}
-	
-	//Si on clique en dehors de la video centrale, alors on dézoome.
-	var TL = $('.Ldt-Timeline');
-	var TLwidth = TL.width(), TLheight = TL.height();
-	var Ptop = $('.LdtPlayer').position().top, Pleft = $('.LdtPlayer').position().left;
-	var Pheight = $('.LdtPlayer').height();
-	var MPx = this.mousePosX, MPy = this.mousePosY;
-	
-	//On regarde si on a cliqué sur un snapshot.
-	var SN = this.pointerPositionToSN(MPx - this.notifyLeftVideo, MPy - this.notifyTopVideo, true);
-	var SNId;
-	if(SN)
-	{
-		SNId = parseInt(SN.attr('id').replace('snapshotDiv-', ''));
-	}
-	
-	//Si on n'a pas demandé à supprimé la notification de gesture.
-	if(!this.gestureDelRequested && !this.helpDisplayed)
-	{
-		//Si non, ou s'il ne fait pas partie des voisins.
-		if(!SNId || !_.include(this.neighboursIds, SNId))
-		{
-			//Si le clic a lieu en dehors du player et que l'aide n'est pas affichée, on dezoom.
-			if(MPx < Pleft || MPx > (+Pleft + TLwidth) || MPy < Ptop || MPy > (+Ptop + Pheight - TLheight))
-			{
-				this.unzoom();
-			}
-		}
-		//Si on se trouve sur un voisin, on bouge.
-		else if(SNId && _.include(this.neighboursIds, SNId) && this.canMoveToNeighbour)
-		{
-			this.moveToNeighbour($('#snapshotDiv-' + SNId));
-		}
-	}
-	//Si on l'a demandé, on enlève la demande de suppression.
-	else
-	{
-		this.gestureDelRequested = false;
-	}
-	
-	//Si l'aide est affichée, un clic la ferme.
-	if(this.helpDisplayed && !this.isHelpIconZoomed && !this.isHelpIconZooming)
-	{
-		this.removeHelp();
-	}
-}
-
-/*
  * Permet de raffraichir la mosaïque.
  * Est appelé dans le fichier :
  * mosaic > fonction loadFromJson, afin de charger la mosaique une fois que les fichiers de métadonnées ont été lus.
@@ -675,6 +378,8 @@
     this.previousZoomedSN;
     //On met à jour la mosaïque.
     $('#mainPanel').html(createMosaic);
+	//On ajoute le panneau de protection (principalement pour le mode tablettes).
+	$('body').append('<div id="ghostPanel"></div>');
     //On récupère la taille des bordures.
     this.marginWidth = $('.snapshotDivs').css('margin-bottom');
     this.marginWidth = parseFloat(this.marginWidth)*2;
@@ -683,7 +388,7 @@
     //On ne calculera pas tout de suite la hauteur de la mosaique étant donnée qu'elle est calculée par la suite dynamiquement.
     this.snapshotWidth = this.width / this.config.imagesByLine - this.marginWidth;
     this.snapshotHeight = this.snapshotWidth*9/16;
-    $('.snapshotDivs').css('width', this.snapshotWidth).css('height', this.snapshotHeight).css('margin', this.marginWidth/2);
+    $('.snapshotDivs').css('width', this.snapshotWidth).css('height', this.snapshotHeight).css('margin-left', this.marginWidth/2);
     
     this.height = $('#mainPanel').innerHeight();
     //On centre verticalement la mosaïque.
@@ -730,14 +435,8 @@
                 //Si on gère les interactions à la souris.
                 if(_this.config.mouseInteractions)
                 {
-                    //On met à jour la position estimée de la souris.
-                    $(window).mousemove(function(e)
-                    {
-                        // _this.refreshPointers(e.pageX, e.pageY, _this, true);
-                        _this.refreshPointers(e.pageX, e.pageY, true);
-                        _this.mousePosX = e.pageX;
-                        _this.mousePosY = e.pageY;
-                    });
+					//On bind les événements utiles.
+					_this.eventBinder();
                 }
                 
                 //Si on a activé la préphase mais qu'on est en mode Kinect.
@@ -760,34 +459,94 @@
             }
         });
     }
-    
-    //Si on est en mode d'intéraction souris.
-    if(this.config.mouseInteractions)
-    {
-		//On affiche l'icone d'aide.
-		this.helpIcon();
-		
-        //Si on fait un mouse down sur le body, on vérifie enregistre le déplacement de la souris jusqu'au prochain mouse up.
-        $(window).mousedown(function (e)
-        {
+}
+
+/*
+ * Bind les événements souris ou touch dans le mode d'interaction souris.
+*/
+Mosaic.prototype.eventBinder = function()
+{
+	var _this = this;
+	
+	//On affiche l'icone d'aide.
+	this.helpIcon();
+	
+	//Si on est sur tablette, on utilise l'événement touch start.
+	if(this.isTablet)
+	{
+		document.addEventListener('touchstart', function(e)
+		{
+			if(e.touches.length == 1)
+			{
+				var touch = e.touches[0];
+				_this.onTouchStart(touch);
+			}
+			e.preventDefault();
+		}, false);
+	}
+	//Sinon souris.
+	else
+	{
+		//Si on fait un mouse down sur le body, on vérifie enregistre le déplacement de la souris jusqu'au prochain mouse up.
+		$(window).mousedown(function (e)
+		{
 			_this.onMouseDown(e);
 			return false;
-        });
-		
+		});
+	}
+	
+	//Si on est sur tablette, on utilise l'événement touch start.
+	if(this.isTablet)
+	{
+		document.addEventListener('touchmove', function(e)
+		{
+			if(e.touches.length == 1)
+			{
+				var touch = e.touches[0];
+				_this.refreshPointers(touch.pageX, touch.pageY, true);
+				_this.mousePosX = touch.pageX;
+				_this.mousePosY = touch.pageY;
+				_this.onTouchMove(touch);
+			}
+			e.preventDefault();
+		}, false);
+	}
+	//Sinon souris.
+	else
+	{
 		//On écoute le déplacement de la souris.
 		$(window).mousemove(function(e)
 		{
+			_this.refreshPointers(e.pageX, e.pageY, true);
+			_this.mousePosX = e.pageX;
+			_this.mousePosY = e.pageY;
 			_this.onMouseMove(e);
 			return false;
 		});
-		
+	}
+	
+	//Si on est sur tablette, on utilise l'événement touch start.
+	if(this.isTablet)
+	{
+		document.addEventListener('touchend', function(e)
+		{
+			_this.onTouchEnd(e);
+			e.preventDefault();
+		}, false);
+	}
+	//Sinon souris.
+	else
+	{
 		//Si on fait un mouse up après ce mouse down.
 		$(window).mouseup(function()
 		{
 			_this.onMouseUp();
 			return false;
 		});
-		
+	}
+	
+	if(!this.isTablet)
+	{
 		//Si on fait un clic.
 		$(window).click(function(e)
 		{
@@ -797,20 +556,20 @@
 		});
 		
 		$(window).on('mousewheel', function(event, delta, deltaX, deltaY)
-        {
+		{
 			//Si on est dans un mode autre qu'on mode zoomé ou que l'aide est affichée, on part.
 			if(_this.currentMode != "VIDEO" && _this.currentMode != "SEARCH" && _this.currentMode != "TIMELINE" || _this.helpDisplayed)
 			{
 				return;
 			}
 			
-            //Quand on "tire" la molette vers soi, on dezoom.
-            if (delta < 0)
-            {
-                _this.unzoom();
-            }
-        });
-    }
+			//Quand on "tire" la molette vers soi, on dezoom.
+			if (delta < 0)
+			{
+				_this.unzoom();
+			}
+		});
+	}
 }
 
 /*
@@ -823,7 +582,7 @@
     var _this = this;
     
     //Variables censées être des ints.
-    var supposedToBeInt = ['imagesByLine', 'imagesToShow', 'totalImages', 'timeReloadAfterResize', 'timePrezoom', 'timePreUnzoom', 'zoomTime', 'timeUnzoom', 'timeNeighbourGlowing', 'timeNeighbourUnglowing', 'timeMovingToNeighbour', 'timeSearchFade', 'timeNotifyFade', 'timeFilterFade', 'timeANFade', 'timeFilling', 'zoomedMargin', 'timeoutZoom', 'timeoutUnzoom', 'timeoutMoveToNeighbour', 'timeoutPointersIdle', 'timeoutAreBothPointersHere', 'timeoutRemoveNotificationByGesture', 'timeoutNotifySwipe', 'timeoutSelectTL', 'timeoutSlideTL', 'timeoutCanNotifyHelp', 'timeoutRemoveSpinner', 'timeoutNouser', 'timeoutNextDrawCurve', 'mouseUpDownDeltaTreshold', 'kinectUpDownDeltaTreshold', 'helpBorderSize'];
+    var supposedToBeInt = ['imagesByLine', 'imagesToShow', 'totalImages', 'timeReloadAfterResize', 'timePrezoom', 'timePreUnzoom', 'zoomTime', 'timeUnzoom', 'timeNeighbourGlowing', 'timeNeighbourUnglowing', 'timeMovingToNeighbour', 'timeSearchFade', 'timeNotifyFade', 'timeFilterFade', 'timeANFade', 'timeFilling', 'zoomedMargin', 'timeoutZoom', 'timeoutUnzoom', 'timeoutMoveToNeighbour', 'timeoutPointersIdle', 'timeoutAreBothPointersHere', 'timeoutRemoveNotificationByGesture', 'timeoutNotifySwipe', 'timeoutSelectTL', 'timeoutSlideTL', 'timeoutCanNotifyHelp', 'timeoutRemoveSpinner', 'timeoutNouser', 'timeoutNextDrawCurve', 'touchUpDownDeltaTreshold', 'mouseUpDownDeltaTreshold', 'kinectUpDownDeltaTreshold', 'helpBorderSize'];
     //Variables censées êtres des floats.
     var supposedToBeFloat = ['zoomPercentage', 'prezoomPercentage'];
     
@@ -1222,6 +981,12 @@
 {
 	var _this = this;
 	
+	//Si on est sur une tablette, on affiche les controls.
+	if(this.isTablet)
+	{
+		$('video').attr('controls', 'controls');
+	}
+	
 	if(this.currentMode == 'NO-USER')
 	{
 		//On peut s'approcher de la kinect.
@@ -1362,6 +1127,7 @@
         },
         player:{
             type: 'html5', // player type
+            // type: 'jwplayer', // player type
             video: videoToPlay,
             live: true,
             height: newSnHeight,
@@ -1376,7 +1142,8 @@
         position: 'absolute',
         'background-color': '#000000',
         top: newZoomTop,
-        left: newZoomLeft
+        left: newZoomLeft,
+		'z-index': 500
     });
     
     //On démarre le player.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/mosaic/js/mouseInteractions.js	Wed Aug 08 18:40:40 2012 +0200
@@ -0,0 +1,325 @@
+/*
+* This file is part of the TraKERS\Front IDILL package.
+*
+* (c) IRI <http://www.iri.centrepompidou.fr/>
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+/*
+ * Projet : TraKERS
+ * Module : Front IDILL
+ * Fichier : mouseInteractions.js
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Définit les fonctions d'intéraction souris.
+ */
+
+/*
+ * Fonction appelée lors d'un mouse down en mode d'interaction souris.
+ * Est appelé dans le fichier :
+ * mosaic > fonction loadMosaic, attachée à l'événement jQuery mousedown.
+*/
+Mosaic.prototype.onMouseDown = function(e)
+{
+	this.isMouseDown = true;
+	
+	//Si on se trouve sur l'icone d'aide et qu'elle est zoomée.
+	if(this.isHelpIconZoomed)
+	{
+		//On affiche différentes aides en fonction de si on se trouve dans une vidéo ou non.
+		if(this.currentMode == 'SEARCH' || this.currentMode == 'VIDEO' || this.currentMode == 'TIMELINE')
+		{
+			this.notifyHelp(false);
+		}
+		else if(this.currentMode == 'FILTER' || this.currentMode == 'MOSAIC')
+		{
+			this.notifyHelp(true);
+		}
+	}
+	
+	//On met à jour les coordonnées de la souris au dernier mouse down.
+	this.mouseDownPosX = e.pageX;
+	this.mouseDownPosY = e.pageY;
+	
+	//Si on est sur une notification de gesture de recherche.
+	this.removeSearchNotificationIfOnIt(e.pageX, e.pageY);
+	this.isUserInSearchZone = true;
+	
+	//Si on est en mode de tracé de courbes, on indique qu'on a commencé à tracer au canvas.
+	if(this.isSearchByCurvesOn)
+	{
+		this.searchCanvas.onPointerIn(this.mousePosX, this.mousePosY, null, null);
+	}
+}
+
+/*
+ * Fonction appelée lors d'un mouse move en mode d'interaction souris.
+ * Est appelé dans le fichier :
+ * mosaic > fonction loadMosaic, attachée à l'événement jQuery mousemove.
+*/
+Mosaic.prototype.onMouseMove = function(e)
+{
+	//On vérifie si la souris n'est pas sur l'icone d'aide.
+	if(this.isOnHelpIcon(this.mousePosX, this.mousePosY))
+	{
+		//On agrandit l'icone d'aide.
+		this.showBigHelp();
+	}
+	else
+	{
+		//On la rétrecit sinon.
+		this.showSmallHelp();
+	}
+	
+	//Si on n'a pas appuyé sur la souris avant, on part.
+	if(!this.isMouseDown)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//Si on est en mode de tracé de courbes, on met à jour la courbe.
+	if(this.isSearchByCurvesOn)
+	{
+		this.searchCanvas.onPointerMove(this.mousePosX, this.mousePosY - this.MPTop_margin, null, null);
+	}
+	
+	//On met à jour l'ancienne position de la souris si elle est nulle.
+	if(!this.mousePosLastX && this.mousePosLastX != 0)
+	{
+		this.mousePosLastX = this.mousePosX;
+	}
+	if(!this.mousePosLastY && this.mousePosLastY != 0)
+	{
+		this.mousePosLastY = this.mousePosY;
+	}
+	
+	//Le delta s'accroît si la souris bouge.
+	this.mouseUpDownDelta += Math.floor(Math.sqrt((this.mousePosLastX - e.pageX) * (this.mousePosLastX - e.pageX) + (this.mousePosLastY - e.pageY) * (this.mousePosLastY - e.pageY)));
+	
+	//On met à jour l'ancienne position de la souris.
+	if(this.mousePosLastX != this.mousePosX)
+	{
+		this.mousePosLastX = this.mousePosX;
+	}
+	if(this.mousePosLastY != this.mousePosY)
+	{
+		this.mousePosLastY = this.mousePosY;
+	}
+	
+	//Si la souris a parcouru une trop grande distance, on entre en recherche.
+	if(this.mouseUpDownDelta > this.config.mouseUpDownDeltaTreshold)
+	{
+		//Si on est en mosaique, on entre en filtrage.
+		if(this.currentMode == "MOSAIC")
+		{
+			this.preUnzoom();
+			this.currentMode = "FILTER";
+			this.isMosaicFiltered = true;
+		}
+		//Si on est en mode de filtrage, mais qu'on n'est pas en tracé de courbes.
+		else if(this.currentMode == "FILTER" && !this.isSearchByCurvesOn && this.isUserInSearchZone)
+		{
+			//On lance une nouvelle recherche pas courbes.
+			this.preUnzoom();
+		}
+		//Si on est dans une vidéo, on entre en recherche.
+		else if(this.currentMode == "VIDEO" || this.currentMode == "TIMELINE")
+		{
+			this.currentMode = "SEARCH";
+		}
+		//Si on est en mode recherche dans une vidéo, mais qu'on n'est pas en tracé de courbes.
+		/*else if(this.currentMode == "SEARCH" && !this.isSearchByCurvesOn)
+		{
+			//On lance une nouvelle recherche pas courbes.
+		}*/
+		
+		if(this.currentMode != "NO-USER" && this.currentMode.indexOf("INCOMING") == -1 && !this.isSearchByCurvesOn)
+		{
+			this.isSearchByCurvesOn = true;
+			this.startSearch();
+			this.searchCanvas.onPointerIn(this.mousePosX, this.mousePosY - this.MPTop_margin, null, null);
+		}
+		
+		//S'il n'est pas possible d'afficher l'aide.
+		if(!this.canNotifyHelp)
+		{
+			//On rend son affichage possible après un certain délai.
+			this.canNotifyHelpTimeout = setTimeout(function()
+			{
+				_this.canNotifyHelp = true;
+			}, this.config.timeoutCanNotifyHelp);
+		}
+	}
+}
+
+/*
+ * Fonction appelée lors d'un mouse up en mode d'interaction souris.
+ * Est appelé dans le fichier :
+ * mosaic > fonction loadMosaic, attachée à l'événement jQuery mousemove.
+*/
+Mosaic.prototype.onMouseUp = function()
+{
+	this.isMouseDown = false;
+	
+	//Si on était en train de tracer une courbe.
+	if(this.isSearchByCurvesOn)
+	{
+		//On quitte la zone de recherche.
+		/*this.isUserInSearchZone = false;
+		
+		//On regarde si ce qu'on a tracé correspond à une courbe en particulier.
+		var gesture_match = this.gestureWithSameCode(this.actualCode);
+		this.actualCode = '';
+		
+		//Si oui.
+		if(gesture_match.length > 0)
+		{
+			//Si on est en mode recherche dans une vidéo et que le player est prêt.
+			if(this.currentMode == "SEARCH" && this.playerIsReady)
+			{
+				//On effectue une recherche dans cette vidéo.
+				this.player.widgets[0].searchByGesture(gesture_match);
+				this.isCurrentlyInASearchByGesture = this.player.widgets[0].isCurrentlyInASearchByGesture;
+				
+				//On va au premier marqueur trouvé.
+				if(this.player && this.player.widgets[0] && this.timeToGoAt[this.centerId] === 0 && this.player.widgets[0].atLeastOneSearchMarker(this.currentSearchGesture[this.centerId]))
+				{
+					this.player.widgets[0].goToFirstSearchedMarker(this.currentSearchGesture[this.centerId]);
+				}
+				
+				//On affiche la notification de gesture de recherche.
+				this.removeNotifications();
+				this.currentSearchGesture[this.centerId] = gesture_match;
+				this.searchGesture(gesture_match, 'valid');
+				this.curvesGesturesFound = false;
+			}
+			//Si on est en mode de filtrage de mosaique.
+			else if(this.currentMode == "FILTER")
+			{
+				if(this.isMosaicFiltered)
+				{
+					//On notifie la recherche par filtrage.
+					this.removeNotifications();
+					this.filterSearchedType = gesture_match;
+					this.filterGesture(gesture_match, 'valid');
+					//On filtre la mosaique.
+					this.searchFilter(gesture_match);
+					this.curvesGesturesFound = false;
+				}
+			}
+		}
+		//Si aucune gesture ne matche dans le dictionnaire.
+		else
+		{
+			//Si on était en mode filtrage de la mosaïque et qu'aucune gesture de filtrage n'avait été détectée avant ca, on revient en mode mosaïque.
+			if(this.currentMode == "FILTER" && this.filterSearchedType == "")
+			{
+				this.currentMode = "MOSAIC";
+				this.isMosaicFiltered = false;
+			}
+			//Sinon si on était en mode recherche dans une video et qu'aucune gesture n'avait été détectée avant ca, on revient en mode video.
+			if(this.currentMode == "SEARCH" && this.currentSearchGesture[this.centerId] == "")
+			{
+				this.currentMode = "VIDEO";
+			}
+		}*/
+		//On dit au module de recherche qu'on arrête de tracer des courbes.
+		this.searchCanvas.onPointerOut();
+	}
+	
+	this.mousePosLastX = null;
+	this.mousePosLastY = null;
+	
+	//Si la distance parcourue par la souris entre le mouse down et le mouse up est inférieure ou égale au seuil.
+	if(this.mouseUpDownDelta <= this.config.mouseUpDownDeltaTreshold)
+	{
+		//Si on est sur un snapshot prézoomé.
+		if(this.isOnAPrezoomSN && this.previousZoomedSN != '' && (this.currentMode == 'MOSAIC' || this.currentMode == 'FILTER') && !this.isPrezooming)
+		{
+			this.zoom();
+		}
+	}
+	
+	//On réinitialise le delta, on quitte la recherche par courbes.
+	this.mouseUpDownDelta = 0;
+	this.isSearchByCurvesOn = false;
+	this.leaveSearch();
+	
+	//Si on est en mode de filtrage et qu'on a une gesture de filtrage trouvée.
+	if(this.currentMode == 'FILTER' && this.filterSearchedType != '')
+	{
+		//On notifie.
+		this.removeNotifications();
+		this.filterGesture(this.filterSearchedType, 'valid');
+	}
+}
+
+/*
+ * Fonction appelée lors d'un clic en mode d'interaction souris.
+ * Est appelé dans le fichier :
+ * mosaic > fonction loadMosaic.
+*/
+Mosaic.prototype.onClick = function(x, y)
+{
+	//Si la position de la souris entre le mouse down et le mouse up change de plus de 10px, on part.
+	if(!this.mouseDownPosX || !this.mouseDownPosY || Math.sqrt((this.mouseDownPosX - x) * (this.mouseDownPosX - x) + (this.mouseDownPosY - y) * (this.mouseDownPosY - y)) > 10)
+	{
+		return;
+	}
+	
+	//Si on est dans un mode autre qu'un mode zoomé et qu'on n'affiche pas l'aide, on part.
+	if(this.currentMode != "VIDEO" && this.currentMode != "SEARCH" && this.currentMode != "TIMELINE" && !this.helpDisplayed)
+	{
+		return;
+	}
+	
+	//Si on clique en dehors de la video centrale, alors on dézoome.
+	var TL = $('.Ldt-Timeline');
+	var TLwidth = TL.width(), TLheight = TL.height();
+	var Ptop = $('.LdtPlayer').position().top, Pleft = $('.LdtPlayer').position().left;
+	var Pheight = $('.LdtPlayer').height();
+	var MPx = this.mousePosX, MPy = this.mousePosY;
+	
+	//On regarde si on a cliqué sur un snapshot.
+	var SN = this.pointerPositionToSN(MPx - this.notifyLeftVideo, MPy - this.notifyTopVideo, true);
+	var SNId;
+	if(SN)
+	{
+		SNId = parseInt(SN.attr('id').replace('snapshotDiv-', ''));
+	}
+	
+	//Si on n'a pas demandé à supprimé la notification de gesture.
+	if(!this.gestureDelRequested && !this.helpDisplayed)
+	{
+		//Si non, ou s'il ne fait pas partie des voisins.
+		if(!SNId || !_.include(this.neighboursIds, SNId))
+		{
+			//Si le clic a lieu en dehors du player et que l'aide n'est pas affichée, on dezoom.
+			if(MPx < Pleft || MPx > (+Pleft + TLwidth) || MPy < Ptop || MPy > (+Ptop + Pheight - TLheight))
+			{
+				this.unzoom();
+			}
+		}
+		//Si on se trouve sur un voisin, on bouge.
+		else if(SNId && _.include(this.neighboursIds, SNId) && this.canMoveToNeighbour)
+		{
+			this.moveToNeighbour($('#snapshotDiv-' + SNId));
+		}
+	}
+	//Si on l'a demandé, on enlève la demande de suppression.
+	else
+	{
+		this.gestureDelRequested = false;
+	}
+	
+	//Si l'aide est affichée, un clic la ferme.
+	if(this.helpDisplayed && !this.isHelpIconZoomed && !this.isHelpIconZooming)
+	{
+		this.removeHelp();
+	}
+}
\ No newline at end of file
--- a/front_idill/src/mosaic/js/neighbours.js	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/mosaic/js/neighbours.js	Wed Aug 08 18:40:40 2012 +0200
@@ -73,7 +73,7 @@
     
     //Si on est sur une bordure.
     //On crée des voisins supplémentaires.
-    if(_.include(this.neighboursIds, -1))
+    if(_.include(this.neighboursIds, -1) && !this.isTablet)
     {
         this.createAdditionalNeighbours();
     }
@@ -394,9 +394,12 @@
 {
     var _this = this;
     
+	var id = parseInt(id);
+	
     if(this.neighboursIds != null && this.neighboursIds.length > 0 && this.canMoveToNeighbour)
     {
-        var idx = $.inArray(id, this.neighboursIds);
+        var idx = this.neighboursIds.indexOf(id);
+		
         //Si l'id du snapshot qu'on vient de quitter fait partie des voisins.
         if(idx > -1)
         {
@@ -409,7 +412,6 @@
             //On cherche le symétrique de l'id du voisin quitté.
             //Astuce : S'il est pair, cela signifie qu'on doit faire +1, sinon c'est -1.
             //var sym = (idx % 2 == 0) ? (+idx + 1) : (idx - 1);
-            
             //S'il est > -1 alors forcément il existe.
             //Si on peut se déplacer vers un voisin, on le fait.
             if(this.neighboursIds[idx] > -1)
@@ -419,10 +421,20 @@
                 //Si l'id du tableau est pair, alors forcément le pointeur doit être plus à droite/plus en bas que le milieu de l'écran pour se déplacer vers le voisin.
                 //Sinon c'est l'inverse.
                 //(sym et idx on été échangés).
-                if(idx == 0 && x > centerWidth || idx == 2 && y > centerHeight || idx == 1 && x < centerWidth || idx == 3 && y < centerHeight)
-                {
-                    this.moveToNeighbour($('#snapshotDiv-' + this.neighboursIds[idx]));
-                }
+				if(this.isTablet)
+				{
+					if(idx > -1 && idx < 4)
+					{
+						this.moveToNeighbour($('#snapshotDiv-' + this.neighboursIds[idx]));
+					}
+				}
+				else
+				{
+					if(idx == 0 && x > centerWidth || idx == 2 && y > centerHeight || idx == 1 && x < centerWidth || idx == 3 && y < centerHeight)
+					{
+						this.moveToNeighbour($('#snapshotDiv-' + this.neighboursIds[idx]));
+					}
+				}
             }
         }
         else if(id >= this.config.imagesToShow)
@@ -443,7 +455,7 @@
     var _this = this;
     
     //Si on ne peut pas se déplacer vers les voisins, on quitte.
-    if((!this.canMoveToNeighbour || neighbour.length <= 0 || this.currentlyMoving) && !this.autoMove)
+    if((!this.canMoveToNeighbour || neighbour.length <= 0 || this.currentlyMoving || this.currentlyUnzooming) && !this.autoMove)
     {
         return;
     }
@@ -514,7 +526,7 @@
         _this.player.widgets[0].freePlayer();
         _this.playerIsReady = false;
         $('.LdtPlayer').remove();
-        $('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
+        
     }
     
     //On obtient l'ID du div de coloration du snapshot vers lequel on se déplace afin de le supprimer.
@@ -532,6 +544,7 @@
         left: MPCurrentLeft
     }, _this.config.timeMovingToNeighbour, function()
     {
+		$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
         //On passe en mode recherche et on recherche dans la vidéo en fonction de la gesture de recherche enregistrée dans la nouvelle vidéo.
         if(_this.currentSearchGesture[_this.centerId] != '')
         {
--- a/front_idill/src/mosaic/js/notifications.js	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/mosaic/js/notifications.js	Wed Aug 08 18:40:40 2012 +0200
@@ -130,6 +130,9 @@
             search_body_imgs += "<div id='body_" + search_body_tab[i] + "' class='notify_imgs_small' style='opacity: " + search_body_tab_opacities[i] + ";'></div>";
         }
         search_body_imgs += "</div>";
+		
+		//On ajoute ce qu'il faut pour quitter l'aide.
+		
     }
     
     //Titre de la colonne des actions de contrôle.
@@ -172,9 +175,29 @@
     //On les ajoute à la mosaïque.
     $('body').append(notification_help);
     
+	if(this.isTablet)
+	{
+		//On rétrécit certaines images si on est sur une tablette.
+		$('#search_img, #controls_img').css(
+		{
+			height: 150,
+			'background-size': '150px 150px'
+		});
+		
+		$('.notify_imgs_small').css(
+		{
+			height: 80,
+			width: 80,
+			'background-size': '80px 80px'
+		});
+		
+		//On ajoute l'icone de sortie.
+		this.exitIcon();
+	}
+	
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $(window).width(), notify_height = $(window).height();
-    var notify_margin = parseInt($('#notify_help').css('margin'));
+    var notify_margin = parseInt($('#notify_help').css('margin-left'));
     var notify_ = 10;
     
     //On les positionne.
@@ -188,7 +211,7 @@
     });
     
     //Taille des marges des images.
-    var margins = parseInt($('.notify_imgs_small').css('margin'));
+    var margins = parseInt($('.notify_imgs_small').css('margin-left'));
     //Largeur des images.
     var widths = $('.notify_imgs_small').width();
     //Hauteur des images.
@@ -196,7 +219,7 @@
     //Position horizontale du séparateur de colonnes.
     var sep_left = $('#help_sep').position().left;
     //Marge du panneau d'aide.
-    var help_margin = parseInt($('#notify_help').css('margin'));
+    var help_margin = parseInt($('#notify_help').css('margin-left'));
     
     //On calcule la taille d'une zone de recherche (une des deux parties).
     var help_column_width = sep_left - help_margin;
@@ -212,7 +235,7 @@
     $('#search_2hands_imgs').css(
     {
         'padding-left': search_2hands_padding_left,
-        'height': ($('.notify_imgs_small').height() * 2 + parseInt($('.notify_imgs_small').css('margin')))
+        'height': ($('.notify_imgs_small').height() * 2 + parseInt($('.notify_imgs_small').css('margin-left')))
     });
     
     //On récupère le nombre d'images affichables horizontalement pour les gestures de recherche corporelles dans une des parties de l'aide.
@@ -224,7 +247,7 @@
     $('#search_body_imgs').css(
     {
         'padding-left': search_body_padding_left,
-        'height': ($('.notify_imgs_small').height() * 2 + parseInt($('.notify_imgs_small').css('margin')))
+        'height': ($('.notify_imgs_small').height() * 2 + parseInt($('.notify_imgs_small').css('margin-left')))
     });
     
     //On récupère le nombre d'images affichables horizontalement pour les gestures de controle dans une des parties de l'aide.
@@ -353,7 +376,7 @@
 	{
 		//On ajoute à la mosaïque seulement la recherche.
 		$('body').append(notification_search);
-		notify_margin = parseInt($('.notifications').css('margin'));
+		notify_margin = parseInt($('.notifications').css('margin-left'));
 		notify_width = $('.notifications').width();
 		notify_height = $('.notifications').height();
 		//On calcule leurs coordonnées.
@@ -365,7 +388,7 @@
 	{
 		//On les ajoute à la mosaïque.
 		$('body').append(notification_selection + notification_search);
-		notify_margin = parseInt($('.notifications').css('margin'));
+		notify_margin = parseInt($('.notifications').css('margin-left'));
 		notify_width = $('.notifications').width();
 		notify_height = $('.notifications').height();
 		//On calcule leurs coordonnées.
@@ -416,7 +439,7 @@
 
     //On calcule ses coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var selection_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
     
 	if(this.config.mouseInteractions)
@@ -462,7 +485,7 @@
 
     //On calcule ses coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var search_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
     
 	if(this.config.mouseInteractions)
@@ -506,7 +529,7 @@
 	//On les ajoute à la mosaïque.
 	$('body').append(notification_selection + notification_search);
 	
-	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height(), notify_margin = parseInt($('.notifications').css('margin'));
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height(), notify_margin = parseInt($('.notifications').css('margin-left'));
 	
 	//On calcule leurs coordonnées.
 	var selection_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
@@ -566,7 +589,7 @@
     
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
     
     if(_.include(this.gestures, gestureName))
@@ -592,6 +615,11 @@
     {
         opacity: "0.9"
     });
+	
+	if(this.isTablet)
+	{
+		this.searchExitIcon();
+	}
 }
 
 /*
@@ -616,7 +644,7 @@
 
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var search_1gesture_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
     var selection_left = search_1gesture_left + notify_width + notify_margin;
     
@@ -679,7 +707,7 @@
     
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
     
     var notifyTop = 0, notifyLeft = 0;
@@ -731,7 +759,7 @@
     
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var move_left = $(window).width() / 2 - (notify_width) / 2 + notify_margin;
     
     var side = $.inArray(parseInt(targetId), this.neighboursIds);
@@ -786,7 +814,7 @@
     
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var move_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
     var unzoom_left = move_left + notify_width + notify_margin;
     
@@ -850,7 +878,7 @@
     
     //On calcule ses coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var unzoom_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
     
     var side = $.inArray(parseInt(targetId), this.neighboursIds);
@@ -903,7 +931,7 @@
     
     //On calcule ses coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var timeline_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
     
     var notifyTop = 0, notifyLeft = 0;
@@ -949,7 +977,7 @@
     
     //On calcule ses coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var search_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
     
     var notifyTop = 0, notifyLeft = 0;
@@ -994,7 +1022,7 @@
     
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var search_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
     var swipe_left = search_left + notify_width + notify_margin;
     
@@ -1052,7 +1080,7 @@
     
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var search_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
     var move_left = search_left + notify_width + notify_margin;
     
@@ -1113,7 +1141,7 @@
     
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var search_left = $(window).width() / 2 - (notify_width * 3 + notify_margin * 4) / 2;
     var move_left = search_left + notify_width + notify_margin;
     var unzoom_left = move_left + notify_width + notify_margin;
@@ -1183,7 +1211,7 @@
     
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var search_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
     var unzoom_left = search_left + notify_width + notify_margin;
     
@@ -1246,10 +1274,10 @@
     
     //On les ajoute à la mosaïque.
     $('body').append(notification_search_1gesture);
-    
+	
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
     
     if(_.include(this.gestures, gestureName))
@@ -1275,6 +1303,11 @@
     {
         opacity: "0.9"
     });
+	
+	if(this.isTablet)
+	{
+		this.searchExitIcon();
+	}
 }
 
 /*
@@ -1298,10 +1331,10 @@
     
     //On les ajoute à la mosaïque.
     $('body').append(notification_search_1gesture + notification_swipe);
-    
+	
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var search_1gesture_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
     var swipe_left = search_1gesture_left + notify_width + notify_margin;
     
@@ -1364,10 +1397,10 @@
     
     //On les ajoute à la mosaïque.
     $('body').append(notification_search_1gesture + notification_move);
-    
+	
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var search_1gesture_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
     var move_left = search_1gesture_left + notify_width + notify_margin;
     
@@ -1408,6 +1441,11 @@
     {
         opacity: "0.9"
     });
+	
+	if(this.isTablet)
+	{
+		this.searchExitIcon();
+	}
 }
 
 /*
@@ -1435,7 +1473,7 @@
     
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var search_1gesture_left = $(window).width() / 2 - (notify_width * 3 + notify_margin * 4) / 2;
     var move_left = search_1gesture_left + notify_width + notify_margin;
     var unzoom_left = move_left + notify_width + notify_margin;
@@ -1484,6 +1522,11 @@
     {
         opacity: "0.9"
     });
+	
+	if(this.isTablet)
+	{
+		this.searchExitIcon();
+	}
 }
 
 /*
@@ -1509,7 +1552,7 @@
     
     //On calcule leurs coordonnées et dimensions.
     var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
+    var notify_margin = parseInt($('.notifications').css('margin-left'));
     var search_1gesture_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
     var unzoom_left = search_1gesture_left + notify_width + notify_margin;
     
@@ -1568,7 +1611,7 @@
         
         //On calcule leurs dimensions et coordonnées.
         var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-        var notify_margin = parseInt($('.notifications').css('margin'));
+        var notify_margin = parseInt($('.notifications').css('margin-left'));
         var curves_left = $(window).width() / 2 - (notify_width + notify_margin * 2) / 2;
         
         $('#notify_curves').css(
@@ -1586,24 +1629,40 @@
     //Sinon, on les met dans un tableau.
     var gestures_tab = gestures.split(';');
     
-    var notifications_curves_gestures = '';
+    var notifications_curves_gestures = "<div id='notify_curves_container'>";
     
     //On crée autant de notifications qu'il y a de gestures.
     for(var i = 0 ; i < gestures_tab.length ; i++)
     {
-        notifications_curves_gestures += "<div class='notifications' id='notify_curves_" + gestures_tab[i] + "'></div>";
+        notifications_curves_gestures += "<div class='notification_curves' id='notify_curves_" + gestures_tab[i] + "'></div>";
     }
+	
+	notifications_curves_gestures += "</div>";
     
     //On les ajoute à la mosaïque.
     $('body').append(notifications_curves_gestures);
     
     //On calcule leurs dimensions.
-    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-    var notify_margin = parseInt($('.notifications').css('margin'));
-    var curves_gestures_left = [];
+    var notify_width = $('.notification_curves').width(), notify_height = $('.notification_curves').height();
+    var notify_margin = parseInt($('.notification_curves').css('margin-left'));
+	
+	//Nombre de notifications dans une ligne.
+	var notify_in_a_row = Math.floor($(window).width() / (+notify_width + 2 * notify_margin));
+	//Espace libre restant sur la ligne.
+	var free_space = $(window).width() - notify_in_a_row * (+notify_width + 2 * notify_margin);
+	
+	//On met à jour le container.
+	$('#notify_curves_container').css(
+	{
+		height: Math.ceil(gestures_tab.length * (+notify_width + 2 * notify_margin) / $(window).width()),
+		'margin-left': free_space / 2,
+		'margin-right': free_space / 2
+	});
+	
+    // var curves_gestures_left = [];
     
     //On calcule leurs dimensions et leur backgrounds.
-    curves_gestures_left[0] = $(window).width() / 2 - (notify_width * (gestures_tab.length) + notify_margin * (gestures_tab.length + 2)) / 2;
+    // curves_gestures_left[0] = $(window).width() / 2 - (notify_width * (gestures_tab.length) + notify_margin * (gestures_tab.length + 2)) / 2;
     
     for(var i = 0 ; i < gestures_tab.length ; i++)
     {
@@ -1613,16 +1672,16 @@
         //On calcule leurs coordonnées.
         if(i+1 < gestures_tab.length)
         {
-            curves_gestures_left[i+1] = curves_gestures_left[i] + notify_width + notify_margin * 2;
+            // curves_gestures_left[i+1] = curves_gestures_left[i] + notify_width + notify_margin * 2;
         }
         
         //On les place.
-        $('#notify_curves_' + gestures_tab[i]).css('left', curves_gestures_left[i]);
+        // $('#notify_curves_' + gestures_tab[i]).css('left', curves_gestures_left[i]);
 		this.putText($('#notify_curves_' + gestures_tab[i]), this.notificationStrings[gestures_tab[i]]);
     }
     
     //On les fait apparaître.
-    $('.notifications').css(
+    $('.notification_curves').css(
     {
         opacity: "0.9"
     });
@@ -1643,6 +1702,8 @@
 Mosaic.prototype.removeNotifications = function()
 {
     $('.notifications').remove();
+    $('#notify_curves_container').remove();
+    $('.notification_curves').remove();
 }
 
 /*
@@ -1671,7 +1732,7 @@
 	$('#helpIcon').css(
 	{
 		top: 0,
-		left: $(window).width() - $('#helpIcon').width() - 2 * parseInt($('#helpIcon').css('margin'))
+		left: $(window).width() - $('#helpIcon').width() - 2 * parseInt($('#helpIcon').css('margin-left'))
 	});
 }
 
@@ -1709,7 +1770,7 @@
 	{
 		width: 100,
 		height: 100,
-		left: $(window).width() - 100 - 2 * parseInt($('#helpIcon').css('margin'))
+		left: $(window).width() - 100 - 2 * parseInt($('#helpIcon').css('margin-left'))
 	}, this.config.timeShowBigHelp, function()
 	{
 		_this.isHelpIconZoomed = true;
@@ -1740,10 +1801,97 @@
 	{
 		width: 50,
 		height: 50,
-		left: $(window).width() - 50 - 2 * parseInt($('#helpIcon').css('margin'))
+		left: $(window).width() - 50 - 2 * parseInt($('#helpIcon').css('margin-left'))
 	}, this.config.timeShowBigHelp, function()
 	{
 		_this.isHelpIconZoomed = false;
 		_this.isHelpIconZooming = false;
 	});
+}
+
+/*
+ * Affiche l'icone de sortie pour tablettes.
+*/
+Mosaic.prototype.exitIcon = function()
+{
+	this.removeExitIcon();
+	//On construit le div.
+	var exitIcon = "<img id='exitIcon' src='./img/exitIcon.png' />";
+	//On l'ajoute.
+	$('body').append(exitIcon);
+	//On spécifie ses coordonnées.
+	$('#exitIcon').css(
+	{
+		top: 0,
+		left: $(window).width() - $('#exitIcon').width() - 2 * parseInt($('#exitIcon').css('margin-left')),
+		'z-index': 1000
+	});
+}
+
+/*
+ * Supprime l'icone de sortie pour tablettes.
+*/
+Mosaic.prototype.removeExitIcon = function()
+{
+	$('#exitIcon').remove();
+}
+
+/*
+ * Affiche l'icone de retour à la mosaïque pour tablettes.
+*/
+Mosaic.prototype.homeIcon = function()
+{
+	this.removeHomeIcon();
+	//On construit le div.
+	var homeIcon = "<img id='homeIcon' src='./img/homeIcon.png' />";
+	//On l'ajoute.
+	$('body').append(homeIcon);
+	//On spécifie ses coordonnées.
+	$('#homeIcon').css(
+	{
+		top: 0,
+		left: 0,
+		'z-index': 900
+	});
+}
+
+/*
+ * Supprime l'icone de sortie pour tablettes.
+*/
+Mosaic.prototype.removeHomeIcon = function()
+{
+	$('#homeIcon').remove();
+}
+
+/*
+ * Affiche l'icone de sortie de recherche pour tablettes.
+*/
+Mosaic.prototype.searchExitIcon = function()
+{
+	//S'il n'y a pas de notification de recherche, on s'en va.
+	if($('#notify_search_1gesture').length == 0)
+	{
+		return;
+	}
+	
+	this.removeSearchExitIcon();
+	//On construit le div.
+	var searchExitIcon = "<img id='searchExitIcon' src='./img/exitIcon.png' />";
+	//On l'ajoute.
+	$('body').append(searchExitIcon);
+	//On spécifie ses coordonnées.
+	$('#searchExitIcon').css(
+	{
+		top: 0,
+		left: +$('#notify_search_1gesture').position().left + $('#notify_search_1gesture').width() - $('#searchExitIcon').width() - parseInt($('#searchExitIcon').css('margin-left')) / 2,
+		'z-index': 900
+	});
+}
+
+/*
+ * Supprime l'icone de sortie de recherche pour tablettes.
+*/
+Mosaic.prototype.removeSearchExitIcon = function()
+{
+	$('#searchExitIcon').remove();
 }
\ No newline at end of file
--- a/front_idill/src/mosaic/js/pointers.js	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/mosaic/js/pointers.js	Wed Aug 08 18:40:40 2012 +0200
@@ -805,7 +805,7 @@
         //Si le pointeur est sur la notification.
         if(x > notification_search.position().left && x < (+notification_search.position().left + notification_search.width()) && y > notification_search.position().top && y < (+notification_search.position().top + notification_search.height()))
         {
-            if(!this.alreadyOnNotification && ($('#spinner').length == 0 && !this.config.mouseInteractions || this.config.mouseInteractions))
+            if(!this.alreadyOnNotification && ($('#spinner').length == 0 && !this.config.mouseInteractions || this.config.mouseInteractions) && !this.isTablet)
             {
                 notification_search.css('background-image', currentPicto.replace('/big/' + (this.config.mouseInteractions ? 'MI/' : '') + 'valid/', '/big/' + (this.config.mouseInteractions ? 'MI/' : '') + 'hover/'));
                 
@@ -971,7 +971,91 @@
 	}
 	
 	//Si la souris est sur l'icone, on retourne true.
-	if(x > helpIcon.position().left && x < +helpIcon.position().left + helpIcon.width() && y > helpIcon.position().top && y < +helpIcon.position().top + helpIcon.height() + 2 * parseInt(helpIcon.css('margin')))
+	if(x > helpIcon.position().left && x < +helpIcon.position().left + helpIcon.width() + 2 * parseInt(helpIcon.css('margin-left')) && y > helpIcon.position().top && y < +helpIcon.position().top + helpIcon.height() + 2 * parseInt(helpIcon.css('margin-left')))
+	{
+		return true;
+	}
+	
+	return false;
+}
+
+/*
+ * Retourne vrai si le doigt est sur la notification de sortie dans le mode d'interaction tablettes.
+*/
+Mosaic.prototype.isOnExitIcon = function(x, y)
+{
+	var exitIcon = $('#exitIcon');
+	//S'il n'y a pas d'icone d'aide, on quitte.
+	if(exitIcon.length <= 0)
+	{
+		return;
+	}
+	
+	//Si la souris est sur l'icone, on retourne true.
+	if(x > exitIcon.position().left && x < +exitIcon.position().left + exitIcon.width() + 2 * parseInt(exitIcon.css('margin-left')) && y > exitIcon.position().top && y < +exitIcon.position().top + exitIcon.height() + 2 * parseInt(exitIcon.css('margin-left')))
+	{
+		return true;
+	}
+	
+	return false;
+}
+
+/*
+ * Retourne vrai si le doigt est sur la notification de retour vers la mosaïque dans le mode d'interaction tablettes.
+*/
+Mosaic.prototype.isOnHomeIcon = function(x, y)
+{
+	var homeIcon = $('#homeIcon');
+	//S'il n'y a pas d'icone d'aide, on quitte.
+	if(homeIcon.length <= 0)
+	{
+		return;
+	}
+	
+	//Si la souris est sur l'icone, on retourne true.
+	if(x > homeIcon.position().left && x < +homeIcon.position().left + homeIcon.width() + 2 * parseInt(homeIcon.css('margin-left')) && y > homeIcon.position().top && y < +homeIcon.position().top + homeIcon.height() + 2 * parseInt(homeIcon.css('margin-left')))
+	{
+		return true;
+	}
+	
+	return false;
+}
+
+/*
+ * Retourne vrai si le doigt est sur la notification de sortie de recherche dans le mode d'interaction tablettes.
+*/
+Mosaic.prototype.isOnSearchExitIcon = function(x, y)
+{
+	var searchExitIcon = $('#searchExitIcon');
+	//S'il n'y a pas d'icone d'aide, on quitte.
+	if(searchExitIcon.length <= 0)
+	{
+		return;
+	}
+	
+	//Si la souris est sur l'icone, on retourne true.
+	if(x > searchExitIcon.position().left && x < +searchExitIcon.position().left + searchExitIcon.width() + 2 * parseInt(searchExitIcon.css('margin-left')) && y > searchExitIcon.position().top && y < +searchExitIcon.position().top + searchExitIcon.height() + 2 * parseInt(searchExitIcon.css('margin-left')))
+	{
+		return true;
+	}
+	
+	return false;
+}
+
+/*
+ * Retourne vrai si le doigt est sur la notification de recherche dans le mode d'interaction tablettes.
+*/
+Mosaic.prototype.isOnSearchNotification = function(x, y)
+{
+	var searchNotification = $('#notify_search_1gesture');
+	//S'il n'y a pas d'icone d'aide, on quitte.
+	if(searchNotification.length <= 0)
+	{
+		return;
+	}
+	
+	//Si la souris est sur l'icone, on retourne true.
+	if(x > searchNotification.position().left && x < +searchNotification.position().left + searchNotification.width() + 2 * parseInt(searchNotification.css('margin-left')) && y > searchNotification.position().top && y < +searchNotification.position().top + searchNotification.height() + 2 * parseInt(searchNotification.css('margin-left')))
 	{
 		return true;
 	}
--- a/front_idill/src/mosaic/js/search.js	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/mosaic/js/search.js	Wed Aug 08 18:40:40 2012 +0200
@@ -198,7 +198,7 @@
                 }
             }
             
-            var snMargin = parseInt($('.snapshotDivs').css('margin'));
+            var snMargin = parseInt($('.snapshotDivs').css('margin-left'));
             
             //On affiche l'opacité résultante pour chaque vidéo.
             for(var i = 0 ; i < this.config['imagesToShow'] ; i++)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/mosaic/js/touchInteractions.js	Wed Aug 08 18:40:40 2012 +0200
@@ -0,0 +1,316 @@
+/*
+* This file is part of the TraKERS\Front IDILL package.
+*
+* (c) IRI <http://www.iri.centrepompidou.fr/>
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+/*
+ * Projet : TraKERS
+ * Module : Front IDILL
+ * Fichier : touchInteractions.js
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Définit les fonctions d'intéraction pour tablettes.
+ */
+
+/*
+ * Fonction appelée lors d'un touch start en mode d'interaction touch.
+ * Est appelé dans le fichier :
+ * mosaic > fonction loadMosaic, attachée à l'événement ontouchstart.
+*/
+Mosaic.prototype.onTouchStart = function(e)
+{
+	this.isTouchStart = true;
+	this.isTouchMove = false;
+	
+	//Si on est sur l'icone de sortie.
+	if(this.isOnExitIcon(e.pageX, e.pageY) && this.helpDisplayed)
+	{
+		//On ferme l'aide.
+		this.removeExitIcon();
+		this.removeHelp();
+	}
+	
+	//Si on est sur l'icone de retour à la mosaïque.
+	if(this.isOnHomeIcon(e.pageX, e.pageY) && !this.helpDisplayed)
+	{
+		//On dézoom.
+		this.unzoom();
+	}
+	
+	//Si on se trouve sur l'icone d'aide et qu'elle est zoomée.
+	if(this.isOnHelpIcon(e.pageX, e.pageY) && !this.helpDisplayed)
+	{
+		//On affiche différentes aides en fonction de si on se trouve dans une vidéo ou non.
+		if(this.currentMode == 'SEARCH' || this.currentMode == 'VIDEO' || this.currentMode == 'TIMELINE')
+		{
+			this.notifyHelp(false);
+		}
+		else if(this.currentMode == 'FILTER' || this.currentMode == 'MOSAIC')
+		{
+			this.notifyHelp(true);
+		}
+	}
+	
+	//Si on est dans une vidéo.
+	if(this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH')
+	{
+		//On regarde si on a touché un snapshot.
+		var snapshot = this.positionToSN(e.pageX - this.notifyLeftVideo, e.pageY - this.notifyTopVideo);
+		
+		if(snapshot && !this.isOnSearchNotification(e.pageX, e.pageY) && !this.isOnSearchExitIcon(e.pageX, e.pageY))
+		{
+			this.canMoveToNeighbour = true;
+			var id = snapshot.attr('id').replace('snapshotDiv-', '');
+			this.correctMoveToNeighbour(id, e.pageX - this.notifyLeftVideo, e.pageY - this.notifyTopVideo);
+			this.canMoveToNeighbour = false;
+		}
+	}
+	
+	//Si on est sur l'icone de sortie de recherche.
+	if(this.isOnSearchExitIcon(e.pageX, e.pageY) && !this.helpDisplayed)
+	{
+		//On ferme l'aide.
+		this.removeSearchExitIcon();
+		
+		this.removeNotifications();
+		if(this.currentMode == 'SEARCH')
+		{
+			this.player.widgets[0].removeSearchByGesture();
+			this.currentMode = 'VIDEO';
+			this.currentSearchGesture[this.centerId] = '';
+		}
+		else if(this.currentMode == 'TIMELINE')
+		{
+			this.player.widgets[0].removeSearchByGesture();
+			this.currentMode = 'TIMELINE';
+			this.currentSearchGesture[this.centerId] = '';
+		}
+		else if(this.currentMode == 'FILTER')
+		{
+			this.removeFilter();
+		}
+		
+		this.alreadyOnNotification = false;
+		this.isCurrentlyInASearchByGesture = false;
+		this.curvesGesturesFound = false;
+		this.canDrawNextCurve = false;
+		this.isSearchByCurvesOn = false;
+		this.canNotifyHelp = false;
+	}
+	
+	//On met à jour les coordonnées de la souris au dernier mouse down.
+	this.mouseDownPosX = e.pageX;
+	this.mouseDownPosY = e.pageY;
+	this.mousePosX = e.pageX;
+	this.mousePosY = e.pageY;
+	
+	this.isUserInSearchZone = true;
+	
+	//Si on est en mode de tracé de courbes, on indique qu'on a commencé à tracer au canvas.
+	if(this.isSearchByCurvesOn)
+	{
+		this.searchCanvas.onPointerIn(this.mousePosX, this.mousePosY, null, null);
+	}
+}
+
+/*
+ * Fonction appelée lors d'un touch move en mode d'interaction touch.
+ * Est appelé dans le fichier :
+ * mosaic > fonction loadMosaic, attachée à l'événement jQuery ontouchmove.
+*/
+Mosaic.prototype.onTouchMove = function(e)
+{
+	//Si on n'a pas appuyé sur la souris avant, on part.
+	if(!this.isTouchStart)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//Si on est en mode de tracé de courbes, on met à jour la courbe.
+	if(this.isSearchByCurvesOn)
+	{
+		this.searchCanvas.onPointerMove(this.mousePosX, this.mousePosY - this.MPTop_margin, null, null);
+	}
+	
+	//On met à jour l'ancienne position du doigt si elle est nulle.
+	if(!this.mousePosLastX && this.mousePosLastX != 0)
+	{
+		this.mousePosLastX = this.mousePosX;
+	}
+	if(!this.mousePosLastY && this.mousePosLastY != 0)
+	{
+		this.mousePosLastY = this.mousePosY;
+	}
+	
+	//Le delta s'accroît si le doigt bouge.
+	this.touchUpDownDelta += Math.floor(Math.sqrt((this.mousePosLastX - e.pageX) * (this.mousePosLastX - e.pageX) + (this.mousePosLastY - e.pageY) * (this.mousePosLastY - e.pageY)));
+	
+	//On met à jour l'ancienne position du doigt.
+	if(this.mousePosLastX != this.mousePosX)
+	{
+		this.mousePosLastX = this.mousePosX;
+	}
+	if(this.mousePosLastY != this.mousePosY)
+	{
+		this.mousePosLastY = this.mousePosY;
+	}
+	
+	//Si le doigt a parcouru une trop grande distance, on entre en recherche.
+	if(this.touchUpDownDelta > this.config.touchUpDownDeltaTreshold)
+	{
+		this.isTouchMove = true;
+		//Si on est en mosaique, on entre en filtrage.
+		if(this.currentMode == "MOSAIC")
+		{
+			this.currentMode = "FILTER";
+			this.isMosaicFiltered = true;
+		}
+		//Si on est dans une vidéo, on entre en recherche.
+		else if(this.currentMode == "VIDEO" || this.currentMode == "TIMELINE")
+		{
+			this.currentMode = "SEARCH";
+		}
+		
+		if(!this.isSearchByCurvesOn)
+		{
+			this.isSearchByCurvesOn = true;
+			this.startSearch();
+			this.searchCanvas.onPointerIn(this.mousePosX, this.mousePosY - this.MPTop_margin, null, null);
+		}
+	}
+}
+
+/*
+ * Fonction appelée lors d'un touch end en mode d'interaction touch.
+ * Est appelé dans le fichier :
+ * mosaic > fonction loadMosaic, attachée à l'événement jQuery ontouchend.
+*/
+Mosaic.prototype.onTouchEnd = function(e)
+{
+	// alert(this.mousePosX + ' ' + this.mousePosY);
+	//Si on est dans la mosaïque.
+	if(this.currentMode == 'MOSAIC' || this.currentMode == 'FILTER')
+	{
+		//On regarde si on a touché un snapshot.
+		var snapshot = this.positionToSN(this.mousePosX, this.mousePosY);
+		// alert(snapshot);
+		// alert(this.isTouchMove);
+		if(snapshot && !this.isTouchMove)
+		{
+			this.previousZoomedSN = snapshot;
+			this.previousId = snapshot.attr('id');
+			this.zoom();
+		}
+	}
+	//Sinon si on est dans une video.
+	else if(this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH' || this.currentMode == 'TIMELINE')
+	{
+		// console.log(this.isTLSelected(true, null));
+	}
+	
+	this.isTouchStart = false;
+	
+	//Si on était en train de tracer une courbe.
+	if(this.isSearchByCurvesOn)
+	{
+		//On dit au module de recherche qu'on arrête de tracer des courbes.
+		this.searchCanvas.onPointerOut();
+	}
+	
+	this.mousePosLastX = null;
+	this.mousePosLastY = null;
+	
+	//Si la distance parcourue par la souris entre le mouse down et le mouse up est inférieure ou égale au seuil.
+	if(this.touchUpDownDelta <= this.config.touchUpDownDeltaTreshold)
+	{
+		//Si on est sur un snapshot prézoomé.
+		if(this.isOnAPrezoomSN && this.previousZoomedSN != '' && (this.currentMode == 'MOSAIC' || this.currentMode == 'FILTER') && !this.isPrezooming)
+		{
+			this.zoom();
+		}
+	}
+	
+	//On réinitialise le delta, on quitte la recherche par courbes.
+	this.touchUpDownDelta = 0;
+	this.isSearchByCurvesOn = false;
+	this.leaveSearch();
+	
+	//Si on est en mode de filtrage et qu'on a une gesture de filtrage trouvée.
+	if(this.currentMode == 'FILTER' && this.filterSearchedType != '')
+	{
+		//On notifie.
+		this.removeNotifications();
+		this.filterGesture(this.filterSearchedType, 'valid');
+	}
+	this.isTouchMove = false;
+}
+
+/*
+ * Donne éventuellement un snapshot d'après les coordonnées passées en paramètres.
+ * Renvoie null sinon.
+*/
+Mosaic.prototype.positionToSN = function(x, y)
+{
+    if(this.helpDisplayed)
+    {
+        return;
+    }
+    
+    //Taille de la marge des snapshots.
+    var m = parseInt($('.snapshotDivs').css('margin-left'));
+    
+    //Dimensions d'un snapshot de la mosaïque.
+    var W = $('.snapshotDivs').width() + m * 2, H = $('.snapshotDivs').height() + m * 2;
+    
+    //Position supposée du snapshot dans la mosaïque.
+    //Au départ on ne sélectionne rien.
+    var i = -1, j = -1;
+    
+    //Espace de centrage vertical de la mosaïque.
+    var top_margin = parseInt(this.MPTop_margin);
+    //Dimensions de la mosaïque en nombre de snapshots.
+    var mosW = this.config.imagesByLine, mosH = this.config.imagesToShow / mosW;
+    
+    //Si le pointeur se trouve au niveau de la mosaïque.
+    if(x < W * mosW && y >= top_margin && y < H * mosH + top_margin)
+    {
+        //Si le pointeur est sur une des bordures.
+        var xb = x % W;
+        var yb = y - top_margin;
+        yb %= H;
+        
+        if(xb < m || xb > W - m || yb < m || yb > H - m)
+        {
+            //On renvoie null.
+            return null;
+        }
+        //Sinon il est forcément sur un des snapshots.
+        else
+        {
+            i = Math.floor(x / W);
+            j = Math.floor((y - top_margin) / H);
+        }
+        
+        //On passe des coordonnées 2D en 1D.
+        var snapshot = $('#snapshotDiv-' + (j * mosW + i));
+        
+        //Si le snapshot a été filtré, on renvoie null si on se trouve dans la mosaïque.
+        if(this.isMosaicFiltered && (this.currentMode == "MOSAIC" || this.currentMode == "FILTER") && snapshot.css('opacity') == 0)
+        {
+            return null;
+        }
+        
+        //On renvoie le snapshot.
+        return snapshot;
+    }
+    
+    //Si on est arrivé là, c'est que le pointeur n'est pas dans la mosaïque.
+    return null;
+}
\ No newline at end of file
--- a/front_idill/src/mosaic/js/zoomInteractions.js	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/mosaic/js/zoomInteractions.js	Wed Aug 08 18:40:40 2012 +0200
@@ -273,7 +273,7 @@
     var _this = this;
     
     //Si la mosaïque est en pleine écran, pas la peine de zoomer.
-    if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH" || this.currentMode.indexOf("INCOMING") > -1 || this.helpDisplayed)
+    if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH" || this.currentMode.indexOf("INCOMING") > -1 || this.helpDisplayed || this.isMosaicFiltering)
     {
         return;
     }
@@ -349,6 +349,12 @@
 			_this.helpIcon();
 		}
 		
+		//Si on est sur une tablette, on affiche l'icone de retour.
+		if(_this.isTablet)
+		{
+			_this.homeIcon();
+		}
+		
         _this.snTop = (zoomedImg.position().top + newZoomTop + _this.MPTop_margin), _this.snLeft = (zoomedImg.position().left + newZoomLeft);
         _this.snWidth = newSnWidth + 1, _this.snHeight = newSnHeight + 1;
         
@@ -407,6 +413,12 @@
 	{
 		this.removeHelpIcon();
 	}
+	
+	//Si on est sur une tablette, on enlève l'icone de retour.
+	if(this.isTablet)
+	{
+		this.removeHomeIcon();
+	}
     
     //Il n'est plus possible de swiper.
     this.canSwipe = false;
@@ -440,7 +452,7 @@
     zoomedImg.attr('src', src.replace('snapshots/', 'snapshots-little/'));
     
     //On libère le player.
-    if(_this.player.widgets && _this.player.widgets[0])
+    if(_this.player && _this.player.widgets && _this.player.widgets[0])
     {
         _this.timeToGoAt[_this.centerId] = Math.floor(_this.player.popcorn.currentTime());
         _this.player.widgets[0].freePlayer();
@@ -507,7 +519,7 @@
         left: '0px'
     }, this.config.unzoomTime, function()
     {
-		//Si on est en mode d'interaction souris, on affiche la bordure d'aide.
+		//Si on est en mode d'interaction souris, on affiche l'icone d'aide.
 		if(_this.config.mouseInteractions)
 		{
 			_this.helpIcon();
@@ -536,6 +548,13 @@
                 _this.removeNotifications();
                 _this.mosaicSelectionAndSearch();
             }
+			//Sinon on met la gesture en cours.
+			else if(_this.currentMode == 'FILTER' && _this.filterSearchedType != '')
+			{
+				//On notifie.
+				_this.removeNotifications();
+				_this.filterGesture(_this.filterSearchedType, 'valid');
+			}
         }
         
         //On indique qu'on est plus en dezoom.
--- a/front_idill/src/player/metadataplayer/Timeline.js	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/player/metadataplayer/Timeline.js	Wed Aug 08 18:40:40 2012 +0200
@@ -49,7 +49,7 @@
     
     //Gestures et noms par défaut.
     this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "knee-up", "right-angle", "wave", "no-motion", "contact", "up-down"];
-    this.gesturesText = ["chute", "saut", "rotation", "rotation de groupe", "inclinaison", "port de bras", "levé de genou", "angle droit", "ondulation", "immobilité", "contact", "de haut en bas"];
+    this.gesturesText = ["chute", "saut", "rotation", "rotation de groupe", "inclinaison", "port de bras", "levé de genou", "angle droit", "ondulation", "immobilité", "contact", "de haut en bas", "grand-jeté"];
     
 	var _this = this;
     this.annotations = this.source.getAnnotations().filter(function(annotation)
@@ -170,6 +170,7 @@
  * Starts playing the video when it's ready.
 */
 IriSP.Widgets.Timeline.prototype.ready = function() {
+	// alert('rdy');
     this.player.popcorn.play();
     this.player.popcorn.mute();
     this.processMarkers();
--- a/front_idill/src/search/js/searchCanvas.js	Thu Aug 02 11:54:08 2012 +0200
+++ b/front_idill/src/search/js/searchCanvas.js	Wed Aug 08 18:40:40 2012 +0200
@@ -107,6 +107,11 @@
     {
         $('.canvas').remove();
     });
+	
+	if(this.mosaic.isTablet)
+	{
+		this.mosaic.isTouchStart = false;
+	}
 };
 
 /*