From 0973cde3d30b170a0b1c29f79adb6e4160cb628a Mon Sep 17 00:00:00 2001 From: Pranav Srinivas Kumar Date: Mon, 25 May 2020 09:29:32 -0500 Subject: [PATCH] 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: