Réaliser un layout complexe en CSS n’est pas chose facile. La librairie WPF de Microsoft, disponible sous .NET, permet de décrire les UI avec un langage balisé XML. Les concepteurs de cette librairie proposent des contrôles « panneaux » (comme des éléments en HTML) dont le propos est de spécifier la disposition des élements de l’UI (d’autres panneaux,des textes,des images,etc…).
Les propriétés de ces contrôles orientent l’UI designer vers d’autres paradigmes de spécification de disposition d’élements, qui romp avec le modèle de contrôle de flux de présentation propre à CSS.
Faire un portage en HTML/Javascript de ces contrôles permet dans une page WEB de disposer les éléments HTML d’une manière plus simple qu’en CSS. En s’appuyant sur les capacités natives de HTML/CSS, on limite la quantité de code nécessaire pour gérer les contrôles, et les nouveaux éléments sont proches des standards W3C (respect de la sémantique et de l’accessibilité).
Cet article présente la librairie Javascript wpanels.js.
wpanels est un ensemble d’élements HTML et de classes javascript qui offre le portage de contrôles WPF de disposition ainsi que d’autres contrôles de disposition étendus.
I. Les panneaux de WPF et leurs principales propriétés
I.1. les contrôles de panneau
Le tableau suivant recence les panneaux de WPF. Le Canvas panel est écarté de la liste car il se présente comme un clone de son homologue HTML
contrôle | description |
---|---|
Stack Panel | dispose les élements les uns à la suite des autres ou les uns en dessous des autres. s’agrandit avec le contenu |
Wrap Panel | comme le StackPanel, mais gère le wrapping des élements sur plusieurs lignes. ne s’agrandit pas avec le contenu |
Dock Panel | panneau de layout, fournit des docks en haut, à guauche, à droite et en bas de la zone remplie par le panneau. La partie centrale reçoit un élement qui remplit automatiquement la surface. les docks s’agrandissent avec le contenu, le panel non |
Grid Panel | panneau de layout. arrange ses élements dans une structure de tableau de lignes et de colonnes. similaire à son homologue html, mais offre plus de possibilités: plusieurs éléments dans une cellule les uns par dessus les autres, des élements qui peuvent s’étaler sur plusieurs lignes et/ou plusieurs colonnes, et les propriétés de disposition propres aux contrôles wpf. C’est de loin le plus puissant et le plus utilisé des paneaux wpf |
I.2. les propriétés de disposition
Les contrôles WPF possèdent tous les propriétés de disposition communes:
propriété | description |
---|---|
width, height | la taille peut être fixe (par défaut valeur en pixel, l’unité peut être précisée parmi: px, in, cm, pt) ou automatique (le contrôle adapte sa taille à son contenu, valeur: Auto, casse insensible). pour wpf la vtaille de pixel est indépendante du périphérique et vaut 1 / 96 inch par unit |
minWidth, minHeight | taille minimale adoptable par le contrôle. Mêmes syntaxes que width, height |
maxWidth, maxHeight | taille maximale adoptable par le contrôle. Mêmes syntaxes que width, height |
horizontalAlignment | indique comment le contrôle est docké horizontalement dans son container. les valeurs possibles sont Left, Center, Right, Stretch. Stretch induit le comportement de taille auto sur le contrôle (s’agrandit à la taille du conteneur) sinon le contrôle est adapté à la taille de son contenu. noter que cette propriété peut contredire la propriété width. C’est celle-ci qui l’emporte |
verticalAlignment | indique comment le contrôle est docké verticalement dans son container. les valeurs possibles sont Top, Center, Bottom, Stretch. noter que cette propriété peut contredire la propriété height. C’est celle-ci qui l’emporte |
margin | la marge est l’espace supplémentaire à l’extérieur du contrôle. la valeur d’une marge est une grandeur fixe |
padding | le padding est l’espace supplémentaire à l’intérieur du contrôle. la valeur d’un padding est une grandeur fixe |
et les contrôles possédant un contenu ont également les propriétés suivantes :
propriété | description |
---|---|
horizontalContentAlignment | comme horizontalAlignment, donne la disposition du contenu du contôle par rapport à celui-ci |
verticalContentAlignment | comme verticalAlignment et même effet que horizontalContentAlignement |
pour bien comprendre l’effet des propriétés d’alignment horizontal et vertical, regardez le schéma suivant :
II. Portage vers html/js : cas du Grid
Le Grid étant le panneau de layout le plus complexe, il sert de cas d’école pour l’élaboration des nouveaux contrôles html et de leur mode de gestion
II.1. Les propriétés de conteneur
Des propriétés permettent de déclarer chaque colonne et chaque ligne de la grille et d’en spécifier la taille (ou le comportement de taille).
Ces propriétés sont décrites par les propriétés de collection RowDefinitions et ColumnDefinitions, qui reçoivent des items de type respectivement RowDefinition et ColumnDefinition.
Les tailles de ligne et de colonnes (GridLength) peuvent être définies comme une quantité absolue, un pourcentage ou une taille automatique :
type valeur | description |
---|---|
auto | ajusté à la taille du contenu |
fixed | taille fixe (valeur: nombre). Le débordement est clippé |
star | étoile (valeur: *). La taille est augmentée pour occuper tout l’espace disponible, obtenu après que toutes les tailles auto et fixées ont été définies. si il y a plusieurs lignes/colonnes de taille *, l’espace disponible est partagé de manière proportionelle. La valeur de proportionalité peut être définie sur la taille en indiquant un nombre avant l’étoile. Par exemple 2* et 8* , sont identiques à 20* et 80* indiquent les proportionalités de 20% et de 80%. La proportionalité de taille ne peut être appliqué que si le Grid n’a pas une taille définie sur auto (ajustement a la taille du contenu) |
II.2. Portage de la syntaxe XAML vers HTML
Un Grid se décrit de la manière suivante en XAML :
<Grid Width="auto" MinWidth="100" MinHeight="100" MaxWidth="800" MaxHeight="600" HorizontalAlignment="Left" VerticalAlignment="Stretch" ShowGridLines="true" > <!-- rows definitions : 4 rows --> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="120"/> <RowDefinition Height="4*"/> <RowDefinition Height="6*"/> </Grid> <!-- columns definitions : 2 columns --> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"/> <ColumnDefinition Width="auto"/> </Grid> <!-- grid content --> <Label Grid.Row="0" Grid.Column="0" Background="Yellow" > cell 1,1 </label> <label Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2" Background="Cyan" > cell 1,1 to 2,2 </label> </Grid>
Cette définition de grid produit le résultat suivant dans une fenêtre WPF :
L’objectif des nouveaux élements wpanels est de permettre de mixer les élements courants de HTML et les panneaux de layout. On va donc introduire dans html de nouveaux tags et enrichir les élements existants de nouveaux attributs. Certains attributs existants (communs avec WPF, par exemple width et height) pourront être réutilisés avec une sémantique des valeurs enrichie. Les choix de syntaxe sont les suivants :
syntaxe | description |
---|---|
tags | les tags ajoutés à html sont des noms composés (norme), avec le préfixe wp, le nom des ces nouveaux tags reprend les noms des classes WPF avec lettrage en camel-case sauf la première lettre en minuscule (mix entre norme html et C#). Par exemple, wp-grid est le nom de l’élement Grid. |
attributs | les attributs ajoutés sur les nouveaux élements n’ont pas de préfixe (allégement de la syntaxe), tandis que pour plus de clarté ceux qui sont ajoutés aux éléments HTML existants prennet le préfixe wp. Les noms des attributs sont écrits en camel-case sauf la première lettre en minuscule |
valeurs | de nouvelles valeurs sont ajoutées aux attributs html existants width et height, pour reprendre la syntaxe wpf: Auto (casse insensible). Les valeurs html natives sont toujours autorisées et permettent d’augmenter les possibilités prévues par wpf. Pour les éléments wp-columnDefinition et wp-rowDefinition, les attributs width et height n’acceptent que les syntaxes wpf (*, n*, auto, Auto, n avec n une valeur numérique). Les valeurs mot clefs sont analysées indépendemment de la casse |
exemple précédent dans la syntaxe wpanels :
<wp-grid width="auto" minWidth="100" minHeight="100" maxWidth="800" maxHeight="600" horizontalAlignment="left" verticalAlignment="stretch" showGridLines="true"> <!-- rows definitions --> <wp-rowDefinitions> <wp-rowDefinition height="auto"/> <wp-rowDefinition height="120"/> <wp-rowDefinition height="4*"/> <wp-rowDefinition height="6*"/> </wp-rowDefinitions> <!-- columns definitions --> <wp-columnDefinitions> <wp-columnDefinition width="auto"/> <wp-columnDefinition width="auto"/> </wp-columnDefinitions> <!-- content --> <span wp-row="0" wp-column="0" style="background-color:yellow"> cell 1,1 </span> <span wp-row="1" wp-column="1" wp-rowSpan="2" wp-colSpan="2" style="background-color:cyan"> cell 1,1 to 2,2 </span> </wp-grid>
II.3. Portage des propriétés de disposition en CSS/JS
élement | propriété | mise en oeuvre |
---|---|---|
WPanel (FrameworkElement) | élément | traduit par un HTMLElement, display: block. racine de tous les élements qui fabriquent le contrôle. |
width | • taille fixe en pixels: supporté tel quel par l’élément html. si la propriété width est réglée en taille fixe, un réglage de horizontalAlignement à Stretch sera ignoré. l’attribut doit être omis pour ne pas empêcher Stretch sur horizontalAlignment (width à la précédence). • la valeur auto entraîne le retrait de l’attribut width et annule l’effet de Stretch sur horizontalAlignment • l’abscence de l’attribut entraîne auto par défaut |
|
height | similaire à width | |
minWidth | largeur minimale souhaitée (valeur fixe). l’ordre de précédence est minWidth,maxWidth,width | |
minHeight | hauteur minimale souhaitée | |
maxWidth | largeur maximale souhaitée | |
maxHeight | hauteur maximale souhaitée | |
horizontalAlignment | • left : pour rester compatible avec le placement de l’élément dans le flôt de document (ex: float:left), le positionnement left est géré par js • right : similaire à left • center : similaire à left • stretch : l’agrandissment automatique est géré par js. la taille de l’élément est étendue jusqu’a ce que sont conteneur ou l’élément lui même si il n’est pas dans un conteneur jusqu’à recouvrir l’espace disponible (vers la droite jusqu’à l’élément visuellement à droite) |
|
verticalAlignment | similaire en tous points à horizontalAlignment | |
horizontalContentAlignment | left : les éléments dans le conteneur sont alignés à gauche de celui-ci selon la nature du container right : les éléments dans le conteneur sont alignés à droite de celui-ci selon la nature du container center : les éléments dans le conteneur sont alignés au centre de celui-ci selon la nature du container stretch : les éléments dans le conteneur sont étirés horizontalement dans celui-ci selon la nature du container |
|
verticalContentAlignment | similaire à horizontalContentAlignment |
élément | propriété | mise en oeuvre |
---|---|---|
Grid | représenté par le HTMLElement wp-grid qui contient un élément de type table ou div(display:table) | |
contenu de Grid | wp-row | valeur numérique >=0 <nbRows, l’élément est transféré dans l’élément cellule td ou div(display:table-cell) correspondant |
wp-column | valeur numérique >=0 <nbCols, l’élément est transféré dans l’élément cellule correspondant | |
wp-rowSpan | l’élément doit flotter au dessus des lignes recouvertes, sa hauteur est calculée par js | |
wp-colSpan | l’élément doit flotter au dessus des colonnes recouvertes, sa largeur est calculée par js |
à suivre…