Samyak2 / toipe

yet another typing test, but crab flavoured
MIT License
595 stars 31 forks source link

Refactor UI components to be more modular #2

Closed Samyak2 closed 2 years ago

Samyak2 commented 2 years ago

What?

Currently, the terminal UI in toipe is rendered by directly writing to stdout with cursor positioning and colors provided by termion.

Example: https://github.com/Samyak2/toipe/blob/fae300576c4f83e50ca969c588217bbd3c8cb581/src/lib.rs#L263-L271

This code looks a bit ugly and we need to manually position items by changing the arguments given to cursor::Goto. For example, sizey / 2 - 2 means two lines above the middle line. If I want to add another line to that list and move all of them down, I need to change this part of every line.

The cursor::Left(line.len() as u16 / 2) part positions the text in the center - this snippet is repeated for every line. What's even worse is if the text in that line includes special characters such as colors, this will not work because it will consider those hidden characters too! To get around that, I use this hack: https://github.com/Samyak2/toipe/blob/fae300576c4f83e50ca969c588217bbd3c8cb581/src/lib.rs#L285-L299

As you can see, I need to repeat the formatting characters again in a separate string containing only them and then subtract their length from line.len() like cursor::Left((line.len() - zerowidths.len()) as u16 / 2).

How to fix?

Honestly, I'm not sure. I opened this issue to force myself to document the problem.

The solution will definitely involve abstracting this UI rendering into a different module. Abstracting the cursor::Gotos is simple - take a vec/iter/slice of strings and change the y-position when printing each one such that they are approximately in the middle. cursor::Left(line.len() as u16 / 2) is easy too, as long as the given string contains single-width characters. I'm not sure how zero-width and other characters can be handled here. Perhaps this problem is solved elsewhere?

I'm always open to suggestions!

Samyak2 commented 2 years ago

This is in-progress in https://github.com/Samyak2/toipe/compare/ui-refactor

The formatting code is a bit cumbersome to use. Maybe a macro similar to format! would make sense here.