ansigraph-0.2.0.0: src/System/Console/Ansigraph/Internal/Core.hs
-- | Core functionality of the package. Import from either "System.Console.Ansigraph" or
-- "System.Console.Ansigraph.Core".
module System.Console.Ansigraph.Internal.Core where
import System.Console.ANSI
import System.IO (hFlush, stdout)
---- Basics ----
-- | ANSI colors are characterized by a 'Color' and a 'ColorIntensity'.
data AnsiColor = AnsiColor {
intensity :: ColorIntensity
, color :: Color
} deriving Show
-- | Record that holds graphing options.
data GraphSettings = GraphSettings {
-- | Foreground color for real number component.
realColor :: AnsiColor
-- | Foreground color for imaginary number component.
, imagColor :: AnsiColor
-- | Foreground color for negative real values. For matrix graphs only.
, realNegColor :: AnsiColor
-- | Foreground color for negative imaginary values. For matrix graphs only.
, imagNegColor :: AnsiColor
-- | Background color for real number component.
, realBG :: AnsiColor
-- | Background color for imaginary number component.
, imagBG :: AnsiColor
-- | Framerate in FPS.
, framerate :: Int
}
-- | 'Vivid' 'Blue' – used as the default real foreground color.
blue = AnsiColor Vivid Blue
-- | 'Vivid' 'Magenta' – used as the default foreground color for imaginary
-- graph component.
pink = AnsiColor Vivid Magenta
-- | 'Vivid' 'White' – used as the default graph background color
-- for both real and imaginary graph components.
white = AnsiColor Vivid White
-- | 'Vivid' 'Red' – used as the default foreground color for negative real component.
red = AnsiColor Vivid Red
-- | 'Dull' 'Green' – used as the default foreground color for negative imaginary component.
green = AnsiColor Dull Green
-- | Default graph settings.
graphDefaults = GraphSettings blue pink red green white white 15
-- | Holds two 'Maybe' 'AnsiColor's representing foreground and background colors for display via ANSI.
-- 'Nothing' means use the default terminal color.
data Coloring = Coloring { foreground :: Maybe AnsiColor,
background :: Maybe AnsiColor } deriving Show
-- | A 'Coloring' representing default terminal colors, i.e. two 'Nothing's.
noColoring = Coloring Nothing Nothing
-- | Helper constructor function for 'Coloring' that takes straight 'AnsiColor's without 'Maybe'.
mkColoring :: AnsiColor -> AnsiColor -> Coloring
mkColoring c1 c2 = Coloring (Just c1) (Just c2)
-- | Projection retrieving foreground and background colors
-- for real number graphs in the form of a 'Coloring'.
realColors :: GraphSettings -> Coloring
realColors s = mkColoring (realColor s) (realBG s)
-- | Projection retrieving foreground and background colors
-- for imaginary component of complex number graphs in the form of a 'Coloring'.
imagColors :: GraphSettings -> Coloring
imagColors s = mkColoring (imagColor s) (imagBG s)
-- | Retrieves a pair of 'Coloring's for real and imaginary graph components respectively.
colorSets :: GraphSettings -> (Coloring,Coloring)
colorSets s = (realColors s, imagColors s)
-- | Swaps foreground and background colors within a 'Coloring'.
invert :: Coloring -> Coloring
invert (Coloring fg bg) = Coloring bg fg
-- | The SGR command corresponding to a particular 'ConsoleLayer' and 'AnsiColor'.
interpAnsiColor :: ConsoleLayer -> AnsiColor -> SGR
interpAnsiColor l (AnsiColor i c) = SetColor l i c
-- | Set the given 'AnsiColor' on the given 'ConsoleLayer'.
setColor :: ConsoleLayer -> AnsiColor -> IO ()
setColor l c = setSGR [interpAnsiColor l c]
-- | Easily create a 'Coloring' by specifying the background 'AnsiColor' and no custom foreground.
fromBG :: AnsiColor -> Coloring
fromBG c = Coloring Nothing (Just c)
-- | Easily create a 'Coloring' by specifying the foreground 'AnsiColor' and no custom background.
fromFG :: AnsiColor -> Coloring
fromFG c = Coloring (Just c) Nothing
-- | Produce a (possibly empty) list of 'SGR' commands from a 'ConsoleLayer' and 'AnsiColor'.
-- An empty 'SGR' list is equivalent to 'Reset'.
sgrList :: ConsoleLayer -> Maybe AnsiColor -> [SGR]
sgrList l = fmap (interpAnsiColor l) . maybe [] (\x -> [x])
-- | Apply both foreground and background color contained in a 'Coloring'.
applyColoring :: Coloring -> IO ()
applyColoring (Coloring fg bg) = do
setSGR [Reset]
setSGR $ sgrList Foreground fg ++ sgrList Background bg
-- | Clear any SGR settings and then flush stdout.
clear :: IO ()
clear = setSGR [Reset] *> hFlush stdout
-- | Clear any SGR settings, flush stdout and print a new line.
clearLn :: IO ()
clearLn = clear *> putStrLn ""
-- | Use a particular ANSI 'Coloring' to print a string at the terminal (without a new line),
-- then clear all ANSI SGR codes and flush stdout.
colorStr :: Coloring -> String -> IO ()
colorStr c s = do
applyColoring c
putStr s
clear
-- | Use a particular ANSI 'Coloring' to print a string at the terminal,
-- then clear all ANSI SGR codes, flush stdout and print a new line.
colorStrLn :: Coloring -> String -> IO ()
colorStrLn c s = do
applyColoring c
putStr s
clearLn
-- | Like 'colorStr' but prints bold text.
boldStr :: Coloring -> String -> IO ()
boldStr c s = do
applyColoring c
setSGR [SetConsoleIntensity BoldIntensity]
putStr s
clear
-- | Like 'colorStrLn' but prints bold text.
boldStrLn :: Coloring -> String -> IO ()
boldStrLn c s = do
applyColoring c
setSGR [SetConsoleIntensity BoldIntensity]
putStr s
clearLn