commit 3525f79c252a0ff264af683f365dec1364b5b7f4
parent 1d2692d3f517dad75b7fe8c8aa3b1906b1c57505
Author: gduperon <gduperon@5d9ba3ac-444b-4713-9fb3-0b58e79229a2>
Date: Sat, 15 May 2010 15:12:30 +0000
Recherche incrémentale avec surlignage, ajout dynamique, … la grande classe quoi + ajout blocs quand on zone (mais pas encore taille/position dudit bloc)
git-svn-id: https://projetud.info-ufr.univ-montp2.fr/svn/flin607-2009-gduperon@47 5d9ba3ac-444b-4713-9fb3-0b58e79229a2
Diffstat:
13 files changed, 853 insertions(+), 116 deletions(-)
diff --git a/jside3/extensions-jQuery.js b/jside3/extensions-jQuery.js
@@ -22,6 +22,10 @@ String.prototype.appendTo = function() {
// Extensions de jQuery
jQuery.fn.extend({
+ /* Mathias Bynens - http://stackoverflow.com/questions/2059743/detect-elements-overflow-using-jquery */
+ overflows: function() {
+ return ($(this).width() !== this.clientWidth || $(this).height() !== this.clientHeight);
+ },
scrollToLast: function(speed) {
return this.scrollTo(this.children().last(), speed);
},
@@ -118,7 +122,7 @@ function surchargeAccesseur(nom, type, get, set) {
var args = arguments;
if (options !== undefined) {
var that = this;
- var ret = this.map(function (i) {
+ var ret = $(this).map(function (i) {
if (that[i] instanceof type) {
return set(that[i], options);
} else {
@@ -186,6 +190,86 @@ surchargeAccesseur(
}(jQuery));
+getRectangle = function(x1,y1,x2,y2) {
+ if (x2 === undefined) {
+ var oa = $(x1).offset();
+ var ob = $(y1).offset();
+ return getRectangle(oa.left, oa.top, ob.left, ob.top);
+ }
+ return {
+ x1: Math.min(x1,x2),
+ y1: Math.min(y1,y2),
+ x2: Math.max(x1,x2),
+ y2: Math.max(y1,y2),
+ width: Math.abs(x1 - x2),
+ height: Math.abs(y1 - y2)
+ };
+};
+
+jQuery.fn.corners = function(x1,y1,x2,y2) {
+ var rect = getRectangle(x1,y1,x2,y2);
+ this.offset({left: rect.x1, top: rect.y1});
+ this.width(rect.width);
+ this.height(rect.height);
+}
+
+jQuery.fn.zonable = function(start, zone, end) {
+ var opts = {
+ start: function() {return true;},
+ zone: function() {return true;},
+ end: function() {return true;}
+ };
+ if (typeof start == "function") {
+ if (start) opts.start = start;
+ if (zone) opts.start = start;
+ if (end) opts.start = start;
+ } else {
+ if (start) $.extend(opts, start);
+ }
+
+ var z = {};
+ z.vZone = $('#vue-zone').jqote({}).appendTo(this);
+ z.vZone.hide();
+ z.zoning = false;
+ z.start = null;
+
+ z.manageDown = function(e) {
+ if (e.target != this || opts.start(e) === false) {
+ return true;
+ }
+ z.start = $(e);
+ z.zoning = true;
+ z.vZone.show();
+ z.manageMove(e);
+ return false;
+ };
+ z.manageMove = function(e) {
+ if (z.zoning) {
+ if (opts.zone(z.start, e) === false) {
+ return true;
+ }
+ z.vZone.corners(z.start, e);
+ return false;
+ }
+ };
+ z.manageUp = function(e) {
+ if (z.zoning) {
+ z.manageMove(e);
+ if (opts.end(z.start, e, getRectangle(z.start, e)) === false) {
+ return true;
+ }
+ z.vZone.hide();
+ z.zoning = false;
+ return false;
+ }
+ }
+
+ var that = this;
+ this.mousedown(z.manageDown);
+ this.mousemove(z.manageMove);
+ this.mouseup(z.manageUp);
+}
+
/* Fioritures graphique */
jQuery.fn.extend({
diff --git a/jside3/index.html b/jside3/index.html
@@ -35,11 +35,20 @@
<!-- MVC -->
<script type="text/javascript" src="mvc/monde.js"></script>
+
<script type="text/javascript" src="mvc/barre-outils.js"></script>
+
<script type="text/javascript" src="mvc/log.js"></script>
<script type="text/javascript" src="mvc/instance-log.js"></script>
+
+ <script type="text/javascript" src="mvc/recherche.js"></script>
+ <script type="text/javascript" src="mvc/instance-recherche.js"></script>
+ <script type="text/javascript" src="mvc/resultat-recherche.js"></script>
+
<script type="text/javascript" src="mvc/bloc.js"></script>
<script type="text/javascript" src="mvc/instance-bloc.js"></script>
+ <script type="text/javascript" src="mvc/definitions.js"></script>
+
<script type="text/javascript" src="mvc/definition.js"></script>
<script type="text/javascript" src="mvc/connexion.js"></script>
<script type="text/javascript" src="mvc/port.js"></script>
@@ -77,6 +86,7 @@
<input type="button" class="log pause" value="▌▌" style="padding-right: 0.2em;" />
<input type="button" class="log play" value="▶"/>
<h2 class="titre">Log</h2>
+ <div class="clearfloat"></div>
</div>
<div class="log messages">
<div><!-- Il faut au moins un message (vide). --></div>
@@ -84,16 +94,55 @@
</div>
]]>
</script>
- <script type="text/x-jqote-template" id="vue-bloc">
+ <script type="text/x-jqote-template" id="vue-recherche">
<![CDATA[
- <div class="bloc fenetre">
- <h2 class="bloc barre-titre titre">Nom du bloc</h2>
- <div class="bloc tabs titres">
- <h3 class="définition titre aucune-définition">Aucune définition</h3>
- <input type="button" class="nouvelle-définition" value="+"/>
+ <div class="recherche fenetre">
+ <div class="recherche barre-titre">
+ <input type="text" class="recherche termes" value="Recherche…"/>
+ <h2 class="titre">Recherche</h2>
+ <div class="clearfloat"></div>
+ </div>
+ <div class="recherche résultats">
</div>
- <div class="bloc définitions">
- <div class="définition contenu aucune-définition">
+ </div>
+ ]]>
+ </script>
+ <script type="text/x-jqote-template" id="vue-résultat-recherche">
+ <![CDATA[
+ <div class="résultat-recherche vMain">
+ <span class="résultat-recherche vUid">
+ </span>
+ <span class="résultat-recherche vTexte">
+ </span>
+ </div>
+ ]]>
+ </script>
+ <script type="text/x-jqote-template" id="vue-instance-bloc">
+ <![CDATA[
+ <div class="instance-bloc vMain fenetre">
+ <div class="instance-bloc vBarre-titre">
+ <h2 class="instance-bloc vTitre vVue-titre">Nom du bloc</h2>
+ <form action="#" class="instance-bloc vÉdition-titre">
+ <input type="text" class="instance-bloc vChamp-titre" value=""/>
+ <input type="submit" class="instance-bloc vBouton-valider-titre" value="ok"/>
+ </form>
+ <div class="clearfloat"></div>
+ </div>
+ <div class="instance-bloc vDéfinitions">
+ </div>
+ </div>
+ ]]>
+ </script>
+ <script type="text/x-jqote-template" id="vue-définitions">
+ <![CDATA[
+ <div class="définitions vMain">
+ <div class="définitions vTitresTabs">
+ <h3 class="définition vTitre vAucune-définition">Aucune définition</h3>
+ <input type="button" class="définitions vNouvelle-définition" value="+"/>
+ <div class="clearfloat"></div>
+ </div>
+ <div class="définitions vContenusTabs">
+ <div class="définition vCorps vAucune-définition">
Aucune définition.
<br/>
Cliquez sur le + ci-dessus pour en créer une.
@@ -104,13 +153,18 @@
</script>
<script type="text/x-jqote-template" id="vue-définition-titre">
<![CDATA[
- <h3 class="définition titre">Nom de la définition</h3>
+ <h3 class="définition vTitre">Nom de la définition</h3>
]]>
</script>
<script type="text/x-jqote-template" id="vue-définition">
<![CDATA[
- <div class="définition contenu">
-
+ <div class="définition vCorps">
+ </div>
+ ]]>
+ </script>
+ <script type="text/x-jqote-template" id="vue-zone">
+ <![CDATA[
+ <div class="vZone">
</div>
]]>
</script>
diff --git a/jside3/jquery/jquery.my.enumerable.js b/jside3/jquery/jquery.my.enumerable.js
@@ -38,18 +38,19 @@
},
// $([1,2,3]).select(function() { return this % 2 == 1 }) // => [1, 3]
- select: function(enumerable, callback) {
+ /* Removed by jspam@free.fr : conflicts with $.select() (for input forms)
+ select: function(enumerable, callback) {
var result = [];
$.each(enumerable, function(index) {
if (callback.call(this, index))
result.push(this);
});
return $(result);
- },
+ }, */
// $([1,2,3]).reject(function() { return this % 2 == 1 }) // => [2]
reject: function(enumerable, callback) {
- return $.select(enumerable, negate(callback));
+ return /*$.select*/$.filter(enumerable, negate(callback));
},
// $([1,2]).any(function() { return this == 1 }) // => true
diff --git a/jside3/mvc/barre-outils.js b/jside3/mvc/barre-outils.js
@@ -27,11 +27,28 @@ function CBarreOutils(mBarreOutils, vMondeParente) {
var that = this;
(this.vue.vBoutonNouveauBloc)
.click(function() {
- that.modèle.monde.log.envoiMessage("Nouveau bloc.");
- var mb = new MBloc();
+ that.modèle.monde.log.envoiMessage("Cliquez-glissez pour créer un nouveau bloc.");
+ that.modèle.monde.outilZone = function(cDéfinition, rect) {
+ console.log('Zone sur', cDéfinition, rect.x1, rect.y1, rect.x2, rect.y2, rect.width, rect.height);
+ that.modèle.monde.outilZone = that.modèle.monde.actionAucune;
+
+ var mb = new MBloc();
+ that.modèle.monde.ajouterBloc(mb);
+ var mib = mb.demanderInstance();
+ cDéfinition.modèle.ajouterInstanceBloc(mib);
+ }
+/* var mb = new MBloc();
that.modèle.monde.ajouterBloc(mb);
var mib = mb.demanderInstance();
- that.modèle.monde.scratch.ajouterInstanceBloc(mib);
+ that.modèle.monde.scratch.ajouterInstanceBloc(mib);*/
+ });
+
+ (this.vue.vBoutonRecherche)
+ .click(function() {
+ that.modèle.monde.log.envoiMessage("Nouvelle recherche.");
+ var mr = that.modèle.monde.recherche;
+ var mir = mr.demanderInstance();
+ that.modèle.monde.ajouterInstanceRecherche(mir);
});
(this.vue.vBoutonLog)
diff --git a/jside3/mvc/bloc.js b/jside3/mvc/bloc.js
@@ -22,8 +22,13 @@ function MBloc() {
this.instances.push(mib);
return mib;
},
-
// Modification
+ changeNom: function(nouveauNom) {
+ this.nom = nouveauNom;
+ faireCallbacks(this.cbChangeNom, this);
+ faireCallbacks(this.cbModification, this);
+ },
+
/*déplacerDéfinition: function(def, position) {
var pos = définitions.remove(def);
if (pos < position) position--;
@@ -45,10 +50,19 @@ function MBloc() {
d.bloc = this;
this.définitions.push(d);
faireCallbacks(this.cbAjoutDéfinition, d);
+ faireCallbacks(this.cbModification, this);
},
cbAjoutDéfinition: [],
onAjoutDéfinition: function(callback) {
this.cbAjoutDéfinition.push(callback);
- }
+ },
+ cbChangeNom: [],
+ onChangeNom: function(callback) {
+ this.cbChangeNom.push(callback);
+ },
+ cbModification: [],
+ onModification: function(callback) {
+ this.cbModification.push(callback);
+ },
});
}
diff --git a/jside3/mvc/definition.js b/jside3/mvc/definition.js
@@ -29,19 +29,34 @@ function MDéfinition() {
blablabla = 0;
function VDéfinition(vInstanceBlocParente) {
- var t = $('#vue-définition-titre').jqote({});
- var d = $('#vue-définition').jqote({}).toDom();
- d.append(blablabla++);
- vInstanceBlocParente.ajoutVDéfinition(t, d)
- $.extend(this,d);
+ $.extend(this,(
+ $('#vue-définition')
+ .jqote({})
+ .toDom()));
+ this.vTitre = $('#vue-définition-titre').jqote({});
+ vInstanceBlocParente.ajoutVDéfinition(this.vTitre, this);
- this.mousedown(function(e) {
- console.log("mousedown");
- return false;
- });
+ this.append(blablabla++); // Debug
}
function CDéfinition(mDéfinition, vInstanceBlocParente) {
this.modèle = mDéfinition;
this.vue = new VDéfinition(vInstanceBlocParente);
+
+ var that = this;
+ this.vue.zonable({
+ start: function() {
+ console.log('startZone');
+ },
+ zone: function() {
+ //console.log('zone');
+ },
+ end: function(start, end, rect) {
+ console.log('endZone');
+ that.modèle.bloc.monde.outilZone(that, rect);
+ }
+ });
+ this.modèle.onAjoutInstanceBloc(function(instanceBloc) {
+ var cib = new CInstanceBloc(instanceBloc, that.vue);
+ });
}
diff --git a/jside3/mvc/definitions.js b/jside3/mvc/definitions.js
@@ -0,0 +1,60 @@
+/* Pas de modèle pour définitions: c'est juste une partie de instanceBloc */
+
+function VDéfinitions(vInstanceBlocParente) {
+ $.extend(this,(
+ $('#vue-définitions')
+ .jqote({})
+ .appendTo(vInstanceBlocParente)));
+
+ this.vTitresTabs = this.find('.définitions.vTitresTabs');
+ this.vBoutonNouvelleDéfinition = this.find('.définitions.vNouvelle-définition');
+
+ this.vContenusTabs = this.find('.définitions.vContenusTabs');
+ this.vTitreAucuneDéfinition = this.find('.définition.vTitre.vAucune-définition');
+ this.vCorpsAucuneDéfinition = this.find('.définition.vCorps.vAucune-définition');
+
+ this.aucuneDéfinition = true;
+
+ var that = this;
+ this.ajoutVDéfinition = function(vTitreDéfinition, vCorpsDéfinition) {
+ if (this.aucuneDéfinition) {
+ this.vTitreAucuneDéfinition.hide();
+ this.aucuneDéfinition = false;
+ }
+ var vtd = $(vTitreDéfinition).insertBefore(this.vTitresTabs.children('.clearfloat')); // hack…
+ var vcd = vCorpsDéfinition.appendTo(this.vContenusTabs);
+
+ vtd.click(function() {
+ that.changerTab(vtd, vcd);
+ });
+ this.changerTab(vtd, vcd);
+ return vcd;
+ };
+
+ this.changerTab = function(titreTab, contenuTab) {
+ this.vTitresTabs.children().removeClass("active");
+ this.vContenusTabs.children().hide();
+ titreTab.addClass("active");
+ contenuTab.show();
+ };
+
+ this.vContenusTabs.css('top', this.vTitresTabs.outerHeight());
+}
+
+function CDéfinitions(mInstanceBloc, vInstanceBlocParente) {
+ this.modèle = mInstanceBloc;
+ this.vue = new VDéfinitions(vInstanceBlocParente);
+
+ var that = this;
+ (this.vue.vBoutonNouvelleDéfinition)
+ .click(function() {
+ that.modèle.bloc.monde.log.envoiMessage("Nouvelle définition.");
+ var md = new MDéfinition();
+ that.modèle.bloc.ajouterDéfinition(md);
+ });
+
+ this.modèle.bloc.onAjoutDéfinition(function(définition) {
+ that.modèle.bloc.monde.log.envoiMessage("Ajout de définition", définition);
+ new CDéfinition(définition, that.vue);
+ });
+}
diff --git a/jside3/mvc/instance-bloc.js b/jside3/mvc/instance-bloc.js
@@ -13,46 +13,48 @@ function MInstanceBloc() {
function VInstanceBloc(vDéfinitionParente) {
$.extend(this,(
- $('#vue-bloc')
+ $('#vue-instance-bloc')
.jqote({})
.appendTo(vDéfinitionParente)));
- this.vBarreTitre = this.find('.barre-titre');
- this.vTitre = this.find('.titre');
- this.vBoutonNouvelleDéfinition = this.find('.nouvelle-définition');
- this.vTitresTabs = this.find('.bloc.tabs.titres');
- this.vDéfinitions = this.find('.définitions');
- this.vAucuneDéfinition = this.find('.aucune-définition');
-
- this.aucuneDéfinition = true;
+ this.vBarreTitre = this.find('.instance-bloc.vBarre-titre');
+ this.vTitre = this.find('.instance-bloc.vTitre');
+ this.vVueTitre = this.find('.instance-bloc.vVue-titre');
+ this.vÉditionTitre = this.find('.instance-bloc.vÉdition-titre');
+ this.vChampTitre = this.find('.instance-bloc.vChamp-titre');
+ this.vBoutonValiderTitre = this.find('.instance-bloc.vBoutonValiderTitre');
+ this.vDéfinitions = this.find('.instance-bloc.vDéfinitions');
var that = this;
- this.ajoutVDéfinition = function(vTitreDéfinition, vDéfinition) {
- if (this.aucuneDéfinition) {
- this.vAucuneDéfinition.hide();
- this.aucuneDéfinition = false;
+ this.titre = function(val) {
+ if (typeof val != "function") {
+ this.vTitre.text(val);
+ this.ajusterBarreTitre();
+ return true;
}
- var vD = vDéfinition.appendTo(this.vDéfinitions);
- var vTD = vTitreDéfinition.appendTo(this.vTitresTabs);
-
- vTD.click(function() {
- that.changerTab(vTD, vD);
+ this.vTitre.hide();
+ this.vChampTitre.val(this.vTitre.text());
+ this.vÉditionTitre.show();
+ this.ajusterBarreTitre();
+ this.vChampTitre.select();
+ var cbModifTitre = val;
+ this.vÉditionTitre.submit(function(ev) {
+ that.vTitre.show();
+ that.vÉditionTitre.hide();
+ that.ajusterBarreTitre();
+ window.setTimeout(function() {cbModifTitre(that.vChampTitre.val());}, 0);
+ return false;
});
- this.changerTab(vTD, vD);
- return vD;
- };
+ }
- this.changerTab = function(titreTab, contenuTab) {
- this.vDéfinitions.children().hide();
- this.vTitresTabs.children().removeClass("active");
- titreTab.addClass("active");
- contenuTab.show();
- };
+ this.ajusterBarreTitre = function() {
+ this.vDéfinitions.css('top', this.vBarreTitre.outerHeight());
+ }
this.draggable();
this.resizable();
- this.vTitresTabs.css('top', this.vBarreTitre.outerHeight());
- this.vDéfinitions.css('top', this.vBarreTitre.outerHeight() + this.vTitresTabs.outerHeight());
+ this.vÉditionTitre.hide();
+ this.ajusterBarreTitre();
}
function CInstanceBloc(mInstanceBloc, vDéfinitionParente) {
@@ -60,15 +62,19 @@ function CInstanceBloc(mInstanceBloc, vDéfinitionParente) {
this.vue = new VInstanceBloc(vDéfinitionParente);
var that = this;
- (this.vue.vBoutonNouvelleDéfinition)
- .click(function() {
- that.modèle.bloc.monde.log.envoiMessage("Nouvelle définition.");
- var md = new MDéfinition();
- that.modèle.bloc.ajouterDéfinition(md);
+ (this.vue.vTitre)
+ .dblclick(function() {
+ that.vue.titre(function(nouveauNom) {
+ that.modèle.bloc.changeNom(nouveauNom);
+ });
});
- this.modèle.bloc.onAjoutDéfinition(function(définition) {
- that.modèle.bloc.monde.log.envoiMessage("Ajout de définition", définition);
- new CDéfinition(définition, that.vue);
- });
+ (this.modèle.bloc)
+ .onChangeNom(function(nouveauNom) {
+ that.vue.titre(that.modèle.bloc.nom);
+ });
+
+ this.vue.titre(this.modèle.bloc.nom);
+
+ new CDéfinitions(this.modèle, this.vue.vDéfinitions);
}
diff --git a/jside3/mvc/instance-recherche.js b/jside3/mvc/instance-recherche.js
@@ -0,0 +1,271 @@
+function MInstanceRecherche() {
+ $.extend(this, {
+ uid: singleton.uid(),
+ // Propriétés
+ recherche: null,
+ termes: '',
+ sélection: [],
+ ajouterRésultatSélection: function(s) {
+ this.sélection.push(s);
+ s.ajoutSélection();
+ },
+ supprimerRésultatSélection: function(s) {
+ this.sélection.remove(s);
+ s.suppressionSélection();
+ },
+ effacerSélection: function(s) {
+ for (var i = 0; i < this.sélection.length; i++)
+ this.sélection[i].suppressionSélection();
+ this.sélection = [];
+ }
+ });
+}
+
+function VInstanceRecherche(vMondeParente) {
+ $.extend(this,(
+ $('#vue-recherche')
+ .jqote({})
+ .appendTo(vMondeParente)));
+
+ this.vBarreTitre = this.find('.barre-titre');
+ this.vTitre = this.find('.titre');
+ this.vChampTermes = this.find('.termes');
+ this.vRésultats = this.find('.résultats');
+ this.premièreFois = true;
+ this.addClass('première-fois');
+
+ var that = this;
+ (this.vChampTermes)
+ .focus(function() {
+ if (that.premièreFois) {
+ that.premièreFois = false;
+ that.vChampTermes.val("");
+ // TODO : unbind focus
+ }
+ });
+
+ this.ajoutVRésultatRecherche = function(vrr, position) {
+ if (position === undefined || position >= this.vRésultats.children().size() - 1) {
+ this.vRésultats.append(vrr);
+ } else {
+ this.vRésultats.children().eq(position).before(vrr);
+ }
+ };
+
+ this.sélection = function(s) {
+ this.vRésultats.children.removeClass('sélectionné');
+ s.addClass('sélectionné');
+ };
+
+ this.termes = function(val) {
+ if (val !== undefined) {
+ this.vChampTermes.val(val);
+ this.removeClass('première-fois');
+ this.premièreFois = false;
+ // TODO : unbind focus
+ } else if (this.premièreFois) {
+ return "";
+ } else {
+ return this.vChampTermes.val();
+ }
+ };
+
+ /*this.effacerRésultats = function() {
+ this.vRésultats.empty();
+ };*/
+
+ this.draggable();
+ this.resizable();
+ this.vRésultats.css('top', this.vBarreTitre.outerHeight());
+}
+
+function CInstanceRecherche(mInstanceRecherche, vMondeParente) {
+ this.modèle = mInstanceRecherche;
+ this.vue = new VInstanceRecherche(vMondeParente);
+ this.ancienTerme = "";
+ this.anciensRésultats = [];
+
+ var that = this;
+ (this.vue.vChampTermes)
+ .keyup(function() { // keypress ne prend pas en compte le backspace
+ that.actualiserRecherche();
+ });
+
+ (this.modèle.recherche.monde)
+ .onAjoutBloc(function(bloc) {
+ that.actualiserRecherche([bloc], true, true);
+ });
+
+ (this.modèle.recherche.monde)
+ .onModificationBloc(function(bloc) {
+ that.actualiserRecherche([bloc], true, true);
+ });
+
+ this.actualiserRecherche = function(domaine, animAjout, animSuppression) {
+ var termes = this.vue.termes().toLowerCase().split(" ");
+ var domaine = domaine || this.modèle.recherche.monde.blocs;
+ var résultats = filtrerValeurs(mInstanceRecherche, domaine, termes, function(b) {
+ return {
+ original: b.nom,
+ searchOn: b.nom.toLowerCase()
+ };
+ });
+
+ this.anciensRésultats = fusionRésultats(this.anciensRésultats, domaine, résultats, this.vue, this.modèle, animAjout, animSuppression);
+ }
+
+ this.actualiserRecherche(null, true, true);
+}
+
+/* Fonctions auxiliaires */
+
+function filtrerValeurs(mInstanceRecherche, ensemble, termes, getTexte) {
+ var maxres = 50;
+ var résultats = [];
+ var nbres = 0;
+ var ensemble_length = ensemble.length;
+ termes = termes.filter(function (e) { return e != ""; });
+
+ for (var i = 0; i < ensemble_length; i++) {
+ var texte = getTexte(ensemble[i]);
+ var mrr = searchAndReturnFormatted(mInstanceRecherche, texte.searchOn, texte.original, termes);
+
+ if (mrr !== false) {
+ mrr.objet = ensemble[i];
+ mrr.uid = ensemble[i].uid;
+ résultats.push(mrr);
+ nbres++;
+ if (nbres >= maxres) break;
+ }
+ }
+
+ résultats.sort(function(a,b){return a.score - b.score});
+ for (var i = 0; i<résultats.length; i++) { résultats[i].position = i; }
+ return résultats;
+}
+
+/* searchAndReturnFormatted("abcdefghijkabcxyz", ["abc", "ef", "cxy"]); */
+function searchAndReturnFormatted(mInstanceRecherche, haystack, original, needles) {
+ var status = new Array(haystack.length);
+ for (var i = 0; i < status.length; i++) {
+ status[i] = 0;
+ }
+
+ for (var n = 0; n < needles.length; n++) {
+ var nl = needles[n].length;
+ var idx = haystack.indexOf(needles[n]);
+ if (idx < 0) {
+ // Aucune occurence de needles[n]
+ return false;
+ }
+ while (idx >= 0) {
+ for (var i = idx; i < idx + nl; i++) {
+ if (status[i] > 0) {
+ for (j = idx; j < idx + nl; j++) {
+ if (j >= i && status[j] >= 1) {
+ status[j] = 3;
+ } else {
+ status[j] = 2;
+ }
+ }
+ i = idx + nl;
+ break;
+ }
+ status[i] = 1;
+ }
+ idx = haystack.indexOf(needles[n], i);
+ }
+ }
+
+ var old = -1;
+ var str = "";
+ for (var i = 0; i < status.length; i++) {
+ if (old != status[i]) {
+ if (old >= 1)
+ str += '</span>';
+ if (status[i] == 1) {
+ str += '<span class="occurence">';
+ } else if (status[i] == 2) {
+ str += '<span class="superposée">';
+ } else if (status[i] == 3) {
+ str += '<span class="superposition">';
+ }
+ }
+ str += original[i];
+ old = status[i];
+ }
+
+ if (old >= 1)
+ str += '</span>';
+ var mrr = new MRésultatRecherche();
+ mrr.mInstanceRecherche = mInstanceRecherche;
+ mrr.html = str;
+ mrr.score = $.sum(status); // We definitely need a better score calculation…
+ return mrr;
+}
+
+/* anciens = [] of CRésultatRecherche;
+ * domaine = [] of MBloc;
+ * nouveaux = [] of MRésultatRecherche;
+ * vRechercheParente is a VRechercheParente
+ * mInstanceRecherche is a MInstanceRecherche
+ * animAjout is a boolean
+ * animSuppression is a boolean
+ */
+
+function fusionRésultats(anciens, domaine, nouveaux, vRechercheParente, mInstanceRecherche, animAjout, animSuppression) {
+ anciens.sort(function(a,b) { return a.modèle.objet.uid - b.modèle.objet.uid; });
+ domaine.sort(function(a,b) { return a.uid - b.uid; });
+ nouveaux.sort(function(a,b) { return a.objet.uid - b.objet.uid; });
+
+ // Ceci est une sorte de tri fusion à trois tableaux… aaaaaarrrgggh !
+
+ /* anciens domaine nouveaux || Action
+ * oui non non (obligé) || = Reste
+ * oui oui oui || = Reste
+ * oui oui non || - Supprime
+ * non oui oui || + Ajoute
+ * non oui non || 0 Aucune
+ */
+
+ var fusion = [];
+ var iD = 0;
+ var iN = 0;
+ var iA = 0;
+ var lA = anciens.length;
+ var lD = domaine.length;
+ var lN = nouveaux.length;
+ while ((iA < lA) || (iD < lD) || (iN < lN)) {
+ var uidA = (iA < lA) ? anciens[iA].modèle.objet.uid : Infinity;
+ var uidD = (iD < lD) ? domaine[iD].uid : Infinity;
+ var uidN = (iN < lN) ? nouveaux[iN].objet.uid : Infinity;
+
+ var a = (iA < lA && uidA <= uidD);
+ var d = (iD < lD && uidA >= uidD);
+ var n = (iN < lN && uidD == uidN) && d;
+
+ //console.log([iA,iD,iN], [uidA,uidD,uidN], [a,d,n]);
+
+ if (a && !(d && !n)) { // Reste
+ if (n) {
+ anciens[iA].setModèle(nouveaux[iN]);
+ }
+ fusion.push(anciens[iA]);
+ }
+ if (a && d && !n) { // Supprime
+ anciens[iA].suppression(animSuppression);
+ }
+ if (!a && d && n) { // Ajoute
+ var cr = new CRésultatRecherche(nouveaux[iN], vRechercheParente);
+ if (animAjout) {
+ cr.vue.animAjout();
+ }
+ fusion.push(cr);
+ }
+
+ if (a) iA++;
+ if (d) iD++;
+ if (n) iN++;
+ }
+ return fusion;
+}
diff --git a/jside3/mvc/monde.js b/jside3/mvc/monde.js
@@ -6,21 +6,28 @@ function MMonde(nom) {
// Parents
// Enfants
log: null,
+ recherche: null,
barreOutils: null, // J'ai des doutes sur la présence de barreOutils…
blocs: [],
- scratch: null,
+ mBlocScratch: null,
+ mDéfinitionScratch: null,
// Ajout
ajouterBloc: function(b) {
b.monde = this;
this.blocs.push(b);
+ var that = this;
+ b.onModification(function(b) {
+ faireCallbacks(that.cbModificationBloc, b);
+ });
+ faireCallbacks(this.cbAjoutBloc, b);
},
- définirBarreOutils: function(bo) {
- bo.monde = this;
- this.barreOutils = bo;
+ cbAjoutBloc: [],
+ onAjoutBloc: function(callback) {
+ this.cbAjoutBloc.push(callback);
},
- définirLog: function(l) {
- l.monde = this;
- this.log = l;
+ cbModificationBloc: [],
+ onModificationBloc: function(callback) {
+ this.cbModificationBloc.push(callback);
},
instancesLog: [],
ajouterInstanceLog: function(il) {
@@ -31,18 +38,40 @@ function MMonde(nom) {
onAjoutInstanceLog: function(callback) {
this.cbAjoutInstanceLog.push(callback);
},
+ instancesRecherche: [],
+ ajouterInstanceRecherche: function(ir) {
+ this.instancesRecherche.push(ir);
+ faireCallbacks(this.cbAjoutInstanceRecherche, ir);
+ },
+ cbAjoutInstanceRecherche: [],
+ onAjoutInstanceRecherche: function(callback) {
+ this.cbAjoutInstanceRecherche.push(callback);
+ },
// Suppression
supprimerBloc: function(b) {
this.blocs.remove(b);
}
});
- /*this.scratch = new Bloc("Scratch");
- this.ajouterBloc(this.scratch);
- var iscratch = new InstanceBloc(this.scratch, {vues: this.vues}); // Attention, devrait utiliser une définition !!!
- this.scratch.ajouterInstance(iscratch);*/
- this.scratch = new MDéfinition(); // this.scratch.bloc == null;
- this.définirBarreOutils(new MBarreOutils());
- this.définirLog(new MLog());
+
+ /* Actions */
+ this.actionAucune = function() {}
+
+ /* Outils */
+ this.outilZone = this.actionAucune;
+
+ /* Scratch */
+ this.mBlocScratch = new MBloc(); // this.scratch.bloc == null;
+ this.ajouterBloc(this.mBlocScratch);
+ this.mDéfinitionScratch = new MDéfinition();
+ this.mBlocScratch.ajouterDéfinition(this.mDéfinitionScratch);
+
+ /* this.scratch = new MDéfinition(); // this.scratch.bloc == null; */
+ this.barreOutils = new MBarreOutils();
+ this.barreOutils.monde = this;
+ this.recherche = new MRecherche();
+ this.recherche.monde = this;
+ this.log = new MLog();
+ this.log.monde = this;
}
function VMonde(appendToElement) {
@@ -52,23 +81,29 @@ function VMonde(appendToElement) {
.appendTo(appendToElement)));
this.vBarreOutils = null;
- this.vLog = null;
this.vScratch = this.find('.scratch');
+
+ this.ajoutVDéfinition = function(vTitreDéfinition, vCorpsDéfinition) {
+ this.vScratch.replaceWith(vCorpsDéfinition);
+ this.vScratch = vCorpsDéfinition;
+ }
}
function CMonde(mMonde, appendToElement) {
this.modèle = mMonde;
this.vue = new VMonde(appendToElement, mMonde);
this.vue.vBarreOutils = new CBarreOutils(this.modèle.barreOutils, this.vue);
- //this.vue.vLog = new CLog(this.modèle.log, this.vue);
var that = this;
- this.modèle.scratch.onAjoutInstanceBloc(function(instanceBloc) {
- var cib = new CInstanceBloc(instanceBloc, that.vue.vScratch);
- });
+
+ CDéfinition(this.modèle.mDéfinitionScratch, this.vue);
this.modèle.onAjoutInstanceLog(function (instanceLog) {
var cil = new CInstanceLog(instanceLog, that.vue);
});
+
+ this.modèle.onAjoutInstanceRecherche(function (instanceRecherche) {
+ var cil = new CInstanceRecherche(instanceRecherche, that.vue);
+ });
}
diff --git a/jside3/mvc/recherche.js b/jside3/mvc/recherche.js
@@ -0,0 +1,23 @@
+function MRecherche() {
+ $.extend(this, {
+ uid: singleton.uid(),
+
+ // Parents
+ monde: null,
+
+ // Enfants
+
+ // Instanciation
+ instances: [],
+ demanderInstance: function() {
+ var mir = new MInstanceRecherche();
+ mir.recherche = this;
+ this.instances.push(mir);
+ return mir;
+ },
+
+ // Ajout
+
+ // Évènements
+ });
+}
diff --git a/jside3/mvc/resultat-recherche.js b/jside3/mvc/resultat-recherche.js
@@ -0,0 +1,72 @@
+function MRésultatRecherche() {
+ $.extend(this, {
+ objet: null,
+ html: "",
+ score: 0,
+ position: null,
+ mInstanceRecherche: null
+ });
+}
+
+function VRésultatRecherche(vInstanceRechercheParente, position) {
+ var vrr = $('#vue-résultat-recherche').jqote({}).toDom();
+ vInstanceRechercheParente.ajoutVRésultatRecherche(vrr, position);
+ $.extend(this,vrr);
+
+ this.vTexte = this.find('.résultat-recherche.vTexte');
+ this.vUid = this.find('.résultat-recherche.vUid');
+
+ var that = this;
+ this.animAjout = function() {
+ that.addClass("ajout")
+ .delay(2000)
+ .queue(function(next){
+ that.removeClass("ajout", 1000);
+ next();
+ });
+ };
+
+ this.animSuppression = function() {
+ that.addClass("suppression", 500)
+ .height(that.height) // hauteur fixée
+ .animate({height: 0, opacity: 0}, 500, function() {
+ that.suppression(false);
+ });
+ };
+
+ this.suppression = function(anim) {
+ if (anim) { return this.animSuppression(); }
+ this.remove();
+ }
+}
+
+function CRésultatRecherche(mRésultatRecherche, vInstanceRechercheParente) {
+ this.vue = new VRésultatRecherche(vInstanceRechercheParente, mRésultatRecherche.position);
+ this.setModèle = function(mRésultatRecherche) {
+ this.modèle = mRésultatRecherche;
+ this.vue.vTexte.html(this.modèle.html);
+ this.vue.vUid.text(this.modèle.uid);
+ }
+
+ var that = this;
+ this.vue.toggle(function() {
+ that.modèle.mInstanceRecherche.ajouterRésultatSélection(that);
+ }, function() {
+ that.modèle.mInstanceRecherche.supprimerRésultatSélection(that);
+ });
+
+ this.ajoutSélection = function() {
+ this.vue.addClass('sélectionné');
+ };
+
+ this.suppressionSélection = function() {
+ this.vue.removeClass('sélectionné');
+ };
+
+ this.suppression = function(anim) {
+ that.modèle.mInstanceRecherche.supprimerRésultatSélection(that);
+ that.vue.suppression(anim);
+ }
+
+ this.setModèle(mRésultatRecherche);
+}
+\ No newline at end of file
diff --git a/jside3/style.css b/jside3/style.css
@@ -3,6 +3,10 @@
overflow: hidden;
}
+.clearfloat {
+ clear: both;
+}
+
body {
cursor: default;
position:absolute;
@@ -28,7 +32,78 @@ body {
left: 100px;
border: thin solid blue;
- background-color: lightblue;
+ background-color: white;
+}
+
+/* Recherche */
+.recherche.fenetre {
+ position: absolute;
+ bottom: 250px;
+ right: 100px;
+ width: 15em;
+ min-width: 4em;
+ min-height: 3em;
+ height: 8em;
+
+ border: thin solid blue;
+ background-color: white;
+}
+
+.recherche.résultats {
+ position: absolute;
+ top: 1.4em;
+ bottom: 0;
+ width: 100%;
+ overflow: auto;
+}
+
+.recherche.termes {
+ float: right;
+}
+
+/* Résultat-recherche */
+.résultat-recherche:hover {
+ /* Doit être plus important que les flashouillages
+ * rouges et verts */
+ background-color: #eee !important;
+}
+
+.résultat-recherche.sélectionné {
+ background-color: lightgray; !important;
+}
+
+.résultat-recherche.ajout {
+ background-color: lightgreen;
+}
+
+.résultat-recherche.suppression {
+ background-color: pink;
+ overflow: hidden;
+}
+
+.résultat-recherche.vUid {
+ display: block;
+ font-size: small;
+ color: gray;
+ padding-right: 0.2em;
+ float: right;
+}
+
+.résultat-recherche .occurence {
+ color: green;
+ font-weight: bold;
+}
+
+.résultat-recherche .superposée {
+ color: orange;
+ font-weight: bold;
+}
+
+.résultat-recherche .superposition {
+ /* Yeah, sorry, that character is overlapped by
+ two or more matches. Want some chocolate ? */
+ color: chocolate;
+ font-weight: bold;
}
/* Log */
@@ -61,8 +136,8 @@ body {
float: right;
}
-/* Bloc */
-.bloc.fenetre {
+/* Instance-bloc */
+.instance-bloc.vMain {
position: absolute;
top: 250px;
left: 300px;
@@ -75,23 +150,22 @@ body {
background-color: white;
}
-.bloc.titre {
- background-color: lightgray;
- border: medium solid white;
-}
-
-.bloc.titre {
+.instance-bloc.vBarre-titre {
background-color: lightgray;
border: medium solid white;
border-bottom: none;
}
-/* Tabs */
-.bloc.tabs.titres {
+.instance-bloc.vDéfinitions {
position: absolute;
top: 1.4em;
left: 0;
right: 0;
+ bottom: 0;
+}
+
+/* Définitions (Tabs) */
+.définitions.vTitresTabs {
background: lightgray;
padding-bottom: 0;
@@ -99,23 +173,11 @@ body {
border-style: none solid none solid;
}
-.définition.titre {
- background-color: white;
- border: thin solid gray;
- margin: 0.1em 0.1em 0 0;
- float: left;
-}
-
-.définition.titre.active {
- background-color: #eee;
- border-bottom: thin solid white;
-}
-
-.nouvelle-définition {
+.définitions.vNouvelle-définition {
float: right;
}
-.définitions {
+.définitions.vContenusTabs {
position: absolute;
top: 2.9em;
left: 0;
@@ -125,18 +187,39 @@ body {
padding-bottom: .1em;
}
-/* Définitions */
-.définition.contenu {
+/* Définition */
+.définition.vTitre {
+ background-color: white;
+ border: thin solid gray;
+ margin: 0.1em 0.1em 0 0;
+ float: left;
+}
+
+.définition.vTitre.active {
+ background-color: #eee;
+ border-bottom: thin solid white;
+}
+
+.définition.vCorps {
height: 100%;
}
-.définition.contenu.aucune-définition {
+.définition.vCorps.vAucune-définition {
text-align: center;
padding-top: 1em;
}
+/* Zone */
+.vZone {
+ position: absolute;
+ border: thin solid blue;
+ background-color: lightblue;
+ opacity: 0.5;
+}
+
/* Fenêtres */
-.barre-titre {
+.barre-titre,
+.vBarre-titre{
background-color: #eef;
border-bottom: thin solid blue;
padding: .1em;
@@ -144,7 +227,8 @@ body {
text-align: center;
}
-h2.titre {
+h2.titre,
+h2.vTitre {
font-size: 100%;
margin: 0;
}