FireMonkey Delphi

Conception d'applications FireMonkey
 
FireMonkey utilise des contrôles GUI légers au sommet d'une abstraction multiplate-forme, qui est implémentée pour Windows, Mac OS X et iOS. "Contrôles légers" signifie que chaque pixel est dessiné par FireMonkey ; aucune contrôle natif (à haute densité) n'est utilisé. Cette approche favorise la fidélité à travers les plates-formes par rapport à la fidélité à la plate-forme hôte, gère le problème "plus petit dénominateur commun" des frameworks multiplates-formes haute densité, et permet à FireMonkey de créer ses propres règles de conception d'applications et de contrôles.
 
Arrangement des contrôles
 
Une application FireMonkey présente un ou plusieurs contrôles dans une fiche. La fiche peut contenir du contenu 2D, du contenu 3D, ou un mélange des deux.
 
Système de coordonnées
 
L'origine du système de coordonnées est le coin supérieur gauche, en s'étendant vers le coin inférieur droit. Les coordonnées sont exprimées en nombres à virgule flottante en simple précision Toutes les plates-formes supportées utilisent les pixels carrés. Une unité de coordonnée est généralement mappée sur un pixel, avec quelques exceptions distinctes.
La propriété Position d'un contrôle 2D est un TPosition avec les propriétés X et Y. Les propriétés Width et Height distinctes représentent sa taille. Les objets 3D utilisent un TPosition3D avec une propriété Z supplémentaire, avec des valeurs positives pointant vers l'écran (X va vers la gauche et Y pointe vers le bas, suivant ainsi la "règle de la main droite") ; et une propriété Depth. La position et la taille définissent ensemble une sorte de cadre englobant qui décrit un contrôle : sa zone de contenu.
 
Parents, enfants et propriétaires
 
La fiche possède généralement tous les contrôles qu'elle contient. Les contrôles présentés par le Concepteur de fiches suivent cette convention. Le propriétaire est le premier et le seul argument pour le constructeur Create commun :
 
TFmxObject.Create(AOwner: TComponent)
 
Lors de la création de composants via le code, si le contrôle est prévu pour persister pendant la durée de vie restante de la fiche, spécifiez la fiche en tant que propriétaire. La fiche doit être aisément disponible en tant que Self ou Owner d'un contrôle existant. Le propriétaire est responsable de la suppression du contrôle quand il est supprimé lui-même.
Pour les composants temporaires, passez nil en tant que propriétaire. 
Le code est alors responsable de la suppression du composant quand il en a terminé avec lui. Les meilleures pratiques imposent l'utilisation d'un bloc try/finally pour garantir la suppression du composant, même en présence d'une exception.
Afin que le contrôle apparaisse dans la fiche, la possession n'est pas suffisante. Il doit aussi être placé dans l'arborescence des composants, en tant qu'enfant direct de la fiche, ou quelque part plus bas dans l'arborescence. Les contrôles présentés dans le Concepteur de fiches le font automatiquement, et l'arborescence des composants est présentée dans la vue Structure. Lors de la création de contrôles via le code, définissez la propriété Parent sur la fiche ou un autre contrôle.
La position d'un enfant est relative à son parent. Si les coordonnées sont zéros, l'enfant commence à la même position supérieure-gauche que le parent.
FireMonkey permet à tout contrôle d'être le parent d'un autre. La parenté n'est pas restreinte aux contrôles de type conteneur. De plus, la propriété ClipChildren prend comme valeur par défaut False (si True, elle n'autorise pas le dessin des enfants en dehors de la zone de contenu du contrôle). Cela permet les collections ad-hoc de contrôles associés sans nécessiter un conteneur formel. Par exemple, un TLabel peut être un enfant du TEdit qu'il décrit. Le libellé peut avoir une position négative, le plaçant au-dessus ou devant le contrôle. Le déplacement du TEdit les déplace ensemble. TLayout peut être utilisé en tant qu'autre conteneur commun pour arranger d'autres contrôles.
En plus d'un espace de coordonnées partagé, les objets enfant partagent d'autres attributs tels que la visibilité, l'opacité, la rotation et l'échelle. Changer ces attributs pour le parent affecte tous les enfants dans cette sous-arborescence.
 
Alignement avec les marges et le remplissage
 
