pub struct TextureUi { /* private fields */ }Expand description
A Telar UI composed into an application-owned texture. See the module docs.
Implementations§
Source§impl TextureUi
impl TextureUi
Sourcepub fn new(
target: Texture,
scale: f32,
build: impl FnOnce() -> Result<Box<dyn LayoutItem>, LayoutError>,
) -> Result<Self, TextureUiError>
pub fn new( target: Texture, scale: f32, build: impl FnOnce() -> Result<Box<dyn LayoutItem>, LayoutError>, ) -> Result<Self, TextureUiError>
Builds a UI that composes into target.
build runs with this UI’s surface active, so the content’s layout nodes, overlays and effects are
allocated in its world rather than in whatever surface happened to be active.
scale is the target’s device-pixel ratio: the tree is laid out at target size / scale logical
pixels and drawn at the target’s pixel size. Pass 1.0 for a target whose pixels are its layout
units — a 320×180 sprite, say.
Requirements on target: it must come from the device Telar lends
(gpu::shared) and carry RENDER_ATTACHMENT usage; its format decides the
format this renderer’s pipelines are built against, so it must be renderable and blendable. The
application keeps ownership in every sense that matters — it decides the size, the format and when
the contents change; Telar only draws into it when asked.
Sourcepub fn with_fonts(
target: Texture,
scale: f32,
font_paths: Vec<PathBuf>,
font_data: Vec<Vec<u8>>,
build: impl FnOnce() -> Result<Box<dyn LayoutItem>, LayoutError>,
) -> Result<Self, TextureUiError>
pub fn with_fonts( target: Texture, scale: f32, font_paths: Vec<PathBuf>, font_data: Vec<Vec<u8>>, build: impl FnOnce() -> Result<Box<dyn LayoutItem>, LayoutError>, ) -> Result<Self, TextureUiError>
new carrying faces of its own — font_paths on disk and font_data embedded — in the
same shape AppConfig takes them. The reason to reach for it is a face drawn on
a pixel grid, to pair with GlyphRaster::Pixel.
Loading a face is not choosing it. These go into the font database; which one the text actually
shapes with is the process-wide default family, so a caller that wants its own face has to name it
with set_default_font_family before building this — otherwise
the face is loaded and the platform’s own is drawn, which looks like the file failed to load and did
not.
Two things follow from that default being process-wide. Only the first renderer in the process
settles the shared text shaper, so a UI built after a window is already open draws with the window’s
faces and these are ignored — a face meant for both belongs in the app config. And there is one
family per process: a pixel face here and a different one in the window around it is not expressible
today, because TextStyle has no family axis.
Sourcepub fn set_clear_color(&mut self, clear_color: Color)
pub fn set_clear_color(&mut self, clear_color: Color)
The colour Telar’s own frame starts from before the tree draws, blended into the application’s texture afterwards. Transparent by default, which is what composing into a picture means; an opaque colour makes the UI own every pixel of the target instead.
A colour and not an Option: “keep what was there” is what the blend already does, and asking the
frame’s own target to load instead would read a multisample surface the previous resolve discarded.
Sourcepub fn resize(&mut self, target: Texture, scale: f32)
pub fn resize(&mut self, target: Texture, scale: f32)
Points the UI at a new texture and re-lays the tree out — how an application resizes it.
The new texture must match the format of the one this UI was built with; a different format needs a
new TextureUi, because the render pipelines bake it in.
Sourcepub fn place_in(&mut self, dest: Rect)
pub fn place_in(&mut self, dest: Rect)
Where the texture is shown, as the rectangle it occupies in the window — the other half of
resize, and what makes a pointer land where the user sees it.
Only the application knows this: it is the one that decided where to draw the texture and how to fit it. Without it the pointer arrives in window coordinates and hit-testing drifts from the picture by exactly the offset and zoom of the placement.
Sourcepub fn set_placement(&mut self, placement: Transform)
pub fn set_placement(&mut self, placement: Transform)
place_in for a placement the application composed itself — a rotation, a flip, a
transform it already holds. Maps a point in the UI’s logical space to a point in the window.
Sourcepub fn enter(&self) -> SurfaceGuard
pub fn enter(&self) -> SurfaceGuard
Activates this UI’s world — its layout tree, overlay registry, focus and services — for as long as the guard lives.
Anything that touches those has to happen inside it: they are this UI’s, and outside it the ambient ones a window tree uses are what answer. Building a widget to hand to this tree, reading a node’s rect, opening one of its overlays.
Sourcepub fn logical_size(&self) -> (f32, f32)
pub fn logical_size(&self) -> (f32, f32)
The UI’s logical size: the target’s pixels divided by its scale, which is the box the tree lays out
against and the space on_event delivers pointers in.
Sourcepub fn is_dirty(&self) -> bool
pub fn is_dirty(&self) -> bool
Whether the composition changed since the last render — the gate an application
uses to skip re-composing a frame that would come out identical.
Sourcepub fn on_event(&mut self, event: &Event) -> bool
pub fn on_event(&mut self, event: &Event) -> bool
Routes an event into the UI, mapping pointer coordinates back through the placement.
true means the UI consumed it and the application should not act on it as well. Non-pointer events
(keys, focus) pass through untransformed; the application decides which of them this UI should see at
all, which is the only honest answer when several trees share one window’s keyboard.
Sourcepub fn render(&mut self) -> Result<(), RendererError>
pub fn render(&mut self) -> Result<(), RendererError>
Composes one frame and blends it into the application’s texture.
Blends, rather than replaces: whatever the application drew there survives wherever the UI did not paint. Call it after the application has filled the texture for this frame, and again whenever it refills it — Telar draws when asked and never on its own.
Animations and background work are not advanced here. The motion engine and the task registry are
per-thread, and a windowed application’s runner already drives them for every tree on that thread;
a windowless one drives them itself, with motion::tick and
drain_tasks, exactly as it drives this.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for TextureUi
impl !RefUnwindSafe for TextureUi
impl !Send for TextureUi
impl !Sync for TextureUi
impl !UnwindSafe for TextureUi
impl Unpin for TextureUi
impl UnsafeUnpin for TextureUi
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more