Page 1 sur 1

ImageGadget: Drag and drop ET clic gauche

Publié : mar. 28/juin/2016 10:52
par Marc56
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 :mrgreen: )
- 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
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)

Re: ImageGadget: Drag and drop ET clic gauche

Publié : mar. 28/juin/2016 20:14
par nico
Je crois qu'il faut garder l'identifiant unique lorsque tu fais un drop, dans le bout de ton code qui suit, si je comprend bien, #Img_Test devient l'identifiant unique pour toute tes images à chaque drop, j'ai l'impression que c'est un gros problème.

Code : Tout sélectionner

    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)

J'ai fais un exemple avec un imageID pour chaque ImageGadget, la deuxième image je l'avais créé complètement transparente mais elle posait un problème lors du drop, je perdais la couche alpha. Donc considérer que l'image blanche ne contient pas d'image et représente une case vide, il y a permutation automatique d'image entre la source et la cible.

Code : Tout sélectionner

Enumeration FormWindow
  #Window_0
EndEnumeration

Enumeration FormGadget
  #Zone_0
  #Zone_1
  #Zone_2
  #Btn_Quit
  #Btn_Move
EndEnumeration

Enumeration FormImage
  #Img_Test0
  #Img_Test1
  #Img_Test2
EndEnumeration

; Décalge entre l'énumération des ImageGadegt et des images
Global Decalage = 0

; --- Une image de test
If CreateImage(#Img_Test0, 96, 96, 32)
  StartDrawing(ImageOutput(#Img_Test0))
  Box(0, 0, 96, 96, $00FF00)
  StopDrawing()
EndIf

; --- Une image de test
If CreateImage(#Img_Test1, 96, 96, 32)
  StartDrawing(ImageOutput(#Img_Test1))
  Box(0, 0, 96, 96, RGB(255,255,255))
  StopDrawing()
EndIf

; --- Une image de test
If CreateImage(#Img_Test2, 96, 96, 32)
  StartDrawing(ImageOutput(#Img_Test2))
  Box(0, 0, 96, 96, $00FFCC)
  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_Test0), #PB_Image_Raised)
ImageGadget(#Zone_1, 120, 10, 100, 100, ImageID(#Img_Test1), #PB_Image_Raised)
ImageGadget(#Zone_2, 230, 10, 100, 100, ImageID(#Img_Test2), #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))
            IDGadgetSource = EventGadget()
            Select IDGadgetSource
              Case #Zone_0
                IDImageSource = #Img_Test0
                DragImage(GetGadgetState(#Zone_0))
              Case #Zone_1
                IDImageSource = #Img_Test1
                DragImage(GetGadgetState(#Zone_1))
              Case #Zone_2     
                IDImageSource = #Img_Test2
                DragImage(GetGadgetState(#Zone_2))
            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    
      IDGadgetTarget = EventGadget()
      
      Select IDGadgetTarget
          
        Case #Zone_0
          CopyImage(#Img_Test0, IDImageSource) 
          If EventDropImage(#Img_Test0)
            SetGadgetState(IDGadgetSource, ImageID(IDImageSource))   
            SetGadgetState(#Zone_0, ImageID(#Img_Test0))
          EndIf  
          
        Case #Zone_1 
          CopyImage(#Img_Test1, IDImageSource)  
          If EventDropImage(#Img_Test1)
            SetGadgetState(IDGadgetSource, ImageID(IDImageSource)) 
            SetGadgetState(#Zone_1, ImageID(#Img_Test1))
          EndIf
          
        Case #Zone_2  
          CopyImage(#Img_Test2, IDImageSource) 
          If EventDropImage(#Img_Test2)
            SetGadgetState(IDGadgetSource, ImageID(IDImageSource)) 
            SetGadgetState(#Zone_2, ImageID(#Img_Test2))
          EndIf  
          
      EndSelect ; (drop)
      
  EndSelect ; (waitwindowevent)
  
ForEver

End

Re: ImageGadget: Drag and drop ET clic gauche

Publié : mer. 29/juin/2016 7:42
par Marc56
Merci nico, effectivement je déplaçais toujours la même image de départ 8O

Les forums ont du bon pour avoir un regard neuf car on finit par faire des erreurs bêtes à force d'avoir le nez trop collé au code :?

:wink:

Re: ImageGadget: Drag and drop ET clic gauche

Publié : mer. 29/juin/2016 12:31
par nico
car on finit par faire des erreurs bêtes à force d'avoir le nez trop collé au code
Je vois très bien de quoi tu parles, c'est pareil pour moi. :)

Re: ImageGadget: Drag and drop ET clic gauche

Publié : mer. 29/juin/2016 12:46
par Marc56
Un travail bien fait nécessite aussi de prendre du recul pour reconsidérer l'ensemble :mrgreen:

Image