Depends on #904.
Add BackgroundColor, BorderColor, BorderWidth, CornerRadius and Padding
properties.
Modularize button painting code.
Paint border after background to get slightly better border appearance.
Update screenshots.
Add screenshot test using properties.
This is a minimum viable virtual scrolling widget, making the following
assumptions:
- It does not *care* about scrollbars. This has several big advantages:
- It allows for "infinite" virtual up and down-scrolling
- It allows for much more control by users of how the scrolling happens
(e.g. a date based scrollbar)
It does *not* assume that each item has a fixed height, and instead uses
some best-effort heuristics to work out which items should be loaded.
We've done some thinking about how to handle arbitrary transforms of
child widgets. Essentially, the only way we can reasonably handle this
is for each child widget to be automatically clipped to their layout
rectangle (...maybe e.g. 20% larger than it; that's hard because if we
don't use fixed margins then the variable scroll controller needs to
know about it).
This also does not handle focus and other details around (e.g.)
textboxes properly; it's not actually possible for the VirtualScroll
widget to know which child has the focus, so it can't keep that widget
around. Saving the textbox state would be nice, but requires a redesign
of a lot of things, essentially.

Fixes#51
---------
Co-authored-by: Bruce Mitchener <bruce.mitchener@gmail.com>
Remove nv-flip dependency and use pixel-by-pixel comparison instead.
Reduce error tolerance in tests.
Update a few outdated screenshots.
Create `assert_failing_render_snapshot` macro to make sure our diffing
infrastructure catches regressions.
Fixes#893.
Add `Properties[Mut]` argument to widget methods.
Add a third TreeArena to sort per-widget arbitrary property values.
For the type-to-value map, I considered the following crates:
- https://docs.rs/typemap/latest/typemap/
- https://crates.io/crates/typemap_rev
- https://crates.io/crates/typemap-ors
- https://github.com/chris-morgan/anymap
- https://github.com/reivilibre/anymap3
Of these, anymap3 is the only one actively maintained (last commit less
than 12 months ago). The code source itself is extremely light and
simple; we may or may not decide to roll out our own implementation down
the line.
Add a BackgroundBrush property used by SizedBox as a proof of concept.
Note that SizedBox still has its `background` field, but we should
expect future widgets to use almost *exclusively* properties; properties
usually shouldn't be redundant with local fields.
To get there, we'll first need to better integrate properties in Xilem.
I've ignored most of the changes and the projects still compile and test
fine. Changes I did commit:
Add `+ use<>` after functions.
Remove `ref mut` from some patterns.
Bump MSRV.
Apply new rustfmt format.
Remaining steps
- [x] Update Textbox to use this
- [x] Add internal padding
Follow-up work:
- [ ] Restore IME support
- [ ] Upstream new result of PlainEditor (once other steps are complete)
The biggest remaining issue in this PR is that IME support is not
present.
However, I think landing this is *better* than not landing it, because:
1) If we don't land it, it's going to languish again
2) Getting IME support back can be parallelised (cc @tomcur)
3) Getting Vello 0.3.0 and Parley 0.2.0 unlocks real advantages,
including full emoji support (#420).
To be clear, my first follow-up priority will be connecting the IME back
up. I do not however think this should block on Parley 0.3.0.
Discussion in
https://xi.zulipchat.com/#narrow/channel/317477-masonry/topic/Updating.20Parley.20dependency
This allows exceptions to be burned down on a per-crate basis, rather
than needing to be addressed across the whole codebase at once.
Additionally, this now follows completely the Linebender lint set,
except for the unexpected-cfgs. I don't think I've introduced any
behaviour changes in this PR.
See discussion here https://github.com/linebender/xilem/pull/663 and [on
zulip](https://xi.zulipchat.com/#narrow/channel/317477-masonry/topic/Improving.20docs.20for.20WidgetMut).
Basically, previous code was using `WidgetMut<MyWidget>` as a receiver.
This can be done when WidgetMut is a local type, but external users
wouldn't be able to do it. The result would be that users importing
Masonry as a dependency but copy-pasting code from one of our widgets
would get compile errors.
This PR switches to a syntax that external crates will be able to use
when declaring widgets. It's a more verbose, less readable syntax, but
it's unambiguous and doesn't require clever tricks.
We can consider switching back to WidgetMut-as-a-receiver when
`#![feature(arbitrary_self_types)]` or some equivalent gets stabilized.
See
https://github.com/rust-lang/rust/issues/44874#issuecomment-2122179688
for current progress.
Reimplement calculation of image size in `Image` widget `layout`
function.
Makes it match against `self.fill` before setting size.
Tests still missing.
Fixes#574
It makes more sense to pass the `NodeBuilder` reference separately to
the `accessibility` method. In particular, this avoids the need to keep
calling a method on `AccessCtx` to get that mutable reference.
This PR adds a basic grid layout to Masonry and Xilem.
The way this layout works is it has a fixed grid based on the initial
size passed in, and grid items are placed based on the position
requested. Grid items are allowed to span more than one cell, if
requested.
There are potential improvements that could be done, like the use of
intrinsic sizing for varied column width based on content size. Though
that could be done in the future taffy layout if we want to keep this
one simple.
~~This PR is still a draft because of one remaining concern. I was not
able to successfully optimize with conditional calls to child widgets
for layout. It led to crashes about the paint rects not being within the
widget's paint rect. `Error in 'Grid' #16: paint_rect Rect { x0: 0.0,
y0: 0.0, x1: 800.0, y1: 610.0 } doesn't contain paint_rect Rect { x0:
400.5, y0: 0.0, x1: 800.5, y1: 150.0 } of child widget 'Button' #5`. My
failed attempt at fixing it is commented out.~~
Since I am rusty on View Sequences, a lot of that code is based on the
Flex implementation. Let me know if I did anything incorrectly or if any
of it is unnecessary, or if anything is missing.
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
Also improve documentation of pointer capture.
Continuation of 59ee615651
(https://github.com/linebender/xilem/pull/488).
Makes `has_pointer_capture` available on all context types except
`LayoutCtx`, like `is_active` used to be.
Recursing is done inside the paint and accessibility passes since
ff7635e4c2. I believe this is the correct
continuation of #522, with the removal of these methods "left for later"
as mentioned in
https://github.com/linebender/xilem/pull/522#issuecomment-2298610203.
One note is that Flex now debug-paints its baseline under its children,
rather than over them.
Rather than have to keep a dependency on `kurbo` at the correct version,
always use it via `vello`.
This makes this match how `peniko` is already used within `masonry`.
This is part of the "Pass Specification" RFC:
https://github.com/linebender/rfcs/pull/7
Rename WidgetCtx to MutateCtx.
Add a mutate pass.
Add a `mutate_later` context method to trigger that pass.
Refactor `edit_root_widget` to use a version of that pass.
Add a separate constructor for the synthetic WidgetState created in
RenderRoot.
---------
Co-authored-by: Philipp Mildenberger <philipp@mildenberger.me>
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
This is a first step in implementing the "Pass Specification" RFC:
https://github.com/linebender/rfcs/pull/7
Create a `passes` module.
Create event passes.
Create the update_pointer pass.
Remove `WidgetPod::update_hot_state` method.
Move mouse-cursor-handling code to update_pointer pass.
Implement pointer capture.
Refactor the TreeArena code.
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
This pull request adds a simple calculator that can display binomial
math (ex: 2 + 2 = 4). Math operations with more than two operands are
done by moving the prior binomial results into the left operands.
This pull request also follows the existing convention by masonry's
calculator example to calc_masonry to differentiate them.
Let me know if there are any changes that I should make to improve code
quality.
<img width="404" alt="image"
src="https://github.com/user-attachments/assets/3498913b-dd4d-451c-8fa2-fcd2f7fd26af">
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>