{-# LANGUAGE CPP #-}
-- |

module Test.Sandwich.Formatters.TerminalUI.Draw.Util where

import Brick
import Graphics.Vty.Image
import Lens.Micro


fixedHeightOrViewportPercent :: (Ord n, Show n) => n -> Int -> Widget n -> Widget n
fixedHeightOrViewportPercent :: n -> Int -> Widget n -> Widget n
fixedHeightOrViewportPercent n
vpName Int
maxHeightPercent Widget n
w =
  Size -> Size -> RenderM n (Result n) -> Widget n
forall n. Size -> Size -> RenderM n (Result n) -> Widget n
Widget Size
Fixed Size
Fixed (RenderM n (Result n) -> Widget n)
-> RenderM n (Result n) -> Widget n
forall a b. (a -> b) -> a -> b
$ do
    -- Render the viewport contents in advance
    Result n
result <- Widget n -> RenderM n (Result n)
forall n. Widget n -> RenderM n (Result n)
render Widget n
w
    -- If the contents will fit in the maximum allowed rows,
    -- just return the content without putting it in a viewport.

    Context
ctx <- RenderM n Context
forall n. RenderM n Context
getContext

#if MIN_VERSION_brick(0,56,0)
    let usableHeight :: Int
usableHeight = Context
ctx Context -> Getting Int Context Int -> Int
forall s a. s -> Getting a s a -> a
^. Getting Int Context Int
Lens' Context Int
windowHeightL
#else
    let usableHeight = min 80 (ctx ^. availHeightL) -- Bound this so it looks okay inside a viewport
#endif

    let maxHeight :: Int
maxHeight = Rational -> Int
forall a b. (RealFrac a, Integral b) => a -> b
round (Int -> Rational
forall a. Real a => a -> Rational
toRational Int
usableHeight Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* (Int -> Rational
forall a. Real a => a -> Rational
toRational Int
maxHeightPercent Rational -> Rational -> Rational
forall a. Fractional a => a -> a -> a
/ Rational
100))

    if Image -> Int
imageHeight (Result n -> Image
forall n. Result n -> Image
image Result n
result) Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
maxHeight
      then Result n -> RenderM n (Result n)
forall (m :: * -> *) a. Monad m => a -> m a
return Result n
result
      -- Otherwise put the contents (pre-rendered) in a viewport
      -- and limit the height to the maximum allowable height.
      else Widget n -> RenderM n (Result n)
forall n. Widget n -> RenderM n (Result n)
render (Int -> Widget n -> Widget n
forall n. Int -> Widget n -> Widget n
vLimit Int
maxHeight (Widget n -> Widget n) -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$
                   n -> ViewportType -> Widget n -> Widget n
forall n.
(Ord n, Show n) =>
n -> ViewportType -> Widget n -> Widget n
viewport n
vpName ViewportType
Vertical (Widget n -> Widget n) -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$
                   Size -> Size -> RenderM n (Result n) -> Widget n
forall n. Size -> Size -> RenderM n (Result n) -> Widget n
Widget Size
Fixed Size
Fixed (RenderM n (Result n) -> Widget n)
-> RenderM n (Result n) -> Widget n
forall a b. (a -> b) -> a -> b
$ Result n -> RenderM n (Result n)
forall (m :: * -> *) a. Monad m => a -> m a
return Result n
result)