mod align;
mod grid_solver;
mod row_solver;
mod single_solver;
mod size_rules;
mod size_types;
mod sizer;
mod storage;
mod visitor;
use crate::dir::{Direction, Directional, Directions};
use crate::event::ConfigMgr;
use crate::geom::{Coord, Rect};
use crate::theme::{DrawMgr, SizeMgr};
use crate::WidgetId;
#[allow(unused)] use crate::Layout;
pub use align::{Align, AlignHints, AlignPair};
pub use grid_solver::{DefaultWithLen, GridChildInfo, GridDimensions, GridSetter, GridSolver};
pub use row_solver::{RowPositionSolver, RowSetter, RowSolver};
pub use single_solver::{SingleSetter, SingleSolver};
pub use size_rules::SizeRules;
pub use size_types::*;
pub use sizer::{solve_size_rules, RulesSetter, RulesSolver, SolveCache};
pub use storage::*;
pub use visitor::{FrameStorage, PackStorage, Visitor};
#[derive(Copy, Clone, Debug)]
pub struct AxisInfo {
vertical: bool,
has_fixed: bool,
other_axis: i32,
align: Option<Align>,
}
impl AxisInfo {
#[inline]
pub fn new(vertical: bool, fixed: Option<i32>, align: Option<Align>) -> Self {
AxisInfo {
vertical,
has_fixed: fixed.is_some(),
other_axis: fixed.unwrap_or(0),
align,
}
}
#[inline]
pub fn with_align_hints(mut self, hints: AlignHints) -> Self {
self.align = hints.extract(self).or(self.align);
self
}
#[inline]
pub fn is_vertical(self) -> bool {
self.vertical
}
#[inline]
pub fn is_horizontal(self) -> bool {
!self.vertical
}
#[inline]
pub fn align(self) -> Option<Align> {
self.align
}
#[inline]
pub fn set_align(&mut self, align: Option<Align>) {
self.align = align;
}
#[inline]
pub fn set_default_align(&mut self, align: Align) {
if self.align.is_none() {
self.align = Some(align);
}
}
#[inline]
pub fn set_default_align_hv(&mut self, horiz: Align, vert: Align) {
if self.align.is_none() {
if self.is_horizontal() {
self.align = Some(horiz);
} else {
self.align = Some(vert);
}
}
}
#[inline]
pub fn align_or_default(self) -> Align {
self.align.unwrap_or(Align::Default)
}
#[inline]
pub fn align_or_center(self) -> Align {
self.align.unwrap_or(Align::Center)
}
#[inline]
pub fn align_or_stretch(self) -> Align {
self.align.unwrap_or(Align::Stretch)
}
#[inline]
pub fn other(&self) -> Option<i32> {
if self.has_fixed {
Some(self.other_axis)
} else {
None
}
}
#[inline]
pub fn size_other_if_fixed(&self, vertical: bool) -> Option<i32> {
if vertical == self.vertical && self.has_fixed {
Some(self.other_axis)
} else {
None
}
}
#[inline]
pub fn sub_other(&mut self, x: i32) {
self.other_axis -= x;
}
}
impl Directional for AxisInfo {
type Flipped = Self;
type Reversed = Self;
fn flipped(mut self) -> Self::Flipped {
self.vertical = !self.vertical;
self.has_fixed = false;
self
}
#[inline]
fn reversed(self) -> Self::Reversed {
self
}
#[inline]
fn as_direction(self) -> Direction {
match self.vertical {
false => Direction::Right,
true => Direction::Down,
}
}
}
impl From<AxisInfo> for Directions {
fn from(axis: AxisInfo) -> Directions {
match axis.vertical {
false => Directions::LEFT | Directions::RIGHT,
true => Directions::UP | Directions::DOWN,
}
}
}
pub trait AutoLayout {
fn size_rules(&mut self, size_mgr: SizeMgr, axis: AxisInfo) -> SizeRules;
fn set_rect(&mut self, mgr: &mut ConfigMgr, rect: Rect);
fn find_id(&mut self, coord: Coord) -> Option<WidgetId>;
fn draw(&mut self, draw: DrawMgr);
}
#[cfg(test)]
#[test]
fn size() {
assert_eq!(std::mem::size_of::<AxisInfo>(), 8);
}