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 :

[10.4.2] Le nouveau TControlList


Sujet :

Composants VCL Delphi

  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut [10.4.2] Le nouveau TControlList
    Bonsoir,

    je teste ce nouveau composant à l'aune de FMX
    Côté design ok, je m'en sors
    Nom : Capture.PNG
Affichages : 846
Taille : 30,0 Ko
    par contre côté exécution
    Nom : Capture_1.PNG
Affichages : 791
Taille : 23,0 Ko

    Tout serait bien si ma zone de saisie était bien synchronisée, mais ce n'est pas le cas
    Comme c'est du nouveau, je ne m'attends pas à ce que beaucoup de vous se soit déjà attaquer à ça mais sait-on jamais.

    pour info, je m'attendais à ça (FMX)
    Nom : Capture_2.PNG
Affichages : 816
Taille : 74,4 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

  2. #2
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Bon, a priori il s'agit de mon choix de la source de données (PrototypeBindSource) le coupable.

    Alister Christie fait ici une démo avec un remplissage "à la main"


    j'ai voulu faire son pendant avec LiveBindings (et sans une ligne de code)
    Nom : Capture.PNG
Affichages : 731
Taille : 67,8 Ko

    Là, c'est ok, tout est synchro.

    pprem peut donc être rassuré , je ne le coincerai pas lors de sa présentation de la 10.4.2 le le mardi 23 mars entre 14 et 16 heures
    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
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Ce matin, il m'est venu à l'idée d'utiliser une autre des propriétés de ce TControlList : ColumnLayout=cltMultiLeftToRight afin de faire des vignettes. (toujours avec les livebindings)
    Nom : Capture.PNG
Affichages : 750
Taille : 39,6 Ko
    C'est relativement simple à réaliser il suffit d'indiquer une largeur d'item (propriété ItemWidth) supérieure à 0.

    C'est ok sauf deux petits points
    1- le nombre de colonnes calculées
    sans dévoiler tout le source voilà le calcul
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      if (InternalColumnLayout = cltMultiLeftToRight) and (Result * GetItemWidth(True) < ClientWidth) then
        Inc(Result, 2);
    mais pourquoi un Inc(Result,2) forçant le curseur horizontal. Je m'étais attendu à avoir le simple calcul : largeurdeliste divisé par largeursdélément.
    en bref ce calcul est "étrange"

    2- Dans le même ordre d'idée, le onResize de la forme n'est pas pris en compte. Ainsi ma liste qui est alignée au client garde le nombre de colonnes précalculées ( ici 7)
    sauf peut-être à coder dans l'évènement onresize de la forme bien sûr

    Enfin, c'est peut-être voulu ?

    Par contre en utilisant ColumnLayout=cltMultiTopToBottom, c'est nickel
    Nom : Capture_.PNG
Affichages : 735
Taille : 46,8 Ko

    Maintenant que ceci est testé, mon prochain objectif sera d'utilisé ces mêmes propriétés avec un remplissage "à la main" pour les données, une sorte d'images browser. La suite au prochain post.

    Si vous avez d'autres idées d'applications de ce composant n'hésitez pas à en faire part
    Il y a encore beaucoup à investiguer
    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

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut Image browser
    Bon, j'ai un peu triché (utilisation d'un composant tms pour sélectionner un répertoire), ce n'est pas encore totalement au point pour le nom du fichier, pour la recherche de toutes les images pas que les .png,
    sans parler du crènelage dû au stretch de l'image.
    Mais, le résultat est là.
    Nom : Capture_1.PNG
