Event handling (#5)
- Refactor `event` handling (heavily inspired by [crates-tui](https://github.com/ratatui/crates-tui/) via [Tui with Terminal and EventHandler](https://ratatui.rs/recipes/apps/terminal-and-event-handler/)) - Refactor widget structure - Disable `nixos-unstable` temporarily - Add `.rustfmt.toml`
This commit is contained in:
23
src/widgets/countdown.rs
Normal file
23
src/widgets/countdown.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use ratatui::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
widgets::{Paragraph, Widget},
|
||||
};
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub struct Countdown {
|
||||
headline: String,
|
||||
}
|
||||
|
||||
impl Countdown {
|
||||
pub const fn new(headline: String) -> Self {
|
||||
Self { headline }
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Countdown {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let h = Paragraph::new(self.headline).centered();
|
||||
h.render(area, buf);
|
||||
}
|
||||
}
|
||||
71
src/widgets/footer.rs
Normal file
71
src/widgets/footer.rs
Normal file
@@ -0,0 +1,71 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::app::Content;
|
||||
use ratatui::{
|
||||
buffer::Buffer,
|
||||
layout::{Constraint, Layout, Rect},
|
||||
style::{Modifier, Style},
|
||||
symbols,
|
||||
text::{Line, Span},
|
||||
widgets::{Block, Borders, Widget},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Footer {
|
||||
show_menu: bool,
|
||||
selected_content: Content,
|
||||
content_labels: BTreeMap<Content, String>,
|
||||
}
|
||||
|
||||
impl Footer {
|
||||
pub fn new(show_menu: bool, selected_content: Content) -> Self {
|
||||
Self {
|
||||
show_menu,
|
||||
selected_content,
|
||||
content_labels: BTreeMap::from([
|
||||
(Content::Countdown, "[c]ountdown".into()),
|
||||
(Content::Timer, "[t]imer".into()),
|
||||
(Content::Pomodoro, "[p]omodoro".into()),
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Footer {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let [border_area, menu_area] =
|
||||
Layout::vertical([Constraint::Length(1), Constraint::Fill(0)]).areas(area);
|
||||
Block::new()
|
||||
.borders(Borders::TOP)
|
||||
.title(format! {"[m]enu {:} ", if self.show_menu {"↓"} else {"↑"}})
|
||||
.border_set(symbols::border::DOUBLE)
|
||||
.render(border_area, buf);
|
||||
// show menu
|
||||
if self.show_menu {
|
||||
let [title_area, labels_area] =
|
||||
Layout::horizontal([Constraint::Length(12), Constraint::Fill(0)]).areas(menu_area);
|
||||
|
||||
Span::styled("screens", Style::default().add_modifier(Modifier::BOLD))
|
||||
.render(title_area, buf);
|
||||
let spans: Vec<Span> = self
|
||||
.content_labels
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, (content, label))| {
|
||||
let mut style = Style::default();
|
||||
// Add space for all except last
|
||||
let label = if index < self.content_labels.len() - 1 {
|
||||
format!("{} ", label)
|
||||
} else {
|
||||
label.into()
|
||||
};
|
||||
if *content == self.selected_content {
|
||||
style = style.add_modifier(Modifier::BOLD);
|
||||
}
|
||||
Span::styled(label, style)
|
||||
})
|
||||
.collect();
|
||||
Line::from(spans).render(labels_area, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
32
src/widgets/header.rs
Normal file
32
src/widgets/header.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
use ratatui::{
|
||||
buffer::Buffer,
|
||||
layout::{Constraint, Layout, Rect},
|
||||
text::Span,
|
||||
widgets::Widget,
|
||||
};
|
||||
|
||||
use crate::utils::format_ms;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Header {
|
||||
tick: u128,
|
||||
}
|
||||
|
||||
impl Header {
|
||||
pub fn new(tick: u128) -> Self {
|
||||
Self { tick }
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Header {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let time_string = format_ms(self.tick * 100, true);
|
||||
let tick_span = Span::raw(time_string);
|
||||
let tick_width = tick_span.width().try_into().unwrap_or(0);
|
||||
let [h1, h2] =
|
||||
Layout::horizontal([Constraint::Fill(1), Constraint::Length(tick_width)]).areas(area);
|
||||
|
||||
Span::raw("tim:r").render(h1, buf);
|
||||
tick_span.render(h2, buf);
|
||||
}
|
||||
}
|
||||
23
src/widgets/pomodoro.rs
Normal file
23
src/widgets/pomodoro.rs
Normal file
@@ -0,0 +1,23 @@
|
||||
use ratatui::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
widgets::{Paragraph, Widget},
|
||||
};
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub struct Pomodoro {
|
||||
headline: String,
|
||||
}
|
||||
|
||||
impl Pomodoro {
|
||||
pub const fn new(headline: String) -> Self {
|
||||
Self { headline }
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Pomodoro {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let h = Paragraph::new(self.headline).centered();
|
||||
h.render(area, buf);
|
||||
}
|
||||
}
|
||||
24
src/widgets/timer.rs
Normal file
24
src/widgets/timer.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
use ratatui::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
widgets::{Paragraph, Widget},
|
||||
};
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub struct Timer {
|
||||
value: u64,
|
||||
headline: String,
|
||||
}
|
||||
|
||||
impl Timer {
|
||||
pub const fn new(value: u64, headline: String) -> Self {
|
||||
Self { value, headline }
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Timer {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
let h = Paragraph::new(self.headline).centered();
|
||||
h.render(area, buf);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user