Skip to content

Commit

Permalink
listをselectできるようした
Browse files Browse the repository at this point in the history
  • Loading branch information
kyu08 committed Nov 25, 2023
1 parent 1abfc9c commit e1976d5
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 30 deletions.
78 changes: 56 additions & 22 deletions src/usecases/fzf_make_ratatui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ use crossterm::{
};
use ratatui::{
backend::{Backend, CrosstermBackend},
widgets::ListState,
Terminal,
};
use std::{error::Error, io, process};

#[derive(Clone)]
pub enum CurrentPain {
Main,
History,
Expand All @@ -32,13 +34,18 @@ enum Message {
Quit,
KeyInput(String),
Backspace, // TODO: Delegate to rhysd/tui-textarea
Next,
Previous,
}

#[derive(Clone)]
pub struct Model {
pub current_pain: CurrentPain,
pub key_input: String,
pub current_pain: CurrentPain, // the current screen the user is looking at, and will later determine what is rendered.
pub should_quit: bool,
pub makefile: Makefile,
// the current screen the user is looking at, and will later determine what is rendered.
pub should_quit: bool,
pub state: ListState,
}

impl Model {
Expand All @@ -55,18 +62,47 @@ impl Model {
key_input: String::new(),
current_pain: CurrentPain::Main,
should_quit: false,
makefile,
makefile: makefile.clone(),
state: ListState::default(),
})
}

pub fn update_key_input(&mut self, key_input: String) -> String {
pub fn update_key_input(&self, key_input: String) -> String {
self.key_input.clone() + &key_input
}
pub fn pop(&mut self) -> String {
pub fn pop(&self) -> String {
let mut origin = self.key_input.clone();
origin.pop();
origin
}

fn next(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i >= self.makefile.to_targets_string().len() - 1 {
0
} else {
i + 1
}
}
None => 0,
};
self.state.select(Some(i));
}

fn previous(&mut self) {
let i = match self.state.selected() {
Some(i) => {
if i == 0 {
self.makefile.to_targets_string().len() - 1
} else {
i - 1
}
}
None => 0,
};
self.state.select(Some(i));
}
}

pub fn main() -> Result<(), Box<dyn Error>> {
Expand All @@ -77,8 +113,8 @@ pub fn main() -> Result<(), Box<dyn Error>> {
let backend = CrosstermBackend::new(stderr);
let mut terminal = Terminal::new(backend)?;

if let Ok(mut model) = Model::new() {
let _ = run(&mut terminal, &mut model); // TODO: error handling
if let Ok(model) = Model::new() {
let _ = run(&mut terminal, model); // TODO: error handling
}

disable_raw_mode()?;
Expand All @@ -92,12 +128,12 @@ pub fn main() -> Result<(), Box<dyn Error>> {
Ok(())
}

fn run<B: Backend>(terminal: &mut Terminal<B>, model: &mut Model) -> io::Result<()> {
fn run<B: Backend>(terminal: &mut Terminal<B>, mut model: Model) -> io::Result<()> {
loop {
terminal.draw(|f| ui(f, model))?;
match handle_event(model) {
terminal.draw(|f| ui(f, &mut model.clone()))?;
match handle_event(&model) {
Ok(message) => {
let model = update(model, message);
update(&mut model, message);
if model.should_quit {
break;
}
Expand All @@ -118,6 +154,8 @@ fn handle_event(model: &Model) -> io::Result<Option<Message>> {
_ => match model.current_pain {
CurrentPain::Main => match key.code {
KeyCode::Backspace => Some(Message::Backspace),
KeyCode::Down => Some(Message::Next),
KeyCode::Up => Some(Message::Previous),
KeyCode::Char(char) => Some(Message::KeyInput(char.to_string())),
_ => None,
},
Expand All @@ -136,22 +174,18 @@ fn handle_event(model: &Model) -> io::Result<Option<Message>> {
Ok(message)
}

fn update(model: &mut Model, message: Option<Message>) -> &mut Model {
// TODO: Add UT
fn update(model: &mut Model, message: Option<Message>) {
match message {
Some(Message::MoveToNextPain) => match model.current_pain {
CurrentPain::Main => model.current_pain = CurrentPain::History,
CurrentPain::History => model.current_pain = CurrentPain::Main,
},
Some(Message::Quit) => {
model.should_quit = true;
}
Some(Message::KeyInput(key_input)) => {
model.key_input = model.update_key_input(key_input);
}
Some(Message::Backspace) => {
model.key_input = model.pop();
}
Some(Message::Quit) => model.should_quit = true,
Some(Message::KeyInput(key_input)) => model.key_input = model.update_key_input(key_input),
Some(Message::Backspace) => model.key_input = model.pop(),
Some(Message::Next) => model.next(),
Some(Message::Previous) => model.previous(),
None => {}
}
model
}
21 changes: 13 additions & 8 deletions src/usecases/fzf_make_ratatui/ui.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
use super::app::Model;
use crate::models::makefile::Makefile;
use fuzzy_matcher::skim::SkimMatcherV2;
use fuzzy_matcher::FuzzyMatcher;
use ratatui::{
backend::Backend,
layout::{Constraint, Direction, Layout},
style::{Color, Style},
style::{Color, Modifier, Style},
text::{Line, Span},
widgets::{Block, Borders, List, ListItem, Paragraph},
Frame,
};

use crate::models::makefile::Makefile;

use super::app::Model;

pub fn ui<B: Backend>(f: &mut Frame<B>, model: &Model) {
pub fn ui<B: Backend>(f: &mut Frame<B>, model: &mut Model) {
// Create the layout sections.
let main_chunks = Layout::default()
.direction(Direction::Vertical)
Expand All @@ -37,14 +35,16 @@ pub fn ui<B: Backend>(f: &mut Frame<B>, model: &Model) {
rounded_border_block("Preview", model.current_pain.is_main()),
fzf_make_preview_chunks[0],
);
f.render_widget(
f.render_stateful_widget(
targets_block(
"Targets",
model.key_input.clone(),
model.makefile.clone(),
model.current_pain.is_main(),
),
fzf_make_preview_chunks[1],
// NOTE: It is against TEA's way to update the model value on the UI side, but it is unavoidable so it is allowed.
&mut model.state,
);
f.render_widget(
// NOTE: To show cursor, use rhysd/tui-textarea
Expand Down Expand Up @@ -89,7 +89,6 @@ fn input_block<'a>(title: &'a str, target_input: &'a str, is_current: bool) -> P
.style(Style::default())
}
fn targets_block(title: &str, key_input: String, makefile: Makefile, is_current: bool) -> List<'_> {
// TODO: 選択する
let fg_color = if is_current {
Color::Yellow
} else {
Expand Down Expand Up @@ -127,6 +126,12 @@ fn targets_block(title: &str, key_input: String, makefile: Makefile, is_current:
.padding(ratatui::widgets::Padding::new(2, 0, 0, 0)),
)
.style(Style::default())
.highlight_style(
Style::default()
.bg(Color::LightGreen)
.add_modifier(Modifier::BOLD),
)
.highlight_symbol(">> ")
}

fn rounded_border_block(title: &str, is_current: bool) -> Block {
Expand Down

0 comments on commit e1976d5

Please sign in to comment.