summaryrefslogtreecommitdiffstats
path: root/graphics/src/widget/pure/canvas/program.rs
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/src/widget/pure/canvas/program.rs')
-rw-r--r--graphics/src/widget/pure/canvas/program.rs104
1 files changed, 104 insertions, 0 deletions
diff --git a/graphics/src/widget/pure/canvas/program.rs b/graphics/src/widget/pure/canvas/program.rs
new file mode 100644
index 00000000..cb52910d
--- /dev/null
+++ b/graphics/src/widget/pure/canvas/program.rs
@@ -0,0 +1,104 @@
+use crate::widget::pure::canvas::event::{self, Event};
+use crate::widget::pure::canvas::mouse;
+use crate::widget::pure::canvas::{Cursor, Geometry};
+use crate::Rectangle;
+
+/// The state and logic of a [`Canvas`].
+///
+/// A [`Program`] can mutate internal state and produce messages for an
+/// application.
+///
+/// [`Canvas`]: crate::widget::Canvas
+pub trait Program {
+ /// The [`Message`] produced by the [`Program`].
+ type Message;
+
+ /// The internal [`State`] mutated by the [`Program`].
+ type State: Default + 'static;
+
+ /// Updates the state of the [`Program`].
+ ///
+ /// When a [`Program`] is used in a [`Canvas`], the runtime will call this
+ /// method for each [`Event`].
+ ///
+ /// This method can optionally return a `Message` to notify an application
+ /// of any meaningful interactions.
+ ///
+ /// By default, this method does and returns nothing.
+ ///
+ /// [`Canvas`]: crate::widget::Canvas
+ fn update(
+ &self,
+ _state: &mut Self::State,
+ _event: Event,
+ _bounds: Rectangle,
+ _cursor: Cursor,
+ ) -> (event::Status, Option<Self::Message>) {
+ (event::Status::Ignored, None)
+ }
+
+ /// Draws the state of the [`Program`], producing a bunch of [`Geometry`].
+ ///
+ /// [`Geometry`] can be easily generated with a [`Frame`] or stored in a
+ /// [`Cache`].
+ ///
+ /// [`Frame`]: crate::widget::canvas::Frame
+ /// [`Cache`]: crate::widget::canvas::Cache
+ fn draw(
+ &self,
+ state: &Self::State,
+ bounds: Rectangle,
+ cursor: Cursor,
+ ) -> Vec<Geometry>;
+
+ /// Returns the current mouse interaction of the [`Program`].
+ ///
+ /// The interaction returned will be in effect even if the cursor position
+ /// is out of bounds of the program's [`Canvas`].
+ ///
+ /// [`Canvas`]: crate::widget::Canvas
+ fn mouse_interaction(
+ &self,
+ _state: &Self::State,
+ _bounds: Rectangle,
+ _cursor: Cursor,
+ ) -> mouse::Interaction {
+ mouse::Interaction::default()
+ }
+}
+
+impl<T> Program for &T
+where
+ T: Program,
+{
+ type Message = T::Message;
+ type State = T::State;
+
+ fn update(
+ &self,
+ state: &mut Self::State,
+ event: Event,
+ bounds: Rectangle,
+ cursor: Cursor,
+ ) -> (event::Status, Option<Self::Message>) {
+ T::update(self, state, event, bounds, cursor)
+ }
+
+ fn draw(
+ &self,
+ state: &Self::State,
+ bounds: Rectangle,
+ cursor: Cursor,
+ ) -> Vec<Geometry> {
+ T::draw(self, state, bounds, cursor)
+ }
+
+ fn mouse_interaction(
+ &self,
+ state: &Self::State,
+ bounds: Rectangle,
+ cursor: Cursor,
+ ) -> mouse::Interaction {
+ T::mouse_interaction(self, state, bounds, cursor)
+ }
+}