• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

fyne-io / fyne / 27502714592

14 Jun 2026 07:16AM UTC coverage: 60.153% (-0.03%) from 60.178%
27502714592

Pull #6361

github

toaster
[.github/workflows] remove linters which are already part of golangci-lint
Pull Request #6361: use golangci-lint to run multiple linters

84 of 143 new or added lines in 38 files covered. (58.74%)

3 existing lines in 2 files now uncovered.

26803 of 44558 relevant lines covered (60.15%)

674.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.27
/widget/progressbarinfinite.go
1
package widget
2

3
import (
4
        "time"
5

6
        "fyne.io/fyne/v2"
7
        "fyne.io/fyne/v2/canvas"
8
        "fyne.io/fyne/v2/internal/widget"
9
        "fyne.io/fyne/v2/theme"
10
)
11

12
const (
13
        infiniteRefreshRate              = 50 * time.Millisecond
14
        maxProgressBarInfiniteWidthRatio = 1.0 / 5
15
        minProgressBarInfiniteWidthRatio = 1.0 / 20
16
        progressBarInfiniteStepSizeRatio = 1.0 / 50
17
)
18

19
type infProgressRenderer struct {
20
        widget.BaseRenderer
21
        background, bar canvas.Rectangle
22
        animation       fyne.Animation
23
        wasRunning      bool
24
        progress        *ProgressBarInfinite
25
}
26

27
// MinSize calculates the minimum size of a progress bar.
28
func (p *infProgressRenderer) MinSize() fyne.Size {
3✔
29
        th := p.progress.Theme()
3✔
30
        innerPad2 := th.Size(theme.SizeNameInnerPadding) * 2
3✔
31
        // this is to create the same size infinite progress bar as regular progress bar
3✔
32
        text := fyne.MeasureText("100%", th.Size(theme.SizeNameText), fyne.TextStyle{})
3✔
33

3✔
34
        return fyne.NewSize(text.Width+innerPad2, text.Height+innerPad2)
3✔
35
}
3✔
36

37
func (p *infProgressRenderer) updateBar(done float32) {
7✔
38
        size := p.progress.Size()
7✔
39
        progressWidth := size.Width
7✔
40
        spanWidth := progressWidth + (progressWidth * (maxProgressBarInfiniteWidthRatio / 2))
7✔
41
        maxBarWidth := progressWidth * maxProgressBarInfiniteWidthRatio
7✔
42

7✔
43
        barCenterX := spanWidth*done - (spanWidth-progressWidth)/2
7✔
44
        barPos := fyne.NewPos(barCenterX-maxBarWidth/2, 0)
7✔
45
        barSize := fyne.NewSize(maxBarWidth, size.Height)
7✔
46
        if barPos.X < 0 {
8✔
47
                barSize.Width += barPos.X
1✔
48
                barPos.X = 0
1✔
49
        }
1✔
50
        if barPos.X+barSize.Width > progressWidth {
9✔
51
                barSize.Width = progressWidth - barPos.X
2✔
52
        }
2✔
53

54
        p.bar.Resize(barSize)
7✔
55
        p.bar.Move(barPos)
7✔
56
        canvas.Refresh(&p.bar)
7✔
57
}
58

59
// Layout the components of the infinite progress bar
60
func (p *infProgressRenderer) Layout(size fyne.Size) {
4✔
61
        p.background.Resize(size)
4✔
62
}
4✔
63

64
// Refresh updates the size and position of the horizontal scrolling infinite progress bar
65
func (p *infProgressRenderer) Refresh() {
1✔
66
        running := p.progress.Running()
1✔
67
        if running {
2✔
68
                if !p.wasRunning {
1✔
69
                        p.start()
×
70
                }
×
71
                return // we refresh from the goroutine
1✔
72
        } else if p.wasRunning {
×
73
                p.stop()
×
74
                return
×
75
        }
×
76

77
        th := p.progress.Theme()
×
78
        v := fyne.CurrentApp().Settings().ThemeVariant()
×
79
        cornerRadius := th.Size(theme.SizeNameInputRadius)
×
80
        primaryColor := th.Color(theme.ColorNamePrimary, v)
×
81

×
82
        p.background.FillColor = progressBlendColor(primaryColor)
×
83
        p.background.CornerRadius = cornerRadius
×
84
        p.bar.FillColor = primaryColor
×
85
        p.bar.CornerRadius = cornerRadius
×
86
        p.background.Refresh()
×
87
        p.bar.Refresh()
×
88
        canvas.Refresh(p.progress.super())
×
89
}
90

91
// Start the infinite progress bar background thread to update it continuously
92
func (p *infProgressRenderer) start() {
4✔
93
        p.animation.Duration = time.Second * 3
4✔
94
        p.animation.Tick = p.updateBar
4✔
95
        p.animation.Curve = fyne.AnimationLinear
4✔
96
        p.animation.RepeatCount = fyne.AnimationRepeatForever
4✔
97
        p.animation.AutoReverse = true
4✔
98

4✔
99
        p.wasRunning = true
4✔
100
        p.animation.Start()
4✔
101
}
4✔
102

103
// Stop the background thread from updating the infinite progress bar
104
func (p *infProgressRenderer) stop() {
2✔
105
        p.wasRunning = false
2✔
106
        p.animation.Stop()
2✔
107
}
2✔
108

109
func (p *infProgressRenderer) Destroy() {
2✔
110
        p.progress.running = false
2✔
111

2✔
112
        p.stop()
2✔
113
}
2✔
114

115
// ProgressBarInfinite widget creates a horizontal panel that indicates waiting indefinitely
116
// An infinite progress bar loops 0% -> 100% repeatedly until Stop() is called
117
type ProgressBarInfinite struct {
118
        BaseWidget
119
        running bool
120
}
121

122
// Show this widget, if it was previously hidden
123
func (p *ProgressBarInfinite) Show() {
1✔
124
        p.running = true
1✔
125

1✔
126
        p.BaseWidget.Show()
1✔
127
}
1✔
128

129
// Hide this widget, if it was previously visible
130
func (p *ProgressBarInfinite) Hide() {
3✔
131
        p.running = false
3✔
132

3✔
133
        p.BaseWidget.Hide()
3✔
134
}
3✔
135

136
// Start the infinite progress bar animation
137
func (p *ProgressBarInfinite) Start() {
×
138
        if p.running {
×
139
                return
×
140
        }
×
141

142
        p.running = true
×
NEW
143
        p.Refresh()
×
144
}
145

146
// Stop the infinite progress bar animation
147
func (p *ProgressBarInfinite) Stop() {
×
148
        if !p.running {
×
149
                return
×
150
        }
×
151

152
        p.running = false
×
NEW
153
        p.Refresh()
×
154
}
155

156
// Running returns the current state of the infinite progress animation
157
func (p *ProgressBarInfinite) Running() bool {
9✔
158
        return p.running
9✔
159
}
9✔
160

161
// MinSize returns the size that this widget should not shrink below
162
func (p *ProgressBarInfinite) MinSize() fyne.Size {
3✔
163
        p.ExtendBaseWidget(p)
3✔
164
        return p.BaseWidget.MinSize()
3✔
165
}
3✔
166

167
// CreateRenderer is a private method to Fyne which links this widget to its renderer
168
func (p *ProgressBarInfinite) CreateRenderer() fyne.WidgetRenderer {
4✔
169
        p.ExtendBaseWidget(p)
4✔
170
        th := p.Theme()
4✔
171
        v := fyne.CurrentApp().Settings().ThemeVariant()
4✔
172

4✔
173
        primaryColor := th.Color(theme.ColorNamePrimary, v)
4✔
174
        cornerRadius := th.Size(theme.SizeNameInputRadius)
4✔
175

4✔
176
        render := &infProgressRenderer{
4✔
177
                background: canvas.Rectangle{
4✔
178
                        FillColor:    progressBlendColor(primaryColor),
4✔
179
                        CornerRadius: cornerRadius,
4✔
180
                },
4✔
181
                bar: canvas.Rectangle{
4✔
182
                        FillColor:    primaryColor,
4✔
183
                        CornerRadius: cornerRadius,
4✔
184
                },
4✔
185
                progress: p,
4✔
186
        }
4✔
187

4✔
188
        render.SetObjects([]fyne.CanvasObject{&render.background, &render.bar})
4✔
189

4✔
190
        p.running = true
4✔
191
        render.start()
4✔
192
        return render
4✔
193
}
4✔
194

195
// NewProgressBarInfinite creates a new progress bar widget that loops indefinitely from 0% -> 100%
196
// SetValue() is not defined for infinite progress bar
197
// To stop the looping progress and set the progress bar to 100%, call ProgressBarInfinite.Stop()
198
func NewProgressBarInfinite() *ProgressBarInfinite {
4✔
199
        bar := &ProgressBarInfinite{}
4✔
200
        bar.ExtendBaseWidget(bar)
4✔
201
        return bar
4✔
202
}
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc