Add mouse handling to gpui input example (#13960)

Release Notes:

- N/A
This commit is contained in:
Conrad Irwin 2024-07-08 20:04:28 -06:00 committed by GitHub
parent b0ecda6370
commit 2e7db8f855
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -26,6 +26,8 @@ struct TextInput {
selection_reversed: bool, selection_reversed: bool,
marked_range: Option<Range<usize>>, marked_range: Option<Range<usize>>,
last_layout: Option<ShapedLine>, last_layout: Option<ShapedLine>,
last_bounds: Option<Bounds<Pixels>>,
is_selecting: bool,
} }
impl TextInput { impl TextInput {
@ -80,6 +82,21 @@ impl TextInput {
self.replace_text_in_range(None, "", cx) self.replace_text_in_range(None, "", cx)
} }
fn on_mouse_down(&mut self, event: &MouseDownEvent, cx: &mut ViewContext<Self>) {
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>) {
self.is_selecting = false;
}
fn on_mouse_move(&mut self, event: &MouseMoveEvent, cx: &mut ViewContext<Self>) {
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<Self>) { fn show_character_palette(&mut self, _: &ShowCharacterPalette, cx: &mut ViewContext<Self>) {
cx.show_character_palette(); cx.show_character_palette();
} }
@ -97,6 +114,20 @@ impl TextInput {
} }
} }
fn index_for_mouse_position(&self, position: Point<Pixels>) -> 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<Self>) { fn select_to(&mut self, offset: usize, cx: &mut ViewContext<Self>) {
if self.selection_reversed { if self.selection_reversed {
self.selected_range.start = offset self.selected_range.start = offset
@ -409,6 +440,7 @@ impl Element for TextElement {
} }
self.input.update(cx, |input, _cx| { self.input.update(cx, |input, _cx| {
input.last_layout = Some(line); 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::home))
.on_action(cx.listener(Self::end)) .on_action(cx.listener(Self::end))
.on_action(cx.listener(Self::show_character_palette)) .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)) .bg(rgb(0xeeeeee))
.size_full() .size_full()
.line_height(px(30.)) .line_height(px(30.))
@ -475,6 +511,8 @@ fn main() {
selection_reversed: false, selection_reversed: false,
marked_range: None, marked_range: None,
last_layout: None, last_layout: None,
last_bounds: None,
is_selecting: false,
}) })
}, },
) )