GPUI Box GitHub

Components / content

ImageViewer builder

A framed viewer for one image at a time.

A builder is RenderOnce. Construct and mount it in one expression.

use gpui_kit::content::ImageViewer;

Reviewed in image-viewer.

Construct
new(ident: impl Into<Ident>, frames: impl IntoIterator<Item = ImageFrame>) -> Self
Options

Chain onto the value.

showing(id: impl Into<SharedString>) -> Self
fit(fit: FitMode) -> Self
zoom_range(min: f32, max: f32) -> Self
height(height: f32) -> Self
image(supplier: impl Fn(&ImageFrame, &mut Window, &mut App) -> Option<AnyElement> + 'static) -> Self
on_event(handler: impl Fn(&ImageViewerEvent, &mut Window, &mut App) + 'static) -> Self
Reports

The variants of the event it emits. It never applies the change itself.

  • FitChanged
  • Stepped
  • ImageRequested
Example · image-viewer
fn image_viewer(window: &mut Window, cx: &mut App) -> AnyElement {
    let theme = cx.theme().clone();
    let state = crate::motion::keyed::slot::<(FitMode, Option<SharedString>)>(
        &"scene.image.controlled".into(),
        window.window_handle().window_id(),
        cx,
    );
    let (fit, showing) = state.borrow().clone();
    stack(&theme)
        .w(px(860.0))
        .child(
            div()
                .row()
                .items_start()
                .gap(px(theme.spacing.lg))
                .child(
                    div().w(px(396.0)).child(
                        ImageViewer::new(
                            "scene.image.ready",
                            [
                                ImageFrame::new("graph", "The run graph")
                                    .source("runs/graph.png")
                                    .natural(1600, 900),
                                ImageFrame::new("trace", "The failing trace")
                                    .source("runs/trace.png")
                                    .natural(1200, 1200),
                            ],
                        )
                        .showing(showing.unwrap_or_else(|| "graph".into()))
                        .fit(fit)
                        .control_size(gpui_kit_theme::ControlSize::Touch)
                        .height(200.0)
                        .image(|_, _, cx| Some(run_graph_picture(cx)))
                        .on_event(move |event, window, _| {
                            match event {
                                ImageViewerEvent::FitChanged(fit) => state.borrow_mut().0 = *fit,
                                ImageViewerEvent::Stepped { id } => state.borrow_mut().1 = Some(id.clone()),
                                _ => return,
                            }
                            window.refresh();
                        }),
                    ),
                )
                .child(
                    div().w(px(396.0)).child(
                        ImageViewer::new(
                            "scene.image.refused",
                            [ImageFrame::new("scan", "Page 4 of the scan")
                                .source("scans/page-4.tiff")
                                .natural(2480, 3508)
                                .unavailable("The workspace is frozen for the release.")],
                        )
                        .height(200.0)
                        .image(|_, _, cx| Some(scene_picture("Supplied by the host", cx)))
                        .on_event(|_, _, _| {}),
                    ),
                ),
        )
        .child(
            Divider::new()
                .id("scene.image.rule.unmeasured")
                .label("A size the host never stated"),
        )
        .child(
            div().row().items_start().gap(px(theme.spacing.lg)).child(div().w(px(396.0)).child(
                ImageViewer::new(
                    "scene.image.unmeasured",
                    [ImageFrame::new("sketch", "A pasted sketch").source("clipboard")],
                )
                .height(200.0)
                .image(|_, _, cx| Some(pasted_workflow_picture(cx)))
                .on_event(|_, _, _| {}),
            )).child(div().w(px(396.0)).child(
                ImageViewer::new("scene.image.zoom-refused", [ImageFrame::new("graph", "Zoom retained by host").natural(1600, 900)])
                    .fit(FitMode::Zoom(0.5))
                    .control_size(gpui_kit_theme::ControlSize::Touch)
                    .height(200.0)
                    .image(|_, _, cx| Some(pasted_workflow_picture(cx)))
                    .on_event(|_, _, _| {}),
            )),
        )
        .child(caption(&theme, "Fixture: the run graph accepts zoom and stepping; Zoom retained by host refuses fit changes; the scan refuses image access."))
        .into_any_element()
}

Source: crates/gpui-kit/src/content/image_viewer.rs