dyna-brick-0.1.0.0: src/Dyna/Brick/Types.hs
-- | Brick application types
module Dyna.Brick.Types(
-- * Brick helper types
Box,
BoxId(..),
Win(..),
Act(..),
MouseUpEvent(..),
MouseDownEvent(..),
-- * Brick application monad
Run(..),
evalRun,
-- * FRP types
Evt(..),
Dyn(..),
-- * Internal types
Env(..),
newEnv,
InternalEvent(..),
) where
import Prelude hiding ((<*))
import Control.Applicative (liftA2, liftA3)
import Control.Monad.Reader
import Control.Monad.Base
import Control.Monad.Trans.Control (MonadBaseControl(..))
import Control.Monad.Random.Class
import Control.Concurrent.Chan.Unagi
import Data.Text (Text)
import Data.Boolean
import Data.AdditiveGroup
import Data.AffineSpace
import Data.VectorSpace
import Data.Basis
import Data.Cross
import Data.String
import Temporal.Class
import Data.IORef
import Dyna qualified as D
import Brick
import qualified Graphics.Vty as Vty
import Graphics.Vty (Key(..), Modifier, Button)
----------------------------------------------------------------------------------
-- brick helper types
-- | Synonym to fix the Widget parameter
type Box = Widget BoxId
-- | Box identifier
newtype BoxId = BoxId { getBoxId :: Text }
deriving (Show, Eq, Ord, Read)
-- | Actions for Brick rendering engine
data Act
= Quit -- ^ Quit the app
-- | Window of the application
data Win = Win
{ win'widgets :: Dyn [Box] -- ^ window view
, win'acts :: Evt Act -- ^ brick app actions
}
-- | Mouse down events only
data MouseDownEvent = MouseDownEvent BoxId Button [Modifier] Location
-- | Mouse up events only
data MouseUpEvent = MouseUpEvent BoxId (Maybe Button) Location
----------------------------------------------------------------------------------
-- Brick application monad
newtype Run a = Run { unRun :: ReaderT Env IO a }
deriving ( Functor, Applicative, Monad, MonadReader Env, MonadIO
, MonadBase IO, MonadRandom)
evalRun :: Run a -> Env -> IO a
evalRun (Run act) env = runReaderT act env
newtype StMRun a =
StMRun { unStMRun :: StM (ReaderT Env IO) a }
instance MonadBaseControl IO Run where
type StM Run a = StMRun a
liftBaseWith f =
Run $ liftBaseWith $ \q -> f (fmap StMRun . q . unRun)
restoreM = Run . restoreM . unStMRun
instance D.Frp Run where
type Ref Run = IORef
----------------------------------------------------------------------------------
-- FRP types
-- | Event stream
newtype Evt a = Evt { unEvt :: D.Evt Run a }
deriving (Functor, Semigroup, Monoid, Applicative, Monad, Melody, Harmony, Compose, Loop)
type instance DurOf (Evt a) = Float
instance Limit (Evt a) where
lim t (Evt evt) = Evt $ lim (realToFrac t) evt
-- | Dynamic value that continuously changes over time
newtype Dyn a = Dyn { unDyn :: D.Dyn Run a }
deriving (Functor, Applicative, Num, Fractional, Semigroup, Monoid, IsString,
Boolean, AdditiveGroup, VectorSpace, HasNormal, HasCross2, HasCross3, AffineSpace, HasBasis)
type instance BooleanOf (Dyn a) = Dyn (BooleanOf a)
instance (IfB a) => IfB (Dyn a) where
ifB = liftA3 ifB
instance (EqB a) => EqB (Dyn a) where
(==*) = liftA2 (==*)
instance (OrdB a) => OrdB (Dyn a) where
(<*) = liftA2 (<*)
(>*) = liftA2 (>*)
(<=*) = liftA2 (<=*)
(>=*) = liftA2 (>=*)
----------------------------------------------------------------------------------
-- internal types
-- | Environment for execution of Brick and routing events to sensor streams
data Env = Env
{ env'eventChan :: D.UChan Vty.Event
, env'mouseDownChan :: D.UChan MouseDownEvent
, env'mouseUpChan :: D.UChan MouseUpEvent
}
-- | Init new environment
newEnv :: IO Env
newEnv = Env <$> newChan <*> newChan <*> newChan
-- | Internal events to interact with brock application
data InternalEvent
= UpdateWidgets [Box]
-- ^ update the view
| BrickAct Act
-- ^ send command to brick