Skip to content

Commit

Permalink
A foundation for text editing and selection in Masonry (#241)
Browse files Browse the repository at this point in the history
This brings in a lot of the old work from Druid and Masonry (prior to
linebender/masonry#56) on text, as well as some types from Glazier.

Needed work:
- [X] Text display using abstract types
- [x] Text selection with mouse
- [x] Text input with keyboard
- [ ] IME integration (of the kind winit understands)

Follow up work:
- [ ] Keyboard control of the selection area (hard-coded hotkeys)
- [ ] [Proper
placement](https://raphlinus.github.io/text/2020/10/26/text-layout.html#shaping-cluster)
of cursor
- [ ] Input methods
- [ ] Proper hotkey handling
- [ ] Copy and/or paste
  • Loading branch information
DJMcNab authored May 3, 2024
1 parent 205a9a2 commit 52bbfa0
Show file tree
Hide file tree
Showing 43 changed files with 6,511 additions and 251 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/masonry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ pollster = "0.3.0"
parley.workspace = true
wgpu = { version = "0.19.3" }
winit.workspace = true
unicode-segmentation = "1.11.0"
# TODO: Is this still the most up-to-date crate for this?
xi-unicode = "0.3.0"

[dev-dependencies]
float-cmp = { version = "0.8.0", features = ["std"], default-features = false }
Expand Down
4 changes: 2 additions & 2 deletions crates/masonry/examples/calc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ impl AppDriver for CalcState {
ctx.get_root::<Flex>()
.child_mut(1)
.unwrap()
.downcast::<Label>()
.downcast::<Label<String>>()
.unwrap()
.set_text(self.value.clone());
.set_text((&*self.value).into());
}
}

Expand Down
4 changes: 3 additions & 1 deletion crates/masonry/examples/custom_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,16 @@ impl Widget for CustomWidget {
FontFamily::Generic(parley::style::GenericFamily::Serif),
)));
text_layout_builder.push_default(&StyleProperty::FontSize(24.0));
text_layout_builder.push_default(&StyleProperty::Brush(Brush::Solid(fill_color)));
text_layout_builder.push_default(&StyleProperty::Brush(Brush::Solid(fill_color).into()));

let mut text_layout = text_layout_builder.build();
text_layout.break_all_lines(None, Alignment::Start);

let mut scratch_scene = Scene::new();
// We can pass a transform matrix to rotate the text we render
masonry::text_helpers::render_text(
scene,
&mut scratch_scene,
Affine::rotate(std::f64::consts::FRAC_PI_4).then_translate((80.0, 40.0).into()),
&text_layout,
);
Expand Down
18 changes: 18 additions & 0 deletions crates/masonry/src/event_loop_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,27 @@ impl ApplicationHandler for MainState<'_> {
.handle_window_event(WindowEvent::Resize(size));
}
WinitWindowEvent::ModifiersChanged(modifiers) => {
self.pointer_state.mods = modifiers;
self.render_root
.handle_text_event(TextEvent::ModifierChange(modifiers.state()));
}
WinitWindowEvent::KeyboardInput {
device_id: _,
event,
is_synthetic: _,
} => {
self.render_root.handle_text_event(TextEvent::KeyboardKey(
event,
self.pointer_state.mods.state(),
));
}
WinitWindowEvent::Ime(ime) => {
self.render_root.handle_text_event(TextEvent::Ime(ime));
}
WinitWindowEvent::Focused(new_focus) => {
self.render_root
.handle_text_event(TextEvent::FocusChange(new_focus));
}
WinitWindowEvent::CursorMoved { position, .. } => {
self.pointer_state.physical_position = position;
self.pointer_state.position = position.to_logical(self.window.scale_factor());
Expand Down
2 changes: 2 additions & 0 deletions crates/masonry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ pub mod paint_scene_helpers;
pub mod promise;
pub mod render_root;
pub mod testing;
// mod text;
pub mod text_helpers;
pub mod theme;
pub mod widget;
Expand All @@ -113,6 +114,7 @@ pub mod app_driver;
pub mod debug_logger;
pub mod debug_values;
pub mod event_loop_runner;
pub mod text2;

pub use action::Action;
pub use box_constraints::BoxConstraints;
Expand Down
2 changes: 1 addition & 1 deletion crates/masonry/src/render_root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,8 +464,8 @@ impl RenderRoot {
// Only send RouteFocusChanged in case there's actual change
if old != new {
let event = LifeCycle::Internal(InternalLifeCycle::RouteFocusChanged { old, new });
self.root_lifecycle(event);
self.state.focused_widget = new;
self.root_lifecycle(event);

// TODO - Handle IME
// Send TextFieldFocused(focused_widget) signal
Expand Down
6 changes: 6 additions & 0 deletions crates/masonry/src/text/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Old Text code

This folder contains code which was previously used for handling text in Masonry and Druid.
This is provided for reference.

The expectation is that this will be adapted into the versions in `text2`, then this will be deleted and `text2` will be renamed to text.
Loading

0 comments on commit 52bbfa0

Please sign in to comment.