Skip to content

Commit

Permalink
refactor(tui): extract CmdLine widget
Browse files Browse the repository at this point in the history
  • Loading branch information
Eliot00 committed Dec 14, 2021
1 parent 3ae961d commit 849b508
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 18 deletions.
41 changes: 36 additions & 5 deletions quake_tui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ use std::path::PathBuf;
use quake_core::usecases::entry_usecases;
use quake_core::QuakeConfig;

use crate::widgets::MainWidget;
use crate::widgets::{CmdLine, MainWidget};

pub struct App {
pub mode: Mode,
pub command: String,
pub main_widget: MainWidget,
pub state: AppState,
pub config: QuakeConfig,
pub main_widget: MainWidget,
pub cmd_line: CmdLine,
}

impl App {
pub fn new(config: QuakeConfig) -> App {
App {
mode: Mode::Command,
command: "".to_string(),
mode: Mode::Normal,
main_widget: MainWidget::Home,
cmd_line: CmdLine::default(),
state: Default::default(),
config,
}
Expand All @@ -45,6 +45,18 @@ impl App {
.unwrap();
}
}

pub fn message_push(&mut self, c: char) {
self.cmd_line.message.push(c);
}

pub fn message_pop(&mut self) {
self.cmd_line.message.pop();
}

pub fn message_clear(&mut self) {
self.cmd_line.message.clear();
}
}

pub enum Mode {
Expand All @@ -62,3 +74,22 @@ impl Default for AppState {
AppState { running: true }
}
}

#[cfg(test)]
mod tests {
use quake_core::QuakeConfig;

use super::App;

#[test]
fn test_message_collect() {
let mut app = App::new(QuakeConfig::default());
app.message_push('g');
app.message_push('t');
assert_eq!(app.cmd_line.message, "gt".to_string());

app.message_pop();
app.message_pop();
assert_eq!(app.cmd_line.message, "".to_string());
}
}
7 changes: 4 additions & 3 deletions quake_tui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,18 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> Result<(), B
}
Mode::Command => match key.code {
KeyCode::Enter => {
let command: String = app.command.drain(..).collect();
let command: String = app.cmd_line.message.drain(..).collect();
execute_command(&command, &mut app)?;
}
KeyCode::Char(c) => {
app.command.push(c);
app.message_push(c);
}
KeyCode::Backspace => {
app.command.pop();
app.message_pop();
}
KeyCode::Esc => {
app.mode = Mode::Normal;
app.message_clear();
}
_ => {}
},
Expand Down
12 changes: 2 additions & 10 deletions quake_tui/src/ui.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use crate::app::{App, Mode};
use tui::backend::Backend;
use tui::layout::{Constraint, Direction, Layout};
use tui::style::{Color, Style};
use tui::widgets::{Block, Borders, Paragraph};
use tui::Frame;
use unicode_width::UnicodeWidthStr;

Expand All @@ -12,19 +10,13 @@ pub fn draw<B: Backend>(f: &mut Frame<B>, app: &mut App) {
.margin(2)
.constraints([Constraint::Length(3), Constraint::Min(1)].as_ref())
.split(f.size());
let command_bar = Paragraph::new(app.command.as_ref())
.style(match app.mode {
Mode::Command => Style::default().fg(Color::Yellow),
_ => Style::default(),
})
.block(Block::default().borders(Borders::ALL).title("Action"));
f.render_widget(command_bar, chunks[0]);
f.render_widget(app.cmd_line.clone(), chunks[0]);
f.render_widget(app.main_widget.clone(), chunks[1]);

match app.mode {
Mode::Normal => {}
Mode::Command => f.set_cursor(
chunks[0].x + app.command.width() as u16 + 1,
chunks[0].x + app.cmd_line.message.width() as u16 + 1,
chunks[0].y + 1,
),
Mode::Insert => {
Expand Down
13 changes: 13 additions & 0 deletions quake_tui/src/widgets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,19 @@ impl MainWidget {
}
}

#[derive(Default, Clone)]
pub struct CmdLine {
pub(crate) message: String,
}

impl Widget for CmdLine {
fn render(self, area: Rect, buf: &mut Buffer) {
let message = Paragraph::new(self.message.as_ref())
.block(Block::default().borders(Borders::ALL).title("Command"));
message.render(area, buf);
}
}

fn list_entry_types() -> Result<Vec<ListItem<'static>>, Box<dyn Error>> {
let config: QuakeConfig = serde_yaml::from_str(fs::read_to_string(".quake.yaml")?.as_str())?;
let entry_defines_path = Path::new(&config.workspace).join(EntryPaths::entries_define());
Expand Down

0 comments on commit 849b508

Please sign in to comment.