use crate::canvas::event::{self, Event}; use crate::canvas::mouse; use crate::core::Rectangle; use crate::graphics::geometry; /// 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 where Renderer: geometry::Renderer, { /// The internal state mutated by the [`Program`]. type State: Default + 'static; /// Updates the [`State`](Self::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: mouse::Cursor, ) -> (event::Status, Option) { (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, renderer: &Renderer, theme: &Renderer::Theme, bounds: Rectangle, cursor: mouse::Cursor, ) -> Vec; /// 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: mouse::Cursor, ) -> mouse::Interaction { mouse::Interaction::default() } } impl Program for &T where Renderer: geometry::Renderer, T: Program, { type State = T::State; fn update( &self, state: &mut Self::State, event: Event, bounds: Rectangle, cursor: mouse::Cursor, ) -> (event::Status, Option) { T::update(self, state, event, bounds, cursor) } fn draw( &self, state: &Self::State, renderer: &Renderer, theme: &Renderer::Theme, bounds: Rectangle, cursor: mouse::Cursor, ) -> Vec { T::draw(self, state, renderer, theme, bounds, cursor) } fn mouse_interaction( &self, state: &Self::State, bounds: Rectangle, cursor: mouse::Cursor, ) -> mouse::Interaction { T::mouse_interaction(self, state, bounds, cursor) } }