sketchbook 0.0.2

Interactive visual applications in Rust
Documentation
use super::{Context, FromWithContext};
use crate::{Point2, Real, ToReal};

/// A circle to draw.
///
/// ```
/// # use sketchbook::aspects::draw::Circle;
/// # use sketchbook::Point2;
/// #
/// // Example of creating a circle.
/// let circle = Circle {
///     center: Point2 { x: 1.0, y: 4.0 },
///     diameter: 10.0,
///     fill: (255, 0, 0),
///     stroke: (0, 255, 0),
///     weight: 23.0,
/// };
/// ```
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct Circle<Num, Color> {
    /// Position of circle's center.
    pub center: Point2<Num>,

    /// Circle's diameter.
    pub diameter: Num,

    /// Color to fill circle with.
    pub fill: Color,

    /// Color to use for the border.
    pub stroke: Color,

    /// Width of the border.
    pub weight: Num,
}

/// Convert from `(x, y, width)` to a circle with the given context.
///
/// The interpretation of `x`, `y`, and `width` are dependant on the context's `ellipse_mode`.
///
/// ```
/// # use sketchbook::aspects::draw::*;
/// # use sketchbook::Point2;
/// #
/// // Create context to create circle in releation to.
/// let context = Context {
///     ellipse_mode: Mode::Radius,
///     fill: (255, 0, 0),
///     stroke: (0, 0, 255),
///     weight: 4.0,
///     ..Context::default()
/// };
///
/// // Create circle.
/// let circle: Circle<f32, (u8, u8, u8)>
///     = (1.0, 2.0, 3.0).into_with_context(&context);
///
/// // Created circle matches what is expected given the context.
/// assert_eq!(
///     circle,
///     Circle {
///         center: Point2 { x: 1.0, y: 2.0 },
///         diameter: 6.0,
///         fill: (255, 0, 0),
///         stroke: (0, 0, 255),
///         weight: 4.0,
///     }
/// );
/// ```
impl<X, Y, Width, Num, Color> FromWithContext<(X, Y, Width), Num, Color> for Circle<Num, Color>
where
    X: ToReal<Num>,
    Y: ToReal<Num>,
    Width: ToReal<Num>,
    Num: Real,
    Color: Clone,
{
    fn from_with_context(data: (X, Y, Width), context: &Context<Num, Color>) -> Self {
        // convert to Num
        let (x, y, diameter) = data;
        let (x, y, diameter) = (x.to_real(), y.to_real(), diameter.to_real());

        // get center and size as interpreted by the context
        let (center, size) = context.ellipse_mode.interpret(x, y, diameter, diameter);

        Circle {
            center,
            diameter: size.width, // the height is the same as the width
            fill: context.fill.clone(),
            stroke: context.stroke.clone(),
            weight: context.weight,
        }
    }
}