vision-0.0.2.2: src/DnD.hs
-- -*-haskell-*-
-- Vision (for the Voice): an XMMS2 client.
--
-- Author: Oleg Belozeorov
-- Created: 10 Sep. 2010
--
-- Copyright (C) 2009-2010 Oleg Belozeorov
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License as
-- published by the Free Software Foundation; either version 3 of
-- the License, or (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- General Public License for more details.
--
{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
module DnD
( setupDnDReorder
) where
import Control.Applicative
import Control.Monad
import Control.Monad.Trans
import Data.IORef
import Graphics.UI.Gtk
setupDnDReorder target store view apply = do
sel <- treeViewGetSelection view
targetList <- targetListNew
targetListAdd targetList target [TargetSameWidget] 0
dropRef <- newIORef False
dragSourceSet view [Button1] [ActionMove]
dragSourceSetTargetList view targetList
view `on` dragDataGet $ \_ _ _ -> do
rows <- liftIO $ treeSelectionGetSelectedRows sel
selectionDataSet selectionTypeInteger $ map head rows
return ()
dragDestSet view [DestDefaultMotion, DestDefaultHighlight] [ActionMove]
dragDestSetTargetList view targetList
view `on` dragDrop $ \ctxt _ tstamp -> do
writeIORef dropRef True
dragGetData view ctxt target tstamp
return True
view `on` dragDataReceived $ \ctxt (_, y) _ tstamp -> do
drop <- liftIO $ readIORef dropRef
when drop $ do
liftIO $ writeIORef dropRef False
(rows :: Maybe [Int]) <- selectionDataGet selectionTypeInteger
liftIO $ doReorder apply store view y rows
liftIO $ dragFinish ctxt True True tstamp
view `on` dragDataDelete $ \_ ->
treeSelectionUnselectAll sel
doReorder _ _ _ _ Nothing = return ()
doReorder apply store view y (Just rows) = do
base <- getTargetRow
apply $ reorder base rows
where getTargetRow = do
maybePos <- treeViewGetPathAtPos view (0, y)
case maybePos of
Just ([n], _, _) ->
return n
Nothing ->
pred <$> listStoreGetSize store
reorder = reorderDown 0
where reorderDown _ _ [] = []
reorderDown dec base rows@(r:rs)
| r <= base = (r - dec, base) : reorderDown (dec + 1) base rs
| otherwise = reorderUp (if dec /= 0 then base + 1 else base) rows
reorderUp _ [] = []
reorderUp base (r:rs)
| r == base = reorderUp (base + 1) rs
| otherwise = (r, base) : reorderUp (base + 1) rs