summaryrefslogtreecommitdiff
path: root/src/geom/sides.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-07-02 19:59:52 +0200
committerLaurenz <laurmaedje@gmail.com>2023-07-02 20:07:43 +0200
commitebfdb1dafa430786db10dad2ef7d5467c1bdbed1 (patch)
tree2bbc24ddb4124c4bb14dec0e536129d4de37b056 /src/geom/sides.rs
parent3ab19185093d7709f824b95b979060ce125389d8 (diff)
Move everything into `crates/` directory
Diffstat (limited to 'src/geom/sides.rs')
-rw-r--r--src/geom/sides.rs268
1 files changed, 0 insertions, 268 deletions
diff --git a/src/geom/sides.rs b/src/geom/sides.rs
deleted file mode 100644
index d4b72a9d..00000000
--- a/src/geom/sides.rs
+++ /dev/null
@@ -1,268 +0,0 @@
-use crate::eval::{CastInfo, FromValue, IntoValue, Reflect};
-
-use super::*;
-
-/// A container with left, top, right and bottom components.
-#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, Hash)]
-pub struct Sides<T> {
- /// The value for the left side.
- pub left: T,
- /// The value for the top side.
- pub top: T,
- /// The value for the right side.
- pub right: T,
- /// The value for the bottom side.
- pub bottom: T,
-}
-
-impl<T> Sides<T> {
- /// Create a new instance from the four components.
- pub const fn new(left: T, top: T, right: T, bottom: T) -> Self {
- Self { left, top, right, bottom }
- }
-
- /// Create an instance with four equal components.
- pub fn splat(value: T) -> Self
- where
- T: Clone,
- {
- Self {
- left: value.clone(),
- top: value.clone(),
- right: value.clone(),
- bottom: value,
- }
- }
-
- /// Map the individual fields with `f`.
- pub fn map<F, U>(self, mut f: F) -> Sides<U>
- where
- F: FnMut(T) -> U,
- {
- Sides {
- left: f(self.left),
- top: f(self.top),
- right: f(self.right),
- bottom: f(self.bottom),
- }
- }
-
- /// Zip two instances into one.
- pub fn zip<U>(self, other: Sides<U>) -> Sides<(T, U)> {
- Sides {
- left: (self.left, other.left),
- top: (self.top, other.top),
- right: (self.right, other.right),
- bottom: (self.bottom, other.bottom),
- }
- }
-
- /// An iterator over the sides, starting with the left side, clockwise.
- pub fn iter(&self) -> impl Iterator<Item = &T> {
- [&self.left, &self.top, &self.right, &self.bottom].into_iter()
- }
-
- /// Whether all sides are equal.
- pub fn is_uniform(&self) -> bool
- where
- T: PartialEq,
- {
- self.left == self.top && self.top == self.right && self.right == self.bottom
- }
-}
-
-impl<T: Add> Sides<T> {
- /// Sums up `left` and `right` into `x`, and `top` and `bottom` into `y`.
- pub fn sum_by_axis(self) -> Axes<T::Output> {
- Axes::new(self.left + self.right, self.top + self.bottom)
- }
-}
-
-impl Sides<Rel<Abs>> {
- /// Evaluate the sides relative to the given `size`.
- pub fn relative_to(self, size: Size) -> Sides<Abs> {
- Sides {
- left: self.left.relative_to(size.x),
- top: self.top.relative_to(size.y),
- right: self.right.relative_to(size.x),
- bottom: self.bottom.relative_to(size.y),
- }
- }
-}
-
-impl<T> Get<Side> for Sides<T> {
- type Component = T;
-
- fn get_ref(&self, side: Side) -> &T {
- match side {
- Side::Left => &self.left,
- Side::Top => &self.top,
- Side::Right => &self.right,
- Side::Bottom => &self.bottom,
- }
- }
-
- fn get_mut(&mut self, side: Side) -> &mut T {
- match side {
- Side::Left => &mut self.left,
- Side::Top => &mut self.top,
- Side::Right => &mut self.right,
- Side::Bottom => &mut self.bottom,
- }
- }
-}
-
-/// The four sides of objects.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-pub enum Side {
- /// The left side.
- Left,
- /// The top side.
- Top,
- /// The right side.
- Right,
- /// The bottom side.
- Bottom,
-}
-
-impl Side {
- /// The opposite side.
- pub fn inv(self) -> Self {
- match self {
- Self::Left => Self::Right,
- Self::Top => Self::Bottom,
- Self::Right => Self::Left,
- Self::Bottom => Self::Top,
- }
- }
-
- /// The next side, clockwise.
- pub fn next_cw(self) -> Self {
- match self {
- Self::Left => Self::Top,
- Self::Top => Self::Right,
- Self::Right => Self::Bottom,
- Self::Bottom => Self::Left,
- }
- }
-
- /// The next side, counter-clockwise.
- pub fn next_ccw(self) -> Self {
- match self {
- Self::Left => Self::Bottom,
- Self::Top => Self::Left,
- Self::Right => Self::Top,
- Self::Bottom => Self::Right,
- }
- }
-
- /// The first corner of the side in clockwise order.
- pub fn start_corner(self) -> Corner {
- match self {
- Self::Left => Corner::BottomLeft,
- Self::Top => Corner::TopLeft,
- Self::Right => Corner::TopRight,
- Self::Bottom => Corner::BottomRight,
- }
- }
-
- /// The second corner of the side in clockwise order.
- pub fn end_corner(self) -> Corner {
- self.next_cw().start_corner()
- }
-
- /// Return the corresponding axis.
- pub fn axis(self) -> Axis {
- match self {
- Self::Left | Self::Right => Axis::Y,
- Self::Top | Self::Bottom => Axis::X,
- }
- }
-}
-
-impl<T: Reflect> Reflect for Sides<Option<T>> {
- fn describe() -> CastInfo {
- T::describe() + Dict::describe()
- }
-
- fn castable(value: &Value) -> bool {
- Dict::castable(value) || T::castable(value)
- }
-}
-
-impl<T> IntoValue for Sides<T>
-where
- T: PartialEq + IntoValue,
-{
- fn into_value(self) -> Value {
- if self.is_uniform() {
- return self.left.into_value();
- }
-
- let mut dict = Dict::new();
- let mut handle = |key: &str, component: T| {
- let value = component.into_value();
- if value != Value::None {
- dict.insert(key.into(), value);
- }
- };
-
- handle("left", self.left);
- handle("top", self.top);
- handle("right", self.right);
- handle("bottom", self.bottom);
-
- Value::Dict(dict)
- }
-}
-
-impl<T> FromValue for Sides<Option<T>>
-where
- T: Default + FromValue + Clone,
-{
- fn from_value(mut value: Value) -> StrResult<Self> {
- let keys = ["left", "top", "right", "bottom", "x", "y", "rest"];
- if let Value::Dict(dict) = &mut value {
- if dict.iter().any(|(key, _)| keys.contains(&key.as_str())) {
- let mut take = |key| dict.take(key).ok().map(T::from_value).transpose();
- let rest = take("rest")?;
- let x = take("x")?.or_else(|| rest.clone());
- let y = take("y")?.or_else(|| rest.clone());
- let sides = Sides {
- left: take("left")?.or_else(|| x.clone()),
- top: take("top")?.or_else(|| y.clone()),
- right: take("right")?.or_else(|| x.clone()),
- bottom: take("bottom")?.or_else(|| y.clone()),
- };
-
- dict.finish(&keys)?;
- return Ok(sides);
- }
- }
-
- if T::castable(&value) {
- Ok(Self::splat(Some(T::from_value(value)?)))
- } else {
- Err(Self::error(&value))
- }
- }
-}
-
-impl<T: Resolve> Resolve for Sides<T> {
- type Output = Sides<T::Output>;
-
- fn resolve(self, styles: StyleChain) -> Self::Output {
- self.map(|v| v.resolve(styles))
- }
-}
-
-impl<T: Fold> Fold for Sides<Option<T>> {
- type Output = Sides<T::Output>;
-
- fn fold(self, outer: Self::Output) -> Self::Output {
- self.zip(outer).map(|(inner, outer)| match inner {
- Some(value) => value.fold(outer),
- None => outer,
- })
- }
-}