From: Axel S. <A....@ke...> - 2007-12-09 08:13:20
|
Sun Dec 9 00:11:48 PST 2007 A....@ke... * Forgot to add the file with helper functions for tree DND. addfile ./gtk/Graphics/UI/Gtk/ModelView/TreeDrag.chs hunk ./gtk/Graphics/UI/Gtk/ModelView/TreeDrag.chs 1 +-- -*-haskell-*- +-- GIMP Toolkit (GTK) Interface DragSource and DragDest +-- +-- Author : Axel Simon +-- +-- Created: 24 July 2007 +-- +-- Copyright (C) 2007 Axel Simon +-- +-- This library is free software; you can redistribute it and/or +-- modify it under the terms of the GNU Lesser General Public +-- License as published by the Free Software Foundation; either +-- version 2.1 of the License, or (at your option) any later version. +-- +-- This library 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 +-- Lesser General Public License for more details. +-- +-- | +-- Maintainer : gtk...@li... +-- Stability : provisional +-- Portability : portable (depends on GHC) +-- +-- Interfaces for drag-and-drop support in 'Graphics.UI.Gtk.ModelView.TreeView'. +-- +module Graphics.UI.Gtk.ModelView.TreeDrag ( + +-- * Detail +-- +-- | 'Graphics.UI.Gtk.ModelView.TreeView's provide special support for +-- Drag-and-Drop such as hover-to-open-rows or autoscrolling. This module +-- implements two utility functions that set and get a path and a model in a +-- 'Graphics.UI.Gtk.General.Selection.Selection' structure. These functions +-- are thus useful to implement drag-and-drop functionality in a +-- 'Graphics.UI.Gtk.ModelView.TreeModel'. In fact, they are used as part of +-- the default drag-and-drop interfaces of +-- 'Graphics.UI.Gtk.ModelView.ListStore' and +-- 'Graphics.UI.Gtk.ModelView.TreeStore' that allows to permute rows and move +-- them between hierarchy levels. + +-- * Utility functions + treeModelEqual, + treeGetRowDragData, + treeSetRowDragData + + ) where + +-- I've decided not to bind the DragSource and DragDest interfaces. They seem +-- to be useful if you (a) write your own 'TreeView' widget or (b) if you +-- can't be bothered to implement a special variant of these interfaces in +-- ListStore and TreeStore. In the latter case the interfaces are useful to +-- "simulate" a drag-and-drop that looks like a row-permutation which is the +-- interface that Gtk's ListStore and TreeStore support by default. Since +-- overriding or augmenting the dnd interfaces for ListStore and TreeStore is +-- so easy in Gtk2Hs, I think we can do without the cheat way. + +import System.Glib.FFI +import System.Glib.GObject +{#import Graphics.UI.Gtk.Types#} +{#import Graphics.UI.Gtk.ModelView.Types#} (TreePath, fromTreePath, withTreePath, + NativeTreePath(..)) +import Graphics.UI.Gtk.General.DNDTypes (SelectionDataM, SelectionData) +import Control.Monad (liftM) +import Control.Monad.Trans (liftIO) +import Control.Monad.Reader (ask) + +{# context lib="gtk" prefix="gtk" #} + +-- | Compare two tree model for equality. +treeModelEqual :: (TreeModelClass tm1, TreeModelClass tm2) => tm1 -> tm2 -> Bool +treeModelEqual tm1 tm2 = unTreeModel (toTreeModel tm1) == unTreeModel (toTreeModel tm2) + +-- %hash c:8dcb d:af3f +-- | Obtains a 'TreeModel' and a path from 'SelectionDataM' whenever the target name is +-- "GTK_TREE_MODEL_ROW". Normally called from a 'treeDragDestDragDataReceived' handler. +-- +treeGetRowDragData :: SelectionDataM (Maybe (TreeModel, TreePath)) +treeGetRowDragData = ask >>= \selPtr -> liftIO $ alloca $ \tmPtrPtr -> alloca $ \pathPtrPtr -> do + isValid <- liftM toBool $ + {# call unsafe gtk_tree_get_row_drag_data #} selPtr (castPtr tmPtrPtr) (castPtr pathPtrPtr) + if isValid then do + tmPtr <- peek tmPtrPtr + pathPtr <- peek pathPtrPtr + tm <- makeNewGObject mkTreeModel (return tmPtr) + path <- fromTreePath pathPtr + return (Just (tm, path)) + else return Nothing + +-- %hash c:e3e3 d:af3f +-- | Sets selection data with the target name "GTK_TREE_MODEL_ROW", consisting +-- of a 'TreeModel' and a 'TreePath'. Normally used in a +-- 'treeDragSourceDragDataGet' handler. +-- +-- * Returns @True@ if setting the data was successful. +-- +treeSetRowDragData :: TreeModelClass treeModel => treeModel -> TreePath -> SelectionDataM Bool +treeSetRowDragData treeModel path = do + selPtr <- ask + liftM toBool $ liftIO $ withTreePath path $ \path -> + {# call unsafe gtk_tree_set_row_drag_data #} selPtr [_$_] + (toTreeModel treeModel) + path |