From fcda546c9ce4e6e36b8fa2f945699de8ca3fdba4 Mon Sep 17 00:00:00 2001 From: Pranav Date: Sat, 22 Feb 2020 00:49:12 +0530 Subject: [PATCH] Update README.md --- README.md | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/README.md b/README.md index 23f5adb..ae57336 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ * [Progress Bar](#progress-bar) * [Block Progress Bar](#block-progress-bar) * [Multi Progress](#multiprogress) +* [Dynamic Progress](#dynamicprogress) * [Progress Spinner](#progress-spinner) * [Contributing](#contributing) * [License](#license) @@ -342,6 +343,156 @@ int main() { } ``` +# DynamicProgress + +`DynamicProgress` is a container class, similar to `MultiProgress`, for managing multiple progress bars. As the name suggests, with `DynamicProgress`, you can dynamically add new progress bars. Simply call `bars.push_back`. + +Below is an example `DynamicProgress` object that manages six `ProgressBar` objects. Three of these bars are added dynamically. + +

+ +

+ +```cpp +#include +#include +using namespace indicators; + +int main() { + + ProgressBar bar1{option::BarWidth{50}, option::ForegroundColor{Color::red}, + option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, + option::PrefixText{"5c90d4a2d1a8: Downloading "}}; + + ProgressBar bar2{option::BarWidth{50}, option::ForegroundColor{Color::yellow}, + option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, + option::PrefixText{"22337bfd13a9: Downloading "}}; + + ProgressBar bar3{option::BarWidth{50}, option::ForegroundColor{Color::green}, + option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, + option::PrefixText{"10f26c680a34: Downloading "}}; + + ProgressBar bar4{option::BarWidth{50}, option::ForegroundColor{Color::white}, + option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, + option::PrefixText{"6364e0d7a283: Downloading "}}; + + ProgressBar bar5{option::BarWidth{50}, option::ForegroundColor{Color::blue}, + option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, + option::PrefixText{"ff1356ba118b: Downloading "}}; + + ProgressBar bar6{option::BarWidth{50}, option::ForegroundColor{Color::cyan}, + option::ShowElapsedTime{true}, option::ShowRemainingTime{true}, + option::PrefixText{"5a17453338b4: Downloading "}}; + + std::cout << termcolor::bold << termcolor::white << "Pulling image foo:bar/baz\n"; + + DynamicProgress bars(bar1, bar2, bar3); + bars.set_option(option::HideBarWhenComplete{true}); + + std::thread fourth_job, fifth_job, sixth_job; + + auto job4 = [&bars](size_t i) { + while (true) { + bars[i].tick(); + if (bars[i].is_completed()) { + bars[i].set_option(option::PrefixText{"6364e0d7a283: Pull complete "}); + bars[i].mark_as_completed(); + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + }; + + auto job5 = [&bars](size_t i) { + while (true) { + bars[i].tick(); + if (bars[i].is_completed()) { + bars[i].set_option(option::PrefixText{"ff1356ba118b: Pull complete "}); + bars[i].mark_as_completed(); + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + }; + + auto job6 = [&bars](size_t i) { + while (true) { + bars[i].tick(); + if (bars[i].is_completed()) { + bars[i].set_option(option::PrefixText{"5a17453338b4: Pull complete "}); + bars[i].mark_as_completed(); + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(40)); + } + }; + + auto job1 = [&bars, &bar6, &sixth_job, &job6]() { + while (true) { + bars[0].tick(); + if (bars[0].is_completed()) { + bars[0].set_option(option::PrefixText{"5c90d4a2d1a8: Pull complete "}); + // bar1 is completed, adding bar6 + auto i = bars.push_back(bar6); + sixth_job = std::thread(job6, i); + sixth_job.join(); + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(140)); + } + }; + + auto job2 = [&bars, &bar5, &fifth_job, &job5]() { + while (true) { + bars[1].tick(); + if (bars[1].is_completed()) { + bars[1].set_option(option::PrefixText{"22337bfd13a9: Pull complete "}); + // bar2 is completed, adding bar5 + auto i = bars.push_back(bar5); + fifth_job = std::thread(job5, i); + fifth_job.join(); + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(25)); + } + }; + + auto job3 = [&bars, &bar4, &fourth_job, &job4]() { + while (true) { + bars[2].tick(); + if (bars[2].is_completed()) { + bars[2].set_option(option::PrefixText{"10f26c680a34: Pull complete "}); + // bar3 is completed, adding bar4 + auto i = bars.push_back(bar4); + fourth_job = std::thread(job4, i); + fourth_job.join(); + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + }; + + std::thread first_job(job1); + std::thread second_job(job2); + std::thread third_job(job3); + + third_job.join(); + second_job.join(); + first_job.join(); + + std::cout << termcolor::bold << termcolor::green << "✔ Downloaded image foo/bar:baz" << std::endl; + std::cout << termcolor::reset; + + return 0; +} +``` + +In the above code, notice the option `bars.set_option(option::HideBarWhenComplete{true});`. Yes, you can hide progress bars as and when they complete by setting this option to `true`. If you do so, the above example will look like this: + +

+ +

+ # Progress Spinner To introduce a progress spinner in your application, include `indicators/progress_spinner.hpp` and create a `ProgressSpinner` object. Here's the general structure of a progress spinner: