From 46c9983fabb0a6cf0a1b7b1876c1ae7bbfce9261 Mon Sep 17 00:00:00 2001 From: Dawid Pilarski Date: Tue, 4 Feb 2020 23:29:14 +0100 Subject: [PATCH] Progress spinner changed, default values approach changed, templates refactored --- demo/demo.cpp | 71 ++--- include/indicators/progress_bar.hpp | 160 +++++------ include/indicators/progress_spinner.hpp | 152 ++++++----- include/indicators/setting.hpp | 343 +++++++++--------------- samples/progress_spinner.cpp | 21 +- 5 files changed, 344 insertions(+), 403 deletions(-) diff --git a/demo/demo.cpp b/demo/demo.cpp index cebd531..093a0d4 100644 --- a/demo/demo.cpp +++ b/demo/demo.cpp @@ -188,19 +188,21 @@ int main() { // // PROGRESS BAR 5 // - indicators::ProgressSpinner p; - p.set_prefix_text(""); - p.set_postfix_text("Checking credentials"); - p.set_foreground_color(indicators::Color::YELLOW); - p.set_spinner_states({"⠈", "⠐", "⠠", "⢀", "⡀", "⠄", "⠂", "⠁"}); + indicators::ProgressSpinner p{ + option::PrefixText{""}, + option::PostfixText{"Checking credentials"}, + option::ForegroundColor{indicators::Color::YELLOW}, + option::SpinnerStates{std::vector{"⠈", "⠐", "⠠", "⢀", "⡀", "⠄", "⠂", "⠁"}} + }; + auto job = [&p]() { while (true) { if (p.is_completed()) { - p.set_foreground_color(indicators::Color::GREEN); - p.set_prefix_text("✔"); - p.hide_spinner(); - p.hide_percentage(); - p.set_postfix_text("Authenticated!"); + p.set_option(option::ForegroundColor{indicators::Color::GREEN}); + p.set_option(option::PrefixText{"✔"}); + p.set_option(option::SpinnerShow{false}); + p.set_option(option::ShowPercentage{false}); + p.set_option(option::PostfixText{"Authenticated!"}); p.mark_as_completed(); break; } else @@ -217,42 +219,43 @@ int main() { // // PROGRESS BAR 6 // - indicators::ProgressSpinner p; - p.set_prefix_text(" - "); - p.set_postfix_text("Searching for the Moon"); - p.set_foreground_color(indicators::Color::WHITE); - p.set_spinner_states({"▖", "▘", "▝", "▗"}); - p.hide_percentage(); + indicators::ProgressSpinner p{ + option::PrefixText{" - "}, + option::PostfixText{"Searching for the Moon"}, + option::ForegroundColor{indicators::Color::WHITE}, + option::ShowPercentage{false}, + option::SpinnerStates{std::vector{"▖", "▘", "▝", "▗"}} + }; auto job = [&p]() { while (true) { auto current = p.current(); if (current == 24) { - p.set_prefix_text(" - ✔"); - p.hide_spinner(); + p.set_option(option::PrefixText{" - ✔"}); + p.set_option(option::SpinnerShow{false}); } else if (current == 25) { std::cout << std::endl; - p.show_spinner(); - p.set_prefix_text(" - "); - p.set_postfix_text("Contacting Kerbal headquarters"); + p.set_option(option::SpinnerShow{true}); + p.set_option(option::PrefixText{" - "}); + p.set_option(option::PostfixText{"Contacting Kerbal headquarters"}); } else if (current == 49) { - p.set_prefix_text(" - ✔"); - p.hide_spinner(); + p.set_option(option::PrefixText{" - ✔"}); + p.set_option(option::SpinnerShow{false}); } else if (current == 50) { std::cout << std::endl; - p.show_spinner(); - p.set_prefix_text(" - "); - p.set_postfix_text("Designing spaceship"); + p.set_option(option::SpinnerShow{true}); + p.set_option(option::PrefixText{" - "}); + p.set_option(option::PostfixText{"Designing spaceship"}); } else if (current == 74) { - p.set_prefix_text(" - ✔"); - p.hide_spinner(); + p.set_option(option::PrefixText{" - ✔"}); + p.set_option(option::SpinnerShow{false}); } else if (current == 75) { std::cout << std::endl; - p.show_spinner(); - p.set_prefix_text(" - "); - p.set_postfix_text("Launching rocket"); + p.set_option(option::SpinnerShow{true}); + p.set_option(option::PrefixText{" - "}); + p.set_option(option::PostfixText{"Launching rocket"}); } else if (current == 95) { - p.set_prefix_text(" - ✔"); - p.hide_spinner(); + p.set_option(option::PrefixText{" - ✔"}); + p.set_option(option::SpinnerShow{false}); } else if (current == 99) { std::cout << std::endl; // @@ -291,7 +294,7 @@ int main() { }; std::thread thread2(job2); thread2.join(); - p.set_postfix_text("Mission successful!"); + p.set_option(indicators::option::PostfixText{"Mission successful!"}); p.mark_as_completed(); break; } diff --git a/include/indicators/progress_bar.hpp b/include/indicators/progress_bar.hpp index d840bb1..887165d 100644 --- a/include/indicators/progress_bar.hpp +++ b/include/indicators/progress_bar.hpp @@ -41,60 +41,79 @@ SOFTWARE. #include #include #include +#include +#include namespace indicators { class ProgressBar { + using Settings = std::tuple< + option::BarWidth, + option::PrefixText, + option::PostfixText, + option::Start, + option::End, + option::Fill, + option::Lead, + option::Remainder, + option::MaxPostfixTextLen, + option::Completed, + option::ShowPercentage, + option::ShowElapsedTime, + option::ShowRemainingTime, + option::SavedStartTime, + option::ForegroundColor + >; public: - template + template ::type...>::value, void*>::type = nullptr> explicit ProgressBar(Args&&... args) : settings_( - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(std::forward(args)...), - indicators::get(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::ShowElapsedTime{false}, std::forward(args)...), + details::get(option::ShowRemainingTime{false}, std::forward(args)...), + details::get(option::SavedStartTime{false}, std::forward(args)...), + details::get(option::ForegroundColor{Color::WHITE}, std::forward(args)...) ) {} - template - void set_option(Setting&& setting){ - static_assert(!std::is_same())>::type>::value, "Setting has wrong type!"); + template + void set_option(details::Setting&& setting){ + 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 Setting& setting){ - static_assert(!std::is_same())>::type>::value, "Setting has wrong type!"); + template + void set_option(const details::Setting& setting){ + 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 Setting& setting){ + void set_option(const details::Setting& setting){ std::lock_guard lock(_mutex); - get_value() = setting.value; - if(setting.value.length() > get_value()){ - get_value() = setting.value.length(); + get_value() = setting.value; + if(setting.value.length() > get_value()){ + get_value() = setting.value.length(); } } - void set_option(Setting&& setting){ + void set_option(details::Setting&& setting){ std::lock_guard lock(_mutex); - get_value() = std::move(setting).value; - auto& new_value = get_value(); - if(new_value.length() > get_value()){ - get_value() = new_value.length(); + get_value() = std::move(setting).value; + auto& new_value = get_value(); + if(new_value.length() > get_value()){ + get_value() = new_value.length(); } } @@ -122,40 +141,23 @@ public: return std::min(static_cast(_progress), size_t(100)); } - bool is_completed() const { return get_value(); } + bool is_completed() const { return get_value(); } void mark_as_completed() { - get_value() = true; + get_value() = true; _print_progress(); } private: - using Settings = std::tuple< - option::BarWidth, - option::PrefixText, - option::PostfixText, - option::Start, - option::End, - option::Fill, - option::Lead, - option::Remainder, - option::MaxPostfixTextLen, - option::Completed, - option::ShowPercentage, - option::ShowElapsedTime, - option::ShowRemainingTime, - option::SavedStartTime, - option::ForegroundColor - >; - template - auto get_value() -> decltype((std::get(id)>(std::declval()).value)) { - return std::get(id)>(settings_).value; + template + auto get_value() -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; } - template - auto get_value() const -> decltype((std::get(id)>(std::declval()).value)) { - return std::get(id)>(settings_).value; + template + auto get_value() const -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; } float _progress{0}; @@ -168,9 +170,9 @@ 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; @@ -180,40 +182,40 @@ private: void _print_progress(bool from_multi_progress = false) { if (_multi_progress_mode && !from_multi_progress) { if (_progress > 100.0) { - get_value() = true; + get_value() = true; } return; } std::lock_guard lock{_mutex}; auto now = std::chrono::high_resolution_clock::now(); - if (!get_value()) + if (!get_value()) _elapsed = std::chrono::duration_cast(now - _start_time_point); std::cout << termcolor::bold; - details::set_stream_color(std::cout, get_value()); - std::cout << get_value(); + details::set_stream_color(std::cout, get_value()); + std::cout << get_value(); - std::cout << get_value(); + std::cout << get_value(); - details::ProgressScaleWriter writer{std::cout, get_value(), - get_value(), - get_value(), - get_value()}; + details::ProgressScaleWriter writer{std::cout, get_value(), + get_value(), + get_value(), + get_value()}; writer.write(_progress); - std::cout << get_value(); + std::cout << get_value(); - if (get_value()) { + if (get_value()) { std::cout << " " << std::min(static_cast(_progress), size_t(100)) << "%"; } - if (get_value()) { + if (get_value()) { std::cout << " ["; details::write_duration(std::cout, _elapsed); } - if (get_value()) { - if (get_value()) + if (get_value()) { + if (get_value()) std::cout << "<"; else std::cout << " ["; @@ -223,18 +225,18 @@ private: details::write_duration(std::cout, remaining); std::cout << "]"; } else { - if (get_value()) + if (get_value()) std::cout << "]"; } - if (get_value() == 0) - get_value() = 10; - std::cout << " " << get_value() << std::string(get_value(), ' ') << "\r"; + if (get_value() == 0) + get_value() = 10; + std::cout << " " << get_value() << std::string(get_value(), ' ') << "\r"; std::cout.flush(); if (_progress > 100.0) { - get_value() = true; + get_value() = true; } - if (get_value() && !from_multi_progress) // Don't std::endl if calling from MultiProgress + if (get_value() && !from_multi_progress) // Don't std::endl if calling from MultiProgress std::cout << termcolor::reset << std::endl; } }; diff --git a/include/indicators/progress_spinner.hpp b/include/indicators/progress_spinner.hpp index c8f1c5e..ce767a3 100644 --- a/include/indicators/progress_spinner.hpp +++ b/include/indicators/progress_spinner.hpp @@ -34,49 +34,77 @@ SOFTWARE. #include #include #include +#include #include #include #include #include +#include #include #include namespace indicators { class ProgressSpinner { + using Settings = std::tuple< + option::ForegroundColor, + option::PrefixText, + option::PostfixText, + option::ShowPercentage, + option::ShowElapsedTime, + option::ShowRemainingTime, + option::SpinnerShow, + option::SavedStartTime, + option::Completed, + option::MaxPostfixTextLen, + option::SpinnerStates + >; public: - void set_foreground_color(Color color) { - std::lock_guard lock{_mutex}; - _foreground_color = color; + template ::type...>::value, void*>::type = nullptr> + explicit ProgressSpinner(Args&&... args) : settings_( + details::get(option::ForegroundColor{Color::WHITE}, std::forward(args)...), + details::get(option::PrefixText{}, std::forward(args)...), + details::get(option::PostfixText{}, std::forward(args)...), + details::get(option::ShowPercentage{true}, std::forward(args)...), + details::get(option::ShowElapsedTime{false}, std::forward(args)...), + details::get(option::ShowRemainingTime{false}, std::forward(args)...), + details::get(option::SpinnerShow{true}, std::forward(args)...), + details::get(option::SavedStartTime{false}, std::forward(args)...), + details::get(option::Completed{false}, std::forward(args)...), + details::get(option::MaxPostfixTextLen{0}, std::forward(args)...), + details::get(option::SpinnerStates{std::vector{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}}, std::forward(args)...) + ){} + + template + void set_option(details::Setting&& setting){ + static_assert(!std::is_same(std::declval()))>::type>::value, "Setting has wrong type!"); + std::lock_guard lock(_mutex); + get_value() = std::move(setting).value; } - void set_prefix_text(const std::string &text) { - std::lock_guard lock{_mutex}; - _prefix_text = text; + template + void set_option(const details::Setting& setting){ + static_assert(!std::is_same(std::declval()))>::type>::value, "Setting has wrong type!"); + std::lock_guard lock(_mutex); + get_value() = setting.value; } - void set_postfix_text(const std::string &text) { - std::lock_guard lock{_mutex}; - _postfix_text = text; - if (_postfix_text.length() > _max_postfix_text_length) - _max_postfix_text_length = _postfix_text.length(); + void set_option(const details::Setting& setting){ + std::lock_guard lock(_mutex); + get_value() = setting.value; + if(setting.value.length() > get_value()){ + get_value() = setting.value.length(); + } } - void show_percentage() { _show_percentage = true; } - - void hide_percentage() { _show_percentage = false; } - - void show_elapsed_time() { _show_elapsed_time = true; } - - void hide_elapsed_time() { _show_elapsed_time = false; } - - void show_remaining_time() { _show_remaining_time = true; } - - void hide_remaining_time() { _show_remaining_time = false; } - - void show_spinner() { _show_spinner = true; } - - void hide_spinner() { _show_spinner = false; } + void set_option(details::Setting&& setting){ + std::lock_guard lock(_mutex); + get_value() = std::move(setting).value; + auto& new_value = get_value(); + if(new_value.length() > get_value()){ + get_value() = new_value.length(); + } + } void set_progress(float value) { { @@ -101,39 +129,37 @@ public: return std::min(static_cast(_progress), size_t(100)); } - bool is_completed() const { return _completed; } + bool is_completed() const { return get_value(); } void mark_as_completed() { - _completed = true; + get_value() = true; _print_progress(); } - void set_spinner_states(const std::vector &states) { - std::lock_guard lock{_mutex}; - _states = states; +private: + Settings settings_; + float _progress{0.0}; + size_t _index{0}; + std::chrono::time_point _start_time_point; + std::mutex _mutex; + + template + auto get_value() -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; } -private: - float _progress{0.0}; - std::string _prefix_text{""}; - size_t _index{0}; - std::vector _states{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}; - std::string _postfix_text{""}; - std::atomic _max_postfix_text_length{0}; - std::atomic _completed{false}; - std::atomic _show_percentage{true}; - std::atomic _show_elapsed_time{false}; - std::atomic _show_remaining_time{false}; - std::atomic _saved_start_time{false}; - std::chrono::time_point _start_time_point; - std::atomic _show_spinner{true}; - std::mutex _mutex; - Color _foreground_color; + template + auto get_value() const -> decltype((details::get_value(std::declval()).value)) { + return details::get_value(settings_).value; + } void _save_start_time() { - if ((_show_elapsed_time || _show_remaining_time) && !_saved_start_time) { + auto& show_elapsed_time = get_value(); + auto& show_remaining_time = get_value(); + auto& saved_start_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; + saved_start_time = true; } } @@ -143,21 +169,21 @@ private: auto elapsed = std::chrono::duration_cast(now - _start_time_point); std::cout << termcolor::bold; - details::set_stream_color(std::cout, _foreground_color); - std::cout << _prefix_text; - if (_show_spinner) - std::cout << _states[_index % _states.size()]; - if (_show_percentage) { + details::set_stream_color(std::cout, get_value()); + std::cout << get_value(); + if (get_value()) + std::cout << get_value()[_index % get_value().size()]; + if (get_value()) { std::cout << " " << std::min(static_cast(_progress), size_t(100)) << "%"; } - if (_show_elapsed_time) { + if (get_value()) { std::cout << " ["; details::write_duration(std::cout, elapsed); } - if (_show_remaining_time) { - if (_show_elapsed_time) + if (get_value()) { + if (get_value()) std::cout << "<"; else std::cout << " ["; @@ -167,19 +193,19 @@ private: details::write_duration(std::cout, remaining); std::cout << "]"; } else { - if (_show_elapsed_time) + if (get_value()) std::cout << "]"; } - if (_max_postfix_text_length == 0) - _max_postfix_text_length = 10; - std::cout << " " << _postfix_text << std::string(_max_postfix_text_length, ' ') << "\r"; + if (get_value() == 0) + get_value() = 10; + std::cout << " " << get_value() << std::string(get_value(), ' ') << "\r"; std::cout.flush(); _index += 1; if (_progress > 100.0) { - _completed = true; + get_value() = true; } - if (_completed) + if (get_value()) std::cout << termcolor::reset << std::endl; } }; diff --git a/include/indicators/setting.hpp b/include/indicators/setting.hpp index 2dbb60d..6015045 100644 --- a/include/indicators/setting.hpp +++ b/include/indicators/setting.hpp @@ -35,22 +35,70 @@ SOFTWARE. namespace indicators{ +namespace details{ + +template +struct if_else; + +template<> +struct if_else{ + using type = std::true_type; +}; + +template<> +struct if_else{ + using type = std::false_type ; +}; + +template +struct if_else_type; + +template +struct if_else_type{ + using type = True; +}; + +template +struct if_else_type{ + using type = False; +}; + +template +struct conjuction; + +template <> +struct conjuction<> : std::true_type {}; + +template +struct conjuction : if_else_type>::type {}; + +template +struct disjunction; + +template <> +struct disjunction<> : std::false_type {}; + +template +struct disjunction : if_else_type>::type {}; + enum class ProgressBarOption{ - BAR_WIDTH=0, - PREFIX_TEXT, - POSTFIX_TEXT, - START, - END, - FILL, - LEAD, - REMAINDER, - MAX_POSTFIX_TEXT_LEN, - COMPLETED, - SHOW_PERCENTAGE, - SHOW_ELAPSED_TIME, - SHOW_REMAINING_TIME, - SAVED_START_TIME, - FOREGROUND_COLOR, + bar_width=0, + prefix_text, + postfix_text, + start, + end, + fill, + lead, + remainder, + max_postfix_text_len, + completed, + show_percentage, + show_elapsed_time, + show_remaining_time, + saved_start_time, + foreground_color, + spinner_show, + spinner_states }; template @@ -63,7 +111,7 @@ struct Setting{ static constexpr auto id = Id; using type = T; - T value; + T value{}; }; template @@ -72,61 +120,54 @@ struct is_setting : std::false_type{}; template struct is_setting> : std::true_type{}; - -template -struct are_settings_impl{ - static constexpr bool value = is_setting::value && are_settings_impl::value; -}; - -template -struct are_settings_impl : is_setting{}; - - template -struct are_settings{ - static constexpr bool value = are_settings_impl::value; -}; +struct are_settings : if_else...>::value>::type {}; template <> -struct are_settings<>{ - static constexpr bool value = true; -}; +struct are_settings<> : std::true_type{}; + +template +struct is_setting_from_tuple; + +template +struct is_setting_from_tuple> : std::true_type {}; + +template +struct is_setting_from_tuple> : + if_else...>::value>::type {}; + +template +struct are_settings_from_tuple : if_else...>::value>::type {}; -namespace detail{ template struct always_true{ static constexpr auto value = true; }; -template -struct get_ret_type; +template +Default&& get_impl(Default&& def){ + return std::forward(def); +} -template -typename get_ret_type::type get(){ - static_assert(!always_true::value, "No default value for option specified!"); -} // customization point, should never be called - -template -auto get(T&& first, Args&&... tail) -> typename std::enable_if< +template +auto get_impl(Default&& def, T&& first, Args&&... tail) -> typename std::enable_if< (std::decay::type::id == Id), decltype(std::forward(first))> ::type{ return std::forward(first); } -template -auto get(T&& first, Args&&... tail) -> typename std::enable_if< +template +auto get_impl(Default&& def, T&& first, Args&&... tail) -> typename std::enable_if< (std::decay::type::id != Id), - decltype(get(std::forward(tail)...))>::type{ - return get(std::forward(tail)...); + decltype(get_impl(std::forward(def), std::forward(tail)...))>::type{ + return get_impl(std::forward(def), std::forward(tail)...); } -} - -template ::value, void>::type> -auto get(Args&&... args) -> decltype(detail::get(std::forward(args)...)){ - return detail::get(std::forward(args)...); +template ::value, void>::type> +auto get(Default&& def, Args&&... args) -> decltype(details::get_impl(std::forward(def), std::forward(args)...)){ + return details::get_impl(std::forward(def), std::forward(args)...); } template @@ -138,174 +179,44 @@ using IntegerSetting = Setting; template using BooleanSetting = Setting; -namespace option{ - using BarWidth = IntegerSetting; - using PrefixText = StringSetting; - using PostfixText = StringSetting; - using Start = StringSetting; - using End = StringSetting; - using Fill = StringSetting; - using Lead = StringSetting; - using Remainder = StringSetting; - using MaxPostfixTextLen = IntegerSetting; - using Completed = BooleanSetting; - using ShowPercentage = BooleanSetting; - using ShowElapsedTime = BooleanSetting; - using ShowRemainingTime = BooleanSetting; - using SavedStartTime = BooleanSetting; - using ForegroundColor = Setting; +template +struct option_idx; + +template +struct option_idx, counter> : if_else_type<(Id == T::id), + std::integral_constant, + option_idx, counter+1>>::type{}; + +template +struct option_idx, counter>{ + static_assert(always_true<(ProgressBarOption)Id>::value, "No such option was found"); +}; + +template +auto get_value(Settings&& settings) -> decltype((std::get::type>::value>(std::declval()))){ + return std::get::type>::value>(std::forward(settings)); } -namespace detail{ - template<> - struct get_ret_type{ - using type = ::indicators::option::BarWidth; - }; +} - template<> get_ret_type::type - get(){ - return indicators::option::BarWidth{100}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::PrefixText; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::PrefixText{}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::PostfixText; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::PostfixText{}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::Start; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::Start{"["}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::Fill; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::Fill{"="}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::Lead; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::Lead{">"}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::Remainder; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::Remainder{" "}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::End; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::End{"]"}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::MaxPostfixTextLen; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::MaxPostfixTextLen{0}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::Completed; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::Completed{false}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::ShowPercentage; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::ShowPercentage{false}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::ShowElapsedTime; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::ShowElapsedTime{false}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::ShowRemainingTime; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::ShowRemainingTime{false}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::SavedStartTime; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::SavedStartTime{false}; - } - - template<> - struct get_ret_type{ - using type = ::indicators::option::ForegroundColor; - }; - - template<> get_ret_type::type - get(){ - return indicators::option::ForegroundColor{::indicators::Color::WHITE}; - } +namespace option{ + using BarWidth = details::IntegerSetting; + using PrefixText = details::StringSetting; + using PostfixText = details::StringSetting; + using Start = details::StringSetting; + using End = details::StringSetting; + using Fill = details::StringSetting; + using Lead = details::StringSetting; + using Remainder = details::StringSetting; + using MaxPostfixTextLen = details::IntegerSetting; + using Completed = details::BooleanSetting; + using ShowPercentage = details::BooleanSetting; + using ShowElapsedTime = details::BooleanSetting; + using ShowRemainingTime = details::BooleanSetting; + using SavedStartTime = details::BooleanSetting; + using ForegroundColor = details::Setting; + using SpinnerShow = details::BooleanSetting; + using SpinnerStates = details::Setting, details::ProgressBarOption::spinner_states>; } } \ No newline at end of file diff --git a/samples/progress_spinner.cpp b/samples/progress_spinner.cpp index 37de709..5b571e7 100644 --- a/samples/progress_spinner.cpp +++ b/samples/progress_spinner.cpp @@ -5,22 +5,21 @@ int main() { // Hide cursor std::cout << "\e[?25l"; - indicators::ProgressSpinner spinner; - - // Configure the spinner - spinner.set_postfix_text("Checking credentials"); - spinner.set_foreground_color(indicators::Color::YELLOW); - spinner.set_spinner_states({"⠈", "⠐", "⠠", "⢀", "⡀", "⠄", "⠂", "⠁"}); + indicators::ProgressSpinner spinner{ + indicators::option::PostfixText{"Checking credentials"}, + indicators::option::ForegroundColor{indicators::Color::YELLOW}, + indicators::option::SpinnerStates{std::vector{"⠈", "⠐", "⠠", "⢀", "⡀", "⠄", "⠂", "⠁"}}, + }; // Update spinner state auto job = [&spinner]() { while (true) { if (spinner.is_completed()) { - spinner.set_foreground_color(indicators::Color::GREEN); - spinner.set_prefix_text("✔"); - spinner.hide_spinner(); - spinner.hide_percentage(); - spinner.set_postfix_text("Authenticated!"); + spinner.set_option(indicators::option::ForegroundColor{indicators::Color::GREEN}); + spinner.set_option(indicators::option::PrefixText{"✔"}); + spinner.set_option(indicators::option::SpinnerShow{false}); + spinner.set_option(indicators::option::ShowPercentage{false}); + spinner.set_option(indicators::option::PostfixText{"Authenticated!"}); spinner.mark_as_completed(); break; } else