Fix task edit border and rename some symbols
This commit is contained in:
		
							parent
							
								
									fc237b9f29
								
							
						
					
					
						commit
						da10719250
					
				
							
								
								
									
										16
									
								
								src/app.rs
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/app.rs
									
									
									
									
									
								
							@ -57,25 +57,25 @@ impl Default for Project {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
pub enum NewTaskFocus {
 | 
					pub enum TaskEditFocus {
 | 
				
			||||||
    Title,
 | 
					    Title,
 | 
				
			||||||
    Description,
 | 
					    Description,
 | 
				
			||||||
    CreateBtn,
 | 
					    CreateBtn,
 | 
				
			||||||
    CancelBtn
 | 
					    CancelBtn
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct NewTask<'a> {
 | 
					pub struct TaskState<'a> {
 | 
				
			||||||
    pub title: TextArea<'a>,
 | 
					    pub title: TextArea<'a>,
 | 
				
			||||||
    pub description: TextArea<'a>,
 | 
					    pub description: TextArea<'a>,
 | 
				
			||||||
    pub focus: NewTaskFocus
 | 
					    pub focus: TaskEditFocus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Default for NewTask<'_> {
 | 
					impl Default for TaskState<'_> {
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        NewTask {
 | 
					        TaskState {
 | 
				
			||||||
            title: TextArea::default(),
 | 
					            title: TextArea::default(),
 | 
				
			||||||
            description: TextArea::default(),
 | 
					            description: TextArea::default(),
 | 
				
			||||||
            focus: NewTaskFocus::Title
 | 
					            focus: TaskEditFocus::Title
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -84,14 +84,14 @@ pub struct AppState<'a> {
 | 
				
			|||||||
    pub project: Project,
 | 
					    pub project: Project,
 | 
				
			||||||
    pub quit: bool,
 | 
					    pub quit: bool,
 | 
				
			||||||
    pub columns: Vec<Column>,
 | 
					    pub columns: Vec<Column>,
 | 
				
			||||||
    pub new_task_state: Option<NewTask<'a>>,
 | 
					    pub task_edit_state: Option<TaskState<'a>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl AppState<'_> {
 | 
					impl AppState<'_> {
 | 
				
			||||||
    pub fn new(project: Project) -> Self {
 | 
					    pub fn new(project: Project) -> Self {
 | 
				
			||||||
        AppState {
 | 
					        AppState {
 | 
				
			||||||
            quit: false,
 | 
					            quit: false,
 | 
				
			||||||
            new_task_state: None,
 | 
					            task_edit_state: None,
 | 
				
			||||||
            project,
 | 
					            project,
 | 
				
			||||||
            columns: vec![],
 | 
					            columns: vec![],
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										41
									
								
								src/input.rs
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								src/input.rs
									
									
									
									
									
								
							@ -1,7 +1,7 @@
 | 
				
			|||||||
#![allow(unused_imports)]
 | 
					#![allow(unused_imports)]
 | 
				
			||||||
use crossterm::event;
 | 
					use crossterm::event;
 | 
				
			||||||
use crossterm::event::{Event, KeyCode};
 | 
					use crossterm::event::{Event, KeyCode};
 | 
				
			||||||
use crate::app::{NewTask, AppState, NewTaskFocus};
 | 
					use crate::app::{TaskState, AppState, TaskEditFocus};
 | 
				
			||||||
use std::io::{stdout, Write};
 | 
					use std::io::{stdout, Write};
 | 
				
			||||||
use tui_textarea::TextArea;
 | 
					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 project = &mut state.project;
 | 
				
			||||||
    let column = project.get_selected_column_mut();
 | 
					    let column = project.get_selected_column_mut();
 | 
				
			||||||
    if let Event::Key(key) = event::read()? {
 | 
					    if let Event::Key(key) = event::read()? {
 | 
				
			||||||
        match &mut state.new_task_state {
 | 
					        match &mut state.task_edit_state {
 | 
				
			||||||
            Some(task) => {
 | 
					            Some(task) => {
 | 
				
			||||||
                // TODO: Extract this code to a separate function to avoid nesting
 | 
					                // TODO: Extract this code to a separate function to avoid nesting
 | 
				
			||||||
                match task.focus {
 | 
					                match task.focus {
 | 
				
			||||||
                    // TODO: Handle wrapping around the enum rather than doing it manually
 | 
					                    // TODO: Handle wrapping around the enum rather than doing it manually
 | 
				
			||||||
                    NewTaskFocus::Title => {
 | 
					                    TaskEditFocus::Title => {
 | 
				
			||||||
                        match key.code {
 | 
					                        match key.code {
 | 
				
			||||||
                            KeyCode::Tab => task.focus = NewTaskFocus::Description,
 | 
					                            KeyCode::Tab => task.focus = TaskEditFocus::Description,
 | 
				
			||||||
                            KeyCode::BackTab => task.focus = NewTaskFocus::CancelBtn,
 | 
					                            KeyCode::BackTab => task.focus = TaskEditFocus::CancelBtn,
 | 
				
			||||||
                            KeyCode::Enter => (),
 | 
					                            KeyCode::Enter => (),
 | 
				
			||||||
                            _ => { task.title.input(key); }
 | 
					                            _ => { task.title.input(key); }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    NewTaskFocus::Description => {
 | 
					                    TaskEditFocus::Description => {
 | 
				
			||||||
                        match key.code {
 | 
					                        match key.code {
 | 
				
			||||||
                            KeyCode::Tab => task.focus = NewTaskFocus::CreateBtn,
 | 
					                            KeyCode::Tab => task.focus = TaskEditFocus::CreateBtn,
 | 
				
			||||||
                            KeyCode::BackTab => task.focus = NewTaskFocus::Title,
 | 
					                            KeyCode::BackTab => task.focus = TaskEditFocus::Title,
 | 
				
			||||||
                            _ => { task.description.input(key); }
 | 
					                            _ => { task.description.input(key); }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    NewTaskFocus::CreateBtn => {
 | 
					                    TaskEditFocus::CreateBtn => {
 | 
				
			||||||
                        match key.code {
 | 
					                        match key.code {
 | 
				
			||||||
                            KeyCode::Tab => task.focus = NewTaskFocus::CancelBtn,
 | 
					                            KeyCode::Tab => task.focus = TaskEditFocus::CancelBtn,
 | 
				
			||||||
                            KeyCode::BackTab => task.focus = NewTaskFocus::Description,
 | 
					                            KeyCode::BackTab => task.focus = TaskEditFocus::Description,
 | 
				
			||||||
                            KeyCode::Enter => {
 | 
					                            KeyCode::Enter => {
 | 
				
			||||||
                                let title = task.title.clone().into_lines().join("\n");
 | 
					                                let title = task.title.clone().into_lines().join("\n");
 | 
				
			||||||
                                let description = task.description.clone().into_lines().clone().join("\n");
 | 
					                                let description = task.description.clone().into_lines().clone().join("\n");
 | 
				
			||||||
                                column.add_task(title, description);
 | 
					                                column.add_task(title, description);
 | 
				
			||||||
                                state.new_task_state = None
 | 
					                                state.task_edit_state = None
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            _ => (),
 | 
					                            _ => (),
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    NewTaskFocus::CancelBtn => {
 | 
					                    TaskEditFocus::CancelBtn => {
 | 
				
			||||||
                        match key.code {
 | 
					                        match key.code {
 | 
				
			||||||
                            KeyCode::Tab => task.focus = NewTaskFocus::Title,
 | 
					                            KeyCode::Tab => task.focus = TaskEditFocus::Title,
 | 
				
			||||||
                            KeyCode::BackTab => task.focus = NewTaskFocus::CreateBtn,
 | 
					                            KeyCode::BackTab => task.focus = TaskEditFocus::CreateBtn,
 | 
				
			||||||
                            KeyCode::Enter => {
 | 
					                            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('J') => project.move_task_down(),
 | 
				
			||||||
                    KeyCode::Char('-') |
 | 
					                    KeyCode::Char('-') |
 | 
				
			||||||
                    KeyCode::Char('K') => project.move_task_up(),
 | 
					                    KeyCode::Char('K') => project.move_task_up(),
 | 
				
			||||||
                    KeyCode::Char('p') => {
 | 
					                    KeyCode::Char('n') => state.task_edit_state = Some(TaskState::default()),
 | 
				
			||||||
                        match state.new_task_state {
 | 
					                    KeyCode::Char('e') => {
 | 
				
			||||||
                            None => state.new_task_state = Some(NewTask::default()),
 | 
					                        match state.task_edit_state {
 | 
				
			||||||
                            Some(_) => state.new_task_state = None,
 | 
					                            None => state.task_edit_state = Some(TaskState::default()),
 | 
				
			||||||
 | 
					                            Some(_) => state.task_edit_state = None,
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    KeyCode::Char('D') => column.remove_task(),
 | 
					                    KeyCode::Char('D') => column.remove_task(),
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										175
									
								
								src/ui.rs
									
									
									
									
									
								
							
							
						
						
									
										175
									
								
								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]
 | 
					        .split(popup_layout[1])[1]
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn draw_new_task_popup<B: Backend>(f: &mut Frame<B>, state: &mut AppState) {
 | 
					pub fn draw_task_popup<B: Backend>(f: &mut Frame<B>, state: &mut AppState, popup_title: &str) {
 | 
				
			||||||
    let area = centered_rect_for_popup(45, 60, f.size());
 | 
					    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);
 | 
					    f.render_widget(Clear, area);
 | 
				
			||||||
    match &mut state.new_task_state {
 | 
					    f.render_widget(Paragraph::new("").block(block.clone()), area);
 | 
				
			||||||
        None => {}
 | 
					    if let Some(task) = &mut state.task_edit_state {
 | 
				
			||||||
        Some(task) => {
 | 
					        let block_inner = block.inner(area);
 | 
				
			||||||
            let block = Block::default()
 | 
					        let layout = Layout::default()
 | 
				
			||||||
                .title("Add Task")
 | 
					            .direction(Direction::Vertical)
 | 
				
			||||||
                .title_alignment(Alignment::Center)
 | 
					            .constraints(
 | 
				
			||||||
                .borders(Borders::ALL);
 | 
					                [
 | 
				
			||||||
            let block_inner = block.inner(area);
 | 
					                    Constraint::Length(3),
 | 
				
			||||||
            // let main = Paragraph::new(task.description.clone()).block(block);
 | 
					                    Constraint::Max(100),
 | 
				
			||||||
            let layout = Layout::default()
 | 
					                    Constraint::Length(1),
 | 
				
			||||||
                .direction(Direction::Vertical)
 | 
					                    Constraint::Length(2),
 | 
				
			||||||
                .constraints(
 | 
					                ]
 | 
				
			||||||
                    [
 | 
					                .as_ref(),
 | 
				
			||||||
                        Constraint::Length(3),
 | 
					            )
 | 
				
			||||||
                        Constraint::Max(100),
 | 
					            .split(block_inner);
 | 
				
			||||||
                        Constraint::Length(3),
 | 
					 | 
				
			||||||
                        Constraint::Length(2),
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                    .as_ref(),
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                .split(block_inner);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let buttons = Layout::default()
 | 
					        let buttons = Layout::default()
 | 
				
			||||||
                .direction(Direction::Horizontal)
 | 
					            .direction(Direction::Horizontal)
 | 
				
			||||||
                .constraints(
 | 
					            .constraints(
 | 
				
			||||||
                    [
 | 
					                [
 | 
				
			||||||
                        Constraint::Percentage(80),
 | 
					                    Constraint::Percentage(80),
 | 
				
			||||||
                        Constraint::Min(10),
 | 
					                    Constraint::Min(10),
 | 
				
			||||||
                        Constraint::Min(10)
 | 
					                    Constraint::Min(10)
 | 
				
			||||||
                    ]
 | 
					                ]
 | 
				
			||||||
                    .as_ref(),
 | 
					                .as_ref(),
 | 
				
			||||||
                )
 | 
					            )
 | 
				
			||||||
                .split(layout[2]);
 | 
					            .split(layout[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let create_style;
 | 
					        let create_style;
 | 
				
			||||||
            let create_txt;
 | 
					        let create_txt;
 | 
				
			||||||
            let cancel_style;
 | 
					        let cancel_style;
 | 
				
			||||||
            let cancel_txt;
 | 
					        let cancel_txt;
 | 
				
			||||||
            match task.focus {
 | 
					        match task.focus {
 | 
				
			||||||
                NewTaskFocus::CreateBtn => {
 | 
					            TaskEditFocus::CreateBtn => {
 | 
				
			||||||
                    create_style = Style::default().fg(Color::Yellow);
 | 
					                create_style = Style::default().fg(Color::Yellow);
 | 
				
			||||||
                    cancel_style = Style::default();
 | 
					                cancel_style = Style::default();
 | 
				
			||||||
                    create_txt = "[Create]";
 | 
					                create_txt = "[Confirm]";
 | 
				
			||||||
                    cancel_txt = " Cancel ";
 | 
					                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_btn = Paragraph::new(create_txt).style(create_style);
 | 
					            TaskEditFocus::CancelBtn => {
 | 
				
			||||||
            let cancel_btn = Paragraph::new(cancel_txt).style(cancel_style);
 | 
					                create_style = Style::default();
 | 
				
			||||||
            f.render_widget(create_btn, buttons[1]);
 | 
					                cancel_style = Style::default().fg(Color::Yellow);
 | 
				
			||||||
            f.render_widget(cancel_btn, buttons[2]);
 | 
					                create_txt = " Confirm ";
 | 
				
			||||||
 | 
					                cancel_txt = "[Cancel]";
 | 
				
			||||||
            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());
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            f.render_widget(task.title.widget(), layout[0]);
 | 
					            _ => {
 | 
				
			||||||
 | 
					                create_style = Style::default();
 | 
				
			||||||
            task.description.set_block(b2);
 | 
					                cancel_style = Style::default();
 | 
				
			||||||
            if let NewTaskFocus::Description = task.focus {
 | 
					                create_txt = " Confirm ";
 | 
				
			||||||
                task.description.set_style(Style::default().fg(Color::Yellow));
 | 
					                cancel_txt = " Cancel ";
 | 
				
			||||||
                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]);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        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<B: Backend>(f: &mut Frame<B>, state: &mut AppState) {
 | 
				
			|||||||
    let footer = Paragraph::new(foot_txt).block(block);
 | 
					    let footer = Paragraph::new(foot_txt).block(block);
 | 
				
			||||||
    f.render_widget(footer, main_layout[3]);
 | 
					    f.render_widget(footer, main_layout[3]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if state.new_task_state.is_some() {
 | 
					    if state.task_edit_state.is_some() {
 | 
				
			||||||
        draw_new_task_popup(f, state);
 | 
					        draw_task_popup(f, state, "Create Task");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user