aboutsummaryrefslogtreecommitdiff
path: root/helix-term/src/ui
diff options
context:
space:
mode:
authorBlaž Hrastnik2021-03-02 08:58:15 +0000
committerBlaž Hrastnik2021-03-02 08:58:15 +0000
commit11c4e0b05325d8fd8046a764ec4b9e655486313d (patch)
tree664aad1754a2733486da6dba7ccbd1d42ade5b4e /helix-term/src/ui
parent8f4ff4c646988c377218c08c851297e68e860c65 (diff)
ui: Calculate popup rendering and sizing.
Diffstat (limited to 'helix-term/src/ui')
-rw-r--r--helix-term/src/ui/popup.rs37
1 files changed, 29 insertions, 8 deletions
diff --git a/helix-term/src/ui/popup.rs b/helix-term/src/ui/popup.rs
index ca860707..673321dc 100644
--- a/helix-term/src/ui/popup.rs
+++ b/helix-term/src/ui/popup.rs
@@ -12,6 +12,9 @@ use std::borrow::Cow;
use helix_core::Position;
use helix_view::Editor;
+// TODO: share logic with Menu, it's essentially Popup(render_fn), but render fn needs to return
+// a width/height hint. maybe Popup(Box<Component>)
+
pub struct Popup {
contents: String,
position: Position,
@@ -64,11 +67,31 @@ impl Component for Popup {
// EventResult::Consumed(None)
EventResult::Consumed(None)
}
- fn render(&self, area: Rect, surface: &mut Surface, cx: &mut Context) {
- // render a box at x, y. Width equal to max width of item.
- const MAX: usize = 15;
- let rows = std::cmp::min(self.contents.lines().count(), MAX) as u16; // inefficient
- let area = Rect::new(self.position.col as u16, self.position.row as u16, 80, rows);
+ fn render(&self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
+ use tui::text::Text;
+ use tui::widgets::{Paragraph, Widget, Wrap};
+
+ let contents = Text::from(self.contents.clone());
+
+ let width = contents.width().min(150) as u16;
+ let height = contents.height().min(13) as u16;
+
+ // -- make sure frame doesn't stick out of bounds
+ let mut rel_x = self.position.col as u16;
+ let mut rel_y = self.position.row as u16;
+ if viewport.width <= rel_x + width {
+ rel_x -= ((rel_x + width) - viewport.width)
+ };
+
+ if height <= rel_y {
+ rel_y -= height // position above point
+ } else {
+ rel_y += 1 // position below point
+ }
+
+ let area = Rect::new(rel_x, rel_y, width, height);
+ // clip to viewport
+ let area = viewport.intersection(Rect::new(rel_x, rel_y, width, height));
// clear area
let background = cx.editor.theme.get("ui.popup");
@@ -85,10 +108,8 @@ impl Component for Popup {
let style = Style::default().fg(Color::Rgb(164, 160, 232)); // lavender
- use tui::text::Text;
- use tui::widgets::{Paragraph, Widget, Wrap};
- let contents = Text::from(self.contents.clone());
let par = Paragraph::new(contents).wrap(Wrap { trim: false });
+ // .scroll(x, y) offsets
par.render(area, surface);
}