frpnow-gtk3-0.2.0: Control/FRPNow/GTK/TreeView.hs
{-# LANGUAGE RankNTypes #-}
{- |
Module : Control.FRPNow.GTK.TreeView
Copyright : (c) George Steel 2017
License : BSD3
Maintainer : george.steel@gmail.org
Functions for working with 'TreeView' and dynamic data.
-}
module Control.FRPNow.GTK.TreeView where
import Control.FRPNow.GTK.Core
import Graphics.UI.Gtk.General.Enums (Align(..))
import Graphics.UI.Gtk
import Control.Applicative
import Control.Monad
import Control.Monad.Reader
import Control.Monad.IO.Class
import Control.FRPNow
import Data.Maybe
import qualified Data.Text as T
import Data.Text (Text)
-- | Creates a TreeView displauying a dynamic list. The columns and cell renderers are defined using reader monads built from the other functions in this module.In this casem the cells must be polymorphic in the type of store they accept so as to ensure read-only behavior. Returns the TreeView and the curently-selected item.
createListDisplay :: (Eq a) => Behavior [a] -> (forall store . (TreeModelClass (store a), TypedTreeModelClass store) => ReaderT (TreeView, store a) IO b) -> Now (TreeView, Behavior (Maybe a))
createListDisplay datafeed filler = do
tv <- sync $ treeViewNew
initdata <- sample datafeed
store <- sync $ listStoreNew initdata
sync $ treeViewSetModel tv store
sync $ runReaderT filler (tv,store)
flip callStream (toChanges datafeed) $ \newdata' -> sync $ do
let newdata = last newdata'
listStoreClear store
mapM_ (listStoreAppend store) newdata
itemSelected <- getSignal cursorChanged tv $ \cb -> do
mcur <- fst <$> treeViewGetCursor tv
case mcur of
[i] -> do
x <- listStoreGetValue store i
cb (Just x)
_ -> cb Nothing
selItem <- sample $ fromChanges Nothing itemSelected
return (tv,selItem)
-- | Add a column with the given title and renderers to the enclosing TreeView.
tvColumn :: Text -> ReaderT (TreeViewColumn, store) IO b -> ReaderT (TreeView, store) IO TreeViewColumn
tvColumn title filler = ReaderT $ \(tv,model) -> do
col <- treeViewColumnNew
set col [treeViewColumnTitle := title]
runReaderT filler (col,model)
treeViewAppendColumn tv col
return col
-- | Add a cell renderer diaplaying a text-valued function of a row to a column.
tvTextDisplay :: (CellLayoutClass col, TreeModelClass (store a), TypedTreeModelClass store) => (a -> Text) -> ReaderT (col, store a) IO CellRendererText
tvTextDisplay f = ReaderT $ \(col,model) -> do
cell <- cellRendererTextNew
set cell [cellTextEditable := False]
cellLayoutPackStart col cell True
cellLayoutSetAttributes col cell model $ \row -> [cellText := f row]
return cell
-- | Add a cell renderer diaplaying a s function of a row using Show. Useful for Int values.
tvShowDisplay :: (CellLayoutClass col, TreeModelClass (store a), TypedTreeModelClass store, Show b) => (a -> b) -> ReaderT (col, store a) IO CellRendererText
tvShowDisplay f = ReaderT $ \(col,model) -> do
cell <- cellRendererTextNew
set cell [cellTextEditable := False]
cellLayoutPackStart col cell True
cellLayoutSetAttributes col cell model $ \row -> [cellText := show (f row)]
return cell