# This code is free software; you can redistribute it and/or modify it under # the terms of the new BSD License. # # Copyright (c) 2009-2010, Sebastian Staudt # Copyright (c) 2010, Dotan J. Nahum module Rubikon # A class for displaying and managing progress bars # # @author Sebastian Staudt # @see Application::DSLMethods#progress_bar # @since 0.2.0 class ProgressBar # Create a new ProgressBar using the given options. # # @param [Hash, Numeric] options A Hash of options to customize the # progress bar or the maximum value of the progress bar # @see Application::InstanceMethods#progress_bar # # @option options [String] :char ('#') The character used for progress bar # display # @option options [Numeric] :maximum (100) The maximum value of this # progress bar # @option options [IO] :ostream ($stdout) The output stream where the # progress bar should be displayed # @option options [Numeric] :size (20) The actual size of the progress bar # @option options [Numeric] :start (0) The start value of the progress bar def initialize(options = {}) if options.is_a? Numeric @maximum = options options = {} else @maximum = options[:maximum] || 100 end @maximum.round @progress_char = options[:char] || '#' @ostream = options[:ostream] || $stdout @progress = 0 @size = options[:size] || 20 @factor = @size.round.to_f / @maximum @value = 0 @brackets = options[:brackets] || false @bracket_filler = options[:bracket_filler] || ' ' if @brackets @ostream << '[' + @bracket_filler * @size + ']'+ "\b" * (@size + 1) @ostream.flush end self + (options[:start] || 0) end # Add an amount to the current value of the progress bar # # This triggers a refresh of the progress bar, if the added value actually # changes the displayed bar. # # @param [Numeric] value The amount to add to the progress bar # @return [ProgressBar] The progress bar itself # # @example Different alternatives to increase the progress # progress_bar + 1 # (will add 1) # progress_bar + 5 # (will add 5) # progress_bar.+ # (will add 1) def +(value = 1) return if (value <= 0) || (@value == @maximum) @value += value old_progress = @progress add_progress = ((@value - @progress / @factor) * @factor).round @progress += add_progress if @progress > @size @progress = @size add_progress = @size - old_progress end if add_progress > 0 @ostream << @progress_char * add_progress @ostream.flush @ostream.putc 10 if @progress == @size end self end end end