Remove coordinates rounding code from Align and Flex.
Remove rounding from BoxConstraints: instead, widgets do layout under
the assumption that they're in a full f64 coordinate space, and rounding
only happens at the end of layout.
Document pixel snapping.
Pixel-snap the baseline as well.
Remove `invalid_screenshot_2` test (which relied on placing a child
widget with sub-pixel boundaries to produce a slightly incorrect image,
which we can no longer do).
Update all screenshot tests.
See [#masonry > Aligning layout boxes to pixel
boundaries](https://xi.zulipchat.com/#narrow/channel/317477-masonry/topic/Aligning.20layout.20boxes.20to.20pixel.20boundaries)
for details.
Switching from `Button` to `Button<W>` so that it can contain other type
of widgets as well!
Edit: Now switching to `Button` with a `dyn Widget` as the child
instead!
Have WidgetExt methods return NewWidget instead of WrapperWidget.
Rewrite testing tutorial a bit.
Rewrite some tests to avoid relying on WidgetExt.
This overall makes code more consistent: everything which creates a
widget takes `NewWidget`.
The main differences are:
- get_raw and get_raw_mut now both give a mutable context.
- get_raw_ and get_raw_mut are no longer included in AccessCtx.
- No need for more layers of macro copy-pasting, instead everything is
in RawCtx.
Currently RawCtx is only used in Portal widget.
Places where the code was gated behind an `if false` block have been
removed.
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
The previous docs were very uninformative, and missed some crucial info
(e.g. the mechanics of dragging and resizing).
Some of these enum values directly mirror winit methods.
For these, the new docs match how Winit will handle these values.
---------
Co-authored-by: Tom Churchman <thomas@kepow.org>
This only supports copy-pasting strings, not rich text. And the way
Ctrl+V is detected is somewhat dubious.
But it does effectively add clipboard support to Masonry apps.
Ideally, on the long term, we may want to be able to programmatically
request clipboard contents; I'm not sure how to implement that cleanly
given RenderRoot's architecture, without making masonry_core depend
directly on a clipboard-handling library.
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
This reduces code duplication (a lot of code no longer has to be
copy-pasted three times).
This is especially important for the upcoming widget refactor, which
will add more code for each arena.
`MASONRY_BLESS_TEST` is used to treat all screenshots as valid.
This PR documents the flag and makes sure it works even when there's no
reference file.
Constructing those types take a lot of time.
Caching them between render calls lets us considerably speed up tests
with multiple snapshots. (Still doesn't help with single-snapshot
tests.)
Re-enable a multi-screenshot test that was taking too long.
The `ctx.target() == ctx.widget_id()` checks were added back when
Masonry still used the "send event to every widget in the tree, recurse
inside widget code, use bloom filters to skip subtrees" approach.
It doesn't make sense anymore, except maybe as a guard against bubbling,
but button and checkbox don't have to worry about that.
The tests re-use the examples, since they already use a variety of
widgets.
Tweak harness renderer code to not give wgpu a size of zero in those
cases.
Fix some problems that came up.
Use a Grid widget instead of a hierarchy of Flex widgets for layout
Remove the redundant CalcButton widget implementation.
I'm quite happy with how the result looks, but I'm surprised by the gap
between buttons. It should definitely be smaller. EDIT: Oh, it's because
gave them fairly wide transparent borders. Makes sense.
The example code itself became much, much easier to understand at a
glance.
Remove caching code from `Flex`.
Fix how layout handles stashing flags.
`skip_layout()` was used for stashed widgets (no longer necessary) and
layout caching, which we now handle at the Masonry level.
Instead of re-exporting `cursor_icon` from `masonry_core` and `masonry`,
we can re-export the single type that matters (`CursorIcon`) from
`masonry_core::core` / `masonry::core`.
Add color_rectangle mod which mirror the code examples in the tutorial.
Fix bitrot in tutorials surfaced by creating color_rectangle. Add
snapshot files for new tests in color_rectangle.
This is a fairly large PR, with a few motivations:
- To introduce the concept of a `NewWidget` type which holds all the
options a widget will be created with.
- To standardize how new widgets are added, and remove the code
duplication in `with_child`, `with_child_id`, `with_child_pod`,
`insert_child`, `insert_child_pod`, etc, methods.
- To make the Xilem-side code much simpler by taking care of the widget
creation options on the Masonry side.
- To prepare the way for #1212.
- To prepare the upcoming lifecycle refactor, in which NewWidget will be
the only way to add a widget to the widget tree.
Overall I think it makes the Masonry APIs more elegant, at the cost of
making the builder-style "Create a widget tree with the children already
filled in" widget construction more verbose.
I think that's a worthwhile trade-off because (1) we still expect most
of our users to be Xilem-style frameworks which can tolerate the
verbosity (2) I expect the builder-style constructors to be
significantly altered in the lifecycle refactor (though I think this PR
is still worth adding even if the lifecycle refactor doesn't come).
Make `run_layout_on` function more modular:
- Make it not take a LayoutCtx parameter.
- Make it not propagate state to parent state.
Make run_layout_pass no longer create a fake WidgetState parent to the
root.
Remove `WidgetState::synthetic()` constructor since it's no longer
needed.
Otherwise, doesn't change any behavior.
Use type alias in various places.
Avoid referencing smallvec from widget code.
Fixes#1141.
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
Add `GradientShape::Radial` variant.
Add `GradientShape::Sweep` variant.
Add new `Gradient` constructors.
Add screenshot tests for new gradients.
This PR adds a lot of TODOs, but implementing gradients in a way that
closely matches the CSS spec is just hard.
It still covers many common use-cases, and as such it's worth merging
this before figuring out the full solution.
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
This implements the right AccessKit role, properties, and actions for
`VirtualScroll`.
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
This is the first step of a refactor where widgets, widget states and
widget properties will be stored in the same object. So we would end up
with a type like this:
```rust
struct WidgetArenaNode {
pub(crate) widget: Box<dyn Widget>,
pub(crate) state: WidgetState,
pub(crate) properties: AnyMap,
}
```
and WidgetArena might look like:
```rust
pub(crate) struct WidgetArena {
pub(crate) nodes: TreeArena<WidgetArenaNode>,
}
```
Doing so without making an absolutely unreadable diff is tough, so I
split the work into several PRs. This one just moves code around to make
future diffs shorter.
Adds a basic nix flake with `devShells` that uses a rust environment to
run on various targets, using the MSRV `rust-version` specified in the
root `Cargo.toml`.
Fixes#66
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
This replaces "has pointer capture" with "active" as the name of the
concept of "this button / checkbox / widget is being interacted with".
Pointer capture is its own thing and in the future we might want them to
mean slightly different things.
(Also, when we add multiple pointers, checking an "active" flag will be
easier than checking "is this widget the pointer capture target of any
of the currently live pointers".)
This appears to fix the issue in #1175. I'm not very familiar with the
accessibility system, but from what I understand the issue was that
stashed nodes were being included in the focus chain used by
`update_focus`. However, when they would be focused, that was failing in
some way (likely due to them being marked as hidden in the accessibility
tree, again due to being stashed). This caused the `update_focus` logic
to break in strange ways, including periodically failing to focus on
anything when `tab` or `shift-tab` is pressed.
I checked the branch in #1179 since it looks related, but the tab
selection issue persists on that branch as well.
### Testing
I did not find any regressions in the other examples during my testing,
but I'm not sure how to properly test this change.
If you create a `text_input` and set the border width to zero using
`.border_width(0.0)`, it simply fills the entire area with the border
color, and if focused, with a white color. Currently, a workaround for
this is to use some epsilon (e.g., 0.00001 as the border width), but
ideally we should just be able to use `0.0`, and in that case we
shouldn't be drawing any strokes anyway.
This PR simply adds a check to see if `stroke_width` is equal to zero,
and turns the `masonry::util::stroke` function into a no-op, but maybe
there is a more logical spot to do this.