Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wx haskell Drag and Drop example

I am looking for a wx haskell Drag and Drop example. I haven't found any yet.

Any available ? or hints ?

So far:

  • I can see a on drag event ( but no "on drop")
  • mouse is just giving a left up on target
  • I see some comment where I am supposed to attache a drop target to on object , but I do not see how it is invoked:

    Graphics.UI.WXCore.DragAndDrop

    L 51

    -- | Create 'DropSource'. Then 'dragAndDrop' replace target\'s 'DataObject' by this 'DataObject'.

    dropSource :: DataObject a -> Window b -> IO (DropSource ())

  • I cannot see where is the WX layer above Graphics.UI.WXCore.DragAndDrop

  • this is (too) old I guess: [0] : http://bb10.com/haskell-wxhaskell-general/2007-08/msg00035.html

anyway, quite fuzzy for now...


edit: this is where I stand for now: on drag do no get activated, so no dragAndDrop either ( on mouse in xinput is just there to see whats going on) ( dragger is what I got from [O]), but i do not get the event from this)

--- test where DnD from yinput to xinput
module Main where

import CustoWidget
import Graphics.UI.WX hiding (empty)
import Data.Graph.Inductive
import Data.Maybe
import Control.Monad
import Graphics.UI.WX.Events
import Graphics.UI.WXCore.WxcClassesMZ
import Graphics.UI.WXCore.WxcClassesAL
import Graphics.UI.WXCore.DragAndDrop
import Graphics.UI.WXCore.Events
import Debug.Trace
main
  = start ballsFrame
  -- @next : try andrun start within a state

ballsFrame
  = do

      f      <- frame  [text := "Layout test"]
      p      <- panel  f []                       -- panel for color and tab management.
      ok     <- button p [text := "Ok"]
      can    <- button p [text := "Cancel", on command := infoDialog f "Info" "Pressed 'Cancel'"]
      xinput <- textEntry p [text := "100", alignment := AlignRight]
      yinput <- textEntry p [text := "100", alignment := AlignRight]

      set f [defaultButton := ok
             ,layout := container p $
                        margin 10 $
                        column 5 [boxed "coordinates" (grid 5 5 [[label "x:", hfill $ widget xinput]
                                                                ,[label "y:", hfill $ widget yinput]])
                                 ,floatBottomRight $ row 5 [widget ok,widget can]]
                                 ]
      set xinput [    on mouse := showMe] --, on keyboard := showMeK
      set yinput [ ] --on mouse := showMe, on keyboard := showMeK ]
--      fileDropTarget xinput (\pt file ->  putStrLn $ show file )


      -- prepare the drop source

      textdata <- textDataObjectCreate ""
      drop <- dropTarget xinput textdata

      textdata' <- textDataObjectCreate "text"
      src <- dropSource textdata' yinput

      -- activate on drag the do drag drop
      set yinput [ on drag := onDrag src]
      set ok [ on command := onOk f textdata]




      return ()



onDrag s p =  trace ("on drag " ++ show s ++ " " ++ show p) 
    dragAndDrop s Default (\_ -> return ()) 



onOk f textdata = do

          txt <- textDataObjectGetText textdata
          infoDialog f "resultText" txt
          close f

showMe = \x -> do putStrLn $ show x

dragger win wout = do
          textdata <- textDataObjectCreate ""
          drop <- dropTarget wout textdata
          textdata' <- textDataObjectCreate "text"
          src <- dropSource textdata' win
          dragAndDrop src Default (\_ -> return ())
          txt <- textDataObjectGetText textdata
          infoDialog wout "resultText" txt
like image 922
Luc Taesch Avatar asked Nov 03 '22 00:11

Luc Taesch


1 Answers

Summary :

  • create a dropTarget and a dropSource : from Graphics.UI.WXCore.DragAndDrop
  • use the Event "on drag" on the source widget, from where you would invoke dragAndDrop from Graphics.UI.WXCore.Events

My mistakes and wrong assumptions:

  • I was looking for a "on drop" event, on the target. does not exists, and not needed, because:
  • When "on drag", the other events are suspended. no more mouse up or mouse down. If not released on (DnD) target, the drag will abort and normal events resume. [0]
  • Note that a textEntry need a focus to get the "paste", however the drop still occurs. look at "on drag Activated" on console.
  • the text exchanged are the one from the DataObjects ( and not from the source, if this would be a textEntry. ). see the "text dropped".

The following code dumps the events on the console, to experiment:

module Main where


import Graphics.UI.WX hiding (empty)

import Data.Maybe
import Control.Monad
import Graphics.UI.WX.Events
import Graphics.UI.WXCore.WxcClassesMZ
--import Graphics.UI.WXCore.WxcClassesAL
import Graphics.UI.WXCore.DragAndDrop
import Graphics.UI.WXCore.Events

main
  = start dndtest


dndtest
  = do

      f      <- frame  [text := "Drag And Drop test"]
      p      <- panel  f []                       
      ok     <- button p [text := "Ok"]
      xinput <- textEntry p [text := "here :"] 
      yinput <- staticText p [text := "drag me"]

      set f [defaultButton := ok
             ,layout := container p $
                        margin 10 $
                        column 5 [boxed "coordinates" (grid 5 5 [[label "source:", hfill $ widget yinput]
                                                                ,[label "target(focus first):", hfill $ widget xinput]
                                                                ])
                                 ,floatBottomRight $ row 5 [widget ok]]
                                 ]

      set xinput [ on enter := onEnter]

      set yinput [ ] 
---------------------------------------------------------
--- meaningful stuff starts here
---------------------------------------------------------

       -- prepare the drop source : create a DataObject and associate it with the source
      textdata' <- textDataObjectCreate "text dropped"
      src <- dropSource textdata' yinput

      -- prepare the drop target: create a DataObject (placeholder here) and associate it with the target
      textdata <- textDataObjectCreate ".."
      drop <- dropTarget xinput textdata 


      -- activate on drag the do dragdrop. this will replace the target dataObject with the source one.
      -- Try with and without giving focus to the textEntry field
      -- Try and source from your favorite editor also (focus first!)
      set yinput [ on drag := onDrag src ]
---------------------------------------------------------
--- meaningful stuff stops here
---------------------------------------------------------

      set ok [ on command := close f ]
      return ()





--onDrag:: Graphics.UI.WXCore.WxcClassTypes.DropSource a -> Point -> IO ()
onDrag s p  =  do
    dragAndDrop s Default (\_ -> return ())
    putStrLn "on Drag activated:"



showMeE :: EventMouse -> IO ()
showMeE (MouseMotion point mod) = putStr ""  --- discard meaningless Motion event
showMeE  e = putStrLn $ show e


onEnter p = putStrLn $ "on Enter:" ++ show p

I have seen other goodies I may explore, like changing the cursor during the drag, or reacting on different variants of drop.

[0] : http://docs.wxwidgets.org/2.8/wx_wxdndoverview.html

like image 182
Luc Taesch Avatar answered Nov 15 '22 07:11

Luc Taesch