brick/programs/Main.hs

148 lines
4.4 KiB
Haskell
Raw Normal View History

2015-05-09 09:09:40 +03:00
{-# LANGUAGE OverloadedStrings #-}
2015-05-11 17:55:48 +03:00
{-# LANGUAGE TemplateHaskell #-}
2015-05-09 09:09:40 +03:00
module Main where
2015-05-11 17:55:48 +03:00
import Control.Lens
import Control.Monad.IO.Class (liftIO)
2015-05-09 19:56:14 +03:00
import Data.Default
2015-05-17 19:22:08 +03:00
import Data.Monoid
import Graphics.Vty hiding (translate)
2015-05-09 09:09:40 +03:00
import System.Exit
import qualified Data.Text as T
2015-05-09 09:09:40 +03:00
2015-05-18 04:41:38 +03:00
import Brick.Main
import Brick.Edit
import Brick.List
import Brick.Core
2015-06-25 06:54:32 +03:00
import Brick.Widgets.Core
2015-05-18 05:37:25 +03:00
import Brick.Center
2015-05-18 04:41:38 +03:00
import Brick.Border
import Brick.Border.Style
2015-05-18 04:41:38 +03:00
import Brick.Util
import Brick.AttrMap
import Brick.Markup
import Data.Text.Markup
2015-05-09 10:18:29 +03:00
styles :: [(T.Text, BorderStyle)]
2015-05-19 06:59:58 +03:00
styles =
2015-05-19 07:01:59 +03:00
[ ("ascii", ascii)
, ("uni", unicode)
, ("uni-bold", unicodeBold)
, ("uni-rounded", unicodeRounded)
2015-05-19 06:59:58 +03:00
]
data St =
2015-05-11 17:55:48 +03:00
St { _stEditor :: Editor
2015-05-19 00:14:13 +03:00
, _stList :: List Int
2015-05-19 06:59:58 +03:00
, _stBorderStyle :: Int
, _stTrans :: Location
}
2015-05-09 10:18:29 +03:00
2015-05-11 17:55:48 +03:00
makeLenses ''St
keywordAttr :: AttrName
keywordAttr = "app" <> "keyword"
editHighlightedKw1Attr :: AttrName
editHighlightedKw1Attr = editAttr <> "kw1"
editHighlightedKw2Attr :: AttrName
editHighlightedKw2Attr = editAttr <> "kw2"
kw :: Widget -> Widget
kw = withAttrName keywordAttr
2015-05-19 07:18:51 +03:00
highlightWord :: (Eq a) => String -> a -> Markup a -> Markup a
highlightWord w att mk = assignAttrs 0 chunks mk
where
wordLen = length w
s = toText mk
chunks = T.splitOn (T.pack w) s
assignAttrs _ [] m = m
assignAttrs _ [_] m = m
assignAttrs pos (t:ts) m = markupSet (pos + T.length t, wordLen) att $ assignAttrs (pos + T.length t + wordLen) ts m
applyMarkup :: String -> Markup AttrName
applyMarkup s =
highlightWord "foo" editHighlightedKw1Attr $
highlightWord "bar" editHighlightedKw2Attr $
(T.pack s) @? editAttr
drawEditString :: String -> Widget
drawEditString = markup . applyMarkup
drawUI :: St -> [Widget]
drawUI st = [withBorderStyle bs a]
2015-05-10 00:28:37 +03:00
where
2015-05-19 07:07:55 +03:00
(bsName, bs) = styles !! (st^.stBorderStyle)
box = borderWithLabel (txt bsName) $
(hLimit 25 (
(renderEditor drawEditString (st^.stEditor))
<=> hBorder
<=> (vLimit 10 $ renderList (st^.stList))
))
a = translateBy (st^.stTrans) $ vCenter $
(hCenter box)
<=> (vLimit 1 $ vPad ' ')
<=> (hCenter (kw "Enter" <+> " adds a list item"))
<=> (hCenter (kw "+" <+> " changes border styles"))
<=> (hCenter (kw "Arrow keys" <+> " navigates the list"))
<=> (hCenter (kw "Ctrl-Arrow keys" <+> " move the interface"))
2015-05-09 09:09:40 +03:00
appEvent :: Event -> St -> EventM St
appEvent e st =
2015-05-09 09:09:40 +03:00
case e of
EvKey (KChar '+') [] ->
return $ st & stBorderStyle %~ ((`mod` (length styles)) . (+ 1))
2015-05-19 06:59:58 +03:00
EvKey KEsc [] -> liftIO exitSuccess
2015-05-18 18:38:30 +03:00
EvKey KUp [MCtrl] -> return $ st & stTrans %~ (\(Location (w, h)) -> Location (w, h - 1))
EvKey KDown [MCtrl] -> return $ st & stTrans %~ (\(Location (w, h)) -> Location (w, h + 1))
EvKey KLeft [MCtrl] -> return $ st & stTrans %~ (\(Location (w, h)) -> Location (w - 1, h))
EvKey KRight [MCtrl] -> return $ st & stTrans %~ (\(Location (w, h)) -> Location (w + 1, h))
EvKey KEnter [] ->
2015-05-17 20:01:23 +03:00
let el = length $ listElements $ st^.stList
in return $ st & stList %~ (listMoveBy 1 . listInsert el el)
2015-05-18 18:38:30 +03:00
ev -> return $ st & stEditor %~ (handleEvent ev)
& stList %~ (handleEvent ev)
initialState :: St
initialState =
St { _stEditor = editor (Name "edit") ""
, _stList = list (Name "list") listDrawElem []
2015-05-19 06:59:58 +03:00
, _stBorderStyle = 0
, _stTrans = Location (0, 0)
}
listDrawElem :: Bool -> Int -> Widget
2015-05-17 19:44:18 +03:00
listDrawElem sel i =
let selStr s = if sel then "<" <> s <> ">" else s
in hCenterWith (Just ' ') $ vBox $ for [1..i+1] $ \j ->
(str $ "Item " <> (selStr $ show i) <> " L" <> show j, High)
theAttrMap :: AttrMap
theAttrMap = attrMap defAttr
[ (listSelectedAttr, white `on` blue)
, (editAttr, white `on` blue)
, (editHighlightedKw1Attr, fg magenta)
, (editHighlightedKw2Attr, fg cyan)
, (keywordAttr, fg blue)
, (borderAttr, fg blue)
, (hBorderLabelAttr, fg cyan)
]
2015-05-17 19:22:08 +03:00
2015-05-11 01:51:08 +03:00
theApp :: App St Event
2015-05-11 00:56:58 +03:00
theApp =
2015-05-09 19:56:14 +03:00
def { appDraw = drawUI
2015-05-11 01:42:59 +03:00
, appChooseCursor = showFirstCursor
, appHandleEvent = appEvent
, appAttrMap = const theAttrMap
}
2015-05-09 09:09:40 +03:00
main :: IO ()
2015-05-11 01:51:08 +03:00
main = defaultMain theApp initialState