zwirn-0.2.3.1: app/zwirnmill/UI/Core.hs
{-# LANGUAGE TemplateHaskell #-}
module UI.Core where
import Brick (EventM)
import qualified Brick.Animation as A
import Brick.BChan (BChan)
import Control.Monad.RWS
import qualified Data.Map as Map
import qualified Data.Text as T
import Data.Vector (Vector)
import Editor.Core
import qualified Graphics.Vty as V
import Keymap (FullKeyConfig)
import Lens.Micro.TH (makeLenses)
import Zwirn.Doux.Types (Stream)
import Zwirn.Language.Compiler (Environment, runCIEnv, setExpression)
import Zwirn.Language.Evaluate.Expression
import Zwirn.Language.TypeCheck.Types (Qualified (..), Scheme (..), numberT)
data Name
= Editor Int
| EditorViewport Int
| Cursor
| Status
| Output
| Slider Int
| Background
| OptionWin
| Animator
| SampleBrowser
| SampleBrowserViewport
| Keyboard
| EnvBrowser
| EnvBrowserViewport
| Documentation
| DocViewport
| DocLink Int
| DocCode Int
deriving (Eq, Ord, Show)
data AppEvent
= FileSelected (Maybe FilePath)
| UpdateStatus
| UpdateOutput (OutputType, String)
| UpdateEnv
| ClearFlash
| AnimationUpdate (EventM Name AppState ())
data DragAction
= Move
| ResizeBottom
| ResizeRight
| ResizeBoth
| Content
deriving (Eq, Show)
data AnimationConfig = AnimationConfig {animationConfigRate :: Int, animationConfigPath :: String}
deriving (Show, Eq)
data Content
= StatusContent String Double Double Int Double (Int, Int) Int Int Double
| OutputContent [(OutputType, String)]
| EditorContent EditorState
| SliderContent Double
| AnimationContent (Maybe (A.Animation AppState Name)) AnimationConfig
| DocumentationContent Doc DocFocus DocMap
| SampleBrowserContent SampleBrowser
| EnvBrowserContent EnvBrowser
| KeyboardContent Keyboard
newtype DocumentationConfig = DocumentationConfig (Maybe T.Text)
deriving (Show, Eq)
newtype Keyboard = KeyB {kSound :: Maybe T.Text}
data SampleBrowser = SampleB
{ sbSearchString :: T.Text,
sbContent :: Vector (T.Text, Int)
}
data EnvBrowser = EnvB
{ ebSearchString :: T.Text,
ebContent :: Vector T.Text
}
data DocFocus
= CodeFocus Int
| LinkFocus Int
| NoFocus
deriving (Eq, Show)
data DocStyle
= Normal
| Emph
| Strong
| Code
deriving (Eq, Show)
data DocInline
= TextChunk T.Text DocStyle
| Link T.Text T.Text
| Linebreak
deriving (Show, Eq)
data DocBlock
= Paragraph [DocInline]
| CodeBlock T.Text
deriving (Show, Eq)
newtype Doc = Doc [DocBlock]
deriving (Show, Eq)
type DocMap = Map.Map T.Text Doc
data Option
= Hide
| Close
| Show Name
| AddEditor
| AddSlider
| ToggleAnimation
| ChangeAnimation
| ChangeFramerate
| SetBootPath
| SetSamplePath
| ToggleLabel
| QuitMill
| Copy
| GotoStart
| OpenConfig
| OpenKeymap
| SelectAction
deriving (Eq, Show)
data OptionWindow = OptionWindow
{ optionPos :: (Int, Int),
optionParent :: Name,
options :: [Option]
}
data Window = Window
{ windowPos :: (Int, Int),
windowSize :: (Int, Int),
windowContent :: Content,
windowHidden :: Bool,
windowLabel :: Bool
}
type WindowMap = Map.Map Name Window
data AppState = AppState
{ asWindows :: WindowMap,
asEnvironment :: Environment,
asStream :: Stream,
asMaxVoices :: Int,
asKeyConfig :: FullKeyConfig,
asVtyOutput :: Maybe V.Output,
asChan :: BChan AppEvent,
asDragging :: Maybe ((Int, Int), Name, DragAction),
asActiveWindow :: Name,
asOptionWindow :: Maybe OptionWindow,
asAnimationManager :: A.AnimationManager AppState AppEvent Name
}
updateSlider :: Int -> Double -> Environment -> IO Environment
updateSlider slidern val env = do
x <- runCIEnv env (setExpression ("slider" <> T.show slidern) (Forall [] $ Qual [] [] numberT) (EZwirn $ pure $ ENum val))
case x of
Right (_, env') -> return env'
Left _ -> return env
newSlider :: Int -> EventM Name AppState Window
newSlider i = do
env <- gets asEnvironment
env' <- liftIO $ updateSlider i 0.5 env
modify (\as -> as {asEnvironment = env'})
return $ Window (0, 0) (30, 3) (SliderContent 0.5) False False
data EditorEventEnv = EditorEventEnv
{ _envBChan :: BChan AppEvent,
_envName :: Name,
_envKeyConfig :: FullKeyConfig,
_envVtyOut :: Maybe V.Output,
_envEnv :: Environment,
_envEditorState :: EditorState
}
makeLenses ''EditorEventEnv