@@ -6,7 +6,7 @@ use crossterm::event::Event;
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::Rect;
9+use helix_view::graphics::{Margin, Rect};
11// TODO: share logic with Menu, it's essentially Popup(render_fn), but render fn needs to return
11// 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>)
12// a width/height hint. maybe Popup(Box<Component>)
@@ -14,6 +14,7 @@ use helix_view::graphics::Rect;
14pub struct Popup<T: Component> {
14pub struct Popup<T: Component> {
15 contents: T,
15 contents: T,
16 position: Option<Position>,
16 position: Option<Position>,
17 size: (u16, u16),
18 size: (u16, u16),
18 child_size: (u16, u16),
19 child_size: (u16, u16),
19 scroll: usize,
20 scroll: usize,
@@ -25,6 +26,10 @@ impl<T: Component> Popup<T> {
27 position: None,
28 position: None,
28 size: (0, 0),
33 size: (0, 0),
29 child_size: (0, 0),
34 child_size: (0, 0),
30 scroll: 0,
35 scroll: 0,
@@ -36,6 +41,11 @@ impl<T: Component> Popup<T> {
36 self.position = pos;
41 self.position = pos;
44+ pub fn margin(mut self, margin: Margin) -> Self {
45+ self.margin = margin;
39 pub fn get_rel_position(&mut self, viewport: Rect, cx: &Context) -> (u16, u16) {
49 pub fn get_rel_position(&mut self, viewport: Rect, cx: &Context) -> (u16, u16) {
40 let position = self
50 let position = self
@@ -126,13 +136,18 @@ impl<T: Component> Component for Popup<T> {
126 let max_width = 120.min(viewport.0);
136 let max_width = 120.min(viewport.0);
127 let max_height = 26.min(viewport.1.saturating_sub(2)); // add some spacing in the viewport
137 let max_height = 26.min(viewport.1.saturating_sub(2)); // add some spacing in the viewport
139+ let inner = Rect::new(0, 0, max_width, max_height).inner(&self.margin);
129 let (width, height) = self
141 let (width, height) = self
130 .contents
142 .contents
131− .required_size((max_width, max_height))
143+ .required_size((inner.width, inner.height))
132 .expect("Component needs required_size implemented in order to be embedded in a popup");
144 .expect("Component needs required_size implemented in order to be embedded in a popup");
134 self.child_size = (width, height);
146 self.child_size = (width, height);
148+ (width + self.margin.horizontal * 2).min(max_width),
135− self.size = (width.min(max_width), height.min(max_height));
149+ (height + self.margin.vertical * 2).min(max_height),
137 // re-clamp scroll offset
152 // re-clamp scroll offset
138 let max_offset = self.child_size.1.saturating_sub(self.size.1);
153 let max_offset = self.child_size.1.saturating_sub(self.size.1);
@@ -156,7 +171,8 @@ impl<T: Component> Component for Popup<T> {
156 let background = cx.editor.theme.get("ui.popup");
171 let background = cx.editor.theme.get("ui.popup");
157 surface.clear_with(area, background);
172 surface.clear_with(area, background);
174+ let inner = area.inner(&self.margin);
159− self.contents.render(area, surface, cx);
175+ self.contents.render(inner, surface, cx);
162 fn id(&self) -> Option<&'static str> {
178 fn id(&self) -> Option<&'static str> {