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

C++Builder Discussion :

Bouton/Panel de forme irrégulière


Sujet :

C++Builder

  1. #1
    Membre émérite
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Par défaut Bouton/Panel de forme irrégulière
    Bonjour à tous,

    Je souhaiterais savoir s'il existe une méthode ou une astuce pour faire un bouton, un Panel ou autre permettant de dessiner une forme irrégulière et de détecter un déplacement de la souris dans cette zone non rectangulaire.

    Toute idée est bonne à prendre en compte, je suis à votre écoute.
    Merci d'avance.

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2002
    Messages
    481
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2002
    Messages : 481
    Par défaut
    Pour créee une "Form" de forme rectangulaire avec des bord arrondis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     hRGN = CreateRoundRectRgn(0, 0, Width, Height, EllipseLargeur, EllipseHauteur);
      if(hRGN != NULL)
      	SetWindowRgn(Handle, hRGN, TRUE);
    Pour ne From elliptique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     hRGN = CreateEllipticRgn(x0, y0, xf, yf);
      if(hRGN != NULL)
    	SetWindowRgn(Handle, hRGN, TRUE);
    Il est possible d'assembler plusieurs régions pour n'en faire qu'une seule, et dessiner n'importe quel type de région finale.

  3. #3
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Salut bandit boy
    Si on suppose que ta forme quelconque est dessinee par une formule mathematique, il doit etre possible par calcul de savoir si on est dans l'aire de cette forme.

  4. #4
    Membre émérite
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Par défaut
    Merci, c'est sympa,
    mais c'est pas la Form mais plutôt un composant qui se trouvera sur un Form que je souhaite modifier.

    Il existe aussi un moyen de rendre transparent certains pixel de la Form et du coup lui donner la forme que l'on souhaite. Mais cette méthode est-elle adaptable pour un bouton ou un Panel ?

  5. #5
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    bandit boy a ecrit:
    Merci, c'est sympa,
    mais c'est pas la Form mais plutôt un composant qui se trouvera sur un Form que je souhaite modifier.

    Il existe aussi un moyen de rendre transparent certains pixel de la Form et du coup lui donner la forme que l'on souhaite. Mais cette méthode est-elle adaptable pour un bouton ou un Panel ?
    Il y a eut un post resolu il y a quelque temps ou un bouton etait represente par une image.
    J'ai retrouve le lien

  6. #6
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Est ce que l'on pourrait imaginer une image qui s'inscrit dans une forme de base, carre, rectangle, triangle ..., cette image pourrait avoir des pixels transparents, pour les testes au passage de la souris ils se feraient sur les formes de base, ce qui simplifiraient les testes, et seraient peu perceptibles a l'ecran.

  7. #7
    Membre émérite
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Par défaut
    Le truc c'est que ca reste carré, ou rectangulaire tout ca.
    Je continue de chercher dans cette piste. Je fouille du côté de l'image avec pixel transparent.

  8. #8
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    Salut motard.
    Juste une idee comme cela est il possible de faire une detection sur des pixels uniquement si ils ne sont pas transparents, je m'explique tu te defini une zone non visuelle carre, ronde, rectangulaire, ...a partir de cette zone tu fait un teste pour savoir si tu est sur ton image ou non pour visualiser la selection il suffit de changer l'image par une image identique avec un fond different ou une bordure ...

  9. #9
    Membre émérite
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Par défaut
    Alors j'ai testé l'image avec la transparence et ca ne marche pas.

    -Lorsque l'image est vide au départ et que je charge mon image avec la transparence, elle ne se fait pas.
    -Si je charge un fond, j'obtiens ma transparence mais perd le fait d'obtenir un MouseMoove dans la zone dessiné.
    -Si je dessine dans une zone qui n'est pas initialisé (le Strech = false et l'image inséré plus petite que le Timage) le dessin sensé être transparent ne s'affiche que dans la zone initialisée.
    -Si je l'insère dans une zone non initialisé je ne le vois pas.

    En gros, ca n'avance pas.

    L'idéale serait en fait un Shape de forme personalisée, mais comment la modifier pour donner mon propre polygone?

  10. #10
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    bandit boy a ecrit:
    Alors j'ai testé l'image avec la transparence et ca ne marche pas.

    -Lorsque l'image est vide au départ et que je charge mon image avec la transparence, elle ne se fait pas.
    -Si je charge un fond, j'obtiens ma transparence mais perd le fait d'obtenir un MouseMoove dans la zone dessiné.
    -Si je dessine dans une zone qui n'est pas initialisé (le Strech = false et l'image inséré plus petite que le Timage) le dessin sensé être transparent ne s'affiche que dans la zone initialisée.
    -Si je l'insère dans une zone non initialisé je ne le vois pas.

    En gros, ca n'avance pas.

    L'idéale serait en fait un Shape de forme personalisée, mais comment la modifier pour donner mon propre polygone?
    Tu a regarde le lien que je t'ai poste Herdenson a poste des renseignement au sujet de la transparence, sur la deuxieme page du lien

  11. #11
    Membre émérite
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Par défaut
    Citation Envoyé par blondelle
    bandit boy a ecrit:

    Tu a regarde le lien que je t'ai poste Herdenson a poste des renseignement au sujet de la transparence, sur la deuxieme page du lien
    Il parle de la propriété BevelOuter pour modifier la bordure du TPanel, mais je n'ai rien vu sur la transparence venant de Henderson !
    Je ne suis peut être pas réveillé, ou j'ai mal vu.

  12. #12
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 417
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 417
    Par défaut
    Salut !

    Si la complexité du graphisme n'est pas trop importante, on peut dériver de TCustomControl (et oui ... encore lui !).
    Il suffit de surcharger la méthode Paint pour réaliser le dessin via son canvas en prenant comme couleur de fond celle du Parent et d'autres couleurs pour le graphisme.
    On obtient ainsi une parfaite illusion à condition que l'objet ne vienne pas se superposer à d'autres car le TCustomControl reste un objet rectangulaire qui se dessine toujours comme tel.
    Dans la OnMouseDown il suffira donc d'analyser la couleur du pixel en X,Y.
    Si cette couleur équivaut à celle du parent c’est que l’on est hors du graphique.

    Pour d’éventuels effets de bords 3D, il faudra les dessiner en fonction d’un état actualisé lors du OnMouseDown !

    J'ai un exemple (simple) d'étoile à 4 branches... ainsi qu'un exemple (plus compliqué) avec 4 cercles pleins.

    A plus !

  13. #13
    Membre émérite
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Par défaut
    Je ne sais pas si ca peut marcher, je suis prêt à tester. Par contre, ton idée de couleur et de test de la couleur du pixel X,Y n'est pas bête du tout. En gors je voulais faire un truc du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    +-----+----------------+
    |     |                |
    |     +--              |
    |    /   \             |
    +---/      \           |
    |   |     \------------+
    |   |                  |
    |   +---\              |
    |        \             |
    +----------------------+

    c'est pas évident de dessiner comme ca et chaque zone serait un bouton. J'aurait eu besoin du MouseMoove et MouseClic. Mais si je fais chaque zone de couleur différente, et que lors du clic je prend la couleur du pixel cliqué, je peut deviner dans quel zone il est.
    Je pense devoir m'en sortir comme ça.
    Merci bien pour cette idée simple mais efficace. Je teste et je confirme

  14. #14
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 417
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 417
    Par défaut
    Salut !

    Je vais voir ça en essayant d'y apporter le plus de flexibilité possible...

    A plus !

  15. #15
    Rédacteur
    Avatar de blondelle
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    2 738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 738
    Par défaut
    bandit boy a ecrit:
    Il parle de la propriété BevelOuter pour modifier la bordure du TPanel, mais je n'ai rien vu sur la transparence venant de Henderson !
    Je ne suis peut être pas réveillé, ou j'ai mal vu.
    Excuse moi, j'ai du me reveiller apres avoir fait un reve premonitoire car henderson a donne une idee
    A+

  16. #16
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 417
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 417
    Par défaut
    Salut !

    J'ai fini par m'arrêter à ce qui suit :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    +-----+----------------+
    | red |                |
    |     +--    green     |
    |    /   \             |
    +---/     \            |
    |   |      \-----------+ << Points[0]
    |   |                  |
    |   +---\   yellow     |
    | blue   \             |
    +----------------------+

    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
    enum{none, red, blue, yellow, green};
     
    class jBanditBoyButton : public TCustomControl
    {
    private :
    TColor Outside; //facultatif pour ce qui concerne cette classe
    TPoint Points[8];
    int FActiveButton;
     
    protected :
        void __fastcall SetActiveButton(int Value);
     
    public :
     
        __fastcall jBanditBoyButton(TComponent *Owner, TRect R);
        __fastcall ~jBanditBoyButton();
     
        void __fastcall Paint();
     
        void __fastcall WhenMouseDown(TObject *Sender, TMouseButton Button,
                        TShiftState Shift, int X, int Y);
     
    __property int ActiveButton = {read=FActiveButton, write=SetActiveButton};
    };
    Les méthodes :

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    __fastcall jBanditBoyButton::jBanditBoyButton(TComponent *Owner, TRect R)
        : TCustomControl(Owner)
    {
    if(Owner->InheritsFrom(__classid(TWinControl))) Parent = (TWinControl*)Owner;
    BoundsRect = R;
    OnMouseDown = WhenMouseDown;
    }
     
    __fastcall jBanditBoyButton::~jBanditBoyButton()
    {
    }
     
    void __fastcall jBanditBoyButton::Paint()
    {
    //La couleur de fond est donnée par Parent->Brush->Color
    //Si on ne devait utiliser que 3 boutons sur les 4, Outside
    //permettrait de simuler un clic dans le vide...
    Outside = Parent->Brush->Color;
     
    //Brush, Pen et on efface avec la couleur du parent tout en
    //dessinant un cadre, puisque toute la surface est prise
    Canvas->Brush->Color = Outside;
    Canvas->Brush->Style = bsSolid;
    Canvas->Pen->Color = clBlack;
    Canvas->Pen->Style = psSolid;
    Canvas->Pen->Mode = pmCopy;
    Canvas->Rectangle(0,0,Width, Height);
     
    //Calcul des 8 points
    //Points[0] correspond au point le plus à droite les autres points en suivant.
    //J'ai opté pour ce type de calcul afin de garder une apparence similaire
    //quelles que soient les dimensions (dans les limites du raisonnable)
     
    Points[0] = Point(Width - 1, Height * 9 / 16);
    Points[1] = Point(Width * 12 / 24, Height * 9 / 16);
    Points[2] = Point(Width *  9 / 24, Height * 3 / 16);
    Points[3] = Point(Width *  6 / 24, Height *  3 / 16);
    Points[4] = Point(Width *  4 / 24, Height *  7 / 16);
    Points[5] = Point(Width *  4 / 24, Height * 13 / 16);
    Points[6] = Point(Width *  8 / 24, Height * 13 / 16);
    Points[7] = Point(Width * 10 / 24, Height - 1);
     
    //Dessin des lignes
     
    Canvas->Polyline(Points, 7);
    Canvas->MoveTo(Points[3].x, 0); Canvas->LineTo(Points[3].x, Points[3].y);
    Canvas->MoveTo(0, Points[4].y); Canvas->LineTo(Points[4].x, Points[4].y);
     
    //Remplissage des zones
     
    TColor color = (TColor)0x00000090;
    if(ActiveButton == red) color = clRed;
    Canvas->Brush->Color = color;
    Canvas->FloodFill(1,1, Outside, fsSurface);
     
    color = clNavy;
    if(ActiveButton == blue) color = (TColor)clAqua;
    Canvas->Brush->Color = color;
    Canvas->FloodFill(1, Height - 2, Outside, fsSurface);
     
    color = (TColor)0x00008A8A;
    if(ActiveButton == yellow) color = clYellow;
    Canvas->Brush->Color = color;
    Canvas->FloodFill(Width-2, Height-2, Outside, fsSurface);
     
    color = clGreen;
    if(ActiveButton == green) color = clLime;
    Canvas->Brush->Color = color;
    Canvas->FloodFill( Width - 2, 1, Outside, fsSurface);
    }
     
    void __fastcall jBanditBoyButton::SetActiveButton(int Value)
    {
    if(Value <= green)
        {
        FActiveButton = Value;
        Repaint();
        }
    }
     
    void __fastcall jBanditBoyButton::WhenMouseDown(TObject *Sender,
                TMouseButton Button, TShiftState Shift, int X, int Y)
    {
    //Les boutons fonctionnent en mode exclusion mutuelle
    //La dernière partie de l'arbre logique (facultatif) permet de revenir à état
    //initial, c'est à dire aucun bouton sélectionné.
    //La sélection est représentée par une teinte plus vive (approximativement)
     
    TColor Pixel = Canvas->Pixels[X][Y];
    if(Pixel == (TColor)0x00000090)
        {
        ActiveButton = red;
        }
    else
        {
        if(Pixel == clNavy)
            {
            ActiveButton = blue;
            }
        else
            {
            if(Pixel == (TColor)0x00008A8A)
                {
                ActiveButton = yellow;
                }
            else
                {
                if(Pixel == clGreen)
                    {
                    ActiveButton = green;
                    }
     
                //cette partie permet d'annuler la sélection
                //elle n'arrive que lorsque l'on clique sur un 
                //boutton déjà sélectionné 
                else
                    {
                    ActiveButton = none;
                    }
                }
            }
        }
    }
    Pour tester, j'ai fait bêtement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    jBanditBoyButton *BanditBoyButton;
     
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
    BanditBoyButton = new jBanditBoyButton(this, Rect(10,10,130,90));
    }
    En espérant que... !

    A plus !

  17. #17
    Membre émérite
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Par défaut
    C'est cool, la class marche bien, l'affichage est correct mais je n'ai pas d'affichage de couleur?
    Je ne vois pas trop d'où viens le soucis vu que tu passes bien color et tu l'affect à Brush.

  18. #18
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 417
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 417
    Par défaut
    Salut !

    Quand tu dis qu'il n'y a pas de couleurs, ça veut dire quoi au juste ...?

    Est-ce que tu vois les couleurs dans ces miniatures ?


    A plus !
    Images attachées Images attachées   

  19. #19
    Membre émérite
    Avatar de bandit boy
    Profil pro
    Inscrit en
    Février 2006
    Messages
    916
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 916
    Par défaut
    En fait nan.
    La couleur de chaque pièce dessinée à la base est de la couleur du fond de la form. Donc ActiveButton est false tout le temps.

  20. #20
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2005
    Messages
    351
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juin 2005
    Messages : 351
    Par défaut
    J'ai eu le même problème: surfaces vide. J'ai corrigé en mopdifiant le mode de remplissage des surfaces:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Canvas->FloodFill(1,1, clBlack, fsBorder);
    pour chaque FloodFill.

    C'est excellent comme ça marche bien

    [edit]En fait la couleur de fond obtenue par n'est pas la couleur de fond obtenue par . Lorsque je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    color = clGreen;
    if(ActiveButton == green) color = clLime;
    Canvas->Brush->Color = Outside;
    TColor fond=Canvas->Pixels[Width - 2][1];
    Canvas->FloodFill( Width - 2, 1, clBlack, fsBorder);
    je trouve fond=-1 et Outside= -16777201 (0xFFFFF1)[/edit]

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Créer bouton avec la forme qu'on veut
    Par ponpon17430 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 21/09/2006, 15h08
  2. [D7] comment savoir quel bouton appelle ma form ?
    Par dleu dans le forum Langage
    Réponses: 8
    Dernier message: 21/03/2006, 08h20
  3. [MySQL] plusieurs bouton dans 1 form
    Par vincedjs dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 16/02/2006, 09h40
  4. Prob, images, Panels, et form.
    Par CaptainChoc dans le forum Composants VCL
    Réponses: 2
    Dernier message: 10/05/2003, 10h08

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