sketchbook 0.0.2

Interactive visual applications in Rust
Documentation
use crate::geometry::*;
use crate::real::Real;

/// Mode for interpeting the position and size of a shape.
///
/// ```
/// # use sketchbook::aspects::draw::Mode;
/// #
/// // Example of creating mode.
/// let mode = Mode::Corners;
/// ```
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum Mode {
    /// Read as `(x_left, y_top, width, height)`.
    ///
    /// Interprets as left, top coordinate and width, height.
    Corner,

    /// Read as `(x_left, y_top, x_right, y_bottom)`.
    ///
    /// Interprets as left, top coordinate and right, bottom coordinate.
    Corners,

    /// Read as (x_center, y_center, width, height)
    ///
    /// Interprets as center coordinate and width, height.
    Center,

    /// Read as (x_center, y_center, width / 2, height / 2)
    ///
    /// Interprets as center coordinate and half of width, height.
    Radius,
}

impl Mode {
    /// Interpret the `x`, `y`, `width`, `height` based on the mode.
    ///
    /// See the variant docs for details about how each mode interprets the values.
    ///
    /// ```
    /// # use sketchbook::aspects::draw::Mode;
    /// let (center, size) = Mode::Radius.interpret(1.0, 2.0, 3.0, 4.0);
    ///
    /// assert_eq!(center.x, 1.0);
    /// assert_eq!(center.y, 2.0);
    /// assert_eq!(size.width, 6.0);
    /// assert_eq!(size.height, 8.0);
    /// ```
    pub fn interpret<Num>(
        &self,
        x: Num,
        y: Num,
        width: Num,
        height: Num,
    ) -> (Point2<Num>, Size2<Num>)
    where
        Num: Real,
    {
        use Mode::*;
        match self {
            Corner => (
                Point2 {
                    x: x + width.div2(),
                    y: y + height.div2(),
                },
                Size2 { width, height },
            ),

            Corners => (
                Point2 {
                    x: x + (width - x).div2(),
                    y: y + (height - y).div2(),
                },
                Size2 {
                    width: width - x,
                    height: height - y,
                },
            ),

            Center => (Point2 { x, y }, Size2 { width, height }),

            Radius => (
                Point2 { x, y },
                Size2 {
                    width: width.mul2(),
                    height: height.mul2(),
                },
            ),
        }
    }
}