Codebase list golang-github-vbauerster-mpb / 53ea770
BarStyleComposer add TipOnComplete Vladimir Bauer 4 years ago
1 changed file(s) with 68 addition(s) and 79 deletion(s). Raw diff Collapse all Expand all
2525 Filler(string) BarStyleComposer
2626 Refiller(string) BarStyleComposer
2727 Padding(string) BarStyleComposer
28 Tip(...string) BarStyleComposer
29 Inclusive(tipOnCompleteIndex uint) BarStyleComposer
28 TipOnComplete(string) BarStyleComposer
29 Tip(frames ...string) BarStyleComposer
3030 Reverse() BarStyleComposer
3131 }
3232
3333 type bFiller struct {
3434 components [components]*component
3535 tip struct {
36 count uint
37 onCompleteIndex uint
38 inclusive bool
39 frames []*component
36 count uint
37 inclusive bool
38 onComplete *component
39 frames []*component
4040 }
4141 flush func(dst io.Writer, filling, padding [][]byte)
4242 }
4747 }
4848
4949 type barStyle struct {
50 lbound string
51 rbound string
52 filler string
53 refiller string
54 padding string
55 tip []string
56 tipOnCompleteIndex uint
57 tipInclusive bool
58 rev bool
50 lbound string
51 rbound string
52 filler string
53 refiller string
54 padding string
55 tipOnComplete string
56 tipFrames []string
57 rev bool
5958 }
6059
6160 // BarStyle constructs default bar style which can be altered via
6261 // BarStyleComposer interface.
6362 func BarStyle() BarStyleComposer {
6463 return &barStyle{
65 lbound: "[",
66 rbound: "]",
67 filler: "=",
68 refiller: "+",
69 padding: "-",
70 tip: []string{">"},
64 lbound: "[",
65 rbound: "]",
66 filler: "=",
67 refiller: "+",
68 padding: "-",
69 tipFrames: []string{">"},
7170 }
7271 }
7372
9695 return s
9796 }
9897
99 func (s *barStyle) Tip(tip ...string) BarStyleComposer {
100 if len(tip) != 0 {
101 s.tip = append(s.tip[:0], tip...)
102 }
103 return s
104 }
105
106 func (s *barStyle) Inclusive(tipOnCompleteIndex uint) BarStyleComposer {
107 s.tipInclusive = true
108 s.tipOnCompleteIndex = tipOnCompleteIndex
98 func (s *barStyle) TipOnComplete(tip string) BarStyleComposer {
99 s.tipOnComplete = tip
100 return s
101 }
102
103 func (s *barStyle) Tip(frames ...string) BarStyleComposer {
104 if len(frames) != 0 {
105 s.tipFrames = append(s.tipFrames[:0], frames...)
106 }
109107 return s
110108 }
111109
143141 width: runewidth.StringWidth(stripansi.Strip(s.padding)),
144142 bytes: []byte(s.padding),
145143 }
146 bf.tip.inclusive = s.tipInclusive
147 bf.tip.onCompleteIndex = s.tipOnCompleteIndex
148 bf.tip.frames = make([]*component, len(s.tip))
149 for i, t := range s.tip {
144 bf.tip.onComplete = &component{
145 width: runewidth.StringWidth(stripansi.Strip(s.tipOnComplete)),
146 bytes: []byte(s.tipOnComplete),
147 }
148 bf.tip.frames = make([]*component, len(s.tipFrames))
149 for i, t := range s.tipFrames {
150150 bf.tip.frames[i] = &component{
151151 width: runewidth.StringWidth(stripansi.Strip(t)),
152152 bytes: []byte(t),
158158 func (s *bFiller) Fill(w io.Writer, width int, stat decor.Statistics) {
159159 width = internal.CheckRequestedWidth(width, stat.AvailableWidth)
160160 brackets := s.components[iLbound].width + s.components[iRbound].width
161 if width < brackets {
162 return
163 }
164161 // don't count brackets as progress
165162 width -= brackets
163 if width < 0 {
164 return
165 }
166166
167167 w.Write(s.components[iLbound].bytes)
168168 defer w.Write(s.components[iRbound].bytes)
169169
170 if width == 0 {
171 return
172 }
173
170174 var filling [][]byte
171175 var padding [][]byte
172 var refWidth int
173 curWidth := int(internal.PercentageRound(stat.Total, stat.Current, width))
174 filled := curWidth
175
176 tip := s.tip.frames[s.tip.count%uint(len(s.tip.frames))]
177
178 if s.tip.inclusive {
179 if curWidth > 0 {
180 if stat.Current == stat.Total {
181 if s.tip.onCompleteIndex >= uint(len(s.tip.frames)) {
182 s.tip.onCompleteIndex = 0
183 }
184 tip = s.tip.frames[s.tip.onCompleteIndex]
185 }
186 filling = append(filling, tip.bytes)
187 curWidth -= tip.width
188 s.tip.count++
189 }
190 } else if curWidth < width {
176 var tip *component
177 var filled int
178 curWidth := int(internal.PercentageRound(stat.Total, stat.Current, uint(width)))
179
180 if stat.Current >= stat.Total {
181 tip = s.tip.onComplete
182 } else {
183 tip = s.tip.frames[s.tip.count%uint(len(s.tip.frames))]
184 }
185
186 if curWidth > 0 {
191187 filling = append(filling, tip.bytes)
192188 filled += tip.width
193189 s.tip.count++
194190 }
195191
196 if stat.Refill > 0 && curWidth > 0 {
197 refWidth = int(internal.PercentageRound(stat.Total, stat.Refill, width))
198 if refWidth > curWidth {
199 refWidth = curWidth
200 }
201 curWidth -= refWidth
202 }
203
204 for curWidth > 0 && curWidth >= s.components[iFiller].width {
192 for filled < curWidth && curWidth-filled >= s.components[iFiller].width {
205193 filling = append(filling, s.components[iFiller].bytes)
206 curWidth -= s.components[iFiller].width
207194 if s.components[iFiller].width == 0 {
208195 break
209196 }
210 }
211
212 for refWidth > 0 && refWidth >= s.components[iRefiller].width {
213 filling = append(filling, s.components[iRefiller].bytes)
214 refWidth -= s.components[iRefiller].width
215 if s.components[iRefiller].width == 0 {
216 break
217 }
218 }
219
220 filled -= curWidth + refWidth
197 filled += s.components[iFiller].width
198 }
199
200 if stat.Refill > 0 {
201 refWidth := int(internal.PercentageRound(stat.Total, stat.Refill, uint(width)))
202 available := curWidth
203 bound := available - refWidth
204 for i := len(filling) - 1; available > bound && i > 0; i-- {
205 filling[i] = s.components[iRefiller].bytes
206 available -= s.components[iRefiller].width
207 }
208 }
209
221210 padWidth := width - filled
222211 for padWidth > 0 && padWidth >= s.components[iPadding].width {
223212 padding = append(padding, s.components[iPadding].bytes)
224 padWidth -= s.components[iPadding].width
225213 if s.components[iPadding].width == 0 {
226214 break
227215 }
216 padWidth -= s.components[iPadding].width
228217 }
229218
230219 for padWidth > 0 {