{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE Trustworthy #-}
module WEditorBrick.WrappingEditor (
WrappingEditor,
WrappingEditorAction,
WrappingEditorDoer,
doWrappingEditor,
dumpWrappingEditor,
genericWrappingEditor,
handleWrappingEditor,
mapWrappingEditor,
newWrappingEditor,
renderWrappingEditor,
) where
import Brick.Main
import Brick.Types
import Brick.Widgets.Core
import Graphics.Vty.Input
import Lens.Micro
import WEditor.Base
import WEditor.Document
newWrappingEditor :: FixedFontParser a c => a -> n -> [[c]] -> WrappingEditor c n
newWrappingEditor b n cs = genericWrappingEditor n $ editDocument b $ map UnparsedPara cs
genericWrappingEditor :: (FixedFontViewer a c, FixedFontEditor a c) => n -> a -> WrappingEditor c n
genericWrappingEditor = WrappingEditor
type WrappingEditorAction c = forall a. (FixedFontViewer a c, FixedFontEditor a c) => a -> a
mapWrappingEditor :: WrappingEditorAction c -> WrappingEditor c n -> WrappingEditor c n
mapWrappingEditor f (WrappingEditor name editor) = WrappingEditor name (f editor)
type WrappingEditorDoer c b = forall a. (FixedFontViewer a c, FixedFontEditor a c) => a -> b
doWrappingEditor :: WrappingEditorDoer c b -> WrappingEditor c n -> b
doWrappingEditor f (WrappingEditor _ editor) = f editor
dumpWrappingEditor :: WrappingEditor c n -> [[c]]
dumpWrappingEditor = map upText . doWrappingEditor exportData
renderWrappingEditor :: (Ord n, Show n) => Bool -> WrappingEditor Char n -> Widget n
renderWrappingEditor focus editor = doWrappingEditor edit editor where
edit e = Widget Greedy Greedy $ do
ctx <- getContext
let width = ctx^.availWidthL
let height = ctx^.availHeightL
let e' = if height > 0
then viewerResizeAction (width,height) e
else e
render $ viewport (getName editor) Vertical $ setCursor e' $ textArea width height e' where
setCursor
| focus = showCursor (getName editor) . Location . getCursor
| otherwise = const id
textArea w h = vBox . lineFill w h . map (strFill w) . getVisible
strFill w cs = str $ take w $ cs ++ repeat ' '
lineFill w h ls = take h $ ls ++ repeat (strFill w "")
handleWrappingEditor :: (Eq n) => WrappingEditor Char n -> Event -> EventM n (WrappingEditor Char n)
handleWrappingEditor editor event = do
extent <- lookupExtent (getName editor)
return $ mapWrappingEditor (action . resizeAction extent) editor where
action :: EditorAction Char
action =
case event of
EvKey KBS [] -> editorBackspaceAction
EvKey KDel [] -> editorDeleteAction
EvKey KDown [] -> editorDownAction
EvKey KEnd [] -> editorEndAction
EvKey KEnter [] -> editorEnterAction
EvKey KHome [] -> editorHomeAction
EvKey KLeft [] -> editorLeftAction
EvKey KPageDown [] -> editorPageDownAction
EvKey KPageUp [] -> editorPageUpAction
EvKey KRight [] -> editorRightAction
EvKey KUp [] -> editorUpAction
EvKey (KChar c) [] | not (c `elem` "\t\r\n") -> editorAppendAction [c]
_ -> id
resizeAction (Just ext) | snd (extentSize ext) > 0 = viewerResizeAction (extentSize ext)
resizeAction _ = id
data WrappingEditor c n =
forall a. (FixedFontViewer a c, FixedFontEditor a c) => WrappingEditor {
weName :: n,
weEditor :: a
}
instance Show n => Show (WrappingEditor c n) where
show (WrappingEditor name editor) =
"WrappingEditor { name: " ++ show name ++
", size: " ++ show (getViewSize editor) ++
", cursor: " ++ show (getCursor editor) ++
", point: " ++ show (getEditPoint editor) ++ " }"
instance Named (WrappingEditor c n) n where
getName = weName