mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-03 13:23:00 +00:00
interpreter: Return the ElementRc + index, not just the ElementRc
This way we do not have to check the ElementRc once more to find the node in its debug data.
This commit is contained in:
parent
b4a20b2c47
commit
15fb452017
5 changed files with 56 additions and 43 deletions
|
|
@ -1221,12 +1221,12 @@ impl ComponentInstance {
|
|||
///
|
||||
/// WARNING: this is not part of the public API
|
||||
#[cfg(feature = "highlight")]
|
||||
pub fn element_at_source_code_position(
|
||||
pub fn element_node_at_source_code_position(
|
||||
&self,
|
||||
path: &Path,
|
||||
offset: u32,
|
||||
) -> Vec<i_slint_compiler::object_tree::ElementRc> {
|
||||
crate::highlight::element_at_source_code_position(&self.inner, path, offset)
|
||||
) -> Vec<(i_slint_compiler::object_tree::ElementRc, usize)> {
|
||||
crate::highlight::element_node_at_source_code_position(&self.inner, path, offset)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,10 +37,11 @@ pub(crate) fn component_positions(
|
|||
generativity::make_guard!(guard);
|
||||
let c = component_instance.unerase(guard);
|
||||
|
||||
let elements = find_element_at_offset(&c.description().original, path, offset);
|
||||
let elements =
|
||||
find_element_node_at_source_code_position(&c.description().original, path, offset);
|
||||
collect_highlight_data(
|
||||
component_instance,
|
||||
&elements.into_iter().map(|e| Rc::downgrade(&e)).collect::<Vec<_>>(),
|
||||
&elements.into_iter().map(|(e, _)| Rc::downgrade(&e)).collect::<Vec<_>>(),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -58,15 +59,15 @@ pub(crate) fn element_positions(
|
|||
values
|
||||
}
|
||||
|
||||
pub(crate) fn element_at_source_code_position(
|
||||
pub(crate) fn element_node_at_source_code_position(
|
||||
component_instance: &DynamicComponentVRc,
|
||||
path: &Path,
|
||||
offset: u32,
|
||||
) -> Vec<ElementRc> {
|
||||
) -> Vec<(ElementRc, usize)> {
|
||||
generativity::make_guard!(guard);
|
||||
let c = component_instance.unerase(guard);
|
||||
|
||||
find_element_at_offset(&c.description().original, path, offset)
|
||||
find_element_node_at_source_code_position(&c.description().original, path, offset)
|
||||
}
|
||||
|
||||
fn fill_highlight_data(
|
||||
|
|
@ -113,8 +114,12 @@ fn fill_highlight_data(
|
|||
}
|
||||
|
||||
// Go over all elements in original to find the one that is highlighted
|
||||
fn find_element_at_offset(component: &Rc<Component>, path: &Path, offset: u32) -> Vec<ElementRc> {
|
||||
let mut result = Vec::<ElementRc>::new();
|
||||
fn find_element_node_at_source_code_position(
|
||||
component: &Rc<Component>,
|
||||
path: &Path,
|
||||
offset: u32,
|
||||
) -> Vec<(ElementRc, usize)> {
|
||||
let mut result = Vec::new();
|
||||
i_slint_compiler::object_tree::recurse_elem_including_sub_components(
|
||||
component,
|
||||
&(),
|
||||
|
|
@ -122,9 +127,15 @@ fn find_element_at_offset(component: &Rc<Component>, path: &Path, offset: u32) -
|
|||
if elem.borrow().repeated.is_some() {
|
||||
return;
|
||||
}
|
||||
for node in elem.borrow().debug.iter().filter_map(|n| n.0.QualifiedName()) {
|
||||
for (index, node) in elem
|
||||
.borrow()
|
||||
.debug
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, n)| n.0.QualifiedName().map(|n| (i, n)))
|
||||
{
|
||||
if node.source_file.path() == path && node.text_range().contains(offset.into()) {
|
||||
result.push(elem.clone());
|
||||
result.push((elem.clone(), index));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -30,6 +30,12 @@ impl std::fmt::Debug for ElementRcNode {
|
|||
}
|
||||
|
||||
impl ElementRcNode {
|
||||
pub fn new(element: ElementRc, debug_index: usize) -> Option<Self> {
|
||||
let _ = element.borrow().debug.get(debug_index)?;
|
||||
|
||||
Some(Self { element, debug_index })
|
||||
}
|
||||
|
||||
pub fn find_in(element: ElementRc, path: &std::path::Path, offset: u32) -> Option<Self> {
|
||||
let debug_index = element.borrow().debug.iter().position(|(n, _)| {
|
||||
u32::from(n.text_range().start()) == offset && n.source_file.path() == path
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||
|
||||
use crate::common::{self, ComponentInformation, PreviewComponent, PreviewConfig};
|
||||
use crate::common::{self, ComponentInformation, ElementRcNode, PreviewComponent, PreviewConfig};
|
||||
use crate::lsp_ext::Health;
|
||||
use crate::preview::element_selection::ElementSelection;
|
||||
use crate::util;
|
||||
|
|
@ -423,24 +423,26 @@ pub fn load_preview(preview_component: PreviewComponent) {
|
|||
|
||||
if notify_editor {
|
||||
if let Some(component_instance) = component_instance() {
|
||||
if let Some(element) = component_instance
|
||||
.element_at_source_code_position(&se.path, se.offset)
|
||||
if let Some((element, debug_index)) = component_instance
|
||||
.element_node_at_source_code_position(&se.path, se.offset)
|
||||
.first()
|
||||
{
|
||||
if let Some((node, _)) =
|
||||
element.borrow().debug.iter().find(|n| !is_element_node_ignored(&n.0))
|
||||
{
|
||||
let Some(element_node) = ElementRcNode::new(element.clone(), *debug_index)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let (path, pos) = element_node.with_element_node(|node| {
|
||||
let sf = &node.source_file;
|
||||
let pos = util::map_position(sf, se.offset.into());
|
||||
(sf.path().to_owned(), util::map_position(sf, se.offset.into()))
|
||||
});
|
||||
ask_editor_to_show_document(
|
||||
&se.path.to_string_lossy(),
|
||||
&path.to_string_lossy(),
|
||||
lsp_types::Range::new(pos, pos),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -534,29 +536,22 @@ pub fn highlight(url: Option<Url>, offset: u32) {
|
|||
}
|
||||
cache.highlight = highlight;
|
||||
|
||||
let selected = selected_element();
|
||||
|
||||
if cache.highlight.as_ref().map_or(true, |(url, _)| cache.dependency.contains(url)) {
|
||||
run_in_ui_thread(move || async move {
|
||||
let Some(component_instance) = component_instance() else {
|
||||
return;
|
||||
};
|
||||
let Some(path) = url.and_then(|u| Url::to_file_path(&u).ok()) else {
|
||||
return;
|
||||
};
|
||||
let elements = component_instance.element_at_source_code_position(&path, offset);
|
||||
if let Some(e) = elements.first() {
|
||||
let Some(debug_index) = e.borrow().debug.iter().position(|(n, _)| {
|
||||
n.text_range().contains(offset.into()) && n.source_file.path() == path
|
||||
}) else {
|
||||
|
||||
if Some((path.clone(), offset)) == selected.map(|s| (s.path, s.offset)) {
|
||||
// Already selected!
|
||||
return;
|
||||
};
|
||||
let is_layout =
|
||||
e.borrow().debug.get(debug_index).map_or(false, |(_, l)| l.is_some());
|
||||
element_selection::select_element_at_source_code_position(
|
||||
path, offset, is_layout, None, false,
|
||||
);
|
||||
} else {
|
||||
element_selection::unselect_element();
|
||||
}
|
||||
// TODO: false is wrong for is_layout here, but we will replace that soon anyway!
|
||||
element_selection::select_element_at_source_code_position(
|
||||
path, offset, false, None, false,
|
||||
);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,9 @@ impl ElementSelection {
|
|||
pub fn as_element(&self) -> Option<ElementRc> {
|
||||
let component_instance = super::component_instance()?;
|
||||
|
||||
let elements = component_instance.element_at_source_code_position(&self.path, self.offset);
|
||||
elements.get(self.instance_index).or_else(|| elements.first()).cloned()
|
||||
let elements =
|
||||
component_instance.element_node_at_source_code_position(&self.path, self.offset);
|
||||
elements.get(self.instance_index).or_else(|| elements.first()).map(|(e, _)| e.clone())
|
||||
}
|
||||
|
||||
pub fn as_element_node(&self) -> Option<ElementRcNode> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue