parent
0c87fda795
commit
a3c1065f96
@ -9,7 +9,8 @@ use ratatui::crossterm::event;
|
|||||||
use ratatui::crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
|
use ratatui::crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers};
|
||||||
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
||||||
use ratatui::prelude::{Color, Style, Widget};
|
use ratatui::prelude::{Color, Style, Widget};
|
||||||
use ratatui::widgets::{Block, Borders, Padding, Tabs};
|
use ratatui::text::Text;
|
||||||
|
use ratatui::widgets::{Block, Borders, Padding, Paragraph, Tabs, Wrap};
|
||||||
use ratatui::{DefaultTerminal, symbols};
|
use ratatui::{DefaultTerminal, symbols};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -93,7 +94,7 @@ impl<'a> App<'a> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_status(&self, area: Rect, buf: &mut Buffer) {
|
fn draw_top_status(&self, area: Rect, buf: &mut Buffer) {
|
||||||
// TODO: Status bar should have drop down menus
|
// TODO: Status bar should have drop down menus
|
||||||
Tabs::new(["File", "Edit", "View", "Help"])
|
Tabs::new(["File", "Edit", "View", "Help"])
|
||||||
.style(Style::default())
|
.style(Style::default())
|
||||||
@ -101,6 +102,21 @@ impl<'a> App<'a> {
|
|||||||
.render(area, buf);
|
.render(area, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn draw_bottom_status(&self, area: Rect, buf: &mut Buffer) {
|
||||||
|
// TODO: Set help text based on most recent component enabled.
|
||||||
|
Paragraph::new(
|
||||||
|
self.get_component::<Logger>()
|
||||||
|
.unwrap()
|
||||||
|
.component_state
|
||||||
|
.help_text
|
||||||
|
.clone(),
|
||||||
|
)
|
||||||
|
.style(Color::Gray)
|
||||||
|
.wrap(Wrap { trim: false })
|
||||||
|
.centered()
|
||||||
|
.render(area, buf);
|
||||||
|
}
|
||||||
|
|
||||||
fn draw_tabs(&self, area: Rect, buf: &mut Buffer) {
|
fn draw_tabs(&self, area: Rect, buf: &mut Buffer) {
|
||||||
// Determine the tab title from the current file (or use a fallback).
|
// Determine the tab title from the current file (or use a fallback).
|
||||||
let mut title: Option<&str> = None;
|
let mut title: Option<&str> = None;
|
||||||
@ -153,9 +169,10 @@ impl<'a> Widget for &mut App<'a> {
|
|||||||
let vertical = Layout::default()
|
let vertical = Layout::default()
|
||||||
.direction(Direction::Vertical)
|
.direction(Direction::Vertical)
|
||||||
.constraints([
|
.constraints([
|
||||||
Constraint::Length(3), // status bar
|
Constraint::Length(3), // top status bar
|
||||||
Constraint::Percentage(70), // horizontal layout
|
Constraint::Percentage(70), // horizontal layout
|
||||||
Constraint::Percentage(30), // terminal
|
Constraint::Percentage(30), // terminal
|
||||||
|
Constraint::Length(3), // bottom status bar
|
||||||
])
|
])
|
||||||
.split(area);
|
.split(area);
|
||||||
|
|
||||||
@ -175,7 +192,8 @@ impl<'a> Widget for &mut App<'a> {
|
|||||||
])
|
])
|
||||||
.split(horizontal[1]);
|
.split(horizontal[1]);
|
||||||
|
|
||||||
self.draw_status(vertical[0], buf);
|
self.draw_top_status(vertical[0], buf);
|
||||||
|
self.draw_bottom_status(vertical[3], buf);
|
||||||
self.draw_tabs(editor_layout[0], buf);
|
self.draw_tabs(editor_layout[0], buf);
|
||||||
let id = self.id().to_string();
|
let id = self.id().to_string();
|
||||||
for component in &mut self.components {
|
for component in &mut self.components {
|
||||||
@ -225,7 +243,7 @@ impl<'a> Component for App<'a> {
|
|||||||
AppComponents::AppEditor(e) => e as &mut dyn Component,
|
AppComponents::AppEditor(e) => e as &mut dyn Component,
|
||||||
AppComponents::AppExplorer(e) => e as &mut dyn Component,
|
AppComponents::AppExplorer(e) => e as &mut dyn Component,
|
||||||
AppComponents::AppLogger(e) => e as &mut dyn Component,
|
AppComponents::AppLogger(e) => e as &mut dyn Component,
|
||||||
AppComponents::AppComponent(e) => e.as_mut() as &mut dyn Component,
|
AppComponents::AppComponent(e) => e.as_mut(),
|
||||||
};
|
};
|
||||||
if !c.is_active() {
|
if !c.is_active() {
|
||||||
if let Some(mouse) = event.as_mouse_event() {
|
if let Some(mouse) = event.as_mouse_event() {
|
||||||
|
|||||||
@ -51,17 +51,24 @@ pub trait Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct ComponentState {
|
pub struct ComponentState {
|
||||||
pub(crate) focus: Focus,
|
pub(crate) focus: Focus,
|
||||||
|
pub(crate) help_text: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ComponentState {
|
impl ComponentState {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
focus: Focus::Active,
|
focus: Focus::Active,
|
||||||
|
help_text: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn with_help_text(mut self, help_text: &str) -> Self {
|
||||||
|
self.help_text = help_text.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Default, PartialEq)]
|
#[derive(Debug, Clone, Copy, Default, PartialEq)]
|
||||||
@ -79,7 +86,10 @@ pub trait FocusState {
|
|||||||
|
|
||||||
impl FocusState for ComponentState {
|
impl FocusState for ComponentState {
|
||||||
fn with_focus(self, focus: Focus) -> Self {
|
fn with_focus(self, focus: Focus) -> Self {
|
||||||
Self { focus }
|
Self {
|
||||||
|
focus,
|
||||||
|
help_text: self.help_text,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_focus(&mut self, focus: Focus) {
|
fn set_focus(&mut self, focus: Focus) {
|
||||||
|
|||||||
@ -46,7 +46,7 @@ impl Editor {
|
|||||||
event_handler: EditorEventHandler::default(),
|
event_handler: EditorEventHandler::default(),
|
||||||
file_path: None,
|
file_path: None,
|
||||||
syntax_set: SyntaxSet::load_defaults_nonewlines(),
|
syntax_set: SyntaxSet::load_defaults_nonewlines(),
|
||||||
component_state: Default::default(),
|
component_state: ComponentState::default().with_help_text("TODO: Vim help text"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -39,7 +39,7 @@ impl<'a> Explorer<'a> {
|
|||||||
root_path: path.to_owned(),
|
root_path: path.to_owned(),
|
||||||
tree_items: Self::build_tree_from_path(path.to_owned())?,
|
tree_items: Self::build_tree_from_path(path.to_owned())?,
|
||||||
tree_state: TreeState::default(),
|
tree_state: TreeState::default(),
|
||||||
component_state: Default::default(),
|
component_state: ComponentState::default().with_help_text("TODO: Explorer help text."),
|
||||||
};
|
};
|
||||||
Ok(explorer)
|
Ok(explorer)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,7 +33,11 @@ impl Logger {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
state: TuiWidgetState::new(),
|
state: TuiWidgetState::new(),
|
||||||
component_state: Default::default(),
|
component_state: ComponentState::default().with_help_text(concat!(
|
||||||
|
"Q: Quit | Tab: Switch state | ↑/↓: Select target | f: Focus target",
|
||||||
|
" | ←/→: Display level | +/-: Filter level | Space: Toggle hidden targets",
|
||||||
|
" | h: Hide target selector | PageUp/Down: Scroll | Esc: Cancel scroll"
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user