La propriété Align d'un contrôle détermine sa participation dans le positionnement et/ou le dimensionnement automatique le long des quatre côtés et du centre du parent, initialement et au fur et à mesure que le parent est redimensionné. Sa valeur par défaut est alNone, de sorte que de tels calculs automatiques ne sont pas effectués : le contrôle reste à son emplacement. La propriété est une énumération de type TAlignLayout, avec plus d'une douzaine d'autres valeurs possibles. La plupart de ces valeurs provoquent l'inclusion dans le calcul de deux valeurs pour l'alignement automatique : la propriété Margins du parent et la propriété Padding du contrôle.
Les marges définissent un espace à part sur l'intérieur de la zone de contenu du parent ; comme les marges d'une page imprimée, dans la perspective du papier. Par exemple, si les marges Top et Left du parent valent toutes les deux 10, ainsi un composant qui est automatiquement positionné dans le coin supérieur gauche aura sa position définie sur 10,10.
Plus précisément, ce qui est automatiquement positionné n'est pas la zone de contenu du contrôle, mais plutôt sa zone de disposition. La différence entre les deux est le remplissage (propriété Padding), ou marge intérieure, du contrôle, le cas échéant. La marge intérieure définit un espace à part sur l'extérieur de la zone de contenu du contrôle. Au fur et à mesure qu'elle augmente, la taille de la zone de disposition reste la même, et la zone de contenu se réduit si elle est limitée. Revenons à l'exemple 10,10, si les marges intérieures Top et Left sont toutes deux à 5, la position du contrôle sera 15,15.
Remarque : Le rôle des marges et du remplissage dans FireMonkey est l'opposé du modèle CSS Box Model.
Le remplissage garantit la séparation entre des contrôles positionnés automatiquement par un parent, et les marges assurent un espace entre ces contrôles et le bord du parent. C'est pour les valeurs positives des marges et du remplissage, mais les valeurs négatives sont aussi autorisées. Des marges négatives placent les enfants en dehors de la zone de contenu du parent, qui sont toujours rendus si la propriété ClipChildren vaut False. Un remplissage négatif place la zone de contenu d'un contrôle en dehors de sa zone de disposition calculée.
 
Mise à l'échelle et mise en rotation
 
Deux autres attributs fréquemment disponibles affectent l'emplacement rendu final d'un contrôle : l'échelle et la rotation.
Remarque : L'échelle et la rotation n'altèrent pas les propriétés de taille et de position d'un contrôle. Cela se reflète dans le Concepteur de fiches : les huit poignées d'un objet sélectionné (quatre coins et quatre côtés) marquent la zone de contenu réelle, définie manuellement ou calculée à travers la disposition, avant l'application de l'échelle et de la rotation.
La propriété Scale d'un contrôle est représentée par une instance du même type que sa Position : TPosition pour les objets 2D et TPosition3D pour les objets 3D. Ses valeurs X, Y et Z passent par défaut à 1, ce qui signifie que l'objet n'est pas mis à l'échelle dans toutes les dimensions. La valeur de l'échelle est un simple multiplicateur sur chaque axe. Des valeurs supérieures à un effectueront un étirement le long de cet axe. Des valeurs inférieures à un, mais supérieures à zéro, effectueront un rétrécissement le long de cet axe. La mise à l'échelle d'un axe par zéro provoquera la disparition du contrôle. Une mise à l'échelle uniforme nécessite les mêmes valeurs dans tous les axes.
La mise à l'échelle 2D est toujours ancrée depuis l'origine du contrôle, le coin supérieur gauche de sa zone de contenu. Une mise à l'échelle négative effectue un pivotement sur ce point d'origine. Par exemple, une échelle X négative provoquera un rendu du contrôle vers le bas et sur la gauche, en le faisant pivoter sur le bord gauche de la zone de contenu. La mise à l'échelle 3D s'effectue à partir du centre de l'objet.
Dans la rotation 2D, le pivot est ajustable. La propriété RotationCenter est aussi un TPosition, mais la valeur est dans les coordonnées d'unité : 0,0 représente le coin supérieur gauche du contrôle et 1,1 représente le coin inférieur droit. Elle a pour valeur par défaut le centre du contrôle : 0.5,0.5. Les proportions de la zone de contenu sont sans importance. Sur ce point de pivot, la propriété RotationAngle est en degrés, dans le sens des aiguilles d'une montre.
En 3D, la rotation s'effectue toujours à partir du centre, avec pour RotationAngle un TPosition3D, spécifiant les degrés sur les axes X, Y et Z. La rotation suit aussi la règle de la main droite. Par exemple, avec une rotation X et Y à zéro, l'axe Z pointe dans l'écran, et la rotation positive sur l'axe Z s'effectue dans le sens des aiguilles d'une montre.
En 2D, la mise à l'échelle survient avant la rotation, ce qui est important car la mise à l'échelle s'effectue depuis l'origine et la rotation est ajustable. En 3D, les deux se produisent à partir du centre, ainsi l'ordre n'a pas d'importance.

Aucun commentaire: