简体   繁体   中英

How to extend fyne BaseWidget - go gives error "type *SimpleCard has no field or method super"

I'm trying to extend fyne widget to have a simple clickable content with background. I searched fyne widgets to find an example that could be used as a starter and found something similar in List/ListItem.

I basically copied the list item code and adapted it a little bit. It does look similar to the simpler example on fyne documentation . But for some unknown reason go gives me an error and I don't know what the cause is or how I can fix it:

custom_widget/simple_card.go:80:24: c.card.super undefined (type *SimpleCard has no field or method super)

Here is the code of the module (custom_widget/simple_card.go):

package custom_widget

import (
    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/canvas"
    "fyne.io/fyne/v2/theme"
    "fyne.io/fyne/v2/widget"
    "log"
)

// Declare conformity with interfaces.
var _ fyne.Widget = (*SimpleCard)(nil)
var _ fyne.Tappable = (*SimpleCard)(nil)

type SimpleCard struct {
    widget.BaseWidget

    onTapped   func()
    background *canvas.Rectangle
    content    fyne.CanvasObject
    selected   bool
}

func NewSimpleCard(content fyne.CanvasObject, tapped func()) *SimpleCard {
    card := &SimpleCard{onTapped: tapped, content: content}
    card.ExtendBaseWidget(card)
    return card
}

// CreateRenderer is a private method to Fyne which links this custom_widget to its renderer.
func (c *SimpleCard) CreateRenderer() fyne.WidgetRenderer {
    c.ExtendBaseWidget(c)

    c.background = canvas.NewRectangle(theme.SelectionColor())
    c.background.Hide()

    objects := []fyne.CanvasObject{c.background, c.content}

    // NewBaseRenderer and BaseRenderer are copied from
    // https://github.com/fyne-io/fyne/blob/master/internal/widget/base_renderer.go
    // because the functionality is marked internal in fyne !?
    return &SimpleCardRenderer{NewBaseRenderer(objects), c}
}

func (c *SimpleCard) Tapped(_ *fyne.PointEvent) {
    log.Println("I have been tapped")
    if c.onTapped != nil {
        c.selected = true
        c.Refresh()
        c.onTapped()
    }
}

// Declare conformity with the WidgetRenderer interface.
var _ fyne.WidgetRenderer = (*SimpleCardRenderer)(nil)

type SimpleCardRenderer struct {
    BaseRenderer

    card *SimpleCard
}

// MinSize calculates the minimum size of a SimpleCardRenderer.
// This is based on the size of the status indicator and the size of the child object.
func (c *SimpleCardRenderer) MinSize() fyne.Size {
    return c.card.content.MinSize()
}

// Layout the components of the SimpleCardRenderer custom_widget.
func (c *SimpleCardRenderer) Layout(size fyne.Size) {
    c.card.background.Resize(size)
    c.card.content.Resize(size)
}

func (c *SimpleCardRenderer) Refresh() {
    if c.card.selected {
        c.card.background.FillColor = theme.SelectionColor()
        c.card.background.Show()
    } else {
        c.card.background.Hide()
    }
    c.card.background.Refresh()
    canvas.Refresh(c.card.super()) // compiler error !
}

Remove all of the renderer type you created and in the CreateRenderer just return widget.NewSimpleRenderer(container.NewMax(c.background, c.content)) . It is simpler than you think.

Copying code out of the main widgets is often not the best way as we have shortcuts and/or must support more functionality than your own widgets.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM