Edit: move content draw function to render time, not construction

This change makes the renderEditor function take the content drawing
function that "editor" previously took. This does a better job of
separating presentation and representation concerns, and the content
drawing function never should have been part of the state to begin with.

This change removed the corresponding lens and Editor accessor for the
drawing function, removed the smart constructor parameter, and moved it
to be a parameter of the renderEditor function.
This commit is contained in:
Jonathan Daugherty 2017-06-26 11:52:46 -07:00
parent 5f6c0e443d
commit c07e9c0503
3 changed files with 13 additions and 18 deletions

View File

@ -37,8 +37,8 @@ makeLenses ''St
drawUI :: St -> [T.Widget Name]
drawUI st = [ui]
where
e1 = F.withFocusRing (st^.focusRing) E.renderEditor (st^.edit1)
e2 = F.withFocusRing (st^.focusRing) E.renderEditor (st^.edit2)
e1 = F.withFocusRing (st^.focusRing) (E.renderEditor (str . unlines)) (st^.edit1)
e2 = F.withFocusRing (st^.focusRing) (E.renderEditor (str . unlines)) (st^.edit2)
ui = C.center $
(str "Input 1 (unlimited): " <+> (hLimit 30 $ vLimit 5 e1)) <=>
@ -63,8 +63,8 @@ appEvent st _ = M.continue st
initialState :: St
initialState =
St (F.focusRing [Edit1, Edit2])
(E.editor Edit1 (str . unlines) Nothing "")
(E.editor Edit2 (str . unlines) (Just 2) "")
(E.editor Edit1 Nothing "")
(E.editor Edit2 (Just 2) "")
theMap :: A.AttrMap
theMap = A.attrMap V.defAttr

View File

@ -46,7 +46,7 @@ buttonLayer st =
C.hCenterLayer (padBottom (T.Pad 1) $ str "Click a button:") <=>
C.hCenterLayer (hBox $ padLeftRight 1 <$> buttons) <=>
C.hCenterLayer (padTopBottom 1 $ str "Or enter text and then click in this editor:") <=>
C.hCenterLayer (vLimit 3 $ hLimit 50 $ E.renderEditor True (st^.edit))
C.hCenterLayer (vLimit 3 $ hLimit 50 $ E.renderEditor (str . unlines) True (st^.edit))
where
buttons = mkButton <$> buttonData
buttonData = [ (Button1, "Button 1", "button1")
@ -143,4 +143,4 @@ main = do
\Excepteur sint occaecat cupidatat not proident,\n\
\sunt in culpa qui officia deserunt mollit\n\
\anim id est laborum.\n"
(E.editor TextBox (str . unlines) Nothing "")
(E.editor TextBox Nothing "")

View File

@ -18,7 +18,7 @@
-- Emacs. It is also not suitable for building sophisticated editors. If
-- you want to build your own editor, I suggest starting from scratch.
module Brick.Widgets.Edit
( Editor(editContents, editorName, editDrawContents)
( Editor(editContents, editorName)
-- * Constructing an editor
, editor
, editorText
@ -30,7 +30,6 @@ module Brick.Widgets.Edit
, applyEdit
-- * Lenses for working with editors
, editContentsL
, editDrawContentsL
-- * Rendering editors
, renderEditor
-- * Attributes
@ -64,8 +63,6 @@ import Brick.AttrMap
data Editor t n =
Editor { editContents :: Z.TextZipper t
-- ^ The contents of the editor
, editDrawContents :: [t] -> Widget n
-- ^ The function the editor uses to draw its contents
, editorName :: n
-- ^ The name of the editor
}
@ -105,8 +102,6 @@ handleEditorEvent e ed =
-- | Construct an editor over 'Text' values
editorText :: n
-- ^ The editor's name (must be unique)
-> ([T.Text] -> Widget n)
-- ^ The content rendering function
-> Maybe Int
-- ^ The limit on the number of lines in the editor ('Nothing'
-- means no limit)
@ -119,15 +114,13 @@ editorText = editor
editor :: Z.GenericTextZipper a
=> n
-- ^ The editor's name (must be unique)
-> ([a] -> Widget n)
-- ^ The content rendering function
-> Maybe Int
-- ^ The limit on the number of lines in the editor ('Nothing'
-- means no limit)
-> a
-- ^ The initial content
-> Editor a n
editor name draw limit s = Editor (Z.textZipper (Z.lines s) limit) draw name
editor name limit s = Editor (Z.textZipper (Z.lines s) limit) name
-- | Apply an editing operation to the editor's contents. Bear in mind
-- that you should only apply zipper operations that operate on the
@ -156,13 +149,15 @@ getEditContents e = Z.getText $ e^.editContentsL
-- name for its scrollable viewport handle and the name is also used to
-- report mouse events.
renderEditor :: (Ord n, Show n, Monoid t, TextWidth t, Z.GenericTextZipper t)
=> Bool
=> ([t] -> Widget n)
-- ^ The content drawing function
-> Bool
-- ^ Whether the editor has focus. It will report a cursor
-- position if and only if it has focus.
-> Editor t n
-- ^ The editor.
-> Widget n
renderEditor foc e =
renderEditor draw foc e =
let cp = Z.cursorPosition z
z = e^.editContentsL
toLeft = Z.take (cp^._2) (Z.currentLine z)
@ -178,7 +173,7 @@ renderEditor foc e =
clickable (e^.editorNameL) $
(if foc then showCursor (e^.editorNameL) cursorLoc else id) $
visibleRegion cursorLoc (atCharWidth, 1) $
e^.editDrawContentsL $
draw $
getEditContents e
charAtCursor :: (Z.GenericTextZipper t) => Z.TextZipper t -> Maybe t