84 lines
2.5 KiB
Rust
84 lines
2.5 KiB
Rust
use crossterm::event::{Event, KeyCode, KeyEventKind, KeyModifiers};
|
|
use ratatui::{
|
|
buffer::Buffer,
|
|
layout::{Alignment, Rect},
|
|
style::{Color, Modifier, Style},
|
|
text::{Line, Span},
|
|
widgets::{Block, Borders, Paragraph, Widget},
|
|
};
|
|
|
|
use super::UiAction;
|
|
|
|
pub struct ControlsWidget;
|
|
|
|
pub fn parse_ui_action(raw_event: Event) -> UiAction {
|
|
match raw_event {
|
|
Event::Key(key_event) => {
|
|
if key_event.kind != KeyEventKind::Press {
|
|
return UiAction::None;
|
|
}
|
|
|
|
if key_event.modifiers == KeyModifiers::CONTROL {
|
|
return match key_event.code {
|
|
KeyCode::Char('p') => UiAction::FocusEntryUp,
|
|
KeyCode::Char('n') => UiAction::FocusEntryDown,
|
|
KeyCode::Char('l') => UiAction::FocusPaneRight,
|
|
KeyCode::Char('h') => UiAction::FocusPaneLeft,
|
|
_ => UiAction::None,
|
|
};
|
|
}
|
|
|
|
if key_event.modifiers == KeyModifiers::NONE {
|
|
return match key_event.code {
|
|
KeyCode::Char('l') => UiAction::FocusPaneRight,
|
|
KeyCode::Char('h') => UiAction::FocusPaneLeft,
|
|
KeyCode::Char('d') => UiAction::ToggleDebug,
|
|
KeyCode::Char('q') => UiAction::Exit,
|
|
KeyCode::Enter => UiAction::OpenArticle,
|
|
_ => UiAction::None,
|
|
};
|
|
}
|
|
|
|
UiAction::None
|
|
}
|
|
_ => UiAction::None,
|
|
}
|
|
}
|
|
|
|
macro_rules! control {
|
|
($key:literal) => {
|
|
Span::styled(
|
|
$key,
|
|
Style::default().fg(Color::Red).add_modifier(Modifier::BOLD),
|
|
)
|
|
};
|
|
}
|
|
|
|
macro_rules! description {
|
|
($key:literal) => {
|
|
Span::raw($key)
|
|
};
|
|
}
|
|
|
|
impl Widget for ControlsWidget {
|
|
fn render(self, area: Rect, buf: &mut Buffer) {
|
|
let controls_text = Line::from(vec![
|
|
control!("j/k"),
|
|
description!(" to navigate up/down, "),
|
|
control!("h/l"),
|
|
description!(" to switch between channels and articles, "),
|
|
control!("q"),
|
|
description!(" to exit"),
|
|
])
|
|
.style(
|
|
Style::default()
|
|
.fg(Color::DarkGray)
|
|
.add_modifier(Modifier::BOLD),
|
|
);
|
|
let para = Paragraph::new(controls_text)
|
|
.block(Block::default().borders(Borders::NONE))
|
|
.alignment(Alignment::Center);
|
|
para.render(area, buf);
|
|
}
|
|
}
|