We use the setup_code for that for now, so apply the same logic as in the C++ generator.
However there's more work to be done later to make forward-focus work corectly into sub-components.
Consider this code:
```60
Foo := Rectangle {
animate y { /*...*/ }
x: some_binding;
}
Bar := Rectangle {
foo_instance := Foo {
y: some_binding;
animate x { /*...*/ }
}
}
```
We need to make sure that the binding are set with the right animation.
FIXME: the generator should actually handle this case without needing for inlining.
Also, this currently do not work if there is several level of "inheritence"
If there is a Expression::Invalid as a binding (because it has an animation,
for example) we must check that the binding expression in the base is not
constant.
This fixes the rust test `properties_animation_merging` without inlining
(The o4_val was considered constant despite it shouldn't be)
```
error[E0599]: no method named `unwrap` found for struct `sixtyfps::re_exports::OnceCell` in the current scope
--> .../test-driver-rust-0868c471dd25beed/out/imports_external_type.rs:384:29
|
384 | &_self.root.unwrap().upgrade(),
| ^^^^^^ method not found in `sixtyfps::re_exports::OnceCell<VWeak<sixtyfps::re_exports::ComponentVTable, imports_external_type::sixtyfps_generated_TestCase::InnerTestCase>>`
```
Treating the Tab key as text disallows handling Shift-Tab because
the shift modifier will not be passed down. This makes the
handling of Tab analogous to Escape, Return and other non-text
keycodes.
* Generate a visit_dynamic_children dispatch function in sub-components and call it
* Add a self_weak to sub-components
* Fix access to the window from within repeated components
* Fix the parent type of repeated elements within sub-components to be a VWeakMapped instead of VWeak
* Fix the build of the parent_item() implementation of repeated elements within sub-comps. The parent index might still be wrong, needs to be checked.
We generate a getter that hides the renaming. Instead of returning a field offset, we
might as well use the same code as for the value getter
and return a `Pin<&Property<T>>`.
What doesn't work yet are aliases to globals, because that
uses a temporary.
At the use-size a binding for width and height is created that
uses the layout info. So that function needs to be emitted for sub-components,
and access to the window needs to be provided as well.
There's cleanup for later, which is unifying the name (layout vs layouting)
and shortening the signature for
sub-component calls (no need for the window parameter).
As seen in 4116878357, we
sometimes get pipenv errors:
(truncated backtrace):
```
File "/usr/local/lib/python3.8/dist-packages/pipenv/patched/notpip/_vendor/certifi/core.py", line 51, in where 64
_CACERT_PATH = str(_CACERT_CTX.__enter__()) 65
File "/usr/lib/python3.8/contextlib.py", line 113, in __enter__ 66
return next(self.gen) 67
File "/usr/lib/python3.8/importlib/resources.py", line 184, in path 68
package = _get_package(package) 69
File "/usr/lib/python3.8/importlib/resources.py", line 47, in _get_package 70
module = import_module(package) 71
File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module 72
return _bootstrap._gcd_import(name[level:], package, level) 73
ModuleNotFoundError: No module named 'pip._vendor.certifi'
````
Previously we installed pip/pipenv via sudo install pipenv (via the GH
action). Doing a manual pip upgrade and user installation of pipenv
appears to not produce this error.
Declare a const getter function that retrieves the field offset and call it from access_member.
Right now the indirection through
the function is not needed, but
it will be necessary when supporting aliases.
instead of in the sixtyfps! macro, so se actually see where the error is in
the generated code.
This also expose a bunch of warning that were not being taken care on.
When we have
```
S1 := Rectangle {}
S2 := S1 {}
App := Window {
S2 {}
}
```
Then the right path to the rectangle is
offsetof(App, s2) + offsetof(S2, root) + offset(S1, rectangle)
The middle one was left out in C++, where it also probably doesn't matter
because the root is the first member (although it might not always remain that way).
In Rust the FieldOffset type generated won't allow for adding
together without the middle one.
Therefore visit_item() in the generator is changed to bring forward the sub-component
state when following the chain.
For now this requires pinning on the type contained in VRc as well as
the fields mapped to. This could be lifted using additional flags, but
for now this is what we need anyway.
* For sub-components create a super-primitive struct with just its fields
and a new() function to create it. There's no init() function yet.
* Provide access to the root item of the sub-component
This just makes the most trivial example work:
```
SubComp := Rectangle {}
App := Window {
SubComp {
background: green;
}
}
```
Pass the sub-component as a parameter in enter_component(), as it's needed in the C++
implementation, it's readily available (no need to unwrap again) and Rust will need it, too.
In the tree builder's enter_component we registered the sub-component as a member
and also registered the member initializer
in the constructor.
However the call to `init()` to initialize the bindings was registered in `enter_component_children` for no good reason.
It's cleaner to do that all in one place.
For the following reduced test-case the order in how the dynamic nodes
in the item tree were generated (and dyn indices assigned) differed from
the way the visit_dynamic_children slots were generated:
```
Blah := Rectangle {
for x in 1: Text {
text: "Should be on the right";
}
}
MainWindow := Window {
width: 772px;
height: 504px;
Text {
if (false): TouchArea {
}
}
Blah {
x: 200px;
}
}
```
The item tree node was constructed using build_item_tree, which
basically assigned dyn index 0 to the "repater" for the touch area
and "1" to the one for the repeater inside the sub-component.
Afterwards we traversed the element tree - without descending into the
sub-components - to generate the fields and the dispatch in in the
dynamic visitor. Here a subtle order would result in a mismatch of
indices:
recurse_elem_level_order would end up visiting Text, Blah and then
Text's children, assigning the first dynamic index to Blah.
This is now fixed by merging the two iterations into one.