From 63bb0d89465041e3c239c3fc1bb8766a85a2a26a Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Mon, 25 May 2020 08:51:34 -0500 Subject: [PATCH 1/8] Progress bar now uses terminal size to figure out how many spaces to use to fill up the remainder of the terminal row --- include/indicators/progress_bar.hpp | 312 ++++++++++++++-------- include/indicators/terminal_size.hpp | 6 +- single_include/indicators/indicators.hpp | 318 +++++++++++++++-------- 3 files changed, 424 insertions(+), 212 deletions(-) diff --git a/include/indicators/progress_bar.hpp b/include/indicators/progress_bar.hpp index dcfae7a..51c328f 100644 --- a/include/indicators/progress_bar.hpp +++ b/include/indicators/progress_bar.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -21,42 +22,45 @@ namespace indicators { class ProgressBar { using Settings = - std::tuple; + std::tuple; public: template ::type...>::value, - void *>::type = nullptr> + typename std::enable_if< + details::are_settings_from_tuple< + Settings, typename std::decay::type...>::value, + void *>::type = nullptr> explicit ProgressBar(Args &&... args) : settings_( - details::get(option::BarWidth{100}, - std::forward(args)...), - details::get(option::PrefixText{}, - std::forward(args)...), - details::get(option::PostfixText{}, - std::forward(args)...), - details::get(option::Start{"["}, - std::forward(args)...), - details::get(option::End{"]"}, - std::forward(args)...), - details::get(option::Fill{"="}, - std::forward(args)...), - details::get(option::Lead{">"}, - std::forward(args)...), - details::get(option::Remainder{" "}, - std::forward(args)...), + details::get( + option::BarWidth{100}, std::forward(args)...), + details::get( + option::PrefixText{}, std::forward(args)...), + details::get( + option::PostfixText{}, std::forward(args)...), + details::get( + option::Start{"["}, std::forward(args)...), + details::get( + option::End{"]"}, std::forward(args)...), + details::get( + option::Fill{"="}, std::forward(args)...), + details::get( + option::Lead{">"}, std::forward(args)...), + details::get( + option::Remainder{" "}, std::forward(args)...), details::get( option::MaxPostfixTextLen{0}, std::forward(args)...), - details::get(option::Completed{false}, - std::forward(args)...), - details::get(option::ShowPercentage{false}, - std::forward(args)...), + details::get( + option::Completed{false}, std::forward(args)...), + details::get( + option::ShowPercentage{false}, std::forward(args)...), details::get( option::ShowElapsedTime{false}, std::forward(args)...), details::get( @@ -64,17 +68,20 @@ public: details::get( option::SavedStartTime{false}, std::forward(args)...), details::get( - option::ForegroundColor{Color::unspecified}, std::forward(args)...), + option::ForegroundColor{Color::unspecified}, + std::forward(args)...), details::get( - option::FontStyles{std::vector{}}, std::forward(args)...), - details::get(option::MinProgress{0}, - std::forward(args)...), - details::get(option::MaxProgress{100}, - std::forward(args)...), + option::FontStyles{std::vector{}}, + std::forward(args)...), + details::get( + option::MinProgress{0}, std::forward(args)...), + details::get( + option::MaxProgress{100}, std::forward(args)...), details::get( - option::ProgressType{ProgressType::incremental}, std::forward(args)...), - details::get(option::Stream{std::cout}, - std::forward(args)...)) { + option::ProgressType{ProgressType::incremental}, + std::forward(args)...), + details::get( + option::Stream{std::cout}, std::forward(args)...)) { // if progress is incremental, start from min_progress // else start from max_progress @@ -87,38 +94,47 @@ public: template void set_option(details::Setting &&setting) { - static_assert(!std::is_same( - std::declval()))>::type>::value, - "Setting has wrong type!"); + static_assert( + !std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); std::lock_guard lock(mutex_); get_value() = std::move(setting).value; } template void set_option(const details::Setting &setting) { - static_assert(!std::is_same( - std::declval()))>::type>::value, - "Setting has wrong type!"); + static_assert( + !std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); std::lock_guard lock(mutex_); get_value() = setting.value; } - void set_option( - const details::Setting &setting) { + void + set_option(const details::Setting< + std::string, details::ProgressBarOption::postfix_text> &setting) { std::lock_guard lock(mutex_); get_value() = setting.value; - if (setting.value.length() > get_value()) { - get_value() = setting.value.length(); + if (setting.value.length() > + get_value()) { + get_value() = + setting.value.length(); } } - void - set_option(details::Setting &&setting) { + void set_option( + details::Setting + &&setting) { std::lock_guard lock(mutex_); - get_value() = std::move(setting).value; + get_value() = + std::move(setting).value; auto &new_value = get_value(); - if (new_value.length() > get_value()) { - get_value() = new_value.length(); + if (new_value.length() > + get_value()) { + get_value() = + new_value.length(); } } @@ -147,10 +163,14 @@ public: size_t current() { std::lock_guard lock{mutex_}; - return std::min(progress_, size_t(get_value())); + return std::min( + progress_, + size_t(get_value())); } - bool is_completed() const { return get_value(); } + bool is_completed() const { + return get_value(); + } void mark_as_completed() { get_value() = true; @@ -159,13 +179,14 @@ public: private: template - auto get_value() -> decltype((details::get_value(std::declval()).value)) { + auto get_value() + -> decltype((details::get_value(std::declval()).value)) { return details::get_value(settings_).value; } template - auto get_value() const - -> decltype((details::get_value(std::declval()).value)) { + auto get_value() const -> decltype( + (details::get_value(std::declval()).value)) { return details::get_value(settings_).value; } @@ -180,61 +201,41 @@ private: std::atomic multi_progress_mode_{false}; void save_start_time() { - auto &show_elapsed_time = get_value(); - auto &saved_start_time = get_value(); - auto &show_remaining_time = get_value(); + auto &show_elapsed_time = + get_value(); + auto &saved_start_time = + get_value(); + auto &show_remaining_time = + get_value(); if ((show_elapsed_time || show_remaining_time) && !saved_start_time) { start_time_point_ = std::chrono::high_resolution_clock::now(); saved_start_time = true; } } -public: - void print_progress(bool from_multi_progress = false) { - std::lock_guard lock{mutex_}; - - auto &os = get_value(); - - const auto type = get_value(); - const auto min_progress = get_value(); - const auto max_progress = get_value(); - if (multi_progress_mode_ && !from_multi_progress) { - if ((type == ProgressType::incremental && progress_ >= max_progress) || - (type == ProgressType::decremental && progress_ <= min_progress)) { - get_value() = true; - } - return; - } - auto now = std::chrono::high_resolution_clock::now(); - if (!get_value()) - elapsed_ = std::chrono::duration_cast(now - start_time_point_); - - if (get_value() != Color::unspecified) - details::set_stream_color(os, get_value()); - - for (auto &style : get_value()) - details::set_font_style(os, style); - + size_t get_prefix_length() { + std::stringstream os; os << get_value(); + return os.str().size(); + } - os << get_value(); - - details::ProgressScaleWriter writer{os, get_value(), - get_value(), - get_value(), - get_value()}; - writer.write(double(progress_) / double(max_progress) * 100.0f); - - os << get_value(); + size_t get_postfix_length() { + std::stringstream os; + const auto min_progress = + get_value(); + const auto max_progress = + get_value(); if (get_value()) { os << " " - << std::min(static_cast(static_cast(progress_) / max_progress * 100), + << std::min(static_cast(static_cast(progress_) / + max_progress * 100), size_t(100)) << "%"; } - auto &saved_start_time = get_value(); + auto &saved_start_time = + get_value(); if (get_value()) { os << " ["; @@ -252,7 +253,8 @@ public: if (saved_start_time) { auto eta = std::chrono::nanoseconds( - progress_ > 0 ? static_cast(elapsed_.count() * max_progress / progress_) + progress_ > 0 ? static_cast(elapsed_.count() * + max_progress / progress_) : 0); auto remaining = eta > elapsed_ ? (eta - elapsed_) : (elapsed_ - eta); details::write_duration(os, remaining); @@ -266,11 +268,115 @@ public: os << "]"; } - if (get_value() == 0) - get_value() = 10; - os << " " << get_value() - << std::string(get_value(), ' ') << "\r"; + os << " " << get_value(); + + return os.str().size(); + } + +public: + void print_progress(bool from_multi_progress = false) { + std::lock_guard lock{mutex_}; + + auto &os = get_value(); + + const auto type = get_value(); + const auto min_progress = + get_value(); + const auto max_progress = + get_value(); + if (multi_progress_mode_ && !from_multi_progress) { + if ((type == ProgressType::incremental && progress_ >= max_progress) || + (type == ProgressType::decremental && progress_ <= min_progress)) { + get_value() = true; + } + return; + } + auto now = std::chrono::high_resolution_clock::now(); + if (!get_value()) + elapsed_ = std::chrono::duration_cast( + now - start_time_point_); + + if (get_value() != + Color::unspecified) + details::set_stream_color( + os, get_value()); + + for (auto &style : get_value()) + details::set_font_style(os, style); + + os << get_value(); + + os << get_value(); + + details::ProgressScaleWriter writer{ + os, get_value(), + get_value(), + get_value(), + get_value()}; + writer.write(double(progress_) / double(max_progress) * 100.0f); + + os << get_value(); + + if (get_value()) { + os << " " + << std::min(static_cast(static_cast(progress_) / + max_progress * 100), + size_t(100)) + << "%"; + } + + auto &saved_start_time = + get_value(); + + if (get_value()) { + os << " ["; + if (saved_start_time) + details::write_duration(os, elapsed_); + else + os << "00:00s"; + } + + if (get_value()) { + if (get_value()) + os << "<"; + else + os << " ["; + + if (saved_start_time) { + auto eta = std::chrono::nanoseconds( + progress_ > 0 ? static_cast(elapsed_.count() * + max_progress / progress_) + : 0); + auto remaining = eta > elapsed_ ? (eta - elapsed_) : (elapsed_ - eta); + details::write_duration(os, remaining); + } else { + os << "00:00s"; + } + + os << "]"; + } else { + if (get_value()) + os << "]"; + } + + os << " " << get_value(); + + // Get length of prefix text and postfix text + const auto prefix_length = get_prefix_length(); + const auto start_length = get_value().size(); + const auto bar_width = get_value(); + const auto end_length = get_value().size(); + const auto postfix_length = get_postfix_length(); + const auto terminal_width = terminal_size().second; + // prefix + bar_width + postfix should be <= terminal_width + const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length); + if (remaining > 0) { + os << std::string(remaining, ' ') << "\r"; + } else if (remaining < 0) { + // Do nothing. Maybe in the future truncate postfix with ... + } os.flush(); + if ((type == ProgressType::incremental && progress_ >= max_progress) || (type == ProgressType::decremental && progress_ <= min_progress)) { get_value() = true; diff --git a/include/indicators/terminal_size.hpp b/include/indicators/terminal_size.hpp index 29b21e7..f75f10d 100644 --- a/include/indicators/terminal_size.hpp +++ b/include/indicators/terminal_size.hpp @@ -7,7 +7,7 @@ namespace indicators { #if defined(_MSC_VER) #include -std::pair terminal_size() { +static inline std::pair terminal_size() { CONSOLE_SCREEN_BUFFER_INFO csbi; int columns, rows; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); @@ -22,13 +22,13 @@ size_t terminal_width() { return terminal_size().second; } #include //ioctl() and TIOCGWINSZ #include // for STDOUT_FILENO -std::pair terminal_size() { +static inline std::pair terminal_size() { struct winsize size; ioctl(STDOUT_FILENO, TIOCGWINSZ, &size); return {static_cast(size.ws_row), static_cast(size.ws_col)}; } -size_t terminal_width() { return terminal_size().second; } +static inline size_t terminal_width() { return terminal_size().second; } #endif } // namespace indicators \ No newline at end of file diff --git a/single_include/indicators/indicators.hpp b/single_include/indicators/indicators.hpp index 9a91316..43d9854 100644 --- a/single_include/indicators/indicators.hpp +++ b/single_include/indicators/indicators.hpp @@ -1297,7 +1297,7 @@ namespace indicators { #if defined(_MSC_VER) #include -std::pair terminal_size() { +static inline std::pair terminal_size() { CONSOLE_SCREEN_BUFFER_INFO csbi; int columns, rows; GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); @@ -1312,13 +1312,13 @@ size_t terminal_width() { return terminal_size().second; } #include //ioctl() and TIOCGWINSZ #include // for STDOUT_FILENO -std::pair terminal_size() { +static inline std::pair terminal_size() { struct winsize size; ioctl(STDOUT_FILENO, TIOCGWINSZ, &size); return {static_cast(size.ws_row), static_cast(size.ws_col)}; } -size_t terminal_width() { return terminal_size().second; } +static inline size_t terminal_width() { return terminal_size().second; } #endif } // namespace indicators @@ -2150,6 +2150,7 @@ private: // #include #include #include +#include #include #include #include @@ -2160,42 +2161,45 @@ namespace indicators { class ProgressBar { using Settings = - std::tuple; + std::tuple; public: template ::type...>::value, - void *>::type = nullptr> + typename std::enable_if< + details::are_settings_from_tuple< + Settings, typename std::decay::type...>::value, + void *>::type = nullptr> explicit ProgressBar(Args &&... args) : settings_( - details::get(option::BarWidth{100}, - std::forward(args)...), - details::get(option::PrefixText{}, - std::forward(args)...), - details::get(option::PostfixText{}, - std::forward(args)...), - details::get(option::Start{"["}, - std::forward(args)...), - details::get(option::End{"]"}, - std::forward(args)...), - details::get(option::Fill{"="}, - std::forward(args)...), - details::get(option::Lead{">"}, - std::forward(args)...), - details::get(option::Remainder{" "}, - std::forward(args)...), + details::get( + option::BarWidth{100}, std::forward(args)...), + details::get( + option::PrefixText{}, std::forward(args)...), + details::get( + option::PostfixText{}, std::forward(args)...), + details::get( + option::Start{"["}, std::forward(args)...), + details::get( + option::End{"]"}, std::forward(args)...), + details::get( + option::Fill{"="}, std::forward(args)...), + details::get( + option::Lead{">"}, std::forward(args)...), + details::get( + option::Remainder{" "}, std::forward(args)...), details::get( option::MaxPostfixTextLen{0}, std::forward(args)...), - details::get(option::Completed{false}, - std::forward(args)...), - details::get(option::ShowPercentage{false}, - std::forward(args)...), + details::get( + option::Completed{false}, std::forward(args)...), + details::get( + option::ShowPercentage{false}, std::forward(args)...), details::get( option::ShowElapsedTime{false}, std::forward(args)...), details::get( @@ -2203,17 +2207,20 @@ public: details::get( option::SavedStartTime{false}, std::forward(args)...), details::get( - option::ForegroundColor{Color::unspecified}, std::forward(args)...), + option::ForegroundColor{Color::unspecified}, + std::forward(args)...), details::get( - option::FontStyles{std::vector{}}, std::forward(args)...), - details::get(option::MinProgress{0}, - std::forward(args)...), - details::get(option::MaxProgress{100}, - std::forward(args)...), + option::FontStyles{std::vector{}}, + std::forward(args)...), + details::get( + option::MinProgress{0}, std::forward(args)...), + details::get( + option::MaxProgress{100}, std::forward(args)...), details::get( - option::ProgressType{ProgressType::incremental}, std::forward(args)...), - details::get(option::Stream{std::cout}, - std::forward(args)...)) { + option::ProgressType{ProgressType::incremental}, + std::forward(args)...), + details::get( + option::Stream{std::cout}, std::forward(args)...)) { // if progress is incremental, start from min_progress // else start from max_progress @@ -2226,38 +2233,47 @@ public: template void set_option(details::Setting &&setting) { - static_assert(!std::is_same( - std::declval()))>::type>::value, - "Setting has wrong type!"); + static_assert( + !std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); std::lock_guard lock(mutex_); get_value() = std::move(setting).value; } template void set_option(const details::Setting &setting) { - static_assert(!std::is_same( - std::declval()))>::type>::value, - "Setting has wrong type!"); + static_assert( + !std::is_same( + std::declval()))>::type>::value, + "Setting has wrong type!"); std::lock_guard lock(mutex_); get_value() = setting.value; } - void set_option( - const details::Setting &setting) { + void + set_option(const details::Setting< + std::string, details::ProgressBarOption::postfix_text> &setting) { std::lock_guard lock(mutex_); get_value() = setting.value; - if (setting.value.length() > get_value()) { - get_value() = setting.value.length(); + if (setting.value.length() > + get_value()) { + get_value() = + setting.value.length(); } } - void - set_option(details::Setting &&setting) { + void set_option( + details::Setting + &&setting) { std::lock_guard lock(mutex_); - get_value() = std::move(setting).value; + get_value() = + std::move(setting).value; auto &new_value = get_value(); - if (new_value.length() > get_value()) { - get_value() = new_value.length(); + if (new_value.length() > + get_value()) { + get_value() = + new_value.length(); } } @@ -2286,10 +2302,14 @@ public: size_t current() { std::lock_guard lock{mutex_}; - return std::min(progress_, size_t(get_value())); + return std::min( + progress_, + size_t(get_value())); } - bool is_completed() const { return get_value(); } + bool is_completed() const { + return get_value(); + } void mark_as_completed() { get_value() = true; @@ -2298,13 +2318,14 @@ public: private: template - auto get_value() -> decltype((details::get_value(std::declval()).value)) { + auto get_value() + -> decltype((details::get_value(std::declval()).value)) { return details::get_value(settings_).value; } template - auto get_value() const - -> decltype((details::get_value(std::declval()).value)) { + auto get_value() const -> decltype( + (details::get_value(std::declval()).value)) { return details::get_value(settings_).value; } @@ -2319,61 +2340,41 @@ private: std::atomic multi_progress_mode_{false}; void save_start_time() { - auto &show_elapsed_time = get_value(); - auto &saved_start_time = get_value(); - auto &show_remaining_time = get_value(); + auto &show_elapsed_time = + get_value(); + auto &saved_start_time = + get_value(); + auto &show_remaining_time = + get_value(); if ((show_elapsed_time || show_remaining_time) && !saved_start_time) { start_time_point_ = std::chrono::high_resolution_clock::now(); saved_start_time = true; } } -public: - void print_progress(bool from_multi_progress = false) { - std::lock_guard lock{mutex_}; - - auto &os = get_value(); - - const auto type = get_value(); - const auto min_progress = get_value(); - const auto max_progress = get_value(); - if (multi_progress_mode_ && !from_multi_progress) { - if ((type == ProgressType::incremental && progress_ >= max_progress) || - (type == ProgressType::decremental && progress_ <= min_progress)) { - get_value() = true; - } - return; - } - auto now = std::chrono::high_resolution_clock::now(); - if (!get_value()) - elapsed_ = std::chrono::duration_cast(now - start_time_point_); - - if (get_value() != Color::unspecified) - details::set_stream_color(os, get_value()); - - for (auto &style : get_value()) - details::set_font_style(os, style); - + size_t get_prefix_length() { + std::stringstream os; os << get_value(); + return os.str().size(); + } - os << get_value(); - - details::ProgressScaleWriter writer{os, get_value(), - get_value(), - get_value(), - get_value()}; - writer.write(double(progress_) / double(max_progress) * 100.0f); - - os << get_value(); + size_t get_postfix_length() { + std::stringstream os; + const auto min_progress = + get_value(); + const auto max_progress = + get_value(); if (get_value()) { os << " " - << std::min(static_cast(static_cast(progress_) / max_progress * 100), + << std::min(static_cast(static_cast(progress_) / + max_progress * 100), size_t(100)) << "%"; } - auto &saved_start_time = get_value(); + auto &saved_start_time = + get_value(); if (get_value()) { os << " ["; @@ -2391,7 +2392,8 @@ public: if (saved_start_time) { auto eta = std::chrono::nanoseconds( - progress_ > 0 ? static_cast(elapsed_.count() * max_progress / progress_) + progress_ > 0 ? static_cast(elapsed_.count() * + max_progress / progress_) : 0); auto remaining = eta > elapsed_ ? (eta - elapsed_) : (elapsed_ - eta); details::write_duration(os, remaining); @@ -2405,11 +2407,115 @@ public: os << "]"; } - if (get_value() == 0) - get_value() = 10; - os << " " << get_value() - << std::string(get_value(), ' ') << "\r"; + os << " " << get_value(); + + return os.str().size(); + } + +public: + void print_progress(bool from_multi_progress = false) { + std::lock_guard lock{mutex_}; + + auto &os = get_value(); + + const auto type = get_value(); + const auto min_progress = + get_value(); + const auto max_progress = + get_value(); + if (multi_progress_mode_ && !from_multi_progress) { + if ((type == ProgressType::incremental && progress_ >= max_progress) || + (type == ProgressType::decremental && progress_ <= min_progress)) { + get_value() = true; + } + return; + } + auto now = std::chrono::high_resolution_clock::now(); + if (!get_value()) + elapsed_ = std::chrono::duration_cast( + now - start_time_point_); + + if (get_value() != + Color::unspecified) + details::set_stream_color( + os, get_value()); + + for (auto &style : get_value()) + details::set_font_style(os, style); + + os << get_value(); + + os << get_value(); + + details::ProgressScaleWriter writer{ + os, get_value(), + get_value(), + get_value(), + get_value()}; + writer.write(double(progress_) / double(max_progress) * 100.0f); + + os << get_value(); + + if (get_value()) { + os << " " + << std::min(static_cast(static_cast(progress_) / + max_progress * 100), + size_t(100)) + << "%"; + } + + auto &saved_start_time = + get_value(); + + if (get_value()) { + os << " ["; + if (saved_start_time) + details::write_duration(os, elapsed_); + else + os << "00:00s"; + } + + if (get_value()) { + if (get_value()) + os << "<"; + else + os << " ["; + + if (saved_start_time) { + auto eta = std::chrono::nanoseconds( + progress_ > 0 ? static_cast(elapsed_.count() * + max_progress / progress_) + : 0); + auto remaining = eta > elapsed_ ? (eta - elapsed_) : (elapsed_ - eta); + details::write_duration(os, remaining); + } else { + os << "00:00s"; + } + + os << "]"; + } else { + if (get_value()) + os << "]"; + } + + os << " " << get_value(); + + // Get length of prefix text and postfix text + const auto prefix_length = get_prefix_length(); + const auto start_length = get_value().size(); + const auto bar_width = get_value(); + const auto end_length = get_value().size(); + const auto postfix_length = get_postfix_length(); + const auto terminal_width = terminal_size().second; + // prefix + bar_width + postfix should be <= terminal_width + const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length); + if (remaining > 0) { + os << std::string(remaining, ' ') << "\r"; + } else if (remaining < 0) { + // Do nothing. Maybe in the future truncate postfix with ... + } os.flush(); + if ((type == ProgressType::incremental && progress_ >= max_progress) || (type == ProgressType::decremental && progress_ <= min_progress)) { get_value() = true; From 7c1d7d63679350199d9591aa47bdb84bac21f28a Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Mon, 25 May 2020 09:14:23 -0500 Subject: [PATCH 2/8] Added dynamic postfix text sample based on #56 --- include/indicators/block_progress_bar.hpp | 8 ++++ include/indicators/progress_bar.hpp | 1 + samples/CMakeLists.txt | 3 ++ samples/dynamic_postfix_text.cpp | 46 +++++++++++++++++++++++ single_include/indicators/indicators.hpp | 8 ++++ 5 files changed, 66 insertions(+) create mode 100644 samples/dynamic_postfix_text.cpp diff --git a/include/indicators/block_progress_bar.hpp b/include/indicators/block_progress_bar.hpp index 11ae0a8..8bb4086 100644 --- a/include/indicators/block_progress_bar.hpp +++ b/include/indicators/block_progress_bar.hpp @@ -8,8 +8,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -160,6 +162,12 @@ private: } } + size_t get_prefix_length() { + std::stringstream os; + os << get_value(); + return os.str().size(); + } + public: void print_progress(bool from_multi_progress = false) { std::lock_guard lock{mutex_}; diff --git a/include/indicators/progress_bar.hpp b/include/indicators/progress_bar.hpp index 51c328f..3978f82 100644 --- a/include/indicators/progress_bar.hpp +++ b/include/indicators/progress_bar.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 8e70f8a..fb68137 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -44,3 +44,6 @@ target_link_libraries(max_progress PRIVATE indicators::indicators) add_executable(indeterminate_progress_bar indeterminate_progress_bar.cpp) target_link_libraries(indeterminate_progress_bar PRIVATE indicators::indicators) +add_executable(dynamic_postfix_text dynamic_postfix_text.cpp) +target_link_libraries(dynamic_postfix_text PRIVATE indicators::indicators) + diff --git a/samples/dynamic_postfix_text.cpp b/samples/dynamic_postfix_text.cpp new file mode 100644 index 0000000..d0d460b --- /dev/null +++ b/samples/dynamic_postfix_text.cpp @@ -0,0 +1,46 @@ +#include +#include +#include +using namespace indicators; + +int main() { + + std::cout << "Terminal width: " << terminal_size().second << "\n"; + + // prepare progress bar + auto prepare_p = [](ProgressBar *p, const std::string &prefix){ + p->set_option(option::PrefixText{prefix}); + p->set_option(option::Start{""}); + p->set_option(option::Fill{""}); + p->set_option(option::Lead{""}); + p->set_option(option::Remainder{""}); + p->set_option(option::End{""}); + p->set_option(option::BarWidth{0}); + }; + + ProgressBar p1, p2; + + prepare_p(&p1, "Progress #1"); + prepare_p(&p2, "Progress #2"); + + MultiProgress mp(p1, p2); + + std::string some_text[] = {"foo", "bar", "independence", "beta", "alfa"}; + std::string dynamic_text; + + // first pb with static postfix text + p1.set_option(option::PostfixText{"Static text"}); + + // second pb with dynamic postfix text + for (auto &t: some_text) { + dynamic_text += t + " "; + p2.set_option(option::PostfixText{dynamic_text}); + mp.set_progress<0>(size_t(0)); + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + + // update postfix to little text for pb #2 + p2.set_option(option::PostfixText{"abcd"}); + mp.set_progress<0>(size_t(0)); + +} diff --git a/single_include/indicators/indicators.hpp b/single_include/indicators/indicators.hpp index 43d9854..c53dfef 100644 --- a/single_include/indicators/indicators.hpp +++ b/single_include/indicators/indicators.hpp @@ -2516,6 +2516,14 @@ public: } os.flush(); + // std::cout << "\n" + // << prefix_length << " " + // << start_length << " " + // << bar_width << " " + // << end_length << " " + // << postfix_length << " " + // << " = " << terminal_width << "\n"; + if ((type == ProgressType::incremental && progress_ >= max_progress) || (type == ProgressType::decremental && progress_ <= min_progress)) { get_value() = true; From 958228f55d199538a64c84102e3d5cc453561dd6 Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Mon, 25 May 2020 09:25:22 -0500 Subject: [PATCH 3/8] Removed code duplication in prefix/postfix length calculation --- include/indicators/block_progress_bar.hpp | 48 +++++++++++++++++ include/indicators/progress_bar.hpp | 64 +++++------------------ 2 files changed, 60 insertions(+), 52 deletions(-) diff --git a/include/indicators/block_progress_bar.hpp b/include/indicators/block_progress_bar.hpp index 8bb4086..58c236d 100644 --- a/include/indicators/block_progress_bar.hpp +++ b/include/indicators/block_progress_bar.hpp @@ -168,6 +168,53 @@ private: return os.str().size(); } + size_t get_postfix_length() { + std::stringstream os; + const auto max_progress = get_value(); + auto now = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(now - start_time_point_); + + if (get_value()) { + os << " " << std::min(static_cast(progress_ / max_progress * 100.0), size_t(100)) + << "%"; + } + + auto &saved_start_time = get_value(); + + if (get_value()) { + os << " ["; + if (saved_start_time) + details::write_duration(os, elapsed); + else + os << "00:00s"; + } + + if (get_value()) { + if (get_value()) + os << "<"; + else + os << " ["; + + if (saved_start_time) { + auto eta = std::chrono::nanoseconds( + progress_ > 0 ? static_cast(elapsed.count() * max_progress / progress_) : 0); + auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta); + details::write_duration(os, remaining); + } else { + os << "00:00s"; + } + + os << "]"; + } else { + if (get_value()) + os << "]"; + } + + os << " " << get_value(); + + return os.str().size(); + } + public: void print_progress(bool from_multi_progress = false) { std::lock_guard lock{mutex_}; @@ -240,6 +287,7 @@ public: os << " " << get_value() << std::string(get_value(), ' ') << "\r"; os.flush(); + if (progress_ > max_progress) { get_value() = true; } diff --git a/include/indicators/progress_bar.hpp b/include/indicators/progress_bar.hpp index 3978f82..d9edcaf 100644 --- a/include/indicators/progress_bar.hpp +++ b/include/indicators/progress_bar.hpp @@ -214,16 +214,14 @@ private: } } - size_t get_prefix_length() { + std::pair get_prefix_text() { std::stringstream os; os << get_value(); - return os.str().size(); + return {os.str(), os.str().size()}; } - size_t get_postfix_length() { + std::pair get_postfix_text() { std::stringstream os; - const auto min_progress = - get_value(); const auto max_progress = get_value(); @@ -271,7 +269,7 @@ private: os << " " << get_value(); - return os.str().size(); + return {os.str(), os.str().size()}; } public: @@ -305,7 +303,10 @@ public: for (auto &style : get_value()) details::set_font_style(os, style); - os << get_value(); + const auto prefix_pair = get_prefix_text(); + const auto prefix_text = prefix_pair.first; + const auto prefix_length = prefix_pair.second; + os << prefix_text; os << get_value(); @@ -318,56 +319,15 @@ public: os << get_value(); - if (get_value()) { - os << " " - << std::min(static_cast(static_cast(progress_) / - max_progress * 100), - size_t(100)) - << "%"; - } - - auto &saved_start_time = - get_value(); - - if (get_value()) { - os << " ["; - if (saved_start_time) - details::write_duration(os, elapsed_); - else - os << "00:00s"; - } - - if (get_value()) { - if (get_value()) - os << "<"; - else - os << " ["; - - if (saved_start_time) { - auto eta = std::chrono::nanoseconds( - progress_ > 0 ? static_cast(elapsed_.count() * - max_progress / progress_) - : 0); - auto remaining = eta > elapsed_ ? (eta - elapsed_) : (elapsed_ - eta); - details::write_duration(os, remaining); - } else { - os << "00:00s"; - } - - os << "]"; - } else { - if (get_value()) - os << "]"; - } - - os << " " << get_value(); + const auto postfix_pair = get_postfix_text(); + const auto postfix_text = postfix_pair.first; + const auto postfix_length = postfix_pair.second; + os << postfix_text; // Get length of prefix text and postfix text - const auto prefix_length = get_prefix_length(); const auto start_length = get_value().size(); const auto bar_width = get_value(); const auto end_length = get_value().size(); - const auto postfix_length = get_postfix_length(); const auto terminal_width = terminal_size().second; // prefix + bar_width + postfix should be <= terminal_width const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length); From 0973cde3d30b170a0b1c29f79adb6e4160cb628a Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Mon, 25 May 2020 09:29:32 -0500 Subject: [PATCH 4/8] Using terminal size in block progress bar --- include/indicators/block_progress_bar.hpp | 75 ++++++++++------------- include/indicators/progress_bar.hpp | 9 ++- 2 files changed, 38 insertions(+), 46 deletions(-) diff --git a/include/indicators/block_progress_bar.hpp b/include/indicators/block_progress_bar.hpp index 58c236d..1df2730 100644 --- a/include/indicators/block_progress_bar.hpp +++ b/include/indicators/block_progress_bar.hpp @@ -16,6 +16,7 @@ #include #include #include +#include namespace indicators { @@ -162,13 +163,15 @@ private: } } - size_t get_prefix_length() { + std::pair get_prefix_text() { std::stringstream os; os << get_value(); - return os.str().size(); + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; } - size_t get_postfix_length() { + std::pair get_postfix_text() { std::stringstream os; const auto max_progress = get_value(); auto now = std::chrono::high_resolution_clock::now(); @@ -212,7 +215,9 @@ private: os << " " << get_value(); - return os.str().size(); + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; } public: @@ -238,7 +243,11 @@ public: for (auto &style : get_value()) details::set_font_style(os, style); - os << get_value(); + const auto prefix_pair = get_prefix_text(); + const auto prefix_text = prefix_pair.first; + const auto prefix_length = prefix_pair.second; + os << prefix_text; + os << get_value(); details::BlockProgressScaleWriter writer{os, @@ -246,46 +255,24 @@ public: writer.write(progress_ / max_progress * 100); os << get_value(); - if (get_value()) { - os << " " << std::min(static_cast(progress_ / max_progress * 100.0), size_t(100)) - << "%"; + + const auto postfix_pair = get_postfix_text(); + const auto postfix_text = postfix_pair.first; + const auto postfix_length = postfix_pair.second; + os << postfix_text; + + // Get length of prefix text and postfix text + const auto start_length = get_value().size(); + const auto bar_width = get_value(); + const auto end_length = get_value().size(); + const auto terminal_width = terminal_size().second; + // prefix + bar_width + postfix should be <= terminal_width + const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length); + if (remaining > 0) { + os << std::string(remaining, ' ') << "\r"; + } else if (remaining < 0) { + // Do nothing. Maybe in the future truncate postfix with ... } - - auto &saved_start_time = get_value(); - - if (get_value()) { - os << " ["; - if (saved_start_time) - details::write_duration(os, elapsed); - else - os << "00:00s"; - } - - if (get_value()) { - if (get_value()) - os << "<"; - else - os << " ["; - - if (saved_start_time) { - auto eta = std::chrono::nanoseconds( - progress_ > 0 ? static_cast(elapsed.count() * max_progress / progress_) : 0); - auto remaining = eta > elapsed ? (eta - elapsed) : (elapsed - eta); - details::write_duration(os, remaining); - } else { - os << "00:00s"; - } - - os << "]"; - } else { - if (get_value()) - os << "]"; - } - - if (get_value() == 0) - get_value() = 10; - os << " " << get_value() - << std::string(get_value(), ' ') << "\r"; os.flush(); if (progress_ > max_progress) { diff --git a/include/indicators/progress_bar.hpp b/include/indicators/progress_bar.hpp index d9edcaf..f260ca9 100644 --- a/include/indicators/progress_bar.hpp +++ b/include/indicators/progress_bar.hpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace indicators { @@ -217,7 +218,9 @@ private: std::pair get_prefix_text() { std::stringstream os; os << get_value(); - return {os.str(), os.str().size()}; + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; } std::pair get_postfix_text() { @@ -269,7 +272,9 @@ private: os << " " << get_value(); - return {os.str(), os.str().size()}; + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; } public: From 6be9c8005fde7b2a269744be6f2927497310e0e1 Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Mon, 25 May 2020 09:35:29 -0500 Subject: [PATCH 5/8] Added terminal size checks in indeterminate progress bar --- include/indicators/details/stream_helper.hpp | 3 +- .../indicators/indeterminate_progress_bar.hpp | 47 +++++++++++++++++-- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/include/indicators/details/stream_helper.hpp b/include/indicators/details/stream_helper.hpp index f7e02c9..baad820 100644 --- a/include/indicators/details/stream_helper.hpp +++ b/include/indicators/details/stream_helper.hpp @@ -180,8 +180,9 @@ public: : os(os), bar_width(bar_width), fill(fill), lead(lead) {} std::ostream &write(size_t progress) { - for (size_t i = 0, current_display_width = 0; i < bar_width;) { + for (size_t i = 0; i < bar_width;) { std::string next; + size_t current_display_width = 0; if (i < progress) { next = fill; diff --git a/include/indicators/indeterminate_progress_bar.hpp b/include/indicators/indeterminate_progress_bar.hpp index b549e06..253fa73 100644 --- a/include/indicators/indeterminate_progress_bar.hpp +++ b/include/indicators/indeterminate_progress_bar.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,8 @@ #include #include #include +#include +#include namespace indicators { @@ -156,6 +159,23 @@ private: template friend class DynamicProgress; std::atomic multi_progress_mode_{false}; + std::pair get_prefix_text() { + std::stringstream os; + os << get_value(); + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; + } + + std::pair get_postfix_text() { + std::stringstream os; + os << " " << get_value(); + + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; + } + public: void print_progress(bool from_multi_progress = false) { std::lock_guard lock{mutex_}; @@ -171,7 +191,10 @@ public: for (auto &style : get_value()) details::set_font_style(os, style); - os << get_value(); + const auto prefix_pair = get_prefix_text(); + const auto prefix_text = prefix_pair.first; + const auto prefix_length = prefix_pair.second; + os << prefix_text; os << get_value(); @@ -183,11 +206,25 @@ public: os << get_value(); - if (get_value() == 0) - get_value() = 10; - os << " " << get_value() - << std::string(get_value(), ' ') << "\r"; + const auto postfix_pair = get_postfix_text(); + const auto postfix_text = postfix_pair.first; + const auto postfix_length = postfix_pair.second; + os << postfix_text; + + // Get length of prefix text and postfix text + const auto start_length = get_value().size(); + const auto bar_width = get_value(); + const auto end_length = get_value().size(); + const auto terminal_width = terminal_size().second; + // prefix + bar_width + postfix should be <= terminal_width + const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length); + if (remaining > 0) { + os << std::string(remaining, ' ') << "\r"; + } else if (remaining < 0) { + // Do nothing. Maybe in the future truncate postfix with ... + } os.flush(); + if (get_value() && !from_multi_progress) // Don't std::endl if calling from MultiProgress os << termcolor::reset << std::endl; From f6cef6161ddbc64ff4f2bf2e6f72e5c63f138b29 Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Mon, 25 May 2020 09:47:48 -0500 Subject: [PATCH 6/8] Removed sleep --- samples/progress_bar_unicode.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/samples/progress_bar_unicode.cpp b/samples/progress_bar_unicode.cpp index 9ab668a..68817cc 100644 --- a/samples/progress_bar_unicode.cpp +++ b/samples/progress_bar_unicode.cpp @@ -8,8 +8,6 @@ int main() { indicators::show_console_cursor(false); - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); - { // Plain old ASCII indicators::ProgressBar bar{indicators::option::BarWidth{50}, From 20b1d1f69f412d60d3fa20650b10a1b551d7f60c Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Mon, 25 May 2020 09:51:02 -0500 Subject: [PATCH 7/8] Updated single include version --- single_include/indicators/indicators.hpp | 231 +++++++++++++---------- 1 file changed, 135 insertions(+), 96 deletions(-) diff --git a/single_include/indicators/indicators.hpp b/single_include/indicators/indicators.hpp index c53dfef..92fe034 100644 --- a/single_include/indicators/indicators.hpp +++ b/single_include/indicators/indicators.hpp @@ -2101,8 +2101,9 @@ public: : os(os), bar_width(bar_width), fill(fill), lead(lead) {} std::ostream &write(size_t progress) { - for (size_t i = 0, current_display_width = 0; i < bar_width;) { + for (size_t i = 0; i < bar_width;) { std::string next; + size_t current_display_width = 0; if (i < progress) { next = fill; @@ -2148,6 +2149,7 @@ private: #include // #include // #include +// #include #include #include #include @@ -2156,6 +2158,7 @@ private: #include #include #include +#include namespace indicators { @@ -2352,16 +2355,16 @@ private: } } - size_t get_prefix_length() { + std::pair get_prefix_text() { std::stringstream os; os << get_value(); - return os.str().size(); + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; } - size_t get_postfix_length() { + std::pair get_postfix_text() { std::stringstream os; - const auto min_progress = - get_value(); const auto max_progress = get_value(); @@ -2409,7 +2412,9 @@ private: os << " " << get_value(); - return os.str().size(); + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; } public: @@ -2443,7 +2448,10 @@ public: for (auto &style : get_value()) details::set_font_style(os, style); - os << get_value(); + const auto prefix_pair = get_prefix_text(); + const auto prefix_text = prefix_pair.first; + const auto prefix_length = prefix_pair.second; + os << prefix_text; os << get_value(); @@ -2456,56 +2464,15 @@ public: os << get_value(); - if (get_value()) { - os << " " - << std::min(static_cast(static_cast(progress_) / - max_progress * 100), - size_t(100)) - << "%"; - } - - auto &saved_start_time = - get_value(); - - if (get_value()) { - os << " ["; - if (saved_start_time) - details::write_duration(os, elapsed_); - else - os << "00:00s"; - } - - if (get_value()) { - if (get_value()) - os << "<"; - else - os << " ["; - - if (saved_start_time) { - auto eta = std::chrono::nanoseconds( - progress_ > 0 ? static_cast(elapsed_.count() * - max_progress / progress_) - : 0); - auto remaining = eta > elapsed_ ? (eta - elapsed_) : (elapsed_ - eta); - details::write_duration(os, remaining); - } else { - os << "00:00s"; - } - - os << "]"; - } else { - if (get_value()) - os << "]"; - } - - os << " " << get_value(); + const auto postfix_pair = get_postfix_text(); + const auto postfix_text = postfix_pair.first; + const auto postfix_length = postfix_pair.second; + os << postfix_text; // Get length of prefix text and postfix text - const auto prefix_length = get_prefix_length(); const auto start_length = get_value().size(); const auto bar_width = get_value(); const auto end_length = get_value().size(); - const auto postfix_length = get_postfix_length(); const auto terminal_width = terminal_size().second; // prefix + bar_width + postfix should be <= terminal_width const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length); @@ -2516,14 +2483,6 @@ public: } os.flush(); - // std::cout << "\n" - // << prefix_length << " " - // << start_length << " " - // << bar_width << " " - // << end_length << " " - // << postfix_length << " " - // << " = " << terminal_width << "\n"; - if ((type == ProgressType::incremental && progress_ >= max_progress) || (type == ProgressType::decremental && progress_ <= min_progress)) { get_value() = true; @@ -2545,12 +2504,15 @@ public: #include #include // #include +// #include #include #include +#include #include #include #include #include +#include namespace indicators { @@ -2697,37 +2659,20 @@ private: } } -public: - void print_progress(bool from_multi_progress = false) { - std::lock_guard lock{mutex_}; - - auto &os = get_value(); + std::pair get_prefix_text() { + std::stringstream os; + os << get_value(); + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; + } + std::pair get_postfix_text() { + std::stringstream os; const auto max_progress = get_value(); - if (multi_progress_mode_ && !from_multi_progress) { - if (progress_ > max_progress) { - get_value() = true; - } - return; - } - auto now = std::chrono::high_resolution_clock::now(); auto elapsed = std::chrono::duration_cast(now - start_time_point_); - if (get_value() != Color::unspecified) - details::set_stream_color(os, get_value()); - - for (auto &style : get_value()) - details::set_font_style(os, style); - - os << get_value(); - os << get_value(); - - details::BlockProgressScaleWriter writer{os, - get_value()}; - writer.write(progress_ / max_progress * 100); - - os << get_value(); if (get_value()) { os << " " << std::min(static_cast(progress_ / max_progress * 100.0), size_t(100)) << "%"; @@ -2764,11 +2709,68 @@ public: os << "]"; } - if (get_value() == 0) - get_value() = 10; - os << " " << get_value() - << std::string(get_value(), ' ') << "\r"; + os << " " << get_value(); + + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; + } + +public: + void print_progress(bool from_multi_progress = false) { + std::lock_guard lock{mutex_}; + + auto &os = get_value(); + + const auto max_progress = get_value(); + if (multi_progress_mode_ && !from_multi_progress) { + if (progress_ > max_progress) { + get_value() = true; + } + return; + } + + auto now = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(now - start_time_point_); + + if (get_value() != Color::unspecified) + details::set_stream_color(os, get_value()); + + for (auto &style : get_value()) + details::set_font_style(os, style); + + const auto prefix_pair = get_prefix_text(); + const auto prefix_text = prefix_pair.first; + const auto prefix_length = prefix_pair.second; + os << prefix_text; + + os << get_value(); + + details::BlockProgressScaleWriter writer{os, + get_value()}; + writer.write(progress_ / max_progress * 100); + + os << get_value(); + + const auto postfix_pair = get_postfix_text(); + const auto postfix_text = postfix_pair.first; + const auto postfix_length = postfix_pair.second; + os << postfix_text; + + // Get length of prefix text and postfix text + const auto start_length = get_value().size(); + const auto bar_width = get_value(); + const auto end_length = get_value().size(); + const auto terminal_width = terminal_size().second; + // prefix + bar_width + postfix should be <= terminal_width + const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length); + if (remaining > 0) { + os << std::string(remaining, ' ') << "\r"; + } else if (remaining < 0) { + // Do nothing. Maybe in the future truncate postfix with ... + } os.flush(); + if (progress_ > max_progress) { get_value() = true; } @@ -2790,6 +2792,7 @@ public: #include // #include // #include +// #include #include #include #include @@ -2797,6 +2800,8 @@ public: #include #include #include +#include +#include namespace indicators { @@ -2937,6 +2942,23 @@ private: template friend class DynamicProgress; std::atomic multi_progress_mode_{false}; + std::pair get_prefix_text() { + std::stringstream os; + os << get_value(); + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; + } + + std::pair get_postfix_text() { + std::stringstream os; + os << " " << get_value(); + + const auto result = os.str(); + const auto result_size = result.size(); + return {result, result_size}; + } + public: void print_progress(bool from_multi_progress = false) { std::lock_guard lock{mutex_}; @@ -2952,7 +2974,10 @@ public: for (auto &style : get_value()) details::set_font_style(os, style); - os << get_value(); + const auto prefix_pair = get_prefix_text(); + const auto prefix_text = prefix_pair.first; + const auto prefix_length = prefix_pair.second; + os << prefix_text; os << get_value(); @@ -2964,11 +2989,25 @@ public: os << get_value(); - if (get_value() == 0) - get_value() = 10; - os << " " << get_value() - << std::string(get_value(), ' ') << "\r"; + const auto postfix_pair = get_postfix_text(); + const auto postfix_text = postfix_pair.first; + const auto postfix_length = postfix_pair.second; + os << postfix_text; + + // Get length of prefix text and postfix text + const auto start_length = get_value().size(); + const auto bar_width = get_value(); + const auto end_length = get_value().size(); + const auto terminal_width = terminal_size().second; + // prefix + bar_width + postfix should be <= terminal_width + const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length); + if (remaining > 0) { + os << std::string(remaining, ' ') << "\r"; + } else if (remaining < 0) { + // Do nothing. Maybe in the future truncate postfix with ... + } os.flush(); + if (get_value() && !from_multi_progress) // Don't std::endl if calling from MultiProgress os << termcolor::reset << std::endl; From 8e39967c1e1a81a357a431d92875003a943b2ed3 Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Mon, 25 May 2020 09:53:56 -0500 Subject: [PATCH 8/8] Removed unused variables --- include/indicators/block_progress_bar.hpp | 3 --- single_include/indicators/indicators.hpp | 3 --- 2 files changed, 6 deletions(-) diff --git a/include/indicators/block_progress_bar.hpp b/include/indicators/block_progress_bar.hpp index 1df2730..162c2f3 100644 --- a/include/indicators/block_progress_bar.hpp +++ b/include/indicators/block_progress_bar.hpp @@ -234,9 +234,6 @@ public: return; } - auto now = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(now - start_time_point_); - if (get_value() != Color::unspecified) details::set_stream_color(os, get_value()); diff --git a/single_include/indicators/indicators.hpp b/single_include/indicators/indicators.hpp index 92fe034..441e8b3 100644 --- a/single_include/indicators/indicators.hpp +++ b/single_include/indicators/indicators.hpp @@ -2730,9 +2730,6 @@ public: return; } - auto now = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(now - start_time_point_); - if (get_value() != Color::unspecified) details::set_stream_color(os, get_value());