{-# LANGUAGE CPP #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE RankNTypes #-} #ifndef MIN_VERSION_base #defined MIN_VERSION_base(x,y,z) 1 #endif -- | Display attributes -- -- Typically the values 'defAttr' or 'currentAttr' are modified to form attributes: -- -- @ -- defAttr `withForeColor` red -- @ -- -- Is the attribute that will set the foreground color to red and the background color to the -- default. -- -- This can then be used to build an image wiht a red foreground like so: -- -- @ -- string (defAttr `withForeColor` red) "this text will be red" -- @ -- -- The default attributes set by 'defAttr' have a presentation determined by the terminal. This is -- not something VTY can control. The user is free to define the color scheme of the terminal as -- they see fit. Up to the limits of the terminal anyways. -- -- The value 'currentAttr' will keep the attributes of whatever was output previously. -- -- \todo This API is very verbose IMO. I'd like something more succinct. module Graphics.Vty.Attributes ( module Graphics.Vty.Attributes , module Graphics.Vty.Attributes.Color , module Graphics.Vty.Attributes.Color240 ) where import Data.Bits import Data.Default import Data.Word import Graphics.Vty.Attributes.Color import Graphics.Vty.Attributes.Color240 #if !(MIN_VERSION_base(4,8,0)) import Data.Monoid #endif -- | A display attribute defines the Color and Style of all the characters rendered after the -- attribute is applied. -- -- At most 256 colors, picked from a 240 and 16 color palette, are possible for the background and -- foreground. The 240 colors and 16 colors are points in different palettes. See Color for more -- information. data Attr = Attr { attrStyle :: !(MaybeDefault Style) , attrForeColor :: !(MaybeDefault Color) , attrBackColor :: !(MaybeDefault Color) } deriving ( Eq, Show, Read ) -- This could be encoded into a single 32 bit word. The 32 bit word is first divided -- into 4 groups of 8 bits where: The first group codes what action should be taken with regards to -- the other groups. -- XXYYZZ__ -- XX - style action -- 00 => reset to default -- 01 => unchanged -- 10 => set -- YY - foreground color action -- 00 => reset to default -- 01 => unchanged -- 10 => set -- ZZ - background color action -- 00 => reset to default -- 01 => unchanged -- 10 => set -- __ - unused -- -- Next is the style flags -- SURBDO__ -- S - standout -- U - underline -- R - reverse video -- B - blink -- D - dim -- O - bold -- __ - unused -- -- Then the foreground color encoded into 8 bits. -- Then the background color encoded into 8 bits. instance Monoid Attr where mempty = Attr mempty mempty mempty mappend attr0 attr1 = Attr ( attrStyle attr0 `mappend` attrStyle attr1 ) ( attrForeColor attr0 `mappend` attrForeColor attr1 ) ( attrBackColor attr0 `mappend` attrBackColor attr1 ) -- | Specifies the display attributes such that the final style and color values do not depend on -- the previously applied display attribute. The display attributes can still depend on the -- terminal's default colors (unfortunately). data FixedAttr = FixedAttr { fixedStyle :: !Style , fixedForeColor :: !(Maybe Color) , fixedBackColor :: !(Maybe Color) } deriving ( Eq, Show ) -- | The style and color attributes can either be the terminal defaults. Or be equivalent to the -- previously applied style. Or be a specific value. data MaybeDefault v where Default :: MaybeDefault v KeepCurrent :: MaybeDefault v SetTo :: forall v . ( Eq v, Show v, Read v ) => !v -> MaybeDefault v deriving instance Eq v => Eq (MaybeDefault v) deriving instance Eq v => Show (MaybeDefault v) deriving instance (Eq v, Show v, Read v) => Read (MaybeDefault v) instance Eq v => Monoid ( MaybeDefault v ) where mempty = KeepCurrent mappend Default Default = Default mappend Default KeepCurrent = Default mappend Default ( SetTo v ) = SetTo v mappend KeepCurrent Default = Default mappend KeepCurrent KeepCurrent = KeepCurrent mappend KeepCurrent ( SetTo v ) = SetTo v mappend ( SetTo _v ) Default = Default mappend ( SetTo v ) KeepCurrent = SetTo v mappend ( SetTo _ ) ( SetTo v ) = SetTo v -- | Standard 8-color ANSI terminal color codes. black, red, green, yellow, blue, magenta, cyan, white :: Color black = ISOColor 0 red = ISOColor 1 green = ISOColor 2 yellow = ISOColor 3 blue = ISOColor 4 magenta= ISOColor 5 cyan = ISOColor 6 white = ISOColor 7 -- | Bright/Vivid variants of the standard 8-color ANSI brightBlack, brightRed, brightGreen, brightYellow :: Color brightBlue, brightMagenta, brightCyan, brightWhite :: Color brightBlack = ISOColor 8 brightRed = ISOColor 9 brightGreen = ISOColor 10 brightYellow = ISOColor 11 brightBlue = ISOColor 12 brightMagenta= ISOColor 13 brightCyan = ISOColor 14 brightWhite = ISOColor 15 -- | Styles are represented as an 8 bit word. Each bit in the word is 1 if the style attribute -- assigned to that bit should be applied and 0 if the style attribute should not be applied. type Style = Word8 -- | The 6 possible style attributes: -- -- * standout -- -- * underline -- -- * reverseVideo -- -- * blink -- -- * dim -- -- * bold/bright -- -- ( The invisible, protect, and altcharset display attributes some terminals support are not -- supported via VTY.) standout, underline, reverseVideo, blink, dim, bold :: Style standout = 0x01 underline = 0x02 reverseVideo = 0x04 blink = 0x08 dim = 0x10 bold = 0x20 defaultStyleMask :: Style defaultStyleMask = 0x00 styleMask :: Attr -> Word8 styleMask attr = case attrStyle attr of Default -> 0 KeepCurrent -> 0 SetTo v -> v -- | true if the given Style value has the specified Style set. hasStyle :: Style -> Style -> Bool hasStyle s bitMask = ( s .&. bitMask ) /= 0 -- | Set the foreground color of an `Attr'. withForeColor :: Attr -> Color -> Attr withForeColor attr c = attr { attrForeColor = SetTo c } -- | Set the background color of an `Attr'. withBackColor :: Attr -> Color -> Attr withBackColor attr c = attr { attrBackColor = SetTo c } -- | Add the given style attribute withStyle :: Attr -> Style -> Attr withStyle attr styleFlag = attr { attrStyle = SetTo $ styleMask attr .|. styleFlag } -- | Sets the style, background color and foreground color to the default values for the terminal. -- There is no easy way to determine what the default background and foreground colors are. defAttr :: Attr defAttr = Attr Default Default Default instance Default Attr where def = defAttr -- | Keeps the style, background color and foreground color that was previously set. Used to -- override some part of the previous style. -- -- EG: current_style `withForeColor` brightMagenta -- -- Would be the currently applied style (be it underline, bold, etc) but with the foreground color -- set to brightMagenta. currentAttr :: Attr currentAttr = Attr KeepCurrent KeepCurrent KeepCurrent