use std::ops::Deref;
use cassowary::{Expression, Variable};
use crate::layout::Attr;
pub(crate) struct Variables {
idxes: Vec<Variable>,
}
impl Default for Variables {
fn default() -> Self {
Self {
idxes: Default::default(),
}
}
}
impl Variables {
#[inline(always)]
pub(crate) fn add(&mut self) -> Variable {
let var = Variable::new();
self.idxes.push(var);
var
}
#[inline(always)]
pub(crate) fn get_id(&self, var: Variable) -> usize {
self.idxes.iter().position(|&x| x == var).expect(
"Failed to find Cassowary Variable in vector of used Variables in split operation",
)
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct LineBox {
pub(crate) cross_start: Variable,
pub(crate) cross_size: Variable,
}
impl LineBox {
pub(crate) fn new(variables: &mut Variables) -> Self {
Self {
cross_start: variables.add(),
cross_size: variables.add(),
}
}
#[inline(always)]
pub(crate) fn vars(
&self,
vars: &mut Vec<Option<(usize, usize, Attr)>>,
line: usize,
variables: &Variables,
) {
vars[variables.get_id(self.cross_start)] = Some((line, 0, Attr::CrossStart));
vars[variables.get_id(self.cross_size)] = Some((line, 0, Attr::CrossSize));
}
#[inline(always)]
pub(crate) fn cross_end(&self) -> Expression {
self.cross_start + self.cross_size
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct Element {
pub(crate) start: Variable,
pub(crate) size: Variable,
pub(crate) strength: f64,
pub(crate) constraint: ElConstraint,
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub(crate) enum ElConstraint {
Min(f64),
Max(f64),
Percentage(f64),
Ratio(f64),
Length(f64),
}
impl Deref for ElConstraint {
type Target = f64;
fn deref(&self) -> &Self::Target {
match self {
ElConstraint::Min(v)
| ElConstraint::Max(v)
| ElConstraint::Percentage(v)
| ElConstraint::Ratio(v)
| ElConstraint::Length(v) => v,
}
}
}
impl Element {
pub(crate) fn new(
strength: f64,
constraint: ElConstraint,
variables: &mut Variables,
) -> Element {
Element {
start: variables.add(),
size: variables.add(),
strength,
constraint,
}
}
#[inline(always)]
pub(crate) fn vars(
&self,
vars: &mut Vec<Option<(usize, usize, Attr)>>,
line: usize,
index: usize,
variables: &Variables,
) {
vars[variables.get_id(self.start)] = Some((line, index, Attr::Start));
vars[variables.get_id(self.size)] = Some((line, index, Attr::Size));
}
#[inline(always)]
pub(crate) fn end(&self) -> Expression {
self.start + self.size
}
}