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 main :: IO () main = void $ displayConsoleRegions $ do ir <- infoRegion cr <- clockRegion rr <- rulerRegion growingDots mapM_ closeConsoleRegion [ir, cr] 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 rightAlign :: ConsoleRegion -> STM () rightAlign r = tuneDisplay r $ \t -> do w <- consoleWidth return (T.replicate (w - T.length t) (T.singleton ' ') <> t) growingDots = withConsoleRegion Linear $ \r -> do atomically $ rightAlign r width <- atomically consoleWidth replicateM width $ do appendConsoleRegion r "." threadDelay (100000) 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]