{-# OPTIONS_HADDOCK hide #-} {-# LANGUAGE NoImplicitPrelude #-} module Imj.Game.Hamazed.World.InTerminal ( mkInTerminal ) where import Imj.Prelude import Control.Monad.IO.Class(MonadIO) import qualified System.Console.Terminal.Size as Terminal( Window(..), size ) import Imj.Game.Hamazed.World.Size import Imj.Game.Hamazed.World.Types import Imj.Geo.Discrete.Types -- | Minimal margin between the upper left corner of the console -- and upper left corner of the world minimalWorldMargin :: Int minimalWorldMargin = 4 -- | Will compute the position of the 'World' so as to display it in the -- center of the terminal window. {-# INLINABLE mkInTerminal #-} mkInTerminal :: (MonadIO m) => Size -- ^ Measures the dimensions of the /inner/ content of the 'World', -- excluding the outer frame. -> m (Either String InTerminal) mkInTerminal s = do mayTermSize <- liftIO Terminal.size return $ InTerminal mayTermSize <$> worldUpperLeftToCenterIt' s mayTermSize worldUpperLeftToCenterIt' :: Size -> Maybe (Terminal.Window Int) -> Either String (Coords Pos) worldUpperLeftToCenterIt' worldSize mayTermSize = case mayTermSize of Just termSize@(Terminal.Window h w) -> let (Size rs cs) = maxWorldSize heightMargin = 2 * (1 {-outer walls-} + 1 {-1 line above and below-}) widthMargin = 2 * (1 {-outer walls-} + 4 {-brackets, spaces-} + 16 * 2 {-display all numbers-}) minSize@(Terminal.Window minh minw) = Terminal.Window (fromIntegral rs + heightMargin) (fromIntegral cs + widthMargin) in if h < minh || w < minw then Left $ "\nMinimum terminal size : " ++ show minSize ++ ".\nCurrent terminal size : " ++ show termSize ++ ".\nThe current terminal size doesn't match the minimum size," ++ "\nplease adjust your terminal size and restart the executable" ++ ".\n" else Right $ worldUpperLeftFromTermSize termSize worldSize Nothing -> Right $ Coords (Coord minimalWorldMargin) (Coord minimalWorldMargin) -- | upper left for the /outer/ content of the 'World', i.e including the /outer/ -- frame. worldUpperLeftFromTermSize :: Terminal.Window Int -> Size -> (Coords Pos) worldUpperLeftFromTermSize (Terminal.Window h w) (Size rs cs) = let walls = 2 :: Int in toCoords (quot (fromIntegral h-(rs+ fromIntegral walls)) 2) (quot (fromIntegral w-(cs+ fromIntegral walls)) 2)