2024-08-06 17:21:47 +01:00
|
|
|
use crossterm::event::{KeyCode, KeyEvent};
|
|
|
|
use ratatui::{
|
|
|
|
layout::{Constraint, Direction, Layout, Rect},
|
|
|
|
Frame,
|
|
|
|
};
|
|
|
|
|
2024-09-06 22:36:12 +01:00
|
|
|
use crate::hint::ShortcutList;
|
|
|
|
|
2024-08-06 17:21:47 +01:00
|
|
|
pub trait FloatContent {
|
|
|
|
fn draw(&mut self, frame: &mut Frame, area: Rect);
|
|
|
|
fn handle_key_event(&mut self, key: &KeyEvent) -> bool;
|
|
|
|
fn is_finished(&self) -> bool;
|
2024-09-06 22:36:12 +01:00
|
|
|
fn get_shortcut_list(&self) -> ShortcutList;
|
2024-08-06 17:21:47 +01:00
|
|
|
}
|
|
|
|
|
2024-08-09 10:22:19 +01:00
|
|
|
pub struct Float {
|
|
|
|
content: Box<dyn FloatContent>,
|
2024-08-06 17:21:47 +01:00
|
|
|
width_percent: u16,
|
|
|
|
height_percent: u16,
|
2024-06-06 23:56:45 +01:00
|
|
|
}
|
|
|
|
|
2024-08-09 10:22:19 +01:00
|
|
|
impl Float {
|
|
|
|
pub fn new(content: Box<dyn FloatContent>, width_percent: u16, height_percent: u16) -> Self {
|
2024-08-06 17:21:47 +01:00
|
|
|
Self {
|
2024-08-09 10:22:19 +01:00
|
|
|
content,
|
2024-08-06 17:21:47 +01:00
|
|
|
width_percent,
|
|
|
|
height_percent,
|
|
|
|
}
|
2024-06-06 23:56:45 +01:00
|
|
|
}
|
2024-08-06 17:21:47 +01:00
|
|
|
|
|
|
|
fn floating_window(&self, size: Rect) -> Rect {
|
|
|
|
let hor_float = Layout::default()
|
|
|
|
.constraints([
|
|
|
|
Constraint::Percentage((100 - self.width_percent) / 2),
|
|
|
|
Constraint::Percentage(self.width_percent),
|
|
|
|
Constraint::Percentage((100 - self.width_percent) / 2),
|
|
|
|
])
|
|
|
|
.direction(Direction::Horizontal)
|
|
|
|
.split(size)[1];
|
|
|
|
|
|
|
|
Layout::default()
|
|
|
|
.constraints([
|
|
|
|
Constraint::Percentage((100 - self.height_percent) / 2),
|
|
|
|
Constraint::Percentage(self.height_percent),
|
|
|
|
Constraint::Percentage((100 - self.height_percent) / 2),
|
|
|
|
])
|
|
|
|
.direction(Direction::Vertical)
|
|
|
|
.split(hor_float)[1]
|
2024-06-06 23:56:45 +01:00
|
|
|
}
|
|
|
|
|
2024-08-06 17:21:47 +01:00
|
|
|
pub fn draw(&mut self, frame: &mut Frame, parent_area: Rect) {
|
|
|
|
let popup_area = self.floating_window(parent_area);
|
2024-09-19 19:18:55 +01:00
|
|
|
self.content.draw(frame, popup_area);
|
2024-08-06 17:21:47 +01:00
|
|
|
}
|
|
|
|
|
2024-08-09 10:22:19 +01:00
|
|
|
// Returns true if the floating window is finished.
|
2024-08-06 17:21:47 +01:00
|
|
|
pub fn handle_key_event(&mut self, key: &KeyEvent) -> bool {
|
2024-08-09 10:22:19 +01:00
|
|
|
match key.code {
|
2024-09-22 20:08:27 +01:00
|
|
|
KeyCode::Enter
|
|
|
|
| KeyCode::Char('p')
|
|
|
|
| KeyCode::Char('d')
|
|
|
|
| KeyCode::Char('g')
|
|
|
|
| KeyCode::Esc
|
2024-09-19 01:17:08 +01:00
|
|
|
if self.content.is_finished() =>
|
|
|
|
{
|
2024-08-09 10:22:19 +01:00
|
|
|
true
|
2024-08-06 17:21:47 +01:00
|
|
|
}
|
2024-08-09 10:22:19 +01:00
|
|
|
_ => self.content.handle_key_event(key),
|
2024-08-06 17:21:47 +01:00
|
|
|
}
|
|
|
|
}
|
2024-09-06 22:36:12 +01:00
|
|
|
|
|
|
|
pub fn get_shortcut_list(&self) -> ShortcutList {
|
|
|
|
self.content.get_shortcut_list()
|
|
|
|
}
|
2024-06-06 23:56:45 +01:00
|
|
|
}
|