Files
libscterm/src/utils.cpp

91 lines
2.4 KiB
C++

#include <unistd.h>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <string>
#include <libscerror.hpp>
#include "utils.hpp"
#include "iomanip.hpp"
using namespace sc;
term::term(int fd) {
_isatty = isatty(fd);
if (_isatty) {
throw_if_min1(ioctl(fd, TIOCGWINSZ, &_ws));
}
switch (fd) {
case STDOUT_FILENO: _out = &std::cout; break;
case STDERR_FILENO: _out = &std::cerr; break;
default: break;
}
}
int term::rows() const {
return _isatty ? _ws.ws_row : 0;
}
int term::cols() const {
return _isatty ? _ws.ws_col : 0;
}
void term::progress(int prefixlen,
const std::string& prefix,
double cur,
double total) const
{
progress(prefixlen, prefix, cur / total);
}
void term::progress(int prefixlen, const std::string& prefix, double fraction) const {
if (!_isatty) return;
// use unicode to make nice bar
const char* bar[8] = {
u8"\u258F", u8"\u258E", u8"\u258D", u8"\u258C",
u8"\u258B", u8"\u258A", u8"\u2589", u8"\u2588"
};
if (fraction > 1) fraction = 1.0;
int perclen = 5;
int barwidth = cols() - perclen - prefixlen - 1;
int maxsteps = barwidth * 8;
int steps = round(fraction * maxsteps);
int perc = round(100 * fraction);
int fill_len = barwidth - steps / 8;
*_out << '\r' << std::setw(prefixlen) << prefix.substr(0, prefixlen) << ' ' << io::grayf(8);
for (int i = 0; i < steps / 8; ++i) {
*_out << bar[7];
}
if (steps % 8) {
*_out << bar[steps % 8 - 1];
fill_len--;
}
*_out << io::reset << std::string(fill_len, ' ');
*_out << ' ' << std::setw(3) << perc << '%';
}
bool term::has_truecolor() {
char* tc = getenv("COLORTERM");
std::string colorterm {tc ? tc : ""};
return colorterm.size() > 0 && (colorterm == "truecolor" || colorterm == "24bit");
}
// ------------------------------------------------------------------------
cursor_hider::cursor_hider(std::ostream* out) : _out {out} {
*_out << io::hide_cursor;
}
cursor_hider::~cursor_hider() {
*_out << io::show_cursor;
}
// ------------------------------------------------------------------------
sc::io::clear_line::clear_line(const term& t) : _term {t} {}
std::ostream& sc::io::operator<<(std::ostream& out, const sc::io::clear_line& obj) {
out << '\r' << std::string(obj._term.cols(), ' ') << '\r';
return out;
}