TTY-CPP

C++ library for writing terminal applications
No description
66 Replies
Dumb Bird
Dumb Bird•2y ago
GitHub
GitHub - ZackeryRSmith/tty-cpp: C++ library for writing terminal ap...
C++ library for writing terminal applications. Contribute to ZackeryRSmith/tty-cpp development by creating an account on GitHub.
Dumb Bird
Dumb Bird•17mo ago
Currently working on fixing some bugs, this is in no means a stable form. The smashed together header can be found here https://github.com/ZackeryRSmith/tty-cpp/tree/main/include I've yet to create a README, but that will happen soon Color testing is done for the most part Auto color conversion to the nearest color This is helpful for developers that just want their application to look similar on all terminals. This means you are free to use TrueColor without having to worry about dumbing down your colors for other terminals. All that is handled for you!
Dumb Bird
Dumb Bird•17mo ago
No description
Dumb Bird
Dumb Bird•17mo ago
Some things are still a bit funky with the color conversions namely 24bit to 4bit. But overall this keeps the colors looking good even on dumber terminals that don't support 8bit or 24bit color! I've also implemented a Terminfo db parser. I may remove this in the future as it's not really needed. I'll decide what I want to do with it in the future. I'd like to implement the way the end-user api is done It makes some big code For example here is the color test file shown here
Dumb Bird
Dumb Bird•17mo ago
Dumb Bird
Dumb Bird•17mo ago
tty-cpp does have proper error handling through the exception class I've made. Here are all the current cursor movement functions tty-cpp has.
c++
// terminal cursor control
void set_row(std::size_t); // move cursor to row
void set_column(std::size_t); // move cursor to column
void cursor_next(std::size_t); // moves cursor to beginning of next line, N lines down (default N=1)
void cursor_prev(std::size_t); // moves cursor to beginning of previous line, N lines up (default N=1)
void cursor_up(std::size_t); // move the cursor up N lines (default N=1)
void cursor_down(std::size_t); // move the cursor down N lines (default N=1)
void cursor_right(std::size_t); // move the cursor forward N columns (default N=1)
void cursor_left(std::size_t); // move the cursor backward N columns (default N=1)
void cursor_position_report(); // the ANSI code to generate a cursor position report
void cursor_off(); // hide cursor
void cursor_on(); // show cursor
cursor_pos_t cursor_position(); // returns the current cursor position (row, column)
void cursor_move(std::size_t, std::size_t); // move cursor by the given row and column
void cursor_set(std::size_t, std::size_t); // move cursor to given row and column
c++
// terminal cursor control
void set_row(std::size_t); // move cursor to row
void set_column(std::size_t); // move cursor to column
void cursor_next(std::size_t); // moves cursor to beginning of next line, N lines down (default N=1)
void cursor_prev(std::size_t); // moves cursor to beginning of previous line, N lines up (default N=1)
void cursor_up(std::size_t); // move the cursor up N lines (default N=1)
void cursor_down(std::size_t); // move the cursor down N lines (default N=1)
void cursor_right(std::size_t); // move the cursor forward N columns (default N=1)
void cursor_left(std::size_t); // move the cursor backward N columns (default N=1)
void cursor_position_report(); // the ANSI code to generate a cursor position report
void cursor_off(); // hide cursor
void cursor_on(); // show cursor
cursor_pos_t cursor_position(); // returns the current cursor position (row, column)
void cursor_move(std::size_t, std::size_t); // move cursor by the given row and column
void cursor_set(std::size_t, std::size_t); // move cursor to given row and column
Here are the clear functions, one of which is inspired by @earth's god's project #newtrodit
c++
// clear functions
void clear_screen(); // clear screen
//void clear_buffer(); // clear screen and the scroll-back buffer
void clear_to_eol(); // clear from cursor position to the end of the line
void clear_to_eof(); // clear from cursor position to the end of the screen
void clear_to_sol(); // clear from cursor position to the start of the line
void clear_to_sof(); // clear from cursor position to the start of the screen
void clear_line(); // clear the entire line where the cursor is located
void clear_partial(); // clear from a specific (Y, X) and a custom (width, height) *idea from Newtrodit*
c++
// clear functions
void clear_screen(); // clear screen
//void clear_buffer(); // clear screen and the scroll-back buffer
void clear_to_eol(); // clear from cursor position to the end of the line
void clear_to_eof(); // clear from cursor position to the end of the screen
void clear_to_sol(); // clear from cursor position to the start of the line
void clear_to_sof(); // clear from cursor position to the start of the screen
void clear_line(); // clear the entire line where the cursor is located
void clear_partial(); // clear from a specific (Y, X) and a custom (width, height) *idea from Newtrodit*
As tty-cpp is a single header I can clean up this end-user api in a clean way. And for anyone wondering, the single header file is actually generated and smashed together using Heady. This makes development of tty-cpp so much smoother as I'm not confined to a single header while actually developing the project. After I clean up the end user api a bit I will be going to add a mouse class of some kind. At the very least, functions for detecting mouse events without using X11 Then I'll be working on the input system which will allow control keys to be detected as read as bytes. For example allowing for Ctrl-V to be read as a 22 byte, and Ctrl-O as a 15 byte. This list just goes on. Then I'll define an enum for all the keys, hopefully if all goes well I'll have a decent input function. I'm also thinking about maybe implementing a window class of some kind, mainly for doing more graphical based stuff with the library. The window class would take care of quite a bit of backend stuff.
anic17
anic17•17mo ago
Remember what we did with getch_n() You can use that algorithm to concert everything into a single integer
Dumb Bird
Dumb Bird•17mo ago
I may implement something of the like. Though Termios actually makes getting certain key events much easier. Which is something I never actually knew till recently
anic17
anic17•17mo ago
We were using termios for that Canonical mode and echo off
Dumb Bird
Dumb Bird•17mo ago
To some degree, using ICANON and ECHO is just a start though For example adding IEXTEN will cause Ctrl-V to know be able to be read as a 22 byte
anic17
anic17•17mo ago
Didn't this already happen
Dumb Bird
Dumb Bird•17mo ago
Not sure.
anic17
anic17•17mo ago
I think so Let me check the code
Dumb Bird
Dumb Bird•17mo ago
IXON allows Ctrl+S to be detected as 19 byte And Ctrl-Q can be read as a 17 byte as well ICRNL makes Ctrl-M able to be read as 13 byte Which is the same as enter, which is also 13 byte Ctrl-M is the keybind for a carriage return though, so it makes sense why Ctrl-M and Enter are the same. Not sure if getch_n() has the ability to capture these key code, and if it does I'm pretty sure it does it differently. I think you have it, so it collects the escape code the key outputs or something. Sorry haven't worked with Newtrodit for a while. We also probably should've disabled all outpost processing when the terminal is in raw mode. You can do this by setting the OPOST flag
anic17
anic17•17mo ago
Just checked, it already did Basically it's the same flags as showkey -a
Dumb Bird
Dumb Bird•17mo ago
Hm, I still seem to remember Newtrodit has some issues with capturing some keys. Though I may just yoink some code from Newtrodit's input system, as you did work hard on that.
anic17
anic17•17mo ago
That is the full code
anic17
anic17•17mo ago
Dumb Bird
Dumb Bird•17mo ago
What keys doesn't it collect. Because I swear on my life I remember like 4 keys that didn't actually get detected.
anic17
anic17•17mo ago
I don't know, I made it so it collected all the keys I could Try with this
anic17
anic17•17mo ago
anic17
anic17•17mo ago
@earth's bird
Dumb Bird
Dumb Bird•17mo ago
Sorry I was upstairs cooking some food
anic17
anic17•17mo ago
no worries lol
Dumb Bird
Dumb Bird•17mo ago
Is it meant to just repeatedly print out stuff even if I'm not pressing any keys?
anic17
anic17•17mo ago
No
Dumb Bird
Dumb Bird•17mo ago
No description
Dumb Bird
Dumb Bird•17mo ago
Haven't pressed a single thing Is there no way to quit 💀
anic17
anic17•17mo ago
No description
anic17
anic17•17mo ago
just made this run in a while loop not really Control-C and Control-Z are intercepted
Dumb Bird
Dumb Bird•17mo ago
Yeah I see that lol Odd I’ll try a different terminal
anic17
anic17•17mo ago
Which terminal emulator is this
Dumb Bird
Dumb Bird•17mo ago
I'm using alacritty With an XTERM backend It happens in the 3 other terminals I just tested it in Not sure what the issue is Maybe just check if the code is 0 then just don't print I guess It also still happens when I use different shells, I normally use ZSH but Bash, nor Fish worked. Still the actual detection seems to work pretty damn good
anic17
anic17•17mo ago
Even some special locale issues are avoided For example in my ca-ES keyboard layout Control-Alt-E prints the € sign
Dumb Bird
Dumb Bird•17mo ago
Ah, nice this is definitely really handy!
Unknown User
Unknown User•17mo ago
Message Not Public
Sign In & Join Server To View
Dumb Bird
Dumb Bird•17mo ago
Bresenham's line algorithm
No description
Dumb Bird
Dumb Bird•17mo ago
anic17
anic17•17mo ago
Nice
Dumb Bird
Dumb Bird•17mo ago
tty-cpp now supports conversions between hex to rgb and rgb to hex. Along with being able to convert rgb->int and hex->int I've also inlined a few very common functions namely the movement and clear functions Along with color_fg & color_bg color_fg and color_bg now will convert to the closest color if the color passed isn't supported by the terminal I'm honestly not sure if I should do this in color_fg and color_bg (which convert colors to an escape sequence) Or maybe have another function called like auto_color_fg and auto_color_bg I haven't actually run the tests, but I can't imagine checking if a certain color is supported each time color_fg or color_bg is called can't be all the optimised Especially if the end user doesn't actually care about keeping cross compatible colors. What do you think @earth's god?
Dumb Bird
Dumb Bird•17mo ago
Now works with unicode
No description
Dumb Bird
Dumb Bird•17mo ago
c++
// code used in the image above
int main() {
Term::clear_screen();
plot_line(0, 15, 66, 15, "─");
plot_line(34, 0, 0, 34, "╱");
plot_line(32, 0, 65, 33, "╲");
plot_line(33, 0, 33, 66, "│");


Term::cursor_set(14, 33);
std::cout << "┼";
Term::cursor_home();

Term::cursor_down(30); // just to make sure things don't get overwritten :/

return 0;
}
c++
// code used in the image above
int main() {
Term::clear_screen();
plot_line(0, 15, 66, 15, "─");
plot_line(34, 0, 0, 34, "╱");
plot_line(32, 0, 65, 33, "╲");
plot_line(33, 0, 33, 66, "│");


Term::cursor_set(14, 33);
std::cout << "┼";
Term::cursor_home();

Term::cursor_down(30); // just to make sure things don't get overwritten :/

return 0;
}
anic17
anic17•17mo ago
Neat I think that's the best thing How would it look if it didn't change to the closest available color?
Dumb Bird
Dumb Bird•17mo ago
The way I have colors stored is different for each bit and I overload the color_fg and color_bg functions so it’s easy for me to differentiate between colors 4bit colors are stored in a ColorBit4 struct, 8bit colors are stored as std::uint8’s and 24bit is stored as either an rgb struct or for some functions you can just pass 3 values or an rgb struct The thing I’m wondering is do I make the color conversion take place when color_fg is called or should have functions like auto_color_fg and such. As some people may not care for color conversation across terminals. As I mentioned a little bit up I can’t imagine it’s very optimized to check the terminals color support each time the function is called. I mean I don’t think it’s a huge difference but I’m still not sure Oh sorry I completely miss read this. God I swear, I was trying to speedrun answering you question because I was at school and I didn’t want the teacher to notice me on my phone. Regardless, if you try to use an invalid escape sequence nothing will happen. Meaning if I don’t convert to colors the terminal can use then no color will be displayed at all The terminal may also just display the escape sequence as plain text It could also cause unexpected behavior on the terminal or in some cases the terminal will freeze or crash (Which is especially true if the escape sequence is used repeatedly or in combination with other sequences ) So it tends to be quite vital to make sure we don’t use unsupported escape sequences, but in some cases you just can’t be bothered and depending on your target terminal you may not even need cross compatibility with your colors
Dumb Bird
Dumb Bird•17mo ago
GitHub
GitHub - ZackeryRSmith/tty-cpp: C++ library for writing terminal ap...
C++ library for writing terminal applications. Contribute to ZackeryRSmith/tty-cpp development by creating an account on GitHub.
Dumb Bird
Dumb Bird•17mo ago
Ah the banner seems to work fine
anic17
anic17•17mo ago
Bad boy :abyss:
Dumb Bird
Dumb Bird•17mo ago
💀
anic17
anic17•17mo ago
Awake at 2 AM
Dumb Bird
Dumb Bird•17mo ago
I don’t want to be but I can’t sleep
anic17
anic17•17mo ago
Is this behavior terminal dependant
Dumb Bird
Dumb Bird•17mo ago
Yes
anic17
anic17•17mo ago
I'm guessing you will create a table with compatible terminals just as you did with Newtrodit-LCL Try to avoid this
Dumb Bird
Dumb Bird•17mo ago
No, I parse the terminfo database so try-cpp works on any terminal that has support for escape sequences
anic17
anic17•17mo ago
Even better
Dumb Bird
Dumb Bird•17mo ago
I can avoid it
anic17
anic17•17mo ago
Anyways gtg
Dumb Bird
Dumb Bird•15mo ago
Alright Added some new tests
Dumb Bird
Dumb Bird•15mo ago
Dumb Bird
Dumb Bird•15mo ago
Simple typeracer clone Small issue with rendering at small sizes, but for the most part works fine at all screen sizes
Dumb Bird
Dumb Bird•15mo ago
Simple alert box function
Dumb Bird
Dumb Bird•15mo ago
Dumb Bird
Dumb Bird•15mo ago
Nyan cat! I also added a basic fill function to fill the screen with a specific char and color For other tests I also created a table generating library and shape drawer An example of using the table generator can be seen under the test pidinfo.cpp Which will give you basic information on a pid, should work on all major platforms. Windows, Mac, and Linux
Dumb Bird
Dumb Bird•15mo ago
No description
anic17
anic17•15mo ago
HE'S ALIVE AGAIN :catthumbsup:
Dumb Bird
Dumb Bird•15mo ago
😮