StatefulWidgets (#7)
* trait EventHandler * StatefulWidget: AppWidget, CountdownWidget * StatefulWidget: TimerWidget
This commit is contained in:
@@ -1,12 +1,16 @@
|
||||
use ratatui::{
|
||||
buffer::Buffer,
|
||||
crossterm::event::KeyCode,
|
||||
layout::{Constraint, Layout, Rect},
|
||||
widgets::{Paragraph, Widget},
|
||||
widgets::{Paragraph, StatefulWidget, Widget},
|
||||
};
|
||||
|
||||
use crate::clock::{self, Clock};
|
||||
use crate::{
|
||||
clock::{self, Clock},
|
||||
events::{Event, EventHandler},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Countdown {
|
||||
headline: String,
|
||||
clock: Clock<clock::Countdown>,
|
||||
@@ -18,13 +22,33 @@ impl Countdown {
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Countdown {
|
||||
fn render(mut self, area: Rect, buf: &mut Buffer) {
|
||||
let h = Paragraph::new(self.headline).centered();
|
||||
let c = Paragraph::new(self.clock.format()).centered();
|
||||
impl EventHandler for Countdown {
|
||||
fn update(&mut self, event: Event) {
|
||||
match event {
|
||||
Event::Tick => {
|
||||
self.clock.tick();
|
||||
}
|
||||
Event::Key(key) if key.code == KeyCode::Char('s') => {
|
||||
self.clock.toggle_pause();
|
||||
}
|
||||
Event::Key(key) if key.code == KeyCode::Char('r') => {
|
||||
self.clock.reset();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CountdownWidget;
|
||||
|
||||
impl StatefulWidget for &CountdownWidget {
|
||||
type State = Countdown;
|
||||
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
|
||||
let h = Paragraph::new(state.headline.clone()).centered();
|
||||
let c = Paragraph::new(state.clock.format()).centered();
|
||||
let [v1, v2] = Layout::vertical([Constraint::Length(1), Constraint::Length(1)]).areas(area);
|
||||
|
||||
h.render(v1, buf);
|
||||
c.render(v2, buf)
|
||||
c.render(v2, buf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
use ratatui::{
|
||||
buffer::Buffer,
|
||||
crossterm::event::KeyCode,
|
||||
layout::{Constraint, Layout, Rect},
|
||||
widgets::{Paragraph, Widget},
|
||||
widgets::{Paragraph, StatefulWidget, Widget},
|
||||
};
|
||||
|
||||
use crate::clock::{self, Clock};
|
||||
use crate::{
|
||||
clock::{self, Clock},
|
||||
events::{Event, EventHandler},
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Timer {
|
||||
headline: String,
|
||||
clock: Clock<clock::Timer>,
|
||||
@@ -18,10 +22,30 @@ impl Timer {
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Timer {
|
||||
fn render(mut self, area: Rect, buf: &mut Buffer) {
|
||||
let h = Paragraph::new(self.headline).centered();
|
||||
let c = Paragraph::new(self.clock.format()).centered();
|
||||
impl EventHandler for Timer {
|
||||
fn update(&mut self, event: Event) {
|
||||
match event {
|
||||
Event::Tick => {
|
||||
self.clock.tick();
|
||||
}
|
||||
Event::Key(key) if key.code == KeyCode::Char('s') => {
|
||||
self.clock.toggle_pause();
|
||||
}
|
||||
Event::Key(key) if key.code == KeyCode::Char('r') => {
|
||||
self.clock.reset();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TimerWidget;
|
||||
|
||||
impl StatefulWidget for TimerWidget {
|
||||
type State = Timer;
|
||||
fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
|
||||
let h = Paragraph::new(state.headline.clone()).centered();
|
||||
let c = Paragraph::new(state.clock.format()).centered();
|
||||
let [v1, v2] = Layout::vertical([Constraint::Length(1), Constraint::Length(1)]).areas(area);
|
||||
|
||||
h.render(v1, buf);
|
||||
|
||||
Reference in New Issue
Block a user