├── .gitignore ├── LICENSE ├── README.md ├── indicators.hpp └── previews ├── 0.gif ├── 1.gif ├── 2.gif ├── 3.gif ├── 4.gif ├── 5.gif └── 6.gif /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | .vscode 3 | .vs 4 | *.o 5 | *.pdb -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 iAmir (Amir Ahmady) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cpp-indicators 2 | 3 | A very simple, easy-to-use, and single-header-only C++ library for console based indicators (loading spinners) 4 | 5 | ## Pre-made frames (indicator types) 6 | | Type | Preview | 7 | |------|--------------------------------------------------------------------------------------------------| 8 | | 0 | ![ScreenShot](https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/master/previews/0.gif) | 9 | | 1 | ![ScreenShot](https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/master/previews/1.gif) | 10 | | 2 | ![ScreenShot](https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/master/previews/2.gif) | 11 | | 3 | ![ScreenShot](https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/master/previews/3.gif) | 12 | | 4 | ![ScreenShot](https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/master/previews/4.gif) | 13 | | 5 | ![ScreenShot](https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/master/previews/5.gif) | 14 | | 6 | ![ScreenShot](https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/master/previews/6.gif) | 15 | 16 | ## Examples 17 | 18 | ### Basic usage: 19 | 20 | ```cpp 21 | #include 22 | #include 23 | #include "indicators.hpp" 24 | using namespace std::chrono; 25 | 26 | int main() 27 | { 28 | auto spin = std::make_unique(200ms, 0); 29 | spin->start(); 30 | std::this_thread::sleep_for(std::chrono::milliseconds(5000)); 31 | spin->stop(); 32 | return 0; 33 | } 34 | ``` 35 | 36 | 37 | ### Including prefix, suffix, and final message: 38 | 39 | ```cpp 40 | #include 41 | #include 42 | #include "indicators.hpp" 43 | using namespace std::chrono; 44 | 45 | int main() 46 | { 47 | auto spin = std::make_unique(200ms, 0, "Finished loading some data", "Process info: ", " Loading data..."); 48 | spin->start(); 49 | std::this_thread::sleep_for(std::chrono::milliseconds(5000)); 50 | spin->stop(); 51 | return 0; 52 | } 53 | ``` 54 | 55 | You can decide if you want to hide the loading line after process or keep it 56 | by setting `hide_on_end` parameter to `true` or `false` in `indicator` constructor. Example: 57 | ```cpp 58 | // this hides loading line after process 59 | auto spin = std::make_unique(200ms, 0, "Finished loading some data", "Process info: ", " Loading data...", true); 60 | 61 | // this keeps the loading line 62 | auto spin = std::make_unique(200ms, 0, "Finished loading some data", "Process info: ", " Loading data...", false); 63 | ``` 64 | 65 | ### Indicator with custom frames 66 | 67 | ```cpp 68 | std::vector custom_indicator = 69 | {"aaaaa", "aaaa ", "aaa ", "aa ", "a ", " ", "aa ", "aaa ", "aaaa ", "aaaaa", " aaaa", " aaa", " aa", " a", " ", " aa", " aaa", " aaaa"}; 70 | auto spin = std::make_unique(100ms, 0, "Final msg", "prefix", "suffix", false, custom_indicator); 71 | ``` 72 | 73 | ### Changes during the process 74 | 75 | You can change prefix, suffix, and final message during the indicator process as well, not just on initialization. 76 | Or even changing the timer interval (delay value). Example: 77 | (it can be useful for stuff like downloading files or something that needs updating messages like pecent or speed) 78 | ```cpp 79 | auto spin = std::make_unique(200ms, 0); 80 | spin->start(); 81 | spin->set_suffix(" Downloading files..."); 82 | spin->set_prefix("Download info: "); 83 | spin->set_end_msg("Okay seems like we're done"); 84 | spin->set_delay(500ms); 85 | ``` -------------------------------------------------------------------------------- /indicators.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * cpp-indicators - iAmir (Amir Ahmady) (C) 2020 3 | * file name: indicators.hpp 4 | */ 5 | 6 | #ifndef __CPP_INDICATORS_ 7 | #define __CPP_INDICATORS_ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace indicator 17 | { 18 | 19 | using namespace std::chrono; 20 | 21 | std::vector> IndicatorFrames = { 22 | {"|", "/", "-", "\\"}, 23 | {"+", "x"}, 24 | {"v", "<", "^", ">"}, 25 | {"( o )", "( o )", "( o )", "( o )", "( o)", "( o )", "( o )", "( o )", "( o )"}, 26 | {">))'> ", " >))'> ", " >))'> ", " >))'> ", " >))'>", " <'((<", " <'((< ", " <'((< ", " <'((< ", "<'((< "}, 27 | {" o o o o o", "o o o o o", "o o o o o", "o o o o o", "o o o o o", "o o o o o ", "o o o o o o"}, 28 | {"::|\\____________::", "::_|\\___________::", "::__|\\__________::", "::___|\\_________::", "::____|\\________::", "::_____|\\_______::", "::______|\\______::", "::_______|\\_____::", "::________|\\____::", "::_________|\\___::", "::__________|\\__::", "::___________|\\_::", "::____________|\\::", "::____________/|::", "::___________/|_::", "::__________/|__::", "::_________/|___::", "::________/|____::", "::_______/|_____::", "::______/|______::", "::_____/|_______::", "::____/|________::", "::___/|_________::", "::__/|__________::", "::_/|___________::", "::/|____________::"}, 29 | }; 30 | 31 | class indicator 32 | { 33 | public: 34 | indicator(const duration &delay = 200ms, 35 | int type = 0, 36 | const std::string &endmsg = "", 37 | const std::string &prefix = "", 38 | const std::string &suffix = "", 39 | bool hide_on_end = false, 40 | const std::vector &custom_frames = {}) : frame_delay(delay), 41 | type(type), 42 | endmsg(endmsg), 43 | prefix(prefix), 44 | suffix(suffix), 45 | hide_on_end(hide_on_end), 46 | custom_frames(custom_frames), 47 | is_active(false) 48 | { 49 | } 50 | 51 | ~indicator() 52 | { 53 | stop(); 54 | } 55 | 56 | void start() 57 | { 58 | is_active = true; 59 | std::cout.flush(); 60 | last_text_size = 0; 61 | if (type >= IndicatorFrames.size()) 62 | type = 0; 63 | 64 | thread = std::thread([&]() { 65 | unsigned int c = 0; 66 | const std::vector &frames = (custom_frames.size() > 0) ? custom_frames 67 | : IndicatorFrames[type]; 68 | int l = frames.size(); 69 | 70 | while (is_active) 71 | { 72 | const std::string &frame = frames[c % l]; 73 | ++c; 74 | std::cout << "\r" << prefix << frame << suffix; 75 | last_text_size = prefix.length() + frame.length() + suffix.length(); 76 | std::cout.flush(); 77 | std::this_thread::sleep_for(frame_delay); 78 | } 79 | }); 80 | } 81 | 82 | void stop() 83 | { 84 | if (is_active) 85 | { 86 | is_active = false; 87 | thread.join(); 88 | if (endmsg.size() > 0) 89 | { 90 | if (hide_on_end) 91 | { 92 | std::cout << "\r" << std::string(last_text_size, ' '); 93 | std::cout << "\r" 94 | << " - " << endmsg << std::endl; 95 | } 96 | else 97 | { 98 | std::cout << "\n" 99 | << " - " << endmsg << std::endl; 100 | } 101 | } 102 | std::cout.flush(); 103 | } 104 | } 105 | 106 | void set_frame_delay(const duration &delay) 107 | { 108 | frame_delay = delay; 109 | } 110 | 111 | void set_prefix(const std::string &string) 112 | { 113 | prefix = string; 114 | } 115 | 116 | void set_suffix(const std::string &string) 117 | { 118 | suffix = string; 119 | } 120 | 121 | void set_end_msg(const std::string &string) 122 | { 123 | endmsg = string; 124 | } 125 | 126 | private: 127 | duration frame_delay; 128 | std::string prefix; 129 | std::string suffix; 130 | std::vector custom_frames; 131 | unsigned char type; 132 | std::string endmsg; 133 | unsigned int last_text_size; 134 | bool hide_on_end; 135 | bool is_active; 136 | std::thread thread; 137 | }; 138 | } // namespace indicator 139 | 140 | #endif -------------------------------------------------------------------------------- /previews/0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/be7816dc5dac5e93cf53621a084563e7ccf73f3e/previews/0.gif -------------------------------------------------------------------------------- /previews/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/be7816dc5dac5e93cf53621a084563e7ccf73f3e/previews/1.gif -------------------------------------------------------------------------------- /previews/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/be7816dc5dac5e93cf53621a084563e7ccf73f3e/previews/2.gif -------------------------------------------------------------------------------- /previews/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/be7816dc5dac5e93cf53621a084563e7ccf73f3e/previews/3.gif -------------------------------------------------------------------------------- /previews/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/be7816dc5dac5e93cf53621a084563e7ccf73f3e/previews/4.gif -------------------------------------------------------------------------------- /previews/5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/be7816dc5dac5e93cf53621a084563e7ccf73f3e/previews/5.gif -------------------------------------------------------------------------------- /previews/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AmyrAhmady/cpp-indicators/be7816dc5dac5e93cf53621a084563e7ccf73f3e/previews/6.gif --------------------------------------------------------------------------------