Merge pull request #59 from p-ranav/feature/countdown_progress_bar

Feature/countdown progress bar
This commit is contained in:
Pranav
2020-05-24 22:56:04 -05:00
committed by GitHub
7 changed files with 125 additions and 23 deletions

View File

@@ -53,7 +53,7 @@ int main() {
// PROGRESS BAR 2 // PROGRESS BAR 2
// //
indicators::ProgressBar p; indicators::ProgressBar p;
p.set_option(option::BarWidth{40}); p.set_option(option::BarWidth{0});
p.set_option(option::PrefixText{"Reading package list... "}); p.set_option(option::PrefixText{"Reading package list... "});
p.set_option(option::Start{""}); p.set_option(option::Start{""});
p.set_option(option::Fill{""}); p.set_option(option::Fill{""});
@@ -141,6 +141,7 @@ int main() {
std::cout << std::endl; std::cout << std::endl;
p4.set_option(option::ForegroundColor{indicators::Color::red}); p4.set_option(option::ForegroundColor{indicators::Color::red});
p4.set_option(option::PrefixText{"{ ERROR }"}); p4.set_option(option::PrefixText{"{ ERROR }"});
p4.set_option(option::BarWidth{0});
p4.set_option(option::Start{}); p4.set_option(option::Start{});
p4.set_option(option::Fill{}); p4.set_option(option::Fill{});
p4.set_option(option::Lead{}); p4.set_option(option::Lead{});
@@ -158,6 +159,35 @@ int main() {
thread4.join(); thread4.join();
std::this_thread::sleep_for(std::chrono::milliseconds(100)); std::this_thread::sleep_for(std::chrono::milliseconds(100));
{
//
// GOING BACKWARDS
//
indicators::ProgressBar p{option::BarWidth{50},
option::ProgressType{ProgressType::decremental},
option::Start{"["},
option::Fill{""},
option::Lead{""},
option::Remainder{"-"},
option::End{"]"},
option::ForegroundColor{indicators::Color::white},
option::PostfixText{"Reverting system restore"},
option::FontStyles{
std::vector<indicators::FontStyle>{indicators::FontStyle::bold}}};
auto job = [&p]() {
while (true) {
p.tick();
if (p.is_completed()) {
p.set_option(option::PostfixText{"Revert complete!"});
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(60));
}
};
std::thread thread(job);
thread.join();
}
} }
{ {

View File

@@ -24,7 +24,10 @@ class ProgressBar {
option::End, option::Fill, option::Lead, option::Remainder, option::End, option::Fill, option::Lead, option::Remainder,
option::MaxPostfixTextLen, option::Completed, option::ShowPercentage, option::MaxPostfixTextLen, option::Completed, option::ShowPercentage,
option::ShowElapsedTime, option::ShowRemainingTime, option::SavedStartTime, option::ShowElapsedTime, option::ShowRemainingTime, option::SavedStartTime,
option::ForegroundColor, option::FontStyles, option::MaxProgress, option::Stream>; option::ForegroundColor, option::FontStyles,
option::MinProgress, option::MaxProgress,
option::ProgressType,
option::Stream>;
public: public:
template <typename... Args, template <typename... Args,
@@ -64,10 +67,23 @@ public:
option::ForegroundColor{Color::unspecified}, std::forward<Args>(args)...), option::ForegroundColor{Color::unspecified}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::font_styles>( details::get<details::ProgressBarOption::font_styles>(
option::FontStyles{std::vector<FontStyle>{}}, std::forward<Args>(args)...), option::FontStyles{std::vector<FontStyle>{}}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::min_progress>(
option::MinProgress{0}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_progress>( details::get<details::ProgressBarOption::max_progress>(
option::MaxProgress{100}, std::forward<Args>(args)...), option::MaxProgress{100}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::progress_type>(
option::ProgressType{ProgressType::incremental}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::stream>( details::get<details::ProgressBarOption::stream>(
option::Stream{std::cout}, std::forward<Args>(args)...)) {} option::Stream{std::cout}, std::forward<Args>(args)...)) {
// if progress is incremental, start from min_progress
// else start from max_progress
const auto type = get_value<details::ProgressBarOption::progress_type>();
if (type == ProgressType::incremental)
progress_ = get_value<details::ProgressBarOption::min_progress>();
else
progress_ = get_value<details::ProgressBarOption::max_progress>();
}
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(details::Setting<T, id> &&setting) { void set_option(details::Setting<T, id> &&setting) {
@@ -119,7 +135,11 @@ public:
void tick() { void tick() {
{ {
std::lock_guard<std::mutex> lock{mutex_}; std::lock_guard<std::mutex> lock{mutex_};
const auto type = get_value<details::ProgressBarOption::progress_type>();
if (type == ProgressType::incremental)
progress_ += 1; progress_ += 1;
else
progress_ -= 1;
} }
save_start_time(); save_start_time();
print_progress(); print_progress();
@@ -175,9 +195,12 @@ public:
auto& os = get_value<details::ProgressBarOption::stream>(); auto& os = get_value<details::ProgressBarOption::stream>();
const auto type = get_value<details::ProgressBarOption::progress_type>();
const auto min_progress = get_value<details::ProgressBarOption::min_progress>();
const auto max_progress = get_value<details::ProgressBarOption::max_progress>(); const auto max_progress = get_value<details::ProgressBarOption::max_progress>();
if (multi_progress_mode_ && !from_multi_progress) { if (multi_progress_mode_ && !from_multi_progress) {
if (progress_ >= max_progress) { if ((type == ProgressType::incremental && progress_ >= max_progress) ||
(type == ProgressType::decremental && progress_ <= min_progress)) {
get_value<details::ProgressBarOption::completed>() = true; get_value<details::ProgressBarOption::completed>() = true;
} }
return; return;
@@ -246,7 +269,8 @@ public:
<< std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ') << std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ')
<< "\r"; << "\r";
os.flush(); os.flush();
if (progress_ >= max_progress) { if ((type == ProgressType::incremental && progress_ >= max_progress) ||
(type == ProgressType::decremental && progress_ <= min_progress)) {
get_value<details::ProgressBarOption::completed>() = true; get_value<details::ProgressBarOption::completed>() = true;
} }
if (get_value<details::ProgressBarOption::completed>() && if (get_value<details::ProgressBarOption::completed>() &&

View File

@@ -0,0 +1,5 @@
#pragma once
namespace indicators {
enum class ProgressType { incremental, decremental };
}

View File

@@ -29,6 +29,7 @@ SOFTWARE.
#include <cstddef> #include <cstddef>
#include <indicators/color.hpp> #include <indicators/color.hpp>
#include <indicators/font_style.hpp> #include <indicators/font_style.hpp>
#include <indicators/progress_type.hpp>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
@@ -91,7 +92,9 @@ enum class ProgressBarOption {
spinner_states, spinner_states,
font_styles, font_styles,
hide_bar_when_complete, hide_bar_when_complete,
min_progress,
max_progress, max_progress,
progress_type,
stream stream
}; };
@@ -207,7 +210,9 @@ using HideBarWhenComplete =
details::BooleanSetting<details::ProgressBarOption::hide_bar_when_complete>; details::BooleanSetting<details::ProgressBarOption::hide_bar_when_complete>;
using FontStyles = using FontStyles =
details::Setting<std::vector<FontStyle>, details::ProgressBarOption::font_styles>; details::Setting<std::vector<FontStyle>, details::ProgressBarOption::font_styles>;
using MinProgress = details::IntegerSetting<details::ProgressBarOption::min_progress>;
using MaxProgress = details::IntegerSetting<details::ProgressBarOption::max_progress>; using MaxProgress = details::IntegerSetting<details::ProgressBarOption::max_progress>;
using ProgressType = details::Setting<ProgressType, details::ProgressBarOption::progress_type>;
using Stream = details::Setting<std::ostream&, details::ProgressBarOption::stream>; using Stream = details::Setting<std::ostream&, details::ProgressBarOption::stream>;
} // namespace option } // namespace option
} // namespace indicators } // namespace indicators

View File

@@ -4,6 +4,7 @@
"sources": [ "sources": [
"include/indicators/color.hpp", "include/indicators/color.hpp",
"include/indicators/font_style.hpp", "include/indicators/font_style.hpp",
"include/indicators/progress_type.hpp",
"include/indicators/termcolor.hpp", "include/indicators/termcolor.hpp",
"include/indicators/terminal_size.hpp", "include/indicators/terminal_size.hpp",
"include/indicators/setting.hpp", "include/indicators/setting.hpp",

View File

@@ -460,6 +460,11 @@ namespace indicators {
enum class FontStyle { bold, dark, italic, underline, blink, reverse, concealed, crossed }; enum class FontStyle { bold, dark, italic, underline, blink, reverse, concealed, crossed };
}
#pragma once
namespace indicators {
enum class ProgressType { incremental, decremental };
} }
//! //!
//! termcolor //! termcolor
@@ -978,6 +983,7 @@ SOFTWARE.
#include <cstddef> #include <cstddef>
// #include <indicators/color.hpp> // #include <indicators/color.hpp>
// #include <indicators/font_style.hpp> // #include <indicators/font_style.hpp>
// #include <indicators/progress_type.hpp>
#include <string> #include <string>
#include <tuple> #include <tuple>
#include <type_traits> #include <type_traits>
@@ -1040,7 +1046,9 @@ enum class ProgressBarOption {
spinner_states, spinner_states,
font_styles, font_styles,
hide_bar_when_complete, hide_bar_when_complete,
min_progress,
max_progress, max_progress,
progress_type,
stream stream
}; };
@@ -1156,7 +1164,9 @@ using HideBarWhenComplete =
details::BooleanSetting<details::ProgressBarOption::hide_bar_when_complete>; details::BooleanSetting<details::ProgressBarOption::hide_bar_when_complete>;
using FontStyles = using FontStyles =
details::Setting<std::vector<FontStyle>, details::ProgressBarOption::font_styles>; details::Setting<std::vector<FontStyle>, details::ProgressBarOption::font_styles>;
using MinProgress = details::IntegerSetting<details::ProgressBarOption::min_progress>;
using MaxProgress = details::IntegerSetting<details::ProgressBarOption::max_progress>; using MaxProgress = details::IntegerSetting<details::ProgressBarOption::max_progress>;
using ProgressType = details::Setting<ProgressType, details::ProgressBarOption::progress_type>;
using Stream = details::Setting<std::ostream&, details::ProgressBarOption::stream>; using Stream = details::Setting<std::ostream&, details::ProgressBarOption::stream>;
} // namespace option } // namespace option
} // namespace indicators } // namespace indicators
@@ -1719,19 +1729,22 @@ public:
std::ostream &write(float progress) { std::ostream &write(float progress) {
auto pos = static_cast<size_t>(progress * bar_width / 100.0); auto pos = static_cast<size_t>(progress * bar_width / 100.0);
for (size_t i = 0, current_display_width = 0; i < bar_width;) { for (size_t i = 0; i < bar_width;) {
std::string next; std::string next{""};
size_t current_display_width = 0;
if (i < pos) { if (i < pos && !fill.empty()) {
next = fill; next = fill;
current_display_width = unicode::display_width(fill); current_display_width = unicode::display_width(fill);
} else if (i == pos) { } else if (i == pos && !lead.empty()) {
next = lead; next = lead;
current_display_width = unicode::display_width(lead); current_display_width = unicode::display_width(lead);
} else { } else {
if (!remainder.empty()) {
next = remainder; next = remainder;
current_display_width = unicode::display_width(remainder); current_display_width = unicode::display_width(remainder);
} }
}
i += current_display_width; i += current_display_width;
@@ -1825,7 +1838,10 @@ class ProgressBar {
option::End, option::Fill, option::Lead, option::Remainder, option::End, option::Fill, option::Lead, option::Remainder,
option::MaxPostfixTextLen, option::Completed, option::ShowPercentage, option::MaxPostfixTextLen, option::Completed, option::ShowPercentage,
option::ShowElapsedTime, option::ShowRemainingTime, option::SavedStartTime, option::ShowElapsedTime, option::ShowRemainingTime, option::SavedStartTime,
option::ForegroundColor, option::FontStyles, option::MaxProgress, option::Stream>; option::ForegroundColor, option::FontStyles,
option::MinProgress, option::MaxProgress,
option::ProgressType,
option::Stream>;
public: public:
template <typename... Args, template <typename... Args,
@@ -1865,10 +1881,23 @@ public:
option::ForegroundColor{Color::unspecified}, std::forward<Args>(args)...), option::ForegroundColor{Color::unspecified}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::font_styles>( details::get<details::ProgressBarOption::font_styles>(
option::FontStyles{std::vector<FontStyle>{}}, std::forward<Args>(args)...), option::FontStyles{std::vector<FontStyle>{}}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::min_progress>(
option::MinProgress{0}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::max_progress>( details::get<details::ProgressBarOption::max_progress>(
option::MaxProgress{100}, std::forward<Args>(args)...), option::MaxProgress{100}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::progress_type>(
option::ProgressType{ProgressType::incremental}, std::forward<Args>(args)...),
details::get<details::ProgressBarOption::stream>( details::get<details::ProgressBarOption::stream>(
option::Stream{std::cout}, std::forward<Args>(args)...)) {} option::Stream{std::cout}, std::forward<Args>(args)...)) {
// if progress is incremental, start from min_progress
// else start from max_progress
const auto type = get_value<details::ProgressBarOption::progress_type>();
if (type == ProgressType::incremental)
progress_ = get_value<details::ProgressBarOption::min_progress>();
else
progress_ = get_value<details::ProgressBarOption::max_progress>();
}
template <typename T, details::ProgressBarOption id> template <typename T, details::ProgressBarOption id>
void set_option(details::Setting<T, id> &&setting) { void set_option(details::Setting<T, id> &&setting) {
@@ -1920,7 +1949,11 @@ public:
void tick() { void tick() {
{ {
std::lock_guard<std::mutex> lock{mutex_}; std::lock_guard<std::mutex> lock{mutex_};
const auto type = get_value<details::ProgressBarOption::progress_type>();
if (type == ProgressType::incremental)
progress_ += 1; progress_ += 1;
else
progress_ -= 1;
} }
save_start_time(); save_start_time();
print_progress(); print_progress();
@@ -1976,9 +2009,12 @@ public:
auto& os = get_value<details::ProgressBarOption::stream>(); auto& os = get_value<details::ProgressBarOption::stream>();
const auto type = get_value<details::ProgressBarOption::progress_type>();
const auto min_progress = get_value<details::ProgressBarOption::min_progress>();
const auto max_progress = get_value<details::ProgressBarOption::max_progress>(); const auto max_progress = get_value<details::ProgressBarOption::max_progress>();
if (multi_progress_mode_ && !from_multi_progress) { if (multi_progress_mode_ && !from_multi_progress) {
if (progress_ >= max_progress) { if ((type == ProgressType::incremental && progress_ >= max_progress) ||
(type == ProgressType::decremental && progress_ <= min_progress)) {
get_value<details::ProgressBarOption::completed>() = true; get_value<details::ProgressBarOption::completed>() = true;
} }
return; return;
@@ -2047,7 +2083,8 @@ public:
<< std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ') << std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ')
<< "\r"; << "\r";
os.flush(); os.flush();
if (progress_ >= max_progress) { if ((type == ProgressType::incremental && progress_ >= max_progress) ||
(type == ProgressType::decremental && progress_ <= min_progress)) {
get_value<details::ProgressBarOption::completed>() = true; get_value<details::ProgressBarOption::completed>() = true;
} }
if (get_value<details::ProgressBarOption::completed>() && if (get_value<details::ProgressBarOption::completed>() &&