ImageGadget: Drag and drop ET clic gauche
Publié : mar. 28/juin/2016 10:52
La dernière version de mon launcher ne fonctionnement pas totalement comme espéré, j'ai du réfléchir à une nouvelle méthode pour permettre à une ImageGadget de pouvoir être cliquable et supporter le drag'n'drop.
Comme l'a indiqué Zorro, une image lors d'un d&d reçoit d'abord l'évènement clic, même si le bouton n'est pas relâché
La solution proposé par Case fonctionnait, mais à l'intégration dans mon projet, il y a eut plusieurs problèmes:
(essentiellement dû à un foutoir pas possible dans mon code
)
- Le curseur ne prenait pas la forme du d&d, mais toujours celui du 'défense de stationner' (il ne trouvait pas le drop)
- Le drapeau ne se libérait pas toujours, donc certains programmes nécessitaient un double clic
J'ai du faire un tas de bidouilles pour identifier la zone de drop et ça ne me satisfait pas
La solution d'utiliser un CanvasGadget (qui possède plus d'évènements) est assez longue à mettre en place.
Je ne veux pas utiliser de double clic
J'ai réfléchi (oui, ça m'arrive, mais pas trop souvent) et trouvé une solution simple: mettre un bouton bascule qui permet d'isoler l'une ou l'autre fonction (drag ou clic)
Voici donc un exemple isolé du système.
C'est assez verbeux, ça pourrait être simplifié, mais c'est purement logique et sans bidouille.
(Ça permet aussi d'illustrer (pour les débutant) l'utilisation très commode du gadget StatusBar en PB)
Il suffit de cliquer sur le bouton "Changer de Mode" pour passer du déplacement d’icône au mode run program
Reste juste un problème: si le drop se fait en dehors d'un gadget, je perds l'image 
Edit: Ça y est, j'ai pu appliquer cela à mon Launcher, avec donc ajout d'un bouton "Réorganiser", qui bloque l'un ou l'autre évènement.
Encore quelques trucs à faire niveau ergonomie (ie: changer la couleur du fond en mode Edit)
Comme l'a indiqué Zorro, une image lors d'un d&d reçoit d'abord l'évènement clic, même si le bouton n'est pas relâché
La solution proposé par Case fonctionnait, mais à l'intégration dans mon projet, il y a eut plusieurs problèmes:
(essentiellement dû à un foutoir pas possible dans mon code

- Le curseur ne prenait pas la forme du d&d, mais toujours celui du 'défense de stationner' (il ne trouvait pas le drop)
- Le drapeau ne se libérait pas toujours, donc certains programmes nécessitaient un double clic
J'ai du faire un tas de bidouilles pour identifier la zone de drop et ça ne me satisfait pas

La solution d'utiliser un CanvasGadget (qui possède plus d'évènements) est assez longue à mettre en place.
Je ne veux pas utiliser de double clic

