Skip to content
This repository has been archived by the owner on Aug 6, 2023. It is now read-only.

Is there a way to center text vertically? #396

Closed
Mirko-von-Leipzig opened this issue Oct 7, 2020 · 1 comment
Closed

Is there a way to center text vertically? #396

Mirko-von-Leipzig opened this issue Oct 7, 2020 · 1 comment

Comments

@Mirko-von-Leipzig
Copy link

Is your feature request related to a problem? Please describe.
I want to center my text both horizontally and vertically in a paragraph.

Describe the solution you'd like
Something similar to alignment::Center, but for vertical.

Describe alternatives you've considered
I've considered calculating the height and prefixing the text with the appropriate number of blank lines.
I've also considered using blank widgets above and below the text to "squish" it towards the middle.

Additional context
Honestly, I'm pretty new to TUI so its very possible I've simply missed the appropriate way to do this.

@HHogg
Copy link

HHogg commented Feb 14, 2023

image

I managed to get some vertical centering of text with a custom component. It worked for what I need now, but I haven't tested it with text overflowing or multi lines. I'll drop the code below if anybody finds it useful.

#[derive(Default)]
struct CenterPosition<'a> {
    block: Option<Block<'a>>,
    text: &'a str,
}

impl<'a> Widget for CenterPosition<'a> {
    fn render(mut self, area: Rect, buf: &mut Buffer) {
        let text_area = match self.block.take() {
            Some(b) => {
                let inner_area = b.inner(area);
                b.render(area, buf);
                inner_area
            }
            None => area,
        };

        if text_area.height < 1 {
            return;
        }

        buf.set_string(
            area.left() + area.width / 2 - self.text.len() as u16 / 2,
            area.top() + area.height / 2,
            self.text,
            Style::default(),
        );
    }
}

impl<'a> CenterPosition<'a> {
    pub fn block(mut self, block: Block<'a>) -> Self {
        self.block = Some(block);
        self
    }

    fn text(mut self, text: &'a str) -> CenterPosition<'a> {
        self.text = text;
        self
    }
}

pub fn render_center<B: Backend>(f: &mut Frame<B>, area: Rect, message: &str) {
    f.render_widget(
        CenterPosition::default()
            .text("Text in the center")
            .block(get_block()),
        area,
    );
}

@fdehau fdehau closed this as completed Aug 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants