impl Trait(can run)
This commit is contained in:
46
src/app.rs
Normal file
46
src/app.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use std::io;
|
||||
|
||||
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind};
|
||||
use ratatui::{DefaultTerminal, Frame};
|
||||
|
||||
use crate::view::home::{self, Home};
|
||||
|
||||
pub struct App {
|
||||
running: bool,
|
||||
view: Home,
|
||||
}
|
||||
|
||||
impl Default for App {
|
||||
fn default() -> Self {
|
||||
App {
|
||||
running: true,
|
||||
view: Home::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn run(&mut self, terminal: &mut DefaultTerminal) -> io::Result<()> {
|
||||
while self.running {
|
||||
terminal.draw(|frame| self.draw(frame))?;
|
||||
self.handle_event()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn draw(&self, frame: &mut Frame) {
|
||||
self.view.draw(frame);
|
||||
}
|
||||
|
||||
fn handle_event(&mut self) -> io::Result<()> {
|
||||
match event::read()? {
|
||||
Event::Key(KeyEvent {
|
||||
kind: KeyEventKind::Press,
|
||||
code: KeyCode::Esc,
|
||||
..
|
||||
}) => self.running = false,
|
||||
event => self.view.handle_event(event)?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
13
src/main.rs
Normal file
13
src/main.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
use std::io;
|
||||
|
||||
use app::App;
|
||||
|
||||
mod app;
|
||||
mod view;
|
||||
|
||||
fn main() -> io::Result<()> {
|
||||
let mut terminal = ratatui::init();
|
||||
let app_result = App::default().run(&mut terminal);
|
||||
ratatui::restore();
|
||||
app_result
|
||||
}
|
||||
7
src/view.rs
Normal file
7
src/view.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
use component::Component;
|
||||
|
||||
pub mod component;
|
||||
pub mod home;
|
||||
|
||||
pub trait View {
|
||||
}
|
||||
13
src/view/component.rs
Normal file
13
src/view/component.rs
Normal file
@@ -0,0 +1,13 @@
|
||||
use std::io;
|
||||
|
||||
use crossterm::event::Event;
|
||||
use ratatui::widgets::Widget;
|
||||
|
||||
pub mod block;
|
||||
pub mod input;
|
||||
pub mod table;
|
||||
|
||||
pub trait Component {
|
||||
fn widget(&self) -> impl Widget;
|
||||
fn event_handler(&mut self, event: Event) -> io::Result<()>;
|
||||
}
|
||||
14
src/view/component/block.rs
Normal file
14
src/view/component/block.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use ratatui::widgets::{Block, Borders};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct BlockWidget<'a> {
|
||||
_phantom: PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
impl<'a> BlockWidget<'a> {
|
||||
pub fn widget(&self) -> Block<'a> {
|
||||
Block::default().borders(Borders::ALL)
|
||||
}
|
||||
}
|
||||
50
src/view/component/input.rs
Normal file
50
src/view/component/input.rs
Normal file
@@ -0,0 +1,50 @@
|
||||
use std::{io, marker::PhantomData, u32};
|
||||
|
||||
use super::{block::BlockWidget, Component};
|
||||
use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
|
||||
use ratatui::{
|
||||
prelude::Rect,
|
||||
widgets::{Block, Paragraph, Widget},
|
||||
Frame,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct InputWidget {
|
||||
name: String,
|
||||
value: String,
|
||||
cursor_idx: usize,
|
||||
}
|
||||
|
||||
impl InputWidget {
|
||||
pub fn new() -> Self {
|
||||
InputWidget::default()
|
||||
}
|
||||
}
|
||||
impl Component for InputWidget {
|
||||
fn widget(&self) -> impl Widget {
|
||||
let block = BlockWidget::default().widget();
|
||||
let input = Paragraph::new(self.value.clone()).block(block);
|
||||
input
|
||||
}
|
||||
|
||||
fn event_handler(&mut self, event: Event) -> io::Result<()> {
|
||||
match event {
|
||||
Event::Key(KeyEvent {
|
||||
kind: KeyEventKind::Press,
|
||||
code,
|
||||
modifiers,
|
||||
..
|
||||
}) => {
|
||||
use KeyCode::*;
|
||||
match (code, modifiers) {
|
||||
(Char(c), KeyModifiers::SHIFT | KeyModifiers::NONE) => {
|
||||
self.value.push(c);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
29
src/view/component/table.rs
Normal file
29
src/view/component/table.rs
Normal file
@@ -0,0 +1,29 @@
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use super::{block::BlockWidget, Component};
|
||||
use crossterm::event::{self, Event};
|
||||
use ratatui::{
|
||||
prelude::Rect,
|
||||
widgets::{Block, Paragraph, Widget},
|
||||
Frame,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct TableWidget {}
|
||||
|
||||
impl TableWidget {
|
||||
pub fn new() -> Self {
|
||||
TableWidget::default()
|
||||
}
|
||||
}
|
||||
impl Component for TableWidget {
|
||||
fn widget(&self) -> impl Widget {
|
||||
let block = BlockWidget::default().widget();
|
||||
let input = Paragraph::new("sss").block(block);
|
||||
input
|
||||
}
|
||||
|
||||
fn event_handler(&mut self, event: Event) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
36
src/view/home.rs
Normal file
36
src/view/home.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use std::io;
|
||||
|
||||
use crossterm::event::{ Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
|
||||
use ratatui::{
|
||||
layout::{Constraint, Direction, Layout, Rect},
|
||||
widgets::Paragraph,
|
||||
Frame,
|
||||
};
|
||||
|
||||
use super::component::{input::InputWidget, table::TableWidget, Component};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Home {
|
||||
input: InputWidget,
|
||||
table: TableWidget,
|
||||
}
|
||||
|
||||
impl Home {
|
||||
pub fn draw(&self, frame: &mut Frame) {
|
||||
let layout = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.constraints(vec![
|
||||
Constraint::Length(3),
|
||||
Constraint::Min(5),
|
||||
Constraint::Length(3),
|
||||
])
|
||||
.split(frame.area());
|
||||
frame.render_widget(self.input.widget(), layout[0]);
|
||||
frame.render_widget(self.table.widget(), layout[1]);
|
||||
}
|
||||
|
||||
pub fn handle_event(&mut self, event: Event) -> io::Result<()> {
|
||||
self.input.event_handler(event)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user