Skip to main content

Module live_image

Module live_image 

Source
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§

ImageGeometry
The placement of a source raster in a widget’s box, and the mapping between the box’s points and the source’s pixels.
LiveImage
Shows a LiveImageSource. See the module documentation.
LiveImageDiffWriter
A LiveImageWriter for 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.
LiveImageHandle
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. Clone is an Rc clone; !Send.
LiveImageSource
A raster that producer threads rewrite and any number of windows show.
LiveImageStats
A source’s counters and one attachment’s.
LiveImageWriter
A producer’s handle on a LiveImageSource. Send + Sync; clones share one session token, and the source frees its pixels and becomes Disconnected when the session’s last token drops.
PixelRect
An integer rectangle in source pixels, half-open: x..x + width by y..y + height. Arithmetic on its edges is done in u64, so no combination of fields overflows.

Enums§

ImageFit
How a picture is fitted within its box: the CSS object-fit set.
ImageOrientation
How the stored pixel grid is turned to be displayed upright, with the semantics of the TIFF and EXIF Orientation tag.
LiveImageSizing
How a LiveImage sizes its box. LiveImage::width, LiveImage::height and LiveImage::size pin it and win over the mode.
LiveImageStatus
What a source can show.
LivePixelFormat
The byte order of one pixel: 4 bytes, row-major from the top-left corner, sRGB-encoded colour, straight (not premultiplied) alpha.
ScalingFilter
How a live picture is sampled when it is drawn at another size.