diff --git a/include/progress/bar.hpp b/include/progress/bar.hpp index cae2b9a..71aedd9 100644 --- a/include/progress/bar.hpp +++ b/include/progress/bar.hpp @@ -15,54 +15,70 @@ class ProgressBar { std::string _remainder{"-"}; std::string _end{" ]"}; std::mutex _mutex; + bool _completed; - void hide_cursor() { - std::cout << "\e[?25l"; - } - - void show_cursor() { - std::cout << "\e[?25h"; - } - -public: - - ProgressBar& start_with(const std::string& start) { - _start = start; - return *this; - } - - ProgressBar& fill_with(const std::string& fill) { - _fill = fill; - return *this; - } - - ProgressBar& lead_with(const std::string& lead) { - _lead = lead; - return *this; - } - - ProgressBar& remainder_with(const std::string& remainder) { - _remainder = remainder; - return *this; - } - - ProgressBar& end_with(const std::string& end) { - _end = end; - return *this; - } - - void increment(float value) { + void _print_progress() { std::unique_lock lock{_mutex}; - _progress = value / 100.0; std::cout << _start; - float pos = _progress * static_cast(_bar_width); + float pos = _progress * static_cast(_bar_width) / 100.0; for (size_t i = 0; i < _bar_width; ++i) { if (i < pos) std::cout << _fill; else if (i == pos) std::cout << _lead; else std::cout << _remainder; } - std::cout << _end << " " << static_cast(value) << "%"; + std::cout << _end << " " << static_cast(_progress) << "%"; std::cout << " " << _name << "\r"; std::cout.flush(); } + +public: + + void bar_width(size_t bar_width) { + std::unique_lock lock{_mutex}; + _bar_width = bar_width; + } + + void start_with(const std::string& start) { + std::unique_lock lock{_mutex}; + _start = start; + } + + void fill_progress_with(const std::string& fill) { + std::unique_lock lock{_mutex}; + _fill = fill; + } + + void lead_progress_with(const std::string& lead) { + std::unique_lock lock{_mutex}; + _lead = lead; + } + + void fill_remainder_with(const std::string& remainder) { + std::unique_lock lock{_mutex}; + _remainder = remainder; + } + + void end_with(const std::string& end) { + std::unique_lock lock{_mutex}; + _end = end; + } + + void set_progress(float value) { + std::unique_lock lock{_mutex}; + if (_completed) return; + _progress = value; + if (static_cast(_progress) == 100) { + _completed = true; + } + _print_progress(); + if (_completed) + std::cout << std::endl; + } + + void tick() { + std::unique_lock lock{_mutex}; + if (_completed) return; + set_progress(_progress + 1); + } + }; diff --git a/test/bar b/test/bar new file mode 100755 index 0000000..88136ea Binary files /dev/null and b/test/bar differ diff --git a/test/bar.cpp b/test/bar.cpp new file mode 100644 index 0000000..193c2cf --- /dev/null +++ b/test/bar.cpp @@ -0,0 +1,27 @@ +#include +#include + +int main() { + ProgressBar bar; + + // Configure progress bar + bar.bar_width(100); + bar.start_with("["); + bar.fill_progress_with("="); + bar.lead_progress_with(">"); + bar.fill_remainder_with(" "); + bar.end_with("]"); + + // As configured, the bar will look like this: + // + // [=================> ] 70% + // + // + + for (size_t i = 0; i < 101; i += 5) { + bar.set_progress(i); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + + return 0; +}