{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses #-} module FRP.Netwire.Input.JavaScript ( JSInputState, JSInputControl, JSInput, JSInputT, Key(..), MouseButton(..), mkInputControl, initialInputState, pollJavaScript, cursorLocked, lockCursor, unlockCursor ) where import Control.Applicative import Control.Wire import FRP.Netwire.Input hiding (Key, MouseButton) import qualified FRP.Netwire.Input import Control.Monad.Trans.State import JavaScript.Input instance FRP.Netwire.Input.Key Key instance FRP.Netwire.Input.MouseButton MouseButton instance Monad m => MonadMouse MouseButton (JSInputT m) where setCursorMode cm = setCursorModeM $ case cm of CursorMode'Enabled -> (Just False, Just False) CursorMode'Hidden -> (Just False, Just True) _ -> (Just True, Nothing) mbIsPressed = mbIsPressedM releaseButton = releaseButtonM cursor = cursorM scroll = scrollM instance Monad m => MonadKeyboard Key (JSInputT m) where keyIsPressed = keyIsPressedM releaseKey = releaseKeyM -- | In JavaScript, you can lock the pointer only after the user releases a -- mouse button or a key. This means that 'cursorMode' (with 'CursorMode'Reset') -- and 'mouseMickies' will not actually lock the pointer, but will schedule -- the pointer lock request for the next interaction from the user. -- In particular, 'mouseMickies' will behave like 'mouseCursor' if the pointer -- is not locked. -- -- This wire, which inhibits if the pointer is not locked, is -- useful if you want to know if you're still waiting for the user to lock the -- pointer, and if the user manually unlocked it. cursorLocked :: (Monoid e, Monad m) => Wire s e (JSInputT m) a a cursorLocked = mkGen_ $ \x -> boolToEither x <$> lockedCursorM where boolToEither _ False = Left mempty boolToEither x True = Right x