Switch usages of ContentStyle to Style

This commit is contained in:
Joscha 2023-02-16 21:24:52 +01:00
parent 4c304ffe79
commit 9ff8007cae
8 changed files with 48 additions and 61 deletions

View file

@ -1,18 +1,12 @@
use crossterm::event::Event; use crossterm::event::Event;
use crossterm::style::{ContentStyle, Stylize}; use crossterm::style::Stylize;
use toss::{Frame, Pos, Terminal}; use toss::{Frame, Pos, Style, Terminal};
fn draw(f: &mut Frame) { fn draw(f: &mut Frame) {
f.write( f.write(Pos::new(0, 0), ("Hello world!", Style::new().green()));
Pos::new(0, 0),
("Hello world!", ContentStyle::default().green()),
);
f.write( f.write(
Pos::new(0, 1), Pos::new(0, 1),
( ("Press any key to exit", Style::new().on_dark_blue()),
"Press any key to exit",
ContentStyle::default().on_dark_blue(),
),
); );
f.show_cursor(Pos::new(16, 0)); f.show_cursor(Pos::new(16, 0));
} }

View file

@ -1,25 +1,22 @@
use std::convert::Infallible; use std::convert::Infallible;
use crossterm::event::Event; use crossterm::event::Event;
use crossterm::style::{ContentStyle, Stylize}; use crossterm::style::Stylize;
use toss::widgets::{BorderLook, Text}; use toss::widgets::{BorderLook, Text};
use toss::{Styled, Terminal, Widget, WidgetExt}; use toss::{Style, Styled, Terminal, Widget, WidgetExt};
fn widget() -> impl Widget<Infallible> { fn widget() -> impl Widget<Infallible> {
let styled = Styled::new("Hello world!", ContentStyle::default().green()) let styled = Styled::new("Hello world!", Style::new().green())
.then_plain("\n") .then_plain("\n")
.then( .then("Press any key to exit", Style::new().on_dark_blue());
"Press any key to exit",
ContentStyle::default().on_dark_blue(),
);
Text::new(styled) Text::new(styled)
.padding() .padding()
.horizontal(1) .horizontal(1)
.border() .border()
.look(BorderLook::LINE_DOUBLE) .look(BorderLook::LINE_DOUBLE)
.style(ContentStyle::default().dark_red()) .style(Style::new().dark_red())
.background() .background()
.style(ContentStyle::default().on_dark_yellow()) .style(Style::new().on_dark_yellow().opaque())
.float() .float()
.all(0.5) .all(0.5)
} }

View file

