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 :

[Rio] Centrer un TscrollBox sur un composant avec scrollBy


Sujet :

Composants FMX Delphi

  1. #1
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    1 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 713
    Points
    5 713
    Par défaut [Rio] Centrer un TscrollBox sur un composant avec scrollBy
    Bonjour à tous,

    J'ai une app avec différents écrans gérés via TabControl.

    Dans un tab, j'ai un scrollbox que je veux obliger à afficher un objet situé hors de la zone d'affichage une seule fois quand le tab est affiché.

    La fonction scrollbox.ScrollBy me permet de décaler la zone d'affichage du scrollBox mais cela ne fonctionne que si le scrollbox est affiché avant d'appeler la fonction scrollBy (j'ai mon scrollbox affiché à l'écran qui est aligné en haut à gauche. Je clique sur un bouton qui appelle scrollBy et mon scrollbox déplace sa zone d'affichage pour montrer mon objet).

    Mon problème? Je veux que le scrollBy soit appelé automatiquement. Si j'appelle scrollBy avant l'affichage du tab ou juste après la ligne de code qui affiche le tab, scrollbox ne fonctionne pas (le scrollbox reste aligné en haut à gauche).

    J'ai essayé d'appeler le scrollby sur l'event TabControl.OnChange si le tab actif est celui qui accueille le scrollbox. Selon la doc, OnChange se produit immédiatement après la modification de l'onglet actif, scrollby est lancé mais ne fonctionne pas, le scrollbox reste aligné en haut à gauche.

    Est-ce que quelqu'un a une idée brillante? Peut-être sur un onPaint avec un système de flanc montant pour que scrollbox ne soit appelé qu'une fois?

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 029
    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 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    ça, c'est pas simple, genre mission pour "SuperFMX", cela AMHA me semble quand même compliqué !

    ça demande aussi d'autres explications :
    - Scrollbox ok, mais rempli comment ? Et, pourquoi ne serait-il pas positionné à ce moment là ?
    - La position est-elle mémorisée quelque part ?
    - S'agit-il d'une cibe windows ou pas uniquement (je suis frileux, je n'ai aucun idée si les windows messages (WM_) fonctionnent hors Windows, la faute au nom très certainement)

    J'ai essayé d'appeler le scrollby sur l'event TabControl.OnChange
    - Le code sur cet event ? Contient-il des beginupdate/endupdate ou équivalent sur le Scrollbox ?
    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

  3. #3
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    1 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 713
    Points
    5 713
    Par défaut
    Bonjour à tous,

    Réponses au "divinateur" SergioMaster:

    1. App pour Android, pas de beginupdate/endupdate sur le scollbox

    2. Le user se trouve sur un tab où il saisit un certain nombre de données

    3. En fonction des données saisies, des objets (genre TRectangle, TCircle, etc...) sont disposés via code dans le scrollbox à des positions qui peuvent dépasser sa zone d'affichage

    4. En fonction des données saisies, il faut rendre visible un objet particulier dont je connais précisément la position X et Y. (je vérifie donc en fonction de la position de cet objet s'il se trouve dans la zone visible du scrollbox, sinon je lance mon scrollby)

    5. Sur clic de l'utilisateur sur un bouton présent sur le tab de saisie des données, le tab où se trouve le scrollbox devient actif et offre le scrollbox à la vue du user

    Problème: si je lance mon scrollby alors que le tab où se trouve le scrollbox est actif, cela fonctionne... Par contre, si je lance par exemple mon scrollbox sur le clic du bouton permettant d'afficher ce tab, le scrollby ne s'applique pas au scrollbox.

    Idéalement, il faudrait disposer d'un event qui se déclenche une seule fois juste après que le tab avec le scrollbox se soit affiché (d'où mon essai avec le TabControl.OnChange qui est décrit comme se déclenchant après que le tab soit activé)

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 029
    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 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par Anselme45 Voir le message
    d'où mon essai avec le TControl.OnChange qui est décrit comme se déclenchant après que le tab soit activé
    Oui mais, le TabControl.onChange est capricieux (AMHA l'a toujours été même en VCL), tout dépend de comment le passage au tab se fait
    exemple : si c'est par Tabcontrol1.Tabindex:=n alors le onChange ne se lève pas, il faut que je vérifie quand on utilise une transition (tabcontrol.next ou prior)
    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

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 029
    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 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Bon, alors, après vérification, pour les Tabcontrol.tabindex:=n ou TabControl.next l'évènement OnChange est bien levé, de même l'index est bien bon (j'ai eu un doute)

    Voilà comment j'ai réussi à déplacer le scrollbox correctement (et il est bien question de beginupdate/endUpdate)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if TabControl1.TabIndex = 1 then
     begin
      TabItem2.BeginUpdate;  // la page contenant le scrollbox
      ScrollBox1.ScrollBy(ScrollBox1.ViewportPosition.X,ScrollBox1.ViewportPosition.y);  // se positionner à 0,0 
      ScrollBox1.ScrollBy(-x,-y);  // se positionner sur "l'objet" 
      TabItem2.EndUpdate; // redessine
     end;
    Le plus difficile : les fameuses positions (valeurs de x et y) qui n'ont rien à voir avec position.x position.y de l'objet
    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
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    1 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 713
    Points
    5 713
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Bon, alors, après vérification, pour les Tabcontrol.tabindex:=n ou TabControl.next l'évènement OnChange est bien levé, de même l'index est bien bon (j'ai eu un doute)
    Chez moi, le problème ne se situe pas au niveau de l'event OnChange. Sur le tab de saisie, un bouton lance le code "TabControl1.ActiveTab:=tabMAP ;" pour afficher le tab avec le scrollbox créé au préalable.

    J'ai le code suivant qui se déclenche:
    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
     
    procedure TForm1.TabControl1Change(Sender: TObject);
    begin
     if TabControl1.ActiveTab=tabMAP then
      begin
       tabMAP.BeginUpdate;
       ScrollBox1.ScrollBy(ScrollBox1.ViewportPosition.X,ScrollBox1.ViewportPosition.y);  // se positionner à 0,0
       ScrollBox1.ScrollBy(G_DeltaX,G_DeltaY);
       tabMAP.EndUpdate;
     
       ShowMessage('OnChange'); //Pour être sûr d'être passé par là
     
      end;
     
    end;
    Le tab tabMAP s'affiche avec le ScrollBox1 sans que le scrollby ait fait son job (la position affichée en haut à gauche = 0/0).

    Je clique sur un bouton que j'ai placé sur le tabMAP où se trouve le scrollbox avec une seule ligne de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ScrollBox1.ScrollBy(G_DeltaX,G_DeltaY);
    Et là le scrollBox réagit sous mes yeux et déplace comme prévu sa zone d'affichage pour faire apparaître l'objet cible (donc les valeurs X et Y du ScrollBy sont correctes).

  7. #7
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 029
    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 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Bigre, tu me fais douter.
    Aussi ai-je repris ce petit programme et l'ai fait tourner sur Androïd au cas où.
    Chez moi cela fonctionne
    Nom : Capture.PNG
Affichages : 163
Taille : 40,3 Ko
    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

  8. #8
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    1 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 713
    Points
    5 713
    Par défaut
    @SergioMaster:

    Hello, je te confirme que chez moi le scrollby ne fonctionne que si le scrollbox est visible

    Tu as fait tes tests avec quelle version de Delphi?

    Au final, j'ai résolu le problème via un bricolage: Quand le user demande l'affichage du tab qui accueille mon scrollbox, j'active un timer qui lance la commande scrollby de manière différée. J'ai donc le scrollbox qui apparaît à l'écran... 500 millisecondes plus tard le scrollby est lancé et... le scrollbox se décale pour afficher l'objet cible

  9. #9
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 029
    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 029
    Points : 40 928
    Points
    40 928
    Billets dans le blog
    62
    Par défaut
    Bonjour
    Citation Envoyé par Anselme45 Voir le message
    Tu as fait tes tests avec quelle version de Delphi?
    Tu avais indiqué Rio, donc c'est Rio 10.3.2

    Citation Envoyé par SergioMaster
    Le plus difficile : les fameuses positions (valeurs de x et y) qui n'ont rien à voir avec position.x position.y de l'objet
    Après quelques tâtonements ce matin (avant de me mettre au travail mais après le café) je pense que j'ai trouvé le calcul des positions

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Contenant:=Scrollbox1.ContentBounds.width // la largeur totale de la scrollbox (hors Scrollbars)
    Contenu:= Scrollbox1.Content.width // la largeur "visible" de la scrollbox
    .... je pense que vous devinez comment obtenir la partie verticale ;)
    Position:=ScrollBox1.ViewportPosition.X // La position horizontale actuelle
    ...
    Debut:= Objet.Position.X // position de l'objet
    largeur:= Objet.Width // largeur de l'objet
     
    dx0:=Contenu-(Contenant-Debut-largeur) // position par rapport à 0
    dx:=Position-dx0 // devrait faire l'affaire
    ...
    ScrollBox1.ScrollBy(dx,dy);
    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

  10. #10
    Membre extrêmement actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2017
    Messages
    1 778
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1 778
    Points : 5 713
    Points
    5 713
    Par défaut
    Citation Envoyé par SergioMaster Voir le message

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Contenant:=Scrollbox1.ContentBounds.width // la largeur totale de la scrollbox (hors Scrollbars)
    Contenu:= Scrollbox1.Content.width // la largeur "visible" de la scrollbox
    .... je pense que vous devinez comment obtenir la partie verticale ;)
    Position:=ScrollBox1.ViewportPosition.X // La position horizontale actuelle
    ...
    Debut:= Objet.Position.X // position de l'objet
    largeur:= Objet.Width // largeur de l'objet
     
    dx0:=Contenu-(Contenant-Debut-largeur) // position par rapport à 0
    dx:=Position-dx0 // devrait faire l'affaire
    ...
    ScrollBox1.ScrollBy(dx,dy);
    Par curiosité, j'ai essayé ton code...

    Et chez moi, l'objet n'est pas dans la zone visible: il reste à la limite extérieur de la zone visible du scrollbox!

    J'ai honte à le dire mais de mon côté avec un calcul simpliste, je retrouve toujours mon objet dans la zone visible (testé uniquement pour un objet avec hauteur et largeur identique)...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    dx:=ScrollBox1.Width-ObjetCible.Position.X-(2*ObjetCible.Width);
    dy:=ScrollBox1.Height-ObjetCible.Position.Y-(2*ObjetCible.Height);

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

Discussions similaires

  1. Focus sur un composant avec les boutons précédent et suivant de Safari
    Par roi_danton dans le forum Développement iOS
    Réponses: 0
    Dernier message: 30/08/2013, 16h30
  2. Réponses: 5
    Dernier message: 16/03/2009, 17h00
  3. Réponses: 6
    Dernier message: 22/01/2008, 14h16
  4. Position des composants sur une frame avec layout null
    Par bellemlih dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 14/12/2007, 22h13
  5. Centrer un composant avec netbeans/matisse
    Par clebig dans le forum NetBeans
    Réponses: 1
    Dernier message: 03/08/2006, 22h32

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