aboutsummaryrefslogtreecommitdiff
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/components.rs14
-rw-r--r--src/widgets/mod.rs21
-rw-r--r--src/widgets/systems.rs35
3 files changed, 70 insertions, 0 deletions
diff --git a/src/widgets/components.rs b/src/widgets/components.rs
new file mode 100644
index 0000000..b6ff925
--- /dev/null
+++ b/src/widgets/components.rs
@@ -0,0 +1,14 @@
+use bevy::prelude::*;
+
+use super::TerminalWidget;
+
+/// Component representing a terminal widget.
+#[derive(Component)]
+pub struct Widget {
+ /// The widget instance itself, containing rendering and input logic
+ pub widget: Box<dyn TerminalWidget + Send + Sync>,
+ /// Depth to render widget at
+ pub depth: u32,
+ /// Whether this widget is currently enabled or should be hidden
+ pub enabled: bool,
+}
diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs
new file mode 100644
index 0000000..46bfa20
--- /dev/null
+++ b/src/widgets/mod.rs
@@ -0,0 +1,21 @@
+use bevy::prelude::*;
+use downcast_rs::{impl_downcast, DowncastSync};
+use ratatui::{layout::Rect, Frame};
+
+use crate::input::events::TerminalInputEvent;
+
+/// Components for this module
+pub mod components;
+
+/// Systems for this module
+pub(crate) mod systems;
+
+/// Trait which defines an interface for terminal widgets
+pub trait TerminalWidget: DowncastSync {
+ /// Called every frame to render the widget
+ fn render(&mut self, frame: &mut Frame, rect: Rect);
+
+ /// Called when a terminal input event is invoked to update any state accordingly
+ fn handle_events(&mut self, _event: &TerminalInputEvent, _commands: &mut Commands) {}
+}
+impl_downcast!(sync TerminalWidget);
diff --git a/src/widgets/systems.rs b/src/widgets/systems.rs
new file mode 100644
index 0000000..69a84e3
--- /dev/null
+++ b/src/widgets/systems.rs
@@ -0,0 +1,35 @@
+use bevy::prelude::*;
+
+use crate::{display::resources::Terminal, input::events::TerminalInputEvent};
+
+use super::components::Widget;
+
+/// Invokes every enabled widget's `render` method
+pub fn draw_widgets(mut terminal: ResMut<Terminal>, mut widgets: Query<&mut Widget>) {
+ terminal
+ .0
+ .draw(|frame| {
+ 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, frame.size());
+ }
+ })
+ .unwrap();
+}
+
+/// Invokes every enabled widget's `handle_events` methods for each incoming input event
+pub fn widget_input_handling(
+ mut widgets: Query<&mut Widget>,
+ mut event_reader: EventReader<TerminalInputEvent>,
+ mut commands: Commands,
+) {
+ for event in event_reader.read() {
+ for mut widget in widgets.iter_mut().filter(|widget| widget.enabled) {
+ widget.widget.handle_events(event, &mut commands);
+ }
+ }
+}