Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/src/ui/popup.rs')
-rw-r--r--helix-term/src/ui/popup.rs48
1 files changed, 46 insertions, 2 deletions
diff --git a/helix-term/src/ui/popup.rs b/helix-term/src/ui/popup.rs
index b38b8b6e..4f379b4a 100644
--- a/helix-term/src/ui/popup.rs
+++ b/helix-term/src/ui/popup.rs
@@ -11,6 +11,7 @@ use tui::{
use helix_core::Position;
use helix_view::{
graphics::{Margin, Rect},
+ input::{MouseEvent, MouseEventKind},
Editor,
};
@@ -23,6 +24,7 @@ pub struct Popup<T: Component> {
margin: Margin,
size: (u16, u16),
child_size: (u16, u16),
+ area: Rect,
position_bias: Open,
scroll: usize,
auto_close: bool,
@@ -40,6 +42,7 @@ impl<T: Component> Popup<T> {
size: (0, 0),
position_bias: Open::Below,
child_size: (0, 0),
+ area: Rect::new(0, 0, 0, 0),
scroll: 0,
auto_close: false,
ignore_escape_key: false,
@@ -146,6 +149,14 @@ impl<T: Component> Popup<T> {
}
}
+ pub fn scroll_half_page_down(&mut self) {
+ self.scroll(self.size.1 as usize / 2, true)
+ }
+
+ pub fn scroll_half_page_up(&mut self) {
+ self.scroll(self.size.1 as usize / 2, false)
+ }
+
/// Toggles the Popup's scrollbar.
/// Consider disabling the scrollbar in case the child
/// already has its own.
@@ -171,12 +182,44 @@ impl<T: Component> Popup<T> {
// clip to viewport
viewport.intersection(Rect::new(rel_x, rel_y, self.size.0, self.size.1))
}
+
+ fn handle_mouse_event(
+ &mut self,
+ &MouseEvent {
+ kind,
+ column: x,
+ row: y,
+ ..
+ }: &MouseEvent,
+ ) -> EventResult {
+ let mouse_is_within_popup = x >= self.area.left()
+ && x < self.area.right()
+ && y >= self.area.top()
+ && y < self.area.bottom();
+
+ if !mouse_is_within_popup {
+ return EventResult::Ignored(None);
+ }
+
+ match kind {
+ MouseEventKind::ScrollDown if self.has_scrollbar => {
+ self.scroll_half_page_down();
+ EventResult::Consumed(None)
+ }
+ MouseEventKind::ScrollUp if self.has_scrollbar => {
+ self.scroll_half_page_up();
+ EventResult::Consumed(None)
+ }
+ _ => EventResult::Ignored(None),
+ }
+ }
}
impl<T: Component> Component for Popup<T> {
fn handle_event(&mut self, event: &Event, cx: &mut Context) -> EventResult {
let key = match event {
Event::Key(event) => *event,
+ Event::Mouse(event) => return self.handle_mouse_event(event),
Event::Resize(_, _) => {
// TODO: calculate inner area, call component's handle_event with that area
return EventResult::Ignored(None);
@@ -200,11 +243,11 @@ impl<T: Component> Component for Popup<T> {
EventResult::Consumed(Some(close_fn))
}
ctrl!('d') => {
- self.scroll(self.size.1 as usize / 2, true);
+ self.scroll_half_page_down();
EventResult::Consumed(None)
}
ctrl!('u') => {
- self.scroll(self.size.1 as usize / 2, false);
+ self.scroll_half_page_up();
EventResult::Consumed(None)
}
_ => {
@@ -249,6 +292,7 @@ impl<T: Component> Component for Popup<T> {
fn render(&mut self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
let area = self.area(viewport, cx.editor);
+ self.area = area;
cx.scroll = Some(self.scroll);
// clear area