mirror of
https://github.com/ilyakooo0/helix.git
synced 2024-11-28 12:42:09 +03:00
fix small terminal size panic with info popup (#563)
* fix small terminal size panic with info popup * remove unused enumerator * fix subtraction overflow panic
This commit is contained in:
parent
b5223618ed
commit
815ee9e334
@ -699,7 +699,8 @@ impl Component for EditorView {
|
||||
match event {
|
||||
Event::Resize(width, height) => {
|
||||
// HAXX: offset the render area height by 1 to account for prompt/commandline
|
||||
cx.editor.resize(Rect::new(0, 0, width, height - 1));
|
||||
cx.editor
|
||||
.resize(Rect::new(0, 0, width, height.saturating_sub(1)));
|
||||
EventResult::Consumed(None)
|
||||
}
|
||||
Event::Key(key) => {
|
||||
|
@ -7,24 +7,32 @@ use tui::widgets::{Block, Borders, Widget};
|
||||
impl Component for Info {
|
||||
fn render(&self, viewport: Rect, surface: &mut Surface, cx: &mut Context) {
|
||||
let style = cx.editor.theme.get("ui.popup");
|
||||
|
||||
// Calculate the area of the terminal to modify. Because we want to
|
||||
// render at the bottom right, we use the viewport's width and height
|
||||
// which evaluate to the most bottom right coordinate.
|
||||
let (width, height) = (self.width + 2, self.height + 2);
|
||||
let area = viewport.intersection(Rect::new(
|
||||
viewport.width.saturating_sub(width),
|
||||
viewport.height.saturating_sub(height + 2),
|
||||
width,
|
||||
height,
|
||||
));
|
||||
surface.clear_with(area, style);
|
||||
|
||||
let block = Block::default()
|
||||
.title(self.title.as_str())
|
||||
.borders(Borders::ALL)
|
||||
.border_style(style);
|
||||
let Info { width, height, .. } = self;
|
||||
let (w, h) = (*width + 2, *height + 2);
|
||||
// -2 to subtract command line + statusline. a bit of a hack, because of splits.
|
||||
let area = viewport.intersection(Rect::new(
|
||||
viewport.width.saturating_sub(w),
|
||||
viewport.height.saturating_sub(h + 2),
|
||||
w,
|
||||
h,
|
||||
));
|
||||
surface.clear_with(area, style);
|
||||
let Rect { x, y, .. } = block.inner(area);
|
||||
for (y, line) in (y..).zip(self.text.lines()) {
|
||||
surface.set_string(x, y, line, style);
|
||||
}
|
||||
let inner = block.inner(area);
|
||||
block.render(area, surface);
|
||||
|
||||
// Only write as many lines as there are rows available.
|
||||
for (y, line) in (inner.y..)
|
||||
.zip(self.text.lines())
|
||||
.take(inner.height as usize)
|
||||
{
|
||||
surface.set_string(inner.x, y, line, style);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,22 +64,27 @@ impl Rect {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn area(self) -> u16 {
|
||||
self.width * self.height
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn left(self) -> u16 {
|
||||
self.x
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn right(self) -> u16 {
|
||||
self.x.saturating_add(self.width)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn top(self) -> u16 {
|
||||
self.y
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bottom(self) -> u16 {
|
||||
self.y.saturating_add(self.height)
|
||||
}
|
||||
@ -97,7 +102,18 @@ impl Rect {
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate the union between two [`Rect`]s.
|
||||
pub fn union(self, other: Rect) -> Rect {
|
||||
// Example:
|
||||
//
|
||||
// If `Rect` A is positioned at `(0, 0)` with a width and height of `5`,
|
||||
// and `Rect` B is positioned at `(5, 0)` with a width and height of `2`,
|
||||
// then this is the resulting union:
|
||||
//
|
||||
// x1 = min(0, 5) => x1 = 0
|
||||
// y1 = min(0, 0) => y1 = 0
|
||||
// x2 = max(0 + 5, 5 + 2) => x2 = 7
|
||||
// y2 = max(0 + 5, 0 + 2) => y2 = 5
|
||||
let x1 = min(self.x, other.x);
|
||||
let y1 = min(self.y, other.y);
|
||||
let x2 = max(self.x + self.width, other.x + other.width);
|
||||
@ -110,7 +126,18 @@ impl Rect {
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate the intersection between two [`Rect`]s.
|
||||
pub fn intersection(self, other: Rect) -> Rect {
|
||||
// Example:
|
||||
//
|
||||
// If `Rect` A is positioned at `(0, 0)` with a width and height of `5`,
|
||||
// and `Rect` B is positioned at `(5, 0)` with a width and height of `2`,
|
||||
// then this is the resulting intersection:
|
||||
//
|
||||
// x1 = max(0, 5) => x1 = 5
|
||||
// y1 = max(0, 0) => y1 = 0
|
||||
// x2 = min(0 + 5, 5 + 2) => x2 = 5
|
||||
// y2 = min(0 + 5, 0 + 2) => y2 = 2
|
||||
let x1 = max(self.x, other.x);
|
||||
let y1 = max(self.y, other.y);
|
||||
let x2 = min(self.x + self.width, other.x + other.width);
|
||||
|
Loading…
Reference in New Issue
Block a user