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)
Somehow the focus_change_subcompo test missed this case and the visible
issue of this off-by-one was that
the combo boxes in the printer demo's settings page opened at the wrong location (wrong parent).
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.
Some code like this was generated:
`if (*self->checkbox_31.get_checked()).get()`
the remove_parentheses function removed a parentheses that it shouldn't have removed
focus() is implemented by calling set_focus() on the window with the absolute item
index as a parameter. The
generate_item_indices pass generates local item indicies,
which need to made absolute.
Sadly there exists a gap in the item tree between the root element of a sub-component
and its children. Therefore each sub-component gets two members passed to the constructor,
the tree_index and tree_index_of_first_child.
The former is to be used when the local index is zero (indicates the root).
The latter is used as base for any children.
The variable in C++ sub-components is sometimes unused. We could try to lazily emit it, but
that requires more work and this is distracting :-). This silencing should hopefully also work for gcc.
This reverts commit fde3846392 because it
breaks the gcc build ("error: 'maybe_unused' attribute ignored
[-Werror=attributes]"). Will need a different solution that works for
clang (which warns about m_root_ being unused).
Calling init on sub-components with self_weak as argument only works after self_weak is
initialized, which happens in create(). So a new init() function for root components is called afterwards.
By accident the tree was still depth-first instead of level-order. This implementation works better,
by placing the root element of sub-components as
parents and the children into the children space later.
There's still more work to do to clean it up and make work with more complex scenarios.
When the use-site of a component tries to set a binding on a property that is an alias,
it might be that the alias was optimized away.
To avoid needeless recursion, this patch generates a mutable property getter
for declared properties (which takes care of alias redirection).
This also removes the use of root_item() because it's insufficient: If the property is custom (and/or an alias), then we need to use the getter,
otherwise we need to recurse.
So there are three cases:
```
MyButton {
text: "Ok";
}
```
If `MyButton` is `MyButton := Rectangle { property<string> text; }` then
we go through the mutable prop reference getter. This also works for aliases.
If it's `MyButton := Text { ... }` or (more complex) `L := Text {} MyButton := L {}` then
we recurse.
Traditionally the recursion is not needed because in public API the "inherited" properties
aren't expose. But since in the language they are exposed, we need to continue.
As a bonus this cleans up the property access code a little by re-using access_member.
* Forward declare the root component
* Pass it as a parameter to the constructor and save it as m_root pointer and use it to access globals
* Make the sub-components friends of the root component, in order to access the globals
* Delay binding initialization to an explicit init() call in sub-components
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.
In the generator for producing the members of built-in items, repeaters
or sub-components, we don't need to traverse into sub-components. The
C++ compiler will take care of instantiating the fields of
sub-components after all.
For the item tree however we do need to recurse, so this change attempts
to do that. Repeaters are explicitly not handled yet though.
Instead of requiring inlining, assume that the generated code will provide an
implementation of layouting_info as well as root_item.
They're not implemented yet though.
Within sub-components we only know the local item index, and together with the
offset provided in the constructor we'll be able to
compute the correct index for items that's needed sometimes,
for example for focus setting.
The item indices are still wrong though, that'll need fixing in the corresponding pass.