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 VCL Delphi Discussion :

Faire un bouton avec image SVG (utilisation de Skia)


Sujet :

Composants VCL Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 624
    Billets dans le blog
    65
    Par défaut Faire un bouton avec image SVG (utilisation de Skia)
    Bonjour,

    Comme Skia va être intégré dans la prochaine version, que je trouve les glyphes des boutons petits et que je n'aime pas trop l'utilisation des collections d'images, je me suis dit qu'un "bouton" avec un svg comme glyphe serait assez sympa. Partant de mes utilisations des SVG avec FMX et avant d'en faire un composant, j'ai fait plusieurs essais

    Nom : Capture.PNG
Affichages : 314
Taille : 9,7 Ko
    de gauche à droite, un simple TSkSVG que du code va "trafiquer", un TSKSVG chargé à partir d'une ressource, un Panel (seul conteneur connu en VCL) avec un skSVG et enfin un skAnimatedPaintbox (qui lui aussi est un conteneur)

    Un impératif : pouvoir changer la couleur de fond quand la souris passe dessus comme pour un bouton "classique" et bien sûr prendre en compte l'apparence en cours.

    Le premier implique un "bidouillage" sur le source du SVG, l'ajout d'un rectangle, et une modification au runtime donc pas forcément interessant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    procedure TFormTest.SkSvg4MouseEnter(Sender: TObject);
    var c : String;
    begin
    SkSVG4.Svg.Source:=ReplaceText(SkSVG4.Svg.Source,'rect  style="fill-opacity:0','rect  style="fill-opacity:1');
    end;
    procedure TFormTest.SkSvg4MouseLeave(Sender: TObject);
    begin
    SkSVG4.Svg.Source:=ReplaceText(SkSVG4.Svg.Source,'rect  style="fill-opacity:1','rect  style="fill-opacity:0');
    end;
    Pour le second, c'est pratiquement la même chose, impliquant deux SVG différents la même manipulation au runtime pouvant s'appliquer (non fait).

    Pour le panel, la solution la plus simple sauf en ce qui concerne "l'effet"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TFormTest.Panel1MouseEnter(Sender: TObject);
    begin
    Panel1.Color:=StyleServices.GetStyleColor(scButtonFocused); // ou TStyleManager.ActiveStyle.GetSystemColor(scButtonFocused) ?
    Panel1.StyleElements:=Panel1.StyleElements-[seClient];
    end;
     
    procedure TFormTest.Panel1MouseLeave(Sender: TObject);
    begin
    panel1.StyleElements:=Panel1.StyleElements+[seClient];
    end;
    inconvénient "l'effet" a tendance à ne faire qu'un petit clignotement, voire ne pas s'appliquer

    Dernière solution avec Skia
    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
    procedure TFormTest.SkAnimatedPaintBox1AnimationDraw(ASender: TObject;
      const ACanvas: ISkCanvas; const ADest: TRectF; const AProgress: Double;
      const AOpacity: Single);
    var btnColor, bordcolor : TColor;
    begin
      var LPaint: ISkPaint := TSkPaint.Create;
      if SkAnimatedPaintBox1.Animation.Enabled
       then begin
            if not Sametext(TStyleManager.ActiveStyle.Name,'windows')
             then btncolor:=StyleServices.GetStyleColor(scButtonHot)
             else btncolor:=clHighlight; // GetSystemColor ?
            var Alpha : byte := Round(255*0.6);  // 255*opacity
            Shape1.Brush.Color:=btncolor;
            Lpaint.SetARGB(alpha,GetrValue(btncolor),GetGValue(btncolor),GetBValue(btncolor));
            Lpaint.Style:=TSkPaintStyle.Fill;
            Acanvas.DrawRoundRect(TRectF.Create(0,0,SkAnimatedPaintBox1.Width,SkAnimatedPaintBox1.Height),10,10,lpaint);
       end
       else begin
           if not Sametext(TStyleManager.ActiveStyle.Name,'windows')
             then bordcolor:=StyleServices.GetStyleColor(scBorder)
             else bordcolor:=clBtnShadow; // GetSystemcolor ?
         Shape1.Brush.Color:=bordcolor;
         lPaint.Style:=TSkPaintStyle.Stroke;
         lPaint.StrokeWidth:=2;
         lPaint.SetARGB(255,GetrValue(bordcolor),GetGValue(bordcolor),GetBValue(bordcolor));
         Acanvas.DrawRoundRect(TRectF.Create(0,0,SkAnimatedPaintBox1.Width,SkAnimatedPaintBox1.Height),10,10,lPaint);
       end;
    end;
     
    procedure TFormTest.SkAnimatedPaintBox1MouseEnter(Sender: TObject);
    begin
     SkAnimatedPaintBox1.Animation.Enabled:=true;
    end;
     
    procedure TFormTest.SkAnimatedPaintBox1MouseLeave(Sender: TObject);
    begin
     SkAnimatedPaintBox1.Animation.Enabled:=False;
    end;
    Il me reste un seul problème quand le style sélectionné est le style "Windows" je n'arrive pas à obtenir la "bonne" couleur

    ici la vidéo
    https://serge-girard.developpez.com/...outonsSVG.webm

    Donc questions :
    Qu'est-ce qui cloche avec mon panel ?
    Comment obtient-on la couleur quand le style est celui par défaut (Windows) ? (j'ai essayé GetSystemColor sans plus de résultat)

  2. #2
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 624
    Billets dans le blog
    65
    Par défaut
    pour ce qui est de cette question
    Il me reste un seul problème quand le style sélectionné est le style "Windows" je n'arrive pas à obtenir la "bonne" couleur
    il semble que pour obtenir une couleur, je dois utiliser cette instruction

    btncolor:=StyleServices.GetSystemColor(clGradientActiveCaption); qui dans mon cas donne une sorte de bleu (pas tout à fait identique, mais s'en approche)
    plutôt que btncolor:=clMenuHighlight; qui retourne un noir

    des explications ?

  3. #3
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 491
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 491
    Par défaut
    salut

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    If  Assigned(StyleServices) Then 
      btncolor:= StyleServices.GetSystemColor(clMenuHighlight)
    else 
      btncolor:= GetSysColor(clMenuHighlight and not(clSystemColor) ); // qui retourne un noir
    Cela ne marche pas mieux ?

    pour les explications, il y a peut etre un soucis de format entre un Dword et un Longint selon la bibliotheque utilisé

  4. #4
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 624
    Billets dans le blog
    65
    Par défaut
    Bonjour,
    Citation Envoyé par anapurna Voir le message
    Cela ne marche pas mieux ?
    en fait non, d'abord le if Assign(StyleServices) en 11.3 me donne une erreur de syntaxe , il faut écrire if Assign(StyleServices())et est toujours assigné donc, je ne passe jamais dans le else.

    Du coup comment "échapper" au style ?

  5. #5
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par défaut
    je utilise if StyleServices.Enabled then par exemple dans TDBGridSLTAssistant ou TStringGridSLTAssistant mais ça date de Delphi XE2 et je crois que c'était pour le thème Windows Server sur Citrix, je sais plus comment le Thème Aero était pris en compte

    j'utilise aussi la variante if StyleServices.IsSystemStyle then dans TTabSheetSLTAssistant car on peut tout de même récupérer les couleurs du thème Windows Aero, c'est peut-être différent ( StyleServices.Enabled à True et StyleServices.IsSystemStyle à True, à vérifier, j'ai pas bossé sur ça depuis 5 ans )
    alors que c'est plus un Style Windows 98 ( StyleServices.Enabled à False ) avec le style désactivé dans l'OS (un vieux style gris et non Aero)

    globalement et je me souviens d'avoir changé le style de mon windows 7 entre le style Aero et le style classique ... Delphi était parfois en vrac

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if StyleServices.Enabled
    begin
      if  StyleServices.IsSystemStyle then
        Gestion des éléments spécifique à ce thème, Aero a des exceptions que n a aucun autre style comme ttAeroWizardBody pour GetElementDetails
      else
        Gestion des éléments de thème VCL
     
       Gestion des couleurs ...
    end
    else
      API Windows genre DrawFrameControl
    Sous Delphi 10, Windows 10, j'avais StyleServices.Enabled à True avec le style Windows

    Sous XE2, Windows Seven, j'avais StyleServices.Enabled à False avec le style Windows classique à mon souvenir, je ne sais même pas comment sur Win8 ou Win10 pour mettre un style Windows classique (EDTI, faut activer un style avec Constrate elevé, genre "Ciel Nocturne")
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par défaut
    En XE2, je souviens d'un bug du Glyph, regarde TSLTButtonStyleHookFix



    je regarde ce vieux code StyleServices.GetSystemColor(clBtnHighLight) comme Pen.Color pour un Control désactivé, ça devrait renvoyer du gris ou blanc, comme toi, j'ai du galéré sur les couleurs et pire, je crois que c'est un copier coller de TButtonStyleHook.Paint donc même les dev de la VCL faisait des choses étranges

    clBtnHighLight c'est différent de clMenuHighLight
    Et je crois que GetElementDetails(tbPushButtonHot)+ GetElementColor(ecFillColor) pour donner une couleur de sélection

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    If StyleServices.Available and not StyleServices.IsSystemStyle Then 
      btncolor := StyleServices.GetElementDetails(tbPushButtonHot).GetSystemColor(ecFillColor)
    else 
      btncolor := ColorToRGB(clHighlight); // clHotLight
    ColorToRGB gère les SystemColor comme clHighlight = SysHighlight
    GetSysColor gère les couleurs API donc cHIGHLIGHT = COLOR_HIGHLIGHT
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre Expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Bonjour,

    en fait non, d'abord le if Assigned(StyleServices) en 11.3 me donne une erreur de syntaxe , il faut écrire if Assigned(StyleServices())et est toujours assigné donc, je ne passe jamais dans le else.

    Du coup comment "échapper" au style ?
    StyleServices étant une fonction, c'est effectivement toujours assigné, en revanche c'est la valeur qu'elle retourne qui doit être testée (mieux vaut la foutre dans une variable pour éliminer l'erreur d'interprétation ou de relecture du code).

Discussions similaires

  1. [Article] Créer des boutons avec icônes sans utiliser d'images
    Par FirePrawn dans le forum Publications (X)HTML et CSS
    Réponses: 9
    Dernier message: 07/09/2012, 16h37
  2. [CSS 3] Créer des boutons avec icônes sans utiliser d'images
    Par FirePrawn dans le forum Mise en page CSS
    Réponses: 9
    Dernier message: 07/09/2012, 16h37
  3. Faire un bouton avec une image ?
    Par blanchonvincent dans le forum Interfaces Graphiques
    Réponses: 3
    Dernier message: 29/04/2007, 13h14
  4. Bouton avec image
    Par xeland dans le forum Windows
    Réponses: 1
    Dernier message: 15/11/2005, 18h32
  5. [Formulaire] Bouton avec image
    Par Mister Nono dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 02/11/2005, 16h16

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