@@ -6,7 +6,7 @@ use crossterm::event::Event;
66use tui::buffer::Buffer as Surface;
77
88use helix_core::Position;
9−use helix_view::graphics::Rect;
9+use helix_view::graphics::{Margin, Rect};
1010
1111// TODO: share logic with Menu, it's essentially Popup(render_fn), but render fn needs to return
1212// a width/height hint. maybe Popup(Box<Component>)
@@ -14,6 +14,7 @@ use helix_view::graphics::Rect;
1414pub struct Popup<T: Component> {
1515 contents: T,
1616 position: Option<Position>,
17+ margin: Margin,
1718 size: (u16, u16),
1819 child_size: (u16, u16),
1920 scroll: usize,
@@ -25,6 +26,10 @@ impl<T: Component> Popup<T> {
2526 Self {
2627 contents,
2728 position: None,
29+ margin: Margin {
30+ vertical: 0,
31+ horizontal: 0,
32+ },
2833 size: (0, 0),
2934 child_size: (0, 0),
3035 scroll: 0,
@@ -36,6 +41,11 @@ impl<T: Component> Popup<T> {
3641 self.position = pos;
3742 }
3843
44+ pub fn margin(mut self, margin: Margin) -> Self {
45+ self.margin = margin;
46+ self
47+ }
48+
3949 pub fn get_rel_position(&mut self, viewport: Rect, cx: &Context) -> (u16, u16) {
4050 let position = self
4151 .position
@@ -126,13 +136,18 @@ impl<T: Component> Component for Popup<T> {
126136 let max_width = 120.min(viewport.0);
127137 let max_height = 26.min(viewport.1.saturating_sub(2)); // add some spacing in the viewport
128138
139+ let inner = Rect::new(0, 0, max_width, max_height).inner(&self.margin);
140+
129141 let (width, height) = self
130142 .contents
131− .required_size((max_width, max_height))
143+ .required_size((inner.width, inner.height))
132144 .expect("Component needs required_size implemented in order to be embedded in a popup");
133145
134146 self.child_size = (width, height);
135− self.size = (width.min(max_width), height.min(max_height));
147+ self.size = (
148+ (width + self.margin.horizontal * 2).min(max_width),
149+ (height + self.margin.vertical * 2).min(max_height),
150+ );
136151
137152 // re-clamp scroll offset
138153 let max_offset = self.child_size.1.saturating_sub(self.size.1);
@@ -156,7 +171,8 @@ impl<T: Component> Component for Popup<T> {
156171 let background = cx.editor.theme.get("ui.popup");
157172 surface.clear_with(area, background);
158173
159− self.contents.render(area, surface, cx);
174+ let inner = area.inner(&self.margin);
175+ self.contents.render(inner, surface, cx);
160176 }
161177
162178 fn id(&self) -> Option<&'static str> {