diff -r 03ea3d7ddbe1 -r 277c94533395 front_idill/src/mosaic/js/search.js --- a/front_idill/src/mosaic/js/search.js Mon Jul 23 10:52:41 2012 +0200 +++ b/front_idill/src/mosaic/js/search.js Mon Jul 23 16:59:35 2012 +0200 @@ -1,358 +1,347 @@ +/* +* This file is part of the TraKERS\Front IDILL package. +* +* (c) IRI +* +* 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 : search.js + * + * Auteur : alexandre.bastien@iri.centrepompidou.fr + * + * Fonctionnalités : Définit les fonctions de recherche par courbe de haut niveau (instantiation et manipulation de la classe de recherche par courbe mais pas les courbes en elles-mêmes ni le détecteur). + */ + /* * Lance une recherche par courbes. + * Est appelé dans le fichier : + * mosaic > fonction onMouseMove. */ -mosaic.prototype.startSearch = function() +Mosaic.prototype.startSearch = function() { - var _this = this; - - var top, left, width, height, margin_top, inMosaic; - //Si on est dans le cas d'un filtrage de mosaïque. - if(this.currentMode == "FILTER") - { - var mainPanel = $('#mainPanel'); - top = mainPanel.position().top; - left = mainPanel.position().left; - width = mainPanel.width(); - height = mainPanel.height(); - margin_top = this.MPTop_margin; - inMosaic = true; - } - //Sinon si c'est une recherche dans la vidéo. - else if(this.currentMode == "SEARCH") - { - top = this.snTop; - left = this.snLeft; - width = this.snWidth; - height = this.snHeight; - margin_top = '0px'; - inMosaic = false; - } - - this.searchCanvas = new searchCanvas(top, left, width, height, margin_top, this.timeSearchFade, inMosaic, this); - this.searchCanvas.create(this.dictionary); + var _this = this; + + var top, left, width, height, margin_top, inMosaic; + //Si on est dans le cas d'un filtrage de mosaïque. + if(this.currentMode == "FILTER") + { + var mainPanel = $('#mainPanel'); + top = mainPanel.position().top; + left = mainPanel.position().left; + width = mainPanel.width(); + height = mainPanel.height(); + margin_top = this.MPTop_margin; + inMosaic = true; + } + //Sinon si c'est une recherche dans la vidéo. + else if(this.currentMode == "SEARCH") + { + top = this.snTop; + left = this.snLeft; + width = this.snWidth; + height = this.snHeight; + margin_top = '0px'; + inMosaic = false; + } + + //On crée le canvas et on récupère le dictionnaire des courbes. + this.searchCanvas = new SearchCanvas(top, left, width, height, margin_top, this.timeSearchFade, inMosaic, this); + this.searchCanvas.create(this.dictionary); } /* * Lit le dictionnaire pour reconnaître les courbes de recherche. + * Est appelé dans le fichier : + * mosaic > fonction loadParameters. */ -mosaic.prototype.getDictionary = function() +Mosaic.prototype.getDictionary = function() { - var path = this.config['dico']; - var dico = []; - - var _this = this; - - $.getJSON(path, function(data) - { - for(var i = 0 ; i < data.gestures.length ; i++) - { - _this.dictionary[i] = data.gestures[i]; - } - }); + var path = this.config.curveDictionary; + var dico = []; + + var _this = this; + + $.getJSON(path, function(data) + { + //Chaque entrée comporte un objet de cette forme : (nom, tableau). Tableau est un array de strings, qui sont les codes décrivant la courbe. Chaque code est un alias de cette courbe. + for(var i = 0 ; i < data.gestures.length ; i++) + { + _this.dictionary[i] = data.gestures[i]; + } + }); } /* * Charge le texte affichable en fonction de la langue. + * Est appelé dans le fichier : + * mosaic > fonction loadParameters. */ -mosaic.prototype.getLang = function(lang) +Mosaic.prototype.getLang = function(lang) { - var path = 'lang/' + this.config['lang'] + '.json'; - - var _this = this; - - $.getJSON(path, function(data) - { - _this.gesturesText = data.gesturesText; - }); + var path = 'lang/' + this.config.lang + '.json'; + + var _this = this; + + $.getJSON(path, function(data) + { + _this.gesturesText = data.gesturesText; + }); } -mosaic.prototype.listenToPointers = function() +/*Mosaic.prototype.listenToPointers = function() { - if(this.searchCanvas) - { - - } -} + if(this.searchCanvas) + { + + } +}*/ /* * Quitte une recherche par courbes. + * Est appelé dans les fichiers : + * mosaic > fonction onMouseUp. + * curvesDetector > fonction updateDists. */ -mosaic.prototype.leaveSearch = function() -{ - if(this.searchCanvas) - { - this.searchCanvas.leaveSearch(); - } - this.searchCanvas = null; -} - -/* - * Affiche les types de marqueurs correspondants à ce qu'on a commencé à tracer lors d'une recherche. -*/ - mosaic.prototype.notifySearchMarkers = function(markersStr) +Mosaic.prototype.leaveSearch = function() { - if($('.notifications_inSearch_container').length > 0) - { - return; - } - - // console.log(markersStr); - - var markersList = markersStr.split(new RegExp(';')); - - var notification_search_markers = "
"; - - //On spécifie les notifications en div. - for(var i = 0 ; i < markersList.length ; i++) - { - notification_search_markers += "
"; - } - - notification_search_markers += "
"; - - //On les ajoute à la mosaïque. - $('#mainPanel').append(notification_search_markers); - - //On calcule leurs coordonnées et dimensions. - var notify_width = $('.notifications_inSearch_container').width(), notify_height = $('.notifications_inSearch_container').height(); - var notify_margin = parseInt($('.notifications_inSearch').css('margin')); - var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin; - var point_top = 0; - - if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH") - { - point_top = -this.notifyTopVideo, - point_left = -this.notifyLeftVideo + ($(window).width() - notify_width) / 2 - } - - //On les positionne. - $('.notifications_inSearch_container').css( - { - left: point_left, - top: point_top - }); - - //On les fait apparaître. - $('.notifications_inSearch').css( - { - opacity: "0.9" - }); -} - -/* - * Supprime la notification de maintient du pointage. -*/ -mosaic.prototype.removeSearchMarkers = function() -{ - $('.notifications_inSearch_container').remove(); + if(this.searchCanvas) + { + this.searchCanvas.leaveSearch(); + //Dans le cadre du mode d'interactions souris, on indique qu'on est en mouse down de facon à ne plus être en mouse move avant le prochain mouse up puis d'un mouse down. + this.isMouseDown = false; + } + this.searchCanvas = null; } /* * Effectuer un filtrage de la mosaïque par rapport à un type de marqueurs. + * Est appelé dans les fichiers : + * mosaic > fonctions onMouseUp et manageControlEvents. + * curvesDetector > fonction updateDists. */ -mosaic.prototype.searchFilter = function(type) +Mosaic.prototype.searchFilter = function(type) { - // type = 'a'; - var _this = this; - - if(this.currentMode == "FILTER") - { - for(var i = 0 ; i < this.config['imagesToShow'] ; i++) - { - this.currentSearchGesture[i] = type; - } - - this.filterSearchedType = type; - - // console.log('Annotations length : ' + this.annotations.length); - if(this.annotations.length > 0) - { - this.isMosaicFiltering = true; - - var gestureNumberByVideo = new Object(); - var maxAnnotationNumber = 0; - // for(var i = 0 ; i < this.config['imagesToShow'] ; i++) - for(var i = 0 ; i < this.annotations.length ; i++) - { - var current = this.annotations[i]; - // console.log(current.annotationType.contents.title + ' == ' + type); - if(current.annotationType.contents.title == type) - { - if(gestureNumberByVideo[current.source.url] == undefined || gestureNumberByVideo[current.source.url] == '') - { - gestureNumberByVideo[current.source.url] = 0; - } - - gestureNumberByVideo[current.source.url]++; - } - } - - for(var i = 0 ; i < this.config['imagesToShow'] ; i++) - { - if(gestureNumberByVideo[this.urls[i]] == undefined || gestureNumberByVideo[this.urls[i]] == '') - { - gestureNumberByVideo[this.urls[i]] = 0; - } - } - - //On récupère la vidéo qui score le nombre d'occurences de la gesture le plus haut. - for(i in gestureNumberByVideo) - { - // console.log(i + " " + gestureNumberByVideo[i] + ' ' + type); - if(maxAnnotationNumber < gestureNumberByVideo[i]) - { - maxAnnotationNumber = gestureNumberByVideo[i]; - } - } - - var snMargin = parseInt($('.snapshotDivs').css('margin')); - - //On affiche l'opacité résultante pour chaque vidéo. - for(var i = 0 ; i < this.config['imagesToShow'] ; i++)// in gestureNumberByVideo) - { - //Toutes les videos ont cette recherche. - this.filterSearchedType[i] = type; - //Opacité conventionelle. - var opacity; - if(maxAnnotationNumber > 0) - { - opacity = gestureNumberByVideo[this.urls[i]] / maxAnnotationNumber; - } - else - { - opacity = 0; - } - - // console.log('opacity b : ' + opacity + ' for ' + gestureNumberByVideo[i]); - //Ce qui est à zéro le restera (par conséquent le snapshot associé sera invisible). - if(opacity > 0) - { - //On réhausse l'opacité de 50%. - opacity = this.scaleIntervals(0., 1., 0.5, 1., opacity); - } - this.opacities[i] = opacity; - - //var filterIndex = this.getIdxFromMetadata(i); - var filterIndex = i; - //if(filterIndex >= 0) - //{ - // console.log('#snapshotDiv-' + filterIndex + " " + _this.config['timeFilterFade'] + " " + opacity); - $('#snapshotDiv-' + filterIndex).fadeTo(this.config['timeFilterFade'], opacity, function() - { - //Pour ne notifier qu'une fois. - if(_this.isMosaicFiltering) - { - _this.isMosaicFiltering = false; - } - }); - - // console.log('filterIdx : ' + filterIndex); - - if(opacity == 0) - { - var filteredSnapshot = $('#snapshotDiv-' + filterIndex); - - if(filteredSnapshot.length > 0) - { - var hider = '
'; - $('#mainPanel').append(hider); - - $('#filterHider-' + filterIndex).css( - { - width: +filteredSnapshot.width() + 4 * snMargin, - height: +filteredSnapshot.height() + 4 * snMargin, - top: filteredSnapshot.position().top - snMargin, - left: filteredSnapshot.position().left - snMargin - }); - } - } - //} - } - // for(var a = 0 ; a < this.config['imagesToShow'] ; a++) - // console.log('op : ' + ' ' + this.imgs[a] + ' \t ' + this.opacities[a]); - - this.isMosaicFiltered = true; - } - } + var _this = this; + + //Si on est en mode filtrage. + if(this.currentMode == "FILTER") + { + //On indique pour chaque snapshot la recherche de filtrage. + for(var i = 0 ; i < this.config['imagesToShow'] ; i++) + { + this.currentSearchGesture[i] = type; + } + + this.filterSearchedType = type; + + //Si on a des annotations. + if(this.annotations.length > 0) + { + //On indique qu'on est en train de filtrer. + this.isMosaicFiltering = true; + + //Va servir à compter le nombre d'occurence des marqueurs dans chaque video. + var gestureNumberByVideo = new Object(); + var maxAnnotationNumber = 0; + + //Pour chaque annotation. + for(var i = 0 ; i < this.annotations.length ; i++) + { + //On récupère l'annotation en cours. + var current = this.annotations[i]; + + //Si l'annotation correspond à la gesture recherchée. + if(current.annotationType.contents.title == type) + { + //Si une video n'a pas été traitée, on met son nombre d'occurences à 0. + if(gestureNumberByVideo[current.source.url] == undefined || gestureNumberByVideo[current.source.url] == '') + { + gestureNumberByVideo[current.source.url] = 0; + } + + //On incrémente le nombre d'occurences de la video. + gestureNumberByVideo[current.source.url]++; + } + } + + //Pour chaque snapshot, s'il son nombre d'occurences n'a pas été encore calculé (cas où il n'y a pas de résultats dans ces videos là, on met leur nombre d'occurences à 0. + for(var i = 0 ; i < this.config['imagesToShow'] ; i++) + { + if(gestureNumberByVideo[this.urls[i]] == undefined || gestureNumberByVideo[this.urls[i]] == '') + { + gestureNumberByVideo[this.urls[i]] = 0; + } + } + + //On récupère la vidéo qui score le nombre d'occurences de la gesture le plus haut. + for(i in gestureNumberByVideo) + { + if(maxAnnotationNumber < gestureNumberByVideo[i]) + { + maxAnnotationNumber = gestureNumberByVideo[i]; + } + } + + var snMargin = parseInt($('.snapshotDivs').css('margin')); + + //On affiche l'opacité résultante pour chaque vidéo. + for(var i = 0 ; i < this.config['imagesToShow'] ; i++) + { + //Opacité conventionelle. + var opacity; + if(maxAnnotationNumber > 0) + { + opacity = gestureNumberByVideo[this.urls[i]] / maxAnnotationNumber; + } + else + { + opacity = 0; + } + + //Ce qui est à zéro le restera (par conséquent le snapshot associé sera invisible). + if(opacity > 0) + { + //On réhausse l'opacité de 50%. + opacity = this.scaleIntervals(0., 1., 0.5, 1., opacity); + } + this.opacities[i] = opacity; + + var filterIndex = i; + + //On applique les opacités aux snapshots. + $('#snapshotDiv-' + filterIndex).fadeTo(this.config['timeFilterFade'], opacity, function() + { + //On indique lorsque c'est terminé que la mosaique a terminé de filtrer. + if(_this.isMosaicFiltering) + { + _this.isMosaicFiltering = false; + } + }); + + //Si l'opacité est nulle. + if(opacity == 0) + { + //Le snapshot filtré actuel. + var filteredSnapshot = $('#snapshotDiv-' + filterIndex); + + //S'il existe. + if(filteredSnapshot.length > 0) + { + //On rajoute un hider de façon à ce qu'on ne puisse pas le sélectionner. + var hider = '
'; + $('#mainPanel').append(hider); + + $('#filterHider-' + filterIndex).css( + { + width: +filteredSnapshot.width() + 4 * snMargin, + height: +filteredSnapshot.height() + 4 * snMargin, + top: filteredSnapshot.position().top - snMargin, + left: filteredSnapshot.position().left - snMargin + }); + } + } + } + + //On indique que la mosaique a été filtrée. + this.isMosaicFiltered = true; + } + } } /* * Passe une valeur de l'intervalle [A, B] à l'intervalle [C, D]. + * Est appelé dans les fichiers : + * pointers > fonction pointersTimelineSelection. + * search > fonction searchFilter. */ -mosaic.prototype.scaleIntervals = function(A, B, C, D, val) +Mosaic.prototype.scaleIntervals = function(A, B, C, D, val) { - return (D - C + A) * val + (C - A); + return (D - C + A) * val + (C - A); } /* * Retourne l'index d'un snapshot en fonction de ses metadonnées. */ -mosaic.prototype.getIdxFromMetadata = function(metadata) +/*Mosaic.prototype.getIdxFromMetadata = function(metadata) { - var _this = this; - - for(idx in this.urls) - { - if(this.urls[idx] == metadata) - { - for(id in this.ids) - { - if(this.ids[id] == idx) - { - return id; - } - } - } - } - - return -1; -} + var _this = this; + + for(idx in this.urls) + { + if(this.urls[idx] == metadata) + { + for(id in this.ids) + { + if(this.ids[id] == idx) + { + return id; + } + } + } + } + + return -1; +}*/ /* * Enlève une recherche par filtre. + * Est appelé : dans les fichiers : + * pointers > fonctions checkIfPointerIsOnSearchNotification et removeSearchNotificationIfOnIt. + * mosaic > fonction onMarkersReady. */ -mosaic.prototype.removeFilter = function() +Mosaic.prototype.removeFilter = function() { - if(this.currentMode == "FILTER") - { - this.currentMode = "MOSAIC"; - - var _this = this; - - this.isMosaicFiltered = false; - this.filterSearchedType = ''; - - for(var i = 0 ; i < this.config['imagesToShow'] ; i++) + //Si on est en filtrage, on passe en mosaic et on retire la recherche. + if(this.currentMode == "FILTER") + { + this.currentMode = "MOSAIC"; + + var _this = this; + + this.isMosaicFiltered = false; + this.isMosaicFiltering = true; + this.filterSearchedType = ''; + + for(var i = 0 ; i < this.config['imagesToShow'] ; i++) + { + this.currentSearchGesture[i] = ''; + } + + this.removeNotifications(); + $('.filterHiders').remove(); + $('.snapshotDivs').fadeTo(_this.config['timeFilterFade'], 1, function() { - this.currentSearchGesture[i] = ''; - } - - $('#notify_search').remove(); - $('#notify_search_1gesture').remove(); - $('.filterHiders').remove(); - $('.snapshotDivs').fadeTo(_this.config['timeFilterFade'], 1); - } + _this.isMosaicFiltering = false; + }); + } } /* * Parcours le dictionnaire pour trouver la première gesture à avoir un code identique à celui en entrée. + * Est appelé dans le fichier : + * mosaic > fonction onMouseUp. */ -mosaic.prototype.gestureWithSameCode = function(code) +Mosaic.prototype.gestureWithSameCode = function(code) { - //Pour tout le dictionnaire. - for(var i = 0 ; i < this.dictionary.length ; i++) - { - //Pour touts les codes de chaque gesture du dictionnaire. - for(var j = 0 ; j < this.dictionary[i].codes.length ; j++) - { - //Si le code en entrée est une partie début d'un des codes. - if(this.dictionary[i].codes[j] === code) - { - //On retourne le nom de la gesture. - return this.dictionary[i].name; - } - } - } - - return ''; + //Pour tout le dictionnaire. + for(var i = 0 ; i < this.dictionary.length ; i++) + { + //Pour touts les codes de chaque gesture du dictionnaire. + for(var j = 0 ; j < this.dictionary[i].codes.length ; j++) + { + //Si le code en entrée est une partie début d'un des codes. + if(this.dictionary[i].codes[j] === code) + { + //On retourne le nom de la gesture. + return this.dictionary[i].name; + } + } + } + + return ''; } \ No newline at end of file