mirror of
https://github.com/ratatui/ratatui.git
synced 2025-09-28 05:21:23 +00:00
feat: accept Color and Modifier for all Styles (#720)
* feat: accept Color and Modifier for all Styles All style related methods now accept `S: Into<Style>` instead of `Style`. `Color` and `Modifier` implement `Into<Style>` so this is allows for more ergonomic usage. E.g.: ```rust Line::styled("hello", Style::new().red()); Line::styled("world", Style::new().bold()); // can now be simplified to Line::styled("hello", Color::Red); Line::styled("world", Modifier::BOLD); ``` Fixes https://github.com/ratatui-org/ratatui/issues/694 BREAKING CHANGE: All style related methods now accept `S: Into<Style>` instead of `Style`. This means that if you are already passing an ambiguous type that implements `Into<Style>` you will need to remove the `.into()` call. `Block` style methods can no longer be called from a const context as trait functions cannot (yet) be const. * feat: add tuple conversions to Style Adds conversions for various Color and Modifier combinations * chore: add unit tests
This commit is contained in:
parent
a62632a947
commit
8f56fabcdd
@ -12,6 +12,7 @@ This is a quick summary of the sections below:
|
||||
|
||||
- [v0.26.0 (unreleased)](#v0260-unreleased)
|
||||
- `Line` now has an extra `style` field which applies the style to the entire line
|
||||
- `Block` style methods cannot be created in a const context
|
||||
- [v0.25.0](#v0250)
|
||||
- Removed `Axis::title_style` and `Buffer::set_background`
|
||||
- `List::new()` now accepts `IntoIterator<Item = Into<ListItem<'a>>>`
|
||||
@ -43,6 +44,14 @@ This is a quick summary of the sections below:
|
||||
|
||||
## v0.26.0 (unreleased)
|
||||
|
||||
### `Block` style methods cannot be used in a const context ([#720])
|
||||
|
||||
[#720]: https://github.com/ratatui-org/ratatui/pull/720
|
||||
|
||||
Previously the `style()`, `border_style()` and `title_style()` methods could be used to create a
|
||||
`Block` in a constant context. These now accept `Into<Style>` instead of `Style`. These methods no
|
||||
longer can be called from a constant context.
|
||||
|
||||
### `Line` now has a `style` field that applies to the entire line ([#708])
|
||||
|
||||
[#708]: https://github.com/ratatui-org/ratatui/pull/708
|
||||
|
@ -175,7 +175,7 @@ fn make_dates(current_year: i32) -> CalendarEventStore {
|
||||
mod cals {
|
||||
use super::*;
|
||||
|
||||
pub(super) fn get_cal<'a, S: DateStyler>(m: Month, y: i32, es: S) -> Monthly<'a, S> {
|
||||
pub(super) fn get_cal<'a, DS: DateStyler>(m: Month, y: i32, es: DS) -> Monthly<'a, DS> {
|
||||
use Month::*;
|
||||
match m {
|
||||
May => example1(m, y, es),
|
||||
@ -188,7 +188,7 @@ mod cals {
|
||||
}
|
||||
}
|
||||
|
||||
fn default<'a, S: DateStyler>(m: Month, y: i32, es: S) -> Monthly<'a, S> {
|
||||
fn default<'a, DS: DateStyler>(m: Month, y: i32, es: DS) -> Monthly<'a, DS> {
|
||||
let default_style = Style::default()
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.bg(Color::Rgb(50, 50, 50));
|
||||
@ -198,7 +198,7 @@ mod cals {
|
||||
.default_style(default_style)
|
||||
}
|
||||
|
||||
fn example1<'a, S: DateStyler>(m: Month, y: i32, es: S) -> Monthly<'a, S> {
|
||||
fn example1<'a, DS: DateStyler>(m: Month, y: i32, es: DS) -> Monthly<'a, DS> {
|
||||
let default_style = Style::default()
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.bg(Color::Rgb(50, 50, 50));
|
||||
@ -209,7 +209,7 @@ mod cals {
|
||||
.show_month_header(Style::default())
|
||||
}
|
||||
|
||||
fn example2<'a, S: DateStyler>(m: Month, y: i32, es: S) -> Monthly<'a, S> {
|
||||
fn example2<'a, DS: DateStyler>(m: Month, y: i32, es: DS) -> Monthly<'a, DS> {
|
||||
let header_style = Style::default()
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.add_modifier(Modifier::DIM)
|
||||
@ -225,7 +225,7 @@ mod cals {
|
||||
.show_month_header(Style::default())
|
||||
}
|
||||
|
||||
fn example3<'a, S: DateStyler>(m: Month, y: i32, es: S) -> Monthly<'a, S> {
|
||||
fn example3<'a, DS: DateStyler>(m: Month, y: i32, es: DS) -> Monthly<'a, DS> {
|
||||
let header_style = Style::default()
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.fg(Color::Green);
|
||||
@ -241,7 +241,7 @@ mod cals {
|
||||
.show_month_header(Style::default())
|
||||
}
|
||||
|
||||
fn example4<'a, S: DateStyler>(m: Month, y: i32, es: S) -> Monthly<'a, S> {
|
||||
fn example4<'a, DS: DateStyler>(m: Month, y: i32, es: DS) -> Monthly<'a, DS> {
|
||||
let header_style = Style::default()
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.fg(Color::Green);
|
||||
@ -255,7 +255,7 @@ mod cals {
|
||||
.default_style(default_style)
|
||||
}
|
||||
|
||||
fn example5<'a, S: DateStyler>(m: Month, y: i32, es: S) -> Monthly<'a, S> {
|
||||
fn example5<'a, DS: DateStyler>(m: Month, y: i32, es: DS) -> Monthly<'a, DS> {
|
||||
let header_style = Style::default()
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.fg(Color::Green);
|
||||
|
@ -1,3 +1,6 @@
|
||||
#![warn(missing_docs)]
|
||||
//! A module for the [`Buffer`] and [`Cell`] types.
|
||||
|
||||
mod assert;
|
||||
#[allow(clippy::module_inception)]
|
||||
mod buffer;
|
||||
|
@ -183,26 +183,35 @@ impl Buffer {
|
||||
}
|
||||
|
||||
/// Print a string, starting at the position (x, y)
|
||||
pub fn set_string<S>(&mut self, x: u16, y: u16, string: S, style: Style)
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
pub fn set_string<T, S>(&mut self, x: u16, y: u16, string: T, style: S)
|
||||
where
|
||||
S: AsRef<str>,
|
||||
T: AsRef<str>,
|
||||
S: Into<Style>,
|
||||
{
|
||||
self.set_stringn(x, y, string, usize::MAX, style);
|
||||
self.set_stringn(x, y, string, usize::MAX, style.into());
|
||||
}
|
||||
|
||||
/// Print at most the first n characters of a string if enough space is available
|
||||
/// until the end of the line
|
||||
pub fn set_stringn<S>(
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
pub fn set_stringn<T, S>(
|
||||
&mut self,
|
||||
x: u16,
|
||||
y: u16,
|
||||
string: S,
|
||||
string: T,
|
||||
width: usize,
|
||||
style: Style,
|
||||
style: S,
|
||||
) -> (u16, u16)
|
||||
where
|
||||
S: AsRef<str>,
|
||||
T: AsRef<str>,
|
||||
S: Into<Style>,
|
||||
{
|
||||
let style = style.into();
|
||||
let mut index = self.index_of(x, y);
|
||||
let mut x_offset = x as usize;
|
||||
let graphemes = UnicodeSegmentation::graphemes(string.as_ref(), true);
|
||||
@ -230,6 +239,7 @@ impl Buffer {
|
||||
(x_offset as u16, y)
|
||||
}
|
||||
|
||||
/// Print a line, starting at the position (x, y)
|
||||
pub fn set_line(&mut self, x: u16, y: u16, line: &Line<'_>, width: u16) -> (u16, u16) {
|
||||
let mut remaining_width = width;
|
||||
let mut x = x;
|
||||
@ -251,12 +261,17 @@ impl Buffer {
|
||||
(x, y)
|
||||
}
|
||||
|
||||
/// Print a span, starting at the position (x, y)
|
||||
pub fn set_span(&mut self, x: u16, y: u16, span: &Span<'_>, width: u16) -> (u16, u16) {
|
||||
self.set_stringn(x, y, span.content.as_ref(), width as usize, span.style)
|
||||
}
|
||||
|
||||
/// Set the style of all cells in the given area.
|
||||
pub fn set_style(&mut self, area: Rect, style: Style) {
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
pub fn set_style<S: Into<Style>>(&mut self, area: Rect, style: S) {
|
||||
let style = style.into();
|
||||
let area = self.area.intersection(area);
|
||||
for y in area.top()..area.bottom() {
|
||||
for x in area.left()..area.right() {
|
||||
|
@ -12,44 +12,68 @@ pub struct Cell {
|
||||
the value. Use `Cell::set_symbol` to update the field. Use `Cell::default` to \
|
||||
create `Cell` instance"
|
||||
)]
|
||||
/// The string to be drawn in the cell.
|
||||
///
|
||||
/// This accepts unicode grapheme clusters which might take up more than one cell.
|
||||
pub symbol: String,
|
||||
|
||||
/// The foreground color of the cell.
|
||||
pub fg: Color,
|
||||
|
||||
/// The background color of the cell.
|
||||
pub bg: Color,
|
||||
|
||||
/// The underline color of the cell.
|
||||
///
|
||||
/// This is only used when the `underline-color` feature is enabled.
|
||||
#[cfg(feature = "underline-color")]
|
||||
pub underline_color: Color,
|
||||
|
||||
/// The modifier of the cell.
|
||||
pub modifier: Modifier,
|
||||
|
||||
/// Whether the cell should be skipped when copying (diffing) the buffer to the screen.
|
||||
pub skip: bool,
|
||||
}
|
||||
|
||||
#[allow(deprecated)] // For Cell::symbol
|
||||
impl Cell {
|
||||
/// Gets the symbol of the cell.
|
||||
pub fn symbol(&self) -> &str {
|
||||
self.symbol.as_str()
|
||||
}
|
||||
|
||||
/// Sets the symbol of the cell.
|
||||
pub fn set_symbol(&mut self, symbol: &str) -> &mut Cell {
|
||||
self.symbol.clear();
|
||||
self.symbol.push_str(symbol);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the symbol of the cell to a single character.
|
||||
pub fn set_char(&mut self, ch: char) -> &mut Cell {
|
||||
self.symbol.clear();
|
||||
self.symbol.push(ch);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the foreground color of the cell.
|
||||
pub fn set_fg(&mut self, color: Color) -> &mut Cell {
|
||||
self.fg = color;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the background color of the cell.
|
||||
pub fn set_bg(&mut self, color: Color) -> &mut Cell {
|
||||
self.bg = color;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_style(&mut self, style: Style) -> &mut Cell {
|
||||
/// Sets the style of the cell.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
pub fn set_style<S: Into<Style>>(&mut self, style: S) -> &mut Cell {
|
||||
let style = style.into();
|
||||
if let Some(c) = style.fg {
|
||||
self.fg = c;
|
||||
}
|
||||
@ -65,21 +89,20 @@ impl Cell {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "underline-color")]
|
||||
/// Returns the style of the cell.
|
||||
pub fn style(&self) -> Style {
|
||||
Style::default()
|
||||
#[cfg(feature = "underline-color")]
|
||||
return Style::default()
|
||||
.fg(self.fg)
|
||||
.bg(self.bg)
|
||||
.underline_color(self.underline_color)
|
||||
.add_modifier(self.modifier)
|
||||
}
|
||||
.add_modifier(self.modifier);
|
||||
|
||||
#[cfg(not(feature = "underline-color"))]
|
||||
pub fn style(&self) -> Style {
|
||||
Style::default()
|
||||
#[cfg(not(feature = "underline-color"))]
|
||||
return Style::default()
|
||||
.fg(self.fg)
|
||||
.bg(self.bg)
|
||||
.add_modifier(self.modifier)
|
||||
.add_modifier(self.modifier);
|
||||
}
|
||||
|
||||
/// Sets the cell to be skipped when copying (diffing) the buffer to the screen.
|
||||
@ -91,6 +114,7 @@ impl Cell {
|
||||
self
|
||||
}
|
||||
|
||||
/// Resets the cell to the default state.
|
||||
pub fn reset(&mut self) {
|
||||
self.symbol.clear();
|
||||
self.symbol.push(' ');
|
||||
|
229
src/style.rs
229
src/style.rs
@ -82,6 +82,9 @@ bitflags! {
|
||||
///
|
||||
/// They are bitflags so they can easily be composed.
|
||||
///
|
||||
/// `From<Modifier> for Style` is implemented so you can use `Modifier` anywhere that accepts
|
||||
/// `Into<Style>`.
|
||||
///
|
||||
/// ## Examples
|
||||
///
|
||||
/// ```rust
|
||||
@ -138,6 +141,20 @@ impl fmt::Debug for Modifier {
|
||||
///
|
||||
/// For more information about the style shorthands, see the [`Stylize`] trait.
|
||||
///
|
||||
/// We implement conversions from [`Color`] and [`Modifier`] to [`Style`] so you can use them
|
||||
/// anywhere that accepts `Into<Style>`.
|
||||
///
|
||||
/// ```rust
|
||||
/// # use ratatui::prelude::*;
|
||||
/// Line::styled("hello", Style::new().fg(Color::Red));
|
||||
/// // simplifies to
|
||||
/// Line::styled("hello", Color::Red);
|
||||
///
|
||||
/// Line::styled("hello", Style::new().add_modifier(Modifier::BOLD));
|
||||
/// // simplifies to
|
||||
/// Line::styled("hello", Modifier::BOLD);
|
||||
/// ```
|
||||
///
|
||||
/// Styles represents an incremental change. If you apply the styles S1, S2, S3 to a cell of the
|
||||
/// terminal buffer, the style of this cell will be the result of the merge of S1, S2 and S3, not
|
||||
/// just S3.
|
||||
@ -227,10 +244,11 @@ impl Styled for Style {
|
||||
*self
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.patch(style)
|
||||
}
|
||||
}
|
||||
|
||||
impl Style {
|
||||
pub const fn new() -> Style {
|
||||
Style {
|
||||
@ -366,6 +384,9 @@ impl Style {
|
||||
/// Results in a combined style that is equivalent to applying the two individual styles to
|
||||
/// a style one after the other.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// ## Examples
|
||||
/// ```
|
||||
/// # use ratatui::prelude::*;
|
||||
@ -378,7 +399,8 @@ impl Style {
|
||||
/// );
|
||||
/// ```
|
||||
#[must_use = "`patch` returns the modified style without modifying the original"]
|
||||
pub fn patch(mut self, other: Style) -> Style {
|
||||
pub fn patch<S: Into<Style>>(mut self, other: S) -> Style {
|
||||
let other = other.into();
|
||||
self.fg = other.fg.or(self.fg);
|
||||
self.bg = other.bg.or(self.bg);
|
||||
|
||||
@ -396,6 +418,134 @@ impl Style {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Color> for Style {
|
||||
/// Creates a new `Style` with the given foreground color.
|
||||
///
|
||||
/// To specify a foreground and background color, use the `from((fg, bg))` constructor.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use ratatui::prelude::*;
|
||||
/// let style = Style::from(Color::Red);
|
||||
/// ```
|
||||
fn from(color: Color) -> Self {
|
||||
Self::new().fg(color)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Color, Color)> for Style {
|
||||
/// Creates a new `Style` with the given foreground and background colors.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use ratatui::prelude::*;
|
||||
/// // red foreground, blue background
|
||||
/// let style = Style::from((Color::Red, Color::Blue));
|
||||
/// // default foreground, blue background
|
||||
/// let style = Style::from((Color::Reset, Color::Blue));
|
||||
/// ```
|
||||
fn from((fg, bg): (Color, Color)) -> Self {
|
||||
Self::new().fg(fg).bg(bg)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Modifier> for Style {
|
||||
/// Creates a new `Style` with the given modifier added.
|
||||
///
|
||||
/// To specify multiple modifiers, use the `|` operator.
|
||||
///
|
||||
/// To specify modifiers to add and remove, use the `from((add_modifier, sub_modifier))`
|
||||
/// constructor.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use ratatui::prelude::*;
|
||||
/// // add bold and italic
|
||||
/// let style = Style::from(Modifier::BOLD|Modifier::ITALIC);
|
||||
fn from(modifier: Modifier) -> Self {
|
||||
Self::new().add_modifier(modifier)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Modifier, Modifier)> for Style {
|
||||
/// Creates a new `Style` with the given modifiers added and removed.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use ratatui::prelude::*;
|
||||
/// // add bold and italic, remove dim
|
||||
/// let style = Style::from((Modifier::BOLD | Modifier::ITALIC, Modifier::DIM));
|
||||
/// ```
|
||||
fn from((add_modifier, sub_modifier): (Modifier, Modifier)) -> Self {
|
||||
Self::new()
|
||||
.add_modifier(add_modifier)
|
||||
.remove_modifier(sub_modifier)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Color, Modifier)> for Style {
|
||||
/// Creates a new `Style` with the given foreground color and modifier added.
|
||||
///
|
||||
/// To specify multiple modifiers, use the `|` operator.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use ratatui::prelude::*;
|
||||
/// // red foreground, add bold and italic
|
||||
/// let style = Style::from((Color::Red, Modifier::BOLD | Modifier::ITALIC));
|
||||
/// ```
|
||||
fn from((fg, modifier): (Color, Modifier)) -> Self {
|
||||
Self::new().fg(fg).add_modifier(modifier)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Color, Color, Modifier)> for Style {
|
||||
/// Creates a new `Style` with the given foreground and background colors and modifier added.
|
||||
///
|
||||
/// To specify multiple modifiers, use the `|` operator.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use ratatui::prelude::*;
|
||||
/// // red foreground, blue background, add bold and italic
|
||||
/// let style = Style::from((Color::Red, Color::Blue, Modifier::BOLD | Modifier::ITALIC));
|
||||
/// ```
|
||||
fn from((fg, bg, modifier): (Color, Color, Modifier)) -> Self {
|
||||
Self::new().fg(fg).bg(bg).add_modifier(modifier)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(Color, Color, Modifier, Modifier)> for Style {
|
||||
/// Creates a new `Style` with the given foreground and background colors and modifiers added
|
||||
/// and removed.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// # use ratatui::prelude::*;
|
||||
/// // red foreground, blue background, add bold and italic, remove dim
|
||||
/// let style = Style::from((
|
||||
/// Color::Red,
|
||||
/// Color::Blue,
|
||||
/// Modifier::BOLD | Modifier::ITALIC,
|
||||
/// Modifier::DIM,
|
||||
/// ));
|
||||
/// ```
|
||||
fn from((fg, bg, add_modifier, sub_modifier): (Color, Color, Modifier, Modifier)) -> Self {
|
||||
Self::new()
|
||||
.fg(fg)
|
||||
.bg(bg)
|
||||
.add_modifier(add_modifier)
|
||||
.remove_modifier(sub_modifier)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -657,4 +807,79 @@ mod tests {
|
||||
// reset
|
||||
assert_eq!(Style::new().reset(), Style::reset());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_color() {
|
||||
assert_eq!(Style::from(Color::Red), Style::new().fg(Color::Red));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_color_color() {
|
||||
assert_eq!(
|
||||
Style::from((Color::Red, Color::Blue)),
|
||||
Style::new().fg(Color::Red).bg(Color::Blue)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_modifier() {
|
||||
assert_eq!(
|
||||
Style::from(Modifier::BOLD | Modifier::ITALIC),
|
||||
Style::new()
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.add_modifier(Modifier::ITALIC)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_modifier_modifier() {
|
||||
assert_eq!(
|
||||
Style::from((Modifier::BOLD | Modifier::ITALIC, Modifier::DIM)),
|
||||
Style::new()
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.add_modifier(Modifier::ITALIC)
|
||||
.remove_modifier(Modifier::DIM)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_color_modifier() {
|
||||
assert_eq!(
|
||||
Style::from((Color::Red, Modifier::BOLD | Modifier::ITALIC)),
|
||||
Style::new()
|
||||
.fg(Color::Red)
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.add_modifier(Modifier::ITALIC)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_color_color_modifier() {
|
||||
assert_eq!(
|
||||
Style::from((Color::Red, Color::Blue, Modifier::BOLD | Modifier::ITALIC)),
|
||||
Style::new()
|
||||
.fg(Color::Red)
|
||||
.bg(Color::Blue)
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.add_modifier(Modifier::ITALIC)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_color_color_modifier_modifier() {
|
||||
assert_eq!(
|
||||
Style::from((
|
||||
Color::Red,
|
||||
Color::Blue,
|
||||
Modifier::BOLD | Modifier::ITALIC,
|
||||
Modifier::DIM
|
||||
)),
|
||||
Style::new()
|
||||
.fg(Color::Red)
|
||||
.bg(Color::Blue)
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.add_modifier(Modifier::ITALIC)
|
||||
.remove_modifier(Modifier::DIM)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,9 @@ use std::{
|
||||
/// - we support `-` and `_` and ` ` as separators for all colors
|
||||
/// - we support both `gray` and `grey` spellings
|
||||
///
|
||||
/// `From<Color> for Style` is implemented by creating a style with the foreground color set to the
|
||||
/// given color. This allows you to use colors anywhere that accepts `Into<Style>`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
|
@ -13,8 +13,14 @@ use crate::{
|
||||
pub trait Styled {
|
||||
type Item;
|
||||
|
||||
/// Returns the style of the object.
|
||||
fn style(&self) -> Style;
|
||||
fn set_style(self, style: Style) -> Self::Item;
|
||||
|
||||
/// Sets the style of the object.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item;
|
||||
}
|
||||
|
||||
/// Generates two methods for each color, one for setting the foreground color (`red()`, `blue()`,
|
||||
@ -209,7 +215,7 @@ impl<'a> Styled for &'a str {
|
||||
Style::default()
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
Span::styled(self, style)
|
||||
}
|
||||
}
|
||||
@ -221,7 +227,7 @@ impl Styled for String {
|
||||
Style::default()
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
Span::styled(self, style)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::style::{Style, Styled};
|
||||
use crate::prelude::*;
|
||||
|
||||
/// A grapheme associated to a style.
|
||||
/// Note that, although `StyledGrapheme` is the smallest divisible unit of text,
|
||||
@ -12,8 +12,15 @@ pub struct StyledGrapheme<'a> {
|
||||
}
|
||||
|
||||
impl<'a> StyledGrapheme<'a> {
|
||||
pub fn new(symbol: &'a str, style: Style) -> StyledGrapheme<'a> {
|
||||
StyledGrapheme { symbol, style }
|
||||
/// Creates a new `StyledGrapheme` with the given symbol and style.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
pub fn new<S: Into<Style>>(symbol: &'a str, style: S) -> StyledGrapheme<'a> {
|
||||
StyledGrapheme {
|
||||
symbol,
|
||||
style: style.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,8 +31,8 @@ impl<'a> Styled for StyledGrapheme<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(mut self, style: Style) -> Self::Item {
|
||||
self.style = style;
|
||||
fn set_style<S: Into<Style>>(mut self, style: S) -> Self::Item {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -33,7 +40,6 @@ impl<'a> Styled for StyledGrapheme<'a> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn new() {
|
||||
|
@ -120,6 +120,9 @@ impl<'a> Line<'a> {
|
||||
// `content` can be any type that is convertible to [`Cow<str>`] (e.g. [`&str`], [`String`],
|
||||
/// [`Cow<str>`], or your own type that implements [`Into<Cow<str>>`]).
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Any newlines in the content are removed.
|
||||
@ -132,9 +135,10 @@ impl<'a> Line<'a> {
|
||||
/// Line::styled(String::from("My text"), style);
|
||||
/// Line::styled(Cow::from("test content"), style);
|
||||
/// ```
|
||||
pub fn styled<T>(content: T, style: Style) -> Line<'a>
|
||||
pub fn styled<T, S>(content: T, style: S) -> Line<'a>
|
||||
where
|
||||
T: Into<Cow<'a, str>>,
|
||||
S: Into<Style>,
|
||||
{
|
||||
Line {
|
||||
spans: content
|
||||
@ -142,7 +146,7 @@ impl<'a> Line<'a> {
|
||||
.lines()
|
||||
.map(|v| Span::raw(v.to_string()))
|
||||
.collect(),
|
||||
style,
|
||||
style: style.into(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
@ -177,13 +181,16 @@ impl<'a> Line<'a> {
|
||||
/// only by the style of each [`Span`] contained in the line. For this reason, this field may
|
||||
/// not be supported by all widgets (outside of the `ratatui` crate itself).
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use ratatui::prelude::*;
|
||||
/// let mut line = Line::from("foo").style(Style::new().red());
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<T: Into<Style>>(mut self, style: T) -> Self {
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
@ -229,6 +236,9 @@ impl<'a> Line<'a> {
|
||||
/// `base_style` is the [`Style`] that will be patched with each grapheme [`Style`] to get
|
||||
/// the resulting [`Style`].
|
||||
///
|
||||
/// `base_style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`],
|
||||
/// or your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
@ -249,11 +259,11 @@ impl<'a> Line<'a> {
|
||||
/// ]
|
||||
/// );
|
||||
/// ```
|
||||
pub fn styled_graphemes(
|
||||
pub fn styled_graphemes<S: Into<Style>>(
|
||||
&'a self,
|
||||
base_style: Style,
|
||||
base_style: S,
|
||||
) -> impl Iterator<Item = StyledGrapheme<'a>> {
|
||||
let style = base_style.patch(self.style);
|
||||
let style = base_style.into().patch(self.style);
|
||||
self.spans
|
||||
.iter()
|
||||
.flat_map(move |span| span.styled_graphemes(style))
|
||||
@ -265,6 +275,9 @@ impl<'a> Line<'a> {
|
||||
/// In contrast to [`Line::style`], this method will not overwrite the existing style, but
|
||||
/// instead will add the given style's modifiers to the existing style of each `Span`.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
@ -283,7 +296,8 @@ impl<'a> Line<'a> {
|
||||
/// raw_line.patch_style(style);
|
||||
/// assert_eq!(raw_line, styled_line);
|
||||
/// ```
|
||||
pub fn patch_style(&mut self, style: Style) {
|
||||
pub fn patch_style<S: Into<Style>>(&mut self, style: S) {
|
||||
let style = style.into();
|
||||
for span in &mut self.spans {
|
||||
span.patch_style(style);
|
||||
}
|
||||
|
@ -119,6 +119,12 @@ impl<'a> Span<'a> {
|
||||
|
||||
/// Create a span with the specified style.
|
||||
///
|
||||
/// `content` accepts any type that is convertible to [`Cow<str>`] (e.g. `&str`, `String`,
|
||||
/// `&String`, etc.).
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
@ -127,13 +133,14 @@ impl<'a> Span<'a> {
|
||||
/// Span::styled("test content", style);
|
||||
/// Span::styled(String::from("test content"), style);
|
||||
/// ```
|
||||
pub fn styled<T>(content: T, style: Style) -> Span<'a>
|
||||
pub fn styled<T, S>(content: T, style: S) -> Span<'a>
|
||||
where
|
||||
T: Into<Cow<'a, str>>,
|
||||
S: Into<Style>,
|
||||
{
|
||||
Span {
|
||||
content: content.into(),
|
||||
style,
|
||||
style: style.into(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,7 +173,8 @@ impl<'a> Span<'a> {
|
||||
/// In contrast to [`Span::patch_style`], this method replaces the style of the span instead of
|
||||
/// patching it.
|
||||
///
|
||||
/// Accepts any type that can be converted to [`Style`]
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -175,16 +183,16 @@ impl<'a> Span<'a> {
|
||||
/// let mut span = Span::default().style(Style::new().green());
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<T>(mut self, style: T) -> Self
|
||||
where
|
||||
T: Into<Style>,
|
||||
{
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Patches the style of the Span, adding modifiers from the given style.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
@ -193,7 +201,7 @@ impl<'a> Span<'a> {
|
||||
/// span.patch_style(Style::new().red().on_yellow().bold());
|
||||
/// assert_eq!(span.style, Style::new().red().on_yellow().italic().bold());
|
||||
/// ```
|
||||
pub fn patch_style(&mut self, style: Style) {
|
||||
pub fn patch_style<S: Into<Style>>(&mut self, style: S) {
|
||||
self.style = self.style.patch(style);
|
||||
}
|
||||
|
||||
@ -223,6 +231,9 @@ impl<'a> Span<'a> {
|
||||
/// `base_style` is the [`Style`] that will be patched with the `Span`'s `style` to get the
|
||||
/// resulting [`Style`].
|
||||
///
|
||||
/// `base_style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`],
|
||||
/// or your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
@ -243,18 +254,16 @@ impl<'a> Span<'a> {
|
||||
/// ],
|
||||
/// );
|
||||
/// ```
|
||||
pub fn styled_graphemes(
|
||||
pub fn styled_graphemes<S: Into<Style>>(
|
||||
&'a self,
|
||||
base_style: Style,
|
||||
base_style: S,
|
||||
) -> impl Iterator<Item = StyledGrapheme<'a>> {
|
||||
let style = base_style.into().patch(self.style);
|
||||
self.content
|
||||
.as_ref()
|
||||
.graphemes(true)
|
||||
.filter(|g| *g != "\n")
|
||||
.map(move |g| StyledGrapheme {
|
||||
symbol: g,
|
||||
style: base_style.patch(self.style),
|
||||
})
|
||||
.map(move |g| StyledGrapheme { symbol: g, style })
|
||||
}
|
||||
}
|
||||
|
||||
@ -274,9 +283,8 @@ impl<'a> Styled for Span<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(mut self, style: Style) -> Self {
|
||||
self.style = style;
|
||||
self
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use super::{Line, Span};
|
||||
use crate::style::Style;
|
||||
use crate::prelude::*;
|
||||
|
||||
/// A string split over multiple lines where each line is composed of several clusters, each with
|
||||
/// their own style.
|
||||
@ -60,6 +59,9 @@ impl<'a> Text<'a> {
|
||||
|
||||
/// Create some text (potentially multiple lines) with a style.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
@ -70,9 +72,10 @@ impl<'a> Text<'a> {
|
||||
/// Text::styled("The first line\nThe second line", style);
|
||||
/// Text::styled(String::from("The first line\nThe second line"), style);
|
||||
/// ```
|
||||
pub fn styled<T>(content: T, style: Style) -> Text<'a>
|
||||
pub fn styled<T, S>(content: T, style: S) -> Text<'a>
|
||||
where
|
||||
T: Into<Cow<'a, str>>,
|
||||
S: Into<Style>,
|
||||
{
|
||||
let mut text = Text::raw(content);
|
||||
text.patch_style(style);
|
||||
@ -107,6 +110,9 @@ impl<'a> Text<'a> {
|
||||
|
||||
/// Patches the style of each line in an existing Text, adding modifiers from the given style.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
@ -121,7 +127,8 @@ impl<'a> Text<'a> {
|
||||
/// raw_text.patch_style(style);
|
||||
/// assert_eq!(raw_text, styled_text);
|
||||
/// ```
|
||||
pub fn patch_style(&mut self, style: Style) {
|
||||
pub fn patch_style<S: Into<Style>>(&mut self, style: S) {
|
||||
let style = style.into();
|
||||
for line in &mut self.lines {
|
||||
line.patch_style(style);
|
||||
}
|
||||
|
@ -170,11 +170,14 @@ impl<'a> BarChart<'a> {
|
||||
|
||||
/// Set the default style of the bar.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// It is also possible to set individually the style of each [`Bar`].
|
||||
/// In this case the default style will be patched by the individual style
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn bar_style(mut self, style: Style) -> BarChart<'a> {
|
||||
self.bar_style = style;
|
||||
pub fn bar_style<S: Into<Style>>(mut self, style: S) -> BarChart<'a> {
|
||||
self.bar_style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -226,6 +229,9 @@ impl<'a> BarChart<'a> {
|
||||
|
||||
/// Set the default value style of the bar.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// It is also possible to set individually the value style of each [`Bar`].
|
||||
/// In this case the default value style will be patched by the individual value style
|
||||
///
|
||||
@ -233,13 +239,16 @@ impl<'a> BarChart<'a> {
|
||||
///
|
||||
/// [Bar::value_style] to set the value style individually.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn value_style(mut self, style: Style) -> BarChart<'a> {
|
||||
self.value_style = style;
|
||||
pub fn value_style<S: Into<Style>>(mut self, style: S) -> BarChart<'a> {
|
||||
self.value_style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the default label style of the groups and bars.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// It is also possible to set individually the label style of each [`Bar`] or [`BarGroup`].
|
||||
/// In this case the default label style will be patched by the individual label style
|
||||
///
|
||||
@ -247,8 +256,8 @@ impl<'a> BarChart<'a> {
|
||||
///
|
||||
/// [Bar::label] to set the label style individually.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn label_style(mut self, style: Style) -> BarChart<'a> {
|
||||
self.label_style = style;
|
||||
pub fn label_style<S: Into<Style>>(mut self, style: S) -> BarChart<'a> {
|
||||
self.label_style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -261,10 +270,13 @@ impl<'a> BarChart<'a> {
|
||||
|
||||
/// Set the style of the entire chart.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// The style will be applied to everything that isn't styled (borders, bars, labels, ...).
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> BarChart<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> BarChart<'a> {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -597,7 +609,7 @@ impl<'a> Styled for BarChart<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::{buffer::Buffer, prelude::Rect, style::Style, text::Line};
|
||||
use crate::prelude::*;
|
||||
|
||||
/// A bar to be shown by the [`BarChart`](crate::widgets::BarChart) widget.
|
||||
///
|
||||
@ -70,22 +70,27 @@ impl<'a> Bar<'a> {
|
||||
|
||||
/// Set the style of the bar.
|
||||
///
|
||||
/// This will apply to every non-styled element.
|
||||
/// It can be seen and used as a default value.
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This will apply to every non-styled element. It can be seen and used as a default value.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Bar<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Bar<'a> {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the style of the value.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # See also
|
||||
///
|
||||
/// [`Bar::value`] to set the value.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn value_style(mut self, style: Style) -> Bar<'a> {
|
||||
self.value_style = style;
|
||||
pub fn value_style<S: Into<Style>>(mut self, style: S) -> Bar<'a> {
|
||||
self.value_style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -13,9 +13,7 @@ use strum::{Display, EnumString};
|
||||
|
||||
pub use self::title::{Position, Title};
|
||||
use crate::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Rect},
|
||||
style::{Style, Styled},
|
||||
prelude::*,
|
||||
symbols::border,
|
||||
widgets::{Borders, Widget},
|
||||
};
|
||||
@ -334,10 +332,13 @@ impl<'a> Block<'a> {
|
||||
|
||||
/// Applies the style to all titles.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// If a [`Title`] already has a style, the title's style will add on top of this one.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub const fn title_style(mut self, style: Style) -> Block<'a> {
|
||||
self.titles_style = style;
|
||||
pub fn title_style<S: Into<Style>>(mut self, style: S) -> Block<'a> {
|
||||
self.titles_style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -405,6 +406,9 @@ impl<'a> Block<'a> {
|
||||
///
|
||||
/// If a [`Block::style`] is defined, `border_style` will be applied on top of it.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// This example shows a `Block` with blue borders.
|
||||
@ -415,8 +419,8 @@ impl<'a> Block<'a> {
|
||||
/// .border_style(Style::new().blue());
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub const fn border_style(mut self, style: Style) -> Block<'a> {
|
||||
self.border_style = style;
|
||||
pub fn border_style<S: Into<Style>>(mut self, style: S) -> Block<'a> {
|
||||
self.border_style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -426,10 +430,13 @@ impl<'a> Block<'a> {
|
||||
/// more specific style. Elements can be styled further with [`Block::title_style`] and
|
||||
/// [`Block::border_style`].
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This will also apply to the widget inside that block, unless the inner widget is styled.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub const fn style(mut self, style: Style) -> Block<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Block<'a> {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -797,7 +804,7 @@ impl<'a> Styled for Block<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
@ -1100,15 +1107,60 @@ mod tests {
|
||||
const _DEFAULT_STYLE: Style = Style::new();
|
||||
const _DEFAULT_PADDING: Padding = Padding::uniform(1);
|
||||
const _DEFAULT_BLOCK: Block = Block::new()
|
||||
.title_style(_DEFAULT_STYLE)
|
||||
// the following methods are no longer const because they use Into<Style>
|
||||
// .style(_DEFAULT_STYLE) // no longer const
|
||||
// .border_style(_DEFAULT_STYLE) // no longer const
|
||||
// .title_style(_DEFAULT_STYLE) // no longer const
|
||||
.title_alignment(Alignment::Left)
|
||||
.title_position(Position::Top)
|
||||
.borders(Borders::ALL)
|
||||
.border_style(_DEFAULT_STYLE)
|
||||
.style(_DEFAULT_STYLE)
|
||||
.padding(_DEFAULT_PADDING);
|
||||
}
|
||||
|
||||
/// This test ensures that we have some coverage on the Style::from() implementations
|
||||
#[test]
|
||||
fn block_style() {
|
||||
// nominal style
|
||||
let block = Block::default().style(Style::new().red());
|
||||
assert_eq!(block.style, Style::new().red());
|
||||
|
||||
// auto-convert from Color
|
||||
let block = Block::default().style(Color::Red);
|
||||
assert_eq!(block.style, Style::new().red());
|
||||
|
||||
// auto-convert from (Color, Color)
|
||||
let block = Block::default().style((Color::Red, Color::Blue));
|
||||
assert_eq!(block.style, Style::new().red().on_blue());
|
||||
|
||||
// auto-convert from Modifier
|
||||
let block = Block::default().style(Modifier::BOLD | Modifier::ITALIC);
|
||||
assert_eq!(block.style, Style::new().bold().italic());
|
||||
|
||||
// auto-convert from (Modifier, Modifier)
|
||||
let block = Block::default().style((Modifier::BOLD | Modifier::ITALIC, Modifier::DIM));
|
||||
assert_eq!(block.style, Style::new().bold().italic().not_dim());
|
||||
|
||||
// auto-convert from (Color, Modifier)
|
||||
let block = Block::default().style((Color::Red, Modifier::BOLD));
|
||||
assert_eq!(block.style, Style::new().red().bold());
|
||||
|
||||
// auto-convert from (Color, Color, Modifier)
|
||||
let block = Block::default().style((Color::Red, Color::Blue, Modifier::BOLD));
|
||||
assert_eq!(block.style, Style::new().red().on_blue().bold());
|
||||
|
||||
// auto-convert from (Color, Color, Modifier, Modifier)
|
||||
let block = Block::default().style((
|
||||
Color::Red,
|
||||
Color::Blue,
|
||||
Modifier::BOLD | Modifier::ITALIC,
|
||||
Modifier::DIM,
|
||||
));
|
||||
assert_eq!(
|
||||
block.style,
|
||||
Style::new().red().on_blue().bold().italic().not_dim()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_be_stylized() {
|
||||
let block = Block::default().black().on_white().bold().not_dim();
|
||||
|
@ -13,18 +13,15 @@ use std::collections::HashMap;
|
||||
use time::{Date, Duration, OffsetDateTime};
|
||||
|
||||
use crate::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::Style,
|
||||
text::Span,
|
||||
prelude::*,
|
||||
widgets::{Block, Widget},
|
||||
};
|
||||
|
||||
/// Display a month calendar for the month containing `display_date`
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Monthly<'a, S: DateStyler> {
|
||||
pub struct Monthly<'a, DS: DateStyler> {
|
||||
display_date: Date,
|
||||
events: S,
|
||||
events: DS,
|
||||
show_surrounding: Option<Style>,
|
||||
show_weekday: Option<Style>,
|
||||
show_month: Option<Style>,
|
||||
@ -32,9 +29,9 @@ pub struct Monthly<'a, S: DateStyler> {
|
||||
block: Option<Block<'a>>,
|
||||
}
|
||||
|
||||
impl<'a, S: DateStyler> Monthly<'a, S> {
|
||||
impl<'a, DS: DateStyler> Monthly<'a, DS> {
|
||||
/// Construct a calendar for the `display_date` and highlight the `events`
|
||||
pub fn new(display_date: Date, events: S) -> Self {
|
||||
pub fn new(display_date: Date, events: DS) -> Self {
|
||||
Self {
|
||||
display_date,
|
||||
events,
|
||||
@ -49,32 +46,44 @@ impl<'a, S: DateStyler> Monthly<'a, S> {
|
||||
/// Fill the calendar slots for days not in the current month also, this causes each line to be
|
||||
/// completely filled. If there is an event style for a date, this style will be patched with
|
||||
/// the event's style
|
||||
pub fn show_surrounding(mut self, style: Style) -> Self {
|
||||
self.show_surrounding = Some(style);
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
pub fn show_surrounding<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.show_surrounding = Some(style.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Display a header containing weekday abbreviations
|
||||
pub fn show_weekdays_header(mut self, style: Style) -> Self {
|
||||
self.show_weekday = Some(style);
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
pub fn show_weekdays_header<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.show_weekday = Some(style.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Display a header containing the month and year
|
||||
pub fn show_month_header(mut self, style: Style) -> Self {
|
||||
self.show_month = Some(style);
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
pub fn show_month_header<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.show_month = Some(style.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// How to render otherwise unstyled dates
|
||||
pub fn default_style(mut self, s: Style) -> Self {
|
||||
self.default_style = s;
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
pub fn default_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.default_style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Render the calendar within a [Block]
|
||||
pub fn block(mut self, b: Block<'a>) -> Self {
|
||||
self.block = Some(b);
|
||||
pub fn block(mut self, block: Block<'a>) -> Self {
|
||||
self.block = Some(block);
|
||||
self
|
||||
}
|
||||
|
||||
@ -108,7 +117,7 @@ impl<'a, S: DateStyler> Monthly<'a, S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, S: DateStyler> Widget for Monthly<'a, S> {
|
||||
impl<'a, DS: DateStyler> Widget for Monthly<'a, DS> {
|
||||
fn render(mut self, area: Rect, buf: &mut Buffer) {
|
||||
// Block is used for borders and such
|
||||
// Draw that first, and use the blank area inside the block for our own purposes
|
||||
@ -178,16 +187,22 @@ pub struct CalendarEventStore(pub HashMap<Date, Style>);
|
||||
|
||||
impl CalendarEventStore {
|
||||
/// Construct a store that has the current date styled.
|
||||
pub fn today(style: Style) -> Self {
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
pub fn today<S: Into<Style>>(style: S) -> Self {
|
||||
let mut res = Self::default();
|
||||
res.add(OffsetDateTime::now_local().unwrap().date(), style);
|
||||
res.add(OffsetDateTime::now_local().unwrap().date(), style.into());
|
||||
res
|
||||
}
|
||||
|
||||
/// Add a date and style to the store
|
||||
pub fn add(&mut self, date: Date, style: Style) {
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
pub fn add<S: Into<Style>>(&mut self, date: Date, style: S) {
|
||||
// to simplify style nonsense, last write wins
|
||||
let _ = self.0.insert(date, style);
|
||||
let _ = self.0.insert(date, style.into());
|
||||
}
|
||||
|
||||
/// Helper for trait impls
|
||||
|
@ -109,6 +109,9 @@ impl<'a> Axis<'a> {
|
||||
///
|
||||
/// This is a fluent setter method which must be chained or used as it consumes self
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// [`Axis`] also implements [`Stylize`](crate::style::Stylize) which mean you can style it
|
||||
@ -119,8 +122,8 @@ impl<'a> Axis<'a> {
|
||||
/// let axis = Axis::default().red();
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Axis<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Axis<'a> {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -379,6 +382,9 @@ impl<'a> Dataset<'a> {
|
||||
/// The given style will be used to draw the legend and the data points. Currently the legend
|
||||
/// will use the entire style whereas the data points will only use the foreground.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This is a fluent setter method which must be chained or used as it consumes self
|
||||
///
|
||||
/// # Example
|
||||
@ -391,8 +397,8 @@ impl<'a> Dataset<'a> {
|
||||
/// let dataset = Dataset::default().red();
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Dataset<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Dataset<'a> {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -547,12 +553,15 @@ impl<'a> Chart<'a> {
|
||||
|
||||
/// Sets the style of the entire chart
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// Styles of [`Axis`] and [`Dataset`] will have priority over this style.
|
||||
///
|
||||
/// This is a fluent setter method which must be chained or used as it consumes self
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Chart<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Chart<'a> {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -1043,7 +1052,7 @@ impl<'a> Styled for Axis<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
@ -1055,7 +1064,7 @@ impl<'a> Styled for Dataset<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
@ -1067,7 +1076,7 @@ impl<'a> Styled for Chart<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
|
@ -128,18 +128,24 @@ impl<'a> Gauge<'a> {
|
||||
|
||||
/// Sets the widget style.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This will style the block (if any non-styled) and background of the widget (everything
|
||||
/// except the bar itself). [`Block`] style set with [`Gauge::block`] takes precedence.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Gauge<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Gauge<'a> {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the style of the bar.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn gauge_style(mut self, style: Style) -> Gauge<'a> {
|
||||
self.gauge_style = style;
|
||||
pub fn gauge_style<S: Into<Style>>(mut self, style: S) -> Gauge<'a> {
|
||||
self.gauge_style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -323,18 +329,24 @@ impl<'a> LineGauge<'a> {
|
||||
|
||||
/// Sets the widget style.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This will style everything except the bar itself, so basically the block (if any) and
|
||||
/// background.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Self {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the style of the bar.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn gauge_style(mut self, style: Style) -> Self {
|
||||
self.gauge_style = style;
|
||||
pub fn gauge_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.gauge_style = style.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -406,7 +418,7 @@ impl<'a> Styled for Gauge<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
@ -418,7 +430,7 @@ impl<'a> Styled for LineGauge<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,7 @@ use strum::{Display, EnumString};
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Corner, Rect},
|
||||
style::{Style, Styled},
|
||||
text::Text,
|
||||
prelude::*,
|
||||
widgets::{Block, HighlightSpacing, StatefulWidget, Widget},
|
||||
};
|
||||
|
||||
@ -256,6 +253,9 @@ impl<'a> ListItem<'a> {
|
||||
|
||||
/// Sets the item style
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This [`Style`] can be overridden by the [`Style`] of the [`Text`] content.
|
||||
///
|
||||
/// This is a fluent setter method which must be chained or used as it consumes self
|
||||
@ -276,8 +276,8 @@ impl<'a> ListItem<'a> {
|
||||
/// let item = ListItem::new("Item 1").red().italic();
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> ListItem<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> ListItem<'a> {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -523,6 +523,9 @@ impl<'a> List<'a> {
|
||||
|
||||
/// Sets the base style of the widget
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// All text rendered by the widget will use this style, unless overridden by [`Block::style`],
|
||||
/// [`ListItem::style`], or the styles of the [`ListItem`]'s content.
|
||||
///
|
||||
@ -547,8 +550,8 @@ impl<'a> List<'a> {
|
||||
/// let list = List::new(items).red().italic();
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> List<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> List<'a> {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -573,6 +576,9 @@ impl<'a> List<'a> {
|
||||
|
||||
/// Set the style of the selected item
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This style will be applied to the entire item, including the
|
||||
/// [highlight symbol](List::highlight_symbol) if it is displayed, and will override any style
|
||||
/// set on the item or on the individual cells.
|
||||
@ -587,8 +593,8 @@ impl<'a> List<'a> {
|
||||
/// let list = List::new(items).highlight_style(Style::new().red().italic());
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn highlight_style(mut self, style: Style) -> List<'a> {
|
||||
self.highlight_style = style;
|
||||
pub fn highlight_style<S: Into<Style>>(mut self, style: S) -> List<'a> {
|
||||
self.highlight_style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -854,7 +860,7 @@ impl<'a> Styled for List<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
@ -866,7 +872,7 @@ impl<'a> Styled for ListItem<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Rect},
|
||||
style::{Style, Styled},
|
||||
text::{StyledGrapheme, Text},
|
||||
prelude::*,
|
||||
text::StyledGrapheme,
|
||||
widgets::{
|
||||
reflow::{LineComposer, LineTruncator, WordWrapper, WrappedLine},
|
||||
Block, Widget,
|
||||
@ -142,6 +140,9 @@ impl<'a> Paragraph<'a> {
|
||||
|
||||
/// Sets the style of the entire widget.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This applies to the entire widget, including the block if one is present. Any style set on
|
||||
/// the block or text will be added to this style.
|
||||
///
|
||||
@ -152,8 +153,8 @@ impl<'a> Paragraph<'a> {
|
||||
/// let paragraph = Paragraph::new("Hello, world!").style(Style::new().red().on_white());
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Paragraph<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Paragraph<'a> {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -355,7 +356,7 @@ impl<'a> Styled for Paragraph<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,7 @@ use strum::{Display, EnumString};
|
||||
|
||||
use super::StatefulWidget;
|
||||
use crate::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::Style,
|
||||
prelude::*,
|
||||
symbols::scrollbar::{Set, DOUBLE_HORIZONTAL, DOUBLE_VERTICAL},
|
||||
};
|
||||
|
||||
@ -239,9 +237,12 @@ impl<'a> Scrollbar<'a> {
|
||||
}
|
||||
|
||||
/// Sets the style that represents the thumb of the scrollbar.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn thumb_style(mut self, thumb_style: Style) -> Self {
|
||||
self.thumb_style = thumb_style;
|
||||
pub fn thumb_style<S: Into<Style>>(mut self, thumb_style: S) -> Self {
|
||||
self.thumb_style = thumb_style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -253,9 +254,12 @@ impl<'a> Scrollbar<'a> {
|
||||
}
|
||||
|
||||
/// Sets the style that is used for the track of the scrollbar.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn track_style(mut self, track_style: Style) -> Self {
|
||||
self.track_style = track_style;
|
||||
pub fn track_style<S: Into<Style>>(mut self, track_style: S) -> Self {
|
||||
self.track_style = track_style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -267,9 +271,12 @@ impl<'a> Scrollbar<'a> {
|
||||
}
|
||||
|
||||
/// Sets the style that is used for the beginning of the scrollbar.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn begin_style(mut self, begin_style: Style) -> Self {
|
||||
self.begin_style = begin_style;
|
||||
pub fn begin_style<S: Into<Style>>(mut self, begin_style: S) -> Self {
|
||||
self.begin_style = begin_style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -281,9 +288,12 @@ impl<'a> Scrollbar<'a> {
|
||||
}
|
||||
|
||||
/// Sets the style that is used for the end of the scrollbar.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn end_style(mut self, end_style: Style) -> Self {
|
||||
self.end_style = end_style;
|
||||
pub fn end_style<S: Into<Style>>(mut self, end_style: S) -> Self {
|
||||
self.end_style = end_style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -316,6 +326,10 @@ impl<'a> Scrollbar<'a> {
|
||||
}
|
||||
|
||||
/// Sets the style used for the various parts of the scrollbar from a [`Style`].
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// ```text
|
||||
/// <--▮------->
|
||||
/// ^ ^ ^ ^
|
||||
@ -325,7 +339,8 @@ impl<'a> Scrollbar<'a> {
|
||||
/// └─────────── begin
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Self {
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
let style = style.into();
|
||||
self.track_style = style;
|
||||
self.thumb_style = style;
|
||||
self.begin_style = style;
|
||||
|
@ -4,10 +4,7 @@ use std::cmp::min;
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
use crate::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::{Style, Styled},
|
||||
symbols,
|
||||
prelude::*,
|
||||
widgets::{Block, Widget},
|
||||
};
|
||||
|
||||
@ -89,10 +86,13 @@ impl<'a> Sparkline<'a> {
|
||||
|
||||
/// Sets the style of the entire widget.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// The foreground corresponds to the bars while the background is everything else.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Sparkline<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Sparkline<'a> {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -151,7 +151,7 @@ impl<'a> Styled for Sparkline<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,9 @@ impl<'a> Cell<'a> {
|
||||
|
||||
/// Set the `Style` of this cell
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This `Style` will override the `Style` of the [`Row`] and can be overridden by the `Style`
|
||||
/// of the [`Text`] content.
|
||||
///
|
||||
@ -120,8 +123,8 @@ impl<'a> Cell<'a> {
|
||||
///
|
||||
/// [`Row`]: super::Row
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Self {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -169,7 +172,7 @@ impl<'a> Styled for Cell<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
|
@ -182,6 +182,9 @@ impl<'a> Row<'a> {
|
||||
|
||||
/// Set the [`Style`] of the entire row
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This [`Style`] can be overridden by the [`Style`] of a any individual [`Cell`] or by their
|
||||
/// [`Text`] content.
|
||||
///
|
||||
@ -204,8 +207,8 @@ impl<'a> Row<'a> {
|
||||
/// let row = Row::new(cells).red().italic();
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Self {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -227,7 +230,7 @@ impl<'a> Styled for Row<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
|
@ -396,6 +396,9 @@ impl<'a> Table<'a> {
|
||||
|
||||
/// Sets the base style of the widget
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// All text rendered by the widget will use this style, unless overridden by [`Block::style`],
|
||||
/// [`Row::style`], [`Cell::style`], or the styles of cell's content.
|
||||
///
|
||||
@ -420,13 +423,16 @@ impl<'a> Table<'a> {
|
||||
/// let table = Table::new(rows, widths).red().italic();
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Self {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the style of the selected row
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This style will be applied to the entire row, including the selection symbol if it is
|
||||
/// displayed, and will override any style set on the row or on the individual cells.
|
||||
///
|
||||
@ -441,8 +447,8 @@ impl<'a> Table<'a> {
|
||||
/// let table = Table::new(rows, widths).highlight_style(Style::new().red().italic());
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn highlight_style(mut self, highlight_style: Style) -> Self {
|
||||
self.highlight_style = highlight_style;
|
||||
pub fn highlight_style<S: Into<Style>>(mut self, highlight_style: S) -> Self {
|
||||
self.highlight_style = highlight_style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -788,7 +794,7 @@ impl<'a> Styled for Table<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,6 @@
|
||||
#![deny(missing_docs)]
|
||||
use crate::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::{Modifier, Style, Styled},
|
||||
symbols,
|
||||
text::{Line, Span},
|
||||
prelude::*,
|
||||
widgets::{Block, Widget},
|
||||
};
|
||||
|
||||
@ -118,21 +114,27 @@ impl<'a> Tabs<'a> {
|
||||
|
||||
/// Sets the style of the tabs.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// This will set the given style on the entire render area.
|
||||
/// More precise style can be applied to the titles by styling the ones given to [`Tabs::new`].
|
||||
/// The selected tab can be styled differently using [`Tabs::highlight_style`].
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style(mut self, style: Style) -> Tabs<'a> {
|
||||
self.style = style;
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the style for the highlighted tab.
|
||||
///
|
||||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// Highlighted tab can be selected with [`Tabs::select`].
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn highlight_style(mut self, style: Style) -> Tabs<'a> {
|
||||
self.highlight_style = style;
|
||||
pub fn highlight_style<S: Into<Style>>(mut self, style: S) -> Tabs<'a> {
|
||||
self.highlight_style = style.into();
|
||||
self
|
||||
}
|
||||
|
||||
@ -232,7 +234,7 @@ impl<'a> Styled for Tabs<'a> {
|
||||
self.style
|
||||
}
|
||||
|
||||
fn set_style(self, style: Style) -> Self::Item {
|
||||
fn set_style<S: Into<Style>>(self, style: S) -> Self::Item {
|
||||
self.style(style)
|
||||
}
|
||||
}
|
||||
@ -307,7 +309,7 @@ impl<'a> Widget for Tabs<'a> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{assert_buffer_eq, prelude::*, widgets::Borders};
|
||||
use crate::{assert_buffer_eq, widgets::Borders};
|
||||
|
||||
#[test]
|
||||
fn new() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user