[RESOLU] ComboBoxGadget() éditable.

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

[RESOLU] ComboBoxGadget() éditable.

Message par Fig »

Bonjour,

Je manque vraiment de pratique en ce qui concerne la GUI. Voici donc ma question.

Quand on édite une ligne d'un ComboBoxGadget(), comment récupérer le texte (GetGadgetText() ça c'est ok) puis remplacer la (bonne) ligne édité par celui-ci lors de l'appuie de [Return/Enter] ou en perdant le focus à la fin de l'édition ?

Par exemple, comment changer un des "test" de la ligne ?

Code : Tout sélectionner

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 Or OpenWindow(0, 0, 0, 200, 400, "Scan test", #PB_Window_SystemMenu)=0 Or CanvasGadget(0,0,0,200,400,#PB_Canvas_Container)=0:End:EndIf
ContainerGadget(1,10,10,180,300,#PB_Container_Raised)
ComboBoxGadget(2, 10, 10, 160, 21, #PB_ComboBox_Editable)
AddGadgetItem(2, -1, "test1")
AddGadgetItem(2, -1, "test2")
AddGadgetItem(2, -1, "test3")

Repeat
    Repeat
        event=WindowEvent()
        If event=#PB_Event_CloseWindow:Break 2:EndIf
        If event=#PB_Event_Gadget
            gadget.i=EventGadget()
            If gadget=2
                type.i=EventType()
                If type=#PB_EventType_LostFocus
                    text.s=GetGadgetText(2)
                    SetGadgetItemText(2,1,text)
                EndIf
            EndIf    
        EndIf    
    Until event=0
    Delay(5)
ForEver
Dernière modification par Fig le dim. 27/mai/2018 13:38, modifié 3 fois.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: ComboBoxGadget() éditable.

Message par Ollivier »

(en anglais)
SetGadgetItemText(1er item = n°0)
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: ComboBoxGadget() éditable.

Message par Fig »

Comment j'obtiens le numéro de l'item modifié et à quel moment je dois modifier le texte ?

J'ai posté un simili code...

Je ne suis pas sûr d'être clair...
Admettons que je selectionne la ligne 2, "test2". Je veux changer cet intitulé en autre chose en tapant au clavier, puis en appuyant sur [enter].
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: ComboBoxGadget() éditable.

Message par Ollivier »

Je pense que ça,

Code : Tout sélectionner

type=#PB_EventType_LostFocus
ce n'est pas la bonne voie à emprunter. Il manque peut-être quelque chose dans ton explication. Si je comprends bien tu veux :

cn) = condition n

n] = action n




0] Boucle de capture d'événement et synchro (I/O)

c1) Combo cliqué

1] Déroulement combo

c2) Item combo sélectionné

2] Mémorisation n° item puis Ajournement texte combo

c3) Texte modifié ET touche Entrée

3] Modification item précédemment sélectionné (mémorisé en action 2) par le texte du combo


C'est à peu près ça que tu veux?
(attention plus de batterie et en déplacement donc réponse vers 6H demain, si pas de correction de ta part de ce graf, je ferai un petit code à partir de ça...)
Dernière modification par Ollivier le ven. 25/mai/2018 19:50, modifié 1 fois.
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: ComboBoxGadget() éditable.

Message par Fig »

Oui, c'est ça... Ça me semble être une utilisation très banale de ce type de gadget... Ou c'est moi qui suis tordu ? :roll: (question purement rhétorique, merci de ne pas me répondre là dessus, l'ignorance est un bonheur parfois...)

Donc étape c3 et 3] dans ton énumération.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: ComboBoxGadget() éditable.

Message par Ollivier »

Oui : si texte modifié ET touche Entrée

Code : Tout sélectionner

OldTxt.s = Txt.s
Txt = GetGadgetText(ggt)
TexteModifié = Bool(OldTxt <> Txt)
Pour "Touche Entrée", je bute... Sûrement un Type_Event_Change qui doit être filtré pour ne pas snifer ta modification d'item (boucle infinie sinon).

Je ne peux pas plus malheureusement avant demain matin (peut-être qu'on fera doublon !)
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: ComboBoxGadget() éditable.

Message par Fig »

Merci pour ton aide.
Ça me semble pourtant intuitif quand on modifie une ligne comme ça, de valider la modification par [Enter]... (sinon comment savoir qu'on a fini la saisie ??)

Bon, peut être que quelqu'un d'autre sait...
Ça devrait pourtant être trivial, non ?
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
Ar-S
Messages : 9472
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: ComboBoxGadget() éditable.

Message par Ar-S »

Regarde du coté de eventmenu() les raccourcis clavier
ainsi tu lorsque tu utilises ton

Code : Tout sélectionner

AddKeyboardShortcut(tafenetre, #PB_Shortcut_Enter , #IDraccourcis)
dans les eventmenu
tu peux peux tester si

Code : Tout sélectionner

getgadgettext(n, text.s) <> tonpremiertext.s
et en faire ce que tu veux
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: ComboBoxGadget() éditable.

Message par falsam »

J'ai repris ton code et ajouter ces petits binds que j'affectionne particulièrement.

Tu vas utiliser l'environnement 2D et je pense que tu devrais garder ta boucle Repeat ... ForEver uniquement pour les instruction 2D :wink:

J'ai utilisés les instructions Bind* pour ajouter
- Un événement pour ton combogadget 2 qui fera appel à la procédure SelectItem()
- Un événement sur la touche Entrée qui fera appel à la procédure ValidItem()
- Un événement pour la fermeture de la fenêtre qui fera appel à la procédure Exit()

Si la touche Entrée gère plusieurs gadgets, alors il faudra tester EventGadget() dans la procédure ValidItem()

Code : Tout sélectionner

#Return = 101

Global Index = #PB_Ignore

Declare SelectItem()
Declare ValidItem()
Declare Exit()

If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 Or OpenWindow(0, 0, 0, 200, 400, "Scan test", #PB_Window_SystemMenu)=0 Or CanvasGadget(0,0,0,200,400,#PB_Canvas_Container)=0
  Exit()
EndIf

ContainerGadget(1,10,10,180,300,#PB_Container_Raised)

ComboBoxGadget(2, 10, 10, 160, 21, #PB_ComboBox_Editable)
AddGadgetItem(2, -1, "test1")
AddGadgetItem(2, -1, "test2")
AddGadgetItem(2, -1, "test3")

;Ajouter l'evenement de la touche Entrée
AddKeyboardShortcut(0, #PB_Shortcut_Return, #Return)  
BindEvent(#PB_Event_Menu, @ValidItem())

;Evenement gadget 2
BindGadgetEvent(2, @SelectItem())

;Evenement de sortie
BindEvent(#PB_Event_CloseWindow, @Exit())

Repeat  
  Repeat : Until Not WindowEvent()  
  
  Delay(5)
ForEver

;Mémoriser l'index de l'item
Procedure SelectItem()
  If GetGadgetState(2) <> -1
    Index = GetGadgetState(2)
  EndIf   
EndProcedure

;Mettre à jour l'item du combogadget en cours d'edition
Procedure ValidItem()
  Protected Text.s
  
  If Index <>  #PB_Ignore
    ;Mémorisation du texte en cours de saisie
    Text = GetGadgetText(2)
    
    ;Mise à jour de l'item
    SetGadgetItemText(2, Index, Text)
  EndIf 
EndProcedure

Procedure Exit()
  End
EndProcedure
Sélectionne un des item de ta combo. Modifie le et presse la touche Entrée. Si aucune sélection alors aucune mise à jour (of course)
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: ComboBoxGadget() éditable.

Message par Ollivier »

Voilà comment ça se présente :

Code : Tout sélectionner

If OpenWindow(10, 0, 0, 270, 180, "Combo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
        ComboBoxGadget(20, 10, 10, 250, 21, #PB_ComboBox_Editable)
        SetGadgetData(20, ComboCreate(10, 20, 1) )        
        AddGadgetItem(20, -1, "Option A")
        AddGadgetItem(20, -1, "Option B")
        AddGadgetItem(20, -1, "Option C")
        SetGadgetState(20, 1)       
        Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Donc, ça reste assez simple : il faut rajouter la ligne suivante :

Code : Tout sélectionner

SetGadgetData(gadget, ComboCreate(window, gadget, itemChoisi) )
Comme la présentation de code est imbouffable, je te mets le code en mp. Il suffit de faire un Ctrl+I et, éventuellement corriger des retour chariot qui n'ont pas lieu d'être. Si tu peux le poster après ça, ce serait arrangeant.
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: ComboBoxGadget() éditable.

Message par Ollivier »

Note : En voyant le code de Falsam, on pourrait penser à un dérivé de plaggia, mais, il s'agit bien d'une différence de rythme d'accès de réseau (je viens de me reconnecter il y a une demi heure...). Ne pouvant exécuter son code à l'instant, je ne peux pas savoir si on aboutit à la même ergo.

Les idées d'ArS (utilisation d'un menu fantôme) et de Falsam (filtrer l'état de gadget de valeur -1) y sont.

Je me suis retenu à l'ergo suivante :
Pour l'item sélectionné
- Touche [Entrée] : modifie l'item préalablement sélectionné
- Perd le focus : annule et réaffiche le texte initial de l'item sélectionné.
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: ComboBoxGadget() éditable.

Message par falsam »

Ollivier a écrit :En voyant le code de Falsam, on pourrait penser à un dérivé de plaggia
Non mais tu vas pas bien toi !
Ollivier a écrit :mais, il s'agit bien d'une différence de rythme d'accès de réseau
Faut être en forme voir même inconscient pour essayer de te plagier :mrgreen:

Le code que je propose à Fig dans mon message précédent est fonctionnel et basé uniquement sur l’événement de la touche Entrée et pas sur cette idée farfelue de prise ou perte de focus sur le gadget.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: ComboBoxGadget() éditable.

Message par Ollivier »

Falsam a écrit :Faut être en forme voire même inconscient pour essayer de te plagier
Non c'est surtout qu'on n'a pas trop le choix en natif.

Les problèmes que j'ai rencontrés sont forcément ceux que tu as rencontrés aussi (pareil pour Ar-S)

- comment détecter la touche [Entrée] ?
solution : un raccourci qui exige un menu "fantôme" (parceque spécifique à ce raccourci)

- comment déterminer préalablement l'item sélectionné ?
solution : détecter un type_change mais exclure la valeur -1.

Pour le plaggia : dans l'autre sens Falsam, t'as compris l'info à l'envers là! Je te poste le code en mp (Je ne le publie pas parce que je ne sais pas dans quel état il apparaît). Mais il contient les mêmes solutions que vous.
pas sur cette idée farfelue de prise ou perte de focus sur le gadget.
Là je ne saisis pas trop pourquoi "farfelu" alors que ça me semble nécessaire, au moins de répondre à ces événements, sinon il y a risque d'artefacts.
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: ComboBoxGadget() éditable.

Message par Ollivier »

Après un peu d'huile de code pour afficher du coude...

Donc

=> X combos peuvent être créés et assortis
=> Pas de conflit entre les gadgets à propos de la touche [Enter]
=> Compatibles avec E/S Screen (accélération graphique)
=> ComboReturnKey() et ComboCallBack() sont des fonctions internes.

Code : Tout sélectionner

;*************************************************************************************************************************
; an idea of Fig : edit any items of combos

Structure COMBO
        Window.I
        Gadget.I
        Item.I
        kMenu.I
        ReturnKey.I
EndStructure

Declare ComboReturnKey()
Declare ComboCallBack()

Procedure ComboCreate(Window, Gadget, Item)
        Define *A.COMBO = AllocateMemory(SizeOf(COMBO) )
        With *A
                \Window = Window
                \Gadget = Gadget
                \Item = Item
                BindEvent(#PB_Event_Gadget, @ComboCallBack(), \Window, \Gadget)        
                \kMenu = CreateMenu(#PB_Any, WindowID(\Window) )
                BindMenuEvent(\kMenu, \Gadget, @ComboReturnKey() )        
        EndWith
        ProcedureReturn *A
EndProcedure

Procedure ComboDelete(Gadget)
        Define *A.COMBO = GetGadgetData(Gadget)
        With *A
                UnbindEvent(#PB_Event_Gadget, @ComboCallBack(), \Window, Gadget)
                UnbindMenuEvent(\kMenu, Gadget, @ComboReturnKey() )        
                FreeMemory(*A)
        EndWith
EndProcedure

Procedure ComboReturnKey()
        Define *A.COMBO = GetGadgetData(EventMenu() )
        *A\ReturnKey = #True
        PostEvent(#PB_Event_Gadget, *A\Window, *A\Gadget)
EndProcedure

Procedure ComboCallBack()
        Define Gadget = EventGadget()
        Define *A.COMBO = GetGadgetData(Gadget)
        Define gState = GetGadgetState(Gadget)
        If *A
                With *A
                        Select EventType()
                                Case #PB_EventType_Focus
                                        AddKeyboardShortcut(\Window, #PB_Shortcut_Return, Gadget)
                                Case #PB_EventType_LostFocus
                                        RemoveKeyboardShortcut(\Window, #PB_Shortcut_Return)
                                        SetGadgetText(Gadget, GetGadgetItemText(Gadget, \Item) )
                                Case #PB_EventType_Change
                                        If gState <> -1
                                                \Item = gState
                                        EndIf
                        EndSelect
                        If \ReturnKey
                                SetGadgetItemText(Gadget, \Item, GetGadgetText(Gadget) )
                                \ReturnKey = #False
                        EndIf
                EndWith
        EndIf
EndProcedure







; *** Example ***

If OpenWindow(10, 0, 0, 270, 180, "Combo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
        ComboBoxGadget(20, 10, 10, 250, 21, #PB_ComboBox_Editable)
        SetGadgetData(20, ComboCreate(10, 20, 1) )        
        AddGadgetItem(20, -1, "Option A")
        AddGadgetItem(20, -1, "Option B")
        AddGadgetItem(20, -1, "Option C")
        SetGadgetState(20, 1)       
        Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: ComboBoxGadget() éditable.

Message par Fig »

Il n'y a décidément pas une seule façon de faire et je trouve ça très bien et enrichissant que chacun ait eu la gentillesse de répondre à ma demande.

Je souhaite que ça ne donne pas lieu à un conflit, je vous considère tous comme des personnes adultes et raisonnables.

Merci à toutes les personnes qui ont répondues, y compris en messages privés.
Je vais me décider pour une manière de faire et m'y tenir, je suis sûr que les différentes options sont intéressantes pour quelqu'un qui pourrait faire une recherche à ce propos dans le futur.

Je vous remercie encore, vous m'ôtez une épine du pied. :D
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Répondre