Is it possible to hide the cursor using Gloss in Haskell? We want to replace the player with the mouse position.
This functionality isn't exposed by gloss: it would be more easily achievable if the Internal
modules were exposed (by using eg. playWithBackendIO
and some custom instances of Backend
to hide the cursor). If you really want this functionality, it'd be best to fork the project and add the functionality you want.
There are workarounds without modifying the original package though: when using any of the ...IO
functions, we can perform arbitrary IO
actions inside the functions we pass in, which allows us to modify the state of the backend.
I'm going to use displayIO
here for simplicity, but this works for any of the modes like playIO
etc.
import Prelude hiding (init)
import Control.Monad
import Data.IORef
import Data.StateVar
import Graphics.Gloss
import Graphics.Gloss.Interface.IO.Display
import qualified Graphics.UI.GLUT.Window as Glut
init :: IO ()
init = Glut.cursor $= Glut.None
render :: IORef Bool -> IO Picture
render doneInit = do
needsInit <- not <$> readIORef doneInit
when needsInit $ do
init
writeIORef doneInit True
return $ color white $ circle 30
controllerCallback :: Controller -> IO ()
controllerCallback _ = return ()
main :: IO ()
main = do
let disp = InWindow "test" (800, 600) (0, 0)
initVar <- newIORef False
displayIO disp black (render initVar) controllerCallback
The vital piece is Glut.cursor $= Glut.None
, which sets GLUT's cursor
value using StateVar's $=
function and automatically updates the glut context. We only want to run this once, so we use an IORef
to keep track of whether we've run it before.
Finally, this doesn't work for the GLFW backend. gloss uses a very old version of GLFW-b which doesn't support anything to do with cursor modes. More modern versions do, but I've not been able to find a way to get the Window
instance as Gloss just discards it.