@@ -6,7 +6,10 @@ use crate::{
6use tui::buffer::Buffer as Surface;
6use tui::buffer::Buffer as Surface;
8use helix_core::Position;
8use helix_core::Position;
9−use helix_view::graphics::{Margin, Rect};
10+ graphics::{Margin, Rect},
11// TODO: share logic with Menu, it's essentially Popup(render_fn), but render fn needs to return
14// TODO: share logic with Menu, it's essentially Popup(render_fn), but render fn needs to return
12// a width/height hint. maybe Popup(Box<Component>)
15// a width/height hint. maybe Popup(Box<Component>)
@@ -88,10 +91,10 @@ impl<T: Component> Popup<T> {
89 /// Calculate the position where the popup should be rendered and return the coordinates of the
92 /// Calculate the position where the popup should be rendered and return the coordinates of the
90 /// top left corner.
93 /// 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) {
92 let position = self
95 let position = self
94− .get_or_insert_with(|| cx.editor.cursor().0.unwrap_or_default());
97+ .get_or_insert_with(|| editor.cursor().0.unwrap_or_default());
96 let (width, height) = self.size;
99 let (width, height) = self.size;
@@ -155,6 +158,16 @@ impl<T: Component> Popup<T> {
155 pub fn contents_mut(&mut self) -> &mut T {
158 pub fn contents_mut(&mut self) -> &mut T {
156 &mut self.contents
159 &mut self.contents
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));
166+ let (rel_x, rel_y) = self.get_rel_position(viewport, editor);
169+ viewport.intersection(Rect::new(rel_x, rel_y, self.size.0, self.size.1))
160impl<T: Component> Component for Popup<T> {
173impl<T: Component> Component for Popup<T> {
@@ -232,16 +245,9 @@ impl<T: Component> Component for Popup<T> {
234 fn render(&mut self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
247 fn render(&mut self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
235− // trigger required_size so we recalculate if the child changed
248+ let area = self.area(viewport, cx.editor);
236− self.required_size((viewport.width, viewport.height));
238 cx.scroll = Some(self.scroll);
249 cx.scroll = Some(self.scroll);
240− let (rel_x, rel_y) = self.get_rel_position(viewport, cx);
243− let area = viewport.intersection(Rect::new(rel_x, rel_y, self.size.0, self.size.1));
245 // clear area
251 // clear area
246 let background = cx.editor.theme.get("ui.popup");
252 let background = cx.editor.theme.get("ui.popup");
247 surface.clear_with(area, background);
253 surface.clear_with(area, background);