Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.12")
project(indicators VERSION 2.3.0 LANGUAGES CXX
HOMEPAGE_URL "https://github.com/p-ranav/indicators"
DESCRIPTION "Activity Indicators for Modern C++")
cmake_minimum_required(VERSION 3.12)
elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.9")
project(indicators VERSION 2.3.0 LANGUAGES CXX
DESCRIPTION "Activity Indicators for Modern C++")
Expand Down
30 changes: 20 additions & 10 deletions include/indicators/cursor_control.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

#ifndef INDICATORS_CURSOR_CONTROL
#define INDICATORS_CURSOR_CONTROL

Expand All @@ -12,12 +11,14 @@
#include <cstdio>
#endif

#include "terminal_size.hpp"

namespace indicators {

#if defined(_MSC_VER)

static inline void show_console_cursor(bool const show) {
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
static inline void show_console_cursor(bool const show, TerminalHandle hndl = TerminalHandle::StdOut) {
HANDLE out = GetStdHandle(os_handle(hndl));

CONSOLE_CURSOR_INFO cursorInfo;

Expand All @@ -26,8 +27,8 @@ static inline void show_console_cursor(bool const show) {
SetConsoleCursorInfo(out, &cursorInfo);
}

static inline void erase_line() {
auto hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
static inline void erase_line(TerminalHandle hndl = TerminalHandle::StdOut) {
auto hStdout = GetStdHandle(os_handle(hndl));
if (!hStdout)
return;

Expand All @@ -51,16 +52,25 @@ static inline void erase_line() {

#else

static inline void show_console_cursor(bool const show) {
std::fputs(show ? "\033[?25h" : "\033[?25l", stdout);
static inline FILE* os_stream(TerminalHandle hndl)
{
switch (hndl) {
case TerminalHandle::StdOut: return stdout;
case TerminalHandle::StdErr: return stderr;
}
return stdout;
}

static inline void erase_line() {
std::fputs("\r\033[K", stdout);
static inline void show_console_cursor(bool const show, TerminalHandle hndl = TerminalHandle::StdOut) {
std::fputs(show ? "\033[?25h" : "\033[?25l", os_stream(hndl));
}

static inline void erase_line(TerminalHandle hndl = TerminalHandle::StdOut) {
std::fputs("\r\033[K", os_stream(hndl));
}

#endif

} // namespace indicators

#endif
#endif
6 changes: 3 additions & 3 deletions include/indicators/display_width.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ namespace details {
*/

struct interval {
int first;
int last;
wchar_t first;
wchar_t last;
};

/* auxiliary function for binary search in interval table */
Expand Down Expand Up @@ -356,4 +356,4 @@ static inline int display_width(const std::wstring &input) {

} // namespace unicode

#endif
#endif
14 changes: 10 additions & 4 deletions include/indicators/progress_bar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class ProgressBar {
option::ProgressType{ProgressType::incremental},
std::forward<Args>(args)...),
details::get<details::ProgressBarOption::stream>(
option::Stream{std::cout}, std::forward<Args>(args)...)) {
option::Stream{TerminalHandle::StdOut}, std::forward<Args>(args)...)) {

// if progress is incremental, start from min_progress
// else start from max_progress
Expand Down Expand Up @@ -278,12 +278,18 @@ class ProgressBar {
const auto result_size = unicode::display_width(result);
return {result, result_size};
}
private:
std::ostream& as_stream(TerminalHandle hndl) {
if (hndl == TerminalHandle::StdOut) { return std::cout; }
return std::cerr;
}

public:
void print_progress(bool from_multi_progress = false) {
std::lock_guard<std::mutex> lock{mutex_};

auto &os = get_value<details::ProgressBarOption::stream>();
auto stream_type = get_value<details::ProgressBarOption::stream>();
auto &os = as_stream(stream_type);

const auto type = get_value<details::ProgressBarOption::progress_type>();
const auto min_progress =
Expand Down Expand Up @@ -335,7 +341,7 @@ class ProgressBar {
const auto start_length = get_value<details::ProgressBarOption::start>().size();
const auto bar_width = get_value<details::ProgressBarOption::bar_width>();
const auto end_length = get_value<details::ProgressBarOption::end>().size();
const auto terminal_width = terminal_size().second;
const auto terminal_width = terminal_size(stream_type).second;
// prefix + bar_width + postfix should be <= terminal_width
const int remaining = terminal_width - (prefix_length + start_length + bar_width + end_length + postfix_length);
if (prefix_length == -1 || postfix_length == -1) {
Expand All @@ -359,4 +365,4 @@ class ProgressBar {

} // namespace indicators

#endif
#endif
6 changes: 4 additions & 2 deletions include/indicators/setting.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ SOFTWARE.
#include <indicators/color.hpp>
#include <indicators/font_style.hpp>
#include <indicators/progress_type.hpp>
#include <indicators/terminal_size.hpp>
#include <string>
#include <tuple>
#include <type_traits>
Expand Down Expand Up @@ -215,8 +216,9 @@ using FontStyles =
using MinProgress = details::IntegerSetting<details::ProgressBarOption::min_progress>;
using MaxProgress = details::IntegerSetting<details::ProgressBarOption::max_progress>;
using ProgressType = details::Setting<ProgressType, details::ProgressBarOption::progress_type>;
using Stream = details::Setting<std::ostream &, details::ProgressBarOption::stream>;

using Stream = details::Setting<TerminalHandle, details::ProgressBarOption::stream>;
} // namespace option
} // namespace indicators

#endif
#endif
39 changes: 31 additions & 8 deletions include/indicators/terminal_size.hpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,37 @@

#ifndef INDICATORS_TERMINAL_SIZE
#define INDICATORS_TERMINAL_SIZE
#include <utility>

namespace indicators {
enum class TerminalHandle {
StdOut, StdErr
};
};

#if defined(_WIN32)
#include <windows.h>

namespace indicators {

static inline std::pair<size_t, size_t> terminal_size() {
static inline DWORD os_handle(TerminalHandle hndl)
{
switch (hndl) {
case TerminalHandle::StdOut: return STD_OUTPUT_HANDLE;
case TerminalHandle::StdErr: return STD_ERROR_HANDLE;
}
return STD_OUTPUT_HANDLE;
}

static inline std::pair<size_t, size_t> terminal_size(TerminalHandle hndl) {
CONSOLE_SCREEN_BUFFER_INFO csbi;
int cols, rows;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
GetConsoleScreenBufferInfo(GetStdHandle(os_handle(hndl)), &csbi);
cols = csbi.srWindow.Right - csbi.srWindow.Left + 1;
rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
return {static_cast<size_t>(rows), static_cast<size_t>(cols)};
}

static inline size_t terminal_width() { return terminal_size().second; }
static inline size_t terminal_width(TerminalHandle hndl) { return terminal_size(hndl).second; }

} // namespace indicators

Expand All @@ -29,16 +42,26 @@ static inline size_t terminal_width() { return terminal_size().second; }

namespace indicators {

static inline std::pair<size_t, size_t> terminal_size() {
static inline int os_handle(TerminalHandle hndl)
{
switch (hndl) {
case TerminalHandle::StdOut: return STDOUT_FILENO;
case TerminalHandle::StdErr: return STDERR_FILENO;
}
return STDOUT_FILENO;
}


static inline std::pair<size_t, size_t> terminal_size(TerminalHandle hndl) {
struct winsize size{};
ioctl(STDOUT_FILENO, TIOCGWINSZ, &size);
ioctl(os_handle(hndl), TIOCGWINSZ, &size);
return {static_cast<size_t>(size.ws_row), static_cast<size_t>(size.ws_col)};
}

static inline size_t terminal_width() { return terminal_size().second; }
static inline size_t terminal_width(TerminalHandle hndl) { return terminal_size(hndl).second; }

} // namespace indicators

#endif

#endif
#endif
4 changes: 2 additions & 2 deletions single_include/indicators/indicators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1415,8 +1415,8 @@ namespace details {
*/

struct interval {
int first;
int last;
wchar_t first;
wchar_t last;
};

/* auxiliary function for binary search in interval table */
Expand Down