summaryrefslogtreecommitdiffstats
path: root/wgpu
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-04-19 14:39:30 +0200
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-04-19 14:39:30 +0200
commit0b5028b1ab47707a469176e9bf20cacdd3a19861 (patch)
treeba4ea88bbb5e3d3ebf22699a758c30181f535b35 /wgpu
parent90c3a183d5e79aee1f323991c8c45161ccf9e187 (diff)
downloadiced-0b5028b1ab47707a469176e9bf20cacdd3a19861.tar.gz
iced-0b5028b1ab47707a469176e9bf20cacdd3a19861.tar.bz2
iced-0b5028b1ab47707a469176e9bf20cacdd3a19861.zip
Draft `Program` interactivity for `Canvas`
Diffstat (limited to 'wgpu')
-rw-r--r--wgpu/src/lib.rs2
-rw-r--r--wgpu/src/widget/canvas.rs82
-rw-r--r--wgpu/src/widget/canvas/drawable.rs6
-rw-r--r--wgpu/src/widget/canvas/event.rs6
-rw-r--r--wgpu/src/widget/canvas/layer/cache.rs16
-rw-r--r--wgpu/src/widget/canvas/program.rs16
6 files changed, 99 insertions, 29 deletions
diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs
index 799c1f34..30b5bb4a 100644
--- a/wgpu/src/lib.rs
+++ b/wgpu/src/lib.rs
@@ -20,7 +20,7 @@
//! [`wgpu`]: https://github.com/gfx-rs/wgpu-rs
//! [WebGPU API]: https://gpuweb.github.io/gpuweb/
//! [`wgpu_glyph`]: https://github.com/hecrj/wgpu_glyph
-#![deny(missing_docs)]
+//#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![deny(unused_results)]
#![forbid(unsafe_code)]
diff --git a/wgpu/src/widget/canvas.rs b/wgpu/src/widget/canvas.rs
index 325f90ce..de4f0203 100644
--- a/wgpu/src/widget/canvas.rs
+++ b/wgpu/src/widget/canvas.rs
@@ -9,7 +9,8 @@
use crate::{Defaults, Primitive, Renderer};
use iced_native::{
- layout, Element, Hasher, Layout, Length, MouseCursor, Point, Size, Widget,
+ input::mouse, layout, Clipboard, Element, Hasher, Layout, Length,
+ MouseCursor, Point, Size, Widget,
};
use std::hash::Hash;
@@ -17,16 +18,20 @@ pub mod layer;
pub mod path;
mod drawable;
+mod event;
mod fill;
mod frame;
+mod program;
mod stroke;
mod text;
pub use drawable::Drawable;
+pub use event::Event;
pub use fill::Fill;
pub use frame::Frame;
pub use layer::Layer;
pub use path::Path;
+pub use program::Program;
pub use stroke::{LineCap, LineJoin, Stroke};
pub use text::Text;
@@ -81,31 +86,31 @@ pub use text::Text;
/// }
///
/// // We can use a `Cache` to avoid unnecessary re-tessellation
-/// let cache: layer::Cache<Circle> = layer::Cache::new();
+/// let mut cache: layer::Cache<Circle> = layer::Cache::new();
///
-/// // Finally, we simply provide the data to our `Cache` and push the resulting
-/// // layer into a `Canvas`
-/// let canvas = Canvas::new()
-/// .push(cache.with(&Circle { radius: 50.0 }));
+/// // Finally, we simply use our `Cache` to create the `Canvas`!
+/// let canvas = Canvas::new(&mut cache, &Circle { radius: 50.0 });
/// ```
#[derive(Debug)]
-pub struct Canvas<'a> {
+pub struct Canvas<'a, P: Program> {
width: Length,
height: Length,
- layers: Vec<Box<dyn Layer + 'a>>,
+ program: &'a mut P,
+ input: &'a P::Input,
}
-impl<'a> Canvas<'a> {
+impl<'a, P: Program> Canvas<'a, P> {
const DEFAULT_SIZE: u16 = 100;
/// Creates a new [`Canvas`] with no layers.
///
/// [`Canvas`]: struct.Canvas.html
- pub fn new() -> Self {
+ pub fn new(program: &'a mut P, input: &'a P::Input) -> Self {
Canvas {
width: Length::Units(Self::DEFAULT_SIZE),
height: Length::Units(Self::DEFAULT_SIZE),
- layers: Vec::new(),
+ program,
+ input,
}
}
@@ -124,20 +129,9 @@ impl<'a> Canvas<'a> {
self.height = height;
self
}
-
- /// Adds a [`Layer`] to the [`Canvas`].
- ///
- /// It will be drawn on top of previous layers.
- ///
- /// [`Layer`]: layer/trait.Layer.html
- /// [`Canvas`]: struct.Canvas.html
- pub fn push(mut self, layer: impl Layer + 'a) -> Self {
- self.layers.push(Box::new(layer));
- self
- }
}
-impl<'a, Message> Widget<Message, Renderer> for Canvas<'a> {
+impl<'a, Message, P: Program> Widget<Message, Renderer> for Canvas<'a, P> {
fn width(&self) -> Length {
self.width
}
@@ -157,6 +151,37 @@ impl<'a, Message> Widget<Message, Renderer> for Canvas<'a> {
layout::Node::new(size)
}
+ fn on_event(
+ &mut self,
+ event: iced_native::Event,
+ layout: Layout<'_>,
+ cursor_position: Point,
+ _messages: &mut Vec<Message>,
+ _renderer: &Renderer,
+ _clipboard: Option<&dyn Clipboard>,
+ ) {
+ let bounds = layout.bounds();
+
+ let canvas_event = match event {
+ iced_native::Event::Mouse(mouse_event) => {
+ Some(Event::Mouse(match mouse_event {
+ mouse::Event::CursorMoved { .. } => {
+ mouse::Event::CursorMoved {
+ x: cursor_position.x - bounds.x,
+ y: cursor_position.y - bounds.y,
+ }
+ }
+ _ => mouse_event,
+ }))
+ }
+ _ => None,
+ };
+
+ if let Some(canvas_event) = canvas_event {
+ self.program.update(canvas_event, bounds.size(), self.input)
+ }
+ }
+
fn draw(
&self,
_renderer: &mut Renderer,
@@ -171,7 +196,8 @@ impl<'a, Message> Widget<Message, Renderer> for Canvas<'a> {
(
Primitive::Group {
primitives: self
- .layers
+ .program
+ .layers(self.input)
.iter()
.map(|layer| Primitive::Cached {
origin,
@@ -184,18 +210,20 @@ impl<'a, Message> Widget<Message, Renderer> for Canvas<'a> {
}
fn hash_layout(&self, state: &mut Hasher) {
- std::any::TypeId::of::<Canvas<'static>>().hash(state);
+ struct Marker;
+ std::any::TypeId::of::<Marker>().hash(state);
self.width.hash(state);
self.height.hash(state);
}
}
-impl<'a, Message> From<Canvas<'a>> for Element<'a, Message, Renderer>
+impl<'a, Message, P: Program> From<Canvas<'a, P>>
+ for Element<'a, Message, Renderer>
where
Message: 'static,
{
- fn from(canvas: Canvas<'a>) -> Element<'a, Message, Renderer> {
+ fn from(canvas: Canvas<'a, P>) -> Element<'a, Message, Renderer> {
Element::new(canvas)
}
}
diff --git a/wgpu/src/widget/canvas/drawable.rs b/wgpu/src/widget/canvas/drawable.rs
index 6c74071c..48ba6b4c 100644
--- a/wgpu/src/widget/canvas/drawable.rs
+++ b/wgpu/src/widget/canvas/drawable.rs
@@ -10,3 +10,9 @@ pub trait Drawable {
/// [`Frame`]: struct.Frame.html
fn draw(&self, frame: &mut Frame);
}
+
+impl<'a> Drawable for dyn Fn(&mut Frame) + 'a {
+ fn draw(&self, frame: &mut Frame) {
+ self(frame)
+ }
+}
diff --git a/wgpu/src/widget/canvas/event.rs b/wgpu/src/widget/canvas/event.rs
new file mode 100644
index 00000000..7a8b0829
--- /dev/null
+++ b/wgpu/src/widget/canvas/event.rs
@@ -0,0 +1,6 @@
+use iced_native::input::mouse;
+
+#[derive(Debug, Clone, Copy, PartialEq)]
+pub enum Event {
+ Mouse(mouse::Event),
+}
diff --git a/wgpu/src/widget/canvas/layer/cache.rs b/wgpu/src/widget/canvas/layer/cache.rs
index 4f8c2bec..2e87297c 100644
--- a/wgpu/src/widget/canvas/layer/cache.rs
+++ b/wgpu/src/widget/canvas/layer/cache.rs
@@ -1,5 +1,5 @@
use crate::{
- canvas::{Drawable, Frame, Layer},
+ canvas::{Drawable, Frame, Layer, Program},
Primitive,
};
@@ -79,6 +79,20 @@ where
}
}
+impl<T> Program for Cache<T>
+where
+ T: Drawable + std::fmt::Debug,
+{
+ type Input = T;
+
+ fn layers<'a>(
+ &'a self,
+ input: &'a Self::Input,
+ ) -> Vec<Box<dyn Layer + 'a>> {
+ vec![Box::new(self.with(input))]
+ }
+}
+
#[derive(Debug)]
struct Bind<'a, T: Drawable> {
cache: &'a Cache<T>,
diff --git a/wgpu/src/widget/canvas/program.rs b/wgpu/src/widget/canvas/program.rs
new file mode 100644
index 00000000..c65a078b
--- /dev/null
+++ b/wgpu/src/widget/canvas/program.rs
@@ -0,0 +1,16 @@
+use crate::canvas::{Event, Layer, Size};
+
+pub trait Program {
+ type Input;
+
+ fn layers<'a>(&'a self, input: &'a Self::Input)
+ -> Vec<Box<dyn Layer + 'a>>;
+
+ fn update<'a>(
+ &'a mut self,
+ _event: Event,
+ _bounds: Size,
+ _input: &'a Self::Input,
+ ) {
+ }
+}