on 00a6a4f help sign in
vty/src/Graphics/Vty/Attributes.hs
213 lines 7.2 kB history raw
1{-# LANGUAGE StandaloneDeriving #-}
2{-# LANGUAGE GADTs #-}
3{-# LANGUAGE RankNTypes #-}
4-- | Display attributes
5--
6-- Typically the values 'def_attr' or 'current_attr' are modified to form attributes:
7--
8-- @
9-- def_attr `with_fore_color` red
10-- @
11--
12-- Is the attribute that will set the foreground color to red and the background color to the
13-- default.
14--
15-- This can then be used to build an image wiht a red foreground like so:
16--
17-- @
18-- string (def_attr `with_fore_color` red) "this text will be red"
19-- @
20--
21-- The default attributes set by 'def_attr' have a presentation determined by the terminal. This is
22-- not something VTY can control. The user is free to define the color scheme of the terminal as
23-- they see fit. Up to the limits of the terminal anyways.
24--
25-- The value 'current_attr' will keep the attributes of whatever was output previously.
26--
27-- \todo This API is very verbose IMO. I'd like something more succinct.
28module Graphics.Vty.Attributes ( module Graphics.Vty.Attributes
29 , module Graphics.Vty.Attributes.Color
30 , module Graphics.Vty.Attributes.Color240
31 )
32 where
34import Data.Bits
35import Data.Monoid
36import Data.Word
38import Graphics.Vty.Attributes.Color
39import Graphics.Vty.Attributes.Color240
41-- | A display attribute defines the Color and Style of all the characters rendered after the
42-- attribute is applied.
43--
44-- At most 256 colors, picked from a 240 and 16 color palette, are possible for the background and
45-- foreground. The 240 colors and 16 colors are points in different palettes. See Color for more
46-- information.
47data Attr = Attr
48 { attr_style :: !(MaybeDefault Style)
49 , attr_fore_color :: !(MaybeDefault Color)
50 , attr_back_color :: !(MaybeDefault Color)
51 } deriving ( Eq, Show )
53-- This could be encoded into a single 32 bit word. The 32 bit word is first divided
54-- into 4 groups of 8 bits where: The first group codes what action should be taken with regards to
55-- the other groups.
56-- XXYYZZ__
57-- XX - style action
58-- 00 => reset to default
59-- 01 => unchanged
60-- 10 => set
61-- YY - foreground color action
62-- 00 => reset to default
63-- 01 => unchanged
64-- 10 => set
65-- ZZ - background color action
66-- 00 => reset to default
67-- 01 => unchanged
68-- 10 => set
69-- __ - unused
70--
71-- Next is the style flags
72-- SURBDO__
73-- S - standout
74-- U - underline
75-- R - reverse video
76-- B - blink
77-- D - dim
78-- O - bold
79-- __ - unused
80--
81-- Then the foreground color encoded into 8 bits.
82-- Then the background color encoded into 8 bits.
84instance Monoid Attr where
85 mempty = Attr mempty mempty mempty
86 mappend attr_0 attr_1 =
87 Attr ( attr_style attr_0 `mappend` attr_style attr_1 )
88 ( attr_fore_color attr_0 `mappend` attr_fore_color attr_1 )
89 ( attr_back_color attr_0 `mappend` attr_back_color attr_1 )
91-- | Specifies the display attributes such that the final style and color values do not depend on
92-- the previously applied display attribute. The display attributes can still depend on the
93-- terminal's default colors (unfortunately).
94data FixedAttr = FixedAttr
95 { fixed_style :: !Style
96 , fixed_fore_color :: !(Maybe Color)
97 , fixed_back_color :: !(Maybe Color)
98 } deriving ( Eq, Show )
100-- | The style and color attributes can either be the terminal defaults. Or be equivalent to the
101-- previously applied style. Or be a specific value.
102data MaybeDefault v where
103 Default :: MaybeDefault v
104 KeepCurrent :: MaybeDefault v
105 SetTo :: forall v . ( Eq v, Show v ) => !v -> MaybeDefault v
107deriving instance Eq v => Eq (MaybeDefault v)
108deriving instance Eq v => Show (MaybeDefault v)
110instance Eq v => Monoid ( MaybeDefault v ) where
111 mempty = KeepCurrent
112 mappend Default Default = Default
113 mappend Default KeepCurrent = Default
114 mappend Default ( SetTo v ) = SetTo v
115 mappend KeepCurrent Default = Default
116 mappend KeepCurrent KeepCurrent = KeepCurrent
117 mappend KeepCurrent ( SetTo v ) = SetTo v
118 mappend ( SetTo _v ) Default = Default
119 mappend ( SetTo v ) KeepCurrent = SetTo v
120 mappend ( SetTo _ ) ( SetTo v ) = SetTo v
122-- | Standard 8-color ANSI terminal color codes.
123black, red, green, yellow, blue, magenta, cyan, white :: Color
124black = ISOColor 0
125red = ISOColor 1
126green = ISOColor 2
127yellow = ISOColor 3
128blue = ISOColor 4
129magenta= ISOColor 5
130cyan = ISOColor 6
131white = ISOColor 7
133-- | Bright/Vivid variants of the standard 8-color ANSI
134bright_black, bright_red, bright_green, bright_yellow :: Color
135bright_blue, bright_magenta, bright_cyan, bright_white :: Color
136bright_black = ISOColor 8
137bright_red = ISOColor 9
138bright_green = ISOColor 10
139bright_yellow = ISOColor 11
140bright_blue = ISOColor 12
141bright_magenta= ISOColor 13
142bright_cyan = ISOColor 14
143bright_white = ISOColor 15
145-- | Styles are represented as an 8 bit word. Each bit in the word is 1 if the style attribute
146-- assigned to that bit should be applied and 0 if the style attribute should not be applied.
147type Style = Word8
149-- | The 6 possible style attributes:
150--
151-- * standout
152--
153-- * underline
154--
155-- * reverse_video
156--
157-- * blink
158--
159-- * dim
160--
161-- * bold/bright
162--
163-- ( The invisible, protect, and altcharset display attributes some terminals support are not
164-- supported via VTY.)
165standout, underline, reverse_video, blink, dim, bold :: Style
166standout = 0x01
167underline = 0x02
168reverse_video = 0x04
169blink = 0x08
170dim = 0x10
171bold = 0x20
173default_style_mask :: Style
174default_style_mask = 0x00
176style_mask :: Attr -> Word8
177style_mask attr
178 = case attr_style attr of
179 Default -> 0
180 KeepCurrent -> 0
181 SetTo v -> v
183-- | true if the given Style value has the specified Style set.
184has_style :: Style -> Style -> Bool
185has_style s bit_mask = ( s .&. bit_mask ) /= 0
187-- | Set the foreground color of an `Attr'.
188with_fore_color :: Attr -> Color -> Attr
189with_fore_color attr c = attr { attr_fore_color = SetTo c }
191-- | Set the background color of an `Attr'.
192with_back_color :: Attr -> Color -> Attr
193with_back_color attr c = attr { attr_back_color = SetTo c }
195-- | Add the given style attribute
196with_style :: Attr -> Style -> Attr
197with_style attr style_flag = attr { attr_style = SetTo $ style_mask attr .|. style_flag }
199-- | Sets the style, background color and foreground color to the default values for the terminal.
200-- There is no easy way to determine what the default background and foreground colors are.
201def_attr :: Attr
202def_attr = Attr Default Default Default
204-- | Keeps the style, background color and foreground color that was previously set. Used to
205-- override some part of the previous style.
206--
207-- EG: current_style `with_fore_color` bright_magenta
208--
209-- Would be the currently applied style (be it underline, bold, etc) but with the foreground color
210-- set to bright_magenta.
211current_attr :: Attr
212current_attr = Attr KeepCurrent KeepCurrent KeepCurrent