module TextViewport.Viewport.Instance where import TextViewport.Buffer.Item import TextViewport.Buffer.Buffer (Buffer) import TextViewport.Buffer.Buffer qualified as Buffer import TextViewport.Render.RenderState qualified as RenderState import TextViewport.Render.RenderState (RenderState, mkRenderState) import TextViewport.Render.RenderedBuffer qualified as RenderedBuffer import TextViewport.Render.RenderedLine (RenderedLine(..)) -- TODO qualified import TextViewport.Viewport.Position (lookupPosition) import TextViewport.Viewport.Viewport (Viewport, clampViewport, mkViewport) import TextViewport.Viewport.Viewport qualified as Viewport data ViewportInstance = ViewportInstance { viRender :: RenderState , viView :: Viewport } deriving (Show) mkViewportInstance :: Int -> Int -> Buffer -> ViewportInstance mkViewportInstance width height buf = let rs = mkRenderState width buf vp = mkViewport width height rs in ViewportInstance rs vp visibleLines :: ViewportInstance -> [RenderedLine] visibleLines (ViewportInstance rs vp) = take (Viewport.vpHeight vp) . drop (Viewport.vpOffset vp) . RenderedBuffer.flatten $ RenderState.rsRendered rs applyToInstance :: (Viewport -> Viewport) -> ViewportInstance -> ViewportInstance applyToInstance f (ViewportInstance rs vp) = let vp' = f vp in ViewportInstance rs (clampViewport rs vp') applyToInstanceRS :: (RenderState -> Viewport -> Viewport) -> ViewportInstance -> ViewportInstance applyToInstanceRS f (ViewportInstance rs vp) = let vp' = f rs vp in ViewportInstance rs (clampViewport rs vp') scrollByI :: Int -> ViewportInstance -> ViewportInstance scrollByI delta = applyToInstance (Viewport.scrollBy delta) scrollUpI :: Int -> ViewportInstance -> ViewportInstance scrollUpI delta = applyToInstance (Viewport.scrollUp delta) scrollDownI :: Int -> ViewportInstance -> ViewportInstance scrollDownI delta = applyToInstance (Viewport.scrollDown delta) pageUpI :: ViewportInstance -> ViewportInstance pageUpI = applyToInstance Viewport.pageUp pageDownI :: ViewportInstance -> ViewportInstance pageDownI = applyToInstance Viewport.pageDown alignTopI :: ViewportInstance -> ViewportInstance alignTopI = applyToInstance Viewport.alignTop alignBottomI :: ViewportInstance -> ViewportInstance alignBottomI = applyToInstanceRS Viewport.alignBottom modifyItemI :: Int -> (Item -> Item) -> ViewportInstance -> ViewportInstance modifyItemI ix f (ViewportInstance rs vp) = let buf' = Buffer.modifyItem ix f (RenderState.rsBuffer rs) rs' = mkRenderState (RenderState.rsWidth rs) buf' vp' = clampViewport rs' vp in ViewportInstance rs' vp' lookupPositionI :: Int -> Int -> ViewportInstance -> Maybe (Int, Int) lookupPositionI x y (ViewportInstance rs vp) = lookupPosition x y vp (RenderState.rsRendered rs) --debugVI :: ViewportInstance -> IO () --debugVI (ViewportInstance rs vp) = do -- putStrLn ("offset = " ++ show (Viewport.vpOffset vp)) -- putStrLn ("height = " ++ show (Viewport.vpHeight vp)) -- putStrLn ("lineCount = " ++ show (RenderState.rsLineCount rs))