mirror of https://github.com/linebender/xilem
Document more items (#899)
Make missing_docs annotations more granular.
This commit is contained in:
parent
ab341367b0
commit
125dab7949
|
@ -1,8 +1,7 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// We use allow because expect(missing_docs) is noisy with rust-analyzer.
|
||||
#![allow(missing_docs, reason = "We have many as-yet undocumented items")]
|
||||
#![expect(missing_docs, reason = "TODO - Document these items")]
|
||||
|
||||
use std::num::NonZeroUsize;
|
||||
use std::sync::Arc;
|
||||
|
|
|
@ -10,12 +10,9 @@ mod event;
|
|||
mod object_fit;
|
||||
mod properties;
|
||||
mod text;
|
||||
#[allow(missing_docs, reason = "TODO")]
|
||||
mod widget;
|
||||
mod widget_arena;
|
||||
#[allow(missing_docs, reason = "TODO")]
|
||||
mod widget_mut;
|
||||
#[allow(missing_docs, reason = "TODO")]
|
||||
mod widget_pod;
|
||||
mod widget_ref;
|
||||
mod widget_state;
|
||||
|
|
|
@ -45,6 +45,7 @@ use crate::kurbo::{Point, Size};
|
|||
pub struct WidgetId(pub(crate) NonZeroU64);
|
||||
|
||||
impl WidgetId {
|
||||
/// A serialized representation of the `WidgetId` for debugging purposes.
|
||||
pub fn trace(self) -> DisplayValue<Self> {
|
||||
tracing::field::display(self)
|
||||
}
|
||||
|
@ -242,6 +243,7 @@ pub trait Widget: AsAny + AsDynWidget {
|
|||
bc: &BoxConstraints,
|
||||
) -> Size;
|
||||
|
||||
/// Runs after the widget's final transform has been computed.
|
||||
fn compose(&mut self, ctx: &mut ComposeCtx) {}
|
||||
|
||||
/// Paint the widget appearance.
|
||||
|
@ -495,6 +497,7 @@ impl WidgetId {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the integer value of the `WidgetId`.
|
||||
pub fn to_raw(self) -> u64 {
|
||||
self.0.into()
|
||||
}
|
||||
|
|
|
@ -8,8 +8,6 @@ use anymap3::Entry;
|
|||
use crate::core::{FromDynWidget, MutateCtx, Widget};
|
||||
use crate::kurbo::Affine;
|
||||
|
||||
// TODO - Document extension trait workaround.
|
||||
// See https://xi.zulipchat.com/#narrow/stream/317477-masonry/topic/Thoughts.20on.20simplifying.20WidgetMut/near/436478885
|
||||
/// A rich mutable reference to a [`Widget`].
|
||||
///
|
||||
/// In Masonry, widgets can't be mutated directly. All mutations go through a `WidgetMut`
|
||||
|
@ -29,8 +27,10 @@ use crate::kurbo::Affine;
|
|||
/// widgets in downstream crates can use `WidgetMut` as the receiver for inherent methods.
|
||||
#[non_exhaustive]
|
||||
pub struct WidgetMut<'a, W: Widget + ?Sized> {
|
||||
pub ctx: MutateCtx<'a>,
|
||||
/// The widget we're mutating.
|
||||
pub widget: &'a mut W,
|
||||
/// A context handle that points to the widget state and other relevant data.
|
||||
pub ctx: MutateCtx<'a>,
|
||||
}
|
||||
|
||||
impl<W: Widget + ?Sized> Drop for WidgetMut<'_, W> {
|
||||
|
@ -48,8 +48,8 @@ impl<W: Widget + ?Sized> WidgetMut<'_, W> {
|
|||
pub fn reborrow_mut(&mut self) -> WidgetMut<'_, W> {
|
||||
let widget = &mut self.widget;
|
||||
WidgetMut {
|
||||
ctx: self.ctx.reborrow_mut(),
|
||||
widget,
|
||||
ctx: self.ctx.reborrow_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,8 +118,8 @@ impl<W: Widget + ?Sized> WidgetMut<'_, W> {
|
|||
let w1_name = self.widget.type_name();
|
||||
match W2::from_dyn_mut(self.widget.as_mut_dyn()) {
|
||||
Some(widget) => WidgetMut {
|
||||
ctx: self.ctx.reborrow_mut(),
|
||||
widget,
|
||||
ctx: self.ctx.reborrow_mut(),
|
||||
},
|
||||
None => {
|
||||
panic!(
|
||||
|
|
|
@ -55,6 +55,7 @@ impl<W: Widget + ?Sized> WidgetPod<W> {
|
|||
Self::new_with_id_and_transform(inner, WidgetId::next(), transform)
|
||||
}
|
||||
|
||||
/// Create a new widget pod with a custom transform and a pre-set [`WidgetId`].
|
||||
pub fn new_with_id_and_transform(inner: Box<W>, id: WidgetId, transform: Affine) -> Self {
|
||||
Self {
|
||||
id,
|
||||
|
@ -67,6 +68,7 @@ impl<W: Widget + ?Sized> WidgetPod<W> {
|
|||
}
|
||||
|
||||
// TODO - Remove transform, have it as a special-case property instead.
|
||||
/// Create a new widget pod with a custom transform and custom [`Properties`].
|
||||
pub fn new_with(inner: Box<W>, id: WidgetId, transform: Affine, props: Properties) -> Self {
|
||||
Self {
|
||||
id,
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Copyright 2019 the Xilem Authors and the Druid Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//! Theme keys and initial values.
|
||||
//! Default values used by various widgets in their paint methods.
|
||||
|
||||
#![allow(missing_docs)]
|
||||
#![allow(missing_docs, reason = "Names are self-explanatory.")]
|
||||
|
||||
use crate::kurbo::Insets;
|
||||
use crate::peniko::Color;
|
||||
|
|
|
@ -86,7 +86,9 @@ impl<T: Any> AsAny for T {
|
|||
// --- MARK: PAINT HELPERS ---
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[allow(missing_docs)]
|
||||
/// A point with coordinates in the range [0.0, 1.0].
|
||||
///
|
||||
/// This is useful for specifying points in a normalized space, such as a gradient.
|
||||
pub struct UnitPoint {
|
||||
u: f64,
|
||||
v: f64,
|
||||
|
@ -96,7 +98,7 @@ pub struct UnitPoint {
|
|||
single_use_lifetimes,
|
||||
reason = "Anonymous lifetimes in `impl Trait` are unstable, see https://github.com/rust-lang/rust/issues/129255"
|
||||
)]
|
||||
#[allow(missing_docs)]
|
||||
/// Helper function for [`Scene::stroke`].
|
||||
pub fn stroke<'b>(
|
||||
scene: &mut Scene,
|
||||
path: &impl Shape,
|
||||
|
@ -112,8 +114,6 @@ pub fn stroke<'b>(
|
|||
scene.stroke(&style, Affine::IDENTITY, brush, None, path);
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
#[allow(missing_docs)]
|
||||
impl UnitPoint {
|
||||
/// `(0.0, 0.0)`
|
||||
pub const TOP_LEFT: Self = Self::new(0.0, 0.0);
|
||||
|
@ -151,7 +151,7 @@ impl UnitPoint {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
/// Helper function for [`Scene::fill`] with a linear gradient as the brush.
|
||||
pub fn fill_lin_gradient(
|
||||
scene: &mut Scene,
|
||||
path: &impl Shape,
|
||||
|
@ -164,7 +164,7 @@ pub fn fill_lin_gradient(
|
|||
scene.fill(Fill::NonZero, Affine::IDENTITY, &brush, None, path);
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
/// Helper function for [`Scene::fill`] with a uniform color as the brush.
|
||||
pub fn fill_color(scene: &mut Scene, path: &impl Shape, color: Color) {
|
||||
scene.fill(Fill::NonZero, Affine::IDENTITY, color, None, path);
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ impl Button {
|
|||
Label::set_text(&mut Self::label_mut(this), new_text);
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Get a mutable reference to the label.
|
||||
pub fn label_mut<'t>(this: &'t mut WidgetMut<'_, Self>) -> WidgetMut<'t, Label> {
|
||||
this.ctx.get_mut(&mut this.widget.label)
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ impl Checkbox {
|
|||
|
||||
// --- MARK: WIDGETMUT ---
|
||||
impl Checkbox {
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Check or uncheck the box.
|
||||
pub fn set_checked(this: &mut WidgetMut<'_, Self>, checked: bool) {
|
||||
this.widget.checked = checked;
|
||||
// Checked state impacts appearance and accessibility node
|
||||
|
@ -60,7 +60,7 @@ impl Checkbox {
|
|||
Label::set_text(&mut Self::label_mut(this), new_text);
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Get a mutable reference to the label.
|
||||
pub fn label_mut<'t>(this: &'t mut WidgetMut<'_, Self>) -> WidgetMut<'t, Label> {
|
||||
this.ctx.get_mut(&mut this.widget.label)
|
||||
}
|
||||
|
|
|
@ -294,12 +294,12 @@ impl Flex {
|
|||
self
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Returns the number of children (widgets and spacers) this flex container has.
|
||||
pub fn len(&self) -> usize {
|
||||
self.children.len()
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Returns `true` if this flex container has no children (widgets or spacers).
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
@ -390,7 +390,11 @@ impl Flex {
|
|||
this.ctx.children_changed();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Add a non-flex child widget with a pre-assigned id.
|
||||
///
|
||||
/// See also [`with_child_id`].
|
||||
///
|
||||
/// [`with_child_id`]: Flex::with_child_id
|
||||
pub fn add_child_id(this: &mut WidgetMut<'_, Self>, child: impl Widget, id: WidgetId) {
|
||||
let child = Child::Fixed {
|
||||
widget: WidgetPod::new_with_id(child, id).erased(),
|
||||
|
@ -453,16 +457,20 @@ impl Flex {
|
|||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
/// Add a non-flex child widget.
|
||||
/// Insert a non-flex child widget at the given index.
|
||||
///
|
||||
/// See also [`with_child`].
|
||||
/// # Panics
|
||||
///
|
||||
/// [`with_child`]: Flex::with_child
|
||||
/// Panics if the index is larger than the number of children.
|
||||
pub fn insert_child(this: &mut WidgetMut<'_, Self>, idx: usize, child: impl Widget) {
|
||||
Self::insert_child_pod(this, idx, WidgetPod::new(child).erased());
|
||||
}
|
||||
|
||||
/// Add a non-flex child widget.
|
||||
/// Insert a non-flex child widget wrapped in a [`WidgetPod`] at the given index.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is larger than the number of children.
|
||||
pub fn insert_child_pod(
|
||||
this: &mut WidgetMut<'_, Self>,
|
||||
idx: usize,
|
||||
|
@ -476,7 +484,11 @@ impl Flex {
|
|||
this.ctx.children_changed();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Insert a flex child widget at the given index.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is larger than the number of children.
|
||||
pub fn insert_flex_child(
|
||||
this: &mut WidgetMut<'_, Self>,
|
||||
idx: usize,
|
||||
|
@ -486,7 +498,11 @@ impl Flex {
|
|||
Self::insert_flex_child_pod(this, idx, WidgetPod::new(child).erased(), params);
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Insert a flex child widget wrapped in a [`WidgetPod`] at the given index.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is larger than the number of children.
|
||||
pub fn insert_flex_child_pod(
|
||||
this: &mut WidgetMut<'_, Self>,
|
||||
idx: usize,
|
||||
|
@ -499,22 +515,30 @@ impl Flex {
|
|||
}
|
||||
|
||||
// TODO - remove
|
||||
/// Add a spacer widget with a standard size.
|
||||
/// Insert a spacer widget with a standard size at the given index.
|
||||
///
|
||||
/// The actual value of this spacer depends on whether this container is
|
||||
/// a row or column, as well as theme settings.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is larger than the number of children.
|
||||
pub fn insert_default_spacer(this: &mut WidgetMut<'_, Self>, idx: usize) {
|
||||
let key = axis_default_spacer(this.widget.direction);
|
||||
Self::insert_spacer(this, idx, key);
|
||||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
/// Add an empty spacer widget with the given size.
|
||||
/// Insert an empty spacer widget with the given size at the given index.
|
||||
///
|
||||
/// If you are laying out standard controls in this container, you should
|
||||
/// generally prefer to use [`add_default_spacer`].
|
||||
///
|
||||
/// [`add_default_spacer`]: Flex::add_default_spacer
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is larger than the number of children.
|
||||
pub fn insert_spacer(this: &mut WidgetMut<'_, Self>, idx: usize, mut len: f64) {
|
||||
if len < 0.0 {
|
||||
tracing::warn!("add_spacer called with negative length: {}", len);
|
||||
|
@ -527,6 +551,10 @@ impl Flex {
|
|||
}
|
||||
|
||||
/// Add an empty spacer widget with a specific `flex` factor.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is larger than the number of children.
|
||||
pub fn insert_flex_spacer(this: &mut WidgetMut<'_, Self>, idx: usize, flex: f64) {
|
||||
let flex = if flex >= 0.0 {
|
||||
flex
|
||||
|
@ -539,7 +567,13 @@ impl Flex {
|
|||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Remove the child at `idx`.
|
||||
///
|
||||
/// This child can be a widget or a spacer.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is larger than the number of children.
|
||||
pub fn remove_child(this: &mut WidgetMut<'_, Self>, idx: usize) {
|
||||
let child = this.widget.children.remove(idx);
|
||||
if let Child::Fixed { widget, .. } | Child::Flex { widget, .. } = child {
|
||||
|
@ -548,7 +582,13 @@ impl Flex {
|
|||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Returns a mutable reference to the child widget at `idx`.
|
||||
///
|
||||
/// Returns `None` if the child at `idx` is a spacer.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is larger than the number of children.
|
||||
pub fn child_mut<'t>(
|
||||
this: &'t mut WidgetMut<'_, Self>,
|
||||
idx: usize,
|
||||
|
@ -623,7 +663,7 @@ impl Flex {
|
|||
this.ctx.children_changed();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Remove all children from the container.
|
||||
pub fn clear(this: &mut WidgetMut<'_, Self>) {
|
||||
if !this.widget.children.is_empty() {
|
||||
this.ctx.request_layout();
|
||||
|
|
|
@ -32,17 +32,21 @@ struct Child {
|
|||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone, PartialEq)]
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Parameters required when adding an item to a [`Grid`] container.
|
||||
pub struct GridParams {
|
||||
/// Index of the column this item is starting from.
|
||||
pub x: i32,
|
||||
/// Index of the row this item is starting from.
|
||||
pub y: i32,
|
||||
/// Number of columns this item spans.
|
||||
pub width: i32,
|
||||
/// Number of rows this item spans.
|
||||
pub height: i32,
|
||||
}
|
||||
|
||||
// --- MARK: IMPL GRID ---
|
||||
impl Grid {
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Create a new grid with the given number of columns and rows.
|
||||
pub fn with_dimensions(width: i32, height: i32) -> Self {
|
||||
Self {
|
||||
children: Vec::new(),
|
||||
|
@ -52,25 +56,23 @@ impl Grid {
|
|||
}
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Builder-style method for setting the spacing between grid items.
|
||||
pub fn with_spacing(mut self, spacing: f64) -> Self {
|
||||
self.grid_spacing = spacing;
|
||||
self
|
||||
}
|
||||
|
||||
/// Builder-style variant of [`Grid::add_child`].
|
||||
///
|
||||
/// Convenient for assembling a group of widgets in a single expression.
|
||||
/// Builder-style method to add a child widget.
|
||||
pub fn with_child(self, child: impl Widget, params: GridParams) -> Self {
|
||||
self.with_child_pod(WidgetPod::new(child).erased(), params)
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Builder-style method to add a child widget with a pre-assigned id.
|
||||
pub fn with_child_id(self, child: impl Widget, id: WidgetId, params: GridParams) -> Self {
|
||||
self.with_child_pod(WidgetPod::new_with_id(child, id).erased(), params)
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Builder-style method to add a child widget already wrapped in a [`WidgetPod`].
|
||||
pub fn with_child_pod(mut self, widget: WidgetPod<dyn Widget>, params: GridParams) -> Self {
|
||||
let child = Child {
|
||||
widget,
|
||||
|
@ -86,13 +88,6 @@ impl Grid {
|
|||
|
||||
// --- MARK: IMPL CHILD ---
|
||||
impl Child {
|
||||
fn widget_mut(&mut self) -> Option<&mut WidgetPod<dyn Widget>> {
|
||||
Some(&mut self.widget)
|
||||
}
|
||||
fn widget(&self) -> Option<&WidgetPod<dyn Widget>> {
|
||||
Some(&self.widget)
|
||||
}
|
||||
|
||||
fn update_params(&mut self, params: GridParams) {
|
||||
self.x = params.x;
|
||||
self.y = params.y;
|
||||
|
@ -113,8 +108,13 @@ fn new_grid_child(params: GridParams, widget: WidgetPod<dyn Widget>) -> Child {
|
|||
|
||||
// --- MARK: IMPL GRIDPARAMS ---
|
||||
impl GridParams {
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Create grid parameters with the given values.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// When debug assertions are on, panics if the width or height is less than or equal to zero or if x or y is negative.
|
||||
pub fn new(mut x: i32, mut y: i32, mut width: i32, mut height: i32) -> Self {
|
||||
// TODO - Use u32 params instead?
|
||||
if x < 0 {
|
||||
debug_panic!("Grid x value should be a non-negative number; got {}", x);
|
||||
x = 0;
|
||||
|
@ -150,15 +150,15 @@ impl GridParams {
|
|||
impl Grid {
|
||||
/// Add a child widget.
|
||||
///
|
||||
/// See also [`with_child`].
|
||||
///
|
||||
/// [`with_child`]: Grid::with_child
|
||||
/// See also [`with_child`](Grid::with_child).
|
||||
pub fn add_child(this: &mut WidgetMut<'_, Self>, child: impl Widget, params: GridParams) {
|
||||
let child_pod: WidgetPod<dyn Widget> = WidgetPod::new(child).erased();
|
||||
Self::insert_child_pod(this, child_pod, params);
|
||||
Self::add_child_pod(this, child_pod, params);
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Add a child widget with a pre-assigned id.
|
||||
///
|
||||
/// See also [`with_child_id`](Grid::with_child_id).
|
||||
pub fn add_child_id(
|
||||
this: &mut WidgetMut<'_, Self>,
|
||||
child: impl Widget,
|
||||
|
@ -166,11 +166,13 @@ impl Grid {
|
|||
params: GridParams,
|
||||
) {
|
||||
let child_pod: WidgetPod<dyn Widget> = WidgetPod::new_with_id(child, id).erased();
|
||||
Self::insert_child_pod(this, child_pod, params);
|
||||
Self::add_child_pod(this, child_pod, params);
|
||||
}
|
||||
|
||||
/// Add a child widget.
|
||||
pub fn insert_child_pod(
|
||||
/// Add a child widget already wrapped in a [`WidgetPod`].
|
||||
///
|
||||
/// See also [`with_child_pod`](Grid::with_child_pod).
|
||||
pub fn add_child_pod(
|
||||
this: &mut WidgetMut<'_, Self>,
|
||||
widget: WidgetPod<dyn Widget>,
|
||||
params: GridParams,
|
||||
|
@ -181,7 +183,14 @@ impl Grid {
|
|||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Insert a child widget at the given index.
|
||||
///
|
||||
/// This lets you control the order in which the children are drawn. Children are
|
||||
/// drawn in index order (i.e. each child is drawn on top of the children with lower indices).
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is larger than the number of children.
|
||||
pub fn insert_grid_child_at(
|
||||
this: &mut WidgetMut<'_, Self>,
|
||||
idx: usize,
|
||||
|
@ -191,7 +200,14 @@ impl Grid {
|
|||
Self::insert_grid_child_pod(this, idx, WidgetPod::new(child).erased(), params);
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Insert a child widget already wrapped in a [`WidgetPod`] at the given index.
|
||||
///
|
||||
/// This lets you control the order in which the children are drawn. Children are
|
||||
/// drawn in index order (i.e. each child is drawn on top of the children with lower indices).
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is larger than the number of children.
|
||||
pub fn insert_grid_child_pod(
|
||||
this: &mut WidgetMut<'_, Self>,
|
||||
idx: usize,
|
||||
|
@ -204,31 +220,37 @@ impl Grid {
|
|||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Set the spacing between grid items.
|
||||
pub fn set_spacing(this: &mut WidgetMut<'_, Self>, spacing: f64) {
|
||||
this.widget.grid_spacing = spacing;
|
||||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
// TODO - Some of these method names should maybe be changed.
|
||||
// "height" and "width" are misleading, since they suggest a pixel size.
|
||||
/// Set the number of columns of the grid.
|
||||
pub fn set_width(this: &mut WidgetMut<'_, Self>, width: i32) {
|
||||
this.widget.grid_width = width;
|
||||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Set the number of rows of the grid.
|
||||
pub fn set_height(this: &mut WidgetMut<'_, Self>, height: i32) {
|
||||
this.widget.grid_height = height;
|
||||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Get a mutable reference to the child at `idx`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if `idx` is out of bounds.
|
||||
pub fn child_mut<'t>(
|
||||
this: &'t mut WidgetMut<'_, Self>,
|
||||
idx: usize,
|
||||
) -> Option<WidgetMut<'t, dyn Widget>> {
|
||||
let child = this.widget.children[idx].widget_mut()?;
|
||||
Some(this.ctx.get_mut(child))
|
||||
) -> WidgetMut<'t, dyn Widget> {
|
||||
let child = &mut this.widget.children[idx].widget;
|
||||
this.ctx.get_mut(child)
|
||||
}
|
||||
|
||||
/// Updates the grid parameters for the child at `idx`,
|
||||
|
@ -246,7 +268,11 @@ impl Grid {
|
|||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Removes a child widget at the given index.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the index is out of bounds.
|
||||
pub fn remove_child(this: &mut WidgetMut<'_, Self>, idx: usize) {
|
||||
let child = this.widget.children.remove(idx);
|
||||
this.ctx.remove_child(child.widget);
|
||||
|
@ -281,8 +307,8 @@ impl Widget for Grid {
|
|||
}
|
||||
|
||||
fn register_children(&mut self, ctx: &mut crate::core::RegisterCtx) {
|
||||
for child in self.children.iter_mut().filter_map(|x| x.widget_mut()) {
|
||||
ctx.register_child(child);
|
||||
for child in self.children.iter_mut() {
|
||||
ctx.register_child(&mut child.widget);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,8 +369,7 @@ impl Widget for Grid {
|
|||
fn children_ids(&self) -> SmallVec<[WidgetId; 16]> {
|
||||
self.children
|
||||
.iter()
|
||||
.filter_map(|child| child.widget())
|
||||
.map(|widget_pod| widget_pod.id())
|
||||
.map(|child| child.widget.id())
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@ use crate::theme;
|
|||
use crate::util::{UnitPoint, fill_lin_gradient, stroke};
|
||||
use crate::widgets::{Label, LineBreaking};
|
||||
|
||||
// TODO - NaN probably shouldn't be a meaningful value in our API.
|
||||
|
||||
/// A progress bar.
|
||||
///
|
||||
#[doc = crate::include_screenshot!("widget/screenshots/masonry__widget__progress_bar__tests__25_percent_progressbar.png", "25% progress bar.")]
|
||||
|
@ -33,11 +35,11 @@ pub struct ProgressBar {
|
|||
impl ProgressBar {
|
||||
/// Create a new `ProgressBar`.
|
||||
///
|
||||
/// `progress` is a number between 0 and 1 inclusive. If it is `NaN`, then an
|
||||
/// indefinite progress bar will be shown.
|
||||
/// Otherwise, the input will be clamped to [0, 1].
|
||||
pub fn new(mut progress: Option<f64>) -> Self {
|
||||
clamp_progress(&mut progress);
|
||||
/// The progress value will be clamped to [0, 1].
|
||||
///
|
||||
/// A `None` value (or NaN) will show an indeterminate progress bar.
|
||||
pub fn new(progress: Option<f64>) -> Self {
|
||||
let progress = clamp_progress(progress);
|
||||
let label = WidgetPod::new(
|
||||
Label::new(Self::value(progress)).with_line_break_mode(LineBreaking::Overflow),
|
||||
);
|
||||
|
@ -63,9 +65,13 @@ impl ProgressBar {
|
|||
|
||||
// --- MARK: WIDGETMUT ---
|
||||
impl ProgressBar {
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
pub fn set_progress(this: &mut WidgetMut<'_, Self>, mut progress: Option<f64>) {
|
||||
clamp_progress(&mut progress);
|
||||
/// Set the progress displayed by the bar.
|
||||
///
|
||||
/// The progress value will be clamped to [0, 1].
|
||||
///
|
||||
/// A `None` value (or NaN) will show an indeterminate progress bar.
|
||||
pub fn set_progress(this: &mut WidgetMut<'_, Self>, progress: Option<f64>) {
|
||||
let progress = clamp_progress(progress);
|
||||
let progress_changed = this.widget.progress != progress;
|
||||
if progress_changed {
|
||||
this.widget.progress = progress;
|
||||
|
@ -80,13 +86,12 @@ impl ProgressBar {
|
|||
/// Helper to ensure progress is either a number between [0, 1] inclusive, or `None`.
|
||||
///
|
||||
/// NaNs are converted to `None`.
|
||||
fn clamp_progress(progress: &mut Option<f64>) {
|
||||
if let Some(value) = progress {
|
||||
if value.is_nan() {
|
||||
*progress = None;
|
||||
} else {
|
||||
*progress = Some(value.clamp(0., 1.));
|
||||
}
|
||||
fn clamp_progress(progress: Option<f64>) -> Option<f64> {
|
||||
let progress = progress?;
|
||||
if progress.is_nan() {
|
||||
None
|
||||
} else {
|
||||
Some(progress.clamp(0., 1.))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,15 +14,15 @@ use crate::core::{
|
|||
};
|
||||
use crate::kurbo::Size;
|
||||
|
||||
// TODO: This is a hack to provide an accessibility node with a Window type.
|
||||
// This should eventually be removed.
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
// TODO: This should eventually be removed once accesskit does that for us.
|
||||
// See https://github.com/AccessKit/accesskit/issues/531
|
||||
/// A widget wrapper that reports a [`Role::Window`] to the accessibility API.
|
||||
pub struct RootWidget<W: ?Sized> {
|
||||
pub(crate) pod: WidgetPod<W>,
|
||||
}
|
||||
|
||||
impl<W: Widget> RootWidget<W> {
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Create a new root widget.
|
||||
pub fn new(widget: W) -> Self {
|
||||
Self {
|
||||
pod: WidgetPod::new(widget),
|
||||
|
@ -31,14 +31,14 @@ impl<W: Widget> RootWidget<W> {
|
|||
}
|
||||
|
||||
impl<W: Widget + FromDynWidget + ?Sized> RootWidget<W> {
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Create a new root widget from a [`WidgetPod`].
|
||||
pub fn from_pod(pod: WidgetPod<W>) -> Self {
|
||||
Self { pod }
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Widget + FromDynWidget + ?Sized> RootWidget<W> {
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Get a mutable reference to the child widget.
|
||||
pub fn child_mut<'t>(this: &'t mut WidgetMut<'_, Self>) -> WidgetMut<'t, W> {
|
||||
this.ctx.get_mut(&mut this.widget.pod)
|
||||
}
|
||||
|
|
|
@ -327,7 +327,9 @@ impl SizedBox {
|
|||
|
||||
// --- MARK: WIDGETMUT ---
|
||||
impl SizedBox {
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Give this container a child widget.
|
||||
///
|
||||
/// If this container already has a child, it will be overwritten.
|
||||
pub fn set_child(this: &mut WidgetMut<'_, Self>, child: impl Widget) {
|
||||
if let Some(child) = this.widget.child.take() {
|
||||
this.ctx.remove_child(child);
|
||||
|
@ -337,7 +339,9 @@ impl SizedBox {
|
|||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Remove the child widget.
|
||||
///
|
||||
/// (If this widget has no child, this method does nothing.)
|
||||
pub fn remove_child(this: &mut WidgetMut<'_, Self>) {
|
||||
if let Some(child) = this.widget.child.take() {
|
||||
this.ctx.remove_child(child);
|
||||
|
@ -422,7 +426,7 @@ impl SizedBox {
|
|||
this.ctx.request_layout();
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Get mutable reference to the child widget, if any.
|
||||
pub fn child_mut<'t>(this: &'t mut WidgetMut<'_, Self>) -> Option<WidgetMut<'t, dyn Widget>> {
|
||||
let child = this.widget.child.as_mut()?;
|
||||
Some(this.ctx.get_mut(child))
|
||||
|
|
|
@ -53,7 +53,7 @@ impl<ChildA: Widget, ChildB: Widget> Split<ChildA, ChildB> {
|
|||
}
|
||||
|
||||
impl<ChildA: Widget + ?Sized, ChildB: Widget + ?Sized> Split<ChildA, ChildB> {
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Build split panel from two children already wrapped in [`WidgetPod`]s.
|
||||
pub fn new_pod(child1: WidgetPod<ChildA>, child2: WidgetPod<ChildB>) -> Self {
|
||||
Self {
|
||||
split_axis: Axis::Horizontal,
|
||||
|
@ -304,12 +304,12 @@ where
|
|||
ChildA: Widget + FromDynWidget + ?Sized,
|
||||
ChildB: Widget + FromDynWidget + ?Sized,
|
||||
{
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Get a mutable reference to the first child widget.
|
||||
pub fn child1_mut<'t>(this: &'t mut WidgetMut<'_, Self>) -> WidgetMut<'t, ChildA> {
|
||||
this.ctx.get_mut(&mut this.widget.child1)
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Get a mutable reference to the second child widget.
|
||||
pub fn child2_mut<'t>(this: &'t mut WidgetMut<'_, Self>) -> WidgetMut<'t, ChildB> {
|
||||
this.ctx.get_mut(&mut this.widget.child2)
|
||||
}
|
||||
|
|
|
@ -133,12 +133,16 @@ impl VariableLabel {
|
|||
Self::from_label_pod(WidgetPod::new(Label::new(text)))
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Create a new variable label from the given label.
|
||||
///
|
||||
/// Uses the label's text and style values.
|
||||
pub fn from_label(label: Label) -> Self {
|
||||
Self::from_label_pod(WidgetPod::new(label))
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO")]
|
||||
/// Create a new variable label from the given label wrapped in a [`WidgetPod`].
|
||||
///
|
||||
/// Uses the label's text and style values.
|
||||
pub fn from_label_pod(label: WidgetPod<Label>) -> Self {
|
||||
Self {
|
||||
label,
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#![expect(missing_docs, reason = "TODO - Document these items")]
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use masonry::app::{AppDriver, EventLoopProxy, MasonryState, MasonryUserEvent};
|
||||
|
|
|
@ -128,7 +128,6 @@
|
|||
#![expect(clippy::missing_assert_message, reason = "Deferred: Noisy")]
|
||||
#![expect(elided_lifetimes_in_paths, reason = "Deferred: Noisy")]
|
||||
// https://github.com/rust-lang/rust/pull/130025
|
||||
#![allow(missing_docs, reason = "We have many as-yet undocumented items")]
|
||||
#![expect(clippy::allow_attributes_without_reason, reason = "Deferred: Noisy")]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
@ -178,11 +177,13 @@ pub struct Xilem<State, Logic> {
|
|||
fonts: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO - Document these items")]
|
||||
impl<State, Logic, View> Xilem<State, Logic>
|
||||
where
|
||||
Logic: FnMut(&mut State) -> View,
|
||||
View: WidgetView<State>,
|
||||
{
|
||||
/// Initialize the builder state for your app.
|
||||
pub fn new(state: State, logic: Logic) -> Self {
|
||||
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||
Self {
|
||||
|
@ -287,6 +288,7 @@ where
|
|||
/// and so might not actually own the underlying widget value.
|
||||
/// When creating widgets in Xilem, layered views all want access to the - using
|
||||
/// `WidgetPod` for this purpose would require fallible unwrapping.
|
||||
#[expect(missing_docs, reason = "TODO - Document these items")]
|
||||
pub struct Pod<W: Widget + FromDynWidget + ?Sized> {
|
||||
pub widget: Box<W>,
|
||||
pub id: WidgetId,
|
||||
|
@ -366,6 +368,7 @@ impl<W: Widget + FromDynWidget + ?Sized> SuperElement<Pod<W>, ViewCtx> for Pod<d
|
|||
}
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO - Document these items")]
|
||||
pub trait WidgetView<State, Action = ()>:
|
||||
View<State, Action, ViewCtx, Element = Pod<Self::Widget>> + Send + Sync
|
||||
{
|
||||
|
@ -438,6 +441,7 @@ impl<Seq, State, Action> WidgetViewSequence<State, Action> for Seq where
|
|||
|
||||
type WidgetMap = HashMap<WidgetId, Vec<ViewId>>;
|
||||
|
||||
/// A context type passed to various methods of Xilem traits.
|
||||
pub struct ViewCtx {
|
||||
/// The map from a widgets id to its position in the View tree.
|
||||
///
|
||||
|
@ -462,6 +466,7 @@ impl ViewPathTracker for ViewCtx {
|
|||
}
|
||||
}
|
||||
|
||||
#[expect(missing_docs, reason = "TODO - Document these items")]
|
||||
impl ViewCtx {
|
||||
pub fn new_pod<W: Widget + FromDynWidget>(&mut self, widget: W) -> Pod<W> {
|
||||
Pod::new(widget)
|
||||
|
|
|
@ -84,20 +84,23 @@ pub struct Flex<Seq, State, Action = ()> {
|
|||
}
|
||||
|
||||
impl<Seq, State, Action> Flex<Seq, State, Action> {
|
||||
/// Set the flex direction (see [`Axis`]).
|
||||
pub fn direction(mut self, axis: Axis) -> Self {
|
||||
self.axis = axis;
|
||||
self
|
||||
}
|
||||
/// Set the childrens' [`CrossAxisAlignment`].
|
||||
pub fn cross_axis_alignment(mut self, axis: CrossAxisAlignment) -> Self {
|
||||
self.cross_axis_alignment = axis;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the childrens' [`MainAxisAlignment`].
|
||||
pub fn main_axis_alignment(mut self, axis: MainAxisAlignment) -> Self {
|
||||
self.main_axis_alignment = axis;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether the container must expand to fill the available space on
|
||||
/// its main axis.
|
||||
pub fn must_fill_major_axis(mut self, fill_major_axis: bool) -> Self {
|
||||
self.fill_major_axis = fill_major_axis;
|
||||
self
|
||||
|
@ -214,12 +217,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// A child element of a [`Flex`] view.
|
||||
pub enum FlexElement {
|
||||
/// Child widget.
|
||||
Child(Pod<dyn Widget>, FlexParams),
|
||||
/// Child spacer with fixed size.
|
||||
FixedSpacer(f64),
|
||||
/// Child spacer with flex size.
|
||||
FlexSpacer(f64),
|
||||
}
|
||||
|
||||
/// A mutable reference to a [`FlexElement`], used internally by Xilem traits.
|
||||
pub struct FlexElementMut<'w> {
|
||||
parent: WidgetMut<'w, widgets::Flex>,
|
||||
idx: usize,
|
||||
|
@ -549,6 +557,7 @@ where
|
|||
|
||||
/// A spacer that can be used within a [`Flex`] [`View`]
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[expect(missing_docs, reason = "TODO - Need to document units used.")]
|
||||
pub enum FlexSpacer {
|
||||
Fixed(f64),
|
||||
Flex(f64),
|
||||
|
@ -610,7 +619,9 @@ impl<State, Action> View<State, Action, ViewCtx> for FlexSpacer {
|
|||
|
||||
/// A widget-type-erased flex child [`View`], can be used within a [`Flex`] [`View`]
|
||||
pub enum AnyFlexChild<State, Action = ()> {
|
||||
/// A child widget.
|
||||
Item(FlexItem<Box<AnyWidgetView<State, Action>>, State, Action>),
|
||||
/// A spacer.
|
||||
Spacer(FlexSpacer),
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ pub struct Grid<Seq, State, Action = ()> {
|
|||
}
|
||||
|
||||
impl<Seq, State, Action> Grid<Seq, State, Action> {
|
||||
/// Set the spacing (both vertical and horizontal) between grid items.
|
||||
#[track_caller]
|
||||
pub fn spacing(mut self, spacing: f64) -> Self {
|
||||
if spacing.is_finite() && spacing >= 0.0 {
|
||||
|
@ -104,12 +105,8 @@ where
|
|||
let mut widget = widgets::Grid::with_dimensions(self.width, self.height);
|
||||
widget = widget.with_spacing(self.spacing);
|
||||
let seq_state = self.sequence.seq_build(ctx, &mut elements);
|
||||
for child in elements.into_inner() {
|
||||
widget = match child {
|
||||
GridElement::Child(child, params) => {
|
||||
widget.with_child_pod(child.erased_widget_pod(), params)
|
||||
}
|
||||
}
|
||||
for element in elements.into_inner() {
|
||||
widget = widget.with_child_pod(element.child.erased_widget_pod(), element.params);
|
||||
}
|
||||
let pod = ctx.new_pod(widget);
|
||||
(pod, seq_state)
|
||||
|
@ -195,7 +192,11 @@ impl<W: Widget + FromDynWidget + ?Sized> SuperElement<Pod<W>, ViewCtx> for GridE
|
|||
// There is not much else, beyond purposefully failing, that can be done here,
|
||||
// because there isn't enough information to determine an appropriate spot
|
||||
// for the widget.
|
||||
Self::Child(child.erased(), GridParams::new(1, 1, 1, 1))
|
||||
Self {
|
||||
child: child.erased(),
|
||||
// TODO - Should be 0, 0?
|
||||
params: GridParams::new(1, 1, 1, 1),
|
||||
}
|
||||
}
|
||||
|
||||
fn with_downcast_val<R>(
|
||||
|
@ -203,8 +204,7 @@ impl<W: Widget + FromDynWidget + ?Sized> SuperElement<Pod<W>, ViewCtx> for GridE
|
|||
f: impl FnOnce(Mut<Pod<W>>) -> R,
|
||||
) -> (Mut<Self>, R) {
|
||||
let ret = {
|
||||
let mut child = widgets::Grid::child_mut(&mut this.parent, this.idx)
|
||||
.expect("This is supposed to be a widget");
|
||||
let mut child = widgets::Grid::child_mut(&mut this.parent, this.idx);
|
||||
let downcast = child.downcast();
|
||||
f(downcast)
|
||||
};
|
||||
|
@ -218,32 +218,24 @@ impl ElementSplice<GridElement> for GridSplice<'_> {
|
|||
fn with_scratch<R>(&mut self, f: impl FnOnce(&mut AppendVec<GridElement>) -> R) -> R {
|
||||
let ret = f(&mut self.scratch);
|
||||
for element in self.scratch.drain() {
|
||||
match element {
|
||||
GridElement::Child(child, params) => {
|
||||
widgets::Grid::insert_grid_child_pod(
|
||||
&mut self.element,
|
||||
self.idx,
|
||||
child.erased_widget_pod(),
|
||||
params,
|
||||
);
|
||||
}
|
||||
};
|
||||
widgets::Grid::insert_grid_child_pod(
|
||||
&mut self.element,
|
||||
self.idx,
|
||||
element.child.erased_widget_pod(),
|
||||
element.params,
|
||||
);
|
||||
self.idx += 1;
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn insert(&mut self, element: GridElement) {
|
||||
match element {
|
||||
GridElement::Child(child, params) => {
|
||||
widgets::Grid::insert_grid_child_pod(
|
||||
&mut self.element,
|
||||
self.idx,
|
||||
child.erased_widget_pod(),
|
||||
params,
|
||||
);
|
||||
}
|
||||
};
|
||||
widgets::Grid::insert_grid_child_pod(
|
||||
&mut self.element,
|
||||
self.idx,
|
||||
element.child.erased_widget_pod(),
|
||||
element.params,
|
||||
);
|
||||
self.idx += 1;
|
||||
}
|
||||
|
||||
|
@ -342,17 +334,22 @@ pub trait GridExt<State, Action>: WidgetView<State, Action> {
|
|||
|
||||
impl<State, Action, V: WidgetView<State, Action>> GridExt<State, Action> for V {}
|
||||
|
||||
pub enum GridElement {
|
||||
Child(Pod<dyn Widget>, GridParams),
|
||||
/// A child widget within a [`Grid`] view.
|
||||
pub struct GridElement {
|
||||
/// The child widget.
|
||||
child: Pod<dyn Widget>,
|
||||
/// The grid parameters of the child widget.
|
||||
params: GridParams,
|
||||
}
|
||||
|
||||
/// A mutable reference to a [`GridElement`], used internally by Xilem traits.
|
||||
pub struct GridElementMut<'w> {
|
||||
parent: WidgetMut<'w, widgets::Grid>,
|
||||
idx: usize,
|
||||
}
|
||||
|
||||
// Used for manipulating the ViewSequence.
|
||||
pub struct GridSplice<'w> {
|
||||
struct GridSplice<'w> {
|
||||
idx: usize,
|
||||
element: WidgetMut<'w, widgets::Grid>,
|
||||
scratch: AppendVec<GridElement>,
|
||||
|
@ -375,6 +372,7 @@ pub struct GridItem<V, State, Action> {
|
|||
phantom: PhantomData<fn() -> (State, Action)>,
|
||||
}
|
||||
|
||||
/// Creates a [`GridItem`] from a view and [`GridParams`].
|
||||
pub fn grid_item<V, State, Action>(
|
||||
view: V,
|
||||
params: impl Into<GridParams>,
|
||||
|
@ -405,7 +403,13 @@ where
|
|||
|
||||
fn build(&self, ctx: &mut ViewCtx) -> (Self::Element, Self::ViewState) {
|
||||
let (pod, state) = self.view.build(ctx);
|
||||
(GridElement::Child(pod.erased(), self.params), state)
|
||||
(
|
||||
GridElement {
|
||||
child: pod.erased(),
|
||||
params: self.params,
|
||||
},
|
||||
state,
|
||||
)
|
||||
}
|
||||
|
||||
fn rebuild(
|
||||
|
@ -423,8 +427,7 @@ where
|
|||
self.params,
|
||||
);
|
||||
}
|
||||
let mut child = widgets::Grid::child_mut(&mut element.parent, element.idx)
|
||||
.expect("GridWrapper always has a widget child");
|
||||
let mut child = widgets::Grid::child_mut(&mut element.parent, element.idx);
|
||||
self.view
|
||||
.rebuild(&prev.view, view_state, ctx, child.downcast());
|
||||
}
|
||||
|
@ -436,8 +439,7 @@ where
|
|||
ctx: &mut ViewCtx,
|
||||
mut element: Mut<Self::Element>,
|
||||
) {
|
||||
let mut child = widgets::Grid::child_mut(&mut element.parent, element.idx)
|
||||
.expect("GridWrapper always has a widget child");
|
||||
let mut child = widgets::Grid::child_mut(&mut element.parent, element.idx);
|
||||
self.view.teardown(view_state, ctx, child.downcast());
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// The [`View`] created by [`portal`].
|
||||
#[must_use = "View values do nothing unless provided to Xilem."]
|
||||
pub struct Portal<V, State, Action> {
|
||||
child: V,
|
||||
|
|
|
@ -6,10 +6,15 @@ use masonry::widgets;
|
|||
use crate::core::{DynMessage, Mut, ViewMarker};
|
||||
use crate::{MessageResult, Pod, View, ViewCtx, ViewId};
|
||||
|
||||
/// A view which displays a progress bar.
|
||||
///
|
||||
/// This can be for showing progress of a task or a download.
|
||||
pub fn progress_bar(progress: Option<f64>) -> ProgressBar {
|
||||
ProgressBar { progress }
|
||||
}
|
||||
|
||||
/// The [`View`] created by [`progress_bar`].
|
||||
#[must_use = "View values do nothing unless provided to Xilem."]
|
||||
pub struct ProgressBar {
|
||||
progress: Option<f64>,
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ use vello::peniko::Brush;
|
|||
use crate::core::{DynMessage, Mut, ViewMarker};
|
||||
use crate::{Color, MessageResult, Pod, TextAlignment, View, ViewCtx, ViewId};
|
||||
|
||||
/// A view which displays selectable text.
|
||||
pub fn prose(content: impl Into<ArcStr>) -> Prose {
|
||||
Prose {
|
||||
content: content.into(),
|
||||
|
@ -30,6 +31,7 @@ pub fn inline_prose(content: impl Into<ArcStr>) -> Prose {
|
|||
prose(content).line_break_mode(LineBreaking::Overflow)
|
||||
}
|
||||
|
||||
/// The [`View`] created by [`prose`] or [`inline_prose`].
|
||||
#[must_use = "View values do nothing unless provided to Xilem."]
|
||||
pub struct Prose {
|
||||
content: ArcStr,
|
||||
|
@ -43,22 +45,27 @@ pub struct Prose {
|
|||
}
|
||||
|
||||
impl Prose {
|
||||
/// Set the brush used to paint the text.
|
||||
#[doc(alias = "color")]
|
||||
pub fn brush(mut self, brush: impl Into<Brush>) -> Self {
|
||||
self.text_brush = brush.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the [alignment](https://en.wikipedia.org/wiki/Typographic_alignment) of the text.
|
||||
pub fn alignment(mut self, alignment: TextAlignment) -> Self {
|
||||
self.alignment = alignment;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the font size of the text.
|
||||
#[doc(alias = "font_size")]
|
||||
pub fn text_size(mut self, text_size: f32) -> Self {
|
||||
self.text_size = text_size;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set how the text is broken when the content is too wide for its container.
|
||||
pub fn line_break_mode(mut self, line_break_mode: LineBreaking) -> Self {
|
||||
self.line_break_mode = line_break_mode;
|
||||
self
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#![expect(missing_docs, reason = "TODO - Document these items")]
|
||||
|
||||
use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
|
|
@ -13,6 +13,7 @@ use crate::{Color, MessageResult, Pod, TextAlignment, ViewCtx, ViewId};
|
|||
|
||||
type Callback<State, Action> = Box<dyn Fn(&mut State, String) -> Action + Send + Sync + 'static>;
|
||||
|
||||
/// A view which displays editable text.
|
||||
pub fn textbox<F, State, Action>(contents: String, on_changed: F) -> Textbox<State, Action>
|
||||
where
|
||||
F: Fn(&mut State, String) -> Action + Send + Sync + 'static,
|
||||
|
@ -28,6 +29,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// The [`View`] created by [`textbox`].
|
||||
#[must_use = "View values do nothing unless provided to Xilem."]
|
||||
pub struct Textbox<State, Action> {
|
||||
contents: String,
|
||||
|
@ -39,17 +41,20 @@ pub struct Textbox<State, Action> {
|
|||
}
|
||||
|
||||
impl<State, Action> Textbox<State, Action> {
|
||||
/// Set the brush used to paint the text.
|
||||
#[doc(alias = "color")]
|
||||
pub fn brush(mut self, color: impl Into<Brush>) -> Self {
|
||||
self.text_brush = color.into();
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the [alignment](https://en.wikipedia.org/wiki/Typographic_alignment) of the text.
|
||||
pub fn alignment(mut self, alignment: TextAlignment) -> Self {
|
||||
self.alignment = alignment;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set a callback that will be run when the user presses the `Enter` key to submit their input.
|
||||
pub fn on_enter<F>(mut self, on_enter: F) -> Self
|
||||
where
|
||||
F: Fn(&mut State, String) -> Action + Send + Sync + 'static,
|
||||
|
|
|
@ -21,6 +21,7 @@ pub fn variable_label(text: impl Into<ArcStr>) -> VariableLabel {
|
|||
}
|
||||
}
|
||||
|
||||
/// The [`View`] created by [`variable_label`].
|
||||
#[must_use = "View values do nothing unless provided to Xilem."]
|
||||
pub struct VariableLabel {
|
||||
label: Label,
|
||||
|
@ -63,17 +64,20 @@ impl VariableLabel {
|
|||
self
|
||||
}
|
||||
|
||||
/// Set the brush used to paint the text.
|
||||
#[doc(alias = "color")]
|
||||
pub fn brush(mut self, brush: impl Into<Brush>) -> Self {
|
||||
self.label = self.label.brush(brush);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the [alignment](https://en.wikipedia.org/wiki/Typographic_alignment) of the text.
|
||||
pub fn alignment(mut self, alignment: TextAlignment) -> Self {
|
||||
self.label = self.label.alignment(alignment);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the font size of the text.
|
||||
#[doc(alias = "font_size")]
|
||||
pub fn text_size(mut self, text_size: f32) -> Self {
|
||||
self.label = self.label.text_size(text_size);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#![expect(missing_docs, reason = "TODO - Document these items")]
|
||||
|
||||
use std::future::Future;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::Arc;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright 2024 the Xilem Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use masonry::core::{FromDynWidget, Widget, WidgetMut};
|
||||
|
|
|
@ -21,9 +21,9 @@ pub trait PhantomElementCtx: ViewPathTracker {
|
|||
}
|
||||
|
||||
/// A [`View`] which can be one of nine inner view types.
|
||||
#[allow(missing_docs)] // On variants
|
||||
#[derive(Debug)]
|
||||
#[must_use = "View values do nothing unless provided to Xilem."]
|
||||
#[expect(missing_docs, reason = "No need to document all variants")]
|
||||
pub enum OneOf<A = (), B = (), C = (), D = (), E = (), F = (), G = (), H = (), I = ()> {
|
||||
A(A),
|
||||
B(B),
|
||||
|
|
|
@ -27,8 +27,7 @@
|
|||
#![expect(clippy::cast_possible_truncation, reason = "Deferred: Noisy")]
|
||||
#![expect(clippy::missing_assert_message, reason = "Deferred: Noisy")]
|
||||
#![expect(elided_lifetimes_in_paths, reason = "Deferred: Noisy")]
|
||||
// expect doesn't work here: https://github.com/rust-lang/rust/pull/130025
|
||||
#![allow(missing_docs, reason = "We have many as-yet undocumented items")]
|
||||
#![expect(missing_docs, reason = "We have many as-yet undocumented items")]
|
||||
#![expect(unreachable_pub, reason = "Potentially controversial code style")]
|
||||
#![expect(
|
||||
unnameable_types,
|
||||
|
|
Loading…
Reference in New Issue