J'ai réfléchi (oui, ça m'arrive, mais pas trop souvent) et trouvé une solution simple: mettre un bouton bascule qui permet d'isoler l'une ou l'autre fonction (drag ou clic)
Voici donc un exemple isolé du système.
C'est assez verbeux, ça pourrait être simplifié, mais c'est purement logique et sans bidouille.
(Ça permet aussi d'illustrer (pour les débutant) l'utilisation très commode du gadget StatusBar en PB)
Il suffit de cliquer sur le bouton "Changer de Mode" pour passer du déplacement d’icône au mode run program
Code : Tout sélectionner
; Drag and drop OR Run (from image)
; Permet de créer un 'launcheur' à base d'ImageGadget
; L'image peut être déplacée par d&d
; L'image peut servir à lancer un programme
; Le choix se fait à l'aide d'un bouton bascule
; (C)Marc56 - 28/06/16
Enumeration FormWindow
#Window_0
EndEnumeration
Enumeration FormGadget
#Zone_0
#Zone_1
#Zone_2
#Btn_Quit
#Btn_Move
EndEnumeration
Enumeration FormImage
#Img_Test
EndEnumeration
; --- Une image de test
If CreateImage(#Img_Test, 96, 96)
StartDrawing(ImageOutput(#Img_Test))
Box(0, 0, 96, 96, $00FF00)
StopDrawing()
EndIf
; --- Fenêtre principale
OpenWindow(#Window_0, 0, 0, 500, 150, "Drag'n'drop or Run", 13107201)
ImageGadget(#Zone_0, 10, 10, 100, 100, ImageID(#Img_Test), #PB_Image_Raised)
ImageGadget(#Zone_1, 120, 10, 100, 100, 0, #PB_Image_Raised)
ImageGadget(#Zone_2, 230, 10, 100, 100, 0, #PB_Image_Raised)
ButtonGadget(#Btn_Move, 390, 10, 100, 25, "Changer de Mode", #PB_Button_Toggle)
ButtonGadget(#Btn_Quit, 390, 85, 100, 25, "Quitter")
; --- Barre d'état
CreateStatusBar(0, WindowID(#Window_0))
AddStatusBarField(80)
AddStatusBarField(#PB_Ignore)
StatusBarText(0, 0, "Mode RUN", #PB_StatusBar_Center)
StatusBarText(0, 1, "Cliquez sur [Mode] pour changer le mode d'utilisation.", #PB_StatusBar_Center)
; --- Activer d&d
EnableGadgetDrop(#Zone_0, #PB_Drop_Image, #PB_Drag_Copy)
EnableGadgetDrop(#Zone_1, #PB_Drop_Image, #PB_Drag_Copy)
EnableGadgetDrop(#Zone_2, #PB_Drop_Image, #PB_Drag_Copy)
Repeat
Select WaitWindowEvent(10)
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case #Btn_Quit
Break
Case #Btn_Move ; (bouton bascule RUN/MOVE type #PB_Button_Toggle)
If GetGadgetState(#Btn_Move)
StatusBarText(0, 0, "Mode EDIT", #PB_StatusBar_Center)
StatusBarText(0, 1, "Déplacez les icônes à l'aide du Bouton GAUCHE", #PB_StatusBar_Center)
Else
StatusBarText(0, 0, "Mode RUN", #PB_StatusBar_Center)
StatusBarText(0, 1, "Cliquez sur l'icône du Programmer à Lancer.", #PB_StatusBar_Center)
EndIf
EndSelect ; (boutons standard)
Select EventType()
Case #PB_EventType_DragStart ; Démarre un d&d
If GetGadgetState(#Btn_Move) ; (Bouton MODE Pressé (=1))
Select EventGadget()
Case #Zone_0
If GetGadgetState(#Zone_0)
DragImage(GetGadgetState(#Zone_0))
SetGadgetState(#Zone_0, 0)
EndIf
Case #Zone_1
If GetGadgetState(#Zone_1)
DragImage(GetGadgetState(#Zone_1))
SetGadgetState(#Zone_1, 0)
EndIf
Case #Zone_2
If GetGadgetState(#Zone_2)
DragImage(GetGadgetState(#Zone_2))
SetGadgetState(#Zone_2, 0)
EndIf
EndSelect ; (dragstart)
EndIf
Case #PB_EventType_LeftClick
If Not GetGadgetState(#Btn_Move) ; (Bouton MODE relaché (=0))
Select EventGadget()
Case #Zone_0
StatusBarText(0, 1, "Run Programme 1", #PB_StatusBar_Center)
Case #Zone_1
StatusBarText(0, 1, "Run Programme 2", #PB_StatusBar_Center)
Case #Zone_2
StatusBarText(0, 1, "Run Programme 3", #PB_StatusBar_Center)
EndSelect ; (run)
EndIf
EndSelect ; (eventype)
Case #PB_Event_GadgetDrop
Select EventGadget()
Case #Zone_0
If EventDropImage(#Img_Test)
SetGadgetState(#Zone_0, ImageID(#Img_Test))
EndIf
Case #Zone_1
If EventDropImage(#Img_Test)
SetGadgetState(#Zone_1, ImageID(#Img_Test))
EndIf
Case #Zone_2
If EventDropImage(#Img_Test)
SetGadgetState(#Zone_2, ImageID(#Img_Test))
EndIf
EndSelect ; (drop)
EndSelect ; (waitwindowevent)
ForEver
End

Edit: Ça y est, j'ai pu appliquer cela à mon Launcher, avec donc ajout d'un bouton "Réorganiser", qui bloque l'un ou l'autre évènement.

Encore quelques trucs à faire niveau ergonomie (ie: changer la couleur du fond en mode Edit)