From 2e7db8f8552acf7b4a6db8d99bbe6194ff5f1c8d Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Mon, 8 Jul 2024 20:04:28 -0600 Subject: [PATCH] Add mouse handling to gpui input example (#13960) Release Notes: - N/A --- crates/gpui/examples/input.rs | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/crates/gpui/examples/input.rs b/crates/gpui/examples/input.rs index ed5047e8cc..e690202e43 100644 --- a/crates/gpui/examples/input.rs +++ b/crates/gpui/examples/input.rs @@ -26,6 +26,8 @@ struct TextInput { selection_reversed: bool, marked_range: Option>, last_layout: Option, + last_bounds: Option>, + is_selecting: bool, } impl TextInput { @@ -80,6 +82,21 @@ impl TextInput { self.replace_text_in_range(None, "", cx) } + fn on_mouse_down(&mut self, event: &MouseDownEvent, cx: &mut ViewContext) { + self.is_selecting = true; + self.move_to(self.index_for_mouse_position(event.position), cx) + } + + fn on_mouse_up(&mut self, _: &MouseUpEvent, _: &mut ViewContext) { + self.is_selecting = false; + } + + fn on_mouse_move(&mut self, event: &MouseMoveEvent, cx: &mut ViewContext) { + if self.is_selecting { + self.select_to(self.index_for_mouse_position(event.position), cx); + } + } + fn show_character_palette(&mut self, _: &ShowCharacterPalette, cx: &mut ViewContext) { cx.show_character_palette(); } @@ -97,6 +114,20 @@ impl TextInput { } } + fn index_for_mouse_position(&self, position: Point) -> usize { + let (Some(bounds), Some(line)) = (self.last_bounds.as_ref(), self.last_layout.as_ref()) + else { + return 0; + }; + if position.y < bounds.top() { + return 0; + } + if position.y > bounds.bottom() { + return self.content.len(); + } + line.closest_index_for_x(position.x - bounds.left()) + } + fn select_to(&mut self, offset: usize, cx: &mut ViewContext) { if self.selection_reversed { self.selected_range.start = offset @@ -409,6 +440,7 @@ impl Element for TextElement { } self.input.update(cx, |input, _cx| { input.last_layout = Some(line); + input.last_bounds = Some(bounds); }); } } @@ -429,6 +461,10 @@ impl Render for TextInput { .on_action(cx.listener(Self::home)) .on_action(cx.listener(Self::end)) .on_action(cx.listener(Self::show_character_palette)) + .on_mouse_down(MouseButton::Left, cx.listener(Self::on_mouse_down)) + .on_mouse_up(MouseButton::Left, cx.listener(Self::on_mouse_up)) + .on_mouse_up_out(MouseButton::Left, cx.listener(Self::on_mouse_up)) + .on_mouse_move(cx.listener(Self::on_mouse_move)) .bg(rgb(0xeeeeee)) .size_full() .line_height(px(30.)) @@ -475,6 +511,8 @@ fn main() { selection_reversed: false, marked_range: None, last_layout: None, + last_bounds: None, + is_selecting: false, }) }, )