Draw a texture handle as the primitive it is
`Painter::primitive` takes `impl PrimitiveLike`: a primitive, or something that yields one and does whatever else drawing it needs. A `&TextureHandle` yields a `TexturePrimitive` and retains its share on the way through, so `texture`, `texture_within` and `texture_at` are gone and an image is drawn like anything else. I said last round that the blanket impl would collide with the one for `&TextureHandle` under coherence. It does not: `Primitive` is ours, so no crate can add the impl that would overlap, and rustc accepts both. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
01a9b8633d
commit
23fb71ee56
3 files changed
+31
-20
No files matched your search
+1
-1
@@ -9,7 +9,7 @@ mod render_state;
|
|||||||
mod size;
|
mod size;
|
||||||
|
|
||||||
pub use active::*;
|
pub use active::*;
|
||||||
pub use painter::Painter;
|
pub use painter::{Painter, PrimitiveLike};
|
||||||
pub use render_state::*;
|
pub use render_state::*;
|
||||||
pub use size::*;
|
pub use size::*;
|
||||||
|
|
||||||
|
|||||||
+29
-18
@@ -52,11 +52,13 @@ impl<'a> Painter<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Writes a primitive to be rendered
|
/// Writes a primitive to be rendered
|
||||||
pub fn primitive<P: Primitive>(&mut self, primitive: P) {
|
pub fn primitive(&mut self, primitive: impl PrimitiveLike) {
|
||||||
|
let primitive = primitive.into_primitive(self);
|
||||||
self.primitive_at(primitive, self.region)
|
self.primitive_at(primitive, self.region)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn primitive_within<P: Primitive>(&mut self, primitive: P, region: UiRegion) {
|
pub fn primitive_within(&mut self, primitive: impl PrimitiveLike, region: UiRegion) {
|
||||||
|
let primitive = primitive.into_primitive(self);
|
||||||
self.primitive_at(primitive, region.within(&self.region));
|
self.primitive_at(primitive, region.within(&self.region));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,22 +91,6 @@ impl<'a> Painter<'a> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn texture_within(&mut self, handle: &TextureHandle, region: UiRegion) {
|
|
||||||
self.texture_at(handle, region.within(&self.region));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn texture(&mut self, handle: &TextureHandle) {
|
|
||||||
self.texture_at(handle, self.region);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A texture primitive, plus a share of the handle it names -- which a
|
|
||||||
/// `Pod` primitive cannot carry, and without which the slot could be
|
|
||||||
/// freed and reused while still drawn.
|
|
||||||
pub fn texture_at(&mut self, handle: &TextureHandle, region: UiRegion) {
|
|
||||||
self.textures.push(handle.clone());
|
|
||||||
self.primitive_at(TexturePrimitive::from(handle), region);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_text(
|
pub fn render_text(
|
||||||
&mut self,
|
&mut self,
|
||||||
buffer: &mut TextBuffer,
|
buffer: &mut TextBuffer,
|
||||||
@@ -185,3 +171,28 @@ impl<'a> Painter<'a> {
|
|||||||
self.state.size_ctx(self.id, self.region.size(), self.rsc)
|
self.state.size_ctx(self.id, self.region.size(), self.rsc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// What `Painter::primitive` takes: a primitive, or something that yields one
|
||||||
|
/// and does whatever else drawing it needs.
|
||||||
|
pub trait PrimitiveLike {
|
||||||
|
type Primitive: Primitive;
|
||||||
|
fn into_primitive(self, painter: &mut Painter) -> Self::Primitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: Primitive> PrimitiveLike for P {
|
||||||
|
type Primitive = P;
|
||||||
|
fn into_primitive(self, _: &mut Painter) -> P {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrimitiveLike for &TextureHandle {
|
||||||
|
type Primitive = TexturePrimitive;
|
||||||
|
|
||||||
|
/// Retains a share of the handle, so the slot the primitive names cannot
|
||||||
|
/// be freed and reused while it is still drawn.
|
||||||
|
fn into_primitive(self, painter: &mut Painter) -> TexturePrimitive {
|
||||||
|
painter.textures.push(self.clone());
|
||||||
|
self.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -7,7 +7,7 @@ pub struct Image {
|
|||||||
|
|
||||||
impl Widget for Image {
|
impl Widget for Image {
|
||||||
fn draw(&mut self, painter: &mut Painter) {
|
fn draw(&mut self, painter: &mut Painter) {
|
||||||
painter.texture(&self.handle);
|
painter.primitive(&self.handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn desired_width(&mut self, _: &mut SizeCtx) -> Len {
|
fn desired_width(&mut self, _: &mut SizeCtx) -> Len {
|
||||||
|
|||||||
Reference in new issue
Block a user