Toggle between event handlers in gtk2hs

312 views Asked by At

I would like to do something like this:

handlerOn = do
  cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOff
  putStrLn "handlerOn"

handlerOff = do
  cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOn
  putStrLn "handlerOff"

This won't work as it is, of course, because I'm trying to use cid inside a code block where cid is not assigned yet.

The idea is to register an event listener that when it receives an event, it will deregister itself and register a different event listener which will do the same, back and forth.

1

There are 1 answers

1
ephemient On BEST ANSWER

GHC supports recursive do.

handlerOn = do
  rec cid <- canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOff
  putStrLn "handlerOn"

You could also use Control.Monad.Fix.

handlerOff = do
  mfix $ \cid -> canvas `on` buttonPressEvent $ tryEvent do
    signalDisconnect cid
    handlerOn
  putStrLn "handlerOff"

Or manage the handler yourself.

do ...
    h <- newIORef undefined
    let handlerOn = do
            ...
            writeIORef h handlerOff
        handlerOff = do
            ...
            writeIORef h handlerOn
    writeIORef h handlerOn
    canvas `on` buttonPressEvent $ tryEvent =<< readIORef h

Or just make everything into a single handler.

do ...
    ms <- newIORef False
    canvas `on` buttonPressEvent $ tryEvent do
        s <- readIORef ms
        if s
            then ...
            else ...