class TTY::ProgressBar::Multi

Used for managing multiple terminal progress bars

@api public

Constants

DEFAULT_INSET

Attributes

rows[R]

Number of currently occupied rows in terminal display

Public Class Methods

new(*args) click to toggle source

Create a multibar

@example

bars = TTY::ProgressBar::Multi.new

@example

bars = TTY::ProgressBar::Multi.new("main [:bar]")

@param [String] format

the formatting string to display this bar

@param [Hash] options

@api public

Calls superclass method
# File lib/tty/progressbar/multi.rb, line 46
def initialize(*args)
  super()
  @options = args.last.is_a?(::Hash) ? args.pop : {}
  format = args.empty? ? nil : args.pop
  @inset_opts = @options.delete(:style) { DEFAULT_INSET }
  @bars = []
  @rows = 0
  @top_bar = nil
  @top_bar = register(format, observable: false) if format

  @width = @options[:width]
  @top_bar.update(width: @width) if @top_bar && @width

  @callbacks = {
    progress: [],
    stopped: [],
    paused: [],
    done: []
  }
end

Public Instance Methods

complete?() click to toggle source

Check if all progress bars are complete

@return [Boolean]

@api public

# File lib/tty/progressbar/multi.rb, line 165
def complete?
  synchronize do
    (@bars - [@top_bar]).all?(&:complete?)
  end
end
current() click to toggle source

Calculate total current progress of all bars

@return [Integer]

@api public

# File lib/tty/progressbar/multi.rb, line 154
def current
  synchronize do
    (@bars - [@top_bar]).map(&:current).reduce(&:+)
  end
end
done?() click to toggle source

Check if all bars are stopped or finished

@return [Boolean]

@api public

# File lib/tty/progressbar/multi.rb, line 187
def done?
  synchronize do
    (@bars - [@top_bar]).all?(&:done?)
  end
end
finish() click to toggle source

Finish all progress bars

@api public

# File lib/tty/progressbar/multi.rb, line 214
def finish
  @bars.each(&:finish)
end
line_inset(bar) click to toggle source

Find the number of characters to move into the line before printing the bar

@param [TTY::ProgressBar] bar

the progress bar for which line inset is calculated

@return [String]

the inset

@api public

# File lib/tty/progressbar/multi.rb, line 242
def line_inset(bar)
  return "" if @top_bar.nil?

  case bar.row
  when @top_bar.row
    @inset_opts[:top]
  when rows
    @inset_opts[:bottom]
  else
    @inset_opts[:middle]
  end
end
next_row() click to toggle source

Increase row count

@api public

# File lib/tty/progressbar/multi.rb, line 94
def next_row
  synchronize do
    @rows += 1
  end
end
observe(bar) click to toggle source

Observe a bar for emitted events

@param [TTY::ProgressBar] bar

the bar to observe for events

@api private

# File lib/tty/progressbar/multi.rb, line 106
def observe(bar)
  bar.on(:progress, &progress_handler)
     .on(:done) { emit(:done) if complete? }
     .on(:stopped) { emit(:stopped) if stopped? }
     .on(:paused) { emit(:paused) if paused? }
end
on(name, &callback) click to toggle source

Listen on event

@param [Symbol] name

the event name to listen on

@api public

# File lib/tty/progressbar/multi.rb, line 261
def on(name, &callback)
  unless @callbacks.key?(name)
    raise ArgumentError, "The event #{name} does not exist. " \
                         "Use :progress, :stopped, :paused or " \
                         ":done instead"
  end
  @callbacks[name] << callback
  self
end
pause() click to toggle source

Pause all progress bars

@api public

# File lib/tty/progressbar/multi.rb, line 221
def pause
  @bars.each(&:pause)
end
paused?() click to toggle source

Check if all bars are paused

@return [Boolean]

@api public

# File lib/tty/progressbar/multi.rb, line 198
def paused?
  synchronize do
    (@bars - [@top_bar]).all?(&:paused?)
  end
end
progress_handler() click to toggle source

Handle the progress event

@api private

# File lib/tty/progressbar/multi.rb, line 116
def progress_handler
  ->(progress) do
    @top_bar.advance(progress) if @top_bar
    emit(:progress, progress)
  end
end
register(format, options = {}) click to toggle source

Register a new progress bar

@param [String] format

the formatting string to display the bar

@api public

# File lib/tty/progressbar/multi.rb, line 73
def register(format, options = {})
  observable = options.delete(:observable) { true }
  bar = TTY::ProgressBar.new(format, @options.merge(options))

  synchronize do
    bar.attach_to(self)
    @bars << bar
    observe(bar) if observable
    if @top_bar
      @top_bar.update(total: total)
      @top_bar.resume if @top_bar.done?
      @top_bar.update(width: total) unless @width
    end
  end

  bar
end
resume() click to toggle source

Resume all progress bars

@api public

# File lib/tty/progressbar/multi.rb, line 228
def resume
  @bars.each(&:resume)
end
start() click to toggle source
# File lib/tty/progressbar/multi.rb, line 132
def start
  raise "No top level progress bar" unless @top_bar

  @top_bar.start
end
stop() click to toggle source

Stop all progress bars

@api public

# File lib/tty/progressbar/multi.rb, line 207
def stop
  @bars.each(&:stop)
end
stopped?() click to toggle source

Check if all of the registered progress bars is stopped

@return [Boolean]

@api public

# File lib/tty/progressbar/multi.rb, line 176
def stopped?
  synchronize do
    (@bars - [@top_bar]).all?(&:stopped?)
  end
end
top_bar() click to toggle source

Get the top level bar if it exists

@api public

# File lib/tty/progressbar/multi.rb, line 126
def top_bar
  raise "No top level progress bar" unless @top_bar

  @top_bar
end
total() click to toggle source

Calculate total maximum progress of all bars

@return [Integer]

@api public

# File lib/tty/progressbar/multi.rb, line 143
def total
  synchronize do
    (@bars - [@top_bar]).map(&:total).compact.reduce(&:+)
  end
end

Private Instance Methods

emit(name, *args) click to toggle source

Fire an event by name

@api private

# File lib/tty/progressbar/multi.rb, line 276
def emit(name, *args)
  @callbacks[name].each do |callback|
    callback.(*args)
  end
end