diff options
| author | pablu <me@pablu.de> | 2026-05-07 13:07:32 +0200 |
|---|---|---|
| committer | pablu <me@pablu.de> | 2026-05-07 13:07:32 +0200 |
| commit | cc8e924ce828d237d7cdd245b794c532a4ee80d8 (patch) | |
| tree | 5fc7c118879eb0107fe20a12ff6c3096a3a36926 /src/ui.rs | |
| parent | 3346222550bc18edc457d9b509f00d0eba9d0f4f (diff) | |
working search
Diffstat (limited to 'src/ui.rs')
| -rw-r--r-- | src/ui.rs | 84 |
1 files changed, 69 insertions, 15 deletions
@@ -1,32 +1,82 @@ use ratatui::{ Frame, - layout::{Constraint, Layout}, + layout::{Constraint, Direction, Layout}, prelude::Rect, - style::{Color, Modifier, Style, Stylize}, + style::{Color, Modifier, Style}, text::{Line, Span}, - widgets::{Block, Borders, List, ListItem, ListState}, + widgets::{Block, Borders, Clear, List, ListItem, ListState, Paragraph}, }; use crate::app::App; pub fn ui(frame: &mut Frame, app: &mut App) { - let constraints = [Constraint::Length(1), Constraint::Fill(1)]; + let constraints = [Constraint::Fill(1), Constraint::Length(3)]; - let layout = Layout::vertical(constraints).spacing(1); - let [top, first] = frame.area().layout(&layout); + let layout = Layout::vertical(constraints); + let [top, bottom] = frame.area().layout(&layout); let split = Layout::horizontal([Constraint::Percentage(70), Constraint::Percentage(30)]) .spacing(1) - .split(first); - - let title = Line::from_iter([ - Span::from("Installed Packages").bold(), - Span::from(" (Press 'q' to quit and arrow keys to navigate)"), - ]); - frame.render_widget(title.centered(), top); + .split(top); render_packages(frame, split[0], app); render_use_flags(frame, split[1], app); + + let key_hint = match app.showing_search_window { + false => Span::styled( + "(q) to quit | (/) to search | (j) down | (k) up", + Style::default().fg(Color::Yellow), + ), + true => Span::styled( + "(esc) to quit search | (enter) to search", + Style::default().fg(Color::Yellow), + ), + }; + + let key_notes_footer = + Paragraph::new(Line::from(key_hint)).block(Block::default().borders(Borders::ALL)); + frame.render_widget(key_notes_footer, bottom); + + if app.showing_search_window { + let mut popup_block = Block::default() + .title("Search") + .borders(Borders::ALL) + .border_type(ratatui::widgets::BorderType::Rounded); + + if let Some(found) = app.search_found { + if found { + popup_block = popup_block.border_style(Style::default().fg(Color::Green)) + } else { + popup_block = popup_block.border_style(Style::default().fg(Color::Red)) + } + } + + app.textarea.set_block(popup_block); + app.textarea.set_style(Style::default().fg(Color::Yellow)); + app.textarea.set_cursor_line_style(Style::default()); + + let area = search_popup_rect(70, frame.area()); + frame.render_widget(Clear, area); + frame.render_widget(&app.textarea, area); + } +} + +fn search_popup_rect(percent_x: u16, r: Rect) -> Rect { + // Cut the given rectangle into three vertical pieces + let popup_layout = Layout::default() + .direction(Direction::Vertical) + .constraints([Constraint::Length(10), Constraint::Length(3)]) + .split(r); + + // Then cut the middle vertical piece into three width-wise pieces + Layout::default() + .direction(Direction::Horizontal) + .constraints([ + Constraint::Percentage((100 - percent_x) / 2), + Constraint::Percentage(percent_x), + Constraint::Percentage((100 - percent_x) / 2), + ]) + .split(popup_layout[1])[1] // Return the middle chunk } fn render_packages(frame: &mut Frame, area: Rect, app: &mut App) { @@ -35,7 +85,11 @@ fn render_packages(frame: &mut Frame, area: Rect, app: &mut App) { .style(Color::White) .highlight_style(Modifier::REVERSED) .highlight_symbol("> ") - .block(Block::new().borders(Borders::ALL)); + .block( + Block::new() + .borders(Borders::ALL) + .title("Installed packages"), + ); frame.render_stateful_widget(list, area, &mut app.list_state); } @@ -68,7 +122,7 @@ fn render_use_flags(frame: &mut Frame, area: Rect, app: &mut App) { .style(Color::White) .scroll_padding(1) .direction(ratatui::widgets::ListDirection::TopToBottom) - .block(Block::new().borders(Borders::ALL)); + .block(Block::new().borders(Borders::ALL).title("USE Flags")); let mut list_state = ListState::default(); list_state.select_first(); |
