Draft input_method support

This commit is contained in:
KENZ 2025-01-10 07:12:31 +09:00 committed by Héctor Ramón Jiménez
parent 599d8b560b
commit 7db5256b72
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
13 changed files with 420 additions and 27 deletions

View file

@ -33,6 +33,7 @@
//! ```
use crate::core::alignment;
use crate::core::clipboard::{self, Clipboard};
use crate::core::input_method;
use crate::core::keyboard;
use crate::core::keyboard::key;
use crate::core::layout::{self, Layout};
@ -46,8 +47,8 @@ use crate::core::widget::operation;
use crate::core::widget::{self, Widget};
use crate::core::window;
use crate::core::{
Background, Border, Color, Element, Event, Length, Padding, Pixels, Point,
Rectangle, Shell, Size, SmolStr, Theme, Vector,
Background, Border, CaretInfo, Color, Element, Event, Length, Padding,
Pixels, Point, Rectangle, Shell, Size, SmolStr, Theme, Vector,
};
use std::borrow::Cow;
@ -322,6 +323,46 @@ where
self.class = class.into();
self
}
fn caret_rect(
&self,
tree: &widget::Tree,
renderer: &Renderer,
layout: Layout<'_>,
) -> Option<Rectangle> {
let bounds = layout.bounds();
let internal = self.content.0.borrow_mut();
let state = tree.state.downcast_ref::<State<Highlighter>>();
let text_bounds = bounds.shrink(self.padding);
let translation = text_bounds.position() - Point::ORIGIN;
if let Some(_) = state.focus.as_ref() {
let position = match internal.editor.cursor() {
Cursor::Caret(position) => position,
Cursor::Selection(ranges) => ranges
.first()
.cloned()
.unwrap_or(Rectangle::default())
.position(),
};
Some(Rectangle::new(
position + translation,
Size::new(
1.0,
self.line_height
.to_absolute(
self.text_size
.unwrap_or_else(|| renderer.default_size()),
)
.into(),
),
))
} else {
None
}
}
}
/// The content of a [`TextEditor`].
@ -605,7 +646,7 @@ where
event: Event,
layout: Layout<'_>,
cursor: mouse::Cursor,
_renderer: &Renderer,
renderer: &Renderer,
clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>,
_viewport: &Rectangle,
@ -701,6 +742,11 @@ where
}));
shell.capture_event();
}
Update::Commit(text) => {
shell.publish(on_edit(Action::Edit(Edit::Paste(
Arc::new(text),
))));
}
Update::Binding(binding) => {
fn apply_binding<
H: text::Highlighter,
@ -825,6 +871,19 @@ where
}
};
shell.update_caret_info(if state.is_focused() {
let rect = self
.caret_rect(tree, renderer, layout)
.unwrap_or(Rectangle::default());
let bottom_left = Point::new(rect.x, rect.y + rect.height);
Some(CaretInfo {
position: bottom_left,
input_method_allowed: true,
})
} else {
None
});
if is_redraw {
self.last_status = Some(status);
} else if self
@ -1129,6 +1188,7 @@ enum Update<Message> {
Drag(Point),
Release,
Scroll(f32),
Commit(String),
Binding(Binding<Message>),
}
@ -1191,6 +1251,9 @@ impl<Message> Update<Message> {
}
_ => None,
},
Event::InputMethod(input_method::Event::Commit(text)) => {
Some(Update::Commit(text))
}
Event::Keyboard(keyboard::Event::KeyPressed {
key,
modifiers,