pass config

pull/88/head
Takayuki Maeda 3 years ago
parent 360cc31c8c
commit c39953ea6d

@ -26,7 +26,7 @@ pub struct RecordTableComponent {
impl RecordTableComponent { impl RecordTableComponent {
pub fn new(key_config: KeyConfig) -> Self { pub fn new(key_config: KeyConfig) -> Self {
Self { Self {
filter: TableFilterComponent::default(), filter: TableFilterComponent::new(key_config.clone()),
table: TableComponent::new(key_config.clone()), table: TableComponent::new(key_config.clone()),
focus: Focus::Table, focus: Focus::Table,
key_config, key_config,
@ -61,11 +61,11 @@ impl DrawableComponent for RecordTableComponent {
.constraints(vec![Constraint::Length(3), Constraint::Length(5)]) .constraints(vec![Constraint::Length(3), Constraint::Length(5)])
.split(area); .split(area);
self.filter
.draw(f, layout[0], focused && matches!(self.focus, Focus::Filter))?;
self.table self.table
.draw(f, layout[1], focused && matches!(self.focus, Focus::Table))?; .draw(f, layout[1], focused && matches!(self.focus, Focus::Table))?;
self.filter
.draw(f, layout[0], focused && matches!(self.focus, Focus::Filter))?;
Ok(()) Ok(())
} }
} }

@ -1,5 +1,9 @@
use super::{compute_character_width, Component, DrawableComponent, EventState}; use super::{
compute_character_width, CompletionComponent, Component, DrawableComponent, EventState,
MovableComponent,
};
use crate::components::command::CommandInfo; use crate::components::command::CommandInfo;
use crate::config::KeyConfig;
use crate::event::Key; use crate::event::Key;
use anyhow::Result; use anyhow::Result;
use database_tree::Table; use database_tree::Table;
@ -14,24 +18,26 @@ use tui::{
use unicode_width::UnicodeWidthStr; use unicode_width::UnicodeWidthStr;
pub struct TableFilterComponent { pub struct TableFilterComponent {
key_config: KeyConfig,
pub table: Option<Table>, pub table: Option<Table>,
pub input: Vec<char>, pub input: Vec<char>,
input_idx: usize, input_idx: usize,
input_cursor_position: u16, input_cursor_position: u16,
completion: CompletionComponent,
} }
impl Default for TableFilterComponent { impl TableFilterComponent {
fn default() -> Self { pub fn new(key_config: KeyConfig) -> Self {
Self { Self {
key_config: key_config.clone(),
table: None, table: None,
input: Vec::new(), input: Vec::new(),
input_idx: 0, input_idx: 0,
input_cursor_position: 0, input_cursor_position: 0,
completion: CompletionComponent::new(key_config, ""),
} }
} }
}
impl TableFilterComponent {
pub fn input_str(&self) -> String { pub fn input_str(&self) -> String {
self.input.iter().collect() self.input.iter().collect()
} }
@ -42,6 +48,21 @@ impl TableFilterComponent {
self.input_idx = 0; self.input_idx = 0;
self.input_cursor_position = 0; self.input_cursor_position = 0;
} }
fn update_completion(&mut self) {
let input = &self
.input
.iter()
.enumerate()
.filter(|(i, _)| i <= &self.input_idx)
.map(|(_, i)| i)
.collect::<String>()
.split(" ")
.map(|i| i.to_string())
.collect::<Vec<String>>();
self.completion
.update(input.last().unwrap_or(&String::new()));
}
} }
impl DrawableComponent for TableFilterComponent { impl DrawableComponent for TableFilterComponent {
@ -69,6 +90,23 @@ impl DrawableComponent for TableFilterComponent {
}) })
.block(Block::default().borders(Borders::ALL)); .block(Block::default().borders(Borders::ALL));
f.render_widget(query, area); f.render_widget(query, area);
if focused {
self.completion.draw(
f,
area,
false,
(self
.table
.as_ref()
.map_or(String::new(), |table| table.name.to_string())
.width() as u16
+ 2)
.saturating_add(self.input_cursor_position),
0,
)?;
};
if focused { if focused {
f.set_cursor( f.set_cursor(
(area.x (area.x
@ -91,21 +129,40 @@ impl Component for TableFilterComponent {
fn event(&mut self, key: Key) -> Result<EventState> { fn event(&mut self, key: Key) -> Result<EventState> {
let input_str: String = self.input.iter().collect(); let input_str: String = self.input.iter().collect();
// apply comletion candidates
if key == self.key_config.enter {
if let Some(candidate) = self.completion.string_to_be_completed() {
let mut input = self.input.iter().collect::<String>();
input.insert_str(self.input_idx, candidate.as_str());
self.input = input.chars().collect();
self.input_idx += candidate.len();
self.input_cursor_position += candidate
.chars()
.map(|c| compute_character_width(c))
.sum::<u16>();
self.update_completion();
return Ok(EventState::Consumed);
}
}
match key { match key {
Key::Char(c) => { Key::Char(c) => {
self.input.insert(self.input_idx, c); self.input.insert(self.input_idx, c);
self.input_idx += 1; self.input_idx += 1;
self.input_cursor_position += compute_character_width(c); self.input_cursor_position += compute_character_width(c);
self.update_completion();
return Ok(EventState::Consumed); Ok(EventState::Consumed)
} }
Key::Delete | Key::Backspace => { Key::Delete | Key::Backspace => {
if input_str.width() > 0 && !self.input.is_empty() && self.input_idx > 0 { if input_str.width() > 0 && !self.input.is_empty() && self.input_idx > 0 {
let last_c = self.input.remove(self.input_idx - 1); let last_c = self.input.remove(self.input_idx - 1);
self.input_idx -= 1; self.input_idx -= 1;
self.input_cursor_position -= compute_character_width(last_c); self.input_cursor_position -= compute_character_width(last_c);
self.update_completion();
} }
return Ok(EventState::Consumed); Ok(EventState::Consumed)
} }
Key::Left => { Key::Left => {
if !self.input.is_empty() && self.input_idx > 0 { if !self.input.is_empty() && self.input_idx > 0 {
@ -114,14 +171,14 @@ impl Component for TableFilterComponent {
.input_cursor_position .input_cursor_position
.saturating_sub(compute_character_width(self.input[self.input_idx])); .saturating_sub(compute_character_width(self.input[self.input_idx]));
} }
return Ok(EventState::Consumed); Ok(EventState::Consumed)
} }
Key::Ctrl('a') => { Key::Ctrl('a') => {
if !self.input.is_empty() && self.input_idx > 0 { if !self.input.is_empty() && self.input_idx > 0 {
self.input_idx = 0; self.input_idx = 0;
self.input_cursor_position = 0 self.input_cursor_position = 0
} }
return Ok(EventState::Consumed); Ok(EventState::Consumed)
} }
Key::Right => { Key::Right => {
if self.input_idx < self.input.len() { if self.input_idx < self.input.len() {
@ -129,17 +186,16 @@ impl Component for TableFilterComponent {
self.input_idx += 1; self.input_idx += 1;
self.input_cursor_position += compute_character_width(next_c); self.input_cursor_position += compute_character_width(next_c);
} }
return Ok(EventState::Consumed); Ok(EventState::Consumed)
} }
Key::Ctrl('e') => { Key::Ctrl('e') => {
if self.input_idx < self.input.len() { if self.input_idx < self.input.len() {
self.input_idx = self.input.len(); self.input_idx = self.input.len();
self.input_cursor_position = self.input_str().width() as u16; self.input_cursor_position = self.input_str().width() as u16;
} }
return Ok(EventState::Consumed); Ok(EventState::Consumed)
} }
_ => (), key => self.completion.event(key),
} }
Ok(EventState::NotConsumed)
} }
} }

Loading…
Cancel
Save