Page 1 sur 2
[RESOLU] ComboBoxGadget() éditable.
Publié : ven. 25/mai/2018 17:10
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
Re: ComboBoxGadget() éditable.
Publié : ven. 25/mai/2018 18:33
par Ollivier
(en anglais)
SetGadgetItemText(1er item = n°0)
Re: ComboBoxGadget() éditable.
Publié : ven. 25/mai/2018 19:08
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].
Re: ComboBoxGadget() éditable.
Publié : ven. 25/mai/2018 19:47
par Ollivier
Je pense que ça,
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...)
Re: ComboBoxGadget() éditable.
Publié : ven. 25/mai/2018 19:49
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 ?

(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.
Re: ComboBoxGadget() éditable.
Publié : ven. 25/mai/2018 19:56
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 !)
Re: ComboBoxGadget() éditable.
Publié : ven. 25/mai/2018 20:02
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 ?
Re: ComboBoxGadget() éditable.
Publié : ven. 25/mai/2018 21:41
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
et en faire ce que tu veux
Re: ComboBoxGadget() éditable.
Publié : ven. 25/mai/2018 23:19
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
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)
Re: ComboBoxGadget() éditable.
Publié : sam. 26/mai/2018 12:32
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.
Re: ComboBoxGadget() éditable.
Publié : sam. 26/mai/2018 13:07
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é.
Re: ComboBoxGadget() éditable.
Publié : sam. 26/mai/2018 13:46
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
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.
Re: ComboBoxGadget() éditable.
Publié : sam. 26/mai/2018 15:15
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.
Re: ComboBoxGadget() éditable.
Publié : sam. 26/mai/2018 17:05
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
Re: ComboBoxGadget() éditable.
Publié : sam. 26/mai/2018 18:39
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.
