Create iced_widget subcrate and re-organize the whole codebase
This commit is contained in:
parent
c54409d171
commit
3a0d34c024
209 changed files with 1959 additions and 2183 deletions
64
widget/src/canvas/cursor.rs
Normal file
64
widget/src/canvas/cursor.rs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
use crate::core::{Point, Rectangle};
|
||||
|
||||
/// The mouse cursor state.
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Cursor {
|
||||
/// The cursor has a defined position.
|
||||
Available(Point),
|
||||
|
||||
/// The cursor is currently unavailable (i.e. out of bounds or busy).
|
||||
Unavailable,
|
||||
}
|
||||
|
||||
impl Cursor {
|
||||
// TODO: Remove this once this type is used in `iced_native` to encode
|
||||
// proper cursor availability
|
||||
pub(crate) fn from_window_position(position: Point) -> Self {
|
||||
if position.x < 0.0 || position.y < 0.0 {
|
||||
Cursor::Unavailable
|
||||
} else {
|
||||
Cursor::Available(position)
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the absolute position of the [`Cursor`], if available.
|
||||
pub fn position(&self) -> Option<Point> {
|
||||
match self {
|
||||
Cursor::Available(position) => Some(*position),
|
||||
Cursor::Unavailable => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the relative position of the [`Cursor`] inside the given bounds,
|
||||
/// if available.
|
||||
///
|
||||
/// If the [`Cursor`] is not over the provided bounds, this method will
|
||||
/// return `None`.
|
||||
pub fn position_in(&self, bounds: &Rectangle) -> Option<Point> {
|
||||
if self.is_over(bounds) {
|
||||
self.position_from(bounds.position())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the relative position of the [`Cursor`] from the given origin,
|
||||
/// if available.
|
||||
pub fn position_from(&self, origin: Point) -> Option<Point> {
|
||||
match self {
|
||||
Cursor::Available(position) => {
|
||||
Some(Point::new(position.x - origin.x, position.y - origin.y))
|
||||
}
|
||||
Cursor::Unavailable => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether the [`Cursor`] is currently over the provided bounds
|
||||
/// or not.
|
||||
pub fn is_over(&self, bounds: &Rectangle) -> bool {
|
||||
match self {
|
||||
Cursor::Available(position) => bounds.contains(*position),
|
||||
Cursor::Unavailable => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
21
widget/src/canvas/event.rs
Normal file
21
widget/src/canvas/event.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
//! Handle events of a canvas.
|
||||
use crate::core::keyboard;
|
||||
use crate::core::mouse;
|
||||
use crate::core::touch;
|
||||
|
||||
pub use crate::core::event::Status;
|
||||
|
||||
/// A [`Canvas`] event.
|
||||
///
|
||||
/// [`Canvas`]: crate::widget::Canvas
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum Event {
|
||||
/// A mouse event.
|
||||
Mouse(mouse::Event),
|
||||
|
||||
/// A touch event.
|
||||
Touch(touch::Event),
|
||||
|
||||
/// A keyboard event.
|
||||
Keyboard(keyboard::Event),
|
||||
}
|
||||
109
widget/src/canvas/program.rs
Normal file
109
widget/src/canvas/program.rs
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
use crate::canvas::event::{self, Event};
|
||||
use crate::canvas::mouse;
|
||||
use crate::canvas::Cursor;
|
||||
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<Message, Renderer = crate::Renderer>
|
||||
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: Cursor,
|
||||
) -> (event::Status, Option<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,
|
||||
renderer: &Renderer,
|
||||
theme: &Renderer::Theme,
|
||||
bounds: Rectangle,
|
||||
cursor: Cursor,
|
||||
) -> Vec<Renderer::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<Message, Renderer, T> Program<Message, Renderer> for &T
|
||||
where
|
||||
Renderer: geometry::Renderer,
|
||||
T: Program<Message, Renderer>,
|
||||
{
|
||||
type State = T::State;
|
||||
|
||||
fn update(
|
||||
&self,
|
||||
state: &mut Self::State,
|
||||
event: Event,
|
||||
bounds: Rectangle,
|
||||
cursor: Cursor,
|
||||
) -> (event::Status, Option<Message>) {
|
||||
T::update(self, state, event, bounds, cursor)
|
||||
}
|
||||
|
||||
fn draw(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
renderer: &Renderer,
|
||||
theme: &Renderer::Theme,
|
||||
bounds: Rectangle,
|
||||
cursor: Cursor,
|
||||
) -> Vec<Renderer::Geometry> {
|
||||
T::draw(self, state, renderer, theme, bounds, cursor)
|
||||
}
|
||||
|
||||
fn mouse_interaction(
|
||||
&self,
|
||||
state: &Self::State,
|
||||
bounds: Rectangle,
|
||||
cursor: Cursor,
|
||||
) -> mouse::Interaction {
|
||||
T::mouse_interaction(self, state, bounds, cursor)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue