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

 Delphi Discussion :

savoir si un objet est sur un autre (pas son parent)


Sujet :

Delphi

  1. #1
    Membre actif Avatar de Speed41
    Homme Profil pro
    Inscrit en
    Novembre 2002
    Messages
    718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 718
    Points : 210
    Points
    210
    Par défaut savoir si un objet est sur un autre (pas son parent)
    Bonjour,

    J'ai développé des objets à partir d'un TPanel que je nomme TPeriode

    Dans mon programme je place ces TPeriode sur un Tpanel (le parent) mais ne sont pas alignés. ils sont de petite taille. Leur position peu changer pendant l'utilisation du programme (programme pour générer des lignes de temps)

    Ce que je voudrais savoir c'est que quand je veux placer un TPeriode à un endroit donné savoir s'il ne va pas se superposer (partiellement ou totalement) à un autre TPeriode.

    Je place un TPeriode à un endroit sur mon TPanel mais est que sous ce TPeriode y en a pas déjà un qui serai alors caché.

    Pas facile à expliquer

    J'ai la possibilité de regarder tous les composants et quand c'est un TPeriode qui est sur le même parent calculer mais c'est long. S'il y avait une autre solution

    Merci

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Utilise un TFlowPanel qui gère la disposition automatique des Panels
    ou un TGridPanel, plus rigide

    Si tu n'as qu'un Panel contenant TOUS les TPeriode utilise Panel.ControlAtPos(Panel.ScreenToClient(CursorPos)) pour connaitre le contrôle sous la souris
    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

  3. #3
    Membre actif Avatar de Speed41
    Homme Profil pro
    Inscrit en
    Novembre 2002
    Messages
    718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 718
    Points : 210
    Points
    210
    Par défaut
    Je ne connais pas les objets TFlowPanel et TGridPanel, je suis sous Delphi 7. Je vais regarder pour plus d'infos.

    Les objets sont placés par le programme et non pas l'utilisateur.

    J'ai un tableau contenant des périodes (préhistoire, moyen age, Viking, vie de totore 1° ...) avec pour chaque période une date de début et une date de fin. Mon TPanel représente la totalité de la période que je souhait voir et donc en fonction de la plage de temps je ne vois pas les Tpériodes pareils

    Merci

  4. #4
    Membre actif Avatar de Speed41
    Homme Profil pro
    Inscrit en
    Novembre 2002
    Messages
    718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 718
    Points : 210
    Points
    210
    Par défaut
    Les deux objets sont trop rigides

    Suivant les paramétrages de l'utilisateur les périodes peuvent être n'importe ou verticalement dans le TPanel alors que sa position horizontale est fonction de la plage (de tel année à tel année) que je souhaite visualiser

  5. #5
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Speed41 : J'ai la possibilité de regarder tous les composants et quand c'est un TPeriode qui est sur le même parent calculer mais c'est long
    A mon avis c'est pourtant la solution la plus simple.
    Et pour éviter d'avoir à calculer sur la totalité des composants il suffit de donner aux propriétés des Tag des TPeriode une valeur quelconque commune TagPeriode mais différente de celles des autres composants et de placer dans la boucle un if d'évitement comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (components[i] is tPanel) and ((components[i] as tPanel).Tag <> TagPeriode) then Continue;
    // Lignes suivantes : Vérifier si "quand je veux placer un TPeriode à un endroit donné  s'il ne va pas se superposer à un des components[i]"
    Cela m'étonnerait qu'un simple if ralentisse notablement l'exécution sans oublier que le reste des calculs est assez simple donc rapide.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    Il n'y a même aucun calcul à faire
    Il suffit de comparer les BoundsRect par IntersectRect et IsRectEmpty.
    Sur un Delphi récent : MonPanel.BoundsRect.IntersectWith()

  7. #7
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-bonjour,

    Et avec un Delphi moins récent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var Ri : tRect; ASG : tPoint;
    begin
    ....
      Ri:=Panel1.BoundsRect; //<= Rectangle du components[i]
      ASG:=Point(Panel2.Left,Panel2.Top); //<= Angle Supérieur Gauche du TPeriode que l'on souhaite positionner
      if PtInRect(Ri,ASG)then ShowMessage('Panel2 empiète sur Panel1')
      else ShowMessage('Panel2 n''empiète pas sur Panel1');
    ...
    end;
    Testé sous D6 : marche.

    A+.

    EDIT : Oups, bien entendu il faut tester le if PtInRect sur les 4 angles du TPeriode que l'on souhaite positionner et pas seulement sur l'Angle Supérieur Gauche.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Testé sous D6 : marche.
    Si Panel2 est plus large ou plus haut que Panel1 et que les deux Panels sont centrés, c'est cuit
    Mieux vaut dans un premier temps tester l'intersection. Ensuite seulement on choisira s'il faut l'insérer ou l'ajouter en fonction d'un point.

  9. #9
    Membre actif Avatar de Speed41
    Homme Profil pro
    Inscrit en
    Novembre 2002
    Messages
    718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 718
    Points : 210
    Points
    210
    Par défaut


    Super merci.

    Je passais juste par une comparaison point à point mais la c'est mieux.

    merci à tous

  10. #10
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Oups, j'ai été pris de vitesse, mais voici quand même une solution plus complète :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function IlYaInstersectionRect(const R1, R2: tRect): boolean;
    // Renvoie True s'il y a intersection entre R1 et R2
    var a1, a2, a3, a4: tPoint; ok1, ok2: boolean;
    begin
      a1 := R1.TopLeft; a2 := Point(R1.Left, R1.Bottom);
      a3 := R1.BottomRight; a4 := Point(R1.Right, R1.Top);
      ok1:=(PtInRect(R2, a1) or PtInRect(R2, a2) or PtInRect(R2, a3) or PtInRect(R2, a4));
     
      a1 := R2.TopLeft; a2 := Point(R2.Left, R2.Bottom);
      a3 := R2.BottomRight; a4 := Point(R2.Right, R2.Top);
      ok2:=(PtInRect(R1, a1) or PtInRect(R1, a2) or PtInRect(R1, a3) or PtInRect(R1, a4));
      Result:=ok1 or ok2;
    end;
    Utilisation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if IlYaInstersectionRect(Panel14.BoundsRect,Panel11.BoundsRect) then ShowMessage('Panel14 empiète sur Panel11')
      else ShowMessage('Panel14 n''empiète pas sur Panel11');
    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut
    Tu te compliques quand même la vie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function IlYaInstersectionRect(R1, R2: tRect): boolean;
    begin
      IntersectRect(R1, R1, R2);
      Result := not IsRectEmpty(R1);
    end;

  12. #12
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Re-bonjour,

    Andnotor : Tu te compliques quand même la vie
    En fait je craignais que IntersectRect() et IsRectEmpty() n'existaient pas sous D6, mais vérification faite elles existent bien sous D6 ... j'aurais dû vérifier avant de compliquer.
    Ta solution est effectivement bien plus simple.

    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

  13. #13
    Membre actif Avatar de Speed41
    Homme Profil pro
    Inscrit en
    Novembre 2002
    Messages
    718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Novembre 2002
    Messages : 718
    Points : 210
    Points
    210
    Par défaut
    Moi je suis content, ça répond à ma question et en plus je ne connaissais pas, j'ai appris un truc de plus

    Merci

    Mise en pratique demain, vivement demain

  14. #14
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 263
    Points
    3 263
    Par défaut
    Bonjour,

    Speed41 : Moi je suis content, ça répond à ma question et en plus je ne connaissais pas, j'ai appris un truc de plus
    ... et moi c'est pareil, merci AndNotOr,
    ... et en plus en jetant un coup d'oeil dans l'Aide de D6 j'ai lu qu'en fait IntersectRect est une fonction et non une procédure en conséquence de quoi on peut encore simplifier comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function IlYaIntersectionRect(R1, R2: tRect): boolean;
    begin
      Result:=IntersectRect(R1, R1, R2); //<= IntersectRect renvoie True si l'intersection des deux rectangles n'est pas vide. Si R1 et R2 ne se chevauchent pas, IntersectRect renvoie False.
    end;
    Utilisation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if IlYaIntersectionRect(Panel14.BoundsRect,Panel12.BoundsRect) then ShowMessage('Panel14 empiète sur Panel12')
      else ShowMessage('Panel14 n''empiète pas sur Panel12');
    A+.
    N'oubliez pas de consulter les FAQ Delphi et les cours et tutoriels Delphi

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 683
    Points : 13 092
    Points
    13 092
    Par défaut

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 21/04/2007, 16h13
  2. [VB6] faire référence à un objet situé sur un autre form
    Par coyott dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 15/05/2006, 15h13
  3. Savoir si le cursor est sur une piece 3d
    Par Happy dans le forum OpenGL
    Réponses: 3
    Dernier message: 12/04/2006, 16h42
  4. Réponses: 5
    Dernier message: 10/01/2006, 17h23
  5. Comment savoir si la souris est sur un TChart ?
    Par marsupilami34 dans le forum Composants VCL
    Réponses: 1
    Dernier message: 30/09/2005, 23h16

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