module Brick.Extensions.ThreeD.Widgets where
import Lens.Micro.Platform (view, (-~), (+~), (%~))
import Tart.Canvas (Canvas, canvasLayersToImage)
import Brick3D.Camera
import Brick3D.Renderer
import Brick3D.State
import Brick hiding (render)
import Graphics.Vty
import Linear.V3 (V3(..), _x, _y, _z)
import Control.Monad.IO.Class (liftIO)

-- | Core widget that displays 3D viewport.
--
-- You *should* call 'render' function in 'EventM'
-- to render image, because it requires IO action.
threeD :: ThreeDState -> Widget n
threeD :: ThreeDState -> Widget n
threeD = Image -> Widget n
forall n. Image -> Widget n
raw (Image -> Widget n)
-> (ThreeDState -> Image) -> ThreeDState -> Widget n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Canvas] -> Image
canvasLayersToImage ([Canvas] -> Image)
-> (ThreeDState -> [Canvas]) -> ThreeDState -> Image
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Canvas -> [Canvas]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Canvas -> [Canvas])
-> (ThreeDState -> Canvas) -> ThreeDState -> [Canvas]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting Canvas ThreeDState Canvas -> ThreeDState -> Canvas
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting Canvas ThreeDState Canvas
Lens' ThreeDState Canvas
screen


handle3DEvent :: Event -> ThreeDState -> EventM n ThreeDState
handle3DEvent :: Event -> ThreeDState -> EventM n ThreeDState
handle3DEvent Event
e ThreeDState
s = IO ThreeDState -> EventM n ThreeDState
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ThreeDState -> EventM n ThreeDState)
-> IO ThreeDState -> EventM n ThreeDState
forall a b. (a -> b) -> a -> b
$ ThreeDState -> IO ThreeDState
forall (m :: * -> *). MonadIO m => ThreeDState -> m ThreeDState
render (ThreeDState -> ThreeDState
modifier ThreeDState
s)
  where
    modifier :: ThreeDState -> ThreeDState
    modifier :: ThreeDState -> ThreeDState
modifier = case Event
e of
                 EvKey (KChar Char
'w') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
moveCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3   Float
0    Float
0  (-Float
1)))
                 EvKey (KChar Char
's') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
moveCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3   Float
0    Float
0    Float
1))
                 EvKey (KChar Char
'a') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
moveCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3 (-Float
1)   Float
0    Float
0))
                 EvKey (KChar Char
'd') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
moveCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3   Float
1    Float
0    Float
0))
                 EvKey (KChar Char
'q') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
moveCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3   Float
0  (-Float
1)   Float
0))
                 EvKey (KChar Char
'e') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
moveCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3   Float
0    Float
1    Float
0))
                 EvKey (KChar Char
'h') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
rotateCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3         Float
0    (Float
forall a. Floating a => a
piFloat -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
180)        Float
0))
                 EvKey (KChar Char
'l') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
rotateCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3         Float
0  (- Float
forall a. Floating a => a
piFloat -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
180)        Float
0))
                 EvKey (KChar Char
'k') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
rotateCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3   (Float
forall a. Floating a => a
piFloat -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
180)         Float
0         Float
0))
                 EvKey (KChar Char
'j') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
rotateCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3 (- Float
forall a. Floating a => a
piFloat -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
180)         Float
0         Float
0))
                 EvKey (KChar Char
'o') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
rotateCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3         Float
0          Float
0   (Float
forall a. Floating a => a
piFloat -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
180)))
                 EvKey (KChar Char
'p') [] -> (Camera -> Identity Camera) -> ThreeDState -> Identity ThreeDState
Lens' ThreeDState Camera
camera((Camera -> Identity Camera)
 -> ThreeDState -> Identity ThreeDState)
-> (Camera -> Camera) -> ThreeDState -> ThreeDState
forall s t a b. ASetter s t a b -> (a -> b) -> s -> t
%~(Position -> Camera -> Camera
rotateCamera (Float -> Float -> Float -> Position
forall a. a -> a -> a -> V3 a
V3         Float
0          Float
0 (- Float
forall a. Floating a => a
piFloat -> Float -> Float
forall a. Fractional a => a -> a -> a
/Float
180)))
                 Event
_ -> ThreeDState -> ThreeDState
forall a. a -> a
id