IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants FMX Delphi Discussion :

Couleur d'un TPanel FMX


Sujet :

Composants FMX Delphi

  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut Couleur d'un TPanel FMX
    Bonjour,

    Cette question refait surface de temps en temps et je voulais y répondre de façon plus appropriée que ce que j'ai pu faire jusqu'à présent.

    En introduction j'écrirais que le TPanel est un vieux reflexe VCL et qu'il me semble totalement inutile en FMX, il suffit de le remplacer par un TRectangle. Toutefois un TRectangle est un composant non stylé donc des subtilités de style peuvent s'échapper ici ou là. (une de ces subtilités est dans la "couleur de fond" proposée, souvent une simple couche de transparence)

    Donc, en marge de ma bagarre avec les TStyleObjects et après la découverte d'un accés à la propriété scene des composants stylés je me suis dit (hier) que je pouvais certainement répondre à la demande "Comment changer la couleur d'un Panel en FMX" afin d'en faire une FAQ ou à tout le moins un billet dans mon blog.

    Et ce sera sous la forme d'un helper que je propose cette solution (ici dans une unité indépendante)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    unit PanelHelper;
     
    interface
    uses System.SysUtils,System.UITypes, FMX.StdCtrls, FMX.Types, FMX.Controls;
     
    type
      TPanelHelper = class helper for TPanel
        procedure ChangeColor(const NewColor : TAlphaColor);
      end;
     
    implementation
     
    { TPanelHelper }
    uses  FMX.Styles, FMX.Styles.Objects, FMX.Objects;
     
    procedure TPanelHelper.ChangeColor(const NewColor: TAlphaColor);
    var
      AStyle, aFMxObj: TFMXObject;
      stname : String;
    begin
       if assigned(self.Scene) then
       begin
       if not Assigned(self.Scene.StyleBook) then
          aStyle := TStyleManager.ActiveStyleForScene(Self.Scene)
        else
          aStyle := Self.Scene.StyleBook.Style;
       end;
      if stname.IsEmpty then stname := 'panelstyle';
     
      aFMxObj := AStyle.FindStyleResource(stname);
      if Assigned(aFMxObj) AND (aFMxObj is TRectangle)
      // attention, fonction du style  n'est pas forcément un Trectangle.
      // cela peut être un tstyleobject cas jamais détecté sur les styles testés
      then begin
        TRectangle(aFMxObj).Fill.Color := NewColor;
        TStyleManager.UpdateScenes;
      end;
    end;
     
    end.
    Utilisation simple, on ajoute l'unité dans la liste des uses et d'un simple Panel1.ChangeColor(TAlphaColors.Red); tous les Panels changent de couleur.

    Bien sûr, il y a cette remarque
    // attention, fonction du style n'est pas forcément un TRectangle.
    // cela peut être un tstyleobject cas jamais détecté sur les styles testés
    mais tous les styles que j'ai scanné me donne le feu vert, à chaque fois, il s'agit d'un TRectangle

    Donc, c'est fonctionnel mais et j'en viens là à ma question, comment retrouver par la suite l'état initial et là, je séche. Sauf à mémoriser la/les* propriété/s je ne vois pas comment accéder au style de la forme et non de la scene (ce qui est ma foi assez hilarant quand on pense que je n'ai découvert la scene d'un composant que récemment !)

    Jusque là mes tentatives
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    // renvoi la "couleur" du panel  : OK 
    function TPanelHelper.GetColor: TAlphaColor;
    var
      AStyle, aFMxObj: TFMXObject;
      stname : String;
    begin
       if assigned(self.Scene) then
       begin
       if not Assigned(self.Scene.StyleBook) then
          aStyle := TStyleManager.ActiveStyleForScene(Self.Scene)
        else
          aStyle := Self.Scene.StyleBook.Style;
       end;
      if stname.IsEmpty then stname := 'panelstyle';
     
      aFMxObj := AStyle.FindStyleResource(stname);
       if Assigned(aFMxObj) AND (aFMxObj is TRectangle)
      // attention, fonction du style  n'est pas forcément un Trectangle.
      // cela peut être un tstyleobject cas jamais détecté sur les styles testés
      then result:=TRectangle(aFMxObj).Fill.Color;
    end;
    // Obtenir la "couleur" du style : Pas OK
    function TPanelHelper.GetDefaultColor(const aStyle : TStyleBook): TAlphaColor;
    var
      aFMxObj: TFMXObject;
    begin
      aFMxObj := Self.Scene.StyleBook.Style.FindStyleResource('panelstyle');
      if Assigned(aFMxObj) AND (aFMxObj is TRectangle)
      // attention, fonction du style  n'est pas forcément un Trectangle.
      // cela peut être un tstyleobject cas jamais détecté sur les styles testés
      then result:=TRectangle(aFMxObj).Fill.Color; // il manque le else 
    end;



    ont échouées


    *Les, car on pourrait jouer sur d'avantage de propriétés du TRectangle en exemple l'épaisseur du trait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    procedure TPanelHelper.ChangeBorder(const NewColor: TAlphaColor;
      const NewThickness: Single);
    var
      AStyle, aFMxObj: TFMXObject;
      stname : String;
    begin
       if assigned(self.Scene) then
       begin
       if not Assigned(self.Scene.StyleBook) then
          aStyle := TStyleManager.ActiveStyleForScene(Self.Scene)
        else
          aStyle := Self.Scene.StyleBook.Style;
       end;
      if stname.IsEmpty then stname := 'panelstyle';
     
      aFMxObj := AStyle.FindStyleResource(stname);
      if Assigned(aFMxObj) AND (aFMxObj is TRectangle)
      // attention, fonction du style  n'est pas forcément un Trectangle.
      // cela peut être un tstyleobject cas jamais détecté sur les styles testés
      then begin
        TRectangle(aFMxObj).Stroke.Color := NewColor;
        TRectangle(aFMxObj).Stroke.Thickness := NewThickness;
        TStyleManager.UpdateScenes;
      end;
    end;
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    oui...ça montre bien pourquoi je disais encore il y a peu que je préfère utiliser un TFrame dans un ScrollBox plutôt que les styles dans un ListView

    cette gestion de thème est nécessaire pour avoir un look adapté à chaque plateforme, mais pour personnaliser l'affichage de ses composants je trouve cela extrêmement lourd

    je préfère de loin utiliser un TRectangle

    en fait, plus j'y pense, et plus j'aimerai avoir une "VCL" avec des styles à part...comme mon TMaterialColorSet qui permet de définir un style a appliquer à une série de composants.

    ça revient à ce qu'on a dans un traitement de texte ou l'on peut choisir la police d'une portion de texte, ou simplement lui appliquer un style "Titre 1", "Paragraphe 12"....

    Dans l'idée j'aimerai pouvoir choisir la police de tous les boutons de mon application, ou la police utilisée par toutes les fiches...et d'ailleurs permettre à l'utilisateur de choisir ces paramètres...mais avec les architectures actuelles ça veux dire que toutes les fiches sont à modifier.

    Bon ok, c'est un peu le principe du StyleBook, mais le code ci-dessus me fait penser que l'implémentation n'est pas la plus simple qui soit, alors que j'aime les choses simples
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    Bon, à vrai dire, mes derniers tests sont moins concluants.
    Je croyais ne toucher que le panel indiqué mais en fait, après avoir ajouté sur ma forme test un autre panel et même en en créant un supplémentaire au runtime, je me suis apperçu que tous les panels changeait de couleurs je touche donc la feuille de style et non l'affichage du seul panel !

    Un grain de sable dans mon raisonnement donc, expliquant du coup le "pourquoi je n'ai pu atteindre les valeurs initiales du style ?"

    A ma décharge je n'avais utilisé scene que pour un "test composant", c'est à dire dans l'unité de création d'un composant (mon fameux FMX.RadiogroupBox), je voulais voir comment un style pouvait être pris en compte voire inclus dans un composant (en m'inspirant de composants TMSFMX).
    Conclusion j'ai des progès à faire sur le sujet

    Citation Envoyé par Paul TOTH
    je préfère utiliser un TFrame dans un ScrollBox plutôt que les styles dans un ListView
    Pour ce qui est des ListView, pas de style au mieux tu as les appararences et en particulier la dynamique (que j'utilise énormément) , seules Listbox permet d'utiliser les styles par élément.
    L'avantage de la TListView c'est quand on a un affichage d'élements tous identiques, en remplacement de grilles par exemple, je dirais que c'est un peu l'équivalent d'un DBCtrlGrid de la VCL (en readonly)
    un style est quelque part un frame ou plutôt chaque élément d'un style est un Tframe (sans code) . Quand on regarde en texte un .style ce ne sont que des TLayouts contenant divers autres controles
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  4. #4
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    les styles FMX sont des composants chargés dynamiquement par ApplyStyle...donc tu peux modifier ces éléments une fois le style appliqué...et si tu veux revenir aux valeurs par défaut, il faut aller recherche la valeur dans le style défini et l'appliquer à l'instance propre au composant ... je sais pas si c'est très clair ce que je dis
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    Si c'est clair (enfin pour moi).
    Je voulais éviter l'utilisation des OnApplyStyleLookup des composants.
    La technique que j'ai employée change en fait le style chargé et non le style de l'élément. En soit c'est pas mal de découvrir ça mais ce n'est pas vraiment ce que je m'étais fixé comme objectif avec ce helper. J'ai raté quelque chose à un endroit entre mes essais avec le composant et ma rédaction du helper tout comme je n'ai pas réussi à récupérer les zones des TCustomStyleObject dans ce code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
         else if aFMxObj is TCustomStyleObject then
          begin
           if Assigned(TStyleObject(aFMxObj).SourceLink) then
            // dans une zone de l'image
            begin
              aBounds := TBitmapLinks(TStyleObject(aFMxObj).SourceLink).Links[0].SourceRect;
              aRect := TRect.Create(Trunc(aBounds.Left), Trunc(aBounds.Top),Trunc(aBounds.Right), Trunc(aBounds.Bottom));
              bmp.Width := aRect.Right - aRect.Left;
              bmp.Height := aRect.Bottom - aRect.Top;
              bmp.CopyFromBitmap(TImage(AStyle.FindStyleResource(TStyleObject(aFMxObj).sourcelookup)).Bitmap, aRect, 0, 0);
            end;
    alors que j'avais réussi à obtenir ça dans ce source en chargeant le fichier style.

    Bref un dimanche matin qui s'est terminé en eau de boudin, j'en suis pas loin mais ... il me faudra plancher d'avantage
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  6. #6
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 042
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 042
    Points : 40 955
    Points
    40 955
    Billets dans le blog
    62
    Par défaut
    je viens de lire une astuce plus simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     if (Panel1.ControlsCount >= 1)
       and (Panel1.Controls[0] is TShape)
     then
           (Panel1.Controls[0] as TShape).Fill.Color := TAlphaColorRec.Red;
    et, pour répondre retrouver ma couleur initiale, comme l'indiquait Paul dans le #4
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    var
      sb, st: TFMXObject;
      stlookup: String;
    begin
      if Assigned(Panel1.Scene) then
      begin
        if not Assigned(Panel1.Scene.StyleBook) then
          sb := TStyleManager.ActiveStyleForScene(Panel1.Scene)
        else
          sb := Panel1.Scene.StyleBook.Style;
        stlookup := Panel1.StyleLookup;  // permet de fonctionner avec stylelookup="calloutpanel" ou "pushpanel"
        if stlookup.IsEmpty then
          stlookup := 'panelstyle';
     
        st := sb.FindStyleResource(stlookup);
        (Panel1.Controls[0] as TShape).Fill.Color := TShape(st).Fill.Color;
      end;
    Cela ne répond toujours pas au TCustomStyleObject (cas extrêmement rare) mais je vais persister

    [Edit] FAQ écrite
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Windows] changement de couleur d'une forme fmx
    Par aladin95 dans le forum Composants FMX
    Réponses: 2
    Dernier message: 06/12/2020, 12h09
  2. Dégradé de couleurs dans un TPanel
    Par yamino dans le forum Composants VCL
    Réponses: 18
    Dernier message: 12/05/2016, 23h12
  3. Fast report FMX changer la couleur d'un tfrxmemoview
    Par Higgins dans le forum Composants FMX
    Réponses: 2
    Dernier message: 07/09/2013, 08h39
  4. Réponses: 6
    Dernier message: 17/10/2010, 14h45
  5. Comment mettre de la couleur à un TPanel ?
    Par bertrand_declerck dans le forum Composants VCL
    Réponses: 11
    Dernier message: 21/08/2005, 12h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo