Search code examples
gouser-interfacefyne

Hold down button in golang fyne


With the fyne GUI framework it's easy to build simple guis with basic functionality. I was unable to find a way to detect the user pushing and holding a button for some time. I can only detect wether the button was clicked. Is it at all possible?


Solution

  • Widgets in fyne come with their most likely used functionality. When a widget does not offer a functionality, that is needed, it can be extended. An example where an icon is made clickable can be seen here. In this example the interface fyne/v2.Tappable is being implemented, which also contains an icon, which leads to a clickable icon.

    To make a button holdable we need to implement an interface, which can register mousedown and mouseup events. This interface is fyne/v2/driver/desktop.Mouseable.

    So this is what this can look like:

    package main
    import (
        "fyne.io/fyne/v2/app"
        "fyne.io/fyne/v2/widget"
        "fyne.io/fyne/v2/driver/desktop"
        "log"
    )
    
    type holdableButton struct {
        widget.Button
    }
    func newHoldableButton(label string) *holdableButton {
        button := &holdableButton{}
        button.ExtendBaseWidget(button)
        button.Text=label
        return button
    }
    
    func (h *holdableButton) MouseDown(*desktop.MouseEvent){
        log.Println("down")
    }
    func (h *holdableButton) MouseUp(*desktop.MouseEvent){
        log.Println("up")
    }
    
    func main() {
        a := app.New()
        w := a.NewWindow("Holdable")
        w.SetContent(newHoldableButton("Button"))
        w.ShowAndRun()
    }
    

    Important to note: The Mouseable interface does not appear by name and the driver package only needs to be imported to reference the desktop.MouseEvent. But as is the case in golang the interface is implemented by creating the two methods MouseUp and MouseDown and both need to exist even if you only "need" one, otherwise none of this will work.

    Thank you to andy.xyz who pointed me in the right direction.