mirror of
https://github.com/mfontanini/presenterm.git
synced 2025-05-06 07:52:59 +00:00
feat: allow configuring alignment when max columns is hit
This commit is contained in:
parent
ec1be93a06
commit
24e6ea8386
@ -50,6 +50,14 @@
|
|||||||
"format": "uint16",
|
"format": "uint16",
|
||||||
"minimum": 0.0
|
"minimum": 0.0
|
||||||
},
|
},
|
||||||
|
"max_columns_alignment": {
|
||||||
|
"description": "The alignment the presentation should have if `max_columns` is set and the terminal is larger than that.",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/MaxColumnsAlignment"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"terminal_font_size": {
|
"terminal_font_size": {
|
||||||
"description": "Override the terminal font size when in windows or when using sixel.",
|
"description": "Override the terminal font size when in windows or when using sixel.",
|
||||||
"default": 16,
|
"default": 16,
|
||||||
@ -267,6 +275,32 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MaxColumnsAlignment": {
|
||||||
|
"description": "The alignment to use when `defaults.max_columns` is set.",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"description": "Align the presentation to the left.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"left"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Align the presentation on the center.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"center"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Align the presentation to the right.",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"right"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"MermaidConfig": {
|
"MermaidConfig": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -74,7 +74,7 @@ pub struct DefaultsConfig {
|
|||||||
pub theme: Option<String>,
|
pub theme: Option<String>,
|
||||||
|
|
||||||
/// Override the terminal font size when in windows or when using sixel.
|
/// Override the terminal font size when in windows or when using sixel.
|
||||||
#[serde(default = "default_font_size")]
|
#[serde(default = "default_terminal_font_size")]
|
||||||
#[validate(range(min = 1))]
|
#[validate(range(min = 1))]
|
||||||
pub terminal_font_size: u8,
|
pub terminal_font_size: u8,
|
||||||
|
|
||||||
@ -89,24 +89,45 @@ pub struct DefaultsConfig {
|
|||||||
/// A max width in columns that the presentation must always be capped to.
|
/// A max width in columns that the presentation must always be capped to.
|
||||||
#[serde(default = "default_max_columns")]
|
#[serde(default = "default_max_columns")]
|
||||||
pub max_columns: u16,
|
pub max_columns: u16,
|
||||||
|
|
||||||
|
/// The alignment the presentation should have if `max_columns` is set and the terminal is
|
||||||
|
/// larger than that.
|
||||||
|
#[serde(default)]
|
||||||
|
pub max_columns_alignment: MaxColumnsAlignment,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DefaultsConfig {
|
impl Default for DefaultsConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
theme: Default::default(),
|
theme: Default::default(),
|
||||||
terminal_font_size: default_font_size(),
|
terminal_font_size: default_terminal_font_size(),
|
||||||
image_protocol: Default::default(),
|
image_protocol: Default::default(),
|
||||||
validate_overflows: Default::default(),
|
validate_overflows: Default::default(),
|
||||||
max_columns: default_max_columns(),
|
max_columns: default_max_columns(),
|
||||||
|
max_columns_alignment: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_font_size() -> u8 {
|
fn default_terminal_font_size() -> u8 {
|
||||||
16
|
16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The alignment to use when `defaults.max_columns` is set.
|
||||||
|
#[derive(Clone, Copy, Debug, Default, Deserialize, JsonSchema)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum MaxColumnsAlignment {
|
||||||
|
/// Align the presentation to the left.
|
||||||
|
Left,
|
||||||
|
|
||||||
|
/// Align the presentation on the center.
|
||||||
|
#[default]
|
||||||
|
Center,
|
||||||
|
|
||||||
|
/// Align the presentation to the right.
|
||||||
|
Right,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, JsonSchema)]
|
#[derive(Clone, Debug, Default, Deserialize, JsonSchema)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum ValidateOverflows {
|
pub enum ValidateOverflows {
|
||||||
|
@ -418,6 +418,7 @@ fn run(cli: Cli) -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
bindings: config.bindings,
|
bindings: config.bindings,
|
||||||
validate_overflows,
|
validate_overflows,
|
||||||
max_columns: config.defaults.max_columns,
|
max_columns: config.defaults.max_columns,
|
||||||
|
max_columns_alignment: config.defaults.max_columns_alignment,
|
||||||
};
|
};
|
||||||
let presenter = Presenter::new(
|
let presenter = Presenter::new(
|
||||||
&default_theme,
|
&default_theme,
|
||||||
|
@ -4,7 +4,7 @@ use crate::{
|
|||||||
listener::{Command, CommandListener},
|
listener::{Command, CommandListener},
|
||||||
speaker_notes::{SpeakerNotesEvent, SpeakerNotesEventPublisher},
|
speaker_notes::{SpeakerNotesEvent, SpeakerNotesEventPublisher},
|
||||||
},
|
},
|
||||||
config::KeyBindingsConfig,
|
config::{KeyBindingsConfig, MaxColumnsAlignment},
|
||||||
export::ImageReplacer,
|
export::ImageReplacer,
|
||||||
markdown::parse::{MarkdownParser, ParseError},
|
markdown::parse::{MarkdownParser, ParseError},
|
||||||
presentation::{
|
presentation::{
|
||||||
@ -43,6 +43,7 @@ pub struct PresenterOptions {
|
|||||||
pub bindings: KeyBindingsConfig,
|
pub bindings: KeyBindingsConfig,
|
||||||
pub validate_overflows: bool,
|
pub validate_overflows: bool,
|
||||||
pub max_columns: u16,
|
pub max_columns: u16,
|
||||||
|
pub max_columns_alignment: MaxColumnsAlignment,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A slideshow presenter.
|
/// A slideshow presenter.
|
||||||
@ -105,6 +106,7 @@ impl<'a> Presenter<'a> {
|
|||||||
let drawer_options = TerminalDrawerOptions {
|
let drawer_options = TerminalDrawerOptions {
|
||||||
font_size_fallback: self.options.font_size_fallback,
|
font_size_fallback: self.options.font_size_fallback,
|
||||||
max_columns: self.options.max_columns,
|
max_columns: self.options.max_columns,
|
||||||
|
max_columns_alignment: self.options.max_columns_alignment,
|
||||||
};
|
};
|
||||||
let mut drawer = TerminalDrawer::new(self.image_printer.clone(), drawer_options)?;
|
let mut drawer = TerminalDrawer::new(self.image_printer.clone(), drawer_options)?;
|
||||||
loop {
|
loop {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use super::{RenderError, RenderResult, layout::Layout, properties::CursorPosition, text::TextDrawer};
|
use super::{RenderError, RenderResult, layout::Layout, properties::CursorPosition, text::TextDrawer};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
config::MaxColumnsAlignment,
|
||||||
markdown::{text::WeightedLine, text_style::Colors},
|
markdown::{text::WeightedLine, text_style::Colors},
|
||||||
render::{
|
render::{
|
||||||
layout::Positioning,
|
layout::Positioning,
|
||||||
@ -27,12 +28,18 @@ const MINIMUM_LINE_LENGTH: u16 = 10;
|
|||||||
pub(crate) struct RenderEngineOptions {
|
pub(crate) struct RenderEngineOptions {
|
||||||
pub(crate) validate_overflows: bool,
|
pub(crate) validate_overflows: bool,
|
||||||
pub(crate) max_columns: u16,
|
pub(crate) max_columns: u16,
|
||||||
|
pub(crate) max_columns_alignment: MaxColumnsAlignment,
|
||||||
pub(crate) column_layout_margin: u16,
|
pub(crate) column_layout_margin: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for RenderEngineOptions {
|
impl Default for RenderEngineOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { validate_overflows: false, max_columns: u16::MAX, column_layout_margin: 4 }
|
Self {
|
||||||
|
validate_overflows: false,
|
||||||
|
max_columns: u16::MAX,
|
||||||
|
max_columns_alignment: Default::default(),
|
||||||
|
column_layout_margin: 4,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +78,12 @@ where
|
|||||||
if window_dimensions.columns > options.max_columns {
|
if window_dimensions.columns > options.max_columns {
|
||||||
let extra_width = window_dimensions.columns - options.max_columns;
|
let extra_width = window_dimensions.columns - options.max_columns;
|
||||||
let dimensions = window_dimensions.shrink_columns(extra_width);
|
let dimensions = window_dimensions.shrink_columns(extra_width);
|
||||||
WindowRect { dimensions, start_column: extra_width / 2, start_row }
|
let start_column = match options.max_columns_alignment {
|
||||||
|
MaxColumnsAlignment::Left => 0,
|
||||||
|
MaxColumnsAlignment::Center => extra_width / 2,
|
||||||
|
MaxColumnsAlignment::Right => extra_width,
|
||||||
|
};
|
||||||
|
WindowRect { dimensions, start_column, start_row }
|
||||||
} else {
|
} else {
|
||||||
WindowRect { dimensions: window_dimensions, start_column: 0, start_row }
|
WindowRect { dimensions: window_dimensions, start_column: 0, start_row }
|
||||||
}
|
}
|
||||||
@ -549,7 +561,12 @@ mod tests {
|
|||||||
fn render(operations: &[RenderOperation]) -> Vec<Instruction> {
|
fn render(operations: &[RenderOperation]) -> Vec<Instruction> {
|
||||||
let mut buf = TerminalBuf::default();
|
let mut buf = TerminalBuf::default();
|
||||||
let dimensions = WindowSize { rows: 100, columns: 100, height: 200, width: 200 };
|
let dimensions = WindowSize { rows: 100, columns: 100, height: 200, width: 200 };
|
||||||
let options = RenderEngineOptions { validate_overflows: false, max_columns: u16::MAX, column_layout_margin: 0 };
|
let options = RenderEngineOptions {
|
||||||
|
validate_overflows: false,
|
||||||
|
max_columns: u16::MAX,
|
||||||
|
max_columns_alignment: Default::default(),
|
||||||
|
column_layout_margin: 0,
|
||||||
|
};
|
||||||
let engine = RenderEngine::new(&mut buf, dimensions, options);
|
let engine = RenderEngine::new(&mut buf, dimensions, options);
|
||||||
engine.render(operations.iter()).expect("render failed");
|
engine.render(operations.iter()).expect("render failed");
|
||||||
buf.instructions
|
buf.instructions
|
||||||
|
@ -6,6 +6,7 @@ pub(crate) mod text;
|
|||||||
pub(crate) mod validate;
|
pub(crate) mod validate;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
config::MaxColumnsAlignment,
|
||||||
markdown::{
|
markdown::{
|
||||||
elements::Text,
|
elements::Text,
|
||||||
text::WeightedLine,
|
text::WeightedLine,
|
||||||
@ -28,16 +29,14 @@ use std::{
|
|||||||
pub(crate) type RenderResult = Result<(), RenderError>;
|
pub(crate) type RenderResult = Result<(), RenderError>;
|
||||||
|
|
||||||
pub(crate) struct TerminalDrawerOptions {
|
pub(crate) struct TerminalDrawerOptions {
|
||||||
/// The font size to fall back to if we can't find the window size in pixels.
|
|
||||||
pub(crate) font_size_fallback: u8,
|
pub(crate) font_size_fallback: u8,
|
||||||
|
|
||||||
/// The max width in columns that the presentation should be capped to.
|
|
||||||
pub(crate) max_columns: u16,
|
pub(crate) max_columns: u16,
|
||||||
|
pub(crate) max_columns_alignment: MaxColumnsAlignment,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TerminalDrawerOptions {
|
impl Default for TerminalDrawerOptions {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { font_size_fallback: 1, max_columns: u16::MAX }
|
Self { font_size_fallback: 1, max_columns: u16::MAX, max_columns_alignment: Default::default() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +97,11 @@ impl TerminalDrawer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn create_engine(&mut self, dimensions: WindowSize) -> RenderEngine<Terminal<Stdout>> {
|
fn create_engine(&mut self, dimensions: WindowSize) -> RenderEngine<Terminal<Stdout>> {
|
||||||
let options = RenderEngineOptions { max_columns: self.options.max_columns, ..Default::default() };
|
let options = RenderEngineOptions {
|
||||||
|
max_columns: self.options.max_columns,
|
||||||
|
max_columns_alignment: self.options.max_columns_alignment,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
RenderEngine::new(&mut self.terminal, dimensions, options)
|
RenderEngine::new(&mut self.terminal, dimensions, options)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user