feat(ui): decouple preview title position from input bar position and make it configurable (#144)

fixes #143 

## example
```toml
[ui]
input_bar_position = "top"
preview_title_position = "top"
```

<img width="2553" alt="Screenshot 2024-12-18 at 22 06 29"
src="https://github.com/user-attachments/assets/6c9ac842-e383-42a8-bdf4-d48c7a826df3"
/>
This commit is contained in:
Alex Pasmantier 2024-12-18 22:30:10 +01:00 committed by GitHub
parent ac7762e8f2
commit 22f1b4dc33
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 35 additions and 7 deletions

View File

@ -40,6 +40,8 @@ ui_scale = 100
show_help_bar = true show_help_bar = true
# Where to place the input bar in the UI (top or bottom) # Where to place the input bar in the UI (top or bottom)
input_bar_position = "bottom" input_bar_position = "bottom"
# Where to place the preview title in the UI (top or bottom)
preview_title_position = "top"
# The theme to use for the UI # The theme to use for the UI
# A list of builtin themes can be found in the `themes` directory of the television # A list of builtin themes can be found in the `themes` directory of the television
# repository. You may also create your own theme by creating a new file in a `themes` # repository. You may also create your own theme by creating a new file in a `themes`

View File

@ -62,6 +62,24 @@ impl Display for InputPosition {
} }
} }
#[derive(Debug, Clone, Copy, Deserialize, Default)]
pub enum PreviewTitlePosition {
#[serde(rename = "top")]
#[default]
Top,
#[serde(rename = "bottom")]
Bottom,
}
impl Display for PreviewTitlePosition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PreviewTitlePosition::Top => write!(f, "top"),
PreviewTitlePosition::Bottom => write!(f, "bottom"),
}
}
}
pub struct Layout { pub struct Layout {
pub help_bar: Option<HelpBarLayout>, pub help_bar: Option<HelpBarLayout>,
pub results: Rect, pub results: Rect,
@ -97,6 +115,7 @@ impl Layout {
with_remote: bool, with_remote: bool,
with_help_bar: bool, with_help_bar: bool,
input_position: InputPosition, input_position: InputPosition,
preview_title_position: PreviewTitlePosition,
) -> Self { ) -> Self {
let main_block = centered_rect(dimensions.x, dimensions.y, area); let main_block = centered_rect(dimensions.x, dimensions.y, area);
// split the main block into two vertical chunks (help bar + rest) // split the main block into two vertical chunks (help bar + rest)
@ -172,16 +191,16 @@ impl Layout {
let right_chunks = layout::Layout::default() let right_chunks = layout::Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.constraints(match input_position { .constraints(match preview_title_position {
InputPosition::Top => { PreviewTitlePosition::Bottom => {
preview_constraints.into_iter().rev().collect() preview_constraints.into_iter().rev().collect()
} }
InputPosition::Bottom => preview_constraints, PreviewTitlePosition::Top => preview_constraints,
}) })
.split(vt_chunks[1]); .split(vt_chunks[1]);
let (preview_title, preview_window) = match input_position { let (preview_title, preview_window) = match preview_title_position {
InputPosition::Bottom => (right_chunks[0], right_chunks[1]), PreviewTitlePosition::Top => (right_chunks[0], right_chunks[1]),
InputPosition::Top => (right_chunks[1], right_chunks[0]), PreviewTitlePosition::Bottom => (right_chunks[1], right_chunks[0]),
}; };
Self::new( Self::new(

View File

@ -2,7 +2,7 @@ use config::ValueKind;
use serde::Deserialize; use serde::Deserialize;
use std::collections::HashMap; use std::collections::HashMap;
use television_screen::layout::InputPosition; use television_screen::layout::{InputPosition, PreviewTitlePosition};
use super::themes::DEFAULT_THEME; use super::themes::DEFAULT_THEME;
@ -15,6 +15,7 @@ pub struct UiConfig {
pub show_help_bar: bool, pub show_help_bar: bool,
#[serde(default)] #[serde(default)]
pub input_bar_position: InputPosition, pub input_bar_position: InputPosition,
pub preview_title_position: PreviewTitlePosition,
pub theme: String, pub theme: String,
} }
@ -25,6 +26,7 @@ impl Default for UiConfig {
ui_scale: DEFAULT_UI_SCALE, ui_scale: DEFAULT_UI_SCALE,
show_help_bar: true, show_help_bar: true,
input_bar_position: InputPosition::Bottom, input_bar_position: InputPosition::Bottom,
preview_title_position: PreviewTitlePosition::Top,
theme: String::from(DEFAULT_THEME), theme: String::from(DEFAULT_THEME),
} }
} }
@ -49,6 +51,10 @@ impl From<UiConfig> for ValueKind {
String::from("input_position"), String::from("input_position"),
ValueKind::String(val.input_bar_position.to_string()).into(), ValueKind::String(val.input_bar_position.to_string()).into(),
); );
m.insert(
String::from("preview_title_position"),
ValueKind::String(val.preview_title_position.to_string()).into(),
);
m.insert(String::from("theme"), ValueKind::String(val.theme).into()); m.insert(String::from("theme"), ValueKind::String(val.theme).into());
ValueKind::Table(m) ValueKind::Table(m)
} }

View File

@ -406,6 +406,7 @@ impl Television {
!matches!(self.mode, Mode::Channel), !matches!(self.mode, Mode::Channel),
self.config.ui.show_help_bar, self.config.ui.show_help_bar,
self.config.ui.input_bar_position, self.config.ui.input_bar_position,
self.config.ui.preview_title_position,
); );
// help bar (metadata, keymaps, logo) // help bar (metadata, keymaps, logo)