Add screenshots to documentation (#832)

Create include_screenshot macro
This commit is contained in:
Olivier FAURE 2025-01-23 18:21:53 +00:00 committed by GitHub
parent 8342d8f3d5
commit df3107e1d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 103 additions and 9 deletions

View File

@ -414,7 +414,7 @@ mod tests {
fn screenshot_test() {
let mut harness = TestHarness::create(build_calc());
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "calc");
assert_render_snapshot!(harness, "initial_screenshot");
// TODO - Test clicking buttons
}

View File

@ -193,6 +193,6 @@ mod tests {
let mut harness = TestHarness::create(CustomWidget(my_string));
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "custom_widget");
assert_render_snapshot!(harness, "initial_screenshot");
}
}

View File

@ -140,7 +140,7 @@ mod tests {
fn screenshot_test() {
let mut harness = TestHarness::create(make_grid(1.0));
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "grid_masonry");
assert_render_snapshot!(harness, "initial_screenshot");
// TODO - Test clicking buttons
}

View File

@ -1,7 +1,44 @@
# Masonry examples
TODO:
## `hello_masonry`
- List examples in this folder
- Add screenshot test to each example
- Use the screenshot in this list
Simples possible Masonry app.
## `two_textboxes`
Example used to test text input and text focus.
## `calc_masonry`
![](screenshots/calc_masonry__tests__initial_screenshot.png)
Calculator app.
## `to_do_list`
![](screenshots/to_do_list__tests__initial_screenshot.png)
To-do list app.
## `custom_widget`
![](screenshots/custom_widget__tests__initial_screenshot.png)
Static render showing off Vello's capabilities.
## `grid_masonry`
![](screenshots/grid_masonry__tests__initial_screenshot.png)
Demonstration of the grid layout.
## `simple_image`
![](screenshots/simple_image__tests__initial_screenshot.png)
Simple image example.

View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -63,6 +63,6 @@ mod tests {
fn screenshot_test() {
let mut harness = TestHarness::create(make_image());
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "grid_masonry");
assert_render_snapshot!(harness, "initial_screenshot");
}
}

View File

