use std::collections::BTreeMap; use git_next_core::ForgeAlias; use ratatui::{ buffer::Buffer, layout::{Direction, Layout, Rect, Size}, widgets::StatefulWidget, }; use tui_scrollview::{ScrollView, ScrollViewState}; use crate::tui::actor::ForgeState; use super::{forge::ForgeWidget, HeightContraintLength}; pub struct ConfiguredAppWidget<'a> { pub forges: &'a BTreeMap, } impl<'a> HeightContraintLength for ConfiguredAppWidget<'a> { fn height_constraint_length(&self) -> u16 { self.children() .iter() .map(HeightContraintLength::height_constraint_length) .sum::() + 2 // top + bottom borders } } impl<'a> StatefulWidget for ConfiguredAppWidget<'a> { type State = ScrollViewState; fn render(self, area: Rect, buf: &mut Buffer, state: &mut Self::State) where Self: Sized, { let height = self .children() .iter() .map(HeightContraintLength::height_constraint_length) .sum::(); let mut scroll = ScrollView::new(Size::new(area.width - 1, height)); let layout_forge_list = Layout::default() .direction(Direction::Vertical) .constraints( self.children() .iter() .map(HeightContraintLength::height_constraint_length), ) .split(scroll.area()); self.children() .into_iter() .enumerate() .for_each(|(i, w)| scroll.render_widget(w, layout_forge_list[i])); scroll.render(area, buf, state); } } impl<'a> ConfiguredAppWidget<'a> { fn children(&self) -> Vec> { self.forges .iter() .map(|(forge_alias, state)| ForgeWidget { forge_alias, repos: &state.repos, view_state: state.view_state, }) .collect::>() } }