Expand description
LiveImage — shows a picture another thread rewrites many times a second.
A virtual machine’s screen, a video frame, a camera preview: the pixels
never pass through the widget. A producer writes a
LiveImageSource from any thread through a LiveImageWriter; the
window’s renderer uploads what changed since its last frame and draws it
where this widget’s last paint put it. A commit that changes only pixels
runs no paint(), marks no widget and repaints nothing else: the window
replays its cached frame. Only a change of the source’s size or status
(resized, Waiting, Live, Disconnected) relayouts and repaints this
widget. A producer that hands over whole frames, changed or not, writes
through a LiveImageDiffWriter instead, which commits only what changed
and nothing for an identical frame.
§Sizing
LiveImageSizing picks the box: Aspect (the default) is the largest
box with the picture’s aspect ratio inside the proposal, rounded to whole
device pixels; Fill takes the whole proposal and letterboxes; Natural
is one source pixel per logical pixel (device_pixels
makes it one per device pixel). width,
height and size pin the box
and win over the mode. Inside the box the picture is placed by an
ImageFit and an [Alignment], turned by an ImageOrientation, and
its edges snap to the device-pixel grid.
use teksilo_widgets::primitives::live_image::{LiveImage, LiveImageSizing};
use teksilo_widgets::primitives::live_image::{LiveImageSource, LivePixelFormat};
use teksilo_widgets::primitives::ImageFit;
let screen = LiveImageSource::new(LivePixelFormat::Bgrx8);
let writer = screen.writer();
// The producer keeps its writer: when the last one drops, the source
// frees its pixels and the picture goes.
std::thread::spawn(move || loop {
let frame = vec![0u8; 720 * 1280 * 4]; // the guest's next frame
writer.write_frame(720, 1280, &frame, 720 * 4).unwrap();
std::thread::sleep(std::time::Duration::from_millis(16));
});
let _view = LiveImage::new(screen)
.sizing(LiveImageSizing::Aspect)
.fit(ImageFit::Contain)
.alt("Virtual machine screen");§Input
LiveImage handles no input. An app that forwards pointer input to what
the picture shows attaches its handlers through WidgetBuilder and maps
the positions they receive with the widget’s LiveImageHandle, taken
before a WidgetBuilder method wraps the widget (or injected with
with_handle):
map_to_source gives the source pixel
a point shows, from the same placement paint drew. A position handed in
window space (Scroll::window_position) goes through
EventContext::to_local first.
§Accessibility
One Role::Image node named by alt; a decorative
picture calls a11y_hidden instead. Pixels are
not accessible content, and a commit never changes the node: only a
status change does, when the placeholder
becomes or stops being its description.
Structs§
- Image
Geometry - The placement of a source raster in a widget’s box, and the mapping between the box’s points and the source’s pixels.
- Live
Image - Shows a
LiveImageSource. See the module documentation. - Live
Image Diff Writer - A
LiveImageWriterfor a producer that redraws, or copies, a whole frame every time, whether or not anything in it moved: a VM’s framebuffer copied at each vsync, a remote desktop’s screen, a renderer with no damage tracking of its own. - Live
Image Handle - A handle to a
LiveImage, for the UI thread: the size and status of what it shows, where it shows it, and the mapping between its points and the source’s pixels.Cloneis anRcclone;!Send. - Live
Image Source - A raster that producer threads rewrite and any number of windows show.
- Live
Image Stats - A source’s counters and one attachment’s.
- Live
Image Writer - A producer’s handle on a
LiveImageSource.Send + Sync; clones share one session token, and the source frees its pixels and becomesDisconnectedwhen the session’s last token drops. - Pixel
Rect - An integer rectangle in source pixels, half-open:
x..x + widthbyy..y + height. Arithmetic on its edges is done inu64, so no combination of fields overflows.
Enums§
- Image
Fit - How a picture is fitted within its box: the CSS
object-fitset. - Image
Orientation - How the stored pixel grid is turned to be displayed upright, with the
semantics of the TIFF and EXIF
Orientationtag. - Live
Image Sizing - How a
LiveImagesizes its box.LiveImage::width,LiveImage::heightandLiveImage::sizepin it and win over the mode. - Live
Image Status - What a source can show.
- Live
Pixel Format - The byte order of one pixel: 4 bytes, row-major from the top-left corner, sRGB-encoded colour, straight (not premultiplied) alpha.
- Scaling
Filter - How a live picture is sampled when it is drawn at another size.