108 lines
3 KiB
Rust
108 lines
3 KiB
Rust
use std::sync::{atomic::{AtomicUsize, Ordering}, Arc};
|
|
|
|
use color_eyre::Result;
|
|
use ratatui::{prelude::*, widgets::*};
|
|
use tokio::sync::mpsc::UnboundedSender;
|
|
|
|
use super::Component;
|
|
use crate::{action::Action, config::Config};
|
|
|
|
#[derive(Default)]
|
|
pub struct Tabs {
|
|
command_tx: Option<UnboundedSender<Action>>,
|
|
config: Config,
|
|
tabs: Vec<&'static str>,
|
|
selected_tab: Arc<AtomicUsize>,
|
|
}
|
|
|
|
impl Tabs {
|
|
pub fn new(tabs: Vec<&'static str>, selected_tab: Arc<AtomicUsize>) -> Self {
|
|
Self {
|
|
tabs,
|
|
selected_tab,
|
|
..Default::default()
|
|
}
|
|
}
|
|
|
|
pub fn next(&mut self) {
|
|
if self.selected_tab.load(Ordering::Relaxed) < self.tabs.len() - 1 {
|
|
self.selected_tab.fetch_add(1, Ordering::Relaxed);
|
|
}
|
|
}
|
|
|
|
pub fn previous(&mut self) {
|
|
if self.selected_tab.load(Ordering::Relaxed) > 0 {
|
|
self.selected_tab.fetch_sub(1, Ordering::Relaxed);
|
|
}
|
|
}
|
|
|
|
pub fn current_tab(&self) -> usize {
|
|
self.selected_tab.load(Ordering::Relaxed)
|
|
}
|
|
}
|
|
|
|
impl Component for Tabs {
|
|
fn register_action_handler(&mut self, tx: UnboundedSender<Action>) -> Result<()> {
|
|
self.command_tx = Some(tx);
|
|
Ok(())
|
|
}
|
|
|
|
fn register_config_handler(&mut self, config: Config) -> Result<()> {
|
|
self.config = config;
|
|
Ok(())
|
|
}
|
|
|
|
fn update(&mut self, action: Action) -> Result<Option<Action>> {
|
|
match action {
|
|
Action::Tick => {}
|
|
Action::Render => {}
|
|
Action::NextTab => self.next(),
|
|
Action::PrevTab => self.previous(),
|
|
_ => {}
|
|
};
|
|
|
|
Ok(None)
|
|
}
|
|
|
|
fn draw(&mut self, frame: &mut Frame, area: Rect) -> Result<()> {
|
|
let mut tab_lines = vec![Line::default(), Line::default()];
|
|
|
|
for (i, &tab) in self.tabs.iter().enumerate() {
|
|
let style = if self.selected_tab.load(Ordering::Relaxed) == i {
|
|
Style::default()
|
|
.fg(Color::Magenta)
|
|
.add_modifier(Modifier::BOLD)
|
|
} else {
|
|
Style::default().fg(Color::White)
|
|
};
|
|
|
|
tab_lines[0].spans.push(Span::styled(
|
|
format!("╭{}╮", "─".repeat(tab.len() + 2)),
|
|
Style::default().fg(Color::DarkGray),
|
|
));
|
|
|
|
tab_lines[1]
|
|
.spans
|
|
.push(Span::styled("│", Style::default().fg(Color::DarkGray)));
|
|
tab_lines[1]
|
|
.spans
|
|
.push(Span::styled(format!(" {} ", tab), style));
|
|
tab_lines[1]
|
|
.spans
|
|
.push(Span::styled("│", Style::default().fg(Color::DarkGray)));
|
|
}
|
|
|
|
let tabs_widget = Paragraph::new(tab_lines).block(Block::default().borders(Borders::NONE));
|
|
|
|
frame.render_widget(
|
|
tabs_widget,
|
|
Rect {
|
|
x: area.x,
|
|
y: area.y,
|
|
width: area.width,
|
|
height: 2,
|
|
},
|
|
);
|
|
|
|
Ok(())
|
|
}}
|