From f85cbce4c6e744c09a13059ba7761156a784051f Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Wed, 28 Aug 2024 07:53:56 +0100 Subject: [PATCH] refactor(tui): child widget can provide constraint to container --- crates/cli/src/tui/components/history.rs | 8 +++ crates/cli/src/tui/components/mod.rs | 8 +++ crates/cli/src/tui/components/repo/mod.rs | 67 +++++++++++------------ 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/crates/cli/src/tui/components/history.rs b/crates/cli/src/tui/components/history.rs index 32714e5..f1b8c8b 100644 --- a/crates/cli/src/tui/components/history.rs +++ b/crates/cli/src/tui/components/history.rs @@ -1,13 +1,21 @@ use git_next_core::git::graph::Log; // use ratatui::{ + prelude::Constraint, text::{Line, Text}, widgets::{Paragraph, Widget}, }; +use super::HeightConstraint; + pub struct CommitLog<'a> { pub log: &'a Log, } +impl<'a> HeightConstraint for CommitLog<'a> { + fn height_constraint(&self) -> Constraint { + Constraint::Length(u16::try_from(self.log.len()).unwrap_or(u16::MAX)) + } +} impl<'a> Widget for CommitLog<'a> { fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer) where diff --git a/crates/cli/src/tui/components/mod.rs b/crates/cli/src/tui/components/mod.rs index 30414f0..f7f034e 100644 --- a/crates/cli/src/tui/components/mod.rs +++ b/crates/cli/src/tui/components/mod.rs @@ -6,3 +6,11 @@ mod repo; pub use configured_app::ConfiguredAppWidget; pub use history::CommitLog; +use ratatui::layout::Constraint; + +pub trait HeightConstraint { + fn height_constraint(&self) -> Constraint; +} +// pub trait WidthConstraints { +// fn width_constraint(&self) -> Constraint; +// } diff --git a/crates/cli/src/tui/components/repo/mod.rs b/crates/cli/src/tui/components/repo/mod.rs index c418c48..f89eeed 100644 --- a/crates/cli/src/tui/components/repo/mod.rs +++ b/crates/cli/src/tui/components/repo/mod.rs @@ -14,34 +14,30 @@ use identity::Identity; use ratatui::{ buffer::Buffer, - layout::{Constraint, Direction, Layout, Rect}, + layout::{Constraint, Rect}, widgets::{Block, Borders, Widget}, }; +use super::HeightConstraint; + pub struct RepoWidget<'a> { pub repo_state: &'a RepoState, } -impl<'a> Widget for RepoWidget<'a> { - fn render(self, area: Rect, buf: &mut Buffer) - where - Self: Sized, - { +impl<'a> RepoWidget<'a> { + fn inner(&self) -> InnerRepoWidget { match self.repo_state { RepoState::Identified { repo_alias, message, alert, - } => { - InnerRepoWidget { - label: "identified", - repo_alias, - message, - alert: alert.as_ref().map(String::as_str), - branches: None, - log: None, - } - .render(area, buf); - } + } => InnerRepoWidget { + label: "identified", + repo_alias, + message, + alert: alert.as_ref().map(String::as_str), + branches: None, + log: None, + }, RepoState::Configured { repo_alias, @@ -56,8 +52,7 @@ impl<'a> Widget for RepoWidget<'a> { alert: alert.as_ref().map(String::as_str), branches: Some(branches), log: Some(log), - } - .render(area, buf), + }, RepoState::Ready { repo_alias, @@ -81,12 +76,18 @@ impl<'a> Widget for RepoWidget<'a> { // main, // next, // dev, - } - .render(area, buf), - }; + }, + } + } +} +impl<'a> Widget for RepoWidget<'a> { + fn render(self, area: Rect, buf: &mut Buffer) + where + Self: Sized, + { + self.inner().render(area, buf); } } -// struct InnerRepoWidget<'a> { pub label: &'a str, @@ -100,6 +101,13 @@ struct InnerRepoWidget<'a> { // pub next: &'a Commit, // pub dev: &'a Commit, } +impl<'a> HeightConstraint for InnerRepoWidget<'a> { + fn height_constraint(&self) -> ratatui::prelude::Constraint { + self.log + .map(|log| CommitLog { log }) + .map_or(Constraint::Length(0), |w| w.height_constraint()) + } +} impl<'a> Widget for InnerRepoWidget<'a> { fn render(self, area: Rect, buf: &mut Buffer) where @@ -114,18 +122,9 @@ impl<'a> Widget for InnerRepoWidget<'a> { self.branches, )) .borders(Borders::ALL); - let log_len: u16 = self.log.map_or_else( - || 0, - |log| u16::try_from(log.len()).map_or(u16::MAX, |len| len), - ); - let layout_repo = Layout::default() - .direction(Direction::Vertical) - .constraints(vec![Constraint::Length(log_len)]) - .split(block.inner(area)); - block.render(area, buf); - if let Some(log) = self.log { - CommitLog { log }.render(layout_repo[0], buf); + (CommitLog { log }).render(block.inner(area), buf); } + block.render(area, buf); } }