Add a MaxProgress option (default: 100).

The MaxProgress option allows you to set the maximum number of ticks
that are within a progress bar. Each call to tick() increments the tick
count. The progress bar percentage is the number of ticks divided by the
MaxProgress option.

The default MaxProgress is 100, so each tick would be 1%.  If
MaxProgress is set to 500, for example, then each tick would be 0.2%.
This commit is contained in:
Kevin M. Godby
2020-04-30 21:37:06 -05:00
parent df4a97b068
commit 371bcb2c3b
6 changed files with 71 additions and 23 deletions

View File

@@ -46,7 +46,8 @@ class BlockProgressBar {
using Settings = std::tuple<option::ForegroundColor, option::BarWidth, option::Start, option::End,
option::PrefixText, option::PostfixText, option::ShowPercentage,
option::ShowElapsedTime, option::ShowRemainingTime, option::Completed,
option::SavedStartTime, option::MaxPostfixTextLen, option::FontStyles>;
option::SavedStartTime, option::MaxPostfixTextLen, option::FontStyles,
option::MaxProgress>;
public:
template <typename... Args,
@@ -79,7 +80,10 @@ public:
details::get<details::ProgressBarOption::max_postfix_text_len>(
option::MaxPostfixTextLen{0}, std::forward<Args>(args)...),
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::max_progress>(option::MaxProgress{100},
std::forward<Args>(args)...)
) {}
template <typename T, details::ProgressBarOption id>
void set_option(details::Setting<T, id> &&setting) {
@@ -138,7 +142,7 @@ public:
size_t current() {
std::lock_guard<std::mutex> lock{mutex_};
return std::min(static_cast<size_t>(progress_), size_t(100));
return std::min(static_cast<size_t>(progress_), size_t(get_value<details::ProgressBarOption::max_progress>()));
}
bool is_completed() const { return get_value<details::ProgressBarOption::completed>(); }
@@ -180,8 +184,9 @@ private:
}
void print_progress(bool from_multi_progress = false) {
const auto max_progress = get_value<details::ProgressBarOption::max_progress>();
if (multi_progress_mode_ && !from_multi_progress) {
if (progress_ > 100.0) {
if (progress_ > max_progress) {
get_value<details::ProgressBarOption::completed>() = true;
}
return;
@@ -201,11 +206,11 @@ private:
details::BlockProgressScaleWriter writer{std::cout,
get_value<details::ProgressBarOption::bar_width>()};
writer.write(progress_);
writer.write(progress_ / max_progress * 100);
std::cout << get_value<details::ProgressBarOption::end>();
if (get_value<details::ProgressBarOption::show_percentage>()) {
std::cout << " " << std::min(static_cast<size_t>(progress_), size_t(100)) << "%";
std::cout << " " << std::min(static_cast<size_t>(progress_ / max_progress * 100.0), size_t(100)) << "%";
}
auto &saved_start_time = get_value<details::ProgressBarOption::saved_start_time>();
@@ -226,7 +231,7 @@ private:
if (saved_start_time) {
auto eta = std::chrono::nanoseconds(
progress_ > 0 ? static_cast<long long>(elapsed.count() * 100 / progress_) : 0);
progress_ > 0 ? static_cast<long long>(elapsed.count() * max_progress / progress_) : 0);
auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta);
details::write_duration(std::cout, remaining);
} else {
@@ -245,7 +250,7 @@ private:
<< std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ')
<< "\r";
std::cout.flush();
if (progress_ > 100.0) {
if (progress_ > max_progress) {
get_value<details::ProgressBarOption::completed>() = true;
}
if (get_value<details::ProgressBarOption::completed>() &&

View File

@@ -50,7 +50,7 @@ class ProgressBar {
option::End, option::Fill, option::Lead, option::Remainder,
option::MaxPostfixTextLen, option::Completed, option::ShowPercentage,
option::ShowElapsedTime, option::ShowRemainingTime, option::SavedStartTime,
option::ForegroundColor, option::FontStyles>;
option::ForegroundColor, option::FontStyles, option::MaxProgress>;
public:
template <typename... Args,
@@ -89,7 +89,9 @@ public:
details::get<details::ProgressBarOption::foreground_color>(
option::ForegroundColor{Color::unspecified}, std::forward<Args>(args)...),
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::max_progress>(
option::MaxProgress{100}, std::forward<Args>(args)...)) {}
template <typename T, details::ProgressBarOption id>
void set_option(details::Setting<T, id> &&setting) {
@@ -149,7 +151,7 @@ public:
size_t current() {
std::lock_guard<std::mutex> lock{mutex_};
return std::min(progress_, size_t(100));
return std::min(progress_, size_t(get_value<details::ProgressBarOption::max_progress>()));
}
bool is_completed() const { return get_value<details::ProgressBarOption::completed>(); }
@@ -193,8 +195,9 @@ private:
void print_progress(bool from_multi_progress = false) {
std::lock_guard<std::mutex> lock{mutex_};
const auto max_progress = get_value<details::ProgressBarOption::max_progress>();
if (multi_progress_mode_ && !from_multi_progress) {
if (progress_ > 100) {
if (progress_ >= max_progress) {
get_value<details::ProgressBarOption::completed>() = true;
}
return;
@@ -218,12 +221,12 @@ private:
get_value<details::ProgressBarOption::fill>(),
get_value<details::ProgressBarOption::lead>(),
get_value<details::ProgressBarOption::remainder>()};
writer.write(progress_);
writer.write(progress_ / max_progress * 100);
std::cout << get_value<details::ProgressBarOption::end>();
if (get_value<details::ProgressBarOption::show_percentage>()) {
std::cout << " " << std::min(progress_, size_t(100)) << "%";
std::cout << " " << std::min(static_cast<size_t>(static_cast<float>(progress_) / max_progress * 100), size_t(100)) << "%";
}
auto &saved_start_time = get_value<details::ProgressBarOption::saved_start_time>();
@@ -244,7 +247,7 @@ private:
if (saved_start_time) {
auto eta = std::chrono::nanoseconds(
progress_ > 0 ? static_cast<long long>(elapsed_.count() * 100 / progress_) : 0);
progress_ > 0 ? static_cast<long long>(elapsed_.count() * max_progress / progress_) : 0);
auto remaining = eta > elapsed_ ? (eta - elapsed_) : (elapsed_ - eta);
details::write_duration(std::cout, remaining);
} else {
@@ -263,7 +266,7 @@ private:
<< std::string(get_value<details::ProgressBarOption::max_postfix_text_len>(), ' ')
<< "\r";
std::cout.flush();
if (progress_ > 100) {
if (progress_ >= max_progress) {
get_value<details::ProgressBarOption::completed>() = true;
}
if (get_value<details::ProgressBarOption::completed>() &&

View File

@@ -49,7 +49,8 @@ class ProgressSpinner {
std::tuple<option::ForegroundColor, option::PrefixText, option::PostfixText,
option::ShowPercentage, option::ShowElapsedTime, option::ShowRemainingTime,
option::ShowSpinner, option::SavedStartTime, option::Completed,
option::MaxPostfixTextLen, option::SpinnerStates, option::FontStyles>;
option::MaxPostfixTextLen, option::SpinnerStates, option::FontStyles,
option::MaxProgress>;
public:
template <typename... Args,
@@ -82,7 +83,9 @@ public:
"", "", "", ""}},
std::forward<Args>(args)...),
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::max_progress>(
option::MaxProgress{100}, std::forward<Args>(args)...)) {}
template <typename T, details::ProgressBarOption id>
void set_option(details::Setting<T, id> &&setting) {
@@ -141,7 +144,7 @@ public:
size_t current() {
std::lock_guard<std::mutex> lock{mutex_};
return std::min(progress_, size_t(100));
return std::min(progress_, size_t(get_value<details::ProgressBarOption::max_progress>()));
}
bool is_completed() const { return get_value<details::ProgressBarOption::completed>(); }
@@ -181,6 +184,7 @@ private:
void print_progress() {
std::lock_guard<std::mutex> lock{mutex_};
const auto max_progress = get_value<details::ProgressBarOption::max_progress>();
auto now = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(now - start_time_point_);
@@ -195,7 +199,7 @@ private:
std::cout << get_value<details::ProgressBarOption::spinner_states>()
[index_ % get_value<details::ProgressBarOption::spinner_states>().size()];
if (get_value<details::ProgressBarOption::show_percentage>()) {
std::cout << " " << std::min(progress_, size_t(100)) << "%";
std::cout << " " << std::min(progress_, size_t(max_progress)) << "%";
}
if (get_value<details::ProgressBarOption::show_elapsed_time>()) {
@@ -209,7 +213,7 @@ private:
else
std::cout << " [";
auto eta = std::chrono::nanoseconds(
progress_ > 0 ? static_cast<long long>(elapsed.count() * 100 / progress_) : 0);
progress_ > 0 ? static_cast<long long>(elapsed.count() * max_progress / progress_) : 0);
auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta);
details::write_duration(std::cout, remaining);
std::cout << "]";
@@ -225,7 +229,7 @@ private:
<< "\r";
std::cout.flush();
index_ += 1;
if (progress_ > 100) {
if (progress_ > max_progress) {
get_value<details::ProgressBarOption::completed>() = true;
}
if (get_value<details::ProgressBarOption::completed>())

View File

@@ -89,7 +89,8 @@ enum class ProgressBarOption {
spinner_show,
spinner_states,
font_styles,
hide_bar_when_complete
hide_bar_when_complete,
max_progress
};
template <typename T, ProgressBarOption Id> struct Setting {
@@ -204,5 +205,6 @@ using HideBarWhenComplete =
details::BooleanSetting<details::ProgressBarOption::hide_bar_when_complete>;
using FontStyles =
details::Setting<std::vector<FontStyle>, details::ProgressBarOption::font_styles>;
using MaxProgress = details::IntegerSetting<details::ProgressBarOption::max_progress>;
} // namespace option
} // namespace indicators

View File

@@ -25,3 +25,7 @@ target_link_libraries(multi_block_progress_bar PRIVATE indicators::indicators)
add_executable(dynamic_progress dynamic_progress.cpp)
target_link_libraries(dynamic_progress PRIVATE indicators::indicators)
add_executable(max_progress max_progress.cpp)
target_link_libraries(max_progress PRIVATE indicators::indicators)

30
samples/max_progress.cpp Normal file
View File

@@ -0,0 +1,30 @@
#include <chrono>
#include <indicators/block_progress_bar.hpp>
#include <indicators/cursor_control.hpp>
#include <thread>
int main() {
// Hide cursor
indicators::show_console_cursor(false);
indicators::BlockProgressBar bar{
indicators::option::BarWidth{80},
indicators::option::FontStyles{
std::vector<indicators::FontStyle>{indicators::FontStyle::bold}},
indicators::option::MaxProgress{400}
};
// Update bar state
while (true) {
bar.tick();
if (bar.is_completed())
break;
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
// Show cursor
indicators::show_console_cursor(true);
return 0;
}