diff --git a/bar.go b/bar.go index 81d2166..45cff64 100644 --- a/bar.go +++ b/bar.go @@ -47,7 +47,7 @@ baseF BarFiller filler BarFiller id int - width int + reqWidth int total int64 current int64 lastN int64 @@ -322,7 +322,7 @@ }() st := newStatistics(tw, s) - frame, lines := s.extender(s.draw(st), s.width, st) + frame, lines := s.extender(s.draw(st), s.reqWidth, st) b.extendedLines = lines b.toShutdown = s.toComplete && !s.completeFlushed @@ -332,7 +332,7 @@ case <-b.done: s := b.cacheState st := newStatistics(tw, s) - frame, lines := s.extender(s.draw(st), s.width, st) + frame, lines := s.extender(s.draw(st), s.reqWidth, st) b.extendedLines = lines b.frameCh <- frame } @@ -399,13 +399,13 @@ s.bufA.WriteByte('\n') - if !s.trimSpace && stat.TermWidth >= 2 { + if !s.trimSpace { defer s.bufB.WriteByte(' ') s.bufB.WriteByte(' ') stat.OccupiedWidth += 2 } - s.filler.Fill(s.bufB, s.width, stat) + s.filler.Fill(s.bufB, s.reqWidth, stat) return io.MultiReader(s.bufP, s.bufB, s.bufA) } diff --git a/bar_filler_bar.go b/bar_filler_bar.go index b473966..4b06906 100644 --- a/bar_filler_bar.go +++ b/bar_filler_bar.go @@ -85,13 +85,10 @@ s.refill = amount } -func (s *barFiller) Fill(w io.Writer, width int, stat decor.Statistics) { - // auto shrink - if stat.OccupiedWidth+width > stat.TermWidth { - width = stat.TermWidth - stat.OccupiedWidth - } - // don't count rLeft and rRight as progress - width -= 2 +func (s *barFiller) Fill(w io.Writer, reqWidth int, stat decor.Statistics) { + width := internal.CalcWidthForBarFiller(reqWidth, stat.TermWidth-stat.OccupiedWidth) + + width -= 2 // don't count rLeft and rRight as progress if width < 2 { return } diff --git a/bar_filler_spinner.go b/bar_filler_spinner.go index e90b09d..845801f 100644 --- a/bar_filler_spinner.go +++ b/bar_filler_spinner.go @@ -6,6 +6,7 @@ "unicode/utf8" "github.com/vbauerster/mpb/v5/decor" + "github.com/vbauerster/mpb/v5/internal" ) // SpinnerAlignment enum. @@ -39,11 +40,8 @@ return filler } -func (s *spinnerFiller) Fill(w io.Writer, width int, stat decor.Statistics) { - // auto shrink - if stat.OccupiedWidth+width > stat.TermWidth { - width = stat.TermWidth - stat.OccupiedWidth - } +func (s *spinnerFiller) Fill(w io.Writer, reqWidth int, stat decor.Statistics) { + width := internal.CalcWidthForBarFiller(reqWidth, stat.TermWidth-stat.OccupiedWidth) frame := s.frames[s.count%uint(len(s.frames))] frameWidth := utf8.RuneCountInString(frame) diff --git a/bar_option.go b/bar_option.go index 02589fc..9a55a8d 100644 --- a/bar_option.go +++ b/bar_option.go @@ -46,7 +46,7 @@ // BarWidth sets bar width independent of the container. func BarWidth(width int) BarOption { return func(s *bState) { - s.width = width + s.reqWidth = width } } diff --git a/bar_test.go b/bar_test.go index 21de834..e6d5dd2 100644 --- a/bar_test.go +++ b/bar_test.go @@ -144,8 +144,8 @@ func TestBarStyle(t *testing.T) { var buf bytes.Buffer customFormat := "╢▌▌░╟" - p := New(WithOutput(&buf)) total := 80 + p := New(WithOutput(&buf), WithWidth(total)) bar := p.AddBar(int64(total), BarStyle(customFormat), TrimSpace()) for i := 0; i < total; i++ { diff --git a/container_option.go b/container_option.go index 2f96bb4..fac59e4 100644 --- a/container_option.go +++ b/container_option.go @@ -21,14 +21,11 @@ } } -// WithWidth sets container width. Default is 80. Bars inherit this -// width, as long as no BarWidth is applied. +// WithWidth sets container width. If not set underlying bars will +// occupy whole term width. func WithWidth(width int) ContainerOption { return func(s *pState) { - if width < 0 { - return - } - s.width = width + s.reqWidth = width } } diff --git a/draw_test.go b/draw_test.go index de3e2a9..43f0477 100644 --- a/draw_test.go +++ b/draw_test.go @@ -3,7 +3,6 @@ import ( "bytes" "testing" - "unicode/utf8" ) func TestDraw(t *testing.T) { @@ -23,7 +22,7 @@ total: 60, current: 20, barWidth: 80, - want: "", + want: " ", }, { name: "t,c,bw{60,20,80}trim", @@ -40,7 +39,7 @@ total: 60, current: 20, barWidth: 80, - want: "", + want: " ", }, { name: "t,c,bw{60,20,80}trim", @@ -323,7 +322,7 @@ for termWidth, cases := range testSuite { for _, tc := range cases { s := newTestState(tc.reverse) - s.width = tc.barWidth + s.reqWidth = tc.barWidth s.total = tc.total s.current = tc.current s.trimSpace = tc.trimSpace @@ -337,10 +336,6 @@ by := tmpBuf.Bytes() by = by[:len(by)-1] - if utf8.RuneCount(by) > termWidth { - t.Errorf("termWidth:%d %q barWidth:%d overflow termWidth\n", termWidth, tc.name, utf8.RuneCount(by)) - } - got := string(by) if got != tc.want { t.Errorf("termWidth:%d %q want: %q %d, got: %q %d\n", termWidth, tc.name, tc.want, len(tc.want), got, len(got)) diff --git a/internal/percentage.go b/internal/percentage.go index e321e0a..d0ca0db 100644 --- a/internal/percentage.go +++ b/internal/percentage.go @@ -16,3 +16,10 @@ func PercentageRound(total, current int64, width int) float64 { return math.Round(Percentage(total, current, width)) } + +func CalcWidthForBarFiller(reqWidth, available int) int { + if reqWidth <= 0 || reqWidth >= available { + return available + } + return reqWidth +} diff --git a/progress.go b/progress.go index 70c6fb4..bd78839 100644 --- a/progress.go +++ b/progress.go @@ -19,8 +19,6 @@ const ( // default RefreshRate prr = 120 * time.Millisecond - // default width - pwidth = 80 ) // Progress represents the container that renders Progress bars @@ -46,7 +44,7 @@ // following are provided/overrided by user idCount int - width int + reqWidth int popCompleted bool rr time.Duration uwg *sync.WaitGroup @@ -70,7 +68,6 @@ func NewWithContext(ctx context.Context, options ...ContainerOption) *Progress { s := &pState{ bHeap: priorityQueue{}, - width: pwidth, rr: prr, parkedBars: make(map[*Bar]*Bar), output: os.Stdout, @@ -113,7 +110,7 @@ // Panics if *Progress instance is done, i.e. called after *Progress.Wait(). func (p *Progress) Add(total int64, filler BarFiller, options ...BarOption) *Bar { if filler == nil { - filler = NewBarFiller(DefaultBarStyle, false) + filler = BarFillerFunc(func(io.Writer, int, decor.Statistics) {}) } p.bwg.Add(1) result := make(chan *Bar) @@ -233,7 +230,7 @@ tw, err := cw.GetWidth() if err != nil { - tw = s.width + tw = s.reqWidth } for i := 0; i < s.bHeap.Len(); i++ { bar := s.bHeap[i] @@ -347,7 +344,7 @@ filler: filler, priority: s.idCount, id: s.idCount, - width: s.width, + reqWidth: s.reqWidth, debugOut: s.debugOut, extender: func(r io.Reader, _ int, _ decor.Statistics) (io.Reader, int) { return r, 0 @@ -364,9 +361,9 @@ bs.priority = -1 } - bs.bufP = bytes.NewBuffer(make([]byte, 0, bs.width)) - bs.bufB = bytes.NewBuffer(make([]byte, 0, bs.width)) - bs.bufA = bytes.NewBuffer(make([]byte, 0, bs.width)) + bs.bufP = bytes.NewBuffer(make([]byte, 0, 64)) + bs.bufB = bytes.NewBuffer(make([]byte, 0, 128)) + bs.bufA = bytes.NewBuffer(make([]byte, 0, 64)) return bs }