This commit is contained in:
2024-10-25 15:50:28 +08:00
parent 9c93085afe
commit aea8ffc9da
6 changed files with 93 additions and 13 deletions

View File

@@ -15,6 +15,10 @@ pub trait View {
fn handle_event(&mut self, event: &Event) -> io::Result<()>; fn handle_event(&mut self, event: &Event) -> io::Result<()>;
} }
pub trait PopupView {
fn active_state(&mut self) -> &mut ActiveState;
}
fn center_rect(area: Rect, width: u16, height: u16) -> Rect { fn center_rect(area: Rect, width: u16, height: u16) -> Rect {
let horizontal = Layout::horizontal([width]).flex(Flex::Center); let horizontal = Layout::horizontal([width]).flex(Flex::Center);
let vertical = Layout::vertical([height]).flex(Flex::Center); let vertical = Layout::vertical([height]).flex(Flex::Center);

View File

@@ -9,6 +9,7 @@ pub mod block;
pub mod help; pub mod help;
pub mod input; pub mod input;
pub mod list; pub mod list;
pub mod button;
pub trait Component { pub trait Component {
type EventResult; type EventResult;

View File

@@ -0,0 +1,41 @@
use ratatui::{symbols::block, widgets::Paragraph};
use crate::view::ActiveState;
use super::{block::BlockComponent, Component};
pub enum ButtonEvent {
Click,
}
#[derive(Default)]
pub struct ButtonComponent {
text: String,
active_state: ActiveState,
}
impl ButtonComponent {
pub fn text(mut self, text: String) -> Self {
self.text = text;
self
}
}
impl Component for ButtonComponent {
type EventResult = ButtonEvent;
fn widget(&self) -> impl ratatui::prelude::Widget {
let block = BlockComponent::default()
.active(self.active_state.is_active())
.widget();
Paragraph::new(self.text.clone()).block(block)
}
fn event_handler(
&mut self,
event: &crossterm::event::Event,
) -> std::io::Result<Self::EventResult> {
Ok(ButtonEvent::Click)
}
fn active_state(&mut self) -> &mut ActiveState {
&mut self.active_state
}
}

View File

@@ -46,7 +46,7 @@ impl Default for ListComponent {
item_keys: vec!["1".to_string(), "2".to_string(), "3".to_string()], item_keys: vec!["1".to_string(), "2".to_string(), "3".to_string()],
cursor: 0, cursor: 0,
selectable: false, selectable: false,
active_state: Default::default() active_state: Default::default(),
} }
} }
} }
@@ -54,7 +54,10 @@ impl Default for ListComponent {
impl Component for ListComponent { impl Component for ListComponent {
type EventResult = ListEvent; type EventResult = ListEvent;
fn widget(&self) -> impl Widget { fn widget(&self) -> impl Widget {
let block = BlockComponent::default().title(self.name.clone()).active(self.active_state.is_active()).widget(); let block = BlockComponent::default()
.title(self.name.clone())
.active(self.active_state.is_active())
.widget();
let list_items: Vec<ListItem> = self let list_items: Vec<ListItem> = self
.item_keys .item_keys
.iter() .iter()
@@ -100,8 +103,8 @@ impl Component for ListComponent {
} }
Enter => { Enter => {
self.active_state.set_active(!self.active_state.is_active()); self.active_state.set_active(!self.active_state.is_active());
return Ok(ListEvent::Select(self.cursor)) return Ok(ListEvent::Select(self.cursor));
}, }
_ => {} _ => {}
} }
} }

View File

@@ -16,7 +16,7 @@ use super::{
Component, Component,
}, },
setting::SettingView, setting::SettingView,
View, PopupView, View,
}; };
// #[derive(Default)] // #[derive(Default)]
@@ -38,6 +38,7 @@ impl Default for Home {
setting: SettingView::default(), setting: SettingView::default(),
}; };
home.table.active_state().set_active(true); home.table.active_state().set_active(true);
// home.setting.active_state().set_active(true);
home home
} }
} }
@@ -66,10 +67,13 @@ impl View for Home {
} }
match self.table.event_handler(event) { match self.table.event_handler(event) {
Ok(ListEvent::Select(i)) => { Ok(ListEvent::Select(i)) => {
let active_state = self.setting.active_state().is_active();
self.setting.active_state().set_active(active_state);
println!("{}", i); println!("{}", i);
} }
_ => {} _ => {}
} }
self.setting.handle_event(event)?;
Ok(()) Ok(())
} }
} }

View File

@@ -1,16 +1,24 @@
use std::io; use std::io;
use ratatui::layout::{Constraint, Layout, Rect}; use ratatui::{
layout::{Constraint, Layout, Rect},
widgets::{Block, Clear},
};
use super::{ use super::{
center_rect, center_rect,
component::{list::ListComponent, Component}, component::{
View, block::BlockComponent,
list::{ListComponent, ListEvent},
Component,
},
ActiveState, PopupView, View,
}; };
pub struct SettingView { pub struct SettingView {
menu: ListComponent, menu: ListComponent,
area: Rect, area: Rect,
activate_state: ActiveState,
} }
impl SettingView {} impl SettingView {}
@@ -20,6 +28,7 @@ impl Default for SettingView {
SettingView { SettingView {
area: Rect::new(0, 0, 10, 5), area: Rect::new(0, 0, 10, 5),
menu: ListComponent::default().selectable(), menu: ListComponent::default().selectable(),
activate_state: Default::default(),
} }
} }
} }
@@ -27,13 +36,31 @@ impl Default for SettingView {
impl View for SettingView { impl View for SettingView {
fn draw(&self, frame: &mut ratatui::Frame) { fn draw(&self, frame: &mut ratatui::Frame) {
let area = center_rect(frame.area(), self.area.width, self.area.height); let area = center_rect(frame.area(), self.area.width, self.area.height);
let layout = Layout::default() if self.activate_state.is_active() {
.constraints([Constraint::default()]) let layout = Layout::default()
.split(area); .constraints([Constraint::default()])
frame.render_widget(self.menu.widget(), layout[0]); .split(area);
frame.render_widget(Clear, area);
frame.render_widget(self.menu.widget(), layout[0]);
} else {
frame.render_widget(Clear, area);
}
} }
fn handle_event(&mut self, _event: &crossterm::event::Event) -> io::Result<()> { fn handle_event(&mut self, event: &crossterm::event::Event) -> io::Result<()> {
match self.menu.event_handler(event) {
Ok(ListEvent::Select(idx)) => {
// self.menu.active_state().set_active(false);
println!("{}", idx);
}
_ => {}
}
Ok(()) Ok(())
} }
} }
impl PopupView for SettingView {
fn active_state(&mut self) -> &mut ActiveState {
&mut self.activate_state
}
}