mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-09 21:28:25 +00:00

Some checks are pending
autofix.ci / format_fix (push) Waiting to run
autofix.ci / lint_typecheck (push) Waiting to run
CI / files-changed (push) Waiting to run
CI / build_and_test (--exclude bevy-example, ubuntu-22.04, 1.82) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, --exclude bevy-example, windows-2022, 1.82) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, macos-14, stable) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, beta) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, stable) (push) Blocked by required conditions
CI / build_and_test (ubuntu-22.04, nightly) (push) Blocked by required conditions
CI / node_test (macos-14) (push) Blocked by required conditions
CI / node_test (ubuntu-22.04) (push) Blocked by required conditions
CI / node_test (windows-2022) (push) Blocked by required conditions
CI / python_test (macos-14) (push) Blocked by required conditions
CI / python_test (ubuntu-22.04) (push) Blocked by required conditions
CI / python_test (windows-2022) (push) Blocked by required conditions
CI / cpp_test_driver (macos-13) (push) Blocked by required conditions
CI / cpp_test_driver (ubuntu-22.04) (push) Blocked by required conditions
CI / cpp_test_driver (windows-2022) (push) Blocked by required conditions
CI / cpp_cmake (macos-14, 1.82) (push) Blocked by required conditions
CI / cpp_cmake (ubuntu-22.04, stable) (push) Blocked by required conditions
CI / cpp_cmake (windows-2022, nightly) (push) Blocked by required conditions
CI / cpp_package_test (push) Blocked by required conditions
CI / vsce_build_test (push) Blocked by required conditions
CI / mcu (pico-st7789, thumbv6m-none-eabi) (push) Blocked by required conditions
CI / mcu (pico2-st7789, thumbv8m.main-none-eabihf) (push) Blocked by required conditions
CI / mcu (stm32h735g, thumbv7em-none-eabihf) (push) Blocked by required conditions
CI / mcu-embassy (push) Blocked by required conditions
CI / ffi_32bit_build (push) Blocked by required conditions
CI / docs (push) Blocked by required conditions
CI / wasm (push) Blocked by required conditions
CI / wasm_demo (push) Blocked by required conditions
CI / tree-sitter (push) Blocked by required conditions
CI / updater_test (0.3.0) (push) Blocked by required conditions
CI / fmt_test (push) Blocked by required conditions
CI / esp-idf-quick (push) Blocked by required conditions
CI / android (push) Blocked by required conditions
CI / miri (push) Blocked by required conditions
CI / test-figma-inspector (push) Blocked by required conditions
This fixes the contents of the `n`-th repeater inside the `ComponentContainer` to also show up in the `n`-th repeater *after* the `ComponentContainer`. The ComponentContainer is lowered to a Comonent Container and a dynamic tree node. The tree node is managed manually and I messed up the repeater indices since there were no entries in the repeater array for the embedded components. That mad things hard to keep consistent as components get merged. This chnages that: It lowers a Component Container to Something like this: ```slint ComponentContainer { if false: Emtpy {} } ``` This way the standard mechanismns make sure we have something to put into the repeater list and that unscrews the indices, saving a bit of code along the way. The inserted repeated node is still marked as `is_component_placeholder`, so that we can wire it up as needed.
108 lines
3.9 KiB
Rust
108 lines
3.9 KiB
Rust
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
|
|
|
//! Assign the Element::item_index on each elements
|
|
|
|
use std::rc::Rc;
|
|
|
|
use crate::object_tree::{Component, ElementRc};
|
|
|
|
/// The item indices are generated and assigned to the ElementRc's item_index for each
|
|
/// element in the component. The indices are local to the component.
|
|
///
|
|
/// For sub-components the structure of the tree becomes a little complicated, which is best
|
|
/// illustrated using an example:
|
|
/// ```slint
|
|
/// SubCompo := Rectangle { Image {} }
|
|
/// MainCompo := Window {
|
|
/// TouchArea {}
|
|
/// SubCompo {}
|
|
/// Text {
|
|
/// Path {}
|
|
/// }
|
|
/// }
|
|
/// ```
|
|
/// The item tree for `MainCompo` with its local indices is as follows:
|
|
/// 0: Window (children: 3, children_offset: 1, parent_index: 0)
|
|
/// 1: TouchArea (children: 0, children_offset: X, parent_index: 0)
|
|
/// 2: Rectangle (children: 1, children_offset: 4, parent_index: 0) // SubCompo's root element
|
|
/// 3: Text (children: 1, children_offset: 5, parent_index: 0)
|
|
/// 4: Image (children: 0, children_offset: X, parent_index: 2) // SubCompo's child(ren)
|
|
/// 5: Path (children: 0, children_offset: X, parent_index: 3)
|
|
pub fn generate_item_indices(component: &Rc<Component>) {
|
|
// In order to create the local indices like in the above example (0-5) we use the same function
|
|
// that is also used for building the item tree. It recurses into all sub-components, but we skip
|
|
// them, by checking if the SubComponentState is true.
|
|
// The immediate children of for example the Window element are emitted first. When a sub-component
|
|
// is encountered (like `SubCompo`) the root element is emitted, but the children later. This simulates
|
|
// the structure as if the SubCompo was inlined, but it also means that the local item indices must be
|
|
// counted continuously.
|
|
crate::generator::build_item_tree(component, &false, &mut Helper { current_item_index: 0 });
|
|
for p in component.popup_windows.borrow().iter() {
|
|
generate_item_indices(&p.component)
|
|
}
|
|
for c in component.menu_item_tree.borrow().iter() {
|
|
generate_item_indices(c);
|
|
}
|
|
}
|
|
|
|
struct Helper {
|
|
current_item_index: u32,
|
|
}
|
|
impl crate::generator::ItemTreeBuilder for Helper {
|
|
// true when not at the root
|
|
type SubComponentState = bool;
|
|
|
|
fn push_repeated_item(
|
|
&mut self,
|
|
item: &ElementRc,
|
|
_repeater_count: u32,
|
|
_parent_index: u32,
|
|
component_state: &Self::SubComponentState,
|
|
) {
|
|
if !component_state {
|
|
item.borrow().item_index.set(self.current_item_index).unwrap();
|
|
if let crate::langtype::ElementType::Component(c) = &item.borrow().base_type {
|
|
generate_item_indices(c);
|
|
}
|
|
}
|
|
self.current_item_index += 1;
|
|
}
|
|
|
|
fn push_native_item(
|
|
&mut self,
|
|
item: &ElementRc,
|
|
children_offset: u32,
|
|
_parent_index: u32,
|
|
component_state: &Self::SubComponentState,
|
|
) {
|
|
if !component_state {
|
|
item.borrow().item_index.set(self.current_item_index).unwrap();
|
|
item.borrow().item_index_of_first_children.set(children_offset as _).unwrap();
|
|
}
|
|
self.current_item_index += 1;
|
|
}
|
|
|
|
fn enter_component(
|
|
&mut self,
|
|
item: &ElementRc,
|
|
_sub_component: &Rc<Component>,
|
|
children_offset: u32,
|
|
component_state: &Self::SubComponentState,
|
|
) -> Self::SubComponentState {
|
|
if !component_state {
|
|
item.borrow().item_index.set(self.current_item_index).unwrap();
|
|
item.borrow().item_index_of_first_children.set(children_offset as _).unwrap();
|
|
}
|
|
true
|
|
}
|
|
|
|
fn enter_component_children(
|
|
&mut self,
|
|
_item: &ElementRc,
|
|
_repeater_count: u32,
|
|
_component_state: &Self::SubComponentState,
|
|
_sub_component_state: &Self::SubComponentState,
|
|
) {
|
|
}
|
|
}
|