From d713a9d666e5bfa1ec58ef22229deb74db9f3975 Mon Sep 17 00:00:00 2001 From: Builditluc Date: Wed, 13 Nov 2024 10:11:24 +0100 Subject: [PATCH] Implement size constraints for content in zen-mode This commit will implement and document two options for setting constraints on the horizontal and vertical length of the content in zen-mode. Signed-off-by: Builditluc --- docs/docs/configuration/page.md | 40 +++++++++++++++++++++++++++++++++ src/components/page.rs | 15 ++++++++++--- src/config.rs | 38 ++++++++++++++++++++++++++++++- 3 files changed, 89 insertions(+), 4 deletions(-) diff --git a/docs/docs/configuration/page.md b/docs/docs/configuration/page.md index 1e9f3e79..83d49507 100644 --- a/docs/docs/configuration/page.md +++ b/docs/docs/configuration/page.md @@ -177,6 +177,46 @@ page.zen_mode.include = "TOC|SCROLLBAR" ![Zen](../assets/images/page-zen.png) +### Changing the size of the content in zen mode + +[:octicons-tag-24: 0.9.0][release-0.9.0] ยท :octicons-milestone-16: Default `80` | `90` + +You can change the size of the content in zen mode by setting the horizontal and vertical constraint +of the content. For example, this is the default configuration for the zen mode: + +```toml +page.zen_mode.horizontal.percentage = 80 +page.zen_mode.vertical.percentage = 90 +``` + +Both of these settings share the same configuration schema. A constraint can have a fixed size or be a +relative constraint. + +* **Min**: `page.zen_mode.{horizontal|vertical}.min = u16` + Applies a minimum size constraint to the element. The element size is set to at least the + specified amount. +* **Max**: `page.zen_mode.{horizontal|vertical}.max = u16` + Applies a maximum size constraint to the element. The element size is set to at most the + specified amount. +* **Length**: `page.zen_mode.{horizontal|vertical}.length = u16` + Applies a length constraint to the element. The element size is set to the specified amount. +* **Percentage**: `page.zen_mode.{horizontal|vertical}.percentage = u16` + Applies a percentage of the available space to the element + + Converts the given percentage to a floating-point value and multiplies that with area. This + value is rounded back to a integer as part of the layout split calculation. + + !!! note + As this value only accepts a u16, certain percentages that cannot be represented exactly + (e.g. 1/3) are not possible. You might want to use Ratio in such cases. + +* **Ratio**: `page.zen_mode.{horizontal|vertical}.ratio = [u32, u32]` + Applies a ratio of the available space to the element + + Converts the given ratio to a floating-point value and multiplies that with area. This value + is rounded back to a integer as part of the layout split calculation. + + [release-0.9.0]: https://github.com/Builditluc/wiki-tui/releases/tag/v0.9 [release-0.5.1]: https://github.com/Builditluc/wiki-tui/releases/tag/v0.5.1 diff --git a/src/components/page.rs b/src/components/page.rs index ea210565..cf813379 100644 --- a/src/components/page.rs +++ b/src/components/page.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, sync::Arc}; use crossterm::event::{KeyCode, KeyEvent}; use ratatui::{ - layout::{Constraint, Direction, Layout}, + layout::{Constraint, Direction, Flex, Layout}, prelude::{Margin, Rect}, style::{Color, Modifier, Style, Stylize}, text::{Line, Span}, @@ -691,8 +691,17 @@ impl Component for PageComponent { fn render(&mut self, f: &mut Frame, mut area: Rect) { let zen_mode = self.config.page.zen_mode.clone(); - // we add padding to the area by using a Block with padding - area = Block::new().padding(self.config.page.padding).inner(area); + // when in zen mode, use the constraints for the zen mode, otherwise the regular padding + area = if self.is_zen_mode() { + let [area] = Layout::horizontal([self.config.page.zen_horizontal]) + .flex(Flex::Center) + .areas(area); + Layout::vertical([self.config.page.zen_vertical]) + .flex(Flex::Center) + .split(area)[0] + } else { + Block::new().padding(self.config.page.padding).inner(area) + }; if !self.is_zen_mode || zen_mode.contains(ZenModeComponents::STATUS_BAR) { area = self.render_status_bar(f, area); diff --git a/src/config.rs b/src/config.rs index b07cf2b7..ba4919ce 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,6 +2,7 @@ use anyhow::{bail, Context, Result}; use bitflags::bitflags; use directories::ProjectDirs; use ratatui::{ + layout::Constraint, style::{Color, Style}, widgets::{BorderType, Padding}, }; @@ -92,7 +93,10 @@ fn override_page_config(config: &mut PageConfig, user_config: UserPageConfig) { if let Some(user_zen) = user_config.zen_mode { override_options!(config, user_zen::{ default->default_zen, - include->zen_mode + include->zen_mode, + + horizontal->zen_horizontal, + vertical->zen_vertical }); } } @@ -122,6 +126,9 @@ pub struct PageConfig { pub default_zen: bool, pub zen_mode: ZenModeComponents, + + pub zen_horizontal: Constraint, + pub zen_vertical: Constraint, } bitflags! { @@ -202,6 +209,9 @@ impl Config { default_zen: false, zen_mode: ZenModeComponents::empty(), + + zen_horizontal: Constraint::Percentage(80), + zen_vertical: Constraint::Percentage(90), }, } } @@ -237,10 +247,36 @@ struct UserPageConfig { zen_mode: Option, } +#[derive(Deserialize)] +#[serde(rename_all = "lowercase")] +enum UserConstraint { + Min(u16), + Max(u16), + Length(u16), + Percentage(u16), + Ratio(u32, u32), +} + +#[allow(clippy::from_over_into)] +impl Into for UserConstraint { + fn into(self) -> Constraint { + match self { + UserConstraint::Min(u) => Constraint::Min(u), + UserConstraint::Max(u) => Constraint::Max(u), + UserConstraint::Length(u) => Constraint::Length(u), + UserConstraint::Percentage(u) => Constraint::Percentage(u), + UserConstraint::Ratio(u, v) => Constraint::Ratio(u, v), + } + } +} + #[derive(Deserialize)] struct UserZenModeConfig { default: Option, include: Option, + + horizontal: Option, + vertical: Option, } #[derive(Deserialize)]