Écrit par Neil Deakin
,
mise à jour par les contributeurs à MDC
.
Traduit par Alain B. (04/04/2007).
Page originale :
http://developer.mozilla.org/en/docs/XUL_Tutorial/Tree_Box_Objects
Attention : Ce tutoriel est ancien et n'est pas mis à jour. Bien que beaucoup d'informations soient encore valables pour les dernières versions de gecko, beaucoup sont aussi obsolètes. Il est préférable d'aller consulter cette page sur la version française de ce tutoriel sur developer.mozilla.org.
Cette section va décrire l'objet de boîte d'arbre qui est utilisé pour gérer l'affichage d'un arbre.
Les objets de boîte ont été décrits dans une section précédente. L'objet de boîte d'arbre est
un objet de boîte spécial utilisé spécifiquement pour les arbres (tree). La boîte d'arbre implémente l'interface
TreeBoxObject
.
Nous avons déjà vu la fonction rowCountChanged()
de l'objet de boîte d'arbre dans
la section précédente. Elle est employée pour indiquer qu'une ou plusieurs lignes de l'arbre ont
été ajoutées ou enlevées. L'arbre rafraîchira l'affichage de la zone affectée. Vous n'avez pas
besoin d'appeler la fonction rowCountChanged()
lorsqu'une ligne a simplement été
modifiée, comme par exemple lors du changement du libellé d'une cellule. Dans ce cas, d'autres
fonctions d'affichage peuvent être utilisées. La plus simple est la fonction invalidateRow()
qui rafraîchit l'affichage d'une ligne spécifique d'un arbre. L'arbre appellera la vue pour obtenir
les données mises à jour et actualise son contenu à l'écran.
Les autres fonctions de rafraichissement sont :
invalidateCell()
pour le rafraichissement d'une unique cellule,invalidateColumn()
pour le rafraichissement d'une colonne,invalidateRange()
pour le rafraichissement d'une plage de lignes,invalidate()
pour le rafraichissement de l'arbre entier.Notez que le rafraichissement de l'affichage n'aura lieu qu'une fois les tâches des scripts achevées, car Mozilla n'effectue pas cette opération en tâche de fond.
Vous pouvez également faire défiler l'arbre en utilisant quatre méthodes différentes, similaires à
celles disponibles pour les menus déroulants. La fonction scrollToRow()
peut être utilisée
pour faire le défilement jusqu'à une ligne particulière. Voici un exemple simple :
<script>
function doScroll()
{
var value = document.getElementById("tbox").value;
var tree = document.getElementById("thetree");
var boxobject = tree.boxObject;
boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
boxobject.scrollToRow(value);
}
</script>
<tree id="thetree" rows="4">
<treecols>
<treecol id="row" label="Ligne" primary="true" flex="1"/>
</treecols>
<treechildren>
<treeitem label="Ligne 0"/>
<treeitem label="Ligne 1"/>
<treeitem label="Ligne 2"/>
<treeitem label="Ligne 3"/>
<treeitem label="Ligne 4"/>
<treeitem label="Ligne 5"/>
<treeitem label="Ligne 6"/>
<treeitem label="Ligne 7"/>
<treeitem label="Ligne 8"/>
<treeitem label="Ligne 9"/>
</treechildren>
</tree>
<hbox align="center">
<label value="Défile jusqu'à la ligne :"/>
<textbox id="tbox"/>
<button label="Défile" oncommand="doScroll();"/>
</hbox>
Notez que nous utilisons l'attribut rows
sur
l'élément tree
pour spécifier que quatre lignes seulement doivent être affichées à la fois. Ainsi, il est plus facile
de se représenter l'exemple. Notez également que la première ligne commence à 0.
La fonction doScroll()
récupère l'objet de boîte et appelle la fonction scrollToRow()
avec comme argument la valeur saisie dans le champ texte. Vous noterez que l'objet de boîte
d'arbre peut être obtenu de la même manière qu'avec d'autres objets de boîte, en utilisant la
propriété boxObject
. Nous devons cependant appeler QueryInterface()
pour invoquer l'objet de boîte spécifique aux arbres. Les fonctions générales
de l'objet de boîte sont également disponibles pour les arbres.
Les méthodes supplémentaires de défilement incluent les fonctions scrollByLines()
,
scrollByPages()
, et ensureRowIsVisible()
.
la fonction scrollByLines()
fait défiler vers le haut ou vers le bas d'un certain nombre de lignes ; un nombre positif
fait défiler vers le bas, un nombre négatif fait défiler vers le haut. La fonction
scrollByPages()
fait défiler d'un certain nombre de pages. Elle est automatiquement appelée
lorsque l'utilisateur appuie sur une des touches Page Up ou Page Down et que l'arbre a le focus. Une page est égale au nombre de lignes visibles. Par exemple, si un arbre
affiche 10 lignes en même temps, une page sera équivalente à 10 lignes. C'est une méthode pratique
dès lors que l'utilisateur redimensionne un arbre flexible : la taille de la page augmentera ou
diminuera automatiquement sans avoir à la recalculer manuellement. Il n'est pas trop difficile
de calculer cette taille manuellement car l'objet de boîte d'arbre fournit également une fonction
getPageLength()
qui retourne le nombre de lignes dans une page. Dans l'exemple de
défilement ci-dessus, getPageLength()
retournerait 4.
Notez que dans Firefox 1.0 et Mozilla 1.7, et les versions plus récentes, la
fonction getPageLength()
est plutôt appelée getPageCount()
. Le nom a été
changé en getPageLength()
afin d'éviter les confusions avec une fonction qui ne
retourne pas le nombre de pages d'un arbre, mais la taille de chaque page. Vous pouvez déterminer
le nombre de pages en divisant le nombre total de lignes par la taille d'une page.
La fonction ensureRowIsVisible()
fera défiler l'arbre jusqu'à une ligne, comme avec
la fonction scrollToRow()
, mais seulement si la ligne n'est pas visible au moment de l'appel.
Certaines des fonctions les plus intéressantes d'un objet de boîte d'arbre sont utilisées pour obtenir les parties d'un arbre se trouvant à des coordonnées spécifiques et vice versa.
getCellAt()
peut être utilisée pour obtenir une cellule précise située à un emplacement défini en pixels,getRowAt()
peut être utilisée pour obtenir une ligne à un
emplacement défini lui aussi en pixels. La fonction getRowAt()
prend deux arguments
qui sont les coordonnées horizontales (x) et verticales (y).tree.boxObject.getRowAt( 50, 100 );
Cet exemple retournera l'index de la ligne ayant une position horizontale de 50 pixels et verticale de 100 pixel. Naturellement, la coordonnée x semble ne pas avoir beaucoup de sens dès lors que la ligne occupe tout l'espace horizontal de l'arbre.
Il est important de noter que les coordonnées sont mesurées à partir du coin supérieur gauche du document et non de l'arbre lui-même.
Il est donc facile de passer à ces fonctions les coordonnées événementielles
de l'objet event
, comme avec la fonction getCellAt()
dans l'exemple suivant.
<script>
function updateFields(event)
{
var row = {}, column = {}, part = {};
var tree = document.getElementById("thetree");
var boxobject = tree.boxObject;
boxobject.QueryInterface(Components.interfaces.nsITreeBoxObject);
boxobject.getCellAt(event.clientX, event.clientY, row, column, part);
if (typeof column.value != "string") column.value = column.id;
document.getElementById("row").value = row.value;
document.getElementById("column").value = column.value;
document.getElementById("part").value = part.value;
}
</script>
<tree id="thetree" flex="1" onmousemove="updateFields(event);">
<treecols>
<treecol id="ustensile" label="Ustensiles" primary="true" flex="1"/>
<treecol id="nombre" label="Nombre" flex="1"/>
</treecols>
<treechildren>
<treeitem>
<treerow>
<treecell label="Fourchette"/>
<treecell label="5"/>
</treerow>
</treeitem>
<treeitem>
<treerow>
<treecell label="Couteau"/>
<treecell label="2"/>
</treerow>
</treeitem>
<treeitem>
<treerow>
<treecell label="Cuillère"/>
<treecell label="8"/>
</treerow>
</treeitem>
</treechildren>
</tree>
<label value="Ligne:"/>
<label id="row"/>
<label value="Colonne:"/>
<label id="column"/>
<label value="Type enfant:"/>
<label id="part"/>
La fonction getCellAt()
prend cinq arguments, les coordonnées où regarder
et trois autres paramètres. Un argument par référence est utilisé parce que la fonction a
besoin de retourner plusieurs valeurs. Vous verrez de nombreuses interfaces utilisant des
arguments par référence avec
les objets disponibles.
Ces arguments sont marqués avec un préfixe 'out'. Pour ceux-ci, vous devez transmettre un
objet vide et la fonction remplira sa propriété value
avec
la valeur adéquate.
Les trois paramètres par référence seront renseignés avec la ligne, la colonne et le
type enfant. L'objet row contient l'index de la ligne survolée par la souris au moment
où la fonction a été appelée par un événement mousemove, avec les coordonnées de cet événement.
Si les coordonnées ne sont pas au-dessus d'une ligne de l'arbre, la valeur row.value
sera égale à -1. La variable column est un objet column
tel que
défini dans Mozilla 1.8 et supérieur.
Dans les versions plus anciennes, les colonnes étaient identifiées avec une chaîne de
caractères (string) : l'identifiant id
de la colonne. Avec les versions
plus récentes, un objet de colonne spécifique existe et permet de réaliser des requêtes sur les données en colonne.
La ligne suivante est utilisée pour que l'exemple ci-dessus puisse fonctionner avec toutes les versions.
if (column.value && typeof column.value != "string")
column.value = column.value.id;
Si la colonne est une chaîne de caractères, nous tournons sur Mozilla 1.7 ou inférieur, mais pour les versions récentes, nous obtenons l'identifiant de la colonne à partir de l'objet column. Si vous écrivez du code pour des versions multiples, vous devrez effectuer un test comme indiqué ci-avant.
Le dernier argument de la fonction getCellAt()
est le type enfant renseigné
avec une chaîne dépendante de la partie de la cellule pointée par les coordonnées. Si vous
déplacez la souris dans l'exemple précédent, vous noterez que le libellé passe de text
à cell. La valeur text indique la zone où le texte est dessiné et la
valeur cell indique la zone autour du texte ; par exemple, la marge gauche où
sont habituellement dessinées les poignées ouvrantes et fermantes. Toutefois, s'il y avait
une poignée, la valeur aurait plutôt été twisty. Cette information pratique
permet de déterminer si l'utilisateur a cliqué sur une poignée plutôt que sur
une autre partie de la ligne. En fait, lorsque l'utilisateur double-clique sur la poignée,
le code natif sous-jacent utilise cette méthode. La dernière valeur qui peut être retournée
est image si une image se trouve dans la cellule et que les coordonnées correspondent
à celles de cette image. Bien entendu, dans la plupart des cas, vous ne désirez pas connaître
quelle partie de la cellule pointe les coordonnées, mais seulement la ligne et la colonne concernées.
Pour inverser la recherche et obtenir les coordonnées spécifiques d'une cellule, utilisez la
fonction getCoordsForCellItem()
. Elle prend sept arguments tels que décrits ci-dessous.
var x = {}, y = {}, width = {}, height = {};
if (typeof tree.columns != "undefined") column = tree.columns[column];
tree.boxObject.getCoordsForCellItem( row, column, part, x, y, width, height );
Les arguments 'row', 'column' et 'part' sont similaires à ceux retournés par la fonction
getCellAt()
. De nouveau, le type de l'argument 'column' dépend de la version que vous utilisez, soit une chaîne de caractères (string),
soit un objet column. Le type de la zone de la cellule
peut être utilisé pour obtenir les coordonnées, soit du texte, soit de toute la cellule, soit de la
poignée, soit de l'image dans la cellule. Les mêmes valeurs que la fonction getCellAt()
sont utilisées. La fonction getCoordsForCellItem()
retourne par le biais des arguments
passés en référence les coordonnées horizontales (x) et verticales (y), accompagnées de la largeur et la hauteur.
Par la suite, nous verrons comment RDF peut être utilisé automatiquement pour peupler des arbres et d'autres éléments.
Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™
sont des marques de la fondation Mozilla.