Skip to content

Commit

Permalink
Merge branch 'develop' into fix/iosfiles
Browse files Browse the repository at this point in the history
  • Loading branch information
andydotxyz committed Feb 16, 2024
2 parents e696513 + ca0e9e5 commit a8f4532
Show file tree
Hide file tree
Showing 33 changed files with 527 additions and 314 deletions.
7 changes: 4 additions & 3 deletions container/tabs_test.go
Expand Up @@ -3,6 +3,7 @@ package container
import (
"testing"

internalTest "fyne.io/fyne/v2/internal/test"
"github.com/stretchr/testify/assert"

"fyne.io/fyne/v2"
Expand All @@ -27,7 +28,7 @@ func TestTabButton_Icon_Change(t *testing.T) {
func TestTab_ThemeChange(t *testing.T) {
a := test.NewApp()
defer test.NewApp()
a.Settings().SetTheme(theme.LightTheme())
a.Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme()))

tabs := NewAppTabs(
NewTabItem("a", widget.NewLabel("a")),
Expand All @@ -37,12 +38,12 @@ func TestTab_ThemeChange(t *testing.T) {

initial := w.Canvas().Capture()

a.Settings().SetTheme(theme.DarkTheme())
a.Settings().SetTheme(internalTest.DarkTheme(theme.DefaultTheme()))
tabs.SelectIndex(1)
second := w.Canvas().Capture()
assert.NotEqual(t, initial, second)

a.Settings().SetTheme(theme.LightTheme())
a.Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme()))
tabs.SelectIndex(0)
assert.Equal(t, initial, w.Canvas().Capture())
}
16 changes: 10 additions & 6 deletions widget/accordion.go
Expand Up @@ -147,8 +147,10 @@ type accordionRenderer struct {
}

