mirror of
https://github.com/p-ranav/indicators.git
synced 2025-12-15 20:08:53 +08:00
Merge pull request #59 from p-ranav/feature/countdown_progress_bar
Feature/countdown progress bar
This commit is contained in:
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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>() &&
|
||||||
|
|||||||
5
include/indicators/progress_type.hpp
Normal file
5
include/indicators/progress_type.hpp
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace indicators {
|
||||||
|
enum class ProgressType { incremental, decremental };
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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>() &&
|
||||||
|
|||||||
Reference in New Issue
Block a user