From ed683d261103bbbc64bf9e5f6845da6247611cd7 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Fri, 6 Dec 2024 20:04:05 +1300 Subject: [PATCH] Upgrade to parley w/masonry changes Signed-off-by: Nico Burns --- Cargo.toml | 2 +- packages/blitz-dom/src/document.rs | 9 +-- packages/blitz-dom/src/events/keyboard.rs | 78 ++++++++----------- packages/blitz-dom/src/layout/construct.rs | 27 ++++--- packages/blitz-dom/src/node.rs | 8 +- .../src/renderer/render.rs | 2 +- 6 files changed, 57 insertions(+), 69 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a1b8fbb9..4c0f61c7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,7 +42,7 @@ taffy = { version = "0.6", default-features = false, features = ["std", "flexbox # Linebender + WGPU peniko = "0.2" vello = { version = "0.3", features = [ "wgpu" ] } -parley = { version = "0.2", git = "https://github.com/linebender/parley", rev = "aa58a6e190cc75b4695b04adb0343d2bc694ba7e" } +parley = { version = "0.2", git = "https://github.com/linebender/parley", rev = "d9a2538184d4f689b8472acaecef0efa78229289" } wgpu = "22.1.0" # SVG dependencies diff --git a/packages/blitz-dom/src/document.rs b/packages/blitz-dom/src/document.rs index fa888f76..1f7a0299 100644 --- a/packages/blitz-dom/src/document.rs +++ b/packages/blitz-dom/src/document.rs @@ -171,11 +171,10 @@ impl DocumentLike for Document { { let x = (hit.x - content_box_offset.x) as f64 * self.viewport.scale_f64(); let y = (hit.y - content_box_offset.y) as f64 * self.viewport.scale_f64(); - text_input_data.editor.transact( - &mut self.font_ctx, - &mut self.layout_ctx, - |txn| txn.move_to_point(x as f32, y as f32), - ); + text_input_data + .editor + .driver(&mut self.font_ctx, &mut self.layout_ctx) + .move_to_point(x as f32, y as f32); self.set_focus_to(hit.node_id); } else if el.name.local == local_name!("input") diff --git a/packages/blitz-dom/src/events/keyboard.rs b/packages/blitz-dom/src/events/keyboard.rs index f86c82e8..7fc43041 100644 --- a/packages/blitz-dom/src/events/keyboard.rs +++ b/packages/blitz-dom/src/events/keyboard.rs @@ -26,13 +26,7 @@ pub(crate) fn apply_keypress_event( } }; - // Small macro to reduce boilerplate - macro_rules! transact { - ($op:expr) => {{ - editor.transact(font_ctx, layout_ctx, $op); - }}; - } - + let mut driver = editor.driver(font_ctx, layout_ctx); match event.logical_key { #[cfg(not(target_os = "android"))] Key::Character(c) if action_mod && matches!(c.as_str(), "c" | "x" | "v") => { @@ -40,123 +34,119 @@ pub(crate) fn apply_keypress_event( match c.to_lowercase().as_str() { "c" => { - if let Some(text) = editor.selected_text() { + if let Some(text) = driver.editor.selected_text() { let mut cb = Clipboard::new().unwrap(); cb.set_text(text.to_owned()).ok(); } } "x" => { - if let Some(text) = editor.selected_text() { + if let Some(text) = driver.editor.selected_text() { let mut cb = Clipboard::new().unwrap(); cb.set_text(text.to_owned()).ok(); - transact!(|txn| txn.delete_selection()) + driver.delete_selection() } } "v" => { let mut cb = Clipboard::new().unwrap(); let text = cb.get_text().unwrap_or_default(); - transact!(|txn| txn.insert_or_replace_selection(&text)) + driver.insert_or_replace_selection(&text) } _ => unreachable!(), } } Key::Character(c) if action_mod && matches!(c.to_lowercase().as_str(), "a") => { if shift { - transact!(|txn| txn.collapse_selection()) + driver.collapse_selection() } else { - transact!(|txn| txn.select_all()) + driver.select_all() } } Key::Named(NamedKey::ArrowLeft) => { if action_mod { if shift { - transact!(|txn| txn.select_word_left()) + driver.select_word_left() } else { - transact!(|txn| txn.move_word_left()) + driver.move_word_left() } } else if shift { - transact!(|txn| txn.select_left()) + driver.select_left() } else { - transact!(|txn| txn.move_left()) + driver.move_left() } } Key::Named(NamedKey::ArrowRight) => { if action_mod { if shift { - transact!(|txn| txn.select_word_right()) + driver.select_word_right() } else { - transact!(|txn| txn.move_word_right()) + driver.move_word_right() } } else if shift { - transact!(|txn| txn.select_right()) + driver.select_right() } else { - transact!(|txn| txn.move_right()) + driver.move_right() } } Key::Named(NamedKey::ArrowUp) => { if shift { - transact!(|txn| txn.select_up()) + driver.select_up() } else { - transact!(|txn| txn.move_up()) + driver.move_up() } } Key::Named(NamedKey::ArrowDown) => { if shift { - transact!(|txn| txn.select_down()) + driver.select_down() } else { - transact!(|txn| txn.move_down()) + driver.move_down() } } Key::Named(NamedKey::Home) => { if action_mod { if shift { - transact!(|txn| txn.select_to_text_start()) + driver.select_to_text_start() } else { - transact!(|txn| txn.move_to_text_start()) + driver.move_to_text_start() } } else if shift { - transact!(|txn| txn.select_to_line_start()) + driver.select_to_line_start() } else { - transact!(|txn| txn.move_to_line_start()) + driver.move_to_line_start() } } Key::Named(NamedKey::End) => { if action_mod { if shift { - transact!(|txn| txn.select_to_text_end()) + driver.select_to_text_end() } else { - transact!(|txn| txn.move_to_text_end()) + driver.move_to_text_end() } } else if shift { - transact!(|txn| txn.select_to_line_end()) + driver.select_to_line_end() } else { - transact!(|txn| txn.move_to_line_end()) + driver.move_to_line_end() } } Key::Named(NamedKey::Delete) => { if action_mod { - transact!(|txn| txn.delete_word()) + driver.delete_word() } else { - transact!(|txn| txn.delete()) + driver.delete() } } Key::Named(NamedKey::Backspace) => { if action_mod { - transact!(|txn| txn.backdelete_word()) + driver.backdelete_word() } else { - transact!(|txn| txn.backdelete()) + driver.backdelete() } } Key::Named(NamedKey::Enter) => { // TODO: support multi-line text inputs - // transact!(|txn| txn.insert_or_replace_selection("\n")) - } - Key::Named(NamedKey::Space) => { - transact!(|txn| txn.insert_or_replace_selection(" ")) - } - Key::Character(s) => { - transact!(|txn| txn.insert_or_replace_selection(&s)) + // driver.insert_or_replace_selection("\n") } + Key::Named(NamedKey::Space) => driver.insert_or_replace_selection(" "), + Key::Character(s) => driver.insert_or_replace_selection(&s), _ => {} }; } diff --git a/packages/blitz-dom/src/layout/construct.rs b/packages/blitz-dom/src/layout/construct.rs index c2e0243b..9d117967 100644 --- a/packages/blitz-dom/src/layout/construct.rs +++ b/packages/blitz-dom/src/layout/construct.rs @@ -665,20 +665,19 @@ fn create_text_editor(doc: &mut Document, input_element_id: usize, is_multiline: let element = &mut node.raw_dom_data.downcast_element_mut().unwrap(); if !matches!(element.node_specific_data, NodeSpecificData::TextInput(_)) { let mut text_input_data = TextInputData::new(is_multiline); - let text = element.attr(local_name!("value")).unwrap_or(" "); - let styles: Arc<[_]> = Arc::from([ - StyleProperty::FontSize(parley_style.font_size), - StyleProperty::LineHeight(parley_style.line_height), - StyleProperty::Brush(parley_style.brush), - ]); - text_input_data - .editor - .transact(&mut doc.font_ctx, &mut doc.layout_ctx, |txn| { - txn.set_text(text); - txn.set_scale(doc.viewport.scale_f64() as f32); - txn.set_width(None); - txn.set_default_style(styles); - }); + let editor = &mut text_input_data.editor; + + editor.set_text(element.attr(local_name!("value")).unwrap_or(" ")); + editor.set_scale(doc.viewport.scale_f64() as f32); + editor.set_width(None); + + let styles = editor.edit_styles(); + styles.insert(StyleProperty::FontSize(parley_style.font_size)); + styles.insert(StyleProperty::LineHeight(parley_style.line_height)); + styles.insert(StyleProperty::Brush(parley_style.brush)); + + editor.refresh_layout(&mut doc.font_ctx, &mut doc.layout_ctx); + element.node_specific_data = NodeSpecificData::TextInput(text_input_data); } } diff --git a/packages/blitz-dom/src/node.rs b/packages/blitz-dom/src/node.rs index 973b3179..8a3d0e65 100644 --- a/packages/blitz-dom/src/node.rs +++ b/packages/blitz-dom/src/node.rs @@ -579,7 +579,7 @@ impl Clone for TextInputData { impl TextInputData { pub fn new(is_multiline: bool) -> Self { - let editor = Box::new(parley::PlainEditor::default()); + let editor = Box::new(parley::PlainEditor::new(16.0)); Self { editor, is_multiline, @@ -592,9 +592,9 @@ impl TextInputData { layout_ctx: &mut LayoutContext, text: &str, ) { - if *self.editor.text() != *text { - self.editor - .transact(font_ctx, layout_ctx, |txn| txn.set_text(text)); + if self.editor.text() != text { + self.editor.set_text(text); + self.editor.driver(font_ctx, layout_ctx).refresh_layout(); } } } diff --git a/packages/blitz-renderer-vello/src/renderer/render.rs b/packages/blitz-renderer-vello/src/renderer/render.rs index abf2f3b5..d513cf91 100644 --- a/packages/blitz-renderer-vello/src/renderer/render.rs +++ b/packages/blitz-renderer-vello/src/renderer/render.rs @@ -714,7 +714,7 @@ impl ElementCx<'_> { }; // Render text - self.stroke_text(scene, input_data.editor.lines(), pos); + self.stroke_text(scene, input_data.editor.try_layout().unwrap().lines(), pos); } }