Developpez.com - 4D
X

Choisissez d'abord la catégorieensuite la rubrique :


Redimensionnements complexes des formulaires

Date de publication : Mars 2003

Par Roland LANNUZEL (Marketing Technique 4D S.A.)
 

Cette note technique propose une méthode qui permet d’effectuer toutes sortes de déplacements et de redimensionnements et de les combiner entre eux, et ce de façon simple et logique.

I. Introduction
II. Déplacements ou agrandissements
III. Ce que l’homme(*) veut...
IV. Le zoom parfait ?
V. Mise en pratique dans un exemple
VI. "En deux temps, 'n' mouvements"
VII. Contrôle de la taille de la fenêtre
VIII. Conclusion
IX. Base exemple


I. Introduction

La plupart des formulaires de saisie sont redimensionnables, que ce soit pour afficher davantage d'informations, plus de texte ou plus d'éléments dans une liste par exemple, ou bien pour afficher ces mêmes informations en plus grand (ou plus petit) afin de s'adapter aux besoins de l'utilisateur.

4ème Dimension offre directement la possibilité, sans programmation, d'agrandir ou bien de déplacer des objets. Cependant, ces options sont parfois insuffisantes et il faut recourir à la programmation et utiliser les commandes de déplacement des objets.

Cette note technique propose une méthode qui permettra d'effectuer toutes sortes de déplacements et de redimensionnements et de les combiner entre eux, et ce de façon relativement simple et logique.


II. Déplacements ou agrandissements

Entre ce qui semble naturel d'un point de vue humain et logique de celui de l'ordinateur il y a une marge dont tout le monde a fait l'expérience plus ou moins douloureuse. Le redimensionnement des objets n'échappe pas à la règle. En effet, si deux objets sont côte à côte et que le développeur souhaite les voir s'agrandir tous les deux lorsque l'on agrandit la fenêtre, il aura pris soin de cliquer sur le bouton " agrandir " pour chacun des objets. L'ordinateur exécutera la demande à la lettre, les deux objets s'agrandiront… et l'objet de gauche débordera sur l'objet de droite ! " Logiquement ", le développeur pensait que l'objet de droite serait " poussé " et que l'espacement entre les deux objets serait respecté.

Que faire alors ? Eh bien il suffit de cliquer " agrandir " sur l'objet de gauche et " déplacer " sur celui de droite, ou bien n'autoriser que l'objet de droite à grandir et laisser celui de gauche tel quel.

Cette solution est parfois suffisante, mais forcément frustrante car, dans un cas comme dans l'autre, l'utilisateur n'a pas ce qu'il souhaitait au départ.


III. Ce que l’homme(*) veut...

(*) Dans le sens "humain", que les femmes ne se sentent pas exclues !

Quand on agrandit une fenêtre, la place gagnée (en hachuré dans le graphique ci-dessous) devrait être répartie entre les objets de façon uniforme. Autrement dit, si un formulaire contient 4 objets côte à côte, ils devront chacun s'agrandir de 25 % de ce que la fenêtre a gagné en largeur (et non pas 25% de leurs propres tailles), et, bien entendu, se déplacer d'autant que son voisin de gauche s'est agrandi (et déplacé !), afin de ne pas être "mordus".

Pictures 0641x0174


Que s'est-il passé exactement ?

L'objet rose s'est agrandi de 25% et n'a pas bougé.

