0

I have a little Haskell program that uses the Gtk2Hs bindings. One can draw points (small squares) on the program's window by clicking on a DrawingArea:

[...]
    image <- builderGetObject gui castToDrawingArea "drawingarea"
    p <- widgetGetDrawWindow image
    gc <- gcNewWithValues p (newGCValues { foreground = Color 0 0 0,
        function = Copy })
    on image buttonPressEvent (point p gc)
    set image [ widgetCanFocus := True ]
[...]

point :: DrawWindow -> GC -> EventM EButton Bool
point p gc = tryEvent $ do
    (x', y') <- eventCoordinates
    liftIO $ do
        let x = round x'
        let y = round y'
        let relx = x `div` 4
        let rely = y `div` 4
        gcval <- gcGetValues gc
        gcSetValues gc (newGCValues { function = Invert })
        drawRectangle p gc True (relx * 4) (rely * 4) 4 4
        gcSetValues gc gcval

Through the trial-and-error method and after reading the docs at Hackage, I managed to add a button press event to the drawing area, since the widget doesn't provide a signal for this event by default. However, I don't understand the definition and usage of EventM, so I'm afraid I'll have to struggle with the EventM monad if I must add a new event to a widget again. I must say I'm still not proficient enough in Haskell. I somewhat understand how simple monads work, but this one "type EventM t a = ReaderT (Ptr t) IO a" (defined in Graphics.UI.Gtk.Gdk.EventM) seems a mistery to me.

My question is: Could someone please explain the internals of the EventM monad? For example in the case of "buttonPressEvent :: WidgetClass self => Signal self (EventM EButton Bool)".

Alfonso Villén
  • 373
  • 1
  • 9

1 Answers1

1

I am stacked by the similar problem,seems that EventM is a ReadT which will read the EButton and return Bool.

realli
  • 990
  • 6
  • 18
  • So some state is passed implicitly to the signal handler using a ReaderT monad, isn't it? I think I'm beginning to grasp this. It seems that Gtk2Hs signal handling conventions aren't consistent, though. – Alfonso Villén Nov 10 '13 at 10:23
  • I think so, document says "Every event carries additional information which is accessible through functions in the EventM monad". So I think the state will be passed implicitily. The EventM is used to access the information in events. – realli Nov 13 '13 at 06:22