This is the smallest change possible to make animations work in Masonry.
Essentially, we treat every redraw as a potential animation frame, so
that animations do work.
I've also added the `spinner` view in Xilem to test this out. The
`state_machine` examples uses this.
This is work done for the variable fonts demo.
See also linebender/vello#439
This should open the door to doing much more comprehensive testing at
higher level in the nearish future (including e.g. in `xilem_masonry`)
`masonry::text::edit::TextEditor` should emit an
`Action::TextChanged(...)` also on `Backspace` and `Delete` if anything
was deleted, so that e.g. `xilem::view::textbox::Textbox` receives this
action. This is already implemented for `Ctrl+Backspace` and
`Ctrl+Delete`.
The code changes are not elegant, but intended to be minimally invasive.
Local `cargo test` failed for the modified and an unmodified code, but
sometimes with different errors—which I do not quite understand.
I apologize in advance for any mistakes on my part, I've never before
worked on open source repos and did not find any guideline for your
project.
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>
There is one "semi-false-positive" lint triggered, which I have fixed.
Otherwise, the required
```
cargo upgrade --ignore-rust-version
cargo update
```
This was remarkably painless.
I especially appreciate @taiki-e providing an install-action which does
90% of the CI work for us.
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
Takes ideas from #235 (in particular the masonry side).
This implements support for explicit spacers in the `Flex` view and flex
parameters for views (see examples `flex` and `mason` for more details).
It also adds a way (`AnyFlexChild`) to dynamically switch between
spacers and widgets (with optional flex parameters).
`masonry::widget::Flex::layout` is also updated to be in sync with
current druid.
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
See discussion in [#linebender > Standard Lint
set](https://xi.zulipchat.com/#narrow/stream/419691-linebender/topic/Standard.20Lint.20set)
Of note: I have taken steps to ensure that this can be practically
reviewed by *not* applying most of the lints.
The commented out lints make good follow-ups
---------
Co-authored-by: Olivier FAURE <couteaubleu@gmail.com>
Supercedes https://github.com/linebender/xilem/pull/411
This is designed with #417 in mind, to not lock-in to our event loop.
---------
Co-authored-by: Philipp Mildenberger <philipp@mildenberger.me>
These changes allow you to create a masonry or xilem app that is driven
by an external event loop.
## Masonry
Existing method for creating masonry app:
```
masonry::event_loop_runner::run(
masonry::event_loop_runner::EventLoop::with_user_event(),
window_attributes,
root_widget,
app_driver,
)
.unwrap();
```
Instead you can now do this:
```
let masonry_state = MasonryState::new(window_attributes, &event_loop, root_widget);
let mut app = AppInterface {
masonry_state,
app_driver: Box::new(driver),
};
event_loop.run_app(&mut app)
```
Where AppInterface implements the winit
ApplicationHandler<accesskit_winit::Event> trait.
## Xilem
Existing method:
```
let app = Xilem::new(state, app_logic);
app.run_windowed(EventLoop::with_user_event(), title)?;
```
Now:
```
let xilem = Xilem::new(0, app_logic);
let (root_widget, app_driver) = xilem.split();
let parts = xilem.split();
let (root_widget, app_driver) = (parts.root_widget, parts.driver)
// and then create masonry app just like above using root_widget and app_driver
```
Also adds example/external_event_loop.rs which duplicates
example/flex.rs but with an external event loop.
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
Related to #44
We don't have any necessary unsafe code, and I don't think any of us
want to lose that.
(Vello is also no longer laundering the unsafety wrt surface creation
thanks to a recent wgpu release)
I had trouble getting masonry to compile for iOS due to a winit platform
method call that's not supported. There's already a cfg for android so I
just added iOS to it.
Reproduction:
```
cargo check --target aarch64-apple-ios
```
---------
Co-authored-by: Daniel McNab <36049421+DJMcNab@users.noreply.github.com>
This was most recently updated in
https://github.com/linebender/vello/pull/505
The main differences are:
1) Greater concurrency between clippy and testing
2) More explanations
3) MSRV checking
4) Use of `cargo hack`
5) WASM checked in CI
I've also added the current values of our MSRVs to the main three
crates.
Format:
```rust
label("everything").text_size(42.)
```
and the same with `prose`.
I've also added `font_size` aliases for these, because people will
expect it to have these names.
Since #314, we request the IME to be positioned every paint cycle. This
triggers a new event from the IME, which is a preedit clear. This IME
event also breaks text selection, which is why we handle it here.
This is still not the fully correct behaviour, but it does at least make
text selection in textboxes work again. We really need to improve our
testing story here.
Also give more detail in the short form of IME events; these events all
have quite different properties.
Based on a suggestion from @dfrg.
This appears to have improved performance with the 30_000 hello's
example from ~$\frac{1}{20}$ms to $\frac{1}{160}$ms
So an approx 8x increase in throughput for that scene.
In most cases, you want a button which only actuates when the primary
mouse button is pressed, so the easy case is still that. This is a short
term hack, because e.g. the active state is still based on any button
being pressed, not just those we are interested in.
That is, we probably need to represent a set of buttons we are
interested in. However, this change minimally unblocks additional work
with Xilem. In particular, see [#xilem > Minesweeper converted from Iced
to
Xilem](https://xi.zulipchat.com/#narrow/stream/354396-xilem/topic/Minesweeper.20converted.20from.20Iced.20to.20Xilem).
This:
1) Renames the current/old `xilem_core` to `xilem_web_core` and moves it
to the `xilem_web/xilem_web_core` folder
2) Creates a new `xilem_core`, which does not use (non-tuple) macros and
instead contains a `View` trait which is generic over the `Context` type
3) Ports `xilem` to this `xilem_core`, but with some functionality
missing (namely a few of the extra views; I expect these to
straightforward to port)
4) Ports the `mason` and `mason_android` examples to this new `xilem`,
with less functionality.
This continues ideas first explored in #235
The advantages of this new View trait are:
1) Improved support for ad-hoc views, such as views with additional
attributes.
This will be very useful for layout algorithms, and will also enable
native *good* multi-window (and potentially menus?)
2) A lack of macros, to better enable using go-to-definition and other
IDE features on the traits
Possible disadvantages:
1) There are a few more traits to enable the flexibility
2) It can be less clear what `Self::Element::Mut` is in the `rebuild`
function, because of how the resolution works
3) When implementing `View`, you need to specify the context (i.e.
`impl<State, Action> View<State, Action, [new] ViewCtx> for
Button<State, Action>`.
---------
Co-authored-by: Philipp Mildenberger <philipp@mildenberger.me>
This brings the `PointerButton` enum from glazier and has all code
outside of the winit event loop integration using it.
For now, it has a `todo!()` for the `MouseButton::Other` as it isn't
clear what that is for.
This was initially a supposed to be a small documentation pass, which
grew into a few changes:
- Adding back a to-do-list example.
- Fixing the bugs revealed by that example (infinite bounding boxes,
wrong accessibility handling in Portal, etc).
- Making sure all widgets return the correct spans instead of the
less-useful default one.
- Adding a trace to the layout pass for easier debugging.
Overall I'm pretty happy with this!
Recently, `instant` has been marked as unmaintained by the maintainer. A
suggested replacement is `web-time`, which is used by `winit` and is
already in our dependency tree.
This allows for running `masonry` with an externally managed event loop
for integrating with an application that is already running an event
loop.
* Expose `PointerState` to allow creating `PointerEvent`
* Expose `WindowEvent` to allow managing window size and scale factor.
* Make `DriverCtx` usable from outside the crate. While this struct was
already `pub`, the sole member of it was not.
In the call to updating the hot state from the widget pod, the
`mouse_pos` is already of the right type, so it doesn't need to try to
reconstruct itself as the right type.
This is different from another call site (in `contexts.rs`) where the
`mouse_pos` is an `Option<Point>` and so it does need reconstructing.
This removes a class of dependencies from within both `masonry` and
`xilem` on the `winit` crate where we can just use `dpi` directly
instead.
The `dpi` crate is meant (like `cursor_icon`) to be a shared ecosystem
crate rather than only for usage with `winit`.
`cursor_icon` is a crate that is used by `winit` to provide its
`CursorIcon` type separately from the `winit` crate.
This re-exports the `CursorIcon` from `masonry` and then uses that
rather than via `winit:🪟:CursorIcon`, allowing the use of the
`CursorIcon` without having to independently discover its provenance.
This is also one step towards not requiring `winit` within the `masonry`
internals apart from the actual window / event loop management.