Introduce `Translate` primitive in `iced_wgpu`
This commit is contained in:
parent
2381a9310c
commit
59b1e90661
|
@ -172,12 +172,14 @@ mod bezier {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let mesh = Primitive::Mesh2D {
|
||||
origin: Point::new(bounds.x, bounds.y),
|
||||
buffers: Mesh2D {
|
||||
vertices: buffer.vertices,
|
||||
indices: buffer.indices,
|
||||
},
|
||||
let mesh = Primitive::Translate {
|
||||
translation: Vector::new(bounds.x, bounds.y),
|
||||
content: Box::new(Primitive::Mesh2D {
|
||||
buffers: Mesh2D {
|
||||
vertices: buffer.vertices,
|
||||
indices: buffer.indices,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
(
|
||||
|
|
|
@ -12,7 +12,7 @@ mod rainbow {
|
|||
// implemented by `iced_wgpu` and other renderers.
|
||||
use iced_native::{
|
||||
layout, Element, Hasher, Layout, Length, MouseCursor, Point, Size,
|
||||
Widget,
|
||||
Vector, Widget,
|
||||
};
|
||||
use iced_wgpu::{
|
||||
triangle::{Mesh2D, Vertex2D},
|
||||
|
@ -85,58 +85,60 @@ mod rainbow {
|
|||
let posn_l = [0.0, b.height / 2.0];
|
||||
|
||||
(
|
||||
Primitive::Mesh2D {
|
||||
origin: Point::new(b.x, b.y),
|
||||
buffers: Mesh2D {
|
||||
vertices: vec![
|
||||
Vertex2D {
|
||||
position: posn_center,
|
||||
color: [1.0, 1.0, 1.0, 1.0],
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_tl,
|
||||
color: color_r,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_t,
|
||||
color: color_o,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_tr,
|
||||
color: color_y,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_r,
|
||||
color: color_g,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_br,
|
||||
color: color_gb,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_b,
|
||||
color: color_b,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_bl,
|
||||
color: color_i,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_l,
|
||||
color: color_v,
|
||||
},
|
||||
],
|
||||
indices: vec![
|
||||
0, 1, 2, // TL
|
||||
0, 2, 3, // T
|
||||
0, 3, 4, // TR
|
||||
0, 4, 5, // R
|
||||
0, 5, 6, // BR
|
||||
0, 6, 7, // B
|
||||
0, 7, 8, // BL
|
||||
0, 8, 1, // L
|
||||
],
|
||||
},
|
||||
Primitive::Translate {
|
||||
translation: Vector::new(b.x, b.y),
|
||||
content: Box::new(Primitive::Mesh2D {
|
||||
buffers: Mesh2D {
|
||||
vertices: vec![
|
||||
Vertex2D {
|
||||
position: posn_center,
|
||||
color: [1.0, 1.0, 1.0, 1.0],
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_tl,
|
||||
color: color_r,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_t,
|
||||
color: color_o,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_tr,
|
||||
color: color_y,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_r,
|
||||
color: color_g,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_br,
|
||||
color: color_gb,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_b,
|
||||
color: color_b,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_bl,
|
||||
color: color_i,
|
||||
},
|
||||
Vertex2D {
|
||||
position: posn_l,
|
||||
color: color_v,
|
||||
},
|
||||
],
|
||||
indices: vec![
|
||||
0, 1, 2, // TL
|
||||
0, 2, 3, // T
|
||||
0, 3, 4, // TR
|
||||
0, 4, 5, // R
|
||||
0, 5, 6, // BR
|
||||
0, 6, 7, // B
|
||||
0, 7, 8, // BL
|
||||
0, 8, 1, // L
|
||||
],
|
||||
},
|
||||
}),
|
||||
},
|
||||
MouseCursor::OutOfBounds,
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use iced_native::{
|
||||
image, svg, Background, Color, Font, HorizontalAlignment, Point, Rectangle,
|
||||
image, svg, Background, Color, Font, HorizontalAlignment, Rectangle,
|
||||
Vector, VerticalAlignment,
|
||||
};
|
||||
|
||||
|
@ -70,13 +70,18 @@ pub enum Primitive {
|
|||
/// The content of the clip
|
||||
content: Box<Primitive>,
|
||||
},
|
||||
/// A primitive that applies a translation
|
||||
Translate {
|
||||
/// The top-left coordinate of the mesh
|
||||
translation: Vector,
|
||||
|
||||
/// The primitive to translate
|
||||
content: Box<Primitive>,
|
||||
},
|
||||
/// A low-level primitive to render a mesh of triangles.
|
||||
///
|
||||
/// It can be used to render many kinds of geometry freely.
|
||||
Mesh2D {
|
||||
/// The top-left coordinate of the mesh
|
||||
origin: Point,
|
||||
|
||||
/// The vertex and index buffers of the mesh
|
||||
buffers: triangle::Mesh2D,
|
||||
},
|
||||
|
@ -85,9 +90,6 @@ pub enum Primitive {
|
|||
/// This can be useful if you are implementing a widget where primitive
|
||||
/// generation is expensive.
|
||||
Cached {
|
||||
/// The origin of the coordinate system of the cached primitives
|
||||
origin: Point,
|
||||
|
||||
/// The cached primitive
|
||||
cache: Arc<Primitive>,
|
||||
},
|
||||
|
|
|
@ -29,7 +29,7 @@ pub struct Renderer {
|
|||
struct Layer<'a> {
|
||||
bounds: Rectangle<u32>,
|
||||
quads: Vec<Quad>,
|
||||
meshes: Vec<(Point, &'a triangle::Mesh2D)>,
|
||||
meshes: Vec<(Vector, &'a triangle::Mesh2D)>,
|
||||
text: Vec<wgpu_glyph::Section<'a>>,
|
||||
|
||||
#[cfg(any(feature = "image", feature = "svg"))]
|
||||
|
@ -214,10 +214,10 @@ impl Renderer {
|
|||
border_color: border_color.into_linear(),
|
||||
});
|
||||
}
|
||||
Primitive::Mesh2D { origin, buffers } => {
|
||||
Primitive::Mesh2D { buffers } => {
|
||||
let layer = layers.last_mut().unwrap();
|
||||
|
||||
layer.meshes.push((*origin + translation, buffers));
|
||||
layer.meshes.push((translation, buffers));
|
||||
}
|
||||
Primitive::Clip {
|
||||
bounds,
|
||||
|
@ -249,15 +249,21 @@ impl Renderer {
|
|||
layers.push(new_layer);
|
||||
}
|
||||
}
|
||||
|
||||
Primitive::Cached { origin, cache } => {
|
||||
Primitive::Translate {
|
||||
translation: new_translation,
|
||||
content,
|
||||
} => {
|
||||
self.draw_primitive(
|
||||
translation + Vector::new(origin.x, origin.y),
|
||||
&cache,
|
||||
translation + *new_translation,
|
||||
&content,
|
||||
layers,
|
||||
);
|
||||
}
|
||||
|
||||
Primitive::Cached { cache } => {
|
||||
self.draw_primitive(translation, &cache, layers);
|
||||
}
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
Primitive::Image { handle, bounds } => {
|
||||
let layer = layers.last_mut().unwrap();
|
||||
|
|
|
@ -59,12 +59,12 @@ impl pane_grid::Renderer for Renderer {
|
|||
height: bounds.height + 0.5,
|
||||
},
|
||||
offset: Vector::new(0, 0),
|
||||
content: Box::new(Primitive::Cached {
|
||||
origin: Point::new(
|
||||
content: Box::new(Primitive::Translate {
|
||||
translation: Vector::new(
|
||||
cursor_position.x - bounds.x - bounds.width / 2.0,
|
||||
cursor_position.y - bounds.y - bounds.height / 2.0,
|
||||
),
|
||||
cache: std::sync::Arc::new(pane),
|
||||
content: Box::new(pane),
|
||||
}),
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Draw meshes of triangles.
|
||||
use crate::{settings, Transformation};
|
||||
use iced_native::{Point, Rectangle};
|
||||
use iced_native::{Rectangle, Vector};
|
||||
use std::mem;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
|
@ -201,7 +201,7 @@ impl Pipeline {
|
|||
target_width: u32,
|
||||
target_height: u32,
|
||||
transformation: Transformation,
|
||||
meshes: &[(Point, &Mesh2D)],
|
||||
meshes: &[(Vector, &Mesh2D)],
|
||||
bounds: Rectangle<u32>,
|
||||
) {
|
||||
// This looks a bit crazy, but we are just counting how many vertices
|
||||
|
|
|
@ -10,7 +10,7 @@ use crate::{Defaults, Primitive, Renderer};
|
|||
|
||||
use iced_native::{
|
||||
input::mouse, layout, Clipboard, Element, Hasher, Layout, Length,
|
||||
MouseCursor, Point, Size, Widget,
|
||||
MouseCursor, Point, Size, Vector, Widget,
|
||||
};
|
||||
use std::hash::Hash;
|
||||
|
||||
|
@ -190,20 +190,20 @@ impl<Message, S: State> Widget<Message, Renderer> for Canvas<S> {
|
|||
_cursor_position: Point,
|
||||
) -> (Primitive, MouseCursor) {
|
||||
let bounds = layout.bounds();
|
||||
let origin = Point::new(bounds.x, bounds.y);
|
||||
let translation = Vector::new(bounds.x, bounds.y);
|
||||
let size = Size::new(bounds.width, bounds.height);
|
||||
|
||||
(
|
||||
Primitive::Group {
|
||||
primitives: self
|
||||
.state
|
||||
.draw(size)
|
||||
.into_iter()
|
||||
.map(|geometry| Primitive::Cached {
|
||||
origin,
|
||||
cache: geometry.into_primitive(),
|
||||
})
|
||||
.collect(),
|
||||
Primitive::Translate {
|
||||
translation,
|
||||
content: Box::new(Primitive::Group {
|
||||
primitives: self
|
||||
.state
|
||||
.draw(size)
|
||||
.into_iter()
|
||||
.map(Geometry::into_primitive)
|
||||
.collect(),
|
||||
}),
|
||||
},
|
||||
MouseCursor::Idle,
|
||||
)
|
||||
|
|
|
@ -57,21 +57,27 @@ impl Cache {
|
|||
if let State::Filled { bounds, primitive } = self.state.borrow().deref()
|
||||
{
|
||||
if *bounds == new_bounds {
|
||||
return Geometry::from_primitive(primitive.clone());
|
||||
return Geometry::from_primitive(Primitive::Cached {
|
||||
cache: primitive.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let mut frame = Frame::new(new_bounds);
|
||||
input.draw(&mut frame);
|
||||
|
||||
let primitive = Arc::new(frame.into_primitive());
|
||||
let primitive = {
|
||||
let geometry = frame.into_geometry();
|
||||
|
||||
Arc::new(geometry.into_primitive())
|
||||
};
|
||||
|
||||
*self.state.borrow_mut() = State::Filled {
|
||||
bounds: new_bounds,
|
||||
primitive: primitive.clone(),
|
||||
};
|
||||
|
||||
Geometry::from_primitive(primitive)
|
||||
Geometry::from_primitive(Primitive::Cached { cache: primitive })
|
||||
}
|
||||
|
||||
pub fn with<'a, T>(&'a self, input: T) -> impl crate::canvas::State + 'a
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use iced_native::{Point, Rectangle, Size, Vector};
|
||||
|
||||
use crate::{
|
||||
canvas::{Fill, Path, Stroke, Text},
|
||||
canvas::{Fill, Geometry, Path, Stroke, Text},
|
||||
triangle, Primitive,
|
||||
};
|
||||
|
||||
|
@ -260,13 +260,13 @@ impl Frame {
|
|||
self.transforms.current.is_identity = false;
|
||||
}
|
||||
|
||||
/// Produces the primitive representing everything drawn on the [`Frame`].
|
||||
/// Produces the [`Geometry`] representing everything drawn on the [`Frame`].
|
||||
///
|
||||
/// [`Frame`]: struct.Frame.html
|
||||
pub fn into_primitive(mut self) -> Primitive {
|
||||
/// [`Geometry`]: struct.Geometry.html
|
||||
pub fn into_geometry(mut self) -> Geometry {
|
||||
if !self.buffers.indices.is_empty() {
|
||||
self.primitives.push(Primitive::Mesh2D {
|
||||
origin: Point::ORIGIN,
|
||||
buffers: triangle::Mesh2D {
|
||||
vertices: self.buffers.vertices,
|
||||
indices: self.buffers.indices,
|
||||
|
@ -274,9 +274,9 @@ impl Frame {
|
|||
});
|
||||
}
|
||||
|
||||
Primitive::Group {
|
||||
Geometry::from_primitive(Primitive::Group {
|
||||
primitives: self.primitives,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
use crate::Primitive;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Geometry(Arc<Primitive>);
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Geometry(Primitive);
|
||||
|
||||
impl Geometry {
|
||||
pub(crate) fn from_primitive(primitive: Arc<Primitive>) -> Self {
|
||||
pub(crate) fn from_primitive(primitive: Primitive) -> Self {
|
||||
Self(primitive)
|
||||
}
|
||||
|
||||
pub(crate) fn into_primitive(self) -> Arc<Primitive> {
|
||||
pub fn into_primitive(self) -> Primitive {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Geometry> for Primitive {
|
||||
fn from(geometry: Geometry) -> Primitive {
|
||||
geometry.0
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue