You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
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!
The text was updated successfully, but these errors were encountered:
Fixes#2
Added a new struct `Text`:
- abstracts formatting and coloring in such a way that length is
preserved i.e., zero-width characters are not counted in the length
- uses a new trait `HasLength` which gives a `length()` method to
get the actual length
- `HasLength` is also implemented for a slice of Text
- implemented conversions from String, &str, char
Added a new struct `ToipeTui`:
- stores the stdout terminal ui (from termion)
- moved flush and reset_screen to this
- added methods to display a raw `Text`, a line of text (which can include
multiple disjoint `Text`), multiple lines (with each line having
multiple `Text`).
- resetting terminal on dropping is handled by this
Changed the `Toipe` struct to use `ToipeTui` methods when possible:
- displaying words at the beginning uses `display_a_line`
- displaying green/red chars on typing uses `display_raw_text`
- displaying results uses `display_lines` to abstract away the special
handling of zero-width characters and the aligning of text
- The text formatting part looks a little worse, but everything
seems much cleaner!
- added TODOs in places where ToipeTui could be further used instead of
accessing the stdout directly
also added TODOs for docstrings
What?
Currently, the terminal UI in toipe is rendered by directly writing to
stdout
with cursor positioning and colors provided by termion.Example:
toipe/src/lib.rs
Lines 263 to 271 in fae3005
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:toipe/src/lib.rs
Lines 285 to 299 in fae3005
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()
likecursor::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::Goto
s 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!
The text was updated successfully, but these errors were encountered: