Skip to content

Commit

Permalink
Upgrade to parley cursor rework branch
Browse files Browse the repository at this point in the history
Signed-off-by: Nico Burns <[email protected]>
  • Loading branch information
nicoburns committed Nov 27, 2024
1 parent 031896c commit e3a98f5
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 58 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ taffy = { version = "0.6", default-features = false, features = ["std", "flexbox
# Linebender + WGPU
peniko = "0.2"
vello = { version = "0.3", features = [ "wgpu" ] }
parley = "0.2"
parley = { version = "0.2", git = "https://github.com/linebender/parley", branch = "cursor2" }

wgpu = "22.1.0"

# SVG dependencies
Expand Down
4 changes: 2 additions & 2 deletions packages/blitz-dom/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{ElementNodeData, Node, NodeData, TextNodeData, Viewport};
use app_units::Au;
use blitz_traits::net::{DummyNetProvider, SharedProvider};
use markup5ever::local_name;
use parley::{FontContext, PlainEditorOp};
use parley::FontContext;
use peniko::kurbo;
use string_cache::Atom;
use style::attr::{AttrIdentifier, AttrValue};
Expand Down Expand Up @@ -173,7 +173,7 @@ impl DocumentLike for Document {
text_input_data.editor.transact(
&mut self.font_ctx,
&mut self.layout_ctx,
[PlainEditorOp::MoveToPoint(x as f32, y as f32)],
|txn| txn.move_to_point(x as f32, y as f32),
);

self.set_focus_to(hit.node_id);
Expand Down
71 changes: 35 additions & 36 deletions packages/blitz-dom/src/events/keyboard.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::node::TextBrush;
use parley::{FontContext, LayoutContext, PlainEditor, PlainEditorOp};
use parley::{FontContext, LayoutContext, PlainEditor};
use winit::{
event::{KeyEvent, Modifiers},
keyboard::{Key, NamedKey},
Expand Down Expand Up @@ -29,134 +29,133 @@ pub(crate) fn apply_keypress_event(
// Small macro to reduce boilerplate
macro_rules! transact {
($op:expr) => {{
editor.transact(font_ctx, layout_ctx, [$op]);
editor.transact(font_ctx, layout_ctx, $op);
}};
}

match event.logical_key {
#[cfg(not(target_os = "android"))]
Key::Character(c) if action_mod && matches!(c.as_str(), "c" | "x" | "v") => {
use arboard::Clipboard;
use parley::layout::editor::ActiveText;

match c.to_lowercase().as_str() {
"c" => {
if let ActiveText::Selection(text) = editor.active_text() {
if let Some(text) = editor.selected_text() {
let mut cb = Clipboard::new().unwrap();
cb.set_text(text.to_owned()).ok();
}
}
"x" => {
if let ActiveText::Selection(text) = editor.active_text() {
if let Some(text) = editor.selected_text() {
let mut cb = Clipboard::new().unwrap();
cb.set_text(text.to_owned()).ok();
transact!(PlainEditorOp::DeleteSelection)
transact!(|txn| txn.delete_selection())
}
}
"v" => {
let mut cb = Clipboard::new().unwrap();
let text = cb.get_text().unwrap_or_default();
transact!(PlainEditorOp::InsertOrReplaceSelection(text.into(),))
transact!(|txn| txn.insert_or_replace_selection(&text))
}
_ => unreachable!(),
}
}
Key::Character(c) if action_mod && matches!(c.to_lowercase().as_str(), "a") => {
if shift {
transact!(PlainEditorOp::CollapseSelection)
transact!(|txn| txn.collapse_selection())
} else {
transact!(PlainEditorOp::SelectAll)
transact!(|txn| txn.select_all())
}
}
Key::Named(NamedKey::ArrowLeft) => {
if action_mod {
if shift {
transact!(PlainEditorOp::SelectWordLeft)
transact!(|txn| txn.select_word_left())
} else {
transact!(PlainEditorOp::MoveWordLeft)
transact!(|txn| txn.move_word_left())
}
} else if shift {
transact!(PlainEditorOp::SelectLeft)
transact!(|txn| txn.select_left())
} else {
transact!(PlainEditorOp::MoveLeft)
transact!(|txn| txn.move_left())
}
}
Key::Named(NamedKey::ArrowRight) => {
if action_mod {
if shift {
transact!(PlainEditorOp::SelectWordRight)
transact!(|txn| txn.select_word_right())
} else {
transact!(PlainEditorOp::MoveWordRight)
transact!(|txn| txn.move_word_right())
}
} else if shift {
transact!(PlainEditorOp::SelectRight)
transact!(|txn| txn.select_right())
} else {
transact!(PlainEditorOp::MoveRight)
transact!(|txn| txn.move_right())
}
}
Key::Named(NamedKey::ArrowUp) => {
if shift {
transact!(PlainEditorOp::SelectUp)
transact!(|txn| txn.select_up())
} else {
transact!(PlainEditorOp::MoveUp)
transact!(|txn| txn.move_up())
}
}
Key::Named(NamedKey::ArrowDown) => {
if shift {
transact!(PlainEditorOp::SelectDown)
transact!(|txn| txn.select_down())
} else {
transact!(PlainEditorOp::MoveDown)
transact!(|txn| txn.move_down())
}
}
Key::Named(NamedKey::Home) => {
if action_mod {
if shift {
transact!(PlainEditorOp::SelectToTextStart)
transact!(|txn| txn.select_to_text_start())
} else {
transact!(PlainEditorOp::MoveToTextStart)
transact!(|txn| txn.move_to_text_start())
}
} else if shift {
transact!(PlainEditorOp::SelectToLineStart)
transact!(|txn| txn.select_to_line_start())
} else {
transact!(PlainEditorOp::MoveToLineStart)
transact!(|txn| txn.move_to_line_start())
}
}
Key::Named(NamedKey::End) => {
if action_mod {
if shift {
transact!(PlainEditorOp::SelectToTextEnd)
transact!(|txn| txn.select_to_text_end())
} else {
transact!(PlainEditorOp::MoveToTextEnd)
transact!(|txn| txn.move_to_text_end())
}
} else if shift {
transact!(PlainEditorOp::SelectToLineEnd)
transact!(|txn| txn.select_to_line_end())
} else {
transact!(PlainEditorOp::MoveToLineEnd)
transact!(|txn| txn.move_to_line_end())
}
}
Key::Named(NamedKey::Delete) => {
if action_mod {
transact!(PlainEditorOp::DeleteWord)
transact!(|txn| txn.delete_word())
} else {
transact!(PlainEditorOp::Delete)
transact!(|txn| txn.delete())
}
}
Key::Named(NamedKey::Backspace) => {
if action_mod {
transact!(PlainEditorOp::BackdeleteWord)
transact!(|txn| txn.backdelete_word())
} else {
transact!(PlainEditorOp::Backdelete)
transact!(|txn| txn.backdelete())
}
}
Key::Named(NamedKey::Enter) => {
// TODO: support multi-line text inputs
// transact!(PlainEditorOp::InsertOrReplaceSelection("\n".into()))
// transact!(|txn| txn.insert_or_replace_selection("\n"))
}
Key::Named(NamedKey::Space) => {
transact!(PlainEditorOp::InsertOrReplaceSelection(" ".into()))
transact!(|txn| txn.insert_or_replace_selection(" "))
}
Key::Character(s) => {
transact!(PlainEditorOp::InsertOrReplaceSelection(s.into()))
transact!(|txn| txn.insert_or_replace_selection(&s))
}
_ => {}
};
Expand Down
22 changes: 10 additions & 12 deletions packages/blitz-dom/src/layout/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::str;
use std::sync::Arc;

use markup5ever::{local_name, namespace_url, ns, QualName};
use parley::{FontStack, InlineBox, PlainEditorOp, StyleProperty, TreeBuilder, WhiteSpaceCollapse};
use parley::{FontStack, InlineBox, StyleProperty, TreeBuilder, WhiteSpaceCollapse};
use slab::Slab;
use style::{
data::ElementData,
Expand Down Expand Up @@ -636,22 +636,20 @@ 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: Arc<str> = Arc::from(element.attr(local_name!("value")).unwrap_or(" "));
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,
[
PlainEditorOp::SetText(text),
PlainEditorOp::SetScale(doc.viewport.scale_f64() as f32),
PlainEditorOp::SetWidth(10000.0),
PlainEditorOp::SetDefaultStyle(styles),
],
);
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);
});
element.node_specific_data = NodeSpecificData::TextInput(text_input_data);
}
}
Expand Down
5 changes: 2 additions & 3 deletions packages/blitz-dom/src/node.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use atomic_refcell::{AtomicRef, AtomicRefCell};
use image::DynamicImage;
use markup5ever::{local_name, LocalName, QualName};
use parley::{FontContext, LayoutContext, PlainEditorOp};
use parley::{FontContext, LayoutContext};
use peniko::kurbo;
use selectors::matching::{ElementSelectorFlags, QuirksMode};
use slab::Slab;
Expand Down Expand Up @@ -587,10 +587,9 @@ impl TextInputData {
layout_ctx: &mut LayoutContext<TextBrush>,
text: &str,
) {
let text = Arc::from(text);
if *self.editor.text() != *text {
self.editor
.transact(font_ctx, layout_ctx, [PlainEditorOp::SetText(text)]);
.transact(font_ctx, layout_ctx, |txn| txn.set_text(text));
}
}
}
Expand Down
5 changes: 1 addition & 4 deletions packages/blitz-renderer-vello/src/renderer/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,12 +684,9 @@ impl ElementCx<'_> {
for rect in input_data.editor.selection_geometry().iter() {
scene.fill(Fill::NonZero, transform, Color::STEEL_BLUE, None, &rect);
}
if let Some(cursor) = input_data.editor.selection_strong_geometry(1.5) {
if let Some(cursor) = input_data.editor.cursor_geometry(1.5) {
scene.fill(Fill::NonZero, transform, Color::BLACK, None, &cursor);
};
if let Some(cursor) = input_data.editor.selection_weak_geometry(1.5) {
scene.fill(Fill::NonZero, transform, Color::DARK_GRAY, None, &cursor);
};

// Render text
self.stroke_text(scene, input_data.editor.lines(), pos);
Expand Down

0 comments on commit e3a98f5

Please sign in to comment.