Skip to content

Commit

Permalink
Merge pull request #386 from sarub0b0/feature-keep-the-filter-input-f…
Browse files Browse the repository at this point in the history
…ield-visible

feat(ui): Keep the filter input field visible.
  • Loading branch information
sarub0b0 authored Aug 22, 2023
2 parents 8d80084 + d1bb07c commit 5231e5d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 23 deletions.
60 changes: 39 additions & 21 deletions src/ui/widget/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use ratatui::{
backend::Backend,
layout::{Constraint, Rect},
style::{Modifier, Style},
text::{Line, Span},
widgets::{Table as TuiTable, TableState},
Frame,
};
Expand All @@ -27,8 +26,7 @@ use crate::{
};

use super::{
config::{Title, WidgetConfig},
styled_graphemes, Item, RenderTrait, SelectedItem, TableItem, WidgetTrait,
config::WidgetConfig, styled_graphemes, Item, RenderTrait, SelectedItem, TableItem, WidgetTrait,
};

const COLUMN_SPACING: u16 = 3;
Expand Down Expand Up @@ -142,8 +140,12 @@ impl TableBuilder {

#[derive(Debug)]
enum Mode {
/// 通常(検索フォーム非表示)
Normal,
/// フィルターワード入力中(検索フォーム表示)
FilterInput,
/// フィルターワード確定後(検索フォーム表示)
FilterConfirm,
}

impl Default for Mode {
Expand All @@ -161,6 +163,10 @@ impl Mode {
*self = Self::FilterInput;
}

fn filter_confirm(&mut self) {
*self = Self::FilterConfirm;
}

#[allow(dead_code)]
fn is_normal(&self) -> bool {
matches!(self, Self::Normal)
Expand All @@ -169,6 +175,10 @@ impl Mode {
fn is_filter_input(&self) -> bool {
matches!(self, Self::FilterInput)
}

fn is_filter_confirm(&self) -> bool {
matches!(self, Self::FilterConfirm)
}
}

#[derive(Derivative)]
Expand Down Expand Up @@ -276,7 +286,7 @@ impl<'a> Table<'a> {

match self.mode {
Mode::Normal => self.chunk,
Mode::FilterInput => {
Mode::FilterInput | Mode::FilterConfirm => {
let filter_hight = 3;
Rect::new(
x,
Expand Down Expand Up @@ -324,6 +334,14 @@ impl<'a> Table<'a> {
}
}
}

fn filter_cancel(&mut self) {
self.mode.normal();

self.filter_widget.clear();

self.filter_items();
}
}

impl WidgetTrait for Table<'_> {
Expand Down Expand Up @@ -470,7 +488,7 @@ impl WidgetTrait for Table<'_> {

fn on_key_event(&mut self, ev: KeyEvent) -> EventResult {
match self.mode {
Mode::Normal => match key_event_to_code(ev) {
Mode::Normal | Mode::FilterConfirm => match key_event_to_code(ev) {
KeyCode::Char('j') | KeyCode::Down | KeyCode::PageDown => {
self.select_next(1);
}
Expand All @@ -491,6 +509,10 @@ impl WidgetTrait for Table<'_> {
self.mode.filter_input();
}

KeyCode::Char('q') | KeyCode::Esc if self.mode.is_filter_confirm() => {
self.filter_cancel();
}

KeyCode::Enter => {
return EventResult::Callback(self.on_select_callback());
}
Expand All @@ -506,11 +528,11 @@ impl WidgetTrait for Table<'_> {

Mode::FilterInput => match key_event_to_code(ev) {
KeyCode::Enter => {
self.mode.normal();
self.mode.filter_confirm();
}

KeyCode::Esc => {
self.mode.normal();
self.filter_cancel();
}

_ => {
Expand Down Expand Up @@ -604,22 +626,12 @@ impl RenderTrait for Table<'_> {
where
B: Backend,
{
let mut widget_config = if let Some(block_injection) = &self.block_injection {
let widget_config = if let Some(block_injection) = &self.block_injection {
(block_injection)(&*self)
} else {
self.widget_config.clone()
};

if let Some(appended_title) = widget_config.append_title_mut().as_mut() {
if !self.filter_widget.word().is_empty() {
let mut spans = appended_title.spans().spans;

spans.push(Span::from(format!(" ({})", self.filter_widget.word())));

*appended_title = Title::from(Line::from(spans));
}
}

let block = widget_config.render_block(self.can_activate() && is_active, is_mouse_over);

let constraints = constraints(self.items.digits());
Expand All @@ -637,10 +649,16 @@ impl RenderTrait for Table<'_> {
widget = widget.header(self.items.header().rendered());
}

f.render_stateful_widget(widget, self.chunk(), &mut self.state);
match self.mode {
Mode::Normal => {
f.render_stateful_widget(widget, self.chunk(), &mut self.state);
}

if self.mode.is_filter_input() {
self.filter_widget.render(f, self.mode.is_filter_input())
Mode::FilterInput | Mode::FilterConfirm => {
self.filter_widget.render(f, self.mode.is_filter_input());

f.render_stateful_widget(widget, self.chunk(), &mut self.state);
}
}

logger!(debug, "{:?}", self.items);
Expand Down
4 changes: 4 additions & 0 deletions src/ui/widget/table/filter_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ impl FilterForm {
self.input_widget.on_key_event(ev)
}

pub fn clear(&mut self) {
self.input_widget.clear();
}

pub fn render<B>(&mut self, f: &mut Frame<'_, B>, is_active: bool)
where
B: Backend,
Expand Down
8 changes: 6 additions & 2 deletions src/window/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,12 @@ const RIGHT_HELP_TEXT: &[HelpBlock] = &[
desc: "open filter form",
},
KeyBindings {
keys: &["Enter", "Esc"],
desc: "close filter form",
keys: &["q", "Esc"],
desc: "clear filter form",
},
KeyBindings {
keys: &["Enter"],
desc: "confirm filter word",
},
],
},
Expand Down

0 comments on commit 5231e5d

Please sign in to comment.