From da10719250e4c719a174ab36d88efe8d8fc3d441 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Tue, 6 Jun 2023 21:03:19 +0700 Subject: [PATCH] Fix task edit border and rename some symbols --- src/app.rs | 16 ++--- src/input.rs | 41 ++++++------ src/ui.rs | 175 +++++++++++++++++++++++++-------------------------- 3 files changed, 115 insertions(+), 117 deletions(-) diff --git a/src/app.rs b/src/app.rs index a2844a3..9bf0e81 100644 --- a/src/app.rs +++ b/src/app.rs @@ -57,25 +57,25 @@ impl Default for Project { } #[derive(Debug)] -pub enum NewTaskFocus { +pub enum TaskEditFocus { Title, Description, CreateBtn, CancelBtn } -pub struct NewTask<'a> { +pub struct TaskState<'a> { pub title: TextArea<'a>, pub description: TextArea<'a>, - pub focus: NewTaskFocus + pub focus: TaskEditFocus } -impl Default for NewTask<'_> { +impl Default for TaskState<'_> { fn default() -> Self { - NewTask { + TaskState { title: TextArea::default(), description: TextArea::default(), - focus: NewTaskFocus::Title + focus: TaskEditFocus::Title } } } @@ -84,14 +84,14 @@ pub struct AppState<'a> { pub project: Project, pub quit: bool, pub columns: Vec, - pub new_task_state: Option>, + pub task_edit_state: Option>, } impl AppState<'_> { pub fn new(project: Project) -> Self { AppState { quit: false, - new_task_state: None, + task_edit_state: None, project, columns: vec![], } diff --git a/src/input.rs b/src/input.rs index f37c33d..7f9eb4d 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,7 +1,7 @@ #![allow(unused_imports)] use crossterm::event; use crossterm::event::{Event, KeyCode}; -use crate::app::{NewTask, AppState, NewTaskFocus}; +use crate::app::{TaskState, AppState, TaskEditFocus}; use std::io::{stdout, Write}; use tui_textarea::TextArea; @@ -9,45 +9,45 @@ pub fn handle_input(state: &mut AppState) -> Result<(), std::io::Error> { let project = &mut state.project; let column = project.get_selected_column_mut(); if let Event::Key(key) = event::read()? { - match &mut state.new_task_state { + match &mut state.task_edit_state { Some(task) => { // TODO: Extract this code to a separate function to avoid nesting match task.focus { // TODO: Handle wrapping around the enum rather than doing it manually - NewTaskFocus::Title => { + TaskEditFocus::Title => { match key.code { - KeyCode::Tab => task.focus = NewTaskFocus::Description, - KeyCode::BackTab => task.focus = NewTaskFocus::CancelBtn, + KeyCode::Tab => task.focus = TaskEditFocus::Description, + KeyCode::BackTab => task.focus = TaskEditFocus::CancelBtn, KeyCode::Enter => (), _ => { task.title.input(key); } } } - NewTaskFocus::Description => { + TaskEditFocus::Description => { match key.code { - KeyCode::Tab => task.focus = NewTaskFocus::CreateBtn, - KeyCode::BackTab => task.focus = NewTaskFocus::Title, + KeyCode::Tab => task.focus = TaskEditFocus::CreateBtn, + KeyCode::BackTab => task.focus = TaskEditFocus::Title, _ => { task.description.input(key); } } } - NewTaskFocus::CreateBtn => { + TaskEditFocus::CreateBtn => { match key.code { - KeyCode::Tab => task.focus = NewTaskFocus::CancelBtn, - KeyCode::BackTab => task.focus = NewTaskFocus::Description, + KeyCode::Tab => task.focus = TaskEditFocus::CancelBtn, + KeyCode::BackTab => task.focus = TaskEditFocus::Description, KeyCode::Enter => { let title = task.title.clone().into_lines().join("\n"); let description = task.description.clone().into_lines().clone().join("\n"); column.add_task(title, description); - state.new_task_state = None + state.task_edit_state = None } _ => (), } } - NewTaskFocus::CancelBtn => { + TaskEditFocus::CancelBtn => { match key.code { - KeyCode::Tab => task.focus = NewTaskFocus::Title, - KeyCode::BackTab => task.focus = NewTaskFocus::CreateBtn, + KeyCode::Tab => task.focus = TaskEditFocus::Title, + KeyCode::BackTab => task.focus = TaskEditFocus::CreateBtn, KeyCode::Enter => { - state.new_task_state = None + state.task_edit_state = None } _ => (), } @@ -73,10 +73,11 @@ pub fn handle_input(state: &mut AppState) -> Result<(), std::io::Error> { KeyCode::Char('J') => project.move_task_down(), KeyCode::Char('-') | KeyCode::Char('K') => project.move_task_up(), - KeyCode::Char('p') => { - match state.new_task_state { - None => state.new_task_state = Some(NewTask::default()), - Some(_) => state.new_task_state = None, + KeyCode::Char('n') => state.task_edit_state = Some(TaskState::default()), + KeyCode::Char('e') => { + match state.task_edit_state { + None => state.task_edit_state = Some(TaskState::default()), + Some(_) => state.task_edit_state = None, } } KeyCode::Char('D') => column.remove_task(), diff --git a/src/ui.rs b/src/ui.rs index 4b7e37d..ab43cf3 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -89,101 +89,98 @@ fn centered_rect_for_popup(percent_x: u16, percent_y: u16, r: Rect) -> Rect { .split(popup_layout[1])[1] } -pub fn draw_new_task_popup(f: &mut Frame, state: &mut AppState) { +pub fn draw_task_popup(f: &mut Frame, state: &mut AppState, popup_title: &str) { let area = centered_rect_for_popup(45, 60, f.size()); + let block = Block::default() + .title(popup_title) + .title_alignment(Alignment::Center) + .borders(Borders::ALL); f.render_widget(Clear, area); - match &mut state.new_task_state { - None => {} - Some(task) => { - let block = Block::default() - .title("Add Task") - .title_alignment(Alignment::Center) - .borders(Borders::ALL); - let block_inner = block.inner(area); - // let main = Paragraph::new(task.description.clone()).block(block); - let layout = Layout::default() - .direction(Direction::Vertical) - .constraints( - [ - Constraint::Length(3), - Constraint::Max(100), - Constraint::Length(3), - Constraint::Length(2), - ] - .as_ref(), - ) - .split(block_inner); + f.render_widget(Paragraph::new("").block(block.clone()), area); + if let Some(task) = &mut state.task_edit_state { + let block_inner = block.inner(area); + let layout = Layout::default() + .direction(Direction::Vertical) + .constraints( + [ + Constraint::Length(3), + Constraint::Max(100), + Constraint::Length(1), + Constraint::Length(2), + ] + .as_ref(), + ) + .split(block_inner); - let buttons = Layout::default() - .direction(Direction::Horizontal) - .constraints( - [ - Constraint::Percentage(80), - Constraint::Min(10), - Constraint::Min(10) - ] - .as_ref(), - ) - .split(layout[2]); + let buttons = Layout::default() + .direction(Direction::Horizontal) + .constraints( + [ + Constraint::Percentage(80), + Constraint::Min(10), + Constraint::Min(10) + ] + .as_ref(), + ) + .split(layout[2]); - let create_style; - let create_txt; - let cancel_style; - let cancel_txt; - match task.focus { - NewTaskFocus::CreateBtn => { - create_style = Style::default().fg(Color::Yellow); - cancel_style = Style::default(); - create_txt = "[Create]"; - cancel_txt = " Cancel "; - } - NewTaskFocus::CancelBtn => { - create_style = Style::default(); - cancel_style = Style::default().fg(Color::Yellow); - create_txt = " Create "; - cancel_txt = "[Cancel]"; - } - _ => { - create_style = Style::default(); - cancel_style = Style::default(); - create_txt = " Create "; - cancel_txt = " Cancel "; - } + let create_style; + let create_txt; + let cancel_style; + let cancel_txt; + match task.focus { + TaskEditFocus::CreateBtn => { + create_style = Style::default().fg(Color::Yellow); + cancel_style = Style::default(); + create_txt = "[Confirm]"; + cancel_txt = " Cancel "; } - let create_btn = Paragraph::new(create_txt).style(create_style); - let cancel_btn = Paragraph::new(cancel_txt).style(cancel_style); - f.render_widget(create_btn, buttons[1]); - f.render_widget(cancel_btn, buttons[2]); - - let b1 = Block::default().title("Title").borders(Borders::ALL); - let b2 = Block::default().title("Description").borders(Borders::ALL); - let b3 = Block::default().title("Keys").borders(Borders::TOP); - task.title.set_cursor_line_style(Style::default()); - task.description.set_cursor_line_style(Style::default()); - - task.title.set_block(b1); - if let NewTaskFocus::Title = task.focus { - task.title.set_style(Style::default().fg(Color::Yellow)); - task.title.set_cursor_style(Style::default().add_modifier(Modifier::REVERSED)); - } else { - task.title.set_style(Style::default()); - task.title.set_cursor_style(Style::default()); + TaskEditFocus::CancelBtn => { + create_style = Style::default(); + cancel_style = Style::default().fg(Color::Yellow); + create_txt = " Confirm "; + cancel_txt = "[Cancel]"; } - f.render_widget(task.title.widget(), layout[0]); - - task.description.set_block(b2); - if let NewTaskFocus::Description = task.focus { - task.description.set_style(Style::default().fg(Color::Yellow)); - task.description.set_cursor_style(Style::default().add_modifier(Modifier::REVERSED)); - } else { - task.description.set_style(Style::default()); - task.description.set_cursor_style(Style::default()); + _ => { + create_style = Style::default(); + cancel_style = Style::default(); + create_txt = " Confirm "; + cancel_txt = " Cancel "; } - f.render_widget(task.description.widget(), layout[1]); - - let footer = Paragraph::new("Tab/Backtab : Cycle").block(b3); - f.render_widget(footer, layout[3]); } + let create_btn = Paragraph::new(create_txt).style(create_style); + let cancel_btn = Paragraph::new(cancel_txt).style(cancel_style); + f.render_widget(create_btn, buttons[1]); + f.render_widget(cancel_btn, buttons[2]); + + let b1 = Block::default().title("Title").borders(Borders::ALL); + let b2 = Block::default().title("Description").borders(Borders::ALL); + let b3 = Block::default().title("Keys").borders(Borders::TOP); + task.title.set_cursor_line_style(Style::default()); + task.description.set_cursor_line_style(Style::default()); + + task.title.set_block(b1); + if let TaskEditFocus::Title = task.focus { + task.title.set_style(Style::default().fg(Color::Yellow)); + task.title.set_cursor_style(Style::default().add_modifier(Modifier::REVERSED)); + } else { + task.title.set_style(Style::default()); + task.title.set_cursor_style(Style::default()); + } + f.render_widget(task.title.widget(), layout[0]); + + task.description.set_block(b2); + if let TaskEditFocus::Description = task.focus { + task.description.set_style(Style::default().fg(Color::Yellow)); + task.description.set_cursor_style(Style::default().add_modifier(Modifier::REVERSED)); + } else { + task.description.set_style(Style::default()); + task.description.set_cursor_style(Style::default()); + } + f.render_widget(task.description.widget(), layout[1]); + + let footer = Paragraph::new("Tab/Backtab : Cycle").block(b3); + f.render_widget(footer, layout[3]); } } @@ -214,7 +211,7 @@ pub fn draw(f: &mut Frame, state: &mut AppState) { let footer = Paragraph::new(foot_txt).block(block); f.render_widget(footer, main_layout[3]); - if state.new_task_state.is_some() { - draw_new_task_popup(f, state); + if state.task_edit_state.is_some() { + draw_task_popup(f, state, "Create Task"); } }