18 Commits
v1.0 ... v1.1

Author SHA1 Message Date
Pranav Srinivas Kumar
2edbccce9c Updated README 2019-12-16 09:31:10 -06:00
Pranav
e6ae6c5513 Update README.md 2019-12-16 09:29:19 -06:00
Pranav Srinivas Kumar
1c2e7d5bd1 Updated README 2019-12-16 09:28:55 -06:00
Pranav Srinivas Kumar
b6d0ec0ee0 Updated README 2019-12-16 09:26:49 -06:00
Pranav Srinivas Kumar
cb879b5eb1 Added block progress bar GIF 2019-12-16 09:24:22 -06:00
Pranav
25001ceb1f Merge pull request #8 from p-ranav/feature/block_progress_bar
Feature/block progress bar
2019-12-16 09:12:37 -06:00
Pranav Srinivas Kumar
21391f3ca0 Added sample for smooth block progress bar 2019-12-16 09:11:25 -06:00
Pranav Srinivas Kumar
55f9eb7c67 Updated smooth block progress bar update logic 2019-12-16 09:07:57 -06:00
Pranav Srinivas Kumar
a516957135 Draft implementation of smooth block progress bar 2019-12-16 08:48:42 -06:00
Pranav
56489bf37a Merge pull request #6 from myd7349/fix-headers-installation
Improve CMakeLists.txt
2019-12-14 07:00:42 -06:00
myd7349
8f903b9741 Improve CMakeLists.txt
- Fix headers installation;
- Handle Threads dependency automatically;
2019-12-14 18:21:40 +08:00
Pranav
a938eb8f4c Update progress_spinner.hpp 2019-12-12 15:15:01 -06:00
Pranav
9e088af612 Update progress_bar.hpp 2019-12-12 15:14:38 -06:00
Pranav Srinivas KumaR
a41c7c118e Closes #2 2019-12-05 19:55:28 -06:00
Pranav Srinivas KumaR
cde4dbd83c Added termcolor LICENSE 2019-12-05 19:49:32 -06:00
Pranav
6f69ca5246 Update README.md 2019-12-05 15:56:17 -06:00
Pranav
d3ef0b0209 Update README.md 2019-12-05 15:55:55 -06:00
Pranav
3012fa78cf Update README.md 2019-12-05 12:59:23 -06:00
9 changed files with 334 additions and 16 deletions

View File

@@ -2,8 +2,11 @@ cmake_minimum_required(VERSION 3.8)
project(indica VERSION 1.0.0 LANGUAGES CXX)
option(INDICA_BUILD_TESTS OFF)
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)
find_package(Threads REQUIRED)
add_library(indica INTERFACE)
add_library(indica::indica ALIAS indica)
@@ -11,10 +14,20 @@ target_compile_features(indica INTERFACE cxx_std_11)
target_include_directories(indica INTERFACE
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>)
target_link_libraries(indica INTERFACE Threads::Threads)
install(TARGETS indica EXPORT indicaConfig)
install(EXPORT indicaConfig
configure_package_config_file(indicaConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/indicaConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/indica)
install(TARGETS indica EXPORT indicaTargets)
install(EXPORT indicaTargets
FILE indicaTargets.cmake
NAMESPACE indica::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/indica)
install(FILES ${CMAKE_CURRENT_LIST_DIR}/include/indica.hpp
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/indica)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/indicaConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/indica)
install(DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/include/indicators
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
USE_SOURCE_PERMISSIONS
PATTERN "*.hpp")

31
LICENSE.termcolor Normal file
View File

@@ -0,0 +1,31 @@
Copyright (c) 2013, Ihor Kalnytskyi.
All rights reserved.
Redistribution and use in source and binary forms of the software as well
as documentation, with or without modification, are permitted provided
that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* The names of the contributors may not be used to endorse or
promote products derived from this software without specific
prior written permission.
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

View File

