Add cursor to textarea
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
use std::any::Any;
|
||||
use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind};
|
||||
use crossterm::event::KeyCode::Char;
|
||||
use rat_cursor::HasScreenCursor;
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::Frame;
|
||||
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
||||
use ratatui::prelude::{Color, Line, Span, Style, Text, Widget};
|
||||
use ratatui::widgets::{Block, Borders, Paragraph, StatefulWidget};
|
||||
use crate::config::types::ApplicationConfig;
|
||||
use crate::constants::APP_CONIFG_FILE_PATH;
|
||||
use crate::widgets::popups::folder::AddFolderPopup;
|
||||
use crate::widgets::views::{AppStatus, View};
|
||||
use crate::widgets::views::{View};
|
||||
|
||||
pub struct MainView {
|
||||
app_config: ApplicationConfig,
|
||||
@@ -18,7 +20,14 @@ pub struct MainView {
|
||||
#[derive(Debug)]
|
||||
pub struct MainViewState {
|
||||
popup: Option<Box<dyn Any>>,
|
||||
status: AppStatus,
|
||||
status: Status,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Status {
|
||||
Running,
|
||||
Exiting,
|
||||
Popup
|
||||
}
|
||||
|
||||
impl MainView {
|
||||
@@ -26,28 +35,25 @@ impl MainView {
|
||||
Self {
|
||||
state: MainViewState {
|
||||
popup: None,
|
||||
status: AppStatus::Running
|
||||
status: Status::Running
|
||||
},
|
||||
app_config: app_conf.clone(),
|
||||
app_config: app_conf.clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn quit(&mut self) -> color_eyre::Result<()> {
|
||||
if self.state.popup.is_none() {
|
||||
self.state.status = AppStatus::Exiting;
|
||||
self.state.status = Status::Exiting;
|
||||
self.app_config
|
||||
.clone()
|
||||
.write_to_file(&APP_CONIFG_FILE_PATH.to_path_buf())?;
|
||||
}
|
||||
else {
|
||||
self.state.popup = None;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn folder_popup(&mut self) {
|
||||
self.state.popup = Some(Box::new(AddFolderPopup::new()));
|
||||
self.state.status = AppStatus::Input;
|
||||
self.state.status = Status::Popup;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,10 +67,11 @@ impl View for MainView {
|
||||
}
|
||||
|
||||
fn handle_key_input(&mut self, key: &KeyEvent) -> color_eyre::Result<()> {
|
||||
if matches!(self.state.status, AppStatus::Input) && matches!(key.code, KeyCode::Esc) {
|
||||
self.state.status = AppStatus::Running;
|
||||
if matches!(self.state.status, Status::Popup) && matches!(key.code, KeyCode::Esc) {
|
||||
self.state.status = Status::Running;
|
||||
self.state.popup = None;
|
||||
}
|
||||
if matches!(key.kind, KeyEventKind::Press) && !matches!(self.state.status, AppStatus::Input) {
|
||||
if !matches!(self.state.status, Status::Popup) && matches!(key.kind, KeyEventKind::Press) {
|
||||
match key.code {
|
||||
Char('q') => self.quit()?,
|
||||
Char('a') => self.folder_popup(),
|
||||
@@ -75,7 +82,7 @@ impl View for MainView {
|
||||
}
|
||||
|
||||
fn is_running(&self) -> bool {
|
||||
!matches!(self.state.status, AppStatus::Exiting)
|
||||
!matches!(self.state.status, Status::Exiting)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +112,16 @@ impl StatefulWidget for MainView {
|
||||
}
|
||||
}
|
||||
|
||||
impl HasScreenCursor for MainView {
|
||||
fn screen_cursor(&self) -> Option<(u16, u16)> {
|
||||
if let Some(popup) = &self.state.popup &&
|
||||
let Some(add_folder) = popup.downcast_ref::<AddFolderPopup>() {
|
||||
return add_folder.textarea.screen_cursor()
|
||||
}
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl MainView {
|
||||
fn render_game_list(state: &mut MainViewState, area: Rect, buf: &mut Buffer) {
|
||||
let game_list = Block::new()
|
||||
@@ -128,8 +145,8 @@ impl MainView {
|
||||
let mut navigation_text = vec![
|
||||
Span::styled("(q) quit / (a) add folders", Style::default().fg(Color::Green)),
|
||||
];
|
||||
if matches!(state.status, AppStatus::Input) {
|
||||
navigation_text[0] = Span::styled("Input Mode", Style::default().fg(Color::Green));
|
||||
if matches!(state.status, Status::Popup) {
|
||||
navigation_text[0] = Span::styled("(Esc) close", Style::default().fg(Color::Green));
|
||||
}
|
||||
let line = Line::from(navigation_text);
|
||||
let footer = Paragraph::new(line);
|
||||
|
||||
Reference in New Issue
Block a user