summaryrefslogtreecommitdiffstats
path: root/renderer
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2023-11-14 12:49:49 +0100
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2023-11-14 12:49:49 +0100
commit9489e29e6619b14ed9f41a8887c4b34158266f71 (patch)
tree34b574112df5f2e63dff66d3a01e470077ce7c9b /renderer
parent2dda9132cda6d2a2279759f3447bae4e1c277555 (diff)
downloadiced-9489e29e6619b14ed9f41a8887c4b34158266f71.tar.gz
iced-9489e29e6619b14ed9f41a8887c4b34158266f71.tar.bz2
iced-9489e29e6619b14ed9f41a8887c4b34158266f71.zip
Re-organize `custom` module as `pipeline` module
... and move `Shader` widget to `iced_widget` crate
Diffstat (limited to 'renderer')
-rw-r--r--renderer/src/lib.rs44
-rw-r--r--renderer/src/widget.rs2
-rw-r--r--renderer/src/widget/shader.rs219
-rw-r--r--renderer/src/widget/shader/event.rs25
-rw-r--r--renderer/src/widget/shader/program.rs60
5 files changed, 23 insertions, 327 deletions
diff --git a/renderer/src/lib.rs b/renderer/src/lib.rs
index e4b1eda9..1fc4c86b 100644
--- a/renderer/src/lib.rs
+++ b/renderer/src/lib.rs
@@ -1,13 +1,15 @@
#![forbid(rust_2018_idioms)]
#![deny(unsafe_code, unused_results, rustdoc::broken_intra_doc_links)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+#[cfg(feature = "wgpu")]
+pub use iced_wgpu as wgpu;
+
pub mod compositor;
#[cfg(feature = "geometry")]
pub mod geometry;
mod settings;
-pub mod widget;
pub use iced_graphics as graphics;
pub use iced_graphics::core;
@@ -60,26 +62,6 @@ impl<T> Renderer<T> {
}
}
}
-
- pub fn draw_custom<P: widget::shader::Primitive>(
- &mut self,
- bounds: Rectangle,
- primitive: P,
- ) {
- match self {
- Renderer::TinySkia(_) => {
- log::warn!(
- "Custom shader primitive is unavailable with tiny-skia."
- );
- }
- #[cfg(feature = "wgpu")]
- Renderer::Wgpu(renderer) => {
- renderer.draw_primitive(iced_wgpu::Primitive::Custom(
- iced_wgpu::primitive::Custom::shader(bounds, primitive),
- ));
- }
- }
- }
}
impl<T> core::Renderer for Renderer<T> {
@@ -292,3 +274,23 @@ impl<T> crate::graphics::geometry::Renderer for Renderer<T> {
}
}
}
+
+#[cfg(feature = "wgpu")]
+impl<T> iced_wgpu::primitive::pipeline::Renderer for Renderer<T> {
+ fn draw_pipeline_primitive(
+ &mut self,
+ bounds: Rectangle,
+ primitive: impl wgpu::primitive::pipeline::Primitive,
+ ) {
+ match self {
+ Self::TinySkia(_renderer) => {
+ log::warn!(
+ "Custom shader primitive is unavailable with tiny-skia."
+ );
+ }
+ Self::Wgpu(renderer) => {
+ renderer.draw_pipeline_primitive(bounds, primitive);
+ }
+ }
+ }
+}
diff --git a/renderer/src/widget.rs b/renderer/src/widget.rs
deleted file mode 100644
index 4b7dad5d..00000000
--- a/renderer/src/widget.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-#[cfg(feature = "wgpu")]
-pub mod shader;
diff --git a/renderer/src/widget/shader.rs b/renderer/src/widget/shader.rs
deleted file mode 100644
index e218f35a..00000000
--- a/renderer/src/widget/shader.rs
+++ /dev/null
@@ -1,219 +0,0 @@
-//! A custom shader widget for wgpu applications.
-use crate::core::event::Status;
-use crate::core::layout::{Limits, Node};
-use crate::core::mouse::{Cursor, Interaction};
-use crate::core::renderer::Style;
-use crate::core::widget::tree::{State, Tag};
-use crate::core::widget::{tree, Tree};
-use crate::core::{
- self, layout, mouse, widget, window, Clipboard, Element, Layout, Length,
- Rectangle, Shell, Size, Widget,
-};
-use std::marker::PhantomData;
-
-mod event;
-mod program;
-
-pub use event::Event;
-pub use iced_graphics::Transformation;
-pub use iced_wgpu::custom::Primitive;
-pub use iced_wgpu::custom::Storage;
-pub use program::Program;
-
-/// A widget which can render custom shaders with Iced's `wgpu` backend.
-///
-/// Must be initialized with a [`Program`], which describes the internal widget state & how
-/// its [`Program::Primitive`]s are drawn.
-#[allow(missing_debug_implementations)]
-pub struct Shader<Message, P: Program<Message>> {
- width: Length,
- height: Length,
- program: P,
- _message: PhantomData<Message>,
-}
-
-impl<Message, P: Program<Message>> Shader<Message, P> {
- /// Create a new custom [`Shader`].
- pub fn new(program: P) -> Self {
- Self {
- width: Length::Fixed(100.0),
- height: Length::Fixed(100.0),
- program,
- _message: PhantomData,
- }
- }
-
- /// Set the `width` of the custom [`Shader`].
- pub fn width(mut self, width: impl Into<Length>) -> Self {
- self.width = width.into();
- self
- }
-
- /// Set the `height` of the custom [`Shader`].
- pub fn height(mut self, height: impl Into<Length>) -> Self {
- self.height = height.into();
- self
- }
-}
-
-impl<P, Message, Theme> Widget<Message, crate::Renderer<Theme>>
- for Shader<Message, P>
-where
- P: Program<Message>,
-{
- fn tag(&self) -> Tag {
- struct Tag<T>(T);
- tree::Tag::of::<Tag<P::State>>()
- }
-
- fn state(&self) -> State {
- tree::State::new(P::State::default())
- }
-
- fn width(&self) -> Length {
- self.width
- }
-
- fn height(&self) -> Length {
- self.height
- }
-
- fn layout(
- &self,
- _tree: &mut Tree,
- _renderer: &crate::Renderer<Theme>,
- limits: &Limits,
- ) -> Node {
- let limits = limits.width(self.width).height(self.height);
- let size = limits.resolve(Size::ZERO);
-
- layout::Node::new(size)
- }
-
- fn on_event(
- &mut self,
- tree: &mut Tree,
- event: crate::core::Event,
- layout: Layout<'_>,
- cursor: Cursor,
- _renderer: &crate::Renderer<Theme>,
- _clipboard: &mut dyn Clipboard,
- shell: &mut Shell<'_, Message>,
- _viewport: &Rectangle,
- ) -> Status {
- let bounds = layout.bounds();
-
- let custom_shader_event = match event {
- core::Event::Mouse(mouse_event) => Some(Event::Mouse(mouse_event)),
- core::Event::Keyboard(keyboard_event) => {
- Some(Event::Keyboard(keyboard_event))
- }
- core::Event::Touch(touch_event) => Some(Event::Touch(touch_event)),
- core::Event::Window(window::Event::RedrawRequested(instant)) => {
- Some(Event::RedrawRequested(instant))
- }
- _ => None,
- };
-
- if let Some(custom_shader_event) = custom_shader_event {
- let state = tree.state.downcast_mut::<P::State>();
-
- let (event_status, message) = self.program.update(
- state,
- custom_shader_event,
- bounds,
- cursor,
- shell,
- );
-
- if let Some(message) = message {
- shell.publish(message);
- }
-
- return event_status;
- }
-
- event::Status::Ignored
- }
-
- fn mouse_interaction(
- &self,
- tree: &Tree,
- layout: Layout<'_>,
- cursor: Cursor,
- _viewport: &Rectangle,
- _renderer: &crate::Renderer<Theme>,
- ) -> mouse::Interaction {
- let bounds = layout.bounds();
- let state = tree.state.downcast_ref::<P::State>();
-
- self.program.mouse_interaction(state, bounds, cursor)
- }
-
- fn draw(
- &self,
- tree: &widget::Tree,
- renderer: &mut crate::Renderer<Theme>,
- _theme: &Theme,
- _style: &Style,
- layout: Layout<'_>,
- cursor_position: mouse::Cursor,
- _viewport: &Rectangle,
- ) {
- let bounds = layout.bounds();
- let state = tree.state.downcast_ref::<P::State>();
-
- renderer.draw_custom(
- bounds,
- self.program.draw(state, cursor_position, bounds),
- );
- }
-}
-
-impl<'a, M, P, Theme> From<Shader<M, P>>
- for Element<'a, M, crate::Renderer<Theme>>
-where
- M: 'a,
- P: Program<M> + 'a,
-{
- fn from(custom: Shader<M, P>) -> Element<'a, M, crate::Renderer<Theme>> {
- Element::new(custom)
- }
-}
-
-impl<Message, T> Program<Message> for &T
-where
- T: Program<Message>,
-{
- type State = T::State;
- type Primitive = T::Primitive;
-
- fn update(
- &self,
- state: &mut Self::State,
- event: Event,
- bounds: Rectangle,
- cursor: Cursor,
- shell: &mut Shell<'_, Message>,
- ) -> (Status, Option<Message>) {
- T::update(self, state, event, bounds, cursor, shell)
- }
-
- fn draw(
- &self,
- state: &Self::State,
- cursor: Cursor,
- bounds: Rectangle,
- ) -> Self::Primitive {
- T::draw(self, state, cursor, bounds)
- }
-
- fn mouse_interaction(
- &self,
- state: &Self::State,
- bounds: Rectangle,
- cursor: Cursor,
- ) -> Interaction {
- T::mouse_interaction(self, state, bounds, cursor)
- }
-}
diff --git a/renderer/src/widget/shader/event.rs b/renderer/src/widget/shader/event.rs
deleted file mode 100644
index 8901fb31..00000000
--- a/renderer/src/widget/shader/event.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-//! Handle events of a custom shader widget.
-use crate::core::keyboard;
-use crate::core::mouse;
-use crate::core::touch;
-use std::time::Instant;
-
-pub use crate::core::event::Status;
-
-/// A [`Shader`] event.
-///
-/// [`Shader`]: crate::widget::shader::Shader;
-#[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),
-
- /// A window requested a redraw.
- RedrawRequested(Instant),
-}
diff --git a/renderer/src/widget/shader/program.rs b/renderer/src/widget/shader/program.rs
deleted file mode 100644
index b8871688..00000000
--- a/renderer/src/widget/shader/program.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-use crate::core::{event, mouse, Rectangle, Shell};
-use crate::widget;
-use widget::shader;
-
-/// The state and logic of a [`Shader`] widget.
-///
-/// A [`Program`] can mutate the internal state of a [`Shader`] widget
-/// and produce messages for an application.
-///
-/// [`Shader`]: crate::widget::shader::Shader
-pub trait Program<Message> {
- /// The internal state of the [`Program`].
- type State: Default + 'static;
-
- /// The type of primitive this [`Program`] can draw.
- type Primitive: shader::Primitive + 'static;
-
- /// Update the internal [`State`] of the [`Program`]. This can be used to reflect state changes
- /// based on mouse & other events. You can use the [`Shell`] to publish messages, request a
- /// redraw for the window, etc.
- ///
- /// By default, this method does and returns nothing.
- ///
- /// [`State`]: Self::State
- fn update(
- &self,
- _state: &mut Self::State,
- _event: shader::Event,
- _bounds: Rectangle,
- _cursor: mouse::Cursor,
- _shell: &mut Shell<'_, Message>,
- ) -> (event::Status, Option<Message>) {
- (event::Status::Ignored, None)
- }
-
- /// Draws the [`Primitive`].
- ///
- /// [`Primitive`]: Self::Primitive
- fn draw(
- &self,
- state: &Self::State,
- cursor: mouse::Cursor,
- bounds: Rectangle,
- ) -> Self::Primitive;
-
- /// 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 [`Shader`]'s program.
- ///
- /// [`Shader`]: crate::widget::shader::Shader
- fn mouse_interaction(
- &self,
- _state: &Self::State,
- _bounds: Rectangle,
- _cursor: mouse::Cursor,
- ) -> mouse::Interaction {
- mouse::Interaction::default()
- }
-}