forked from NationTech/harmony
Add a new `harmony_tui` crate to initialize and run a text-based user interface (TUI) for the Harmony project using `ratatui` for rendering and `crossterm` for handling input. The `HarmonyTUI` struct initializes the terminal, enters a loop to render updates, and handles basic input events to exit. This commit sets up the foundation for further TUI development.
68 lines
1.8 KiB
Rust
68 lines
1.8 KiB
Rust
use std::io;
|
|
use crossterm::event::{self, Event};
|
|
use harmony::maestro::Maestro;
|
|
use ratatui::{self, layout::Position, prelude::CrosstermBackend, Frame, Terminal};
|
|
|
|
pub mod tui {
|
|
// Export any necessary modules or types from the internal tui module
|
|
}
|
|
|
|
/// Initializes the terminal UI with the provided Maestro instance.
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `maestro` - A reference to the Maestro instance containing registered scores.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```rust
|
|
/// use harmony;
|
|
/// use harmony_tui::init;
|
|
///
|
|
/// #[harmony::main]
|
|
/// pub async fn main(maestro: harmony::Maestro) {
|
|
/// maestro.register(DeploymentScore::new("nginx-test", "nginx"));
|
|
/// maestro.register(OKDLoadBalancerScore::new(&maestro.inventory, &maestro.topology));
|
|
/// // Register other scores as needed
|
|
///
|
|
/// init(maestro).await.unwrap();
|
|
/// }
|
|
/// ```
|
|
pub async fn init(maestro: Maestro) -> Result<(), Box<dyn std::error::Error>> {
|
|
HarmonyTUI::new(maestro).init().await
|
|
}
|
|
|
|
pub struct HarmonyTUI {
|
|
maestro: Maestro,
|
|
}
|
|
|
|
impl HarmonyTUI {
|
|
pub fn new(maestro: Maestro) -> Self {
|
|
HarmonyTUI { maestro }
|
|
}
|
|
|
|
pub async fn init(self) -> Result<(), Box<dyn std::error::Error>> {
|
|
color_eyre::install()?;
|
|
let backend = CrosstermBackend::new(io::stdout());
|
|
let mut terminal = Terminal::new(backend)?;
|
|
|
|
loop {
|
|
terminal.draw(|f| self.render(f))?;
|
|
if matches!(event::read()?, Event::Key(_)) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn render(&self, frame: &mut Frame) {
|
|
let size = frame.area();
|
|
frame.set_cursor_position(Position::new(size.x / 2, size.y / 2));
|
|
frame.render_widget(
|
|
ratatui::widgets::Paragraph::new("Hello World"),
|
|
frame.area(),
|
|
);
|
|
}
|
|
}
|