libscterm/src/utils.cpp
2022-11-01 09:52:22 +01:00

78 lines
2.0 KiB
C++

#include "utils.hpp"
#include <libscerror.hpp>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <string>
#include <stdexcept>
#include "iomanip.hpp"
using namespace sc;
term::term(int fd) {
if (isatty(fd)) {
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 _ws.ws_row;
}
int term::cols() const {
return _ws.ws_col;
}
void term::progress(int prefixlen,
const std::string& prefix,
double cur,
double total) const
{
// 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 (cur > total) cur = total;
int perclen = 5;
int barwidth = cols() - perclen - prefixlen - 1;
int maxsteps = barwidth * 8;
int steps = round(cur * maxsteps / total);
int perc = round(100 * cur / total);
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 << '%';
}
// ------------------------------------------------------------------------
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;
}