live preview: Move repeated/conditional elements, too

Now that we move elements with ids, lets also move conditional and repeated
elements.

They have the same problem as elements with ids: They will probably break when
moved into different elements.
This commit is contained in:
Tobias Hunger 2024-05-07 20:53:23 +02:00 committed by Tobias Hunger
parent 51564c4cea
commit eb2f791f3c
3 changed files with 32 additions and 17 deletions

View file

@ -28,6 +28,25 @@ pub fn extract_element(node: SyntaxNode) -> Option<syntax_nodes::Element> {
}
}
fn find_element_with_decoration(element: &syntax_nodes::Element) -> SyntaxNode {
let this_node: SyntaxNode = element.clone().into();
element
.parent()
.and_then(|p| match p.kind() {
SyntaxKind::SubElement => p.parent().map(|gp| {
if gp.kind() == SyntaxKind::ConditionalElement
|| gp.kind() == SyntaxKind::RepeatedElement
{
gp
} else {
p
}
}),
_ => Some(this_node.clone()),
})
.unwrap_or(this_node)
}
#[derive(Clone)]
pub struct ElementRcNode {
pub element: ElementRc,
@ -83,6 +102,7 @@ impl ElementRcNode {
}
}
/// Run with all the debug information on the node
pub fn with_element_debug<R>(
&self,
func: impl Fn(
@ -95,6 +115,7 @@ impl ElementRcNode {
func(n, l)
}
/// Run with the `Element` node
pub fn with_element_node<R>(
&self,
func: impl Fn(&i_slint_compiler::parser::syntax_nodes::Element) -> R,
@ -103,6 +124,12 @@ impl ElementRcNode {
func(&elem.debug.get(self.debug_index).unwrap().0)
}
/// Run with the SyntaxNode incl. any id, condition, etc.
pub fn with_decorated_node<R>(&self, func: impl Fn(SyntaxNode) -> R) -> R {
let elem = self.element.borrow();
func(find_element_with_decoration(&elem.debug.get(self.debug_index).unwrap().0))
}
pub fn path_and_offset(&self) -> (PathBuf, u32) {
self.with_element_node(|n| {
(n.source_file.path().to_owned(), u32::from(n.text_range().start()))

View file

@ -192,14 +192,7 @@ fn delete_selected_element() {
return;
};
let Some(range) = selected_node.with_element_node(|n| {
if let Some(parent) = &n.parent() {
if parent.kind() == SyntaxKind::SubElement {
return util::map_node(parent);
}
}
util::map_node(n)
}) else {
let Some(range) = selected_node.with_decorated_node(|n| util::map_node(&n)) else {
return;
};

View file

@ -813,10 +813,8 @@ fn extract_text_of_element(
element: &common::ElementRcNode,
remove_properties: &[&str],
) -> Vec<String> {
let (start_offset, mut text) = element.with_element_node(|node| {
let parent = node.parent().unwrap();
debug_assert_eq!(parent.kind(), SyntaxKind::SubElement);
(usize::from(parent.text_range().start()), parent.text().to_string())
let (start_offset, mut text) = element.with_decorated_node(|node| {
(usize::from(node.text_range().start()), node.text().to_string())
});
let mut to_delete_ranges = property_ranges(element, remove_properties);
@ -958,11 +956,8 @@ pub fn move_element_to(
let mut edits = Vec::with_capacity(3);
let remove_me = element.with_element_node(|node| {
let parent = node.parent().unwrap();
debug_assert_eq!(parent.kind(), SyntaxKind::SubElement);
node_removal_text_edit(&parent, placeholder_text.clone())
})?;
let remove_me = element
.with_decorated_node(|node| node_removal_text_edit(&node, placeholder_text.clone()))?;
if remove_me.0.path() == source_file.path() {
selection_offset =
TextOffsetAdjustment::new(&remove_me.1, &source_file).adjust(selection_offset);