Hach-0.1.0: nclient/NClient/GUI.hs
{-# LANGUAGE UnicodeSyntax #-}
module NClient.GUI (gui) where
import Control.Applicative ((<$>))
import Control.Concurrent (forkIO, threadDelay)
import Control.Concurrent.Chan (readChan, writeChan)
import Control.Monad (forever, forM_, void)
import Data.IORef (newIORef, atomicModifyIORef)
import Graphics.Vty
import Graphics.Vty.Widgets.All
import NClient.Connect
import NClient.Message.Format
import qualified NClient.Message.History as H
import qualified NClient.Message.Split as S
gui ∷ (Input, Output) → IO ()
gui (i,o) = do
history ← newIORef $ H.empty 10
messages ← newList (getNormalAttr defaultContext)
newMessage ← editWidget
box ← vBox messages newMessage
ui ← centered box
fg ← newFocusGroup
void $ addToFocusGroup fg newMessage
c ← newCollection
void $ addToCollection c ui fg
-- Send message to server
newMessage `onActivate` \this →
getEditText this >>= toC2S >>= writeChan o
--
-- Add send message to history
newMessage `onActivate` \this →
getEditText this >>= \t → atomicModifyIORef history (\h → let α = H.prepend t h in (α, H.line α)) >>= setEditText this
--
-- Catch history movements
newMessage `onKeyPressed` \this k m →
case (k,m) of
(KUp, []) → do
t ← getEditText this
t' ← atomicModifyIORef history $
\h → let h' = H.next t h in (h', H.line h')
setEditText this t'
return True
(KDown, []) → do
t' ← atomicModifyIORef history $
\h → let h' = H.previous h in (h', H.line h')
setEditText this t'
return True
_ → return False
--
-- Read server messages when they come
void . forkIO . forever $ readChan i >>= \m → do
let addMessage f xs ys = textWidget f xs >>= addToList ys xs >> scrollDown ys
schedule $
do a:as ← S.words (fromS2C m) . region_width <$> getCurrentSize messages
addMessage (formatter Tail m) a messages
forM_ as $ \γ → addMessage (formatter Full m) γ messages
threadDelay 10000
--
runUi c defaultContext