@@ -6,7 +6,10 @@ use crate::{
66use tui::buffer::Buffer as Surface;
77
88use helix_core::Position;
9−use helix_view::graphics::{Margin, Rect};
9+use helix_view::{
10+ graphics::{Margin, Rect},
11+ Editor,
12+};
1013
1114// TODO: share logic with Menu, it's essentially Popup(render_fn), but render fn needs to return
1215// a width/height hint. maybe Popup(Box<Component>)
@@ -88,10 +91,10 @@ impl<T: Component> Popup<T> {
8891
8992 /// Calculate the position where the popup should be rendered and return the coordinates of the
9093 /// top left corner.
91− pub fn get_rel_position(&mut self, viewport: Rect, cx: &Context) -> (u16, u16) {
94+ pub fn get_rel_position(&mut self, viewport: Rect, editor: &Editor) -> (u16, u16) {
9295 let position = self
9396 .position
94− .get_or_insert_with(|| cx.editor.cursor().0.unwrap_or_default());
97+ .get_or_insert_with(|| editor.cursor().0.unwrap_or_default());
9598
9699 let (width, height) = self.size;
97100
@@ -155,6 +158,16 @@ impl<T: Component> Popup<T> {
155158 pub fn contents_mut(&mut self) -> &mut T {
156159 &mut self.contents
157160 }
161+
162+ pub fn area(&mut self, viewport: Rect, editor: &Editor) -> Rect {
163+ // trigger required_size so we recalculate if the child changed
164+ self.required_size((viewport.width, viewport.height));
165+
166+ let (rel_x, rel_y) = self.get_rel_position(viewport, editor);
167+
168+ // clip to viewport
169+ viewport.intersection(Rect::new(rel_x, rel_y, self.size.0, self.size.1))
170+ }
158171}
159172
160173impl<T: Component> Component for Popup<T> {
@@ -232,16 +245,9 @@ impl<T: Component> Component for Popup<T> {
232245 }
233246
234247 fn render(&mut self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
235− // trigger required_size so we recalculate if the child changed
236− self.required_size((viewport.width, viewport.height));
237−
248+ let area = self.area(viewport, cx.editor);
238249 cx.scroll = Some(self.scroll);
239250
240− let (rel_x, rel_y) = self.get_rel_position(viewport, cx);
241−
242− // clip to viewport
243− let area = viewport.intersection(Rect::new(rel_x, rel_y, self.size.0, self.size.1));
244−
245251 // clear area
246252 let background = cx.editor.theme.get("ui.popup");
247253 surface.clear_with(area, background);