Search code examples
gosubclassingfyne

catching Enter in a multiline Fyne Entry widget (more generally, calling "parent classes")


This question is more about Go than Fyne. Having extended Fyne's Entry widget is the prescribed fashion, I want to detect when Enter (Return) is pressed and use it as a signal that I need to act on the content of the Entry. I want Shift-Return to add a newline to the text without signalling that I need to act.

Given a struct that starts with

type myEntry struct {
    widget.Entry
    .....more... }

It's easy enough to add

func (m *myEntry) TypedKey(key *fyne.KeyEvent) {
    if key.Name == "Return" {
            ///send m.Text somewhere...
    } else {
        //WRONG: m.(*widget.Entry).TypedKey(key) //give Key to Entry widget to process
    }
}

but the else clause doesn't compile. So after having decided this isn't a Key I want to intercept, how do I give it back to widget.Entry? Other questions here about calling "base classes", which Go doesn't quite have, don't seem to cover this case.

I thought I could finesse this by adding

type myEntry struct {
    widget.Entry
    me *Fyne.Focusable

and setting me to the address of myEntry on creation, so I could simply call me.TypedKey. But keys were not handled, and then there was a crash. Setting me=&myNewEntryObject on creation apparently isn't sufficiently "widget.Entry-like" to win the day.

I know Go isn't an OO language, but extending a type and then redirecting calls back to the parent type is a fundamental programming technique; I'd go as far as saying there's no point in extending a struct if you can't get back to the "base struct's" behaviour from the extension. What am I missing?


Solution

  • Embedded types without a name can be referenced using the name of the type - so the following will work:

    func (m *myEntry) TypedKey(key *fyne.KeyEvent) {
        if key.Name == "Return" {
                // send m.Text somewhere...
        } else {
            Entry.TypedKey(key)
        }
    }