L'objet bleu s'est agrandi de 25% et à bougé de 25% (25% = agrandissement + déplacement de l'objet rose)

L'objet vert s'est agrandi de 25% et à bougé de 50% (50% = agrandissement + déplacement de l'objet bleu)

L'objet jaune s'est agrandi de 25% et à bougé de 75% (75% = agrandissement + déplacement de l'objet vert)

25% c'est 100 (pourcentage à répartir) divisé par 4 (nombre de d'objets). Cela est vrai dans cet exemple car les objets sont de taille identique, mais dans le cas ou les objets sont différents, la répartition du pourcentage pourra être différente de façon à ce que l'aspect général reste inchangé, quelle que soit la taille des objets et des espaces qui les séparent.


Les objets ont des tailles différentes

Avant de poursuivre, précisons que ce que nous expliquons s'applique à la largeur des objets, mais serait, bien entendu, applicable à leur hauteur. De même, en ce qui concerne l'agrandissement des fenêtres, le raisonnement reste vrai lorsque la taille de celles-ci diminue.

Dans l'exemple ci-dessous, l'objet rose occupe 50% de la largeur de la fenêtre et les deux autres 25% ; Il est donc logique qu'il occupe toujours 50% de la largeur quand la fenêtre sera agrandie. Pour cela, il faut donc qu'il gagne en largeur 50% de la surface gagnée, les deux autres objets se contentant de 25% chacun (Cela dit, la souplesse de la solution que nous allons mettre en place permettra d'en décider tout autrement, et de faire en sorte que les proportions changent du tout au tout… mais cela reste au choix du programmeur en concertation avec les utilisateurs).

Pictures 0640x0180


Et les marges ? Et les espaces entre les objets ?

Tout ce que nous avons dit plus haut reste vrai. Le graphique ci-dessous devrait vous en convaincre. Si on applique exactement les mêmes répartitions, on obtient exactement les mêmes résultats. En effet, c'est toujours la largeur gagnée qui est répartie, il est donc normal que les intervalles restent les mêmes...

N.B. les marges sont plus importantes que les intervalles entre les objets… ces espaces ne sont absolument pas modifiés après modification de la taille de la fenêtre.

Pictures 0637x0178


IV. Le zoom parfait ?

Un agrandissement vraiment " naturel " agrandirait les objets et également les espaces entre ces objets et ce de façon exactement proportionnelle à leur occupation dans la fenêtre d'origine. Dans la réalité, l'effet visuel est généralement plus important que la justesse, c'est pourquoi, il est inutile de mesurer les objets un par un afin de leur affecter très précisément un coefficient d'agrandissement. La seule chose réellement importante, c'est que la somme de ces coefficients fasse exactement 100%, il faut donc bien définir ce que l'on souhaite avant de se lancer dans des paramétrages hasardeux.


Reprenons l'exemple précédent :

Nous désirons cette fois augmenter la taille des objets et des espaces.

Pictures 0538x0092


Que constatons nous ?

- L'objet Rose est deux fois plus grand que l'objet bleu et que l'objet vert
- Les marges sont à peu près trois fois plus larges que les espaces inter-objets
- Les espaces représentent grosso modo 20% de la largeur

-> La répartition se fera donc grosso modo à 20% pour les espaces et 80% pour les objets
-> Pour les espaces, on va prendre 6% + 2% +2% +6% = 16% (ce qui est proche de 20%)
-> Il reste donc 100-16 = 84% pour les objets soit 42% pour le rose et 21% pour les bleus et verts.


Ce qui nous donnera finalement la forme ci-dessous, visuellement et fonctionnellement acceptable :

Pictures 0638x0346


V. Mise en pratique dans un exemple

Nous voulons réaliser une calculette redimensionnable…

Pictures 0360x0429

Cet objet si familier est pourtant relativement complexe :
- Les boutons sont nombreux (17)
- Ils sont de tailles différentes ('C' et 'O' sont deux fois plus larges, '=' est deux fois plus haut)
- Les " marges " sont inégales (haut et bas)
- La taille de l'afficheur lui-même doit aussi varier… etc.

Si l'on fait le compte, cette calculatrice compte en tout 21 objets dont voici le détail :
- 17 boutons
- Un afficheur (fond jaune)
- Le résultat affiché
- Le fond gris
- L'objet de redimensionnement hachuré en bas à droite
- Un bouton invisible sur cet objet graphique

Nous allons donc devoir définir, pour chacun de ces objets les informations suivantes :
- Coordonnées d'origine (X et Y)
- Largeur et hauteur
- % de déplacement (X et Y)
- % d'agrandissement (X et Y)
... soit huit paramètres par objet.

À moins de vouloir gérer très précisément les mouvements, ces paramètres pourront être mémorisés dans des tableaux de type "entier long".

Afin de faciliter la compréhension de cette note technique, ces valeurs sont stockées dans une table et mises en tableau au moment de leur utilisation. À votre convenance, ces valeurs pourront être stockées tout autrement (directement codées, dans une méthode d'initialisation, dans une blob des données, dans des ressources, etc.)
Afin de les rendre exploitables, nous associerons à ces huit tableaux un neuvième, qui contiendra le nom de l'objet concerné.


Détails des paramètres

Il serait fastidieux de détailler toutes les valeurs, mais il ne semble pas inutile d'en commenter certaines…

Le choix fait ici est d'augmenter la taille des objets ET des espaces.

Cela apparaît clairement pour les boutons 7, 8, 9 et '-' Ils ont chacun un coefficient de 20% d'agrandissement ce qui donne un total de 80%. Les 20% restants seront répartis dans les 5 espaces, soit 4% par espace. Les espaces ne sont pas des objets et ne sont donc pas matérialisés dans la liste ci-dessous.
En revanche, on constate que le bouton '7' grandit de 20% et se déplace de 4% (L'espace à sa gauche va donc grandir).
Le bouton '8' va faire de même. Il va grandir de 20% et se déplacer de 4% PLUS le déplacement (4 %) PLUS l'agrandissement (20%) du bouton '7' situé à sa gauche, soit un total de 28%.
Il en va de même pour les boutons '9' et '-' ce qui explique la progression 4-28-52-76 des déplacements.

On peut vérifier la cohérence de tout cela :
4+20+4 = 28
28+20+4 = 52
52+20+4 = 76
76+20+4 = 100 % !

Dernier point :
On pourrait penser que le bouton 'C' qui est deux fois plus large que les autres, va s'agrandit de 40% au lieu de 20%. Ce serait oublier l'espace situé entre les autres boutons qui lui aussi grandit (de 4%). La valeur de croissance du bouton 'C' est donc de 20+20+4 = 44%.

Nous vous laissons le soin si vous le désirez d'examiner les coefficients affectés aux boutons et à l'afficheur pour le redimensionnement vertical, le principe étant strictement identique.

Pictures 0638x0589


VI. "En deux temps, 'n' mouvements"

Deux événements formulaires vont ici être traités :
   Sur chargement pour l'initialisation des tableaux et des objets, puis
   Sur redimensionnement pour les déplacements.

Une fois le paramétrage des objets effectué, la suite est très simple…


Sur chargement

      `Mémorisation des coordonnées de référence de la fenêtre
   RefWinX:=270
   RefWinY:=300

   TABLEAU ALPHA(80;_skObjectName;0)
   TABLEAU ENTIER LONG(_skLeft;0)
   TABLEAU ENTIER LONG(_skTop;0)
   TABLEAU ENTIER LONG(_skSizeX;0)
   TABLEAU ENTIER LONG(_skSizeY;0)
   TABLEAU REEL(_skMoveX;0)
   TABLEAU REEL(_skGrowX;0)
   TABLEAU REEL(_skMoveY;0)
   TABLEAU REEL(_skGrowY;0)

      `lecture des paramétrages des objets
   TOUT SELECTIONNER([Elements])
   SELECTION VERS TABLEAU([Elements]ObjectName; _skObjectName;
                                                                [Elements]TopPosition; _skTop;
                                                                [Elements]LeftPosition; _skLeft;
                                                                [Elements]SizeX; _skSizeX;
                                                                [Elements]SizeY; _skSizeY;
                                                                [Elements]MoveX; _skMoveX;
                                                                [Elements]GrowX; _skGrowX;
                                                                [Elements]MoveY; _skMoveY;
                                                                [Elements]GrowY; _skGrowY)
   $n:=Taille tableau(_skObjectName)

      `mise en place des objets sur le formulaire
   Boucle ($i;1;$n)
      DEPLACER OBJET(*;_skObjectName{$i}; _skLeft{$i}; _skTop{$i};
                                                                _skLeft{$i}+_skSizeX{$i};
                                                                _skTop{$i}+_skSizeY{$i}; *)
   Fin de boucle

      `calcul de ta taille de la police à affecter à l'afficheur et aux boutons
   LIRE RECT OBJET(*;"CalcResult";$Left;$Top;$Right;$Bottom)
   $H:=($Bottom-$Top)
   CHANGER TAILLE(*;"CalcResult";$H*0,6)
   CHANGER TAILLE(*;"bIm@";$H*0,4)


Sur redimensionnement

   COORDONNEES FENETRE($Left;$Top;$Right;$Bottom)

      `calcul du chagement de taille par rapport à la taille d'origine de la fenetre
   $DeltaX:=($Right-$left)-RefWinX
   $DeltaY:=($Bottom-$Top)-RefWinY
   $n:=Taille tableau(_skObjectName)

      `répartition des modifications sur chacun des objets
   Boucle ($i;1;$n)
      DEPLACER OBJET (*; _skObjectName{$i}; _skLeft{$i}+(_skMoveX{$i}*$DeltaX/100);
                                                                _skTop{$i}+(_skMoveY{$i}*$DeltaY/100);
                                                                _skLeft{$i}+(_skMoveX{$i}*$DeltaX/100)
                                                                +_skSizeX{$i}+(_skGrowX{$i}*$DeltaX/100);
                                                                _skTop{$i}+(_skMoveY{$i}*$DeltaY/100)
                                                                +_skSizeY{$i}+(_skGrowY{$i}*$DeltaY/100); *)
   Fin de boucle

      `calcul de ta taille de la police à affecter à l'afficheur et aux boutons
   LIRE RECT OBJET(*;"CalcResult";$Left;$Top;$Right;$Bottom)
   $H:=($Bottom-$Top)
   CHANGER TAILLE(*;"CalcResult";$H*0,6)
   CHANGER TAILLE(*;"bIm@";$H*0,4)


VII. Contrôle de la taille de la fenêtre

Afin de pouvoir contrôler le redimensionnement de la fenêtre et son rapport largeur/hauteur nous appellerons une méthode spécifique via un objet invisible situé en bas à droite de la fenêtre.

Cet objet est en fait un petit thermomètre dont la fonction de base a été détournée. Il a l'avantage de pouvoir exécuter un script en continu tant que le bouton de la souris reste enfoncé.

La méthode appelée (ResizeWindow) contrôlera la position de la souris et, si les conditions de taille et de ratio sont respectées, se chargera de redimensionner la fenêtre (pourtant définie comme taille fixe, non-redimensionnable). L'événement Sur redimensionnement sera alors activé et les objets déplacés.


VIII. Conclusion

D'autres applications sont envisageables avec cette méthode. Citons par exemple la possibilité de créer des "skins"(*) évolués via des objets statiques, des boutons images (dont l'apparence peut venir, rappelons-le, soit de ressources, soit de la bibliothèque d'images, mais également de variables images)…

Il serait également possible d'utiliser cette méthode pour faire apparaître ou non des objets en fonction des droits des utilisateurs, etc.

De bien beaux formulaires en perspective !


(*) Skin : éléments graphiques d'interface


IX. Base exemple

Téléchargez la base exemple :

Base pour Windows

Base pour Mac OS

__________________________________________________
Copyright © 1985-2009 4D SA - Tous droits réservés
Tous les efforts ont été faits pour que le contenu de cette note technique présente le maximum de fiabilité possible.
Néanmoins, les différents éléments composant cette note technique, et le cas échéant, le code, sont fournis sans garantie d'aucune sorte. L'auteur et 4D S.A. déclinent donc toute responsabilité quant à l'utilisation qui pourrait être faite de ces éléments, tant à l'égard de leurs utilisateurs que des tiers.
Les informations contenues dans ce document peuvent faire l'objet de modifications sans préavis et ne sauraient en aucune manière engager 4D SA. La fourniture du logiciel décrit dans ce document est régie par un octroi de licence dont les termes sont précisés par ailleurs dans la licence électronique figurant sur le support du Logiciel et de la Documentation afférente. Le logiciel et sa documentation ne peuvent être utilisés, copiés ou reproduits sur quelque support que ce soit et de quelque manière que ce soit, que conformément aux termes de cette licence.
Aucune partie de ce document ne peut être reproduite ou recopiée de quelque manière que ce soit, électronique ou mécanique, y compris par photocopie, enregistrement, archivage ou tout autre procédé de stockage, de traitement et de récupération d'informations, pour d'autres buts que l'usage personnel de l'acheteur, et ce exclusivement aux conditions contractuelles, sans la permission explicite de 4D SA.
4D, 4D Calc, 4D Draw, 4D Write, 4D Insider, 4ème Dimension ®, 4D Server, 4D Compiler ainsi que les logos 4e Dimension, sont des marques enregistrées de 4D SA.
Windows,Windows NT,Win 32s et Microsoft sont des marques enregistrées de Microsoft Corporation.
Apple, Macintosh, Power Macintosh, LaserWriter, ImageWriter, QuickTime sont des marques enregistrées ou des noms commerciaux de Apple Computer,Inc.
Mac2Win Software Copyright © 1990-2002 est un produit de Altura Software,Inc.
4D Write contient des éléments de "MacLink Plus file translation", un produit de DataViz, Inc,55 Corporate drive,Trumbull,CT,USA.
XTND Copyright 1992-2002 © 4D SA. Tous droits réservés.
XTND Technology Copyright 1989-2002 © Claris Corporation.. Tous droits réservés ACROBAT © Copyright 1987-2002, Secret Commercial Adobe Systems Inc.Tous droits réservés. ACROBAT est une marque enregistrée d'Adobe Systems Inc.
Tous les autres noms de produits ou appellations sont des marques déposées ou des noms commerciaux appartenant à leurs propriétaires respectifs.
__________________________________________________
 



Valid XHTML 1.1!Valid CSS!

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
Contacter le responsable de la rubrique 4D