func (r *accordionRenderer) Layout(size fyne.Size) {
pad := theme.Padding()
dividerOff := (pad + theme.SeparatorThicknessSize()) / 2
th := r.container.Theme()
pad := th.Size(theme.SizeNamePadding)
separator := th.Size(theme.SizeNameSeparatorThickness)
dividerOff := (pad + separator) / 2
x := float32(0)
y := float32(0)
hasOpen := 0
Expand Down Expand Up @@ -178,7 +180,7 @@ func (r *accordionRenderer) Layout(size fyne.Size) {
if i > 0 {
div.Move(fyne.NewPos(x, y-dividerOff))
}
div.Resize(fyne.NewSize(size.Width, theme.SeparatorThicknessSize()))
div.Resize(fyne.NewSize(size.Width, separator))
}

h := r.headers[i]
Expand All @@ -200,7 +202,8 @@ func (r *accordionRenderer) Layout(size fyne.Size) {
}

func (r *accordionRenderer) MinSize() fyne.Size {
pad := theme.Padding()
th := r.container.Theme()
pad := th.Size(theme.SizeNamePadding)
size := fyne.Size{}

r.container.propertyLock.RLock()
Expand Down Expand Up @@ -231,6 +234,7 @@ func (r *accordionRenderer) Refresh() {
}

func (r *accordionRenderer) updateObjects() {
th := r.container.themeWithLock()
r.container.propertyLock.RLock()
defer r.container.propertyLock.RUnlock()

Expand Down Expand Up @@ -263,10 +267,10 @@ func (r *accordionRenderer) updateObjects() {
}
}
if ai.Open {
h.Icon = theme.MenuDropUpIcon()
h.Icon = th.Icon(theme.IconNameArrowDropUp)
ai.Detail.Show()
} else {
h.Icon = theme.MenuDropDownIcon()
h.Icon = th.Icon(theme.IconNameArrowDropDown)
ai.Detail.Hide()
}
h.Refresh()
Expand Down
17 changes: 10 additions & 7 deletions widget/activity.go
Expand Up @@ -35,7 +35,7 @@ func NewActivity() *Activity {
func (a *Activity) MinSize() fyne.Size {
a.ExtendBaseWidget(a)

return fyne.NewSquareSize(theme.IconInlineSize())
return fyne.NewSquareSize(a.Theme().Size(theme.SizeNameInlineIcon))
}

// Start the activity indicator animation
Expand All @@ -62,10 +62,11 @@ func (a *Activity) Stop() {

func (a *Activity) CreateRenderer() fyne.WidgetRenderer {
dots := make([]fyne.CanvasObject, 3)
v := fyne.CurrentApp().Settings().ThemeVariant()
for i := range dots {
dots[i] = canvas.NewCircle(theme.ForegroundColor())
dots[i] = canvas.NewCircle(a.Theme().Color(theme.ColorNameForeground, v))
}
r := &activityRenderer{dots: dots}
r := &activityRenderer{dots: dots, parent: a}
r.anim = &fyne.Animation{
Duration: time.Second * 2,
RepeatCount: fyne.AnimationRepeatForever,
Expand All @@ -82,8 +83,9 @@ func (a *Activity) CreateRenderer() fyne.WidgetRenderer {
var _ fyne.WidgetRenderer = (*activityRenderer)(nil)

type activityRenderer struct {
anim *fyne.Animation
dots []fyne.CanvasObject
anim *fyne.Animation
dots []fyne.CanvasObject
parent *Activity

bound fyne.Size
maxCol color.NRGBA
Expand All @@ -100,7 +102,7 @@ func (a *activityRenderer) Layout(size fyne.Size) {
}

func (a *activityRenderer) MinSize() fyne.Size {
return fyne.NewSquareSize(theme.IconInlineSize())
return fyne.NewSquareSize(a.parent.Theme().Size(theme.SizeNameInlineIcon))
}

func (a *activityRenderer) Objects() []fyne.CanvasObject {
Expand Down Expand Up @@ -159,6 +161,7 @@ func (a *activityRenderer) stop() {
}

func (a *activityRenderer) updateColor() {
rr, gg, bb, aa := theme.ForegroundColor().RGBA()
v := fyne.CurrentApp().Settings().ThemeVariant()
rr, gg, bb, aa := a.parent.Theme().Color(theme.ColorNameForeground, v).RGBA()
a.maxCol = color.NRGBA{R: uint8(rr >> 8), G: uint8(gg >> 8), B: uint8(bb >> 8), A: uint8(aa >> 8)}
}
8 changes: 4 additions & 4 deletions widget/button.go
Expand Up @@ -221,7 +221,7 @@ func (b *Button) applyButtonTheme(th fyne.Theme) {
}

func (b *Button) buttonColor() color.Color {
th := b.Theme()
th := b.themeWithLock()
v := fyne.CurrentApp().Settings().ThemeVariant()

switch {
Expand Down Expand Up @@ -368,11 +368,11 @@ func (r *buttonRenderer) Refresh() {
r.label.inset = fyne.NewSquareSize(th.Size(theme.SizeNameInnerPadding))

r.button.propertyLock.RLock()
defer r.button.propertyLock.RUnlock()

r.label.Segments[0].(*TextSegment).Text = r.button.Text
r.updateIconAndText()
r.applyTheme()
r.button.propertyLock.RUnlock()

r.background.Refresh()
r.Layout(r.button.Size())
canvas.Refresh(r.button.super())
Expand All @@ -381,7 +381,7 @@ func (r *buttonRenderer) Refresh() {
// applyTheme updates this button to match the current theme
// must be called with the button propertyLock held
func (r *buttonRenderer) applyTheme() {
r.button.applyButtonTheme(r.button.Theme())
r.button.applyButtonTheme(r.button.themeWithLock())
r.label.Segments[0].(*TextSegment).Style.ColorName = theme.ColorNameForeground
switch {
case r.button.disabled.Load():
Expand Down
19 changes: 12 additions & 7 deletions widget/card.go
Expand Up @@ -34,8 +34,10 @@ func NewCard(title, subtitle string, content fyne.CanvasObject) *Card {
// CreateRenderer is a private method to Fyne which links this widget to its renderer
func (c *Card) CreateRenderer() fyne.WidgetRenderer {
c.ExtendBaseWidget(c)
th := c.Theme()
v := fyne.CurrentApp().Settings().ThemeVariant()

header := canvas.NewText(c.Title, theme.ForegroundColor())
header := canvas.NewText(c.Title, th.Color(theme.ColorNameForeground, v))
header.TextStyle.Bold = true
subHeader := canvas.NewText(c.Subtitle, header.Color)

Expand Down Expand Up @@ -100,7 +102,7 @@ const (

// Layout the components of the card container.
func (c *cardRenderer) Layout(size fyne.Size) {
padding := theme.Padding()
padding := c.card.Theme().Size(theme.SizeNamePadding)
pos := fyne.NewSquareOffsetPos(padding / 2)
size = size.Subtract(fyne.NewSquareSize(padding))
c.LayoutShadow(size, pos)
Expand Down Expand Up @@ -157,7 +159,7 @@ func (c *cardRenderer) MinSize() fyne.Size {
hasImage := c.card.Image != nil
hasContent := c.card.Content != nil

padding := theme.Padding()
padding := c.card.Theme().Size(theme.SizeNamePadding)
if !hasHeader && !hasSubHeader && !hasContent { // just image, or nothing
if c.card.Image == nil {
return fyne.NewSize(padding, padding) // empty, just space for border
Expand Down Expand Up @@ -220,13 +222,16 @@ func (c *cardRenderer) Refresh() {

// applyTheme updates this button to match the current theme
func (c *cardRenderer) applyTheme() {
th := c.card.Theme()
v := fyne.CurrentApp().Settings().ThemeVariant()

if c.header != nil {
c.header.TextSize = theme.TextHeadingSize()
c.header.Color = theme.ForegroundColor()
c.header.TextSize = th.Size(theme.SizeNameHeadingText)
c.header.Color = th.Color(theme.ColorNameForeground, v)
}
if c.subHeader != nil {
c.subHeader.TextSize = theme.TextSize()
c.subHeader.Color = theme.ForegroundColor()
c.subHeader.TextSize = th.Size(theme.SizeNameText)
c.subHeader.Color = th.Color(theme.ColorNameForeground, v)
}
if c.card.Content != nil {
c.card.Content.Refresh()
Expand Down
64 changes: 37 additions & 27 deletions widget/check.go
Expand Up @@ -157,16 +157,19 @@ func (c *Check) MinSize() fyne.Size {

// CreateRenderer is a private method to Fyne which links this widget to its renderer
func (c *Check) CreateRenderer() fyne.WidgetRenderer {
th := c.Theme()
v := fyne.CurrentApp().Settings().ThemeVariant()

c.ExtendBaseWidget(c)
bg := canvas.NewImageFromResource(theme.CheckButtonFillIcon())
icon := canvas.NewImageFromResource(theme.CheckButtonIcon())
bg := canvas.NewImageFromResource(th.Icon(theme.IconNameCheckButtonFill))
icon := canvas.NewImageFromResource(th.Icon(theme.IconNameCheckButton))

c.propertyLock.RLock()
defer c.propertyLock.RUnlock()
text := canvas.NewText(c.Text, theme.ForegroundColor())
text := canvas.NewText(c.Text, th.Color(theme.ColorNameForeground, v))
text.Alignment = fyne.TextAlignLeading

focusIndicator := canvas.NewCircle(theme.BackgroundColor())
focusIndicator := canvas.NewCircle(th.Color(theme.ColorNameBackground, v))
r := &checkRenderer{
widget.NewBaseRenderer([]fyne.CanvasObject{focusIndicator, bg, icon, text}),
bg,
Expand All @@ -175,10 +178,10 @@ func (c *Check) CreateRenderer() fyne.WidgetRenderer {
focusIndicator,
c,
}
r.applyTheme()
r.applyTheme(th, v)
r.updateLabel()
r.updateResource()
r.updateFocusIndicator()
r.updateResource(th)
r.updateFocusIndicator(th, v)
return r
}

Expand Down Expand Up @@ -278,23 +281,27 @@ type checkRenderer struct {
// MinSize calculates the minimum size of a check.
// This is based on the contained text, the check icon and a standard amount of padding added.
func (c *checkRenderer) MinSize() fyne.Size {
pad4 := theme.InnerPadding() * 2
min := c.label.MinSize().Add(fyne.NewSize(theme.IconInlineSize()+pad4, pad4))
th := c.check.Theme()

pad4 := th.Size(theme.SizeNameInnerPadding) * 2
min := c.label.MinSize().Add(fyne.NewSize(th.Size(theme.SizeNameInlineIcon)+pad4, pad4))

c.check.propertyLock.RLock()
text := c.check.Text
c.check.propertyLock.RUnlock()
if text != "" {
min.Add(fyne.NewSize(theme.Padding(), 0))
min.Add(fyne.NewSize(th.Size(theme.SizeNamePadding), 0))
}

return min
}

// Layout the components of the check widget
func (c *checkRenderer) Layout(size fyne.Size) {
innerPadding := theme.InnerPadding()
borderSize := theme.InputBorderSize()
iconInlineSize := theme.IconInlineSize()
th := c.check.Theme()
innerPadding := th.Size(theme.SizeNameInnerPadding)
borderSize := th.Size(theme.SizeNameInputBorder)
iconInlineSize := th.Size(theme.SizeNameInlineIcon)

focusIndicatorSize := fyne.NewSquareSize(iconInlineSize + innerPadding)
c.focusIndicator.Resize(focusIndicatorSize)
Expand All @@ -314,20 +321,23 @@ func (c *checkRenderer) Layout(size fyne.Size) {
}

// applyTheme updates this Check to the current theme
func (c *checkRenderer) applyTheme() {
c.label.Color = theme.ForegroundColor()
c.label.TextSize = theme.TextSize()
func (c *checkRenderer) applyTheme(th fyne.Theme, v fyne.ThemeVariant) {
c.label.Color = th.Color(theme.ColorNameForeground, v)
c.label.TextSize = th.Size(theme.SizeNameText)
if c.check.disabled.Load() {
c.label.Color = theme.DisabledColor()
c.label.Color = th.Color(theme.ColorNameDisabled, v)
}
}

func (c *checkRenderer) Refresh() {
th := c.check.Theme()
v := fyne.CurrentApp().Settings().ThemeVariant()

c.check.propertyLock.RLock()
c.applyTheme()
c.applyTheme(th, v)
c.updateLabel()
c.updateResource()
c.updateFocusIndicator()
c.updateResource(th)
c.updateFocusIndicator(th, v)
c.check.propertyLock.RUnlock()
canvas.Refresh(c.check.super())
}
Expand All @@ -338,14 +348,14 @@ func (c *checkRenderer) updateLabel() {
}

// must be called while holding c.check.propertyLock for reading
func (c *checkRenderer) updateResource() {
res := theme.NewThemedResource(theme.CheckButtonIcon())
func (c *checkRenderer) updateResource(th fyne.Theme) {
res := theme.NewThemedResource(th.Icon(theme.IconNameCheckButton))
res.ColorName = theme.ColorNameInputBorder
bgRes := theme.NewThemedResource(theme.CheckButtonFillIcon())
bgRes := theme.NewThemedResource(th.Icon(theme.IconNameCheckButtonFill))
bgRes.ColorName = theme.ColorNameInputBackground

if c.check.Checked {
res = theme.NewThemedResource(theme.CheckButtonCheckedIcon())
res = theme.NewThemedResource(th.Icon(theme.IconNameCheckButtonChecked))
res.ColorName = theme.ColorNamePrimary
bgRes.ColorName = theme.ColorNameBackground
}
Expand All @@ -361,13 +371,13 @@ func (c *checkRenderer) updateResource() {
}

// must be called while holding c.check.propertyLock for reading
func (c *checkRenderer) updateFocusIndicator() {
func (c *checkRenderer) updateFocusIndicator(th fyne.Theme, v fyne.ThemeVariant) {
if c.check.disabled.Load() {
c.focusIndicator.FillColor = color.Transparent
} else if c.check.focused {
c.focusIndicator.FillColor = theme.FocusColor()
c.focusIndicator.FillColor = th.Color(theme.ColorNameFocus, v)
} else if c.check.hovered {
c.focusIndicator.FillColor = theme.HoverColor()
c.focusIndicator.FillColor = th.Color(theme.ColorNameHover, v)
} else {
c.focusIndicator.FillColor = color.Transparent
}
Expand Down
4 changes: 3 additions & 1 deletion widget/check_internal_test.go
Expand Up @@ -273,12 +273,14 @@ func TestCheck_Disabled(t *testing.T) {

func TestCheckRenderer_ApplyTheme(t *testing.T) {
check := &Check{}
v := fyne.CurrentApp().Settings().ThemeVariant()
render := test.WidgetRenderer(check).(*checkRenderer)

textSize := render.label.TextSize
customTextSize := textSize
test.WithTestTheme(t, func() {
render.applyTheme()
th := test.NewTheme()
render.applyTheme(th, v)
customTextSize = render.label.TextSize
})

Expand Down

0 comments on commit a8f4532

Please sign in to comment.