{-# LANGUAGE BangPatterns #-} -- | The 'Picture' data structure is representative of the final terminal view. -- -- A 'Picture' is a background paired with a layer of 'Image's. module Graphics.Vty.Picture ( module Graphics.Vty.Picture , module Graphics.Vty.Image ) where import Graphics.Vty.Image import Control.DeepSeq -- | The type of images to be displayed using 'update'. -- -- Can be constructed directly or using `picForImage`. Which provides an initial instance with -- reasonable defaults for picCursor and picBackground. data Picture = Picture { picCursor :: Cursor , picLayers :: [Image] , picBackground :: Background } instance Show Picture where show (Picture _ layers _ ) = "Picture ?? " ++ show layers ++ " ??" instance NFData Picture where rnf (Picture c l b) = c `deepseq` l `deepseq` b `deepseq` () -- | a picture with no cursor, background or image layers emptyPicture :: Picture emptyPicture = Picture NoCursor [] ClearBackground -- | The given 'Image' is added as the top layer of the 'Picture' addToTop :: Picture -> Image -> Picture addToTop p i = p {picLayers = i : picLayers p} -- | The given 'Image' is added as the bottom layer of the 'Picture' addToBottom :: Picture -> Image -> Picture addToBottom p i = p {picLayers = picLayers p ++ [i]} -- | Create a picture for display for the given image. The picture will not have a displayed cursor -- and no background pattern (ClearBackground) will be used. picForImage :: Image -> Picture picForImage i = Picture { picCursor = NoCursor , picLayers = [i] , picBackground = ClearBackground } -- | Create a picture for display with the given layers. Ordered top to bottom. -- -- The picture will not have a displayed cursor and no background apttern (ClearBackgroun) will be -- used. -- -- The first 'Image' is the top layer. picForLayers :: [Image] -> Picture picForLayers is = Picture { picCursor = NoCursor , picLayers = is , picBackground = ClearBackground } -- | A picture can be configured either to not show the cursor or show the cursor at the specified -- character position. -- -- There is not a 1 to 1 map from character positions to a row and column on the screen due to -- characters that take more than 1 column. -- -- todo: The Cursor can be given a (character,row) offset outside of the visible bounds of the -- output region. In this case the cursor will not be shown. data Cursor = NoCursor | Cursor Int Int instance NFData Cursor where rnf NoCursor = () rnf (Cursor w h) = w `seq` h `seq` () -- | A 'Picture' has a background pattern. The background is either ClearBackground. Which shows the -- layer below or is blank if the bottom layer. Or the background pattern is a character and a -- display attribute. If the display attribute used previously should be used for a background fill -- then use `currentAttr` for the background attribute. -- -- \todo The current attribute is always set to the default attributes at the start of updating the -- screen to a picture. data Background = Background { backgroundChar :: Char , backgroundAttr :: Attr } -- | A ClearBackground is: -- -- * the space character if there are remaining non-skip ops -- -- * End of line if there are no remaining non-skip ops. | ClearBackground instance NFData Background where rnf (Background c a) = c `seq` a `seq` () rnf ClearBackground = () -- | Compatibility with applications that do not use more than a single layer. picImage :: Picture -> Image picImage = head . picLayers