allow stacking the picker preview vertically

a lot of pickers don't actually make sense without the preview (global
search, for instance), so forcibly hiding the preview on 80x24 terminal
windows (the default in most situations) is not ideal.
This commit is contained in:
Jesse Luehrs 2023-07-29 21:29:43 -04:00
parent 35b6aef5fb
commit 934a1f6645

View File

@ -49,7 +49,10 @@
pub const ID: &str = "picker";
use super::{menu::Item, overlay::Overlay};
pub const MIN_AREA_WIDTH_FOR_PREVIEW: u16 = 72;
pub const MIN_AREA_WIDTH_FOR_PREVIEW: u16 = 40;
pub const MIN_AREA_HEIGHT_FOR_PREVIEW: u16 = 9;
pub const MAX_AREA_WIDTH_FOR_PREVIEW: u16 = 80;
pub const MAX_AREA_HEIGHT_FOR_PREVIEW: u16 = 24;
/// Biggest file size to preview in bytes
pub const MAX_FILE_SIZE_FOR_PREVIEW: u64 = 10 * 1024 * 1024;
@ -802,28 +805,59 @@ fn render_preview(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context
impl<T: Item + 'static + Send + Sync> Component for Picker<T> {
fn render(&mut self, area: Rect, surface: &mut Surface, cx: &mut Context) {
// +---------+ +---------+
// |prompt | |preview |
// +---------+ | |
// |picker | | |
// | | | |
// +---------+ +---------+
let render_preview =
self.show_preview && self.file_fn.is_some() && area.width > MIN_AREA_WIDTH_FOR_PREVIEW;
let picker_width = if render_preview {
area.width / 2
let (show_preview, vertical) = if area.width / 2 >= MIN_AREA_WIDTH_FOR_PREVIEW
&& area.height / 2 >= MIN_AREA_HEIGHT_FOR_PREVIEW
{
if (area.width / 2).abs_diff(area.height * 10 / 3)
> area.width.abs_diff(area.height * 10 / 3 / 2)
{
(self.show_preview, true)
} else {
(self.show_preview, false)
}
} else if area.width >= MIN_AREA_WIDTH_FOR_PREVIEW
&& area.height / 2 >= MIN_AREA_HEIGHT_FOR_PREVIEW
{
(self.show_preview, true)
} else if area.width / 2 >= MIN_AREA_WIDTH_FOR_PREVIEW
&& area.height >= MIN_AREA_HEIGHT_FOR_PREVIEW
{
(self.show_preview, false)
} else {
area.width
(false, false)
};
let picker_area = area.with_width(picker_width);
self.render_picker(picker_area, surface, cx);
if show_preview && self.file_fn.is_some() {
if vertical {
// +---------------------+
// |prompt |
// +---------------------+
// |picker |
// | |
// +---------------------+
// |preview |
// | |
// +---------------------+
let preview_height = (area.height / 2).min(MAX_AREA_HEIGHT_FOR_PREVIEW);
let picker_height = area.height - preview_height;
if render_preview {
let preview_area = area.clip_left(picker_width);
self.render_preview(preview_area, surface, cx);
self.render_picker(area.with_height(picker_height), surface, cx);
self.render_preview(area.clip_top(picker_height), surface, cx);
} else {
// +---------+ +---------+
// |prompt | |preview |
// +---------+ | |
// |picker | | |
// | | | |
// +---------+ +---------+
let preview_width = (area.width / 2).min(MAX_AREA_WIDTH_FOR_PREVIEW);
let picker_width = area.width - preview_width;
self.render_picker(area.with_width(picker_width), surface, cx);
self.render_preview(area.clip_left(picker_width), surface, cx);
}
} else {
self.render_picker(area, surface, cx);
}
}