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 :

Lier/Coller des TPanels


Sujet :

Composants VCL Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    230
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 230
    Par défaut Lier/Coller des TPanels
    Bonjour,

    Dans mon application, je cherche à connecter des objets (panels ou shapes dans l'idéal) entre eux.

    Dans une TForm, l'utilisateur dessine des schémas de machines complexes à l'aide de formes simples (cercle, rectangle...). L'utilisateur choisit sa forme en cliquant sur le bouton puis dessine la forme sur le canvas de la TForm. Je souhaite que les formes soient connectées entre elles et j'aimerais savoir comment le rendre visible graphiquement. Je détaille: j'ai 1 cercle et 1 rectangle qui ne sont pas connectés, je peux les déplacer indépendamment.
    --> Mon but est de les connecter visuellement: avec la souris, je rapproche le cercle du rectangle et hop le cercle et le rectangle se collent pour former une forme. Cette alors cette forme qui se déplace. Évidemment je dois pouvoir délier le cercle du rectangle.

    Je ne sais pas du tout par quel bout prendre ce bazar. Je ne sais même pas comment nommer cette fonction de "coller" 2 composants (j'ai regardé "dock" mais c'est pour les TForm). Est-ce que des propriétés/événements du TPanel, TShape, TadvPanel (TMS) permettent de faire cela ?


    Mes outils de dev:
    - XE5
    - VCL Delphi
    - VCL TMS Component Pack.

    Merci pour vos conseils et bonne fin d'année à vous

    LefjuCabro

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 772
    Par défaut
    Snap to - aimanter

    Comment coder cette fonctionnalité?

    Je commencerais par faire un voisinage qui va dépendre de la forme (*) et tester si un objet est dans ce voisinage.
    Si un objet est dans un voisinage on le colle (**).

    * -> par exemple: un cercle de rayon R, le voisinage serait compris entre une distance de R et (R + a)

    ** -> Il faut voir ce qui est le plus joli. Peut-être le coller en cherchant la plus petite distance entre les 2 formes

  3. #3
    Membre confirmé
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    230
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 230
    Par défaut
    Bonjour Foetus,

    Merci pour ta réponse.

    Je comprends comment coder cette fonctionnalité mais je bloque.

    Dans mon exemple, j'ai posé sur une forme 3 TPanel, je souhaite les déplacer à la souris et les aimanter lorsqu'ils sont proches. Pour déplacer les Panels, j'utilise le code ci-dessous dans le MouseDown des TPanels:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    const
      SC_DragMove = $F012 ;
    begin
      ReleaseCapture ;
      TPanel(Sender).Perform (WM_SysCommand, SC_DragMove, 0) ;
    end;
    Dans l'évènement MouseUp des TPanels, je code la fonction qui teste et aimante si nécessaire. Le problème est que l'évènement MouseUp ne se lance pas... Quelle erreur je fais ? Comment déplacer des TPanels (sachant que ces Panels contiendront ensuite des TImage) autrement ?

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 772
    Par défaut
    Tu confonds les évènements :-)

    L'évènement OnMouseUp est appelé lorsque tu relaches le bouton de la souris.

    http://docwiki.embarcadero.com/Libra...ol.OnMouseMove

    C'est l'évènement OnMouseMove qui permet de faire des actions lorsqu'on déplace la souris.

    OnMouseDown -> OnMouseMove -> OnMouseUp

    D'ailleurs cela serait mieux de tester quel bouton de la souris est appuyé et éventuellement si aucune touche est appuyée.

  5. #5
    Membre confirmé
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    230
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 230
    Par défaut
    J'ai placé mon code de déplacement dans le MouseDown puis sur le MouseMove (suite à tes conseils) mais j'ai toujours le même problème qui est que l'évènement MouseUp ne s'exécute pas.

    Mon évènement pour déplacer le TPanel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    procedure TForm1.Panel1MouseMove(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    const
      SC_DragMove = $F012 ;
    begin
      ReleaseCapture ;
      TPanel(Sender).Perform (WM_SysCommand, SC_DragMove, 0) ;
    end;
    Si je clique sur le Panel sans le déplacer alors l'évènement MouseUp s'exécute. C'est un peu dommage car c'est sur le MouseUp que je veux tester si je dois aimanter...

  6. #6
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 772
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 772
    Par défaut
    Citation Envoyé par lefju cabro Voir le message
    C'est un peu dommage car c'est sur le MouseUp que je veux tester si je dois aimanter...
    Dans ce cas, tu n'as qu'à faire un bouton "Tout aimanter"

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 937
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 937
    Par défaut
    Citation Envoyé par lefju cabro Voir le message
    Le problème est que l'évènement MouseUp ne se lance pas... Quelle erreur je fais ?
    En appelant ReleaseCapture, les messages souris ne sont plus envoyés à ce composant et tant que le bouton reste pressé, aucun autre ne sera sélectionné. Pourquoi ne pas simplement passer par MouseMove ?

    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
    var
      Pt :TPoint;
     
    procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    begin
      Pt := Mouse.CursorPos;
    end;
     
    procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    begin
      if ssLeft in Shift then
        with TControl(Sender) do
        begin
          Left := Left +Mouse.CursorPos.X -Pt.X;
          Top  := Top  +Mouse.CursorPos.Y -Pt.Y;
     
          Pt := Mouse.CursorPos;
        end;
    end;
    EDIT:
    Sinon ce que tu peux imaginer est de générer toi-même le up puisque dès que le bouton est relâché, le panel recapture à nouveau la souris (mais c'est pour le moins pervers) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ReleaseCapture;
    TPanel(Sender).Perform(WM_SysCommand, SC_DragMove, 0);
    Mouse_Event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);

  8. #8
    Membre confirmé
    Développeur informatique
    Inscrit en
    Décembre 2010
    Messages
    230
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2010
    Messages : 230
    Par défaut
    En appelant ReleaseCapture, les messages souris ne sont plus envoyés à ce composant et tant que le bouton reste pressé, aucun autre ne sera sélectionné
    Bonjour Andnotor, merci pour l'explication du ReleaseCapture.

    Ton code avec le TPoint est efficace.

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

Discussions similaires

  1. Coller des liens horizontalement
    Par Gary dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 03/03/2006, 09h27
  2. Réponses: 5
    Dernier message: 14/02/2006, 14h32
  3. [datagrid]lier avec des données
    Par Alex35 dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 11/12/2005, 10h10
  4. Transparence non désirée des TPanel
    Par Manopower dans le forum Composants VCL
    Réponses: 3
    Dernier message: 07/11/2005, 09h25
  5. Améliorations du "Copier / Coller" des XMLInstruct
    Par mchicoix dans le forum XMLRAD
    Réponses: 3
    Dernier message: 29/03/2005, 09h25

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