diff --git a/src/Forest/Client/WidgetTree.hs b/src/Forest/Client/WidgetTree.hs index a38889b..fb134d7 100644 --- a/src/Forest/Client/WidgetTree.hs +++ b/src/Forest/Client/WidgetTree.hs @@ -11,18 +11,34 @@ module Forest.Client.WidgetTree ) where import Brick +import Brick.BorderMap import Control.Monad.Trans.Reader import qualified Data.Text as T import qualified Graphics.Vty as Vty data WidgetTree n = WidgetTree (Widget n) [WidgetTree n] --- This attempts to properly indent multi-line widgets, though it's kinda hacky. --- It seems to work though, so I'm not going to complain (until the first bugs --- appear, that is). --- --- The text strings passed MUST NOT be multiline strings, or this entire --- function will break. +addLoc :: Location -> Location -> Location +addLoc l1 l2 = + let (x1, y1) = loc l1 + (x2, y2) = loc l2 + in Location (x1 + x2, y1 + y2) + +offsetResult :: Location -> Result n -> Result n +offsetResult offset result = result + { cursors = map offsetCursor $ cursors result + , visibilityRequests = map offsetVr $ visibilityRequests result + , extents = map offsetExtent $ extents result + , borders = translate offset $ borders result + } + where + offsetCursor c = c{cursorLocation = addLoc offset $ cursorLocation c} + offsetVr vr = vr{vrPosition = addLoc offset $ vrPosition vr} + offsetExtent e = e + { extentUpperLeft = addLoc offset $ extentUpperLeft e + , extentOffset = addLoc offset $ extentOffset e + } + indentWith :: T.Text -> T.Text -> Widget n -> Widget n indentWith firstLine otherLines wrapped = Widget { hSize = hSize wrapped @@ -35,8 +51,11 @@ indentWith firstLine otherLines wrapped = Widget context <- ask result <- render $ hLimit (availWidth context - maxWidth) wrapped let resultHeight = Vty.imageHeight $ image result - leftText = vBox $ txt firstLine : replicate (resultHeight - 1) (txt otherLines) - render $ leftText <+> wrapped + textLines = firstLine : replicate (resultHeight - 1) otherLines + leftImage = Vty.vertCat $ map (Vty.text' Vty.defAttr) textLines + newImage = leftImage Vty.<|> image result + newResult = offsetResult (Location (maxWidth, 0)) $ result{image=newImage} + pure newResult indent :: IndentOptions -> [Widget n] -> Widget n indent opts widgets = vBox $ reverse $ case reverse widgets of