code source htmlRé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 :
wpf alignments

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 :

wpf grid

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…

à lire également :