Added color support and screen functions.
This commit is contained in:
parent
a593e0cc33
commit
5a968cdecf
4 changed files with 279 additions and 109 deletions
30
include/AnsiTerminal.hpp
Normal file
30
include/AnsiTerminal.hpp
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef H_AnsiTerminal
|
||||||
|
#define H_AnsiTerminal
|
||||||
|
|
||||||
|
// The following are UBUNTU/LINUX, and MacOS ONLY terminal color codes.
|
||||||
|
#define C_RESET "\033[0m" // Reset formatting
|
||||||
|
#define C_BOLD "\033[1m" // Bold font
|
||||||
|
#define C_UNDERLINE "\033[4m" // Underline font
|
||||||
|
#define C_INVERT_FG_BG "\033[7m" // Inverse background and foregroung colors
|
||||||
|
|
||||||
|
// Foreground
|
||||||
|
#define C_BLACK_F "\033[30m" // Black
|
||||||
|
#define C_RED_F "\033[31m" // Red
|
||||||
|
#define C_GREEN_F "\033[32m" // Green
|
||||||
|
#define C_YELLOW_F "\033[33m" // Yellow
|
||||||
|
#define C_BLUE_F "\033[34m" // Blue
|
||||||
|
#define C_MAGENTA_F "\033[35m" // Magenta
|
||||||
|
#define C_CYAN_F "\033[36m" // Cyan
|
||||||
|
#define C_WHITE_F "\033[37m" // White
|
||||||
|
|
||||||
|
// Background
|
||||||
|
#define C_BLACK_B "\033[40m" // Black
|
||||||
|
#define C_RED_B "\033[41m" // Red
|
||||||
|
#define C_GREEN_B "\033[42m" // Green
|
||||||
|
#define C_YELLOW_B "\033[43m" // Yellow
|
||||||
|
#define C_BLUE_B "\033[44m" // Blue
|
||||||
|
#define C_MAGENTA_B "\033[45m" // Magenta
|
||||||
|
#define C_CYAN_B "\033[46m" // Cyan
|
||||||
|
#define C_WHITE_B "\033[47m" // White
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -2,11 +2,14 @@
|
||||||
#define H_Display
|
#define H_Display
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <sys/ioctl.h> //ioctl() and TIOCGWINSZ
|
#include <sys/ioctl.h> //ioctl() and TIOCGWINSZ
|
||||||
#include <unistd.h> // for STDOUT_FILENO
|
#include <unistd.h> // for STDOUT_FILENO
|
||||||
|
|
||||||
|
#include <AnsiTerminal.hpp>
|
||||||
|
|
||||||
class Display
|
class Display
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -15,6 +18,27 @@ class Display
|
||||||
unsigned int Rows() const;
|
unsigned int Rows() const;
|
||||||
unsigned int Cols() const;
|
unsigned int Cols() const;
|
||||||
|
|
||||||
|
/// Returns a constant reference to a given line of the screen.
|
||||||
|
std::string const& GetLine(unsigned int i) const;
|
||||||
|
|
||||||
|
/// Sets the line i to str. /!\ Warning : the line will be truncated at its max length of Cols().
|
||||||
|
void SetLine(unsigned int i, std::string const& str);
|
||||||
|
|
||||||
|
/// Get reference to "pixel" at row i, column j.
|
||||||
|
char & GetPixel(unsigned int i, unsigned int j);
|
||||||
|
|
||||||
|
/// Clears all the screen lines stored within the object and recreates new empty lines of the right size.
|
||||||
|
void ClearScreenLines();
|
||||||
|
|
||||||
|
/// Draws all the screen lines stored within the object. You must call ClearScreen() in order to draw in-place.
|
||||||
|
void DrawScreenLines();
|
||||||
|
|
||||||
|
/// Updates the screen size stored internally.
|
||||||
|
void UpdateScreenSize();
|
||||||
|
|
||||||
|
/// Highlights the line i by inverting its colors (black on white background).
|
||||||
|
void HighlightLine(unsigned int i, bool highlight);
|
||||||
|
|
||||||
/// Returns a winsize structure with size.ws_row is the number of rows, size.ws_col is the number of columns.
|
/// Returns a winsize structure with size.ws_row is the number of rows, size.ws_col is the number of columns.
|
||||||
static winsize GetTerminalSize();
|
static winsize GetTerminalSize();
|
||||||
|
|
||||||
|
|
@ -24,6 +48,8 @@ class Display
|
||||||
protected:
|
protected:
|
||||||
unsigned int screenRows;//<! Number of rows currently displayed in the screen
|
unsigned int screenRows;//<! Number of rows currently displayed in the screen
|
||||||
unsigned int screenCols;//<! Number of columns currently displayed in the screen
|
unsigned int screenCols;//<! Number of columns currently displayed in the screen
|
||||||
|
|
||||||
|
std::vector<std::string> lines;//<! Stores the lines of the screen
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Creates a progress bar
|
/// Creates a progress bar
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,60 @@
|
||||||
using std::cout;
|
using std::cout;
|
||||||
|
|
||||||
Display::Display()
|
Display::Display()
|
||||||
|
{
|
||||||
|
UpdateScreenSize();
|
||||||
|
ClearScreenLines();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Display::Cols() const { return screenCols; }
|
||||||
|
unsigned int Display::Rows() const { return screenRows; }
|
||||||
|
|
||||||
|
std::string const& Display::GetLine(unsigned int i) const { return lines[i]; }
|
||||||
|
|
||||||
|
void Display::SetLine(unsigned int i, std::string const& str)
|
||||||
|
{
|
||||||
|
if(str.size() <= Cols())
|
||||||
|
lines[i] = str + std::string(Cols() - str.size(), ' ');
|
||||||
|
else
|
||||||
|
lines[i] = str.substr(0, Cols());
|
||||||
|
}
|
||||||
|
|
||||||
|
char & Display::GetPixel(unsigned int i, unsigned int j) { return lines[i][j]; }
|
||||||
|
|
||||||
|
void Display::ClearScreenLines()
|
||||||
|
{
|
||||||
|
lines.clear();
|
||||||
|
std::string emptyLine(screenCols, ' ');
|
||||||
|
for(unsigned int i = 0 ; i < screenRows ; i++)
|
||||||
|
lines.push_back(emptyLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::DrawScreenLines()
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0 ; i < lines.size() ; i++)
|
||||||
|
cout << lines[i] << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Display::UpdateScreenSize()
|
||||||
{
|
{
|
||||||
winsize size = Display::GetTerminalSize();
|
winsize size = Display::GetTerminalSize();
|
||||||
screenCols = size.ws_col;
|
screenCols = size.ws_col;
|
||||||
screenRows = size.ws_row;
|
screenRows = size.ws_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Display::Cols() const { return screenCols; }
|
void Display::HighlightLine(unsigned int i, bool highlight)
|
||||||
unsigned int Display::Rows() const { return screenRows; }
|
{
|
||||||
|
if(highlight)
|
||||||
|
{
|
||||||
|
if(lines[i].substr(0, 4) != C_INVERT_FG_BG)
|
||||||
|
lines[i] = C_INVERT_FG_BG + lines[i] + C_RESET;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(lines[i].substr(0, 4) == C_INVERT_FG_BG)
|
||||||
|
lines[i] = lines[i].substr(4, lines[i].size()-4-4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
winsize Display::GetTerminalSize()
|
winsize Display::GetTerminalSize()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
82
src/main.cpp
82
src/main.cpp
|
|
@ -1,15 +1,26 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <TreeNodeDiskUsage.hpp>
|
#include <TreeNodeDiskUsage.hpp>
|
||||||
#include <Display.hpp>
|
#include <Display.hpp>
|
||||||
|
#include <AnsiTerminal.hpp>
|
||||||
|
|
||||||
using std::cout;
|
using std::cout;
|
||||||
using std::cerr;
|
using std::cerr;
|
||||||
using std::endl;
|
using std::endl;
|
||||||
|
|
||||||
|
void runTests(int argc, char *argv[]);
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
if(argc > 1)
|
if(argc > 1)
|
||||||
{
|
runTests(argc, argv);
|
||||||
|
else
|
||||||
|
cerr << "Error : No path given !\n";
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void runTests(int /* argc */, char *argv[])
|
||||||
|
{
|
||||||
if(0)
|
if(0)
|
||||||
{// stat test
|
{// stat test
|
||||||
cout << "Reading '" << argv[1] << "'\n";
|
cout << "Reading '" << argv[1] << "'\n";
|
||||||
|
|
@ -69,7 +80,7 @@ int main(int argc, char *argv[])
|
||||||
d.ClearScreen();
|
d.ClearScreen();
|
||||||
cout << "coucou !\n";
|
cout << "coucou !\n";
|
||||||
}
|
}
|
||||||
//if(0)
|
if(0)
|
||||||
{// progress bar test
|
{// progress bar test
|
||||||
// unsigned int width, unsigned int current, unsigned int total, char fillChar = 219, bool showPercentage = true
|
// unsigned int width, unsigned int current, unsigned int total, char fillChar = 219, bool showPercentage = true
|
||||||
PRINT_VAR(GenerateProgressBar(20, 0, 100, false));
|
PRINT_VAR(GenerateProgressBar(20, 0, 100, false));
|
||||||
|
|
@ -91,7 +102,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
PRINT_VAR(GenerateProgressBar(50, 333, 1000, true, "#"));
|
PRINT_VAR(GenerateProgressBar(50, 333, 1000, true, "#"));
|
||||||
}
|
}
|
||||||
//if(0)
|
if(0)
|
||||||
{// test output
|
{// test output
|
||||||
PRINT_VAR(Bytes2HumanReadable(123ULL, true));
|
PRINT_VAR(Bytes2HumanReadable(123ULL, true));
|
||||||
PRINT_VAR(Bytes2HumanReadable(1234ULL, true));
|
PRINT_VAR(Bytes2HumanReadable(1234ULL, true));
|
||||||
|
|
@ -115,9 +126,66 @@ int main(int argc, char *argv[])
|
||||||
PRINT_VAR(Bytes2HumanReadable(1000000000ULL, false));
|
PRINT_VAR(Bytes2HumanReadable(1000000000ULL, false));
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
//if(0)
|
||||||
else
|
{// test screen functions
|
||||||
cerr << "Error : No path given !\n";
|
Display d;
|
||||||
|
PRINT_VAR(d.Rows());
|
||||||
|
PRINT_VAR(d.Cols());
|
||||||
|
PRINT_VAR(d.GetLine(0));
|
||||||
|
PRINT_VAR(d.GetLine(0).size());
|
||||||
|
|
||||||
return 0;
|
d.GetPixel(5,5) = '#';
|
||||||
|
d.GetPixel(6,6) = '#';
|
||||||
|
d.GetPixel(7,7) = '#';
|
||||||
|
d.GetPixel(20,50) = '#';
|
||||||
|
|
||||||
|
d.SetLine(4, "Coucou !");
|
||||||
|
d.SetLine(10, "------------------------- Coucou ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------");
|
||||||
|
d.SetLine(11, "------------------------- Inverted -------------------------");
|
||||||
|
d.HighlightLine(11, true);
|
||||||
|
d.SetLine(12, " That's normal, bro. Really !");
|
||||||
|
|
||||||
|
Display::ClearScreen();
|
||||||
|
d.DrawScreenLines();
|
||||||
|
|
||||||
|
PRINT_VAR(d.GetLine(12).size());
|
||||||
|
d.HighlightLine(12, true);
|
||||||
|
PRINT_VAR(d.GetLine(12).size());
|
||||||
|
d.HighlightLine(12, true);
|
||||||
|
PRINT_VAR(d.GetLine(12).size());
|
||||||
|
d.HighlightLine(12, false);
|
||||||
|
PRINT_VAR(d.GetLine(12).size());
|
||||||
|
PRINT_VAR(d.GetLine(12));
|
||||||
|
PRINT_VAR(std::string(C_INVERT_FG_BG).size());
|
||||||
|
}
|
||||||
|
if(0)
|
||||||
|
{// test terminal colors
|
||||||
|
cout << C_BLUE_F << "blue" << "\n";
|
||||||
|
cout << C_CYAN_F << "cyan" << "\n";
|
||||||
|
cout << C_YELLOW_F << "yellow" << "\n";
|
||||||
|
cout << C_WHITE_F << "white" << "\n";
|
||||||
|
cout << C_RED_F << "red" << "\n";
|
||||||
|
cout << C_GREEN_F << "green" << "\n";
|
||||||
|
cout << C_BLACK_F << "black" << "\n";
|
||||||
|
cout << C_RESET << "Normal" << "\n";
|
||||||
|
cout << C_BOLD << "Bold text." << C_RESET << " Normal text." << "\n";
|
||||||
|
|
||||||
|
cout << C_BLUE_B << C_YELLOW_F << "Hard on the eyes..." << C_RESET << "\n";
|
||||||
|
cout << C_UNDERLINE << "underlined" << C_RESET << "\n";
|
||||||
|
cout << C_INVERT_FG_BG << "inverted" << C_RESET << "\n";
|
||||||
|
|
||||||
|
cout << "\n\n";
|
||||||
|
|
||||||
|
{// Nice color table
|
||||||
|
int i, j, n;
|
||||||
|
for (i = 0; i < 11; i++) {
|
||||||
|
for (j = 0; j < 10; j++) {
|
||||||
|
n = 10 * i + j;
|
||||||
|
if (n > 107) break;
|
||||||
|
printf("\033[%dm %3d\033[m", n, n);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue