gyscos / cursive

A Text User Interface library for the Rust programming language
MIT License
4.24k stars 240 forks source link

Setting TextView background color? #397

Open vmedea opened 4 years ago

vmedea commented 4 years ago

Is there a way to set the background color of a TextView wrapped in a BoxView to some other color than the default / transparent?

I tried:

gyscos commented 4 years ago

Hi, and thanks for the report!

Indeed it doesn't seem easy right now to achieve that. You'd have to write your own custom Layer + style the TextView.

There's a vague plan to bring "local theme override", where a subtree is given a different theme. You could redefine the "view" color for this tree, and this way both Layer and TextView would use the new color for what they think is the view background.

vmedea commented 4 years ago

Thanks, that works. It was pretty easy to adapt Layer to fill with an arbitrary color instead of the default:

/** Fill a region with an arbitrary color. */
#[derive(Debug)]
pub struct ColoredLayer<T: View> {
    color: ColorStyle,
    view: T,
}

impl<T: View> ColoredLayer<T> {
    /// Wraps the given view.
    pub fn new(color: ColorStyle, view: T) -> Self {
        ColoredLayer { color, view }
    }

    inner_getters!(self.view: T);
}

impl<T: View> ViewWrapper for ColoredLayer<T> {
    wrap_impl!(self.view: T);

    fn wrap_draw(&self, printer: &Printer<'_, '_>) {
        printer.with_color(self.color, |printer| {
            for y in 0..printer.size.y {
                printer.print_hline((0, y), printer.size.x, " ");
            }
        });
        self.view.draw(printer);
    }
}

screenshot

There's a vague plan to bring "local theme override", where a subtree is given a different theme. You could redefine the "view" color for this tree, and this way both Layer and TextView would use the new color for what they think is the view background.

That was kind of what I was looking for! It would be slightly more convenient.

ssokolow commented 4 years ago

@vmedea Do you mind if I use that under the same sort of "just cite the URL you got it from" terms that you see on StackOverflow these days?

I've been trying out Cursive because urwid is so painfully antithetical to what you get with static typing but I'm also very stubborn about my UIs looking exactly right and, until I saw that, I'd been thinking long and hard about whether it would be more difficult to learn enough Cursive internals to force the issue or just go back to wrestling with the devil I know.

gyscos commented 4 years ago

I just pushed an update to the Layer view to let you customize the background color, very similar to how @vmedea did. It's not the perfect solution we want to get with proper sub-tree re-theming, but as a stopgap solution it's not completely terrible (it beats filling "holes" in the TextView with spaces...).

vmedea commented 4 years ago

@vmedea Do you mind if I use that under the same sort of "just cite the URL you got it from" terms that you see on StackOverflow these days?

Sure, no problem !

I just pushed an update to the Layer view to let you customize the background color

That's even better :smile:

(it beats filling "holes" in the TextView with spaces...).

I thought about that too. I think a slight advantage if TextView handled it would be that there's no double drawing, right now with this solution there is flicker with the direct-to-terminal backends such as crossterm But batching updates would be a better general solution to that, eventually.

ssokolow commented 4 years ago

I'll try to try it out soon.

(Given that they're mostly leisure, I can't predict what hobby project I'll feel like working on at any given time.)