I have this little project where I try to use gi-gtk to draw on a window.
https://github.com/bigos/cairo-example/blob/b9480dc63d6fff3bc195d35c7422f193fc8ae7d4/src/Main.hs
I have figured out how to make gi-gtk work with Cairo.
https://github.com/haskell-gi/haskell-gi/wiki/Using-Cairo-with-haskell-gi-generated-bindings
But I have a problem with obtaining cairo context. In the following code I have two events. The first event works fine. But I can't figure out how to get the cairo context needed for drawing on canves when I listen to key presses on window object.
win <- Gtk.windowNew WindowTypeToplevel
canvas <- Gtk.drawingAreaNew
Gtk.containerAdd win canvas
_ <- Gtk.onWidgetDraw canvas $ \context ->
renderWithContext context (updateCanvas canvas) >> pure True
_ <- Gtk.onWidgetKeyPressEvent win $ \x -> do
vvv <- Gdk.getEventKeyKeyval x
-- How do I draw on canvas here?
(putStrLn ("You have pressed key code " ++ (show vvv))) >> pure True
Simply put, you can't. You will not have access to the drawing context outside of the onWidgetDraw
callback.
What you can (and should) do is to use a global state to allow your onWidgetDraw
callback to draw different things depending on what happens. For example, if you want to draw some text when the user press the right arrow:
onWidgetKeyPressEvent
callback, set a value in your global state when the user presses the selected keyonWidgetDraw
callback, use that value to determine if you have to draw the text or not.IORef
s, TVar
s or any equivalent.