mirror of
https://github.com/alexpasmantier/television.git
synced 2025-07-29 14:21:43 +00:00
fix(tui): fix incorrect height calculation when there is not enough space (#611)
## 📺 PR Description Solves #609 - The calculation of available_height for the Inline and Fixed mode were updated to correctly account for the remaining space and the necessary height needed for the TUI - QoL: Refactored the viewport calculation logic for both Inline and Fixed modes to use a shared scrolling function (handle_viewport_scrolling). - Docs: Added note about default minimum height ## Checklist - [x] my commits **and PR title** follow the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) format - [x] if this is a new feature, I have added tests to consolidate the feature and prevent regressions - [ ] if this is a bug fix, I have added a test that reproduces the bug (if applicable) - [x] I have added a reasonable amount of documentation to the code where appropriate
This commit is contained in:
parent
427ca3619c
commit
20a55cf142
@ -360,7 +360,8 @@ Television's options are organized by functionality. Each option behaves differe
|
||||
**Purpose**: Uses all available empty space at the bottom of the terminal
|
||||
|
||||
- **Both Modes**: Same behavior
|
||||
- **Behavior**: Automatically uses all available space below the cursor, minimum height is ensured
|
||||
- **Behavior**: Automatically uses all available space below the cursor,
|
||||
minimum height is ensured (set by default at 15 lines)
|
||||
- **Conflicts**: Cannot be used with `--height`
|
||||
- **Use Case**: Use of all available space without entering fullscreen mode
|
||||
|
||||
|
2
man/tv.1
2
man/tv.1
@ -320,7 +320,7 @@ This flag works identically in both channel mode and ad\-hoc mode.
|
||||
|
||||
When enabled, the picker will be displayed as an inline interface that uses
|
||||
all available empty space at the bottom of the terminal. If there is insufficient
|
||||
space to meet the minimum height the terminal will scroll.
|
||||
space to meet the minimum height (set by default at 15 lines) the terminal will scroll.
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
Print help (see a summary with \*(Aq\-h\*(Aq)
|
||||
|
@ -82,23 +82,20 @@ where
|
||||
let viewport = match mode {
|
||||
TuiMode::Fullscreen => Viewport::Fullscreen,
|
||||
TuiMode::Inline => {
|
||||
let mut cursor_position = Self::get_cursor_position();
|
||||
// take all available height and max width with a minimum of 15 for the height
|
||||
let available_height =
|
||||
terminal_size.height.saturating_sub(cursor_position.y);
|
||||
debug!(
|
||||
"Total height: {}, Available height: {}, cursor position: {:?}",
|
||||
terminal_size.height, available_height, cursor_position.y
|
||||
);
|
||||
if available_height < MIN_VIEWPORT_HEIGHT {
|
||||
execute!(
|
||||
backend,
|
||||
ScrollUp(MIN_VIEWPORT_HEIGHT - available_height)
|
||||
)?;
|
||||
cursor_position.y = cursor_position.y.saturating_sub(
|
||||
MIN_VIEWPORT_HEIGHT - available_height + 1,
|
||||
);
|
||||
}
|
||||
let cursor_position = Self::get_cursor_position();
|
||||
let cursor_position = Self::handle_viewport_scrolling(
|
||||
&mut backend,
|
||||
cursor_position,
|
||||
terminal_size,
|
||||
MIN_VIEWPORT_HEIGHT,
|
||||
)?;
|
||||
|
||||
// Calculate final available height after potential scrolling
|
||||
let available_height = terminal_size
|
||||
.height
|
||||
.saturating_sub(cursor_position.y)
|
||||
.max(MIN_VIEWPORT_HEIGHT);
|
||||
|
||||
Viewport::Fixed(ratatui::layout::Rect::new(
|
||||
0,
|
||||
cursor_position.y,
|
||||
@ -107,16 +104,15 @@ where
|
||||
))
|
||||
}
|
||||
TuiMode::Fixed { width, height } => {
|
||||
let mut cursor_position = Self::get_cursor_position();
|
||||
let cursor_position = Self::get_cursor_position();
|
||||
let cursor_position = Self::handle_viewport_scrolling(
|
||||
&mut backend,
|
||||
cursor_position,
|
||||
terminal_size,
|
||||
*height,
|
||||
)?;
|
||||
|
||||
let w = width.unwrap_or(terminal_size.width);
|
||||
let available_height =
|
||||
terminal_size.height.saturating_sub(cursor_position.y);
|
||||
if available_height < *height {
|
||||
execute!(backend, ScrollUp(height - available_height))?;
|
||||
cursor_position.y = cursor_position
|
||||
.y
|
||||
.saturating_sub(*height - available_height + 1);
|
||||
}
|
||||
Viewport::Fixed(ratatui::layout::Rect::new(
|
||||
0,
|
||||
cursor_position.y,
|
||||
@ -131,8 +127,47 @@ where
|
||||
Ok(Self { terminal, viewport })
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Result<Size> {
|
||||
Ok(self.terminal.size()?)
|
||||
/// Handles scrolling logic when there's insufficient space for the requested height.
|
||||
/// Returns the updated cursor position after scrolling.
|
||||
fn handle_viewport_scrolling(
|
||||
backend: &mut CrosstermBackend<W>,
|
||||
mut cursor_position: Position,
|
||||
terminal_size: Size,
|
||||
required_height: u16,
|
||||
) -> Result<Position> {
|
||||
let available_height =
|
||||
terminal_size.height.saturating_sub(cursor_position.y);
|
||||
|
||||
debug!(
|
||||
"Terminal height: {}, Available height: {}, cursor position: {:?}",
|
||||
terminal_size.height, available_height, cursor_position.y
|
||||
);
|
||||
|
||||
// If we don't have enough space for the required height we need to scroll up.
|
||||
if available_height < required_height {
|
||||
// Minus one to account for the cursor position.
|
||||
let scroll_amount = required_height - available_height - 1;
|
||||
|
||||
// Special case: when we're at the very bottom (available_height == 1),
|
||||
// we need to scroll one less line to avoid creating an empty line
|
||||
// between the TUI and the prompt due to terminal cursor positioning.
|
||||
let actual_scroll = if available_height == 1 {
|
||||
scroll_amount - 1
|
||||
} else {
|
||||
scroll_amount
|
||||
};
|
||||
|
||||
// Scroll up by as needed to reach the required height.
|
||||
debug!("Scrolling up by: {}", actual_scroll);
|
||||
execute!(backend, ScrollUp(actual_scroll))?;
|
||||
|
||||
// Update cursor position to account for the scroll.
|
||||
debug!("New cursor position: {}", cursor_position.y);
|
||||
cursor_position.y =
|
||||
cursor_position.y.saturating_sub(scroll_amount);
|
||||
}
|
||||
|
||||
Ok(cursor_position)
|
||||
}
|
||||
|
||||
const DSR: &'static str = "\x1b[6n";
|
||||
|
Loading…
x
Reference in New Issue
Block a user