class TTY::ProgressBar::Multi
Used for managing multiple terminal progress bars
@api public
Constants
- DEFAULT_INSET
Attributes
Number of currently occupied rows in terminal display
Public Class Methods
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
# 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
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
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
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 all progress bars
@api public
# File lib/tty/progressbar/multi.rb, line 214 def finish @bars.each(&:finish) end
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
Increase row count
@api public
# File lib/tty/progressbar/multi.rb, line 94 def next_row synchronize do @rows += 1 end end
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
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 all progress bars
@api public
# File lib/tty/progressbar/multi.rb, line 221 def pause @bars.each(&:pause) end
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
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 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 all progress bars
@api public
# File lib/tty/progressbar/multi.rb, line 228 def resume @bars.each(&:resume) end
# File lib/tty/progressbar/multi.rb, line 132 def start raise "No top level progress bar" unless @top_bar @top_bar.start end
Stop all progress bars
@api public
# File lib/tty/progressbar/multi.rb, line 207 def stop @bars.each(&:stop) end
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
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
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
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