@ -88,7 +88,7 @@ mod tests {
fn screenshot_test() {
let mut harness = TestHarness::create(make_widget_tree());
assert_debug_snapshot!(harness.root_widget());
assert_render_snapshot!(harness, "to_do_list");
assert_render_snapshot!(harness, "initial_screenshot");
// TODO - Test clicking buttons
// TODO - Test typing text

View File

@ -96,6 +96,8 @@
//! [Druid]: https://crates.io/crates/druid
//! [Xilem]: https://crates.io/crates/xilem
//! [tracing_tracy]: https://crates.io/crates/tracing-tracy
// TODO: Add screenshot. This can't use include_screenshot as that doesn't work with cargo-rdme
// See https://github.com/linebender/xilem/issues/851
// LINEBENDER LINT SET - lib.rs - v1
// See https://linebender.org/wiki/canonical-lints/

View File

@ -6,6 +6,33 @@
use image::{GenericImageView as _, RgbImage};
use nv_flip::{FlipImageRgb8, DEFAULT_PIXELS_PER_DEGREE};
#[cfg(docsrs)]
#[doc(hidden)]
#[macro_export]
macro_rules! include_screenshot {
($path:literal $(, $caption:literal)? $(,)?) => {
concat!(
"![", $($caption,)? "]",
"(", "https://media.githubusercontent.com/media/linebender/xilem/",
"masonry-v", env!("CARGO_PKG_VERSION"), "/masonry/src/", $path,
")",
)
};
}
#[cfg(not(docsrs))]
#[doc(hidden)]
#[macro_export]
/// Macro used to create markdown img tag, with a different URL when uploading to docs.rs.
macro_rules! include_screenshot {
($path:literal $(, $caption:literal)? $(,)?) => {
concat!(
"![", $($caption,)? "]",
"(", env!("CARGO_MANIFEST_DIR"), "/src/", $path, ")",
)
};
}
pub(crate) fn get_image_diff(ref_image: &RgbImage, new_image: &RgbImage) -> Option<RgbImage> {
assert_eq!(
(ref_image.width(), ref_image.height()),

View File

@ -24,6 +24,8 @@ use crate::{
// TODO - Have child widget type as generic argument
/// A widget that aligns its child.
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__align__tests__right.png", "Right-aligned label.")]
pub struct Align {
align: UnitPoint,
child: WidgetPod<dyn Widget>,

View File

@ -26,6 +26,8 @@ const LABEL_INSETS: Insets = Insets::uniform_xy(8., 2.);
/// A button with a text label.
///
/// Emits [`Action::ButtonPressed`] when pressed.
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__button__tests__hello.png", "Button with text label.")]
pub struct Button {
label: WidgetPod<Label>,
}

View File

@ -19,6 +19,8 @@ use crate::{
};
/// A checkbox that can be toggled.
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__checkbox__tests__hello_checked.png", "Checkbox with checked state.")]
pub struct Checkbox {
checked: bool,
label: WidgetPod<Label>,

View File

@ -19,6 +19,8 @@ use crate::{
/// A container with either horizontal or vertical layout.
///
/// This widget is the foundation of most layouts, and is highly configurable.
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceAround.png", "Flex column with multiple labels.")]
pub struct Flex {
direction: Axis,
cross_alignment: CrossAxisAlignment,

View File

@ -13,6 +13,9 @@ use crate::{
QueryCtx, Size, TextEvent, Widget, WidgetId, WidgetPod,
};
/// A widget that arranges its children in a grid.
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__grid__tests__with_changed_spacing.png", "Grid with buttons of various sizes.")]
pub struct Grid {
children: Vec<Child>,
grid_width: i32,

View File

@ -42,6 +42,8 @@ pub enum LineBreaking {
///
/// This is useful for creating interactive widgets which internally
/// need support for displaying text, such as a button.
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__label__tests__styled_label.png", "Styled label.")]
pub struct Label {
text_layout: Layout<BrushIndex>,
accessibility: LayoutAccessibility,

View File

@ -18,6 +18,8 @@ use crate::{
};
/// A progress bar.
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__progress_bar__tests__25_percent_progressbar.png", "25% progress bar.")]
pub struct ProgressBar {
/// A value in the range `[0, 1]` inclusive, where 0 is 0% and 1 is 100% complete.
///

View File

@ -36,6 +36,8 @@ const PROSE_PADDING: Padding = Padding::horizontal(2.0);
/// as it enables users to copy/paste from the text.
///
/// This widget has no actions.
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__prose__tests__prose_alignment_flex.png", "Multiple lines with different alignments.")]
pub struct Prose {
text: WidgetPod<TextArea<false>>,

View File

@ -24,6 +24,9 @@ use crate::{
// - Document names
// - Document invariants
/// A scrollbar.
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_default.png", "Vertical scrollbar.")]
pub struct ScrollBar {
axis: Axis,
pub(crate) cursor_progress: f64,

View File

@ -56,6 +56,8 @@ pub struct Padding {
/// If not given a child, `SizedBox` will try to size itself as close to the specified height
/// and width as possible given the parent's constraints. If height or width is not set,
/// it will be treated as zero.
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__sized_box__tests__label_box_with_outer_padding.png", "Box with blue border, pink background and a child label.")]
pub struct SizedBox {
child: Option<WidgetPod<dyn Widget>>,
width: Option<f64>,

View File

@ -24,6 +24,8 @@ use crate::{
/// that has a fixed width and height.
///
/// [`SizedBox`]: crate::widget::SizedBox
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__spinner__tests__spinner_init.png", "Spinner frame.")]
pub struct Spinner {
t: f64,
color: Color,

View File

@ -21,6 +21,8 @@ use crate::{
// TODO - Have child widget type as generic argument
/// A container containing two other widgets, splitting the area either horizontally or vertically.
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__split__tests__columns.png", "Split panel with two labels.")]
pub struct Split {
split_axis: Axis,
split_point_chosen: f64,

View File

@ -32,6 +32,8 @@ pub enum ChildAlignment {
///
/// The alignment of how the children are placed can be specified globally using [`with_alignment`][Self::with_alignment].
/// Each child can additionally override the global alignment using [`ChildAlignment::SelfAligned`].
///
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__zstack__tests__zstack_alignment_default.png", "Red foreground widget on top of blue background widget.")]
#[derive(Default)]
pub struct ZStack {
children: Vec<Child>,