#include "progress.hpp" #include #include #ifdef _WIN32 #include #include #include #define cout std::wcout using string = std::wstring; #else // UNIX #include #define cout std::cout #define TEXT( a ) a using string = std::string; #endif // UNIX #ifdef WIN32 size_t getTermWidth() { CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &csbi ); return csbi.srWindow.Right - csbi.srWindow.Left + 1; } #else size_t getTermWidth() { struct winsize w; ioctl( 0, TIOCGWINSZ, &w ); return w.ws_col; } #endif #ifdef WIN32 void home( size_t /*UNUSED*/ ) { static HANDLE h = NULL; while ( !h ) h = GetStdHandle( STD_OUTPUT_HANDLE ); CONSOLE_SCREEN_BUFFER_INFO info; GetConsoleScreenBufferInfo( h, &info ); COORD c = { 0, info.dwCursorPosition.Y - 1 }; SetConsoleCursorPosition( h, c ); } #else void home( size_t width ) { cout << "\x1b[" << width << "D"; } #endif size_t getNum( size_t width, int perc ) { return ( width * perc ) / 100; } void ProgressBar::print( int perc ) { auto width = getTermWidth(); home( width ); auto count = getNum( width - 7, perc ); cout << "[" << string( count, TEXT( '=' ) ).c_str(); if ( perc != 100 ) { int wc = width - 8 - count; if ( wc < 0 ) wc = 0; cout << ">" << string( wc, TEXT( ' ' ) ).c_str(); } cout << "] "; if ( perc / 10 == 0 ) cout << " "; else if ( perc / 100 == 0 ) cout << " "; cout << perc << "%" << std::flush; }