From ad5cf841be2d437c75e92c38f8ac2eb8e16c62c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20G=C3=BCndling?= Date: Sat, 25 Apr 2020 08:49:30 +0200 Subject: [PATCH 1/3] cursor movement and cursor hiding support for windows --- include/indicators/cursor_control.hpp | 43 ++++++++++++++++++++++++ include/indicators/cursor_movement.hpp | 46 ++++++++++++++++++++++++++ include/indicators/multi_progress.hpp | 7 ++-- samples/multi_progress_bar.cpp | 5 +++ 4 files changed, 98 insertions(+), 3 deletions(-) create mode 100755 include/indicators/cursor_control.hpp create mode 100755 include/indicators/cursor_movement.hpp diff --git a/include/indicators/cursor_control.hpp b/include/indicators/cursor_control.hpp new file mode 100755 index 0000000..d962f5c --- /dev/null +++ b/include/indicators/cursor_control.hpp @@ -0,0 +1,43 @@ +#pragma once + +#if defined(_MSC_VER) +#if !defined(NOMINMAX) +#define NOMINMAX +#endif +#include +#include +#else +#include +#endif + +namespace indicators { + +#if defined(_MSC_VER) + +void enable_cursor_movement() { + auto hStdout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleMode(hStdout, + ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING); +} + +void show_console_cursor(bool const show) { + HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); + + CONSOLE_CURSOR_INFO cursorInfo; + + GetConsoleCursorInfo(out, &cursorInfo); + cursorInfo.bVisible = show; // set the cursor visibility + SetConsoleCursorInfo(out, &cursorInfo); +} + +#else + +void enable_cursor_movement() {} + +void show_console_cursor(bool const show) { + std::fputs(show ? "\e[?25h" : "\e[?25l", stdout); +} + +#endif + +} // namespace indicators \ No newline at end of file diff --git a/include/indicators/cursor_movement.hpp b/include/indicators/cursor_movement.hpp new file mode 100755 index 0000000..51bab30 --- /dev/null +++ b/include/indicators/cursor_movement.hpp @@ -0,0 +1,46 @@ +#pragma once + +#if defined(_MSC_VER) +#if !defined(NOMINMAX) +#define NOMINMAX +#endif +#include +#include +#else +#include +#endif + +namespace indicators { + +#ifdef _MSC_VER + +void move(int x, int y) { + auto hStdout = GetStdHandle(STD_OUTPUT_HANDLE); + if (!hStdout) + return; + + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo(hStdout, &csbiInfo); + + COORD cursor; + + cursor.X = csbiInfo.dwCursorPosition.X + x; + cursor.Y = csbiInfo.dwCursorPosition.Y + y; + SetConsoleCursorPosition(hStdout, cursor); +} + +void move_up(int lines) { move(0, -lines); } +void move_down(int lines) { move(0, -lines); } +void move_right(int cols) { move(cols, 0); } +void move_left(int cols) { move(-cols, 0); } + +#else + +void move_up(int lines) { std::cout << "x1b[" << lines << "A"; } +void move_down(int lines) { std::cout << "x1b[" << lines << "B"; } +void move_right(int cols) { std::cout << "x1b[" << cols << "C"; } +void move_left(int cols) { std::cout << "x1b[" << cols << "D"; } + +#endif + +} // namespace indicators \ No newline at end of file diff --git a/include/indicators/multi_progress.hpp b/include/indicators/multi_progress.hpp index 41c4e86..d2a210e 100644 --- a/include/indicators/multi_progress.hpp +++ b/include/indicators/multi_progress.hpp @@ -27,11 +27,13 @@ SOFTWARE. #pragma once #include #include -#include #include #include #include +#include +#include + namespace indicators { template class MultiProgress { @@ -86,8 +88,7 @@ private: void print_progress() { std::lock_guard lock{mutex_}; if (started_) - for (size_t i = 0; i < count; ++i) - std::cout << "\x1b[A"; + move_up(count); for (auto &bar : bars_) { bar.get().print_progress(true); std::cout << "\n"; diff --git a/samples/multi_progress_bar.cpp b/samples/multi_progress_bar.cpp index a457cab..4f8da20 100644 --- a/samples/multi_progress_bar.cpp +++ b/samples/multi_progress_bar.cpp @@ -1,7 +1,10 @@ #include #include +#include int main() { + indicators::enable_cursor_movement(); + indicators::show_console_cursor(false); indicators::ProgressBar bar1{indicators::option::BarWidth{50}, indicators::option::Start{"["}, @@ -81,5 +84,7 @@ int main() { second_job.join(); third_job.join(); + indicators::show_console_cursor(true); + return 0; } From d99cad1ede1e1dfe949e9671694879cf7a7f54c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20G=C3=BCndling?= Date: Sat, 25 Apr 2020 08:57:32 +0200 Subject: [PATCH 2/3] setting console mode to processed output not neccesary if we use SetConsoleCursorPosition --- include/indicators/cursor_control.hpp | 8 -------- samples/multi_progress_bar.cpp | 1 - 2 files changed, 9 deletions(-) diff --git a/include/indicators/cursor_control.hpp b/include/indicators/cursor_control.hpp index d962f5c..1d79726 100755 --- a/include/indicators/cursor_control.hpp +++ b/include/indicators/cursor_control.hpp @@ -14,12 +14,6 @@ namespace indicators { #if defined(_MSC_VER) -void enable_cursor_movement() { - auto hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - SetConsoleMode(hStdout, - ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING); -} - void show_console_cursor(bool const show) { HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE); @@ -32,8 +26,6 @@ void show_console_cursor(bool const show) { #else -void enable_cursor_movement() {} - void show_console_cursor(bool const show) { std::fputs(show ? "\e[?25h" : "\e[?25l", stdout); } diff --git a/samples/multi_progress_bar.cpp b/samples/multi_progress_bar.cpp index 4f8da20..c84e4bf 100644 --- a/samples/multi_progress_bar.cpp +++ b/samples/multi_progress_bar.cpp @@ -3,7 +3,6 @@ #include int main() { - indicators::enable_cursor_movement(); indicators::show_console_cursor(false); indicators::ProgressBar bar1{indicators::option::BarWidth{50}, From c2beb2ac2266bbea0e3790e073a374eac0e00c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20G=C3=83=C2=83=C3=82=C2=BCndling?= Date: Sun, 26 Apr 2020 18:28:46 +0200 Subject: [PATCH 3/3] adjust readme, demo, and examples: replace show/hide cursor calls --- README.md | 22 +++++++++++++++------- demo/demo.cpp | 8 +++++--- samples/block_progress_bar.cpp | 5 +++-- samples/multi_progress_bar.cpp | 4 ---- samples/progress_bar_set_progress.cpp | 5 +++-- samples/progress_spinner.cpp | 5 +++-- samples/time_meter.cpp | 6 +++++- 7 files changed, 34 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index e4147a3..a541966 100644 --- a/README.md +++ b/README.md @@ -110,14 +110,16 @@ If you'd rather control progress of the bar in discrete steps, consider using `b ```cpp #include +#include #include #include int main() { + using namespace indicators; // Hide cursor - std::cout << "\e[?25l"; - using namespace indicators; + show_console_cursor(false); + ProgressBar bar{ option::BarWidth{50}, option::Start{"["}, @@ -157,7 +159,7 @@ int main() { bar.mark_as_completed(); // Show cursor - std::cout << "\e[?25h"; + show_console_cursor(true); return 0; } @@ -173,11 +175,16 @@ All progress bars and spinners in `indicators` support showing time elapsed and ```cpp #include +#include #include #include int main() { using namespace indicators; + + // Hide cursor + show_console_cursor(false); + indicators::ProgressBar bar{ option::BarWidth{50}, option::Start{" ["}, @@ -201,7 +208,7 @@ int main() { } // Show cursor - std::cout << "\e[?25h"; + show_console_cursor(true); return 0; } @@ -222,10 +229,11 @@ Are you in need of a smooth block progress bar using [unicode block elements](ht int main() { - // Hide cursor - std::cout << "\e[?25l"; using namespace indicators; + // Hide cursor + show_console_cursor(false); + BlockProgressBar bar{ option::BarWidth{80}, option::Start{"["}, @@ -245,7 +253,7 @@ int main() { } // Show cursor - std::cout << "\e[?25h"; + show_console_cursor(true); return 0; } diff --git a/demo/demo.cpp b/demo/demo.cpp index eaa787c..91b9bda 100644 --- a/demo/demo.cpp +++ b/demo/demo.cpp @@ -1,12 +1,14 @@ #include #include +#include #include int main() { + using namespace indicators; // Hide cursor - std::cout << "\e[?25l"; - using namespace indicators; + show_console_cursor(false); + { // // PROGRESS BAR 1 @@ -312,7 +314,7 @@ int main() { } // Show cursor - std::cout << "\e[?25h"; + show_console_cursor(true); return 0; } diff --git a/samples/block_progress_bar.cpp b/samples/block_progress_bar.cpp index d21a4d7..75b12ca 100644 --- a/samples/block_progress_bar.cpp +++ b/samples/block_progress_bar.cpp @@ -1,11 +1,12 @@ #include #include +#include #include int main() { // Hide cursor - std::cout << "\e[?25l"; + indicators::show_console_cursor(false); indicators::BlockProgressBar bar{ indicators::option::BarWidth{80}, @@ -24,7 +25,7 @@ int main() { } // Show cursor - std::cout << "\e[?25h"; + indicators::show_console_cursor(true); return 0; } diff --git a/samples/multi_progress_bar.cpp b/samples/multi_progress_bar.cpp index c84e4bf..a457cab 100644 --- a/samples/multi_progress_bar.cpp +++ b/samples/multi_progress_bar.cpp @@ -1,9 +1,7 @@ #include #include -#include int main() { - indicators::show_console_cursor(false); indicators::ProgressBar bar1{indicators::option::BarWidth{50}, indicators::option::Start{"["}, @@ -83,7 +81,5 @@ int main() { second_job.join(); third_job.join(); - indicators::show_console_cursor(true); - return 0; } diff --git a/samples/progress_bar_set_progress.cpp b/samples/progress_bar_set_progress.cpp index bbfe325..2288b8e 100644 --- a/samples/progress_bar_set_progress.cpp +++ b/samples/progress_bar_set_progress.cpp @@ -1,11 +1,12 @@ #include +#include #include #include int main() { // Hide cursor - std::cout << "\e[?25l"; + indicators::show_console_cursor(false); indicators::ProgressBar bar{ indicators::option::BarWidth{50}, @@ -47,7 +48,7 @@ int main() { bar.mark_as_completed(); // Show cursor - std::cout << "\e[?25h"; + indicators::show_console_cursor(true); return 0; } diff --git a/samples/progress_spinner.cpp b/samples/progress_spinner.cpp index bbbe834..8808505 100644 --- a/samples/progress_spinner.cpp +++ b/samples/progress_spinner.cpp @@ -1,9 +1,10 @@ +#include #include int main() { // Hide cursor - std::cout << "\e[?25l"; + indicators::show_console_cursor(false); indicators::ProgressSpinner spinner{ indicators::option::PostfixText{"Checking credentials"}, @@ -34,7 +35,7 @@ int main() { thread.join(); // Show cursor - std::cout << "\e[?25h"; + indicators::show_console_cursor(true); return 0; } diff --git a/samples/time_meter.cpp b/samples/time_meter.cpp index e57c956..dcaae07 100644 --- a/samples/time_meter.cpp +++ b/samples/time_meter.cpp @@ -1,8 +1,12 @@ #include +#include #include #include int main() { + // Hide cursor + indicators::show_console_cursor(false); + indicators::ProgressBar bar{ indicators::option::BarWidth{50}, indicators::option::Start{" ["}, @@ -27,7 +31,7 @@ int main() { } // Show cursor - std::cout << "\e[?25h"; + indicators::show_console_cursor(true); return 0; }