Move Position and Location to gradient module

This commit is contained in:
Héctor Ramón Jiménez 2022-11-03 05:15:32 +01:00
parent 921c94162e
commit d8045e2dc3
No known key found for this signature in database
GPG key ID: 140CC052C94F138E
2 changed files with 92 additions and 90 deletions

View file

@ -1,8 +1,9 @@
//! For creating a Gradient. //! For creating a Gradient.
mod linear; pub mod linear;
pub use crate::gradient::linear::{Linear, Location, Position}; pub use linear::Linear;
use crate::Color;
use crate::{Color, Point, Size};
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
/// A fill which transitions colors progressively along a direction, either linearly, radially (TBD), /// A fill which transitions colors progressively along a direction, either linearly, radially (TBD),
@ -13,6 +14,13 @@ pub enum Gradient {
Linear(Linear), Linear(Linear),
} }
impl Gradient {
/// Creates a new linear [`linear::Builder`].
pub fn linear(position: impl Into<Position>) -> linear::Builder {
linear::Builder::new(position.into())
}
}
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
/// A point along the gradient vector where the specified [`color`] is unmixed. /// A point along the gradient vector where the specified [`color`] is unmixed.
pub struct ColorStop { pub struct ColorStop {
@ -22,9 +30,83 @@ pub struct ColorStop {
pub color: Color, pub color: Color,
} }
impl Gradient { #[derive(Debug)]
/// Creates a new linear [`linear::Builder`]. /// The position of the gradient within its bounds.
pub fn linear(position: impl Into<Position>) -> linear::Builder { pub enum Position {
linear::Builder::new(position.into()) /// The gradient will be positioned with respect to two points.
Absolute {
/// The starting point of the gradient.
start: Point,
/// The ending point of the gradient.
end: Point,
},
/// The gradient will be positioned relative to the provided bounds.
Relative {
/// The top left position of the bounds.
top_left: Point,
/// The width & height of the bounds.
size: Size,
/// The start [Location] of the gradient.
start: Location,
/// The end [Location] of the gradient.
end: Location,
},
}
impl From<(Point, Point)> for Position {
fn from((start, end): (Point, Point)) -> Self {
Self::Absolute { start, end }
}
}
#[derive(Debug)]
/// The location of a relatively-positioned gradient.
pub enum Location {
/// Top left.
TopLeft,
/// Top.
Top,
/// Top right.
TopRight,
/// Right.
Right,
/// Bottom right.
BottomRight,
/// Bottom.
Bottom,
/// Bottom left.
BottomLeft,
/// Left.
Left,
}
impl Location {
fn to_absolute(&self, top_left: Point, size: Size) -> Point {
match self {
Location::TopLeft => top_left,
Location::Top => {
Point::new(top_left.x + size.width / 2.0, top_left.y)
}
Location::TopRight => {
Point::new(top_left.x + size.width, top_left.y)
}
Location::Right => Point::new(
top_left.x + size.width,
top_left.y + size.height / 2.0,
),
Location::BottomRight => {
Point::new(top_left.x + size.width, top_left.y + size.height)
}
Location::Bottom => Point::new(
top_left.x + size.width / 2.0,
top_left.y + size.height,
),
Location::BottomLeft => {
Point::new(top_left.x, top_left.y + size.height)
}
Location::Left => {
Point::new(top_left.x, top_left.y + size.height / 2.0)
}
}
} }
} }

View file

@ -1,6 +1,6 @@
//! Linear gradient builder & definition. //! Linear gradient builder & definition.
use crate::gradient::{ColorStop, Gradient}; use crate::gradient::{ColorStop, Gradient, Position};
use crate::{Color, Point, Size}; use crate::{Color, Point};
/// A linear gradient that can be used in the style of [`super::Fill`] or [`super::Stroke`]. /// A linear gradient that can be used in the style of [`super::Fill`] or [`super::Stroke`].
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
@ -13,87 +13,6 @@ pub struct Linear {
pub color_stops: Vec<ColorStop>, pub color_stops: Vec<ColorStop>,
} }
#[derive(Debug)]
/// The position of the gradient within its bounds.
pub enum Position {
/// The gradient will be positioned with respect to two points.
Absolute {
/// The starting point of the gradient.
start: Point,
/// The ending point of the gradient.
end: Point,
},
/// The gradient will be positioned relative to the provided bounds.
Relative {
/// The top left position of the bounds.
top_left: Point,
/// The width & height of the bounds.
size: Size,
/// The start [Location] of the gradient.
start: Location,
/// The end [Location] of the gradient.
end: Location,
},
}
impl From<(Point, Point)> for Position {
fn from((start, end): (Point, Point)) -> Self {
Self::Absolute { start, end }
}
}
#[derive(Debug)]
/// The location of a relatively-positioned gradient.
pub enum Location {
/// Top left.
TopLeft,
/// Top.
Top,
/// Top right.
TopRight,
/// Right.
Right,
/// Bottom right.
BottomRight,
/// Bottom.
Bottom,
/// Bottom left.
BottomLeft,
/// Left.
Left,
}
impl Location {
fn to_absolute(&self, top_left: Point, size: Size) -> Point {
match self {
Location::TopLeft => top_left,
Location::Top => {
Point::new(top_left.x + size.width / 2.0, top_left.y)
}
Location::TopRight => {
Point::new(top_left.x + size.width, top_left.y)
}
Location::Right => Point::new(
top_left.x + size.width,
top_left.y + size.height / 2.0,
),
Location::BottomRight => {
Point::new(top_left.x + size.width, top_left.y + size.height)
}
Location::Bottom => Point::new(
top_left.x + size.width / 2.0,
top_left.y + size.height,
),
Location::BottomLeft => {
Point::new(top_left.x, top_left.y + size.height)
}
Location::Left => {
Point::new(top_left.x, top_left.y + size.height / 2.0)
}
}
}
}
/// A [`Linear`] builder. /// A [`Linear`] builder.
#[derive(Debug)] #[derive(Debug)]
pub struct Builder { pub struct Builder {
@ -175,6 +94,7 @@ impl Builder {
} }
} }
/// An error that happened when building a [`Linear`] gradient.
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
pub enum BuilderError { pub enum BuilderError {
#[error("Gradients must contain at least one color stop.")] #[error("Gradients must contain at least one color stop.")]