Conception de composants FireMonkey
Remonter à Guide des composants FireMonkey
Sommaire |
Cette rubrique décrit comment concevoir des composants en utilisant FireMonkey.
Aperçu des contrôles intégrés sélectionnés
Un examen de quelques contrôles fournis montre une étendue de conceptions dans FireMonkey.
TPanel : Stylage avec les primitives
Le code source pour TPanel est assez court pour être reproduit dans son intégralité ici. L'interface :
TPanel = class(TStyledControl) public constructor Create(AOwner: TComponent); override; published property StyleLookup; end;
et l'implémentation :
constructor TPanel.Create(AOwner: TComponent); begin inherited; Width := 120; Height := 100; end;
TPanel sous-classe TStyledControl, la classe de base de tous les contrôles de niveau utilisateur. TPanel publie la propriété StyleLookup, qui contient le nom du style à rechercher. Le constructeur définit Width et Height, propriétés de TControl. Mais comment ce contrôle effectue son rendu ?
L'un des concepts clé de FireMonkey est l'utilisation des styles. Le style par défaut pour TPanel sur Windows peut être vu en enregistrant un fichier .style et est approximativement comme suit :
object TRectangle StyleName = 'panelstyle' Width = 50 Height = 50 HitTest = False Fill.Color = $FFffFFff Stroke.Color = $FF8e8e8e end
TPanel est un rectangle blanc uni avec une bordure grise. Sur le Mac, le remplissage est un dégradé.
Comme un contrôle stylé, TStyledControl contient un champ FResourceLink qui pointe sur un TFmxObject. FResourceLink est un clone de la ressource de style du contrôle, trouvé par le nom (spécifié dans la propriété StyleLookup du contrôle pour correspondance avec la propriété StyleName de la ressource) ou par défaut. Cet objet lien de ressource est aussi inséré en tant que premier enfant du contrôle, quand le contrôle est d'abord chargé ou quand sa propriété StyleLookup est changée. Ceci est effectué dans TStyledControl.ApplyStyleLookup.
Ainsi quand, comme un TControl, le contrôle se dessine lui-même, il dessine ses enfants. Le premier enfant correspond au contrôle lui-même, et les autres enfants "réels" (le cas échéant) sont ensuite dessinés.
Comme un contrôle primitif, TRectangle se dessine lui-même dans sa méthode Paint en appelant FillRect et DrawRect sur le canevas.
TCalloutPanel : Contrats de style
TCalloutPanel étend TPanel avec les propriétés pour un élément call-out extra visuel. Le style par défaut pour TCalloutPanel est virtuellement identique à celui pour TPanel, approximativement :
object TCalloutRectangle StyleName = 'calloutpanelstyle' Width = 50 Height = 50 HitTest = False Fill.Color = $FFffFFff Stroke.Color = $FF8e8e8e end
Au lieu d'un TRectangle, le style de niveau supérieur est un TCalloutRectangle, c'est-à-dire un rectangle avec une pointe triangulaire sur un côté. La primitive a exactement les mêmes propriétés supplémentaires pour le call-out que le contrôle stylé, qu'il utilise pour dessiner ce triangle. Le mappage est effectué par la méthode ApplyStyle :
procedure TCalloutPanel.ApplyStyle; var Back: TFmxObject; begin inherited; Back := FindStyleResource('Background'); if (Back = nil) and (FResourceLink is TCalloutRectangle) then Back := FResourceLink; if (Back <> nil) and (Back is TCalloutRectangle) then begin TCalloutRectangle(Back).CalloutWidth := FCalloutWidth; TCalloutRectangle(Back).CalloutLength := FCalloutLength; TCalloutRectangle(Back).CalloutPosition := FCalloutPosition; TCalloutRectangle(Back).CalloutOffset := FCalloutOffset; end; end;
ApplyStyle est appelée par ApplyStyleLookup, après la mise en place de l'objet lien de ressource, et par chacun des accesseurs en écriture des propriétés supplémentaires. Pour TCalloutPanel, ApplyStyle s'attend à ce que :
- l'objet racine soit un TCalloutRectangle, ce qui est vrai pour le style par défaut ; ou que
- quelque part dans l'arborescence des composants pour le style, se trouve un objet avec le StyleName "Background" qui est un TCalloutRectangle.
Si l'objet approprié est introuvable, TCalloutPanel ne fonctionne pas : les propriétés supplémentaires qu'il déclare n'ont pas d'effet.
C'est un exemple d'un contrat de style dans lequel les composants utilisés pour formuler un style pour un contrôle doivent se conformer à certaines attentes. Si vous développez un composant qui nécessite un contrat de style spécifique comme celui-ci, il est alors important que ce contrat soit documenté pour les autres utilisateurs de votre composant afin qu'ils puissent développer des styles corrects.
Dans le cas d'un panneau de légende, si une ressource de style correspondante au contrat n'est pas trouvée, vous terminerez alors avec un panneau ordinaire.
TCalendar : Complexité construite
TCalendar n'a pas de style par défaut. A la place, il se construit lui-même dans son constructeur (qui à l'inverse de TPanel, est bien trop long à inclure ici). En réalité, TCalendar crée l'arborescence de composants suivante :
- TLayout dans la partie supérieure
- Trois contrôles TButton épinglés à gauche utilisant le style "transparentcirclebuttonstyle", pour...
- TPopupBox pour le mois utilisant le style "labelstyle", rempli par les chaînes des mois de l'année, défini pour remplir la zone client restante non occupée par ces trois boutons et ...
- TPopupBox pour l'année utilisant le style "labelstyle", rempli par les chaînes des années, des dix années antérieures aux dix années postérieures, épinglé à droite
- TGridLayout épinglé en haut
- Sept contrôles TLabel pour les jours de la semaine (Dimanche, Lundi, etc.)
- TGridLayout le plus à gauche, initialement invisible, dimensionné pour une colonne unique
- Six contrôles TLabel pour les numéros de semaine, montrés par la propriété WeekNumbers
- TListBox avec 7 colonnes épinglées en haut, utilisant le style 'transparentlistboxstyle' et AlternatingRowBackground
- Quarante deux contrôles TListBoxItem, se terminant par six lignes pour six semaines
Chaque objet de l'arborescence des composants a sa propriété Stored définie sur False et sa propriété Locked définie sur True. La désactivation de la propriété Stored empêche la mise en flux de l'objet dans le fichier .fmx par le Concepteur de fiches. Si la propriété Stored n'est pas désactivée, les sous-composants seront créés de façon redondante lors du chargement. L'activation de la propriété Locked change la façon dont le test de résultats fonctionne et se déclenche, afin que le sous-composant fasse partie du plus grand ensemble.
Après la construction de l'arborescence des composants, le constructeur appelle la méthode FillList protégée pour définir le contenu du mois en cours. FillList repose sur la connaissance directe du contenu exact de l'arborescence des composants pour définir les jours de la semaine (en commençant par Dimanche ou Lundi selon les paramètres régionaux), les numéros de semaine, et les jours du mois.
La position relative des composants est codée en dur, mais leur apparence est presque entièrement contrôlée par les styles. Les exceptions sont les deux triangles et le cercle à l'intérieur des trois boutons dans le coin supérieur gauche. Les boutons eux-mêmes sont stylés. Les popups mois et année sur la droite ont leur style par défaut redéfini pour ressembler aux libellés (au lieu d'un bouton) avec le style libellé par défaut. Les jours de la semaine et les numéros de semaine sont des instances de TLabel et ils utilisent ce style libellé automatiquement. La zone de liste multicolonne utilisée pour afficher les jours du mois est stylée. Enfin, les contrôles jour individuel adopteront le style par défaut pour les éléments zone de liste.
Même en l'absence de style par défaut, que se passe-t-il si la propriété Resource d'un TCalendar est définie ? Comme toujours, la ressource de style résultante sera définie comme le premier enfant du contrôle, ce qui provoque son rendu sous la forme de son arrière-plan. Ainsi TCalendar dans son ensemble peut être stylé à un certain degré.
Conseils à propos des composants
Pour récapituler, lors de la création de composants FireMonkey :
- Utilisez les styles FireMonkey, afin que l'apparence puisse être changée par les développeurs d'applications.
- Encapsulez un dessin direct avec un contrôle primitif, qui peut être changé ou sous-classé.
- Les contrats de styles doivent être documentés.
- Les composants d'intérêt sont plus facilement trouvés par leur StyleName, définissez donc le StyleName de façon appropriée.
- Les contrôles complexes peuvent être construits par le code avec des composants stylés.