tui
A library to build rich terminal user interfaces or dashboards
0.19.0
7.1M downloads/mo
#3759 most downloaded on crates.io
fdehau/tui-rs
What this package is like to depend on
Last release 4 years ago
no release in 18 months
Ships fairly regularly
a new release about every 2 months
Most releases are documented
notes for 29 of 33 stable releases
Nothing withdrawn
no release was ever pulled
10 years old
37 releases · first in 2016
0 releases in the last 12 months
see the full history below
Release timeline
37 releases · Nov 2016 to Aug 2022Releases
latest 37-
0.19.014 Aug 2022 -
0.18.024 Apr 2022 -
0.17.022 Jan 2022Release notes
Open source →Features
- Add option to
widgets::Listto repeat the hightlight symbol for each line of multi-line items (#533). - Add option to control the alignment of
Axislabels in theChartwidget (#568).
Breaking changes
- The minimum supported rust version is now
1.56.1.
New default backend and consolidated backend options (#553)
crosstermis now the default backend.
If you are already using thecrosstermbackend, you can simplify your dependency specification inCargo.toml:
- tui = { version = "0.16", default-features = false, features = ["crossterm"] } + tui = "0.17"
If you are using the
termionbackend, yourCargois now a bit more verbose:- tui = "0.16" + tui = { version = "0.17", default-features = false, features = ["termion"] }
crosstermhas also been bumped to version0.22.Because of their apparent low usage,
cursesandrustboxbackends have been removed.
If you are using one of them, you can import their last implementation in your own project:Canvas labels (#543)
- Labels of the
Canvaswidget are nowtext::Spans.
The signature ofwidgets::canvas::Context::printhas thus been updated:
- ctx.print(x, y, "Some text", Color::Yellow); + ctx.print(x, y, Span::styled("Some text", Style::default().fg(Color::Yellow)))
Release notes
Open source →Features
- Add option to
widgets::Listto repeat the hightlight symbol for each line of multi-line items (#533). - Add option to control the alignment of
Axislabels in theChartwidget (#568).
Breaking changes
- The minimum supported rust version is now
1.56.1.
New default backend and consolidated backend options (#553)
crosstermis now the default backend. If you are already using thecrosstermbackend, you can simplify your dependency specification inCargo.toml:
- tui = { version = "0.16", default-features = false, features = ["crossterm"] } + tui = "0.17"If you are using the
termionbackend, yourCargois now a bit more verbose:- tui = "0.16" + tui = { version = "0.17", default-features = false, features = ["termion"] }crosstermhas also been bumped to version0.22.Because of their apparent low usage,
cursesandrustboxbackends have been removed. If you are using one of them, you can import their last implementation in your own project:Canvas labels (#543)
- Labels of the
Canvaswidget are nowtext::Spans. The signature ofwidgets::canvas::Context::printhas thus been updated:
- ctx.print(x, y, "Some text", Color::Yellow); + ctx.print(x, y, Span::styled("Some text", Style::default().fg(Color::Yellow))) - Add option to
-
0.16.001 Aug 2021Release notes
Open source →Features
- Update
crosstermto0.20. - Add
From<Cow<str>>implementation fortext::Text(#471). - Add option to right or center align the title of a
widgets::Block(#462).
Fixes
- Apply label style in
widgets::Gaugeand avoid panics because of overflows with long labels (#494). - Avoid panics because of overflows with long axis labels in
widgets::Chart(#512). - Fix computation of column widths in
widgets::Table(#514). - Fix panics because of invalid offset when input changes between two frames in
widgets::Listand
widgets::Chart(#516).
Release notes
Open source →Features
- Update
crosstermto0.20. - Add
From<Cow<str>>implementation fortext::Text(#471). - Add option to right or center align the title of a
widgets::Block(#462).
Fixes
- Apply label style in
widgets::Gaugeand avoid panics because of overflows with long labels (#494). - Avoid panics because of overflows with long axis labels in
widgets::Chart(#512). - Fix computation of column widths in
widgets::Table(#514). - Fix panics because of invalid offset when input changes between two frames in
widgets::Listandwidgets::Chart(#516).
- Update
-
0.15.002 May 2021Release notes
Open source →Features
- Update
crosstermto0.19. - Update
randto0.8. - Add a read-only view of the terminal state after the draw call (#440).
Fixes
- Remove compile warning in
TestBackend::assert_buffer(#466).
Release notes
Open source →Features
- Update
crosstermto0.19. - Update
randto0.8. - Add a read-only view of the terminal state after the draw call (#440).
Fixes
- Remove compile warning in
TestBackend::assert_buffer(#466).
- Update
-
0.14.001 Jan 2021Release notes
Open source →Breaking changes
New API for the Table widget
The
Tablewidget got a lot of improvements that should make it easier to work with:- It should not longer panic when rendered on small areas.
Rows are now a collection ofCells, themselves wrapping aText. This means you can style
the entireTable, an entireRow, an entireCelland rely on the styling capabilities of
Textto get full control over the look of yourTable.Rows can have multiple lines.- The header is now optional and is just another
Rowalways visible at the top. Rows can have a bottom margin.- The header alignment is no longer off when an item is selected.
Taking the example of the code in
examples/demo/ui.rs, this is what you may have to change:let failure_style = Style::default() .fg(Color::Red) .add_modifier(Modifier::RAPID_BLINK | Modifier::CROSSED_OUT); - let header = ["Server", "Location", "Status"]; let rows = app.servers.iter().map(|s| { let style = if s.status == "Up" { up_style } else { failure_style }; - Row::StyledData(vec![s.name, s.location, s.status].into_iter(), style) + Row::new(vec![s.name, s.location, s.status]).style(style) }); - let table = Table::new(header.iter(), rows) + let table = Table::new(rows) + .header( + Row::new(vec!["Server", "Location", "Status"]) + .style(Style::default().fg(Color::Yellow)) + .bottom_margin(1), + ) .block(Block::default().title("Servers").borders(Borders::ALL)) - .header_style(Style::default().fg(Color::Yellow)) .widths(&[ Constraint::Length(15), Constraint::Length(15),Here, we had to:
- Change the way we construct
Rowwhich is no
longer anenumbut astruct. It accepts anything that can be converted to an iterator of things
that can be converted to aCell - The header is no longer a required parameter so we use
Table::headerto set it.
Table::header_stylehas been removed since the style can be directly set using
Row::style. In addition, we want
to preserve the old margin between the header and the rest of the rows so we add a bottom margin to
the header using
Row::bottom_margin.
You may want to look at the documentation of the different types to get a better understanding:
Fixes
- Fix handling of Non Breaking Space (NBSP) in wrapped text in
Paragraphwidget.
Features
- Add
Style::resetto create aStyleresetting all styling properties when applied. - Add an option to render the
Gaugewidget with unicode blocks. - Manage common project tasks with
cargo-makerather thanmakefor easier on-boarding.
Release notes
Open source →Breaking changes
New API for the Table widget
The
Tablewidget got a lot of improvements that should make it easier to work with:- It should not longer panic when rendered on small areas.
Rows are now a collection ofCells, themselves wrapping aText. This means you can style the entireTable, an entireRow, an entireCelland rely on the styling capabilities ofTextto get full control over the look of yourTable.Rows can have multiple lines.- The header is now optional and is just another
Rowalways visible at the top. Rows can have a bottom margin.- The header alignment is no longer off when an item is selected.
Taking the example of the code in
examples/demo/ui.rs, this is what you may have to change:let failure_style = Style::default() .fg(Color::Red) .add_modifier(Modifier::RAPID_BLINK | Modifier::CROSSED_OUT); - let header = ["Server", "Location", "Status"]; let rows = app.servers.iter().map(|s| { let style = if s.status == "Up" { up_style } else { failure_style }; - Row::StyledData(vec![s.name, s.location, s.status].into_iter(), style) + Row::new(vec![s.name, s.location, s.status]).style(style) }); - let table = Table::new(header.iter(), rows) + let table = Table::new(rows) + .header( + Row::new(vec!["Server", "Location", "Status"]) + .style(Style::default().fg(Color::Yellow)) + .bottom_margin(1), + ) .block(Block::default().title("Servers").borders(Borders::ALL)) - .header_style(Style::default().fg(Color::Yellow)) .widths(&[ Constraint::Length(15), Constraint::Length(15),Here, we had to:
- Change the way we construct
Rowwhich is no longer anenumbut astruct. It accepts anything that can be converted to an iterator of things that can be converted to aCell - The header is no longer a required parameter so we use
Table::headerto set it.Table::header_stylehas been removed since the style can be directly set usingRow::style. In addition, we want to preserve the old margin between the header and the rest of the rows so we add a bottom margin to the header usingRow::bottom_margin.
You may want to look at the documentation of the different types to get a better understanding:
Fixes
- Fix handling of Non Breaking Space (NBSP) in wrapped text in
Paragraphwidget.
Features
- Add
Style::resetto create aStyleresetting all styling properties when applied. - Add an option to render the
Gaugewidget with unicode blocks. - Manage common project tasks with
cargo-makerather thanmakefor easier on-boarding.
-
0.13.014 Nov 2020Release notes
Open source →Features
- Add
LineGaugewidget which is a more compact variant of the existingGauge. - Bump
crosstermto 0.18
Fixes
- Take into account the borders of the
Tablewidget when the widths of columns is controlled by
PercentageandRatioconstraints.
Release notes
Open source →Features
- Add
LineGaugewidget which is a more compact variant of the existingGauge. - Bump
crosstermto 0.18
Fixes
- Take into account the borders of the
Tablewidget when the widths of columns is controlled byPercentageandRatioconstraints.
- Add
-
0.12.027 Sep 2020Release notes
Open source →Release notes
Open source →Features
- Make it easier to work with string with multiple lines in
Text(#361).
Fixes
- Fix a style leak in
Graphso components drawn on top of the plotted data (i.e legend and axis titles) are not affected by the style of theDatasets (#388). - Make sure
BarChartshows bars with the max height only when the plotted data is actually equal to the max (#383).
- Make it easier to work with string with multiple lines in
-
0.11.020 Sep 2020Release notes
Open source →Features
- Add the dot character as a new type of canvas marker (#350).
- Support more style modifiers on Windows (#368).
Fixes
Release notes
Open source →Features
- Add the dot character as a new type of canvas marker (#350).
- Support more style modifiers on Windows (#368).
Fixes
- Clearing the terminal through
Terminal::clearwill cause the whole UI to be redrawn (#380). - Fix incorrect output when the first diff to draw is on the second cell of the terminal (#347).
-
0.10.018 Jul 2020Release notes
Open source →Breaking changes
Easier cursor management
A new method has been added to
Framecalledset_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:
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 Frameinstead ofmut 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.Textis 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
Fromimplementations 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
Blockcan be set in the following ways:// 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_spansandBuffer::set_spanwere added.Paragraph::newexpects an input that can be converted to aText.Block::title_styleis deprecated.Block::titleexpects aSpans.Tabsexpects a list ofSpans.Gaugecustom label is now aSpan.Axistitle and labels areSpans(as a consequenceChartno longer has generic bounds).
Incremental styling
Previously
Stylewas 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 aBlockwhere you wanted to have a green background and
a title in bold, you had to do the following: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:
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
patchto combine two styles into a new set of style
rules: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::modifierhas been removed in favor ofStyle::add_modifierandStyle::remove_modifier.Buffer::set_stylehas been added.Buffer::set_backgroundis deprecated.BarChart::styleno longer set the style of the bars. UseBarChart::bar_stylein replacement.Gauge::styleno longer set the style of the gauge. UseGauge::gauge_stylein replacement.
List with item on multiple lines
The
Listwidget has been refactored once again to support items with variable heights and complex
styling.List::newexpects an input that can be converted to aVec<ListItem>whereListItemis a
wrapper around the item content to provide additional styling capabilities.ListItemcontains a
Text.List::itemshas been removed.
// 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::wrapexpectsWrapinstead ofboolto let users decided whether they want to trim
whitespaces when the text is wrapped.// 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 ofParagraph::scrollhas thus be
changed fromu16to(u16, u16).Features
Serialization of style
You can now serialize and de-serialize
Styleusing the optionalserdefeature.Release notes
Open source →Breaking changes
Easier cursor management
A new method has been added to
Framecalledset_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:
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 Frameinstead ofmut 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.
Textis 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
Fromimplementations 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
Blockcan be set in the following ways:// 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_spansandBuffer::set_spanwere added.Paragraph::newexpects an input that can be converted to aText.Block::title_styleis deprecated.Block::titleexpects aSpans.Tabsexpects a list ofSpans.Gaugecustom label is now aSpan.Axistitle and labels areSpans(as a consequenceChartno longer has generic bounds).
Incremental styling
Previously
Stylewas 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 aBlockwhere you wanted to have a green background and a title in bold, you had to do the following: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:
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
patchto combine two styles into a new set of style rules: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 overiddenStyle::modifierhas been removed in favor ofStyle::add_modifierandStyle::remove_modifier.Buffer::set_stylehas been added.Buffer::set_backgroundis deprecated.BarChart::styleno longer set the style of the bars. UseBarChart::bar_stylein replacement.Gauge::styleno longer set the style of the gauge. UseGauge::gauge_stylein replacement.
List with item on multiple lines
The
Listwidget has been refactored once again to support items with variable heights and complex styling.List::newexpects an input that can be converted to aVec<ListItem>whereListItemis a wrapper around the item content to provide additional styling capabilities.ListItemcontains aText.List::itemshas been removed.
// 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::wrapexpectsWrapinstead ofboolto let users decided whether they want to trim whitespaces when the text is wrapped.// 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 behaviorHorizontal scrolling in paragraph
You can now scroll horizontally in
Paragraph. The argument ofParagraph::scrollhas thus be changed fromu16to(u16, u16).Features
Serialization of style
You can now serialize and de-serialize
Styleusing the optionalserdefeature. -
0.9.521 May 2020Release notes
Open source →Bug Fixes
- Fix out of bounds panic in
widgets::Tabswhen the widget is rendered on small areas.
- Fix out of bounds panic in
-
0.9.412 May 2020 -
0.9.310 May 2020Release notes
Open source →Bug Fixes
- Fix usize overflows in
widgets::Chartwhen a dataset is empty.
- Fix usize overflows in
-
0.9.210 May 2020Release notes
Open source →Bug Fixes
- Fix usize overflows in
widgets::canvas::Linedrawing algorithm.
- Fix usize overflows in
-
0.9.116 Apr 2020Release notes
Open source →Bug Fixes
- The
Listwidget now takes into account the width of thehighlight_symbolwhen calculating the total width of its items. It prevents items to overflow outside of the widget area.
- The
-
0.9.014 Apr 2020Release notes
Open source →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
Tablerow to be selected.
// 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_typeproperty on theDatasetof aChartwidget. By default it will beScatterwhere the points are drawn as is. An other option isLinewhere a line will be draw between each consecutive points of the dataset. - Style methods are now const, allowing you to initialize const
Styleobjects. - Improve control over whether the legend in the
Chartwidget is shown or not. You can now set custom constraints usingChart::hidden_legend_constraints. - Add
Table::header_gapto add some space between the header and the first row. - Remove
logfrom 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_setandCanvas::marker). You can check how the--enhanced-graphicsflag is used in the demos.
Breaking Changes
Widget::renderhas been deleted. You should now useFrame::render_widgetto render a widget on the correspondingFrame. This makes theWidgetimplementation totally decoupled from theFrame.
// Before Block::default().render(&mut f, size); // After let block = Block::default(); f.render_widget(block, size);Widget::drawhas been renamed toWidget::renderand the signature has been updated to reflect that widgets are consumable objects. Thus the method takesselfinstead of&mut self.
// 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::backgroundhas been replaced byBuffer::set_background
// 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
Shapetrait for objects that can be draw on aCanvaswidgets. Instead of returning an iterator over its points, aShapeis given aPainterobject that provides apaintas well as aget_pointmethod. This gives theShapemore information about the surface it will be drawn to. In particular, this change allows theLineshape to use a more precise and efficient drawing algorithm (Bresenham's line algorithm). SelectableListhas been deleted. You can now take advantage of the associatedListStateof theListwidget to select an item.
// 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::Markerhas been moved tosymbols::Marker
-
0.8.015 Dec 2019Release notes
Open source →Breaking Changes
- Bump crossterm to 0.14.
- Add cross symbol to the symbols list.
Bug Fixes
- Use the value of
title_styleto style the title ofAxis.
-
0.7.029 Nov 2019Release notes
Open source →Breaking Changes
- Use
Constraintinstead of integers to specify the widths of theTablewidget's columns. This will allow more responsive tables.
Table::new(header, row) .widths(&[15, 15, 10]) .render(f, chunk);becomes:
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.
- Use
-
0.6.216 Jul 2019Release notes
Open source →Features
Textimplements PartialEq
Bug Fixes
- Avoid overflow errors in canvas
-
0.6.116 Jun 2019Release notes
Open source →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.
-
0.6.018 May 2019 -
0.5.114 Apr 2019 -
0.5.010 Mar 2019Release notes
Open source →Features
- Add a new curses backend (with Windows support thanks to
pancurses). - Add
Backend::get_cursorandBackend::set_cursormethods to query and set the position of the cursor. - Add more constructors to the
Crosstermbackend. - Add a demo for all backends using a shared UI and application state.
- Add
Ratioas a new variant of layoutConstraint. It can be used to define exact ratios constraints.
Breaking Changes
- Add support for multiple modifiers on the same
Styleby changingModifierfrom an enum to a bitflags struct.
So instead of writing:
let style = Style::default().add_modifier(Modifier::Italic);one should use:
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
Crosstermbackend. - Fix out of bounds panic when two
Bufferare merged.
- Add a new curses backend (with Windows support thanks to
-
0.4.003 Feb 2019Release notes
Open source →Features
- Add a new canvas shape:
Rectangle. - Official support of
Crosstermbackend. - 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.
- Add a new canvas shape:
-
0.3.004 Nov 2018 -
0.3.0-beta.324 Sep 2018 pre-releaseRelease notes
Open source →Features
show_cursoris called whenTerminalis dropped if the cursor is hidden.
-
0.3.0-beta.223 Sep 2018 pre-releaseRelease notes
Open source →Breaking Changes
- Remove custom
termionbackends. This is motivated by the fact thattermionstructs 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 ofstdout:
let stdout = io::stdout().into_raw_mode()?; let stdout = MouseTerminal::from(stdout); let stdout = AlternateScreen::from(stdout);and then to create the corresponding
termionbackend:let backend = TermionBackend::new(stdout);The resulting code is more verbose but it works with all combinations of additional
termionfeatures. - Remove custom
-
0.3.0-beta.108 Sep 2018 pre-releaseRelease notes
Open source →Breaking Changes
- Replace
Itemby a generic and flexibleTextthat can be used in bothParagraphandListwidgets. - Remove unecessary borrows on
Style.
- Replace
-
0.3.0-beta.004 Sep 2018 pre-releaseRelease notes
Open source →Features
- Add a basic
Crosstermbackend
Breaking Changes
- Remove
Groupand introduceLayoutin its placeTerminalis no longer required to compute a layoutSizehas been renamedConstraint
- Widgets are rendered on a
Frameinstead of aTerminalin order to avoid mixingdrawandrendercalls drawonTerminalexpects a closure where the UI is built by rendering widgets on the givenFrame- Update
Widgettraitdrawtakes area by valuerendertakes aFrameinstead of aTerminal
- All widgets use the consumable builder pattern
SelectableListcan have no selected item and the highlight symbol is hidden in this case- Remove markup langage inside
Paragraph.Paragraphnow expects an iterator ofTextitems
- Add a basic
-
0.2.309 Jun 2018Release notes
Open source →Features
- Add
start_corneroption forList - Add more text aligment options for
Paragraph
- Add
-
0.2.206 May 2018Release notes
Open source →Features
TerminalimplementsDebug
Breaking Changes
- Use
FnOnceinstead ofFnMutin Group::render
-
0.2.101 Apr 2018Release notes
Open source →Features
- Add
AlternateScreenBackendintermionbackend - Add
TermionBackend::with_stdoutin 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_assertinBuffer::pos_of - Pass the style of
SelectableListto the underlyingList - Fix missing character when wrapping text
- Fix panic when specifying layout constraints
- Add
-
0.2.026 Dec 2017Release notes
Open source →Features
- Add
MouseBackendintermionbackend to handle scroll and mouse events - Add generic
Itemfor items in aList - Drop
log4rsas a dev-dependencies in favor ofstderrlog
Breaking Changes
- Rename
TermionBackendtoRawBackend(to distinguish it from theMouseBackend) - Generic parameters for
Listto allow passing iterators as items - Generic parameters for
Tableto allow using iterators as rows and header - Generic parameters for
Tabs - Rename
borderbitflags toBorders
- Add
-
0.1.315 Jun 2017Nothing published for this version
-
0.1.225 Dec 2016Nothing published for this version
-
0.1.128 Nov 2016Nothing published for this version
-
0.1.008 Nov 2016Nothing published for this version