use tui::widgets::{Block,Borders,Paragraph,Widget,Wrap};
use tui::layout::{Alignment,Layout,Constraint,Direction,Rect};
use tui::buffer::Buffer;
use tui::style::{Style,Color,Modifier};
use tui::symbols::DOT;
use tui::text::{Spans,Span,Text};
use crate::records::Record;
use crate::sm2::Rating;
#[derive(Clone,Default)]
pub struct Slide {
question: String,
answer: String,
selected: usize,
step: Option<usize>,
}
impl Slide {
pub fn record(self,record: &Record) -> Self {
Self {
question: record.question.clone(),
answer: record.answer.clone(),
selected: 0,
step: Some(0),
}
}
pub fn next(&mut self) {
if self.selected < 6 {
self.selected += 2
}
}
pub fn prev(&mut self) {
if self.selected > 0 {
self.selected -= 2
}
}
pub fn cont(&mut self) {
if let Some(x) = self.step {
if x < 2 { self.step = Some(x+1) }
else { self.step = None }
}
}
pub fn step(&self) -> Option<usize> {
self.step
}
pub fn rating(&self) -> Rating {
match self.selected {
0 => Rating::Again,
2 => Rating::Hard,
4 => Rating::Good,
6 => Rating::Easy,
_ => unreachable!(),
}
}
}
impl Widget for Slide {
fn render(self, area: Rect, buf: &mut Buffer) {
let style = Style::default();
buf.set_style(area,style);
let block = Block::default()
.title("Cards")
.borders(Borders::ALL);
let slide_area = {
let inner = block.inner(area);
block.render(area,buf);
inner
};
if slide_area.height < 1 { return };
let layout = Layout::default()
.direction(Direction::Vertical)
.constraints(
[
Constraint::Percentage(45),
Constraint::Percentage(45),
Constraint::Percentage(10),
].as_ref()
).split(slide_area);
let get_paragraph = |s| {
Paragraph::new(s)
.block(Block::default())
.style(Style::default())
.alignment(Alignment::Center)
.wrap(Wrap { trim: true })
};
let question = get_paragraph(Text::from(self.question));
question.render(layout[0],buf);
if let Some(x) = self.step {
if x < 1 { return; }
}
let ans_style = Style::default().fg(Color::Green);
let answer = get_paragraph(Text::from(self.answer)).style(ans_style);
answer.render(layout[1],buf);
if let Some(x) = self.step {
if x < 2 { return; }
}
let selected = self.selected;
let style_selected = Style::default()
.fg(Color::Yellow)
.add_modifier(Modifier::BOLD);
let style_unselected = Style::default()
.add_modifier(Modifier::DIM);
let tabs = {
let titles: Vec<Span> = ["Again ",DOT," Hard ",DOT," Good ",DOT," Easy"].iter()
.cloned()
.enumerate()
.map(|(i,s)| {
if i == selected { Span::styled(s,style_selected) }
else { Span::styled(s,style_unselected) }
})
.collect();
let titles = Spans::from(titles);
get_paragraph(Text::from(titles))
};
tabs.render(layout[2],buf);
}
}