summaryrefslogtreecommitdiffstats
path: root/widget/src/text_editor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'widget/src/text_editor.rs')
-rw-r--r--widget/src/text_editor.rs69
1 files changed, 66 insertions, 3 deletions
diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs
index f1ec589b..2931e7f6 100644
--- a/widget/src/text_editor.rs
+++ b/widget/src/text_editor.rs
@@ -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,