Component Active State
This commit is contained in:
15
src/view.rs
15
src/view.rs
@@ -22,3 +22,18 @@ fn center_rect(area: Rect, width: u16, height: u16) -> Rect {
|
||||
let [area] = horizontal.areas(area);
|
||||
area
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ActiveState {
|
||||
active_state: bool,
|
||||
}
|
||||
|
||||
impl ActiveState {
|
||||
pub fn is_active(&self) -> bool {
|
||||
self.active_state
|
||||
}
|
||||
|
||||
pub fn set_active(&mut self, active_state: bool) {
|
||||
self.active_state = active_state
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,16 @@ use std::io;
|
||||
use crossterm::event::Event;
|
||||
use ratatui::widgets::Widget;
|
||||
|
||||
use super::ActiveState;
|
||||
|
||||
pub mod block;
|
||||
pub mod help;
|
||||
pub mod input;
|
||||
pub mod list;
|
||||
|
||||
pub trait Component {
|
||||
type EventResult;
|
||||
fn widget(&self) -> impl Widget;
|
||||
fn event_handler(&mut self, event: &Event) -> io::Result<()>;
|
||||
fn event_handler(&mut self, event: &Event) -> io::Result<Self::EventResult>;
|
||||
fn active_state(&mut self) -> &mut ActiveState;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use ratatui::widgets::{Block, Borders};
|
||||
use ratatui::{style::{Style, Stylize}, widgets::{Block, Borders}};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct BlockComponent<'a> {
|
||||
_phantom: PhantomData<&'a ()>,
|
||||
title: String,
|
||||
active: bool,
|
||||
}
|
||||
|
||||
impl<'a> BlockComponent<'a> {
|
||||
pub fn widget(&self) -> Block<'a> {
|
||||
Block::default()
|
||||
.borders(Borders::ALL)
|
||||
.border_style(if self.active {Style::new().blue()} else {Style::new().white()})
|
||||
.title(self.title.clone())
|
||||
}
|
||||
|
||||
@@ -19,4 +21,9 @@ impl<'a> BlockComponent<'a> {
|
||||
self.title = text;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn active(mut self, active: bool) -> Self {
|
||||
self.active = active;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,17 @@ use std::io;
|
||||
use crossterm::event::Event;
|
||||
use ratatui::widgets::{Paragraph, Widget};
|
||||
|
||||
use crate::view::ActiveState;
|
||||
|
||||
use super::{block::BlockComponent, Component};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct HelpComponent {}
|
||||
pub struct HelpComponent {
|
||||
active_state: ActiveState
|
||||
}
|
||||
|
||||
impl Component for HelpComponent {
|
||||
type EventResult = ();
|
||||
fn widget(&self) -> impl Widget {
|
||||
let block = BlockComponent::default().title("Help".to_string()).widget();
|
||||
let help = Paragraph::new("Temp").block(block);
|
||||
@@ -17,4 +22,7 @@ impl Component for HelpComponent {
|
||||
fn event_handler(&mut self, _event: &Event) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
fn active_state(&mut self) -> &mut ActiveState {
|
||||
&mut self.active_state
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::io;
|
||||
|
||||
use super::{block::BlockComponent, Component};
|
||||
use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
|
||||
use ratatui::{
|
||||
layout::{Position, Rect},
|
||||
@@ -8,6 +7,10 @@ use ratatui::{
|
||||
Frame,
|
||||
};
|
||||
|
||||
use crate::view::ActiveState;
|
||||
|
||||
use super::{block::BlockComponent, Component};
|
||||
|
||||
pub enum InputEvent {
|
||||
Compelete,
|
||||
None,
|
||||
@@ -18,6 +21,7 @@ pub struct InputComponent {
|
||||
name: String,
|
||||
value: String,
|
||||
cursor: usize,
|
||||
active_state: ActiveState
|
||||
}
|
||||
|
||||
impl InputComponent {
|
||||
@@ -32,13 +36,18 @@ impl InputComponent {
|
||||
}
|
||||
}
|
||||
impl Component for InputComponent {
|
||||
type EventResult = InputEvent;
|
||||
|
||||
fn widget(&self) -> impl Widget {
|
||||
let block = BlockComponent::default().title(self.name.clone()).widget();
|
||||
let block = BlockComponent::default().title(self.name.clone()).active(self.active_state.is_active()).widget();
|
||||
let input = Paragraph::new(self.value.clone()).block(block);
|
||||
input
|
||||
}
|
||||
|
||||
fn event_handler(&mut self, event: &Event) -> io::Result<InputEvent> {
|
||||
if !self.active_state.is_active() {
|
||||
return Ok(InputEvent::None);
|
||||
}
|
||||
match event {
|
||||
Event::Key(KeyEvent {
|
||||
kind: KeyEventKind::Press,
|
||||
@@ -73,6 +82,9 @@ impl Component for InputComponent {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
Ok(InputEvent::None)
|
||||
}
|
||||
fn active_state(&mut self) -> &mut ActiveState {
|
||||
&mut self.active_state
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use super::{block::BlockComponent, Component};
|
||||
use crossterm::{
|
||||
event::{Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers},
|
||||
style::Color,
|
||||
@@ -8,12 +7,22 @@ use ratatui::{
|
||||
widgets::{List, ListItem, Widget},
|
||||
};
|
||||
|
||||
use crate::view::ActiveState;
|
||||
|
||||
use super::{block::BlockComponent, Component};
|
||||
|
||||
pub enum ListEvent {
|
||||
Select(usize),
|
||||
None,
|
||||
}
|
||||
|
||||
// #[derive(Default)]
|
||||
pub struct ListComponent {
|
||||
name: String,
|
||||
item_keys: Vec<String>,
|
||||
cursor: usize,
|
||||
selectable: bool,
|
||||
active_state: ActiveState,
|
||||
}
|
||||
|
||||
impl ListComponent {
|
||||
@@ -37,13 +46,15 @@ impl Default for ListComponent {
|
||||
item_keys: vec!["1".to_string(), "2".to_string(), "3".to_string()],
|
||||
cursor: 0,
|
||||
selectable: false,
|
||||
active_state: Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for ListComponent {
|
||||
type EventResult = ListEvent;
|
||||
fn widget(&self) -> impl Widget {
|
||||
let block = BlockComponent::default().title(self.name.clone()).widget();
|
||||
let block = BlockComponent::default().title(self.name.clone()).active(self.active_state.is_active()).widget();
|
||||
let list_items: Vec<ListItem> = self
|
||||
.item_keys
|
||||
.iter()
|
||||
@@ -60,9 +71,9 @@ impl Component for ListComponent {
|
||||
list
|
||||
}
|
||||
|
||||
fn event_handler(&mut self, event: &Event) -> std::io::Result<()> {
|
||||
if !self.selectable {
|
||||
return Ok(());
|
||||
fn event_handler(&mut self, event: &Event) -> std::io::Result<ListEvent> {
|
||||
if !self.active_state.is_active() {
|
||||
return Ok(ListEvent::None);
|
||||
}
|
||||
match event {
|
||||
Event::Key(KeyEvent {
|
||||
@@ -87,11 +98,18 @@ impl Component for ListComponent {
|
||||
self.cursor + 1
|
||||
}
|
||||
}
|
||||
Enter => {
|
||||
self.active_state.set_active(!self.active_state.is_active());
|
||||
return Ok(ListEvent::Select(self.cursor))
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
Ok(ListEvent::None)
|
||||
}
|
||||
fn active_state(&mut self) -> &mut ActiveState {
|
||||
&mut self.active_state
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ use ratatui::{
|
||||
use super::{
|
||||
component::{
|
||||
help::HelpComponent,
|
||||
input::{self, InputComponent},
|
||||
list::ListComponent,
|
||||
input::{self, InputComponent, InputEvent},
|
||||
list::{ListComponent, ListEvent},
|
||||
Component,
|
||||
},
|
||||
setting::SettingView,
|
||||
@@ -25,20 +25,20 @@ pub struct Home {
|
||||
table: ListComponent,
|
||||
help: HelpComponent,
|
||||
setting: SettingView,
|
||||
event_recive: [bool;4],
|
||||
}
|
||||
|
||||
impl Default for Home {
|
||||
fn default() -> Self {
|
||||
Home {
|
||||
let mut home = Home {
|
||||
input: InputComponent::default().name("Name".to_string()),
|
||||
table: ListComponent::default()
|
||||
.selectable()
|
||||
.name("Connections".to_string()),
|
||||
help: HelpComponent::default(),
|
||||
setting: SettingView::default(),
|
||||
event_recive: [true, false, false, false]
|
||||
}
|
||||
};
|
||||
home.table.active_state().set_active(true);
|
||||
home
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,8 +60,16 @@ impl View for Home {
|
||||
}
|
||||
|
||||
fn handle_event(&mut self, event: &Event) -> io::Result<()> {
|
||||
if self.event_recive[0] {self.input.event_handler(event)?};
|
||||
if self.event_recive[1] {self.table.event_handler(event)?};
|
||||
match self.input.event_handler(event) {
|
||||
Ok(InputEvent::None) => {}
|
||||
_ => {}
|
||||
}
|
||||
match self.table.event_handler(event) {
|
||||
Ok(ListEvent::Select(i)) => {
|
||||
println!("{}", i);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user