| # Changelog |
| |
| ## To be released |
| |
| ## v0.10.0 - 2020-07-17 |
| |
| ### Breaking changes |
| |
| #### Easier cursor management |
| |
| A new method has been added to `Frame` called `set_cursor`. It lets you specify where the cursor |
| should be placed after the draw call. Furthermore like any other widgets, if you do not set a cursor |
| position during a draw call, the cursor is automatically hidden. |
| |
| For example: |
| |
| ```rust |
| fn draw_input(f: &mut Frame, app: &App) { |
| if app.editing { |
| let input_width = app.input.width() as u16; |
| // The cursor will be placed just after the last character of the input |
| f.set_cursor((input_width + 1, 0)); |
| } else { |
| // We are no longer editing, the cursor does not have to be shown, set_cursor is not called and |
| // thus automatically hidden. |
| } |
| } |
| ``` |
| |
| In order to make this possible, the draw closure takes in input `&mut Frame` instead of `mut Frame`. |
| |
| #### Advanced text styling |
| |
| It has been reported several times that the text styling capabilities were somewhat limited in many |
| places of the crate. To solve the issue, this release includes a new set of text primitives that are |
| now used by a majority of widgets to provide flexible text styling. |
| |
| `Text` is replaced by the following types: |
| - `Span`: a string with a unique style. |
| - `Spans`: a string with multiple styles. |
| - `Text`: a multi-lines string with multiple styles. |
| |
| However, you do not always need this complexity so the crate provides `From` implementations to |
| let you use simple strings as a default and switch to the previous primitives when you need |
| additional styling capabilities. |
| |
| For example, the title of a `Block` can be set in the following ways: |
| |
| ```rust |
| // A title with no styling |
| Block::default().title("My title"); |
| // A yellow title |
| Block::default().title(Span::styled("My title", Style::default().fg(Color::Yellow))); |
| // A title where "My" is bold and "title" is a simple string |
| Block::default().title(vec![ |
| Span::styled("My", Style::default().add_modifier(Modifier::BOLD)), |
| Span::from("title") |
| ]); |
| ``` |
| |
| - `Buffer::set_spans` and `Buffer::set_span` were added. |
| - `Paragraph::new` expects an input that can be converted to a `Text`. |
| - `Block::title_style` is deprecated. |
| - `Block::title` expects a `Spans`. |
| - `Tabs` expects a list of `Spans`. |
| - `Gauge` custom label is now a `Span`. |
| - `Axis` title and labels are `Spans` (as a consequence `Chart` no longer has generic bounds). |
| |
| #### Incremental styling |
| |
| Previously `Style` was used to represent an exhaustive set of style rules to be applied to an UI |
| element. It implied that whenever you wanted to change even only one property you had to provide the |
| complete style. For example, if you had a `Block` where you wanted to have a green background and |
| a title in bold, you had to do the following: |
| |
| ```rust |
| let style = Style::default().bg(Color::Green); |
| Block::default() |
| .style(style) |
| .title("My title") |
| // Here we reused the style otherwise the background color would have been reset |
| .title_style(style.modifier(Modifier::BOLD)); |
| ``` |
| |
| In this new release, you may now write this as: |
| |
| ```rust |
| Block::default() |
| .style(Style::default().bg(Color::Green)) |
| // The style is not overidden anymore, we simply add new style rule for the title. |
| .title(Span::styled("My title", Style::default().add_modifier(Modifier::BOLD))) |
| ``` |
| |
| In addition, the crate now provides a method `patch` to combine two styles into a new set of style |
| rules: |
| |
| ```rust |
| let style = Style::default().modifer(Modifier::BOLD); |
| let style = style.patch(Style::default().add_modifier(Modifier::ITALIC)); |
| // style.modifer == Modifier::BOLD | Modifier::ITALIC, the modifier has been enriched not overidden |
| ``` |
| |
| - `Style::modifier` has been removed in favor of `Style::add_modifier` and `Style::remove_modifier`. |
| - `Buffer::set_style` has been added. `Buffer::set_background` is deprecated. |
| - `BarChart::style` no longer set the style of the bars. Use `BarChart::bar_style` in replacement. |
| - `Gauge::style` no longer set the style of the gauge. Use `Gauge::gauge_style` in replacement. |
| |
| #### List with item on multiple lines |
| |
| The `List` widget has been refactored once again to support items with variable heights and complex |
| styling. |
| |
| - `List::new` expects an input that can be converted to a `Vec<ListItem>` where `ListItem` is a |
| wrapper around the item content to provide additional styling capabilities. `ListItem` contains a |
| `Text`. |
| - `List::items` has been removed. |
| |
| ```rust |
| // Before |
| let items = vec![ |
| "Item1", |
| "Item2", |
| "Item3" |
| ]; |
| List::default().items(items.iters()); |
| |
| // After |
| let items = vec![ |
| ListItem::new("Item1"), |
| ListItem::new("Item2"), |
| ListItem::new("Item3"), |
| ]; |
| List::new(items); |
| ``` |
| |
| See the examples for more advanced usages. |
| |
| #### More wrapping options |
| |
| `Paragraph::wrap` expects `Wrap` instead of `bool` to let users decided whether they want to trim |
| whitespaces when the text is wrapped. |
| |
| ```rust |
| // before |
| Paragraph::new(text).wrap(true) |
| // after |
| Paragraph::new(text).wrap(Wrap { trim: true }) // to have the same behavior |
| Paragraph::new(text).wrap(Wrap { trim: false }) // to use the new behavior |
| ``` |
| |
| #### Horizontal scrolling in paragraph |
| |
| You can now scroll horizontally in `Paragraph`. The argument of `Paragraph::scroll` has thus be |
| changed from `u16` to `(u16, u16)`. |
| |
| ### Features |
| |
| #### Serialization of style |
| |
| You can now serialize and de-serialize `Style` using the optional `serde` feature. |
| |
| ## v0.9.5 - 2020-05-21 |
| |
| ### Bug Fixes |
| |
| * Fix out of bounds panic in `widgets::Tabs` when the widget is rendered on |
| small areas. |
| |
| ## v0.9.4 - 2020-05-12 |
| |
| ### Bug Fixes |
| |
| * Ignore zero-width graphemes in `Buffer::set_stringn`. |
| |
| ## v0.9.3 - 2020-05-11 |
| |
| ### Bug Fixes |
| |
| * Fix usize overflows in `widgets::Chart` when a dataset is empty. |
| |
| ## v0.9.2 - 2020-05-10 |
| |
| ### Bug Fixes |
| |
| * Fix usize overflows in `widgets::canvas::Line` drawing algorithm. |
| |
| ## v0.9.1 - 2020-04-16 |
| |
| ### Bug Fixes |
| |
| * The `List` widget now takes into account the width of the `highlight_symbol` |
| when calculating the total width of its items. It prevents items to overflow |
| outside of the widget area. |
| |
| ## v0.9.0 - 2020-04-14 |
| |
| ### Features |
| |
| * Introduce stateful widgets, i.e widgets that can take advantage of keeping |
| some state around between two draw calls (#210 goes a bit more into the |
| details). |
| * Allow a `Table` row to be selected. |
| ```rust |
| // State initialization |
| let mut state = TableState::default(); |
| |
| // In the terminal.draw closure |
| let header = ["Col1", "Col2", "Col"]; |
| let rows = [ |
| Row::Data(["Row11", "Row12", "Row13"].into_iter()) |
| ]; |
| let table = Table::new(header.into_iter(), rows.into_iter()); |
| f.render_stateful_widget(table, area, &mut state); |
| |
| // In response to some event: |
| state.select(Some(1)); |
| ``` |
| * Add a way to choose the type of border used to draw a block. You can now |
| choose from plain, rounded, double and thick lines. |
| * Add a `graph_type` property on the `Dataset` of a `Chart` widget. By |
| default it will be `Scatter` where the points are drawn as is. An other |
| option is `Line` where a line will be draw between each consecutive points |
| of the dataset. |
| * Style methods are now const, allowing you to initialize const `Style` |
| objects. |
| * Improve control over whether the legend in the `Chart` widget is shown or |
| not. You can now set custom constraints using |
| `Chart::hidden_legend_constraints`. |
| * Add `Table::header_gap` to add some space between the header and the first |
| row. |
| * Remove `log` from the dependencies |
| * Add a way to use a restricted set of unicode symbols in several widgets to |
| improve portability in exchange of a degraded output. (see `BarChart::bar_set`, |
| `Sparkline::bar_set` and `Canvas::marker`). You can check how the |
| `--enhanced-graphics` flag is used in the demos. |
| |
| ### Breaking Changes |
| |
| * `Widget::render` has been deleted. You should now use `Frame::render_widget` |
| to render a widget on the corresponding `Frame`. This makes the `Widget` |
| implementation totally decoupled from the `Frame`. |
| ```rust |
| // Before |
| Block::default().render(&mut f, size); |
| |
| // After |
| let block = Block::default(); |
| f.render_widget(block, size); |
| ``` |
| * `Widget::draw` has been renamed to `Widget::render` and the signature has |
| been updated to reflect that widgets are consumable objects. Thus the method |
| takes `self` instead of `&mut self`. |
| ```rust |
| // Before |
| impl Widget for MyWidget { |
| fn draw(&mut self, area: Rect, buf: &mut Buffer) { |
| } |
| } |
| |
| /// After |
| impl Widget for MyWidget { |
| fn render(self, arera: Rect, buf: &mut Buffer) { |
| } |
| } |
| ``` |
| * `Widget::background` has been replaced by `Buffer::set_background` |
| ```rust |
| // Before |
| impl Widget for MyWidget { |
| fn render(self, arera: Rect, buf: &mut Buffer) { |
| self.background(area, buf, self.style.bg); |
| } |
| } |
| |
| // After |
| impl Widget for MyWidget { |
| fn render(self, arera: Rect, buf: &mut Buffer) { |
| buf.set_background(area, self.style.bg); |
| } |
| } |
| ``` |
| * Update the `Shape` trait for objects that can be draw on a `Canvas` widgets. |
| Instead of returning an iterator over its points, a `Shape` is given a |
| `Painter` object that provides a `paint` as well as a `get_point` method. This |
| gives the `Shape` more information about the surface it will be drawn to. In |
| particular, this change allows the `Line` shape to use a more precise and |
| efficient drawing algorithm (Bresenham's line algorithm). |
| * `SelectableList` has been deleted. You can now take advantage of the |
| associated `ListState` of the `List` widget to select an item. |
| ```rust |
| // Before |
| List::new(&["Item1", "Item2", "Item3"]) |
| .select(Some(1)) |
| .render(&mut f, area); |
| |
| // After |
| |
| // State initialization |
| let mut state = ListState::default(); |
| |
| // In the terminal.draw closure |
| let list = List::new(&["Item1", "Item2", "Item3"]); |
| f.render_stateful_widget(list, area, &mut state); |
| |
| // In response to some events |
| state.select(Some(1)); |
| ``` |
| * `widgets::Marker` has been moved to `symbols::Marker` |
| |
| ## v0.8.0 - 2019-12-15 |
| |
| ### Breaking Changes |
| |
| * Bump crossterm to 0.14. |
| * Add cross symbol to the symbols list. |
| |
| ### Bug Fixes |
| |
| * Use the value of `title_style` to style the title of `Axis`. |
| |
| ## v0.7.0 - 2019-11-29 |
| |
| ### Breaking Changes |
| |
| * Use `Constraint` instead of integers to specify the widths of the `Table` |
| widget's columns. This will allow more responsive tables. |
| |
| ```rust |
| Table::new(header, row) |
| .widths(&[15, 15, 10]) |
| .render(f, chunk); |
| ``` |
| |
| becomes: |
| |
| ```rust |
| Table::new(header, row) |
| .widths(&[ |
| Constraint::Length(15), |
| Constraint::Length(15), |
| Constraint::Length(10), |
| ]) |
| .render(f, chunk); |
| ``` |
| |
| * Bump crossterm to 0.13. |
| * Use Github Actions for CI (Travis and Azure Pipelines integrations have been deleted). |
| |
| ### Features |
| |
| * Add support for horizontal and vertical margins in `Layout`. |
| |
| ## v0.6.2 - 2019-07-16 |
| |
| ### Features |
| |
| * `Text` implements PartialEq |
| |
| ### Bug Fixes |
| |
| * Avoid overflow errors in canvas |
| |
| ## v0.6.1 - 2019-06-16 |
| |
| ### Bug Fixes |
| |
| * Avoid a division by zero when all values in a barchart are equal to 0. |
| * Fix the inverted cursor position in the curses backend. |
| * Ensure that the correct terminal size is returned when using the crossterm |
| backend. |
| * Avoid highlighting the separator after the selected item in the Tabs widget. |
| |
| ## v0.6.0 - 2019-05-18 |
| |
| ### Breaking Changes |
| |
| * Update crossterm backend |
| |
| ## v0.5.1 - 2019-04-14 |
| |
| ### Bug Fixes |
| |
| * Fix a panic in the Sparkline widget |
| |
| ## v0.5.0 - 2019-03-10 |
| |
| ### Features |
| |
| * Add a new curses backend (with Windows support thanks to `pancurses`). |
| * Add `Backend::get_cursor` and `Backend::set_cursor` methods to query and |
| set the position of the cursor. |
| * Add more constructors to the `Crossterm` backend. |
| * Add a demo for all backends using a shared UI and application state. |
| * Add `Ratio` as a new variant of layout `Constraint`. It can be used to define |
| exact ratios constraints. |
| |
| ### Breaking Changes |
| |
| * Add support for multiple modifiers on the same `Style` by changing `Modifier` |
| from an enum to a bitflags struct. |
| |
| So instead of writing: |
| |
| ```rust |
| let style = Style::default().add_modifier(Modifier::Italic); |
| ``` |
| |
| one should use: |
| |
| ```rust |
| let style = Style::default().add_modifier(Modifier::ITALIC); |
| // or |
| let style = Style::default().add_modifier(Modifier::ITALIC | Modifier::BOLD); |
| ``` |
| |
| ### Bug Fixes |
| |
| * Ensure correct behavoir of the alternate screens with the `Crossterm` backend. |
| * Fix out of bounds panic when two `Buffer` are merged. |
| |
| ## v0.4.0 - 2019-02-03 |
| |
| ### Features |
| |
| * Add a new canvas shape: `Rectangle`. |
| * Official support of `Crossterm` backend. |
| * Make it possible to choose the divider between `Tabs`. |
| * Add word wrapping on Paragraph. |
| * The gauge widget accepts a ratio (f64 between 0 and 1) in addition of a |
| percentage. |
| |
| ### Breaking Changes |
| |
| * Upgrade to Rust 2018 edition. |
| |
| ### Bug Fixes |
| |
| * Fix rendering of double-width characters. |
| * Fix race condition on the size of the terminal and expose a size that is |
| safe to use when drawing through `Frame::size`. |
| * Prevent unsigned int overflow on large screens. |
| |
| ## v0.3.0 - 2018-11-04 |
| |
| ### Features |
| |
| * Add experimental test backend |
| |
| ## v0.3.0-beta.3 - 2018-09-24 |
| |
| ### Features |
| |
| * `show_cursor` is called when `Terminal` is dropped if the cursor is hidden. |
| |
| ## v0.3.0-beta.2 - 2018-09-23 |
| |
| ### Breaking Changes |
| |
| * Remove custom `termion` backends. This is motivated by the fact that |
| `termion` structs are meant to be combined/wrapped to provide additional |
| functionalities to the terminal (e.g AlternateScreen, Mouse support, ...). |
| Thus providing exclusive types do not make a lot of sense and give a false |
| hint that additional features cannot be used together. The recommended |
| approach is now to create your own version of `stdout`: |
| |
| ```rust |
| let stdout = io::stdout().into_raw_mode()?; |
| let stdout = MouseTerminal::from(stdout); |
| let stdout = AlternateScreen::from(stdout); |
| ``` |
| |
| and then to create the corresponding `termion` backend: |
| |
| ```rust |
| let backend = TermionBackend::new(stdout); |
| ``` |
| |
| The resulting code is more verbose but it works with all combinations of |
| additional `termion` features. |
| |
| ## v0.3.0-beta.1 - 2018-09-08 |
| |
| ### Breaking Changes |
| |
| * Replace `Item` by a generic and flexible `Text` that can be used in both |
| `Paragraph` and `List` widgets. |
| * Remove unecessary borrows on `Style`. |
| |
| ## v0.3.0-beta.0 - 2018-09-04 |
| |
| ### Features |
| |
| * Add a basic `Crossterm` backend |
| |
| ### Breaking Changes |
| |
| * Remove `Group` and introduce `Layout` in its place |
| - `Terminal` is no longer required to compute a layout |
| - `Size` has been renamed `Constraint` |
| * Widgets are rendered on a `Frame` instead of a `Terminal` in order to |
| avoid mixing `draw` and `render` calls |
| * `draw` on `Terminal` expects a closure where the UI is built by rendering |
| widgets on the given `Frame` |
| * Update `Widget` trait |
| - `draw` takes area by value |
| - `render` takes a `Frame` instead of a `Terminal` |
| * All widgets use the consumable builder pattern |
| * `SelectableList` can have no selected item and the highlight symbol is hidden |
| in this case |
| * Remove markup langage inside `Paragraph`. `Paragraph` now expects an iterator |
| of `Text` items |
| |
| ## v0.2.3 - 2018-06-09 |
| |
| ### Features |
| |
| * Add `start_corner` option for `List` |
| * Add more text aligment options for `Paragraph` |
| |
| ## v0.2.2 - 2018-05-06 |
| |
| ### Features |
| |
| * `Terminal` implements `Debug` |
| |
| ### Breaking Changes |
| |
| * Use `FnOnce` instead of `FnMut` in Group::render |
| |
| ## v0.2.1 - 2018-04-01 |
| |
| ### Features |
| |
| * Add `AlternateScreenBackend` in `termion` backend |
| * Add `TermionBackend::with_stdout` in order to let an user of the library |
| provides its own termion struct |
| * Add tests and documentation for `Buffer::pos_of` |
| * Remove leading whitespaces when wrapping text |
| |
| ### Bug Fixes |
| |
| * Fix `debug_assert` in `Buffer::pos_of` |
| * Pass the style of `SelectableList` to the underlying `List` |
| * Fix missing character when wrapping text |
| * Fix panic when specifying layout constraints |
| |
| ## v0.2.0 - 2017-12-26 |
| |
| ### Features |
| |
| * Add `MouseBackend` in `termion` backend to handle scroll and mouse events |
| * Add generic `Item` for items in a `List` |
| * Drop `log4rs` as a dev-dependencies in favor of `stderrlog` |
| |
| ### Breaking Changes |
| |
| * Rename `TermionBackend` to `RawBackend` (to distinguish it from the `MouseBackend`) |
| * Generic parameters for `List` to allow passing iterators as items |
| * Generic parameters for `Table` to allow using iterators as rows and header |
| * Generic parameters for `Tabs` |
| * Rename `border` bitflags to `Borders` |