diff options
-rw-r--r-- | Cargo.toml | 7 | ||||
-rw-r--r-- | src/components.rs | 11 | ||||
-rw-r--r-- | src/lib.rs | 21 | ||||
-rw-r--r-- | src/resources.rs | 61 | ||||
-rw-r--r-- | src/systems.rs | 17 |
5 files changed, 71 insertions, 46 deletions
@@ -1,21 +1,22 @@ [package] name = "grex_terminal_display" -version = "0.1.3" +version = "0.1.5" edition = "2021" [dependencies] crossterm = "0.27.0" +once_cell = "1.19.0" [dependencies.bevy] version = "0.13" [dependencies.grex_framebuffer_extract] git = "https://github.com/exvacuum/grex_framebuffer_extract" -tag = "v0.1.0" +tag = "v0.1.1" [dependencies.grex_dither_post_process] git = "https://github.com/exvacuum/grex_dither_post_process" -tag = "v0.1.2" +tag = "v0.1.3" [dependencies.ratatui] version = "0.26.2" diff --git a/src/components.rs b/src/components.rs index 3ebf507..3814cc7 100644 --- a/src/components.rs +++ b/src/components.rs @@ -11,6 +11,8 @@ use grex_framebuffer_extract::{ render_assets::FramebufferExtractSource, }; +use crate::resources::TerminalWidget; + #[derive(Component)] pub struct TerminalDisplay; @@ -72,3 +74,12 @@ impl TerminalDisplayBundle { } } +#[derive(Component)] +pub struct Widget { + pub widget: Box<dyn TerminalWidget + Send + Sync>, + pub depth: u32, + pub enabled: bool, +} + +#[derive(Component)] +pub struct Tooltip(pub String); @@ -1,4 +1,4 @@ -use std::{io::stdout, fs::OpenOptions}; +use std::{fs::OpenOptions, io::stdout, path::PathBuf, sync::{Arc, Mutex}}; use bevy::{ log::{ @@ -16,6 +16,7 @@ use grex_dither_post_process::DitherPostProcessPlugin; use grex_framebuffer_extract::FramebufferExtractPlugin; pub use crossterm; +use once_cell::sync::Lazy; pub use ratatui; pub mod components; @@ -23,10 +24,23 @@ pub mod events; pub mod resources; mod systems; -pub struct TerminalDisplayPlugin; +static LOG_PATH: Lazy<Arc<Mutex<PathBuf>>> = Lazy::new(|| Arc::new(Mutex::new(PathBuf::default()))); + +pub struct TerminalDisplayPlugin { + pub log_path: PathBuf, +} + +impl Default for TerminalDisplayPlugin { + fn default() -> Self { + Self { + log_path: "debug.log".into() + } + } +} impl Plugin for TerminalDisplayPlugin { fn build(&self, app: &mut App) { + *LOG_PATH.lock().expect("Failed to get lock on log path mutex") = self.log_path.clone(); app.add_plugins(( DitherPostProcessPlugin, FramebufferExtractPlugin, @@ -36,7 +50,7 @@ impl Plugin for TerminalDisplayPlugin { .write(true) .create(true) .truncate(true) - .open("debug.log") + .open(LOG_PATH.lock().expect("Failed to get lock on log path mutex").clone()) .unwrap(); let file_layer = tracing_subscriber::fmt::Layer::new() .with_writer(log_file) @@ -59,7 +73,6 @@ impl Plugin for TerminalDisplayPlugin { .insert_resource(resources::Terminal::default()) .insert_resource(resources::EventQueue::default()) .insert_resource(resources::TerminalInput::default()) - .insert_resource(resources::TerminalUI::default()) .add_event::<events::TerminalInputEvent>(); } } diff --git a/src/resources.rs b/src/resources.rs index a8d5a7f..a373a80 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -1,11 +1,10 @@ use std::{ - io::{stdout, Stdout}, - sync::{Arc, Mutex}, + any::Any, io::{stdout, Stdout}, sync::{Arc, Mutex} }; use bevy::{ prelude::*, - utils::{HashMap, HashSet, Uuid}, + utils::HashSet, }; use crossterm::{ event::{ @@ -72,34 +71,34 @@ impl Default for Terminal { } } -#[derive(Resource, Default)] -pub struct TerminalUI { - widgets: HashMap<Uuid, Box<dyn TerminalWidget + Sync + Send>>, -} - -impl TerminalUI { - pub fn insert_widget(&mut self, widget: Box<dyn TerminalWidget + Sync + Send>) -> Uuid { - let id = Uuid::new_v4(); - self.widgets.insert(id, widget); - id - } - - pub fn get_widget(&mut self, id: Uuid) -> Option<&mut Box<dyn TerminalWidget + Sync + Send>> { - self.widgets.get_mut(&id) - } - - pub fn destroy_widget(&mut self, id: Uuid) { - self.widgets.remove(&id); - } - - pub fn widgets(&mut self) -> Vec<&mut Box<dyn TerminalWidget + Sync + Send>> { - let mut vec = self.widgets.values_mut().collect::<Vec<_>>(); - vec.sort_by(|a, b| a.depth().cmp(&b.depth()).reverse()); - vec - } -} - -pub trait TerminalWidget { +// #[derive(Resource, Default)] +// pub struct TerminalUI { +// widgets: HashMap<Uuid, Box<dyn TerminalWidget + Sync + Send>>, +// } +// +// impl TerminalUI { +// pub fn insert_widget(&mut self, widget: Box<dyn TerminalWidget + Sync + Send>) -> Uuid { +// let id = Uuid::new_v4(); +// self.widgets.insert(id, widget); +// id +// } +// +// pub fn get_widget(&mut self, id: Uuid) -> Option<&mut Box<dyn TerminalWidget + Sync + Send>> { +// self.widgets.get_mut(&id) +// } +// +// pub fn destroy_widget(&mut self, id: Uuid) { +// self.widgets.remove(&id); +// } +// +// pub fn widgets(&mut self) -> Vec<&mut Box<dyn TerminalWidget + Sync + Send>> { +// let mut vec = self.widgets.values_mut().collect::<Vec<_>>(); +// vec.sort_by(|a, b| a.depth().cmp(&b.depth()).reverse()); +// vec +// } +// } + +pub trait TerminalWidget: Any { fn init(&mut self) {} fn update(&mut self) {} fn render(&mut self, frame: &mut Frame, rect: Rect); diff --git a/src/systems.rs b/src/systems.rs index b0055b9..dedef65 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -8,8 +8,7 @@ use grex_framebuffer_extract::{ }; use crate::{ - events::TerminalInputEvent, - resources::{EventQueue, Terminal, TerminalInput, TerminalUI}, + components::Widget, events::TerminalInputEvent, resources::{EventQueue, Terminal, TerminalInput} }; use ratatui::{ @@ -40,7 +39,7 @@ pub fn setup(event_queue: Res<EventQueue>) { pub fn print_to_terminal( mut terminal: ResMut<Terminal>, - mut terminal_ui: ResMut<TerminalUI>, + mut widgets: Query<&mut Widget>, image_exports: Query<&FramebufferExtractDestination>, ) { for image_export in image_exports.iter() { @@ -96,8 +95,10 @@ pub fn print_to_terminal( .wrap(Wrap { trim: true }), area, ); - for widget in terminal_ui.widgets().iter_mut() { - widget.render(frame, area); + let mut active_widgets = widgets.iter_mut().filter(|widget| widget.enabled).collect::<Vec<_>>(); + active_widgets.sort_by(|a, b| a.depth.cmp(&b.depth)); + for mut widget in active_widgets { + widget.widget.render(frame, area); } }) .expect("Failed to draw terminal frame"); @@ -117,13 +118,13 @@ fn braille_char(mask: u8) -> char { } pub fn widget_input_handling( - mut terminal_ui: ResMut<TerminalUI>, + mut widgets: Query<&mut Widget>, mut event_reader: EventReader<TerminalInputEvent>, mut commands: Commands, ) { for event in event_reader.read() { - for widget in terminal_ui.widgets().iter_mut() { - widget.handle_events(event, &mut commands); + for mut widget in widgets.iter_mut().filter(|widget| widget.enabled) { + widget.widget.handle_events(event, &mut commands); } } } |