import Control.Concurrent.Async import Control.Concurrent import System.Console.Regions import qualified Data.Text as T import Control.Concurrent.STM import Control.Applicative import Data.Time.Clock import Control.Monad import Data.Monoid import System.Process main :: IO () main = void $ displayConsoleRegions $ do void titleRegion ir <- infoRegion cr <- clockRegion rr <- rulerRegion growingDots runBash growingDots mapM_ closeConsoleRegion [ir, cr] titleRegion :: IO ConsoleRegion titleRegion = do r <- openConsoleRegion Linear setConsoleRegion r "STM demo!" return r infoRegion :: IO ConsoleRegion infoRegion = do r <- openConsoleRegion Linear setConsoleRegion r $ do w <- consoleWidth h <- consoleHeight regions <- readTMVar regionList return $ T.pack $ unwords [ "size:" , show w , "x" , show h , "regions: " , show (length regions) ] return r timeDisplay :: TVar UTCTime -> STM T.Text timeDisplay tv = T.pack . show <$> readTVar tv clockRegion :: IO ConsoleRegion clockRegion = do tv <- atomically . newTVar =<< getCurrentTime async $ forever $ do threadDelay 1000000 -- 1 sec atomically . (writeTVar tv) =<< getCurrentTime atomically $ do r <- openConsoleRegion Linear setConsoleRegion r (timeDisplay tv) rightAlign r return r rulerRegion :: IO ConsoleRegion rulerRegion = do r <- openConsoleRegion Linear setConsoleRegion r $ do width <- consoleWidth return $ T.pack $ take width nums return r where nums = cycle $ concatMap show [0..9] rightAlign :: ConsoleRegion -> STM () rightAlign r = tuneDisplay r $ \t -> do w <- consoleWidth return (T.replicate (w - T.length t) (T.singleton ' ') <> t) growingDots :: IO () growingDots = withConsoleRegion Linear $ \r -> do atomically $ rightAlign r width <- atomically consoleWidth void $ replicateM width $ do appendConsoleRegion r "." threadDelay (100000) runBash :: IO () runBash = do -- Temporarily clear whatever console regions are open. rs <- waitDisplayChange $ swapTMVar regionList [] putStrLn "We interrupt this demo to run a shell prompt. exit to continue!" callCommand "bash" -- Restore the console regions. void $ atomically $ swapTMVar regionList rs