@ -1,14 +1,14 @@
use crossterm::event::Event; use crossterm::event::Event;
use crossterm::style::{ContentStyle, Stylize}; use crossterm::style::Stylize;
use toss::{Frame, Pos, Terminal}; use toss::{Frame, Pos, Style, Terminal};
fn draw(f: &mut Frame) { fn draw(f: &mut Frame) {
f.write( f.write(
Pos::new(0, 0), Pos::new(0, 0),
"Writing over wide graphemes removes the entire overwritten grapheme.", "Writing over wide graphemes removes the entire overwritten grapheme.",
); );
let under = ContentStyle::default().white().on_dark_blue(); let under = Style::new().white().on_dark_blue();
let over = ContentStyle::default().black().on_dark_yellow(); let over = Style::new().black().on_dark_yellow();
for i in 0..6 { for i in 0..6 {
let delta = i - 2; let delta = i - 2;
f.write(Pos::new(2 + i * 7, 2), ("a😀", under)); f.write(Pos::new(2 + i * 7, 2), ("a😀", under));

View file

@ -2,7 +2,7 @@ use std::ops::Range;
use crossterm::style::ContentStyle; use crossterm::style::ContentStyle;
use crate::{Pos, Size, Styled, WidthDb}; use crate::{Pos, Size, Style, Styled, WidthDb};
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct Cell { pub struct Cell {
@ -242,18 +242,16 @@ impl Buffer {
let y = pos.y as u16; let y = pos.y as u16;
let mut col: usize = 0; let mut col: usize = 0;
for (_, styled_grapheme) in styled.styled_grapheme_indices() { for (_, style, grapheme) in styled.styled_grapheme_indices() {
let x = pos.x + col as i32; let x = pos.x + col as i32;
let g = *styled_grapheme.content(); let width = widthdb.grapheme_width(grapheme, col);
let style = *styled_grapheme.style();
let width = widthdb.grapheme_width(g, col);
col += width as usize; col += width as usize;
if g == "\t" { if grapheme == "\t" {
for dx in 0..width { for dx in 0..width {
self.write_grapheme(&xrange, x + dx as i32, y, 1, " ", style); self.write_grapheme(&xrange, x + dx as i32, y, 1, " ", style);
} }
} else if width > 0 { } else if width > 0 {
self.write_grapheme(&xrange, x, y, width, g, style); self.write_grapheme(&xrange, x, y, width, grapheme, style);
} }
} }
} }
@ -268,7 +266,7 @@ impl Buffer {
y: u16, y: u16,
width: u8, width: u8,
grapheme: &str, grapheme: &str,
style: ContentStyle, style: Style,
) { ) {
let min_x = xrange.start; let min_x = xrange.start;
let max_x = xrange.end - 1; // Last possible cell let max_x = xrange.end - 1; // Last possible cell
@ -280,6 +278,8 @@ impl Buffer {
return; // Not visible return; // Not visible
} }
// TODO Merge styles
if start_x >= min_x && end_x <= max_x { if start_x >= min_x && end_x <= max_x {
// Fully visible, write actual grapheme // Fully visible, write actual grapheme
for offset in 0..width { for offset in 0..width {
@ -287,7 +287,7 @@ impl Buffer {
self.erase(x, y); self.erase(x, y);
*self.at_mut(x, y) = Cell { *self.at_mut(x, y) = Cell {
content: grapheme.to_string().into_boxed_str(), content: grapheme.to_string().into_boxed_str(),
style, style: style.content_style,
width, width,
offset, offset,
}; };
@ -299,7 +299,7 @@ impl Buffer {
for x in start_x..=end_x { for x in start_x..=end_x {
self.erase(x, y); self.erase(x, y);
*self.at_mut(x, y) = Cell { *self.at_mut(x, y) = Cell {
style, style: style.content_style,
..Default::default() ..Default::default()
}; };
} }

View file

@ -30,15 +30,12 @@ impl Style {
self self
} }
pub fn cover(self, base: Self) -> Self { pub fn cover(self, base: ContentStyle) -> ContentStyle {
if self.opaque { if self.opaque {
return self; return self.content_style;
} }
Self { merge_cs(base, self.content_style)
content_style: merge_cs(base.content_style, self.content_style),
opaque: base.opaque,
}
} }
} }

View file

@ -1,19 +1,20 @@
use std::iter::Peekable; use std::iter::Peekable;
use std::slice; use std::slice;
use crossterm::style::{ContentStyle, StyledContent};
use unicode_segmentation::{GraphemeIndices, Graphemes, UnicodeSegmentation}; use unicode_segmentation::{GraphemeIndices, Graphemes, UnicodeSegmentation};
use crate::Style;
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct Styled { pub struct Styled {
text: String, text: String,
/// List of `(style, until)` tuples. The style should be applied to all /// List of `(style, until)` tuples. The style should be applied to all
/// chars in the range `prev_until..until`. /// chars in the range `prev_until..until`.
styles: Vec<(ContentStyle, usize)>, styles: Vec<(Style, usize)>,
} }
impl Styled { impl Styled {
pub fn new<S: AsRef<str>>(text: S, style: ContentStyle) -> Self { pub fn new<S: AsRef<str>>(text: S, style: Style) -> Self {
Self::default().then(text, style) Self::default().then(text, style)
} }
@ -21,7 +22,7 @@ impl Styled {
Self::default().then_plain(text) Self::default().then_plain(text)
} }
pub fn then<S: AsRef<str>>(mut self, text: S, style: ContentStyle) -> Self { pub fn then<S: AsRef<str>>(mut self, text: S, style: Style) -> Self {
let text = text.as_ref(); let text = text.as_ref();
if !text.is_empty() { if !text.is_empty() {
self.text.push_str(text); self.text.push_str(text);
@ -31,7 +32,7 @@ impl Styled {
} }
pub fn then_plain<S: AsRef<str>>(self, text: S) -> Self { pub fn then_plain<S: AsRef<str>>(self, text: S) -> Self {
self.then(text, ContentStyle::default()) self.then(text, Style::new())
} }
pub fn and_then(mut self, mut other: Self) -> Self { pub fn and_then(mut self, mut other: Self) -> Self {
@ -121,11 +122,11 @@ impl Styled {
pub struct StyledGraphemeIndices<'a> { pub struct StyledGraphemeIndices<'a> {
text: GraphemeIndices<'a>, text: GraphemeIndices<'a>,
styles: Peekable<slice::Iter<'a, (ContentStyle, usize)>>, styles: Peekable<slice::Iter<'a, (Style, usize)>>,
} }
impl<'a> Iterator for StyledGraphemeIndices<'a> { impl<'a> Iterator for StyledGraphemeIndices<'a> {
type Item = (usize, StyledContent<&'a str>); type Item = (usize, Style, &'a str);
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
let (gi, grapheme) = self.text.next()?; let (gi, grapheme) = self.text.next()?;
@ -134,7 +135,7 @@ impl<'a> Iterator for StyledGraphemeIndices<'a> {
self.styles.next(); self.styles.next();
(style, until) = **self.styles.peek().expect("styles cover entire text"); (style, until) = **self.styles.peek().expect("styles cover entire text");
} }
Some((gi, StyledContent::new(style, grapheme))) Some((gi, style, grapheme))
} }
} }
@ -177,14 +178,14 @@ impl<S: AsRef<str>> From<(S,)> for Styled {
} }
} }
impl<S: AsRef<str>> From<(S, ContentStyle)> for Styled { impl<S: AsRef<str>> From<(S, Style)> for Styled {
fn from((text, style): (S, ContentStyle)) -> Self { fn from((text, style): (S, Style)) -> Self {
Self::new(text, style) Self::new(text, style)
} }
} }
impl<S: AsRef<str>> From<&[(S, ContentStyle)]> for Styled { impl<S: AsRef<str>> From<&[(S, Style)]> for Styled {
fn from(segments: &[(S, ContentStyle)]) -> Self { fn from(segments: &[(S, Style)]) -> Self {
let mut result = Self::default(); let mut result = Self::default();
for (text, style) in segments { for (text, style) in segments {
result = result.then(text, *style); result = result.then(text, *style);

View file

@ -1,22 +1,21 @@
use async_trait::async_trait; use async_trait::async_trait;
use crossterm::style::ContentStyle;
use crate::{AsyncWidget, Frame, Pos, Size, Widget}; use crate::{AsyncWidget, Frame, Pos, Size, Style, Widget};
pub struct Background<I> { pub struct Background<I> {
inner: I, inner: I,
style: ContentStyle, style: Style,
} }
impl<I> Background<I> { impl<I> Background<I> {
pub fn new(inner: I) -> Self { pub fn new(inner: I) -> Self {
Self { Self {
inner, inner,
style: ContentStyle::default(), style: Style::default(),
} }
} }
pub fn style(mut self, style: ContentStyle) -> Self { pub fn style(mut self, style: Style) -> Self {
self.style = style; self.style = style;
self self
} }

View file

@ -1,7 +1,6 @@
use async_trait::async_trait; use async_trait::async_trait;
use crossterm::style::ContentStyle;
use crate::{AsyncWidget, Frame, Pos, Size, Widget}; use crate::{AsyncWidget, Frame, Pos, Size, Style, Widget};
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct BorderLook { pub struct BorderLook {
@ -90,7 +89,7 @@ impl Default for BorderLook {
pub struct Border<I> { pub struct Border<I> {
inner: I, inner: I,
look: BorderLook, look: BorderLook,
style: ContentStyle, style: Style,
} }
impl<I> Border<I> { impl<I> Border<I> {
@ -98,7 +97,7 @@ impl<I> Border<I> {
Self { Self {
inner, inner,
look: BorderLook::default(), look: BorderLook::default(),
style: ContentStyle::default(), style: Style::default(),
} }
} }
@ -107,7 +106,7 @@ impl<I> Border<I> {
self self
} }
pub fn style(mut self, style: ContentStyle) -> Self { pub fn style(mut self, style: Style) -> Self {
self.style = style; self.style = style;
self self
} }