基于golang的GUI框架fyne,自定义带右键菜单的图标控件,鼠标经过时显示边框,点击鼠标右键弹出命令菜单
package main
import (
"image/color"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/driver/mobile"
"fyne.io/fyne/v2/widget"
)
var _ fyne.Widget = (*WRect)(nil)
type WRect struct {
widget.BaseWidget
hovered bool
Index, role, x, y int
res fyne.Resource
UpdateState func(*WRect)
}
func NewWRect(res fyne.Resource, i, role int, fn func(*WRect)) *WRect {
s := &WRect{
Index: i,
y: i / n, // 行
x: i % n, // 列
role: role,
res: res,
UpdateState: fn,
}
s.ExtendBaseWidget(s)
return s
}
func NewWRect1() *WRect {
s := &WRect{}
s.ExtendBaseWidget(s)
return s
}
func (s *WRect) CreateRenderer() fyne.WidgetRenderer {
s.ExtendBaseWidget(s)
bar := canvas.NewRectangle(color.White)
bar.StrokeColor = red
// bar.StrokeWidth = 1
icon := canvas.NewImageFromResource(s.res)
return &rectRenderer{
objs: []fyne.CanvasObject{bar, icon},
bar: bar,
icon: icon,
d: s,
}
}
func (b *WRect) Cursor() desktop.Cursor {
return desktop.PointerCursor
// if b.hovered {
// return desktop.PointerCursor
// }
// return desktop.DefaultCursor
}
func (b *WRect) MouseIn(*desktop.MouseEvent) {
b.hovered = true
b.Refresh()
}
func (b *WRect) MouseMoved(*desktop.MouseEvent) {
}
func (b *WRect) MouseOut() {
b.hovered = false
b.Refresh()
}
func (s *WRect) MinSize() fyne.Size {
s.ExtendBaseWidget(s)
return s.BaseWidget.MinSize()
}
func (me *WRect) TappedSecondary(pe *fyne.PointEvent) {
// println(me.Index)
entryPos := fyne.CurrentApp().Driver().AbsolutePositionForObject(me)
popUpPos := entryPos.Add(fyne.NewPos(pe.Position.X, pe.Position.Y))
c := fyne.CurrentApp().Driver().CanvasForObject(me)
var popUp *widget.PopUp
btns := make([]fyne.CanvasObject, len(Ress))
for i := range Ress {
btns[i] = widget.NewButtonWithIcon("", Ress[i], func() {
// println(me.x,"-",me.y)
me.SetResource(Ress[i])
me.role = iTiles[i]
if me.UpdateState != nil {
me.UpdateState(me)
}
popUp.Hide()
popUp = nil
})
}
popUp = widget.NewPopUp(container.NewGridWithColumns(2, btns...), c)
popUp.ShowAtPosition(popUpPos)
}
func (s *WRect) SetResource(res fyne.Resource) {
s.res = res
s.Refresh()
}
var _ fyne.WidgetRenderer = (*rectRenderer)(nil)
type rectRenderer struct {
bar *canvas.Rectangle
icon *canvas.Image
d *WRect
objs []fyne.CanvasObject
}
func (r *rectRenderer) MinSize() fyne.Size {
return fyne.NewSquareSize(10)
}
func (r *rectRenderer) Refresh() {
if r.d.hovered {
r.bar.StrokeWidth = 2
} else {
r.bar.StrokeWidth = 0
}
r.icon.Resource = r.d.res
r.icon.Refresh()
canvas.Refresh(r.d)
}
func (r *rectRenderer) Objects() []fyne.CanvasObject {
return r.objs
}
func (r *rectRenderer) Layout(s fyne.Size) {
r.bar.Resize(s)
r.icon.Resize(s.SubtractWidthHeight(2, 2))
r.icon.Move(fyne.NewPos(1, 1))
}
func (r *rectRenderer) Destroy() {
}