diff --git a/src/view.rs b/src/view.rs index 9bdfa35..feb4f0e 100644 --- a/src/view.rs +++ b/src/view.rs @@ -15,6 +15,10 @@ pub trait View { 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 { let horizontal = Layout::horizontal([width]).flex(Flex::Center); let vertical = Layout::vertical([height]).flex(Flex::Center); diff --git a/src/view/component.rs b/src/view/component.rs index 99931e9..870d35d 100644 --- a/src/view/component.rs +++ b/src/view/component.rs @@ -9,6 +9,7 @@ pub mod block; pub mod help; pub mod input; pub mod list; +pub mod button; pub trait Component { type EventResult; diff --git a/src/view/component/button.rs b/src/view/component/button.rs new file mode 100644 index 0000000..18a4da3 --- /dev/null +++ b/src/view/component/button.rs @@ -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 { + Ok(ButtonEvent::Click) + } + fn active_state(&mut self) -> &mut ActiveState { + &mut self.active_state + } +} diff --git a/src/view/component/list.rs b/src/view/component/list.rs index b971aa2..15ce9d9 100644 --- a/src/view/component/list.rs +++ b/src/view/component/list.rs @@ -46,7 +46,7 @@ impl Default for ListComponent { item_keys: vec!["1".to_string(), "2".to_string(), "3".to_string()], cursor: 0, selectable: false, - active_state: Default::default() + active_state: Default::default(), } } } @@ -54,7 +54,10 @@ impl Default for ListComponent { impl Component for ListComponent { type EventResult = ListEvent; 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 = self .item_keys .iter() @@ -100,8 +103,8 @@ impl Component for ListComponent { } Enter => { self.active_state.set_active(!self.active_state.is_active()); - return Ok(ListEvent::Select(self.cursor)) - }, + return Ok(ListEvent::Select(self.cursor)); + } _ => {} } } diff --git a/src/view/home.rs b/src/view/home.rs index b7451fc..b28b851 100644 --- a/src/view/home.rs +++ b/src/view/home.rs @@ -16,7 +16,7 @@ use super::{ Component, }, setting::SettingView, - View, + PopupView, View, }; // #[derive(Default)] @@ -38,6 +38,7 @@ impl Default for Home { setting: SettingView::default(), }; home.table.active_state().set_active(true); + // home.setting.active_state().set_active(true); home } } @@ -66,10 +67,13 @@ impl View for Home { } match self.table.event_handler(event) { Ok(ListEvent::Select(i)) => { + let active_state = self.setting.active_state().is_active(); + self.setting.active_state().set_active(active_state); println!("{}", i); } _ => {} } + self.setting.handle_event(event)?; Ok(()) } } diff --git a/src/view/setting.rs b/src/view/setting.rs index 793bf82..3fa71d5 100644 --- a/src/view/setting.rs +++ b/src/view/setting.rs @@ -1,16 +1,24 @@ use std::io; -use ratatui::layout::{Constraint, Layout, Rect}; +use ratatui::{ + layout::{Constraint, Layout, Rect}, + widgets::{Block, Clear}, +}; use super::{ center_rect, - component::{list::ListComponent, Component}, - View, + component::{ + block::BlockComponent, + list::{ListComponent, ListEvent}, + Component, + }, + ActiveState, PopupView, View, }; pub struct SettingView { menu: ListComponent, area: Rect, + activate_state: ActiveState, } impl SettingView {} @@ -20,6 +28,7 @@ impl Default for SettingView { SettingView { area: Rect::new(0, 0, 10, 5), menu: ListComponent::default().selectable(), + activate_state: Default::default(), } } } @@ -27,13 +36,31 @@ impl Default for SettingView { impl View for SettingView { fn draw(&self, frame: &mut ratatui::Frame) { let area = center_rect(frame.area(), self.area.width, self.area.height); - let layout = Layout::default() - .constraints([Constraint::default()]) - .split(area); - frame.render_widget(self.menu.widget(), layout[0]); + if self.activate_state.is_active() { + let layout = Layout::default() + .constraints([Constraint::default()]) + .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(()) } } + +impl PopupView for SettingView { + fn active_state(&mut self) -> &mut ActiveState { + &mut self.activate_state + } +}