2

Haskell Gi-GTK noob here. And GTK noob in general.

I have an image, which I've wrapped in an Eventbox. Now, I want to detect when the user presses on the event box (mousedown). Some Googling points me to using button-press-event. My code is below.

drag <- imageNewFromFile "rszh.png"
dragevents <- eventBoxNew
containerAdd dragevents drag
set dragevents [widgetHalign := AlignEnd, widgetValign := AlignEnd]
onWidgetButtonPressEvent dragevents (print "Hello world")

And GHC fails to compile this with the following cryptic error message:

panedraggin.hs:30:42: error:
    • Couldn't match type ‘IO ()’
                     with ‘GI.Gdk.Structs.EventButton.EventButton -> IO Bool’
      Expected type: GI.Gtk.Objects.Widget.WidgetButtonPressEventCallback
        Actual type: IO ()
    • Possible cause: ‘print’ is applied to too many arguments
      In the second argument of ‘onWidgetButtonPressEvent’, namely
        ‘(print "Hello world")’
      In a stmt of a 'do' block:
        onWidgetButtonPressEvent dragevents (print "Hello world")
      In the expression:
        do { Gtk.init Nothing;
             window <- windowNew WindowTypeToplevel;
             onWidgetDestroy window mainQuit;
             windowMaximize window;
             .... }

What am I doing incorrectly?

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
hello
  • 73
  • 1
  • 6
  • 1
    You are using `print ...` as the event handler, but this is supposed to be a function accepting information about which button was pressed,etc. , and returning an `IO Bool`, where the boolean states whether the handler succeeded. – chi Jun 25 '17 at 09:59
  • I looked at the [gi-gtk hello world example](https://github.com/haskell-gi/gi-gtk-examples/blob/master/hello/World.hs) for help. On line 30, they used `onButtonClicked button (putStrLn "Hello World")` for signals. That code runs without errors. What is the difference between my code and their code? I ran `:t` on both functions in ghci, and the only difference in their type signatures is that one takes a `ButtonClickedCallback` as a parameter and the other takes a `WidgetButtonPressEventCallback`. Changing my print statement to a putStrLn function still gives me the same error. – hello Jun 25 '17 at 18:01
  • I'm not a gtk+ expert, but I'd guess one reacts to clicks, the other to mouse button presses -- which may or may not be clicks, since we have many buttons on our mice. Consequently, the even handler, in the latter case, takes an argument specifying which button was pressed, etc. – chi Jun 25 '17 at 19:05

1 Answers1

4

Well the error message already says it: it expects a function of the type EventButton -> IO Bool, and print "Hello world" has a type IO ().

You can however easily transform it into one, with:

onWidgetButtonPressEvent dragevents (const $ print "Hello world" >> return True)

So by using const $ we ignore the EventButton parameter for now (later you can decide to take the event parameters into account), and by using >> return True, we make sure that after printing, we return True (meaning the callback succeeded).

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555