module Termtab.Graphics.Demo (
runNotationDemo,
runPlaceholderDemo,
) where
import Codec.Picture (Image, PixelRGBA8)
import Control.Monad (forM_)
import Data.ByteString qualified as BS
import Data.Map.Strict qualified as Map
import System.IO (hFlush, hPutStrLn, stderr, stdout)
import Termtab.Defaults (defaultSong)
import Termtab.Graphics.Font
import Termtab.Graphics.Kitty (encodeImage, encodeVirtual)
import Termtab.Graphics.KittyPlacement
import Termtab.Graphics.Notation (defaultLayout, renderNotationImage)
import Termtab.Graphics.TermColor (foregroundOrDefault)
import Termtab.Types
runNotationDemo :: IO ()
runNotationDemo :: IO ()
runNotationDemo = (Image PixelRGBA8 -> IO ()) -> IO ()
withDefaultNotation ((Image PixelRGBA8 -> IO ()) -> IO ())
-> (Image PixelRGBA8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Image PixelRGBA8
img -> do
Handle -> ByteString -> IO ()
BS.hPut Handle
stdout (Image PixelRGBA8 -> ByteString
encodeImage Image PixelRGBA8
img)
Handle -> IO ()
hFlush Handle
stdout
String -> IO ()
putStr (Int -> Char -> String
forall a. Int -> a -> [a]
replicate Int
9 Char
'\n')
String -> IO ()
putStrLn String
"^ termtab notation (Kitty graphics protocol, foreground-colored)"
runPlaceholderDemo :: IO ()
runPlaceholderDemo :: IO ()
runPlaceholderDemo = (Image PixelRGBA8 -> IO ()) -> IO ()
withDefaultNotation ((Image PixelRGBA8 -> IO ()) -> IO ())
-> (Image PixelRGBA8 -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Image PixelRGBA8
img -> do
let imgId :: Int
imgId = Int
1
cols :: Int
cols = Int
24
rows :: Int
rows = Int
7
Handle -> ByteString -> IO ()
BS.hPut Handle
stdout (Int -> Int -> Int -> Image PixelRGBA8 -> ByteString
encodeVirtual Int
imgId Int
cols Int
rows Image PixelRGBA8
img)
Handle -> IO ()
hFlush Handle
stdout
let sgr :: String
sgr = Int -> String
foregroundIdSGR Int
imgId
[String] -> (String -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (Int -> Int -> [String]
placeholderRows Int
cols Int
rows) ((String -> IO ()) -> IO ()) -> (String -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \String
line ->
String -> IO ()
putStrLn (String
sgr String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
line String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"\ESC[0m")
String -> IO ()
putStrLn String
"^ termtab notation (Kitty Unicode placeholders)"
withDefaultNotation :: (Image PixelRGBA8 -> IO ()) -> IO ()
withDefaultNotation :: (Image PixelRGBA8 -> IO ()) -> IO ()
withDefaultNotation Image PixelRGBA8 -> IO ()
display = do
mFont <- IO (Maybe String)
bravuraFontPath
case mFont of
Maybe String
Nothing ->
Handle -> String -> IO ()
hPutStrLn Handle
stderr String
"TERMTAB_BRAVURA_FONT is not set (use the Nix devshell)."
Just String
path -> do
ink <- IO PixelRGBA8
foregroundOrDefault
withGlyphFont path $ \GlyphFont
font -> do
let song :: Song
song = Song
defaultSong
case (Song -> [Track]
songTracks Song
song, Song -> [Measure]
songMeasures Song
song) of
(Track
track : [Track]
_, Measure
measure : [Measure]
_) -> do
let instr :: Instrument
instr = Track -> Instrument
trackInstrument Track
track
beats :: [Beat]
beats = [Beat] -> MeasureIndex -> Map MeasureIndex [Beat] -> [Beat]
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault [] (Int -> MeasureIndex
MeasureIndex Int
0) (Track -> Map MeasureIndex [Beat]
trackBeats Track
track)
measures :: [(MeasureIndex, [Beat], Measure)]
measures = [(Int -> MeasureIndex
MeasureIndex Int
0, [Beat]
beats, Measure
measure)]
img <- GlyphFont
-> NotationLayout
-> PixelRGBA8
-> Int
-> Instrument
-> [(MeasureIndex, [Beat], Measure)]
-> IO (Image PixelRGBA8)
renderNotationImage GlyphFont
font NotationLayout
defaultLayout PixelRGBA8
ink Int
4 Instrument
instr [(MeasureIndex, [Beat], Measure)]
measures
display img
([Track], [Measure])
_ -> Handle -> String -> IO ()
hPutStrLn Handle
stderr String
"default song is missing a track or measure"