use super::{AxisInfo, SizeRules};
use crate::dir::Directional;
use crate::geom::{Offset, Rect, Size};
use crate::theme::{FrameStyle, SizeCx};
use kas_macros::impl_scope;
use std::fmt::Debug;
#[derive(Clone, Default, Debug)]
pub struct PackStorage {
pub size: Size,
}
#[derive(Clone, Default, Debug)]
pub struct FrameStorage {
pub size: Size,
pub offset: Offset,
pub rect: Rect,
}
impl FrameStorage {
pub fn child_axis(&self, mut axis: AxisInfo) -> AxisInfo {
let size = self.size.extract(axis.flipped());
axis.map_other(|v| v - size);
axis
}
pub fn size_rules(
&mut self,
cx: &mut SizeCx,
axis: AxisInfo,
child_rules: SizeRules,
style: FrameStyle,
) -> SizeRules {
let frame_rules = cx.frame(style, axis);
let (rules, offset, size) = frame_rules.surround(child_rules);
self.offset.set_component(axis, offset);
self.size.set_component(axis, size);
rules
}
}
pub trait RowStorage: Clone + Debug + sealed::Sealed {
fn set_dim(&mut self, cols: usize);
fn rules(&mut self) -> &mut [SizeRules] {
self.widths_and_rules().1
}
fn widths(&mut self) -> &mut [i32] {
self.widths_and_rules().0
}
fn widths_and_rules(&mut self) -> (&mut [i32], &mut [SizeRules]);
}
#[derive(Clone, Debug)]
pub struct FixedRowStorage<const C: usize> {
rules: [SizeRules; C],
widths: [i32; C],
}
impl<const C: usize> Default for FixedRowStorage<C> {
fn default() -> Self {
FixedRowStorage {
rules: [SizeRules::default(); C],
widths: [0; C],
}
}
}
impl<const C: usize> RowStorage for FixedRowStorage<C> {
fn set_dim(&mut self, cols: usize) {
assert_eq!(self.rules.as_ref().len(), cols);
assert_eq!(self.widths.as_ref().len(), cols);
}
fn widths_and_rules(&mut self) -> (&mut [i32], &mut [SizeRules]) {
(self.widths.as_mut(), self.rules.as_mut())
}
}
#[derive(Clone, Debug, Default)]
pub struct DynRowStorage {
rules: Vec<SizeRules>,
widths: Vec<i32>,
}
impl RowStorage for DynRowStorage {
fn set_dim(&mut self, cols: usize) {
self.rules.resize(cols, SizeRules::EMPTY);
self.widths.resize(cols, 0);
}
fn widths_and_rules(&mut self) -> (&mut [i32], &mut [SizeRules]) {
(&mut self.widths, &mut self.rules)
}
}
pub trait RowTemp: AsMut<[i32]> + Default + Debug + sealed::Sealed {
fn set_len(&mut self, len: usize);
}
impl RowTemp for Vec<i32> {
fn set_len(&mut self, len: usize) {
self.resize(len, 0);
}
}
impl<const L: usize> RowTemp for [i32; L]
where
[i32; L]: Default,
{
fn set_len(&mut self, len: usize) {
assert_eq!(self.len(), len);
}
}
pub trait GridStorage: sealed::Sealed + Clone + std::fmt::Debug {
fn set_dims(&mut self, cols: usize, rows: usize);
fn width_rules(&mut self) -> &mut [SizeRules] {
self.widths_and_rules().1
}
fn height_rules(&mut self) -> &mut [SizeRules] {
self.heights_and_rules().1
}
fn widths(&mut self) -> &mut [i32] {
self.widths_and_rules().0
}
fn heights(&mut self) -> &mut [i32] {
self.heights_and_rules().0
}
fn widths_and_rules(&mut self) -> (&mut [i32], &mut [SizeRules]);
fn heights_and_rules(&mut self) -> (&mut [i32], &mut [SizeRules]);
}
impl_scope! {
#[impl_default]
#[derive(Clone, Debug)]
pub struct FixedGridStorage<const C: usize, const R: usize> {
width_rules: [SizeRules; C] = [SizeRules::default(); C],
height_rules: [SizeRules; R] = [SizeRules::default(); R],
widths: [i32; C] = [0; C],
heights: [i32; R] = [0; R],
}
impl GridStorage for Self {
fn set_dims(&mut self, cols: usize, rows: usize) {
assert_eq!(self.width_rules.as_ref().len(), cols);
assert_eq!(self.height_rules.as_ref().len(), rows);
assert_eq!(self.widths.len(), cols);
assert_eq!(self.heights.len(), rows);
}
fn widths_and_rules(&mut self) -> (&mut [i32], &mut [SizeRules]) {
(
self.widths.as_mut(),
self.width_rules.as_mut(),
)
}
fn heights_and_rules(&mut self) -> (&mut [i32], &mut [SizeRules]) {
(
self.heights.as_mut(),
self.height_rules.as_mut(),
)
}
}
}
#[derive(Clone, Debug, Default)]
pub struct DynGridStorage {
width_rules: Vec<SizeRules>,
height_rules: Vec<SizeRules>,
widths: Vec<i32>,
heights: Vec<i32>,
}
impl GridStorage for DynGridStorage {
fn set_dims(&mut self, cols: usize, rows: usize) {
self.width_rules.resize(cols, SizeRules::EMPTY);
self.height_rules.resize(rows, SizeRules::EMPTY);
self.widths.resize(cols, 0);
self.heights.resize(rows, 0);
}
fn widths_and_rules(&mut self) -> (&mut [i32], &mut [SizeRules]) {
(self.widths.as_mut(), self.width_rules.as_mut())
}
fn heights_and_rules(&mut self) -> (&mut [i32], &mut [SizeRules]) {
(self.heights.as_mut(), self.height_rules.as_mut())
}
}
mod sealed {
pub trait Sealed {}
impl<const C: usize> Sealed for super::FixedRowStorage<C> {}
impl Sealed for super::DynRowStorage {}
impl Sealed for Vec<i32> {}
impl<const L: usize> Sealed for [i32; L] {}
impl<const C: usize, const R: usize> Sealed for super::FixedGridStorage<C, R> {}
impl Sealed for super::DynGridStorage {}
}