Using #component_id::item_tree for it does not work because the
public component id is not the right one, we need the one from
the current item tree which is not known at compile time
(could be several if the component is re-used accross item trees)
Also disable the code that sets the focus to the focued element for anything
but the window component: before, the setup code was only run for the
non-sub component, but now it is run for every sub component, and we
don't want to set the focus to anything that has a forward focus property
Opacity, visible and shadows on repeated elements work by replacing the
root element with a new element (opacity, visible clip, etc.) and making
the old one a child.
A tree like this
```
l := VerticalLayout {
for i in 1: Rectangle {
background: green;
opacity: 0.2;
}
}
```
is lowered like so (pseudo):
```
l := VerticalLayout {
for i in 1: Opacity {
opacity <=> r.opacity;
r := Rectangle {
background: green;
opacity: 0.2;
y: layout_cache[i].y;
width: l.width;
height: layout_cache[i].height;
}
}
}
```
and when rendering, it's important that the opacity of the Opacity
element is applied on the item renderer before rendering the Rectangle
r.
The Opacity element has no width/height because the default geometry
pass won't apply that to children of a layout.
Without a geometry, the item rendere will not call render() (no
intersection with the current clip), and thus the opacity is not
applied.
The shadow lowering pass handles this correctly, by moving the geometry
property bindings to the new root and letting the default geometry pass
apply 100% defaults (in the above "r" is not a layout child).
This patch moves this logic into the common
inject_element_as_repeated_element, so that we end up with a lowering
like this (after the default geometry pass):
```
l := VerticalLayout {
for i in 1: op := Opacity {
opacity <=> r.opacity;
width: l.width;
height: layout_cache[i].height;
y: layout_cache[i].y;
r := Rectangle {
background: green;
opacity: 0.2;
width: op.width;
height: op.height;
}
}
}
```
For the MCU port, we need to proccess the image to save them in the binary
in a convenient format.
This patch start this work by trying to anaylyze what format should an image
be using, and saving it as a texture in the binary.
The current graphical backend and the C++ frontend are not yet supported
This will allow later to be able to operate on the binding despite the
element is borrowed.
Since the Binding itself is in a RefCell, the analysis don't need to
be anymore.
To do this change, a small change in the binding_analysis logic was required
which means that we will now detect binding loop if a binding was causing
two binding loop. (before, only one binding loop was detected)
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.
Provide a layout_info implementation for sub-components and call it. This
disables the lowering the implicit_layout_info call again,
also to ensure that when this
is installed from the use-site of the sub-component, the self can be used to obtain
the info (by calling the new generated function).
For the item index generation and the member population for the C++
structs, a level-order variant of `recurse_elem` is sufficient - as also
indicate by the unused item index parameters.
Besides `is_global()` add `is_root_component` to Rc<Component>, so that
we can distinguish between the main component (that should have the full
API, etc.) and supplementary components.
This also avoids the generation of unnecessary members when inlining is
disabled.
The generation is still incomplete, but this change passes them to the C++ generator
when not inlining.
Another option would've been a "inline: bool", but that won't suffice in
the future when we may want to use heuristics to selectively inline some
and others not. And always taking used_types.sub_components is wrong
when inlining as those are ... inlined.
Revert part of the previous commit that tries to do all the pass without inlining
Fixup the few first passes so they work without inlining, but still do a full
inlining for most passes
The goal is to make it work pass by pass until we can have everything without
requiring full inlining
So that the `debug_assert!` that fires when a error message ends with a
period does not crash the LSP when typing an incomplete filename that ends
with a '.'
We just need to adjust the priority of the default binding to be a high value
(eg, less priority) since the other values must always win.
This fixes the placeholder text color
When an animate foo {} declaration ends up creating an synthetic, invalid BindingExpression,
we still need to give it a span, to ensure that the diagnostics
produced later have *some* location set.
Fixes#515
Remove the internal name again and pick the first exported one when
assigning ids. This avoids internal names showing up in code completion
or the internal types leaking into generated code.
When exporting an global multiple times under different names, make sure
that they alias in the generated code.
As a consequence, the compiler maintains the original unique name and in
Rust and C++ makes only the exported names public. In the interpreter
the internal name is theoretically still accessible from the outside.
Don't put them in a fake expression.
This simplifies a bit the expression handling, and will make
possible to fix analysis that needs a vew into the aliases
As a result
- The error messages will now show the error with `-` instead of `_`
- The LSP will auto-complete with -
- The interpreter's list of properties will list the property with '-'
(but we made the change so that set_property, get_property, and so on
work also if passed a '-')
Commit 064c39d625 introduced the regression that
if a two-way binding was set on a property that we'd also set a default geometry
on, we'd end up applying that on the two-way binding, causing a binding loop.
set_binding_if_not_set needs to only set the binding if... there's really none yet.
Fixes#385
When an element gets its width and height from the parent through an implicit 100% binding,
those bindings were missing when an animation was pre-defined.
The provided new-type wrapper offers a function to deal with replacing just
binding expression, instead of the
expression *and* the animation.
Fixes#376