module Graphics.Vty.Inline
( module Graphics.Vty.Inline
, withVty
)
where
import Graphics.Vty
import Graphics.Vty.DisplayAttributes
import Graphics.Vty.Inline.Unsafe
import Blaze.ByteString.Builder (writeToByteString)
import Control.Monad.State.Strict
import Data.Bits ( (.&.), complement )
import Data.IORef
import System.IO
type InlineM v = State Attr v
backColor :: Color -> InlineM ()
backColor c = modify $ flip mappend ( currentAttr `withBackColor` c )
foreColor :: Color -> InlineM ()
foreColor c = modify $ flip mappend ( currentAttr `withForeColor` c )
applyStyle :: Style -> InlineM ()
applyStyle s = modify $ flip mappend ( currentAttr `withStyle` s )
removeStyle :: Style -> InlineM ()
removeStyle sMask = modify $ \attr ->
let style' = case attrStyle attr of
Default -> error $ "Graphics.Vty.Inline: Cannot removeStyle if applyStyle never used."
KeepCurrent -> error $ "Graphics.Vty.Inline: Cannot removeStyle if applyStyle never used."
SetTo s -> s .&. complement sMask
in attr { attrStyle = SetTo style' }
defaultAll :: InlineM ()
defaultAll = put defAttr
putAttrChange :: ( Applicative m, MonadIO m ) => Output -> InlineM () -> m ()
putAttrChange out c = liftIO $ do
bounds <- displayBounds out
dc <- displayContext out bounds
mfattr <- prevFattr <$> readIORef (assumedStateRef out)
fattr <- case mfattr of
Nothing -> do
liftIO $ outputByteBuffer out $ writeToByteString $ writeDefaultAttr dc
return $ FixedAttr defaultStyleMask Nothing Nothing Nothing
Just v -> return v
let attr = execState c currentAttr
attr' = limitAttrForDisplay out attr
fattr' = fixDisplayAttr fattr attr'
diffs = displayAttrDiffs fattr fattr'
outputByteBuffer out $ writeToByteString $ writeSetAttr dc fattr attr' diffs
modifyIORef (assumedStateRef out) $ \s -> s { prevFattr = Just fattr' }
inlineHack dc
putAttrChange_ :: ( Applicative m, MonadIO m ) => InlineM () -> m ()
putAttrChange_ c = liftIO $ withOutput $ \out -> do
hFlush stdout
putAttrChange out c
hFlush stdout