Fix #261: Show next-up sort icon when hovering over sortable list header
This commit is contained in:
@@ -1,17 +1,22 @@
|
||||
package theme
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/canvas"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
)
|
||||
|
||||
const translucentAlpha = 155
|
||||
|
||||
type ThemedRectangle struct {
|
||||
widget.BaseWidget
|
||||
|
||||
rect *canvas.Rectangle
|
||||
|
||||
ColorName fyne.ThemeColorName
|
||||
Translucent bool
|
||||
BorderWidth float32
|
||||
BorderColorName fyne.ThemeColorName
|
||||
}
|
||||
@@ -29,7 +34,12 @@ func NewThemedRectangle(colorName fyne.ThemeColorName) *ThemedRectangle {
|
||||
func (t *ThemedRectangle) Refresh() {
|
||||
settings := fyne.CurrentApp().Settings()
|
||||
theme := settings.Theme()
|
||||
t.rect.FillColor = theme.Color(t.ColorName, settings.ThemeVariant())
|
||||
fc := theme.Color(t.ColorName, settings.ThemeVariant())
|
||||
if t.Translucent {
|
||||
r, g, b, _ := fc.RGBA()
|
||||
fc = color.NRGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: translucentAlpha}
|
||||
}
|
||||
t.rect.FillColor = fc
|
||||
t.rect.StrokeWidth = t.BorderWidth
|
||||
t.rect.StrokeColor = theme.Color(t.BorderColorName, settings.ThemeVariant())
|
||||
t.BaseWidget.Refresh()
|
||||
|
||||
+55
-21
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/driver/desktop"
|
||||
"fyne.io/fyne/v2/layout"
|
||||
"fyne.io/fyne/v2/theme"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
@@ -101,6 +102,7 @@ func (l *ListHeader) SetSorting(sort ListHeaderSort) {
|
||||
}
|
||||
l.sort = sort
|
||||
for i, c := range l.columnsContainer.Objects {
|
||||
c.(*colHeader).hovered = false // reset hovered status
|
||||
if i == sort.ColNumber {
|
||||
c.(*colHeader).Sort = sort.Type
|
||||
} else {
|
||||
@@ -166,9 +168,10 @@ type colHeader struct {
|
||||
|
||||
sortDisabled *bool
|
||||
columnCfg ListColumn
|
||||
hovered bool
|
||||
|
||||
label *widget.RichText
|
||||
sortIcon *widget.Icon
|
||||
sortIconContainer *fyne.Container
|
||||
sortIconNegSpacer fyne.CanvasObject
|
||||
container *fyne.Container
|
||||
}
|
||||
@@ -182,7 +185,9 @@ func newColHeader(columnCfg ListColumn, sortDisabled *bool) *colHeader {
|
||||
TextStyle: fyne.TextStyle{Bold: true},
|
||||
Alignment: columnCfg.Alignment,
|
||||
}
|
||||
c.sortIcon = widget.NewIcon(theme.MenuDropDownIcon())
|
||||
r := myTheme.NewThemedRectangle(myTheme.ColorNameListHeader)
|
||||
r.Translucent = true
|
||||
c.sortIconContainer = container.NewMax(widget.NewIcon(theme.MenuDropDownIcon()), r)
|
||||
// hack to remove extra icon space
|
||||
// should be hidden whenever sortIcon is hidden
|
||||
c.sortIconNegSpacer = util.NewHSpace(0)
|
||||
@@ -190,20 +195,30 @@ func newColHeader(columnCfg ListColumn, sortDisabled *bool) *colHeader {
|
||||
return c
|
||||
}
|
||||
|
||||
var _ desktop.Hoverable = (*colHeader)(nil)
|
||||
|
||||
func (c *colHeader) MouseIn(*desktop.MouseEvent) {
|
||||
if !*c.sortDisabled {
|
||||
c.hovered = true
|
||||
c.Refresh()
|
||||
}
|
||||
}
|
||||
|
||||
func (c *colHeader) MouseOut() {
|
||||
c.hovered = false
|
||||
c.Refresh()
|
||||
}
|
||||
|
||||
func (c *colHeader) MouseMoved(*desktop.MouseEvent) {
|
||||
// intentionally left blank
|
||||
}
|
||||
|
||||
func (c *colHeader) Tapped(*fyne.PointEvent) {
|
||||
if *c.sortDisabled {
|
||||
return
|
||||
}
|
||||
switch c.Sort {
|
||||
case SortNone:
|
||||
c.Sort = SortAscending
|
||||
case SortAscending:
|
||||
c.Sort = SortDescending
|
||||
case SortDescending:
|
||||
c.Sort = SortNone
|
||||
default:
|
||||
log.Println("notReached colHeader.Tapped")
|
||||
}
|
||||
c.hovered = false // stop showing the next-up sort icon
|
||||
c.Sort = nextSortType(c.Sort)
|
||||
c.Refresh()
|
||||
if c.OnSortChanged != nil {
|
||||
c.OnSortChanged(c.Sort)
|
||||
@@ -217,17 +232,22 @@ func (c *colHeader) TappedSecondary(e *fyne.PointEvent) {
|
||||
}
|
||||
|
||||
func (c *colHeader) Refresh() {
|
||||
if c.Sort == SortDescending {
|
||||
c.sortIcon.Resource = theme.MenuDropDownIcon()
|
||||
} else {
|
||||
c.sortIcon.Resource = theme.MenuDropUpIcon()
|
||||
sort := c.Sort
|
||||
if c.hovered {
|
||||
sort = nextSortType(sort)
|
||||
}
|
||||
if sort == SortDescending {
|
||||
c.sortIconContainer.Objects[0].(*widget.Icon).Resource = theme.MenuDropDownIcon()
|
||||
} else {
|
||||
c.sortIconContainer.Objects[0].(*widget.Icon).Resource = theme.MenuDropUpIcon()
|
||||
}
|
||||
c.sortIconContainer.Objects[1].(*myTheme.ThemedRectangle).Hidden = !c.hovered
|
||||
|
||||
if c.Sort > 0 && c.sortIcon.Hidden {
|
||||
c.sortIcon.Show()
|
||||
if sort > 0 && c.sortIconContainer.Hidden {
|
||||
c.sortIconContainer.Hidden = false
|
||||
c.container.Add(c.sortIconNegSpacer)
|
||||
} else if (c.Sort == SortNone || *c.sortDisabled) && !c.sortIcon.Hidden {
|
||||
c.sortIcon.Hide()
|
||||
} else if (sort == SortNone || *c.sortDisabled) && !c.sortIconContainer.Hidden {
|
||||
c.sortIconContainer.Hidden = true
|
||||
c.container.Remove(c.sortIconNegSpacer)
|
||||
}
|
||||
|
||||
@@ -241,7 +261,7 @@ func (c *colHeader) CreateRenderer() fyne.WidgetRenderer {
|
||||
c.container.Add(layout.NewSpacer())
|
||||
}
|
||||
c.container.Add(c.label)
|
||||
c.container.Add(c.sortIcon)
|
||||
c.container.Add(c.sortIconContainer)
|
||||
c.container.Add(c.sortIconNegSpacer)
|
||||
if c.columnCfg.Alignment == fyne.TextAlignCenter {
|
||||
c.container.Add(layout.NewSpacer())
|
||||
@@ -249,3 +269,17 @@ func (c *colHeader) CreateRenderer() fyne.WidgetRenderer {
|
||||
}
|
||||
return widget.NewSimpleRenderer(c.container)
|
||||
}
|
||||
|
||||
func nextSortType(in SortType) SortType {
|
||||
switch in {
|
||||
case SortNone:
|
||||
return SortAscending
|
||||
case SortAscending:
|
||||
return SortDescending
|
||||
case SortDescending:
|
||||
return SortNone
|
||||
default:
|
||||
log.Println("Unreachable")
|
||||
return SortNone
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user