Updates #22: add focus arrow key navigation to grid view

This commit is contained in:
Drew Weymouth
2024-02-02 08:44:52 -08:00
parent 5db80c7109
commit 7e8a4d6d37
3 changed files with 152 additions and 26 deletions
+60 -1
View File
@@ -2,6 +2,7 @@ package widgets
import (
"image"
"image/color"
"github.com/dweymouth/supersonic/res"
"github.com/dweymouth/supersonic/sharedutil"
@@ -12,10 +13,12 @@ import (
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/driver/desktop"
"fyne.io/fyne/v2/theme"
"fyne.io/fyne/v2/widget"
)
var _ fyne.Widget = (*GridViewItem)(nil)
var _ fyne.Focusable = (*GridViewItem)(nil)
var _ fyne.Widget = (*coverImage)(nil)
@@ -138,15 +141,21 @@ type GridViewItem struct {
primaryText *widget.Hyperlink
secondaryText *MultiHyperlink
container *fyne.Container
focused bool
focusRect *canvas.Rectangle
// updated by GridView
Cover *coverImage
ImgLoader util.ThumbnailLoader
ItemIndex int
OnPlay func()
OnShowContextMenu func(fyne.Position)
OnShowItemPage func()
OnShowSecondaryPage func(string)
// Invoked with arg 0-3 when left, right, up, or down neighbor should be focused, respectively
OnFocusNeighbor func(int)
}
func NewGridViewItem(placeholderResource fyne.Resource) *GridViewItem {
@@ -187,7 +196,10 @@ func NewGridViewItem(placeholderResource fyne.Resource) *GridViewItem {
func (g *GridViewItem) createContainer() {
info := container.New(&layouts.VboxCustomPadding{ExtraPad: -16}, g.primaryText, g.secondaryText)
c := container.New(&layouts.VboxCustomPadding{ExtraPad: -5}, g.Cover, info)
g.focusRect = canvas.NewRectangle(color.Transparent)
g.focusRect.StrokeWidth = 3
coverStack := container.NewStack(g.Cover, g.focusRect)
c := container.New(&layouts.VboxCustomPadding{ExtraPad: -5}, coverStack, info)
pad := &layouts.CenterPadLayout{PadLeftRight: 20, PadTopBottom: 10}
g.container = container.New(pad, c)
}
@@ -203,9 +215,15 @@ func (g *GridViewItem) Update(model GridViewItemModel) {
g.secondaryText.BuildSegments(model.Secondary, model.SecondaryIDs)
g.secondaryText.Refresh()
g.Cover.ResetPlayButton()
if g.focused {
fyne.CurrentApp().Driver().CanvasForObject(g).Focus(nil)
g.FocusLost()
}
}
func (g *GridViewItem) Refresh() {
g.focusRect.StrokeColor = util.MakeOpaque(theme.FocusColor())
g.focusRect.Hidden = !g.focused
g.BaseWidget.Refresh()
}
@@ -213,6 +231,47 @@ func (g *GridViewItem) ItemID() string {
return g.itemID
}
func (g *GridViewItem) FocusGained() {
g.focused = true
g.Refresh()
}
func (g *GridViewItem) FocusLost() {
g.focused = false
g.Refresh()
}
func (g *GridViewItem) TypedKey(e *fyne.KeyEvent) {
if !g.focused {
return
}
focusArg := -1
switch e.Name {
case fyne.KeyLeft:
focusArg = 0
case fyne.KeyRight:
focusArg = 1
case fyne.KeyUp:
focusArg = 2
case fyne.KeyDown:
focusArg = 3
case fyne.KeyEnter:
fallthrough
case fyne.KeySpace:
if g.OnShowItemPage != nil {
g.OnShowItemPage()
return
}
}
if focusArg >= 0 && g.OnFocusNeighbor != nil {
g.OnFocusNeighbor(focusArg)
}
}
func (g *GridViewItem) TypedRune(rune) {
// intentionally blank
}
func (g *GridViewItem) CreateRenderer() fyne.WidgetRenderer {
return widget.NewSimpleRenderer(g.container)
}