module SetHo
( runSetter
) where
import qualified GHC.Stats
import Accessors.Dynamic ( DTree )
import qualified Control.Concurrent as CC
import Control.Monad.IO.Class ( liftIO )
import "gtk3" Graphics.UI.Gtk ( AttrOp( (:=) ) )
import qualified "gtk3" Graphics.UI.Gtk as Gtk
import Text.Printf ( printf )
import System.Glib.Signals ( on )
import SetHo.LookupTree ( newLookupTreeview )
import SetHo.OptionsWidget ( GraphInfo(..), makeOptionsWidget )
runSetter :: String -> DTree -> IO (Maybe DTree) -> IO () -> (DTree -> IO ()) -> IO ()
runSetter rootName initialValue userPollForNewMessage sendRequest commit = do
statsEnabled <- GHC.Stats.getGCStatsEnabled
_ <- Gtk.initGUI
_ <- Gtk.timeoutAddFull (CC.yield >> return True) Gtk.priorityDefault 50
win <- Gtk.windowNew
_ <- Gtk.set win [ Gtk.containerBorderWidth := 8
, Gtk.windowTitle := "set-ho-matic"
]
statsLabel <- Gtk.labelNew (Nothing :: Maybe String)
let statsWorker = do
CC.threadDelay 500000
msg <- if statsEnabled
then do
stats <- GHC.Stats.getGCStats
return $ printf "The current memory usage is %.2f MB"
((realToFrac (GHC.Stats.currentBytesUsed stats) :: Double) /(1024*1024))
else return "(enable GHC statistics with +RTS -T)"
Gtk.postGUISync $ Gtk.labelSetText statsLabel ("Welcome to set-ho-matic!\n" ++ msg)
statsWorker
statsThread <- CC.forkIO statsWorker
graphWindowsToBeKilled <- CC.newMVar []
let killEverything = do
CC.killThread statsThread
_gws <- CC.readMVar graphWindowsToBeKilled
Gtk.mainQuit
_ <- on win Gtk.deleteEvent $ liftIO (killEverything >> return False)
buttonCommit <- Gtk.buttonNewWithLabel "commit"
buttonRefresh <- Gtk.buttonNewWithLabel "refresh"
Gtk.widgetSetTooltipText buttonCommit (Just "SET ME SET ME GO HEAD DO IT COME ON SET ME")
graphInfoMVar <- CC.newMVar GraphInfo { giXScaling = True
, giXRange = Nothing
} :: IO (CC.MVar GraphInfo)
optionsWidget <- makeOptionsWidget graphInfoMVar
options <- Gtk.expanderNew "options"
Gtk.set options [ Gtk.containerChild := optionsWidget
, Gtk.expanderExpanded := False
]
(treeview, getLatestStaged, receiveNewValue) <- newLookupTreeview rootName initialValue
treeviewExpander <- Gtk.expanderNew "signals"
Gtk.set treeviewExpander
[ Gtk.containerChild := treeview
, Gtk.expanderExpanded := True
]
vbox <- Gtk.vBoxNew False 4
Gtk.set vbox
[ Gtk.containerChild := statsLabel
, Gtk.boxChildPacking statsLabel := Gtk.PackNatural
, Gtk.containerChild := buttonCommit
, Gtk.boxChildPacking buttonCommit := Gtk.PackNatural
, Gtk.containerChild := buttonRefresh
, Gtk.boxChildPacking buttonRefresh := Gtk.PackNatural
, Gtk.containerChild := options
, Gtk.boxChildPacking options := Gtk.PackNatural
, Gtk.containerChild := treeviewExpander
, Gtk.boxChildPacking treeviewExpander := Gtk.PackGrow
]
_ <- on buttonCommit Gtk.buttonActivated $ do
val <- getLatestStaged
commit val
_ <- on buttonRefresh Gtk.buttonActivated sendRequest
let pollForNewMessage = do
mmsg <- userPollForNewMessage
case mmsg of
Nothing -> return ()
Just newVal -> receiveNewValue newVal
_ <- Gtk.timeoutAddFull (pollForNewMessage >> return True) Gtk.priorityDefault 300
_ <- Gtk.set win [ Gtk.containerChild := vbox ]
Gtk.widgetShowAll win
Gtk.mainGUI