Cette section va décrire l'objet de boîte d'arbre qui est utilisé pour gérer l'affichage d'un arbre.
À propos de l'objet de boîte
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
.
Rafraichissement de l'arbre
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.
Défilement de l'arbre
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>
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'.
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.
Coordonnées d'une cellule
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.
- La fonction
getCellAt()
peut être utilisée pour obtenir une cellule précise située à un emplacement défini en pixels, - La fonction
getRowAt()
peut être utilisée pour obtenir une ligne à un emplacement défini lui aussi en pixels. La fonctiongetRowAt()
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 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 (column.value && typeof column.value != "string") column.value = column.value.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="utensil" label="Ustensiles" primary="true" flex="1"/> <treecol id="count" 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.
Interwiki