summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClementTsang <cjhtsang@uwaterloo.ca>2021-11-29 23:21:48 -0500
committerClementTsang <cjhtsang@uwaterloo.ca>2021-11-29 23:21:48 -0500
commit70294129291359ce6f9c6b252d3720d2b96b26aa (patch)
treeab260814583db4ab20db1cfba7ab1b9ff16b7f49
parent63dcaae8e8958a52c2485b6650c2eae8643632ad (diff)
temp
-rw-r--r--src/tuine/component.rs20
-rw-r--r--src/tuine/component/block.rs0
-rw-r--r--src/tuine/component/column.rs0
-rw-r--r--src/tuine/component/row.rs0
-rw-r--r--src/tuine/component/shortcut.rs35
-rw-r--r--src/tuine/component/text_table.rs34
6 files changed, 65 insertions, 24 deletions
diff --git a/src/tuine/component.rs b/src/tuine/component.rs
index c331b056..31a9899f 100644
--- a/src/tuine/component.rs
+++ b/src/tuine/component.rs
@@ -8,11 +8,17 @@ use tui::{backend::Backend, layout::Rect, Frame};
use super::{Event, Status};
-/// A [`Component`] is an element that displays information and can be interacted with.
+pub type ShouldRender = bool;
+
+/// A is an element that displays information and can be interacted with.
#[allow(unused_variables)]
pub trait Component {
+ /// How to inform a component after some event takes place. Typically some enum.
type Message: 'static;
+ /// Information passed to the component from its parent.
+ type Properties;
+
/// Handles an [`Event`]. Defaults to just ignoring the event.
fn on_event(
&mut self, bounds: Rect, event: Event, messages: &mut Vec<Self::Message>,
@@ -20,8 +26,16 @@ pub trait Component {
Status::Ignored
}
- fn update(&mut self, message: Self::Message) {}
+ /// How the component should handle a [`Self::Message`]. Defaults to doing nothing.
+ fn update(&mut self, message: Self::Message) -> ShouldRender {
+ false
+ }
+
+ /// How the component should handle an update to its properties. Defaults to doing nothing.
+ fn change(&mut self, props: Self::Properties) -> ShouldRender {
+ false
+ }
- /// Draws the [`Component`].
+ /// Draws the component.
fn draw<B: Backend>(&mut self, bounds: Rect, frame: &mut Frame<'_, B>);
}
diff --git a/src/tuine/component/block.rs b/src/tuine/component/block.rs
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/tuine/component/block.rs
diff --git a/src/tuine/component/column.rs b/src/tuine/component/column.rs
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/tuine/component/column.rs
diff --git a/src/tuine/component/row.rs b/src/tuine/component/row.rs
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/tuine/component/row.rs
diff --git a/src/tuine/component/shortcut.rs b/src/tuine/component/shortcut.rs
new file mode 100644
index 00000000..c2204cc9
--- /dev/null
+++ b/src/tuine/component/shortcut.rs
@@ -0,0 +1,35 @@
+use super::Component;
+
+/// A [`Component`] to handle keyboard shortcuts and assign actions to them.
+///
+/// Inspired by [Flutter's approach](https://docs.flutter.dev/development/ui/advanced/actions_and_shortcuts).
+pub struct Shortcut<Msg: 'static> {
+ _p: std::marker::PhantomData<Msg>,
+}
+
+impl<Msg> Component for Shortcut<Msg> {
+ type Message = Msg;
+
+ type Properties = ();
+
+ fn on_event(
+ &mut self, bounds: tui::layout::Rect, event: crate::tuine::Event,
+ messages: &mut Vec<Self::Message>,
+ ) -> crate::tuine::Status {
+ crate::tuine::Status::Ignored
+ }
+
+ fn update(&mut self, message: Self::Message) -> super::ShouldRender {
+ false
+ }
+
+ fn change(&mut self, props: Self::Properties) -> super::ShouldRender {
+ false
+ }
+
+ fn draw<B: tui::backend::Backend>(
+ &mut self, bounds: tui::layout::Rect, frame: &mut tui::Frame<'_, B>,
+ ) {
+ todo!()
+ }
+}
diff --git a/src/tuine/component/text_table.rs b/src/tuine/component/text_table.rs
index 2ab8fe8f..bdfb104b 100644
--- a/src/tuine/component/text_table.rs
+++ b/src/tuine/component/text_table.rs
@@ -20,7 +20,7 @@ use crate::{
pub use self::table_column::{TextColumn, TextColumnConstraint};
use self::table_scroll_state::ScrollState as TextTableState;
-use super::Component;
+use super::{Component, ShouldRender};
#[derive(Clone, Debug, Default)]
pub struct StyleSheet {
@@ -29,7 +29,7 @@ pub struct StyleSheet {
table_header: Style,
}
-struct TextTableMsg {}
+pub enum TextTableMsg {}
/// A sortable, scrollable table for text data.
pub struct TextTable<'a> {
@@ -59,8 +59,6 @@ impl<'a> TextTable<'a> {
style_sheet: StyleSheet::default(),
sortable: false,
table_gap: 0,
- on_select: None,
- on_select_click: None,
}
}
@@ -89,22 +87,6 @@ impl<'a> TextTable<'a> {
self
}
- /// What [`Message`] to send when a row is selected.
- ///
- /// Defaults to `None` (doing nothing).
- pub fn on_select(mut self, on_select: Option<Message>) -> Self {
- self.on_select = on_select;
- self
- }
-
- /// What [`Message`] to send if a selected row is clicked on.
- ///
- /// Defaults to `None` (doing nothing).
- pub fn on_select_click(mut self, on_select_click: Option<Message>) -> Self {
- self.on_select_click = on_select_click;
- self
- }
-
fn update_column_widths(&mut self, bounds: Rect) {
let total_width = bounds.width;
let mut width_remaining = bounds.width;
@@ -157,7 +139,11 @@ impl<'a> TextTable<'a> {
impl<'a> Component for TextTable<'a> {
type Message = TextTableMsg;
- fn on_event(&mut self, bounds: Rect, event: Event, messages: &mut Vec<Message>) -> Status {
+ type Properties = ();
+
+ fn on_event(
+ &mut self, bounds: Rect, event: Event, messages: &mut Vec<Self::Message>,
+ ) -> Status {
use crate::tuine::MouseBoundIntersect;
use crossterm::event::{MouseButton, MouseEventKind};
@@ -190,6 +176,12 @@ impl<'a> Component for TextTable<'a> {
}
}
+ fn update(&mut self, message: Self::Message) -> ShouldRender {
+ match message {}
+
+ true
+ }
+
fn draw<B: Backend>(&mut self, bounds: Rect, frame: &mut Frame<'_, B>) {
self.table_gap = if !self.show_gap
|| (self.data.len() + 2 > bounds.height.into()