Commit graph

340 commits

Author SHA1 Message Date
Orhun Parmaksız
4c4851ca3d
feat(example): add drawing feature to the canvas example (#1429)
![rec_20241018T235208](https://github.com/user-attachments/assets/cfb2f9f8-773b-4599-9312-29625ff2ca60)


fun fact: I had to do [35
pushups](https://www.youtube.com/watch?v=eS92stzBYXA) for this...

---------

Co-authored-by: Josh McKinney <joshka@users.noreply.github.com>
2024-10-20 01:41:40 -07:00
FujiApple
60cc15bbb0
feat!: add support for empty bar style to Sparkline (#1326)
- distingiush between empty bars and bars with a value of 0
- provide custom styling for empty bars
- provide custom styling for individual bars
- inverts the rendering algorithm to be item first

Closes: #1325 

BREAKING CHANGE: `Sparkline::data` takes `IntoIterator<Item = SparklineBar>`
instead of `&[u64]` and is no longer const

Co-authored-by: Josh McKinney <joshka@users.noreply.github.com>
2024-10-19 19:49:05 -07:00
Josh McKinney
4728f0e68b
docs: tweak readme (#1419)
Fixes: <https://github.com/ratatui/ratatui/issues/1417>
2024-10-15 03:00:03 -07:00
Josh McKinney
3df685e114
fix(rect)!: Rect::area now returns u32 and Rect::new() no longer clamps area to u16::MAX (#1378)
This change fixes the unexpected behavior of the Rect::new() function to
be more intuitive. The Rect::new() function now clamps the width and
height of the rectangle to keep each bound within u16::MAX. The
Rect::area() function now returns a u32 instead of a u16 to allow for
larger areas to be calculated.

Previously, the Rect::new() function would clamp the total area of the
rectangle to u16::MAX, by preserving the aspect ratio of the rectangle.

BREAKING CHANGE: Rect::area() now returns a u32 instead of a u16.

Fixes: <https://github.com/ratatui/ratatui/issues/1375>

Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-10-14 15:04:56 -07:00
Tayfun Bocek
dc8d0587ec
feat(table)!: add support for selecting column and cell (#1331)
Fixes https://github.com/ratatui-org/ratatui/issues/1250

Adds support for selecting a column and cell in `TableState`. The
selected column, and cells style can be set by
`Table::column_highlight_style` and `Table::cell_highlight_style`
respectively.

The table example has also been updated to display the new
functionality:


https://github.com/user-attachments/assets/e5fd2858-4931-4ce1-a2f6-a5ea1eacbecc

BREAKING CHANGE: The Serialized output of the state will now include the
"selected_column" field. Software that manually parse the serialized the
output (with anything other than the `Serialize` implementation on
`TableState`) may have to be refactored if the "selected_column" field
is not accounted for. This does not affect users who rely on the
`Deserialize`, or `Serialize` implementation on the state.

BREAKING CHANGE: The `Table::highlight_style` is now deprecated in favor
of `Table::row_highlight_style`.

---------

Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-10-13 14:06:29 +03:00
Josh McKinney
2805dddf05
feat(logo): Add a Ratatui logo widget
This is a simple logo widget that can be used to render the Ratatui logo
in the terminal. It is used in the `examples/ratatui-logo.rs` example,
and may be used in your applications' help or about screens.

```rust
use ratatui::{Frame, widgets::RatatuiLogo};

fn draw(frame: &mut Frame) {
    frame.render_widget(RatatuiLogo::tiny(), frame.area());
}
```
2024-10-05 17:35:43 -07:00
Dheepak Krishnamurthy
edcdc8a814
refactor(layout): rename element to segment in layout (#1397)
This PR renames `element` to `segment` in a couple of functions in the
layout calculations for clarity. `element` can refer to `segment`s or
`spacer`s and functions that take only `segment`s should use `segment`
as the variable names.
2024-10-02 22:34:07 +03:00
Josh McKinney
67c0ea243b
chore(block): deprecate block::Title (#1372)
`ratatui::widgets::block::Title` is deprecated in favor of using `Line`
to represent titles.
This removes an unnecessary layer of wrapping (string -> Span -> Line ->
Title).

This struct will be removed in a future release of Ratatui (likely
0.31).
For more information see:
<https://github.com/ratatui/ratatui/issues/738>

To update your code:
```rust
Block::new().title(Title::from("foo"));
// becomes any of
Block::new().title("foo");
Block::new().title(Line::from("foo"));

Block::new().title(Title::from("foo").position(Position::TOP));
// becomes any of
Block::new().title_top("foo");
Block::new().title_top(Line::from("foo"));

Block::new().title(Title::from("foo").position(Position::BOTTOM));
// becomes any of
Block::new().title_bottom("foo");
Block::new().title_bottom(Line::from("foo"));
```
2024-09-20 10:21:26 +03:00
FujiApple
da821b431e
fix: clippy lints from rust 1.81.0 (#1356) 2024-09-06 22:54:36 -07:00
Mo
20c88aaa5b
refactor: Avoid unneeded allocations (#1345) 2024-08-26 13:59:30 -07:00
Orhun Parmaksız
e02947be61
style(example): update panic message in minimal template (#1344) 2024-08-25 04:45:34 -07:00
Josh McKinney
3631b34f53
docs(examples): add widget implementation example (#1147)
This new example documents the various ways to implement widgets in
Ratatui. It demonstrates how to implement the `Widget` trait on a type,
a reference, and a mutable reference. It also shows how to use the
`WidgetRef` trait to render boxed widgets.
2024-08-23 14:30:23 -07:00
Josh McKinney
ed51c4b342
feat(terminal): Add ratatui::init() and restore() methods (#1289)
These are simple opinionated methods for creating a terminal that is
useful to use in most apps. The new init method creates a crossterm
backend writing to stdout, enables raw mode, enters the alternate
screen, and sets a panic handler that restores the terminal on panic.

A minimal hello world now looks a bit like:

```rust
use ratatui::{
    crossterm::event::{self, Event},
    text::Text,
    Frame,
};

fn main() {
    let mut terminal = ratatui::init();
    loop {
        terminal
            .draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area()))
            .expect("Failed to draw");
        if matches!(event::read().expect("failed to read event"), Event::Key(_)) {
            break;
        }
    }
    ratatui::restore();
}
```

A type alias `DefaultTerminal` is added to represent this terminal
type and to simplify any cases where applications need to pass this
terminal around. It is equivalent to:
`Terminal<CrosstermBackend<Stdout>>`

We also added `ratatui::try_init()` and `try_restore()`, for situations
where you might want to handle initialization errors yourself instead
of letting the panic handler fire and cleanup. Simple Apps should
prefer the `init` and `restore` functions over these functions.

Corresponding functions to allow passing a `TerminalOptions` with
a `Viewport` (e.g. inline, fixed) are also available
(`init_with_options`,
and `try_init_with_options`).

The existing code to create a backend and terminal will remain and
is not deprecated by this approach. This just provides a simple one
line initialization using the common options.

---------

Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-22 15:16:35 +03:00
Josh McKinney
23516bce76
chore: rename ratatui-org to ratatui (#1334)
All urls updated to point at https://github.com/ratatui

To update your repository remotes, you can run the following commands:

```shell
git remote set-url origin https://github.com/ratatui/ratatui
```
2024-08-21 11:35:08 -07:00
Josh McKinney
0256269a7f
build: simplify Windows build (#1317)
Termion is not supported on Windows, so we need to avoid building it.

Adds a conditional dependency to the Cargo.toml file to only include
termion when the target is not Windows. This allows contributors to
build using the `--all-features` flag on Windows rather than needing
to specify the features individually.
2024-08-13 10:09:46 -07:00
Josh McKinney
d5477b50d5
docs(examples): use ratatui::crossterm in examples (#1315) 2024-08-10 17:43:13 -07:00
montmorillonite
730dfd4940
docs(examples): show line gauge in demo example (#1309) 2024-08-07 20:25:43 -07:00
Josh McKinney
69e8ed7db8
chore(deps): remove anyhow from dev dependencies (#1305)
Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
2024-08-06 23:17:11 +03:00
Josh McKinney
5f7a7fbe19
docs(examples): update barcharts gifs (#1306) 2024-08-06 23:09:40 +03:00
EdJoPaTo
c68ee6c64a
feat!: add get/set_cursor_position() methods to Terminal and Backend (#1284)
The new methods return/accept `Into<Position>` which can be either a Position or a (u16, u16) tuple.

```rust
backend.set_cursor_position(Position { x: 0, y: 20 })?;
let position = backend.get_cursor_position()?;
terminal.set_cursor_position((0, 20))?;
let position = terminal.set_cursor_position()?;
```
2024-08-06 04:10:28 -07:00
EdJoPaTo
afe15349c8
feat(chart)!: accept IntoIterator for axis labels (#1283)
BREAKING CHANGES: #1273 is already breaking and this only advances the
already breaking part
2024-08-06 11:39:44 +02:00
Josh McKinney
fe4eeab676
docs(examples): simplify the barchart example (#1079)
The `barchart` example has been split into two examples: `barchart` and
`barchart-grouped`. The `barchart` example now shows a simple barchart
with random data, while the `barchart-grouped` example shows a grouped
barchart with fake revenue data.

This simplifies the examples a bit so they don't cover too much at once.

- Simplify the rendering functions
- Fix several clippy lints that were marked as allowed

---------

Co-authored-by: EdJoPaTo <rfc-conform-git-commit-email@funny-long-domain-label-everyone-hates-as-it-is-too-long.edjopato.de>
2024-08-06 01:10:58 -07:00
Josh McKinney
a23ecd9b45
feat(buffer): add Buffer::cell, cell_mut and index implementations (#1084)
Code which previously called `buf.get(x, y)` or `buf.get_mut(x, y)`
should now use index operators, or be transitioned to `buff.cell()` or
`buf.cell_mut()` for safe access that avoids panics by returning
`Option<&Cell>` and `Option<&mut Cell>`.

The new methods accept `Into<Position>` instead of `x` and `y`
coordinates, which makes them more ergonomic to use.

```rust
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 10));

let cell = buf[(0, 0)];
let cell = buf[Position::new(0, 0)];

let symbol = buf.cell((0, 0)).map(|cell| cell.symbol());
let symbol = buf.cell(Position::new(0, 0)).map(|cell| cell.symbol());

buf[(0, 0)].set_symbol("🐀");
buf[Position::new(0, 0)].set_symbol("🐀");

buf.cell_mut((0, 0)).map(|cell| cell.set_symbol("🐀"));
buf.cell_mut(Position::new(0, 0)).map(|cell| cell.set_symbol("🐀"));
```

The existing `get()` and `get_mut()` methods are marked as deprecated.
These are fairly widely used and we will leave these methods around on
the buffer for a longer time than our normal deprecation approach (2
major release)

Addresses part of: https://github.com/ratatui-org/ratatui/issues/1011

---------

Co-authored-by: EdJoPaTo <rfc-conform-git-commit-email@funny-long-domain-label-everyone-hates-as-it-is-too-long.edjopato.de>
2024-08-06 00:40:47 -07:00
EdJoPaTo
f97e07c08a
feat(frame): replace Frame::size() with Frame::area() (#1293)
Area is the more correct term for the result of this method.
The Frame::size() method is marked as deprecated and will be
removed around Ratatui version 0.30 or later.

Fixes: https://github.com/ratatui-org/ratatui/pull/1254#issuecomment-2268061409
2024-08-05 20:15:14 -07:00
Josh McKinney
6e7b4e4d55
docs(examples): add async example (#1248)
This example demonstrates how to use Ratatui with widgets that fetch
data asynchronously. It uses the `octocrab` crate to fetch a list of
pull requests from the GitHub API. You will need an environment
variable named `GITHUB_TOKEN` with a valid GitHub personal access
token. The token does not need any special permissions.

Co-authored-by: Dheepak Krishnamurthy <me@kdheepak.com>
2024-08-04 22:26:56 -07:00
Josh McKinney
8d4a1026ab
feat(barchart)!: allow axes to accept Lines (#1273)
Fixes: https://github.com/ratatui-org/ratatui/issues/1272
2024-08-03 16:16:57 -07:00
Josh McKinney
edc2af9822
chore: replace big_text with hardcoded logo (#1203)
big_text.rs was a copy of the code from tui-big-text and was getting
gradually out of sync with the original crate. It was also rendering
something a bit different than the Ratatui logo. This commit replaces
the big_text.rs file with a much smaller string representation of the
Ratatui logo.

![demo2](https://raw.githubusercontent.com/ratatui-org/ratatui/images/examples/demo2-destroy.gif)
2024-08-03 16:08:59 -07:00
EdJoPaTo
8857037bff
docs(terminal): fix imports (#1263) 2024-08-02 21:37:05 +03:00
Josh McKinney
84cb16483a
fix(terminal)!: make terminal module private (#1260)
This is a simplification of the public API that is helpful for new users
that are not familiar with how rust re-exports work, and helps avoid
clashes with other modules in the backends that are named terminal.

BREAKING CHANGE: The `terminal` module is now private and can not be
used directly. The types under this module are exported from the root of
the crate.

```diff
- use ratatui::terminal::{CompletedFrame, Frame, Terminal, TerminalOptions, ViewPort};
+ use ratatui::{CompletedFrame, Frame, Terminal, TerminalOptions, ViewPort};
```

Fixes: https://github.com/ratatui-org/ratatui/issues/1210
2024-08-02 04:18:00 -07:00
Alex Saveau
cd93547db8
fix: remove unnecessary synchronization in layout cache (#1245)
Layout::init_cache no longer returns bool and takes a NonZeroUsize instead of usize

The cache is a thread-local, so doesn't make much sense to require
synchronized initialization.
2024-08-01 23:06:49 -07:00
Josh McKinney
5b51018501
feat(chart): add GraphType::Bar (#1205)
![Demo](https://vhs.charm.sh/vhs-50v7I5n7lQF7tHCb1VCmFc.gif)
2024-07-15 20:47:50 -07:00
Liv Haze
935a7187c2
docs(examples): add missing examples to README (#1225)
Resolves: #1014
2024-07-09 21:13:26 -07:00
Liv Haze
50e5674a20
docs(examples): fix typos in tape files (#1224) 2024-07-08 21:57:04 -07:00
Liv Haze
810da72f26
docs(examples): fix hyperlink example tape (#1222) 2024-07-07 20:50:46 -07:00
Josh McKinney
46977d8851
feat(list)!: add list navigation methods (first, last, previous, next) (#1159)
Also cleans up the list example significantly (see also
<https://github.com/ratatui-org/ratatui/issues/1157>)
    
Fixes: <https://github.com/ratatui-org/ratatui/pull/1159>
    
BREAKING CHANGE: The `List` widget now clamps the selected index to the
bounds of the list when navigating with `first`, `last`, `previous`, and
`next`, as well as when setting the index directly with `select`.
2024-06-24 11:37:22 +03:00
Josh McKinney
3f2f2cd6ab
feat(docs): add tracing example (#1192)
Add an example that demonstrates logging to a file for:

<https://forum.ratatui.rs/t/how-do-you-println-debug-your-tui-programs/66>

```shell
cargo run --example tracing
RUST_LOG=trace cargo run --example=tracing
cat tracing.log
```

![Made with VHS](https://vhs.charm.sh/vhs-21jgJCedh2YnFDONw0JW7l.gif)
2024-06-19 17:29:19 -07:00
Josh McKinney
07efde5233
docs(examples): add hyperlink example (#1063) 2024-06-17 15:11:02 -07:00
EdJoPaTo
7d175f85c1
refactor(lint): fix new lint warnings (#1178) 2024-06-14 11:26:57 +02:00
Josh McKinney
7fdccafd52
docs(examples): add vhs tapes for constraint-explorer and minimal examples (#1164) 2024-06-08 19:28:07 +03:00
Josh McKinney
4f307e69db
docs(examples): simplify paragraph example (#1169)
Related: https://github.com/ratatui-org/ratatui/issues/1157
2024-06-05 17:41:46 -07:00
Josh McKinney
8061813f32
refactor: expand glob imports (#1152)
Consensus is that explicit imports make it easier to understand the
example code. This commit removes the prelude import from all examples
and replaces it with the necessary imports, and expands other glob
imports (widget::*, Constraint::*, KeyCode::*, etc.) everywhere else.
Prelude glob imports not in examples are not covered by this PR.

See https://github.com/ratatui-org/ratatui/issues/1150 for more details.
2024-05-29 04:42:29 -07:00
Josh McKinney
74a32afbae
feat: re-export backends from the ratatui crate (#1151)
`crossterm`, `termion`, and `termwiz` can now be accessed as
`ratatui::{crossterm, termion, termwiz}` respectively. This makes it
possible to just add the Ratatui crate as a dependency and use the
backend of choice without having to add the backend crates as
dependencies.

To update existing code, replace all instances of `crossterm::` with
`ratatui::crossterm::`, `termion::` with `ratatui::termion::`, and
`termwiz::` with `ratatui::termwiz::`.
2024-05-28 13:23:39 -07:00
EdJoPaTo
8b447ec4d6
perf(rect)!: Rect::inner takes Margin directly instead of reference (#1008)
BREAKING CHANGE: Margin needs to be passed without reference now.

```diff
-let area = area.inner(&Margin {
+let area = area.inner(Margin {
     vertical: 0,
     horizontal: 2,
 });
```
2024-05-26 19:44:46 +02:00
EdJoPaTo
8a60a561c9
refactor: needless_pass_by_ref_mut (#1137)
<https://rust-lang.github.io/rust-clippy/master/index.html#needless_pass_by_ref_mut>
2024-05-24 18:32:22 -07:00
Matt Armstrong
f429f688da
docs(examples): Remove lifetimes from the List example (#1132)
Simplify the List example by removing lifetimes not strictly necessary
to demonstrate how Ratatui lists work. Instead, the sample strings are
copied into each `TodoItem`. To further simplify, I changed the code to
use a new TodoItem::new function, rather than an implementation of the
`From` trait.
2024-05-24 15:09:24 -07:00
Mikołaj Nowak
eef1afe915
feat(LineGauge): allow LineGauge background styles (#565)
This PR deprecates `gauge_style` in favor of `filled_style` and
`unfilled_style` which can have it's foreground and background styled.

`cargo run --example=line_gauge --features=crossterm`

https://github.com/ratatui-org/ratatui/assets/5149215/5fb2ce65-8607-478f-8be4-092e08612f5b

Implements: <https://github.com/ratatui-org/ratatui/issues/424>

Co-authored-by: Josh McKinney <joshka@users.noreply.github.com>
2024-05-24 11:42:52 -07:00
EdJoPaTo
bf2036987f
refactor(cell): reset instead of applying default (#1127)
Using reset is clearer to me what actually happens. On the other case a
struct is created to override the old one completely which basically
does the same in a less clear way.
2024-05-21 22:11:45 -07:00
Josh McKinney
828d17a3f5
docs: add minimal example (#1114) 2024-05-18 21:18:59 -07:00
EdJoPaTo
2cfe82a47e
refactor(buffer): deprecate assert_buffer_eq! in favor of assert_eq! (#1007)
- Simplify `assert_buffer_eq!` logic.
- Deprecate `assert_buffer_eq!`.
- Introduce `TestBackend::assert_buffer_lines`.

Also simplify many tests involving buffer comparisons.

For the deprecation, just use `assert_eq` instead of `assert_buffer_eq`:

```diff
-assert_buffer_eq!(actual, expected);
+assert_eq!(actual, expected);
```

---

I noticed `assert_buffer_eq!` creating no test coverage reports and
looked into this macro. First I simplified it. Then I noticed a bunch of
`assert_eq!(buffer, …)` and other indirect usages of this macro (like
`TestBackend::assert_buffer`).

The good thing here is that it's mainly used in tests so not many
changes to the library code.
2024-05-13 18:13:46 -07:00
EdJoPaTo
366c2a0e6d
perf(block): use Block::bordered (#1041)
`Block::bordered()` is shorter than
`Block::new().borders(Borders::ALL)`, requires one less import
(`Borders`) and in case `Block::default()` was used before can even be
`const`.
2024-05-02 03:09:48 -07:00