Affichages : 819
Taille : 50,2 Ko

    Peu de code ont été nécessaire, quelques astuces à connaitre
    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
     private
        { Déclarations privées }
        FileList : TArray<String>;
      public
        { Déclarations publiques }
      end;
    
    var
      Form11: TForm11;
    
    implementation
    
    {$R *.dfm}
    
    
    procedure TFormList.AdvDirectoryChange(Sender: TObject);
    begin
    if DirectoryExists(advDirectoryEdit1.Text) then
      begin
        ControlList3.Enabled:=False;   // désactiver le TControlList
        FileList:=TDirectory.GetFiles(advDirectoryEdit1.Text,'*.png'); // récupérer la liste des fichiers images // todo : toutes les images 
        ControlList3.ItemCount:=Length(FileList); // indiquer le nombre d'éléments que contiendra la liste    
        ControlList3.Enabled:=True; // activer la liste (ce qui lancera le onBeforeDrawItem)
      end;
    end;
    
    procedure TFormList.ControlList3BeforeDrawItem(AIndex: Integer; ACanvas: TCanvas;
      ARect: TRect; AState: TOwnerDrawState);
    begin
    if Length(FileList)=0 then exit; // par précaution
    // mettre les informations
    LabelBrowser.Caption:=TPath.GetFileNameWithoutExtension(FileList[Aindex]);
    ImageBrowser.Picture.LoadFromFile(FileList[Aindex]);
    end;
    J'avais craint plus compliqué.
    Prochaine étape, qui va quelque peut se rapporter à mon post 1, utiliser un protypebindsource, remplir au démarrage l'ensemble de données (à la manière de ce tutoriel) et voir ce qui se passe
    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 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut TProtypeBindSource, décidement, le bogue
    Prochaine étape, qui va quelque peu se rapporter à mon post 1, utiliser un protypebindsource, remplir au démarrage l'ensemble de données et voir ce qui se passe
    J'avoue avoir beaucoup galéré hier (la matinée seulement quand même) car la rédaction du tutoriel citée n'était pas récente et je suis tombé dans le piège bête des noms de champs qui ne correspondaient pas aux propriétés de mes objets . Une bonne nuit de sommeil à mis fin à ce calvaire.

    Nom : Capture.PNG
Affichages : 676
Taille : 21,3 Ko

    Comme vous le constaterez j'avais même poussé le vice à utiliser une image (à remplir à partir d'une TimageList) et donc utiliser un mélange Livebindings et code (minime)
    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
     
    procedure TUmain.ControlList1BeforeDrawItem(AIndex: Integer; ACanvas: TCanvas;
      ARect: TRect; AState: TOwnerDrawState);
    begin
    ImageList1.GetBitmap(MesEvenements[AIndex].importance,MgRappel.Picture.Bitmap);
    end;
     
    procedure TUmain.FormCreate(Sender: TObject);
    begin
    LinkGridToDataSourcePrototypeBindSource1.Active:=true;  // équivalent d'un open ?
    end;
     
    procedure TUmain.PrototypeBindSource1CreateAdapter(Sender: TObject;
      var ABindSourceAdapter: TBindSourceAdapter);
    begin
     P_DonneesInternes;
     ABindSourceAdapter:=TListBindSourceAdapter<TEvenement>.Create(self,MesEvenements, True);
    end;
    Le remplissage s'effectue correctement. Le seul hic est donc bien la synchronisation qui ne s'effectue pas entre le TProtypeBindSource et le TControlList. (vous remarquerez que la zone de saisie est remplie avec la dernière ligne visible et non l'élément sélectionné, "Tests" au lieu de "Cahier des Charges")
    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
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut Faut-il raison garder ?
    Je pense que ce sera désormais la fin de ce monologue, qui d'ailleurs pourrait faire l'objet d'un tutoriel ou d'une suite de billets.

    Esprit critique oblige, j'ai voulu faire une comparaison avec un TDBControlGrid car, après, tout ce TControlList y ressemble fort.
    * Oui, si vous suivez les différentes étapes j'ai ajouté une propriété IndexfieldNames = Common_Name (en fait pour vérifier le remplissage de mon post #2), pour info malgré le nom de la propriété ColumnLayout=cltMultiTopToBottom le remplissage se fait de gauche à droite, et de haut en bas.

    Nom : Capture.PNG
Affichages : 699
Taille : 52,9 Ko
    Constatation :
    • Dans cette grille on peut ajouter quelques composants liable (pas tous mais TDBEdit, TDBMemo, TDBText, TDBCheckBox) donc . D'un autre côté, TControlList n'accepte que des composants descendants de TGraphicControl ( oui il est temps de ressortir notre vieux poster des controles VCL pour savoir lesquels en font partie )
    • On ne peut pas par contre avoir plusieurs colonnes
    • On ne peut pas (à ma connaissance) mettre de boutons (comme le TcontrolListButton)
    • Sans investiguer en profondeur, je pense que ce DBControlGrid se comporte au remplissage comme un TDBGrid a contrario TControlList doit se comporter comme le TListView FMX (chargement de l'ensemble de données entier) j'aurai donc tendance à lui ajouter un mais, c'est une question de nombre "raisonnable" d'enregistrements et de temps "raisonnable" de remplissage chacun y voyant "midi à sa porte".


    TControlList semble donc une nouveauté intéressante mais à utiliser en fonction des objectifs visés.
    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

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Juste histoire de ne pas te laisser seul

    J'ai aussi fait un petit essai rapide (mono-colonne uniquement) et franchement je ne suis pas convaincu. Ca va pour faire une liste style "Contacts" mais sans plus.

    Limité à des TGraphicControl. On oublie les alignements à base de panel et on doit se contenter du basique (ex. un alTop est prioritaire sur un alLeft). Ce que j'aurais souhaité est pouvoir avoir un titre éventuellement multilignes avec décalage du texte suivant (la description) et placé à droite de l'image. Le principe des alTop avec des Label en AutoSize ou encore mieux de RelativePanel.

    Un Align-right est correctement positionné mais un Anchors-right passe sous la barre de défilement. La position n'est pas calculée par rapport à la zone cliente. On oublie les alignements à droite.

    Et ce que j'aurais surtout voulu est un composant avec hauteur de ligne variable (au minimum en mono-colonne).

    En bref, l'avantage de ce composant par rapport à une ListBox en lbVirtualOwnerDraw est qu'on utilise un Label à la place d'un Canvas.TextOut, vraiment anecdotique


    ps: j'attends toujours que la ListBox supporte un lbVirtualOwnerDrawVariable...

  8. #8
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    alors j'ai regardé rapidement le code du composant, de ce que je vois, on a une seule instance des composants, pour chaque item à dessiner les champs sont initialisés puis on fait une capture dans un Bitmap qui est ensuite dessiné à l'écran...ça évite d'instancier plusieurs fois les composants.

    j'imagine que la capture ne fonctionnait pas bien pour certains WinControl, d'où la limitation aux TGraphicControl

    et donc, l'idée au départ est simple, je fixe ItemHeight et je colle des composants...reste plus qu'à fixer ItemCount et hop on a un copier/coller de l'image des composants là où il faut (c'est à dire dans la limite ce de qui est visible) avec des OnXXX avec un paramètre Index quand il faut mettre à jour les composants pour l'item n° Index...les différents évènements me semblent un peu confus...un seul OnBeforeDrawItems qui fait tout aurait peut-être été suffisant...ou en tout cas plus simple à comprendre.

    Pour avoir des hauteurs variables il faudrait avoir un OnItemHeight() et jouer sur les composants dynamiquement...ou alors pouvoir s'appuyer sur plusieurs templates de composants en fonction du besoin...image à droite, image à gauche.

    en fait les composants qui font tout c'est bien mais ça fini toujours un peu en usine à gaz, ce qui m'amène souvent à créer un composant sur mesure qui répond bien à mon besoin du moment...plutôt que de faire rentrer mon besoin dans un composant plus ou moins adapté.

    bref, le composant ne fait pas tout, mais s'il fait correctement ce qu'il est supposé faire c'est pas mal déjà
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  9. #9
    Rédacteur/Modérateur

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

    En fait, je suis d'accord, pour l'instant je propose la découverte avant de commencer à forger un peu.
    Pour reprendre l'analogie de mes billets récents, passer à l'étape :
    Nom : scaphatwork.PNG
Affichages : 649
Taille : 297,0 Ko

    Citation Envoyé par Paul
    les différents évènements me semblent un peu confus...un seul OnBeforeDrawItems qui fait tout aurait peut-être été suffisant...ou en tout cas plus simple à comprendre.
    Il y a les deux OnBeforeDraw et OnBeforeDrawItems, (sans parler des After) pour l'instant je ne vois pas à quoi peut servir le second beaucoup moins "complet" quand aux nombres de paramètres.
    l'idée au départ est simple, je fixe ItemHeight et je colle des composants...reste plus qu'à fixer ItemCount et hop on a un copier/coller de l'image des composants là où il faut (c'est à dire dans la limite ce de qui est visible) avec des OnXXX avec un paramètre Index quand il faut mettre à jour les composants pour l'item n° Index.
    oui mais pas que, on peut fixer l'itemwidth. Savoir si on peut mettre des composants au runtime, en plus, en dehors des clous etc. me semble une idée à fouiller.

    @Andnotor Pas de quoi fouetter un chat oui, peut-être, mais pour un débutant, le confort !

    Cela écrit nous avons tous nos habitudes. Ne faisant plus ou presque que des programmes FMX, je voulais pousser le bouchon dans les nouvellee eaux de la VCL en mode vacances. Mais il n'est pas dit que je ne passe pas en mode méchant en fin de course
    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
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par SergioMaster Voir le message
    Il y a les deux OnBeforeDraw et OnBeforeDrawItems, (sans parler des After) pour l'instant je ne vois pas à quoi peut servir le second beaucoup moins "complet" quand aux nombres de paramètres.
    BeforeDrawItems c'est au tout début, ça permet de fixer le Canvas en général, BeforeDrawItem c'est avant le dessin d'un item (c'est là qu'on doit pouvoir définir Enabled, Visible...)....du coup je pensais plus à OnEnableControl et OnShowControl...pourquoi les avoir mis de côté ?
    Citation Envoyé par SergioMaster Voir le message
    oui mais pas que, on peut fixer l'itemwidth. Savoir si on peut mettre des composants au runtime, en plus, en dehors des clous etc. me semble une idée à fouiller.
    oui je parlais de l'idée de départ...il y a d'autres subtilités
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  11. #11
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    du coup je pensais plus à OnEnableControl et OnShowControl...pourquoi les avoir mis de côté ?
    Tout simplement par ce que je découvre le composant sans en avoir lu la doc (enfin s'il y en a)
    Citation Envoyé par Paul TOTH Voir le message
    ..il y a d'autres subtilités
    Il y a pléthore, je voulais les amener petit à petit en commençant (très) doucement.

    Déjà il y a des points qui me semblent des alors .. je continue tranquillement mon tour d'exploration avant.
    Rien que le Canvas nécessite une plongée de niveau 2 pour l'instant il s'agit d'un baptème
    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

  12. #12
    Rédacteur/Modérateur

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

    Je continue mon exploration de TControlList
    Citation Envoyé par Paul Toth
    je pensais plus à OnEnableControl et OnShowControl...pourquoi les avoir mis de côté ?
    Du coup ce todo là est fait

    J'en suis maintenant au dragdrop.
    Problématique : Savoir quel item de la liste reçoit le "drop". Il n'y a aucun ItemAtPos (du moins en fonction privée ou protégée) donc j'ai procédé ainsi :
    1-création d'un collection (Tdictionnary) qui contient les items ItemsVisibles:=TDictionary<Integer,TRect>.Create;2-réinitialisation à chaque nouveau dessin du controllist (utilisation ControlList1BeforeDrawItems) ItemsVisibles.Clear;3-Utilisation de ControlList1AfterDrawItem(AIndex: Integer; ACanvas: TCanvas; ARect: TRect; AState: TOwnerDrawState) pour "mémoriser" les items créés
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ARect.Offset(0,ARect.Height*AIndex);
    ItemsVisibles.AddOrSetValue(AIndex,ARect);
    Rectangles récupérés
    //AfterDrawItems 0 - Rect 0,0,365,70
    //AfterDrawItems 1 - Rect 0,70,365,70
    //AfterDrawItems 2 - Rect 0,140,365,70
    //AfterDrawItems 3 - Rect 0,210,365,70
    4- céation de ma propre fonction ItemAtPos .// Ok, il faudra certainement ajouter d'autres arguments comme la collection concernée en cas d'utilisation "intensive"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function itematpos(X,Y : Integer) : Integer;
     var aRect : TRect;
         Items : TArray<TRect>;
         i: Integer;
     begin
       Items:=ItemsVisibles.Values.ToArray;
       Result:=-1;
       for i:=0 to ItemsVisibles.Count-1 do
        begin
         if Items[i].Contains(TPoint.Create(X,Y)) then Exit(i)
        end;
     end;
    Nom : Capture.PNG
Affichages : 632
Taille : 73,6 Ko

    La question du jour : J'ai raté quelque chose dans le point 3 ! car ma fonction ne me fourni pas le bon Item.

    Les rectangles récupérés me semblent juste aussi je penche pour un problème dans le code du point 4.
    Questions : les coordonnées X et Y du EndDrag(Sender, Target: TObject; X, Y: Integer); ou du DragDrop(Sender, Source: TObject; X, Y: Integer ) correspondent à quoi exactement, faut-il les "triturer" ?
    Ou est-ce ma fonction ItemAtPos qui déconne ?
    // Drop sur le T de chaque élément
    drop sur item 1 position X=78,Y=10 AIndex=1
    drop sur item 2 position X=79,Y=80 AIndex=3
    drop sur item 3 position X=77,Y=153 AIndex=2
    drop sur item 4 position X=78,Y=221 AIndex=0
    je me réponds : Items de la fonction ItemAtPos n'est pas dans l'ordre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Item 0 Rectangle 0,210,365,70
    Item 1 Rectangle 0,0,365,70
    Item 2 Rectangle 0,140,365,70
    Item 3 Rectangle 0,70,365,70
    drop sur item position X=82,Y=13 AIndex=1
    Pendant que j'y suis Alistair Christie à fait deux autres vidéos sur TControlList
    ça a été ma première remarque sur sa première vidéo : "Pourquoi n'avoir pas utiliser les livebindings pour son exemple biolife !"
    https://learndelphi.tv/278-tcontrollist2

    Confuse mais du "Monde réel"
    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

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

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 685
    Points : 13 102
    Points
    13 102
    Par défaut
    Il y a la propriété protégée TCustomControlList.FirstDrawItemIndex (non publiée dans TControlList, un oubli sans doute ).

    Avec elle, ce serait simplement FirstDrawItemIndex +Y div ItemHeight.

  14. #14
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Merci, il y en a au moins un qui suit
    Citation Envoyé par Andnotor Voir le message
    Il y a la propriété protégée TCustomControlList.FirstDrawItemIndex (non publiée dans TControlList, un oubli sans doute ).
    Avec elle, ce serait simplement FirstDrawItemIndex +Y div ItemHeight.
    Ah, zut, je l'ai ratée celle là ! Il va falloir que je teste en attendant j'ai trouvé ce qui déconnait dans ma fonction : itematpos. Avantage pas besoin de hacker la classe ou de faire un helper

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     function itematpos(X,Y : Integer) : Integer;
     var i: Integer;
         ARect : TRect;
     begin
       Result:=-1;
       for i:=0 to ItemsVisibles.Count-1 do
        begin
          if ItemsVisibles.TryGetValue(i,ARect) AND
            ARect.Contains(TPoint.Create(X,Y)) then
          begin
            exit(i);
          end;
        end;
     end;
    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

  15. #15
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    J'ai repris l'idée d'AndnotOr avec un Helper
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     TControlListHelper = class helper for TCustomControlList
      public
       function ItemAtPos(X,Y : Integer) : Integer;
      end;
     
     
    { TControlListHelper }
    function TControlListHelper.ItemAtPos(X, Y: Integer): Integer;
    begin
    result:=FirstDrawItemIndex+Y div ItemHeight;
    end;
    Reste le challenge quand on utilise des ColumnLayout autres que cltSingle , en gros tout ce qui est largeur d'élément<>0. Mais j'ai appercu un ItemAtPos en private quelque part donc, cela ne devrait pas trop poser de soucis.

    Du coup cela me rappelle un vieux post "une sorte de QCM avec images" qui ferait plus "monde réel" que ce programme théorique du week-end Pascal ...

    NOTA BENE : Il faut savoir que les contrôles posés (le peu que l'on puisse mettre : des TGraphicControls) n'ont aucune "réaction" à leurs évènements. Pas de OnDragOver par exemple.
    autres exemples : on peut mettre un TSplitter : aucun effet si ce n'est le dessin, un TSpeedButton sans onClick (c'est sans aucun doute la raison du TControlListButton)
    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

  16. #16
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Alors que ce soit avec ma fonction ou le helper il reste un cas qui coince
    Nom : Capture.PNG
Affichages : 594
Taille : 65,9 Ko
    Dans cette image, on voit que les Items du haut et du bas (moins grave pour le bas) ne sont afficher que partiellement.
    Il y a donc cette partie à prendre en compte.

    Obtenir la position du scrollbox : c'est possible même si FScrollBoxPosition du TCustomControlList ne l'est pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
         si: TScrollInfo;
    begin
      si.cbSize := sizeof(si);
      si.fMask := SIF_POS;
      GetScrollInfo(ControlListSingle.Handle, SB_VERT, si);
      ScrollPosition:=Si.nPos;
    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

  17. #17
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 031
    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 031
    Points : 40 930
    Points
    40 930
    Billets dans le blog
    62
    Par défaut
    Un jour je saurais peut-être mettre des vidéos directement
    Nom : 2021-04-04_115026.png
Affichages : 569
Taille : 102,4 Ko
    Play me
    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

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

Discussions similaires

  1. Nouveau tutoriel de Benoît-M
    Par Smortex dans le forum x86 16-bits
    Réponses: 28
    Dernier message: 28/11/2005, 01h00
  2. Création d'un nouveau skin
    Par TOM-Z dans le forum XMLRAD
    Réponses: 8
    Dernier message: 18/03/2003, 17h14

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