@@ -127,19 +127,28 @@ int main() {
bar.set_foreground_color(indicators::Color::GREEN);
// Update bar state
size_t i = 0;
while (i < 101) {
bar.set_progress(i);
bar.set_progress(10); // 10% done
// do some work
std::this_thread::sleep_for(std::chrono::milliseconds(100));
i += 10;
}
bar.set_progress(30); // 30% done
// do some more work
std::this_thread::sleep_for(std::chrono::milliseconds(600));
bar.set_progress(65); // 65% done
// do final bit of work
std::this_thread::sleep_for(std::chrono::milliseconds(300));
bar.set_progress(100); // all done
return 0;
}
```
The above code will print a progress bar that goes from 0 to 100% at the rate of 10% every 100 ms.
## Multi-threaded Example
```cpp
@@ -208,7 +217,48 @@ int main() {
}
```
For more examples, checkout the examples in the `samples/` directory.
# Smooth Block Progress Bar
Are you in need of a smooth block progress bar using [unicode block elements](https://en.wikipedia.org/wiki/Block_Elements)? Use `BlockProgressBar` instead of `ProgressBar`. Thanks to [this blog post](https://mike42.me/blog/2018-06-make-better-cli-progress-bars-with-unicode-block-characters) for making `BlockProgressBar` an easy addition to the library.
<p align="center">
<img height="70" src="img/block_progress_bar.gif"/>
</p>
```cpp
#include <indicators/block_progress_bar.hpp>
#include <thread>
#include <chrono>
int main() {
// Hide cursor
std::cout << "\e[?25l";
indicators::BlockProgressBar bar;
// Configure the bar
bar.set_bar_width(80);
bar.start_bar_with("[");
bar.end_bar_with("]");
bar.set_foreground_color(indicators::Color::WHITE);
// Update bar state
auto progress = 0.0f;
while (true) {
bar.set_progress(progress);
progress += 0.25f;
if (bar.is_completed())
break;
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
// Show cursor
std::cout << "\e[?25h";
return 0;
}
```
# Progress Spinner

BIN
img/block_progress_bar.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -0,0 +1,183 @@
/*
Activity Indicators for Modern C++
https://github.com/p-ranav/indicators
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
SPDX-License-Identifier: MIT
Copyright (c) 2019 Pranav Srinivas Kumar <pranav.srinivas.kumar@gmail.com>.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#include <algorithm>
#include <atomic>
#include <indicators/color.hpp>
#include <iostream>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
#include <cmath>
namespace indicators {
class BlockProgressBar {
public:
void set_foreground_color(Color color) {
std::unique_lock<std::mutex> lock{_mutex};
_foreground_color = color;
}
void set_bar_width(size_t bar_width) {
std::unique_lock<std::mutex> lock{_mutex};
_bar_width = bar_width;
}
void start_bar_with(const std::string &start) {
std::unique_lock<std::mutex> lock{_mutex};
_start = start;
}
void end_bar_with(const std::string &end) {
std::unique_lock<std::mutex> lock{_mutex};
_end = end;
}
void set_prefix_text(const std::string &text) {
std::unique_lock<std::mutex> lock{_mutex};
_prefix_text = text;
}
void set_postfix_text(const std::string &text) {
std::unique_lock<std::mutex> lock{_mutex};
_postfix_text = text;
if (_postfix_text.length() > _max_postfix_text_length)
_max_postfix_text_length = _postfix_text.length();
}
void show_percentage() { _show_percentage = true; }
void hide_percentage() { _show_percentage = false; }
void set_progress(float value) {
{
std::unique_lock<std::mutex> lock{_mutex};
_progress = value;
}
_print_progress();
}
void tick() {
{
std::unique_lock<std::mutex> lock{_mutex};
_progress += 1;
}
_print_progress();
}
size_t current() {
return std::min(static_cast<size_t>(_progress), size_t(100));
}
bool is_completed() const { return _completed; }
void mark_as_completed() {
_completed = true;
_print_progress();
}
private:
float _progress{0.0};
size_t _bar_width{100};
std::string _prefix_text{""};
std::string _start{"["};
std::string _fill{""};
std::string _lead{" "};
std::string _remainder{" "};
std::string _end{"]"};
std::string _postfix_text{""};
std::atomic<size_t> _max_postfix_text_length{0};
std::atomic<bool> _completed{false};
std::atomic<bool> _show_percentage{true};
std::mutex _mutex;
Color _foreground_color;
void _print_progress() {
std::unique_lock<std::mutex> lock{_mutex};
std::cout << termcolor::bold;
switch (_foreground_color) {
case Color::GREY:
std::cout << termcolor::grey;
break;
case Color::RED:
std::cout << termcolor::red;
break;
case Color::GREEN:
std::cout << termcolor::green;
break;
case Color::YELLOW:
std::cout << termcolor::yellow;
break;
case Color::BLUE:
std::cout << termcolor::blue;
break;
case Color::MAGENTA:
std::cout << termcolor::magenta;
break;
case Color::CYAN:
std::cout << termcolor::cyan;
break;
case Color::WHITE:
std::cout << termcolor::white;
break;
}
std::cout << _prefix_text;
std::cout << _start;
std::vector<std::string> lead_characters{" ", "", "", "", "", "", "", ""};
auto progress = std::min(1.0f, std::max(0.0f, _progress / 100.0f));
auto whole_width = std::floor(progress * _bar_width);
auto remainder_width = fmod((progress * _bar_width), 1.0f);
auto part_width = std::floor(remainder_width * lead_characters.size());
_lead = lead_characters[part_width];
if ((_bar_width - whole_width - 1) < 0)
_lead = "";
for (size_t i = 0; i < whole_width; ++i)
std::cout << _fill;
std::cout << _lead;
for (size_t i = 0; i < (_bar_width - whole_width - 1); ++i)
std::cout << " ";
std::cout << _end;
if (_show_percentage) {
std::cout << " " << std::min(static_cast<size_t>(_progress), size_t(100)) << "%";
}
if (_max_postfix_text_length == 0)
_max_postfix_text_length = 10;
std::cout << " " << _postfix_text << std::string(_max_postfix_text_length, ' ') << "\r";
std::cout.flush();
if (_progress > 100.0) {
_completed = true;
}
if (_completed)
std::cout << termcolor::reset << std::endl;
}
};
} // namespace indicators

View File

@@ -25,6 +25,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#include <algorithm>
#include <atomic>
#include <indicators/color.hpp>
#include <iostream>
@@ -104,7 +105,6 @@ public:
}
size_t current() {
std::unique_lock<std::mutex> lock{_mutex};
return std::min(static_cast<size_t>(_progress), size_t(100));
}

View File

@@ -25,6 +25,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#pragma once
#include <algorithm>
#include <atomic>
#include <indicators/color.hpp>
#include <iostream>
@@ -79,7 +80,6 @@ public:
}
size_t current() {
std::unique_lock<std::mutex> lock{_mutex};
return std::min(static_cast<size_t>(_progress), size_t(100));
}

9
indicaConfig.cmake.in Normal file
View File

@@ -0,0 +1,9 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependency(Threads)
if (NOT TARGET indica::indica)
include(${CMAKE_CURRENT_LIST_DIR}/indicaTargets.cmake)
endif ()

View File

@@ -0,0 +1,32 @@
#include <indicators/block_progress_bar.hpp>
#include <thread>
#include <chrono>
int main() {
// Hide cursor
std::cout << "\e[?25l";
indicators::BlockProgressBar bar;
// Configure the bar
bar.set_bar_width(80);
bar.start_bar_with("[");
bar.end_bar_with("]");
bar.set_foreground_color(indicators::Color::WHITE);
// Update bar state
auto progress = 0.0f;
while (true) {
bar.set_progress(progress);
progress += 0.25f;
if (bar.is_completed())
break;
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
// Show cursor
std::cout << "\e[?25h";
return 0;
}