Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand and rename the center-a-rect article #820

Merged
merged 2 commits into from
Jan 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ export default defineConfig({
"/how-to/develop-apps/migrate-from-tui-rs": "/recipes/apps/migrate-from-tui-rs",
"/how-to/develop-apps/panic-hooks": "/recipes/apps/panic-hooks",
"/how-to/develop-apps/terminal-and-event-handler": "/recipes/apps/terminal-and-event-handler",
"/how-to/layout/center-a-rect": "/recipes/layout/center-a-rect",
"/how-to/layout/center-a-rect": "/recipes/layout/center-a-widget",
"/how-to/layout/collapse-borders": "/recipes/layout/collapse-borders",
"/how-to/layout/dynamic": "/recipes/layout/dynamic",
"/how-to/layout": "/recipes/layout",
Expand All @@ -359,6 +359,7 @@ export default defineConfig({
"/how-to/widgets/custom": "/recipes/widgets/custom",
"/how-to/widgets": "/recipes/widgets",
"/how-to/widgets/paragraph": "/recipes/widgets/paragraph",
"/recipes/layout/center-a-rect": "/recipes/layout/center-a-widget",
},
vite: {
server: {
Expand Down
25 changes: 23 additions & 2 deletions code/recipes/how-to-misc/src/layout.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
#![allow(dead_code)]
// ANCHOR: imports
use ratatui::layout::{Constraint, Flex, Layout, Rect};
// ANCHOR_END: imports

use ratatui::{
layout::{Constraint, Flex, Layout, Rect},
text::Text,
widgets::{Block, Clear, Paragraph},
Frame,
};

// Examples for https://ratatui.rs/recipes/layout/center-a-rect/
// Examples for https://ratatui.rs/recipes/layout/center-a-widget/

// ANCHOR: horizontal
fn center_horizontal(area: Rect, width: u16) -> Rect {
let [area] = Layout::horizontal([Constraint::Length(width)])
.flex(Flex::Center)
.areas(area);
area
}
// ANCHOR_END: horizontal

// ANCHOR: vertical
fn center_vertical(area: Rect, height: u16) -> Rect {
let [area] = Layout::vertical([Constraint::Length(height)])
.flex(Flex::Center)
.areas(area);
area
}
// ANCHOR_END: vertical

// ANCHOR: center
/// Centers a [`Rect`] within another [`Rect`] using the provided [`Constraint`]s.
Expand Down
45 changes: 0 additions & 45 deletions src/content/docs/recipes/layout/center-a-rect.md

This file was deleted.

94 changes: 94 additions & 0 deletions src/content/docs/recipes/layout/center-a-widget.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
title: How to Center Widgets
sidebar:
order: 2
label: Center a Widget
---

## Problem

You want to center a widget within some area of your TUI's layout.

## Solution

To center a widget in any area, create a [`Rect`] that is centered within the area. You can
calculate the x and y positions of the widget by subtracting the widget width and height from the
enclosing area's width and height, respectively, and dividing by 2.

More simply, you can use the [`Layout`] struct to center a widget. You can use a `Horizontal` layout
followed by a `Vertical` layout to get a centered [`Rect`]. The [`Flex`] enum can be used to specify
the alignment of the rect within the containing area.

### Centering horizontally

```rust
{{ #include @code/recipes/how-to-misc/src/layout.rs:imports }}

{{ #include @code/recipes/how-to-misc/src/layout.rs:horizontal }}
```

### Centering vertically

```rust
{{ #include @code/recipes/how-to-misc/src/layout.rs:imports }}

{{ #include @code/recipes/how-to-misc/src/layout.rs:vertical }}
```

### Centering both horizontally and vertically

You can use a `Vertical` layout followed by a `Horizontal` layout to get a centered `Rect`. This
example centers the `Rect` using constraints on each axis. This lets you allocate the space
available based on a percentage, ratio, or fixed size.

```rust collapse={1-13}
{{ #include @code/recipes/how-to-misc/src/layout.rs:center }}
```

### Centering a widget

You can use these methods to draw any widget centered on the containing area.

```rust
{{ #include @code/recipes/how-to-misc/src/layout.rs:render }}
```

### Popups

A common use case for this feature is to create a popup style dialog block. For this, typically,
you'll want to use the [`Clear`] widget to clear the popup area before rendering your content to it.
The following is an example of how you might do that:

```rust
{{ #include @code/recipes/how-to-misc/src/layout.rs:render_popup }}
```

## Summary

The [`Layout`] struct provides a simple way to center a widget in a terminal. You can use the
`Horizontal` and `Vertical` layouts to center a widget on the x and y axes, respectively. You can
also use the `Flex` enum to specify the alignment of the widget within the containing area. There
are more advanced layout options available in the [`Layout`] struct but not covered in this recipe,
which you can use to create more complex layouts.

:::note

There is no method for vertically aligning text within an area yet. We recommend prewrapping the
text using the [textwrap crate] and then using the line count to work out where to render the text.

:::

Full code for this recipe is available in the website repo at:
<https://github.com/ratatui/ratatui-website/blob/main/code/recipes/src/layout.rs>

## See also

There are several third party widget libraries for making popups easy to use:

- [tui-popup](https://crates.io/crates/tui-popup)
- [tui-confirm-dialog](https://crates.io/crates/tui-confirm-dialog)

[textwrap crate]: https://crates.io/crates/textwrap
[`Rect`]: https://docs.rs/ratatui/latest/ratatui/struct.Rect.html
[`Layout`]: https://docs.rs/ratatui/latest/ratatui/layout/struct.Layout.html
[`Flex`]: https://docs.rs/ratatui/latest/ratatui/layout/enum.Flex.html
2 changes: 1 addition & 1 deletion src/content/docs/recipes/layout/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sidebar:
In this section we will cover layout basics and advanced techniques.

- [Create Dynamic Layouts](./dynamic/)
- [Center a Rect](./center-a-rect/)
- [Center a Rect](./center-a-widget/)
- [Collapse Borders](./collapse-borders/)

## See Also
Expand Down
Loading