Tweak whitespace around `use` statements and other lint fixes

This commit is contained in:
Keavon Chambers 2022-01-15 12:55:51 -08:00
parent 314503a6e1
commit 56599db753
23 changed files with 61 additions and 21 deletions

View File

@ -42,9 +42,10 @@ impl Dispatcher {
#[remain::check] #[remain::check]
pub fn handle_message<T: Into<Message>>(&mut self, message: T) { pub fn handle_message<T: Into<Message>>(&mut self, message: T) {
use Message::*;
self.message_queue.push_back(message.into()); self.message_queue.push_back(message.into());
use Message::*;
while let Some(message) = self.message_queue.pop_front() { while let Some(message) = self.message_queue.pop_front() {
// Skip processing of this message if it will be processed later // Skip processing of this message if it will be processed later
if SIDE_EFFECT_FREE_MESSAGES.contains(&message.to_discriminant()) && self.message_queue.contains(&message) { if SIDE_EFFECT_FREE_MESSAGES.contains(&message.to_discriminant()) && self.message_queue.contains(&message) {
@ -106,6 +107,7 @@ impl Dispatcher {
fn log_message(&self, message: &Message) { fn log_message(&self, message: &Message) {
use Message::*; use Message::*;
if log::max_level() == log::LevelFilter::Trace if log::max_level() == log::LevelFilter::Trace
&& !(matches!( && !(matches!(
message, message,
@ -126,6 +128,7 @@ mod test {
use crate::message_prelude::*; use crate::message_prelude::*;
use crate::misc::test_utils::EditorTestUtils; use crate::misc::test_utils::EditorTestUtils;
use crate::Editor; use crate::Editor;
use graphene::color::Color; use graphene::color::Color;
use graphene::Operation; use graphene::Operation;

View File

@ -26,8 +26,9 @@ impl ArtboardMessageHandler {
impl MessageHandler<ArtboardMessage, (&mut LayerMetadata, &GrapheneDocument, &InputPreprocessorMessageHandler)> for ArtboardMessageHandler { impl MessageHandler<ArtboardMessage, (&mut LayerMetadata, &GrapheneDocument, &InputPreprocessorMessageHandler)> for ArtboardMessageHandler {
#[remain::check] #[remain::check]
fn process_action(&mut self, message: ArtboardMessage, _data: (&mut LayerMetadata, &GrapheneDocument, &InputPreprocessorMessageHandler), responses: &mut VecDeque<Message>) { fn process_action(&mut self, message: ArtboardMessage, _data: (&mut LayerMetadata, &GrapheneDocument, &InputPreprocessorMessageHandler), responses: &mut VecDeque<Message>) {
// let (layer_metadata, document, ipp) = data;
use ArtboardMessage::*; use ArtboardMessage::*;
// let (layer_metadata, document, ipp) = data;
#[remain::sorted] #[remain::sorted]
match message { match message {
AddArtboard { top, left, height, width } => { AddArtboard { top, left, height, width } => {

View File

@ -78,10 +78,10 @@ impl DocumentMessageHandler {
let deserialized_result: Result<Self, DocumentError> = serde_json::from_str(serialized_content).map_err(|e| DocumentError::InvalidFile(e.to_string())); let deserialized_result: Result<Self, DocumentError> = serde_json::from_str(serialized_content).map_err(|e| DocumentError::InvalidFile(e.to_string()));
match deserialized_result { match deserialized_result {
Ok(document) => { Ok(document) => {
if document.version != GRAPHITE_DOCUMENT_VERSION { if document.version == GRAPHITE_DOCUMENT_VERSION {
Err(DocumentError::InvalidFile("Graphite document version mismatch".to_string()))
} else {
Ok(document) Ok(document)
} else {
Err(DocumentError::InvalidFile("Graphite document version mismatch".to_string()))
} }
} }
Err(e) => Err(e), Err(e) => Err(e),
@ -440,6 +440,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessorMessageHandler> for Docum
#[remain::check] #[remain::check]
fn process_action(&mut self, message: DocumentMessage, ipp: &InputPreprocessorMessageHandler, responses: &mut VecDeque<Message>) { fn process_action(&mut self, message: DocumentMessage, ipp: &InputPreprocessorMessageHandler, responses: &mut VecDeque<Message>) {
use DocumentMessage::*; use DocumentMessage::*;
#[remain::sorted] #[remain::sorted]
match message { match message {
AbortTransaction => { AbortTransaction => {
@ -585,7 +586,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessorMessageHandler> for Docum
} }
ExportDocument => { ExportDocument => {
// TODO(MFISH33): Add Dialog to select artboards // TODO(MFISH33): Add Dialog to select artboards
let bbox = self.document_bounds().unwrap_or([DVec2::ZERO, ipp.viewport_bounds.size()]); let bbox = self.document_bounds().unwrap_or_else(|| [DVec2::ZERO, ipp.viewport_bounds.size()]);
let size = bbox[1] - bbox[0]; let size = bbox[1] - bbox[0];
let name = match self.name.ends_with(FILE_SAVE_SUFFIX) { let name = match self.name.ends_with(FILE_SAVE_SUFFIX) {
true => self.name.clone().replace(FILE_SAVE_SUFFIX, FILE_EXPORT_SUFFIX), true => self.name.clone().replace(FILE_SAVE_SUFFIX, FILE_EXPORT_SUFFIX),

View File

@ -114,6 +114,7 @@ impl fmt::Display for LayerDataTypeDiscriminant {
impl From<&LayerDataType> for LayerDataTypeDiscriminant { impl From<&LayerDataType> for LayerDataTypeDiscriminant {
fn from(data: &LayerDataType) -> Self { fn from(data: &LayerDataType) -> Self {
use LayerDataType::*; use LayerDataType::*;
match data { match data {
Folder(_) => LayerDataTypeDiscriminant::Folder, Folder(_) => LayerDataTypeDiscriminant::Folder,
Shape(_) => LayerDataTypeDiscriminant::Shape, Shape(_) => LayerDataTypeDiscriminant::Shape,

View File

@ -113,8 +113,10 @@ impl MovementMessageHandler {
impl MessageHandler<MovementMessage, (&Document, &InputPreprocessorMessageHandler)> for MovementMessageHandler { impl MessageHandler<MovementMessage, (&Document, &InputPreprocessorMessageHandler)> for MovementMessageHandler {
#[remain::check] #[remain::check]
fn process_action(&mut self, message: MovementMessage, data: (&Document, &InputPreprocessorMessageHandler), responses: &mut VecDeque<Message>) { fn process_action(&mut self, message: MovementMessage, data: (&Document, &InputPreprocessorMessageHandler), responses: &mut VecDeque<Message>) {
let (document, ipp) = data;
use MovementMessage::*; use MovementMessage::*;
let (document, ipp) = data;
#[remain::sorted] #[remain::sorted]
match message { match message {
DecreaseCanvasZoom { center_on_mouse } => { DecreaseCanvasZoom { center_on_mouse } => {

View File

@ -14,8 +14,9 @@ pub struct OverlaysMessageHandler {
impl MessageHandler<OverlaysMessage, (&mut LayerMetadata, &Document, &InputPreprocessorMessageHandler)> for OverlaysMessageHandler { impl MessageHandler<OverlaysMessage, (&mut LayerMetadata, &Document, &InputPreprocessorMessageHandler)> for OverlaysMessageHandler {
#[remain::check] #[remain::check]
fn process_action(&mut self, message: OverlaysMessage, _data: (&mut LayerMetadata, &Document, &InputPreprocessorMessageHandler), responses: &mut VecDeque<Message>) { fn process_action(&mut self, message: OverlaysMessage, _data: (&mut LayerMetadata, &Document, &InputPreprocessorMessageHandler), responses: &mut VecDeque<Message>) {
// let (layer_metadata, document, ipp) = data;
use OverlaysMessage::*; use OverlaysMessage::*;
// let (layer_metadata, document, ipp) = data;
#[remain::sorted] #[remain::sorted]
match message { match message {
ClearAllOverlays => todo!(), ClearAllOverlays => todo!(),

View File

@ -127,6 +127,7 @@ impl MessageHandler<PortfolioMessage, &InputPreprocessorMessageHandler> for Port
fn process_action(&mut self, message: PortfolioMessage, ipp: &InputPreprocessorMessageHandler, responses: &mut VecDeque<Message>) { fn process_action(&mut self, message: PortfolioMessage, ipp: &InputPreprocessorMessageHandler, responses: &mut VecDeque<Message>) {
use DocumentMessage::*; use DocumentMessage::*;
use PortfolioMessage::*; use PortfolioMessage::*;
#[remain::sorted] #[remain::sorted]
match message { match message {
AutoSaveActiveDocument => responses.push_back(PortfolioMessage::AutoSaveDocument { document_id: self.active_document_id }.into()), AutoSaveActiveDocument => responses.push_back(PortfolioMessage::AutoSaveDocument { document_id: self.active_document_id }.into()),

View File

@ -39,7 +39,7 @@ impl MessageHandler<TransformLayerMessage, (&mut HashMap<Vec<LayerId>, LayerMeta
let mut selected = Selected::new(&mut self.original_transforms, &mut self.pivot, layer_metadata, responses, document); let mut selected = Selected::new(&mut self.original_transforms, &mut self.pivot, layer_metadata, responses, document);
let mut begin_operation = |operation: TransformOperation, typing: &mut Typing, mouse_position: &mut DVec2, start_mouse: &mut DVec2| { let mut begin_operation = |operation: TransformOperation, typing: &mut Typing, mouse_position: &mut DVec2, start_mouse: &mut DVec2| {
if !(operation == TransformOperation::None) { if operation != TransformOperation::None {
selected.revert_operation(); selected.revert_operation();
typing.clear(); typing.clear();
} else { } else {

View File

@ -9,6 +9,7 @@ impl MessageHandler<GlobalMessage, ()> for GlobalMessageHandler {
#[remain::check] #[remain::check]
fn process_action(&mut self, message: GlobalMessage, _data: (), _responses: &mut VecDeque<Message>) { fn process_action(&mut self, message: GlobalMessage, _data: (), _responses: &mut VecDeque<Message>) {
use GlobalMessage::*; use GlobalMessage::*;
#[remain::sorted] #[remain::sorted]
match message { match message {
LogDebug => { LogDebug => {

View File

@ -234,6 +234,7 @@ impl Default for Mapping {
impl Mapping { impl Mapping {
pub fn match_message(&self, message: InputMapperMessage, keys: &KeyStates, actions: ActionList) -> Option<Message> { pub fn match_message(&self, message: InputMapperMessage, keys: &KeyStates, actions: ActionList) -> Option<Message> {
use InputMapperMessage::*; use InputMapperMessage::*;
let list = match message { let list = match message {
KeyDown(key) => &self.key_down[key as usize], KeyDown(key) => &self.key_down[key as usize],
KeyUp(key) => &self.key_up[key as usize], KeyUp(key) => &self.key_up[key as usize],

View File

@ -45,6 +45,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Ellipse {
fn actions(&self) -> ActionList { fn actions(&self) -> ActionList {
use EllipseToolFsmState::*; use EllipseToolFsmState::*;
match self.fsm_state { match self.fsm_state {
Ready => actions!(EllipseMessageDiscriminant; DragStart), Ready => actions!(EllipseMessageDiscriminant; DragStart),
Drawing => actions!(EllipseMessageDiscriminant; DragStop, Abort, Resize), Drawing => actions!(EllipseMessageDiscriminant; DragStop, Abort, Resize),
@ -81,9 +82,11 @@ impl Fsm for EllipseToolFsmState {
input: &InputPreprocessorMessageHandler, input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>, responses: &mut VecDeque<Message>,
) -> Self { ) -> Self {
let mut shape_data = &mut data.data;
use EllipseMessage::*; use EllipseMessage::*;
use EllipseToolFsmState::*; use EllipseToolFsmState::*;
let mut shape_data = &mut data.data;
if let ToolMessage::Ellipse(event) = event { if let ToolMessage::Ellipse(event) = event {
match (self, event) { match (self, event) {
(Ready, DragStart) => { (Ready, DragStart) => {

View File

@ -73,6 +73,7 @@ impl Fsm for EyedropperToolFsmState {
) -> Self { ) -> Self {
use EyedropperMessage::*; use EyedropperMessage::*;
use EyedropperToolFsmState::*; use EyedropperToolFsmState::*;
if let ToolMessage::Eyedropper(event) = event { if let ToolMessage::Eyedropper(event) = event {
match (self, event) { match (self, event) {
(Ready, lmb_or_rmb) if lmb_or_rmb == LeftMouseDown || lmb_or_rmb == RightMouseDown => { (Ready, lmb_or_rmb) if lmb_or_rmb == LeftMouseDown || lmb_or_rmb == RightMouseDown => {

View File

@ -73,6 +73,7 @@ impl Fsm for FillToolFsmState {
) -> Self { ) -> Self {
use FillMessage::*; use FillMessage::*;
use FillToolFsmState::*; use FillToolFsmState::*;
if let ToolMessage::Fill(event) = event { if let ToolMessage::Fill(event) = event {
match (self, event) { match (self, event) {
(Ready, lmb_or_rmb) if lmb_or_rmb == LeftMouseDown || lmb_or_rmb == RightMouseDown => { (Ready, lmb_or_rmb) if lmb_or_rmb == LeftMouseDown || lmb_or_rmb == RightMouseDown => {

View File

@ -44,6 +44,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Navigate {
fn actions(&self) -> ActionList { fn actions(&self) -> ActionList {
use NavigateToolFsmState::*; use NavigateToolFsmState::*;
match self.fsm_state { match self.fsm_state {
Ready => actions!(NavigateMessageDiscriminant; TranslateCanvasBegin, RotateCanvasBegin, ZoomCanvasBegin), Ready => actions!(NavigateMessageDiscriminant; TranslateCanvasBegin, RotateCanvasBegin, ZoomCanvasBegin),
_ => actions!(NavigateMessageDiscriminant; ClickZoom, MouseMove, TransformCanvasEnd), _ => actions!(NavigateMessageDiscriminant; ClickZoom, MouseMove, TransformCanvasEnd),

View File

@ -52,6 +52,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Path {
// Different actions depending on state may be wanted: // Different actions depending on state may be wanted:
fn actions(&self) -> ActionList { fn actions(&self) -> ActionList {
use PathToolFsmState::*; use PathToolFsmState::*;
match self.fsm_state { match self.fsm_state {
Ready => actions!(PathMessageDiscriminant; DragStart), Ready => actions!(PathMessageDiscriminant; DragStart),
Dragging => actions!(PathMessageDiscriminant; DragStop, PointerMove), Dragging => actions!(PathMessageDiscriminant; DragStop, PointerMove),

View File

@ -54,6 +54,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Pen {
fn actions(&self) -> ActionList { fn actions(&self) -> ActionList {
use PenToolFsmState::*; use PenToolFsmState::*;
match self.fsm_state { match self.fsm_state {
Ready => actions!(PenMessageDiscriminant; Undo, DragStart, DragStop, Confirm, Abort), Ready => actions!(PenMessageDiscriminant; Undo, DragStart, DragStop, Confirm, Abort),
Drawing => actions!(PenMessageDiscriminant; DragStop, PointerMove, Confirm, Abort), Drawing => actions!(PenMessageDiscriminant; DragStop, PointerMove, Confirm, Abort),
@ -88,10 +89,11 @@ impl Fsm for PenToolFsmState {
input: &InputPreprocessorMessageHandler, input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>, responses: &mut VecDeque<Message>,
) -> Self { ) -> Self {
let transform = document.graphene_document.root.transform;
use PenMessage::*; use PenMessage::*;
use PenToolFsmState::*; use PenToolFsmState::*;
let transform = document.graphene_document.root.transform;
if let ToolMessage::Pen(event) = event { if let ToolMessage::Pen(event) = event {
match (self, event) { match (self, event) {
(Ready, DragStart) => { (Ready, DragStart) => {

View File

@ -45,6 +45,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Rectangle {
fn actions(&self) -> ActionList { fn actions(&self) -> ActionList {
use RectangleToolFsmState::*; use RectangleToolFsmState::*;
match self.fsm_state { match self.fsm_state {
Ready => actions!(RectangleMessageDiscriminant; DragStart), Ready => actions!(RectangleMessageDiscriminant; DragStart),
Drawing => actions!(RectangleMessageDiscriminant; DragStop, Abort, Resize), Drawing => actions!(RectangleMessageDiscriminant; DragStop, Abort, Resize),
@ -80,9 +81,11 @@ impl Fsm for RectangleToolFsmState {
input: &InputPreprocessorMessageHandler, input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>, responses: &mut VecDeque<Message>,
) -> Self { ) -> Self {
let mut shape_data = &mut data.data;
use RectangleMessage::*; use RectangleMessage::*;
use RectangleToolFsmState::*; use RectangleToolFsmState::*;
let mut shape_data = &mut data.data;
if let ToolMessage::Rectangle(event) = event { if let ToolMessage::Rectangle(event) = event {
match (self, event) { match (self, event) {
(Ready, DragStart) => { (Ready, DragStart) => {

View File

@ -56,6 +56,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Select {
fn actions(&self) -> ActionList { fn actions(&self) -> ActionList {
use SelectToolFsmState::*; use SelectToolFsmState::*;
match self.fsm_state { match self.fsm_state {
Ready => actions!(SelectMessageDiscriminant; DragStart), Ready => actions!(SelectMessageDiscriminant; DragStart),
Dragging => actions!(SelectMessageDiscriminant; DragStop, MouseMove), Dragging => actions!(SelectMessageDiscriminant; DragStop, MouseMove),
@ -229,7 +230,7 @@ impl Fsm for SelectToolFsmState {
data.drag_current = mouse_position + closest_move; data.drag_current = mouse_position + closest_move;
Dragging Dragging
} }
(DrawingBox, MouseMove { snap_angle: _ }) => { (DrawingBox, MouseMove { .. }) => {
data.drag_current = input.mouse.position; data.drag_current = input.mouse.position;
let half_pixel_offset = DVec2::splat(0.5); let half_pixel_offset = DVec2::splat(0.5);
let start = data.drag_start + half_pixel_offset; let start = data.drag_start + half_pixel_offset;

View File

@ -46,6 +46,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Shape {
fn actions(&self) -> ActionList { fn actions(&self) -> ActionList {
use ShapeToolFsmState::*; use ShapeToolFsmState::*;
match self.fsm_state { match self.fsm_state {
Ready => actions!(ShapeMessageDiscriminant; DragStart), Ready => actions!(ShapeMessageDiscriminant; DragStart),
Drawing => actions!(ShapeMessageDiscriminant; DragStop, Abort, Resize), Drawing => actions!(ShapeMessageDiscriminant; DragStop, Abort, Resize),
@ -82,9 +83,11 @@ impl Fsm for ShapeToolFsmState {
input: &InputPreprocessorMessageHandler, input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>, responses: &mut VecDeque<Message>,
) -> Self { ) -> Self {
let mut shape_data = &mut data.data;
use ShapeMessage::*; use ShapeMessage::*;
use ShapeToolFsmState::*; use ShapeToolFsmState::*;
let mut shape_data = &mut data.data;
if let ToolMessage::Shape(event) = event { if let ToolMessage::Shape(event) = event {
match (self, event) { match (self, event) {
(Ready, DragStart) => { (Ready, DragStart) => {

View File

@ -60,8 +60,10 @@ pub fn translate_blend_mode(blend_mode_svg_style_name: &str) -> Option<BlendMode
} }
pub fn translate_key(name: &str) -> Key { pub fn translate_key(name: &str) -> Key {
log::trace!("Key event received: {}", name);
use Key::*; use Key::*;
log::trace!("Key event received: {}", name);
match name.to_lowercase().as_str() { match name.to_lowercase().as_str() {
"a" => KeyA, "a" => KeyA,
"b" => KeyB, "b" => KeyB,

View File

@ -382,9 +382,10 @@ impl Document {
/// Mutate the document by applying the `operation` to it. If the operation necessitates a /// Mutate the document by applying the `operation` to it. If the operation necessitates a
/// reaction from the frontend, responses may be returned. /// reaction from the frontend, responses may be returned.
pub fn handle_operation(&mut self, operation: &Operation) -> Result<Option<Vec<DocumentResponse>>, DocumentError> { pub fn handle_operation(&mut self, operation: &Operation) -> Result<Option<Vec<DocumentResponse>>, DocumentError> {
operation.pseudo_hash().hash(&mut self.state_identifier);
use DocumentResponse::*; use DocumentResponse::*;
operation.pseudo_hash().hash(&mut self.state_identifier);
let responses = match &operation { let responses = match &operation {
Operation::AddEllipse { path, insert_index, transform, style } => { Operation::AddEllipse { path, insert_index, transform, style } => {
let layer = Layer::new(LayerDataType::Shape(Shape::ellipse(*style)), *transform); let layer = Layer::new(LayerDataType::Shape(Shape::ellipse(*style)), *transform);

View File

@ -112,7 +112,7 @@ impl Layer {
self.cache.clear(); self.cache.clear();
let _ = writeln!(self.cache, r#"<g transform="matrix("#); let _ = writeln!(self.cache, r#"<g transform="matrix("#);
self.transform.to_cols_array().iter().enumerate().for_each(|(i, f)| { self.transform.to_cols_array().iter().enumerate().for_each(|(i, f)| {
let _ = self.cache.write_str(&(f.to_string() + if i != 5 { "," } else { "" })); let _ = self.cache.write_str(&(f.to_string() + if i == 5 { "" } else { "," }));
}); });
let _ = write!( let _ = write!(
self.cache, self.cache,

View File

@ -33,7 +33,7 @@ impl LayerData for Shape {
let _ = writeln!(svg, r#"<g transform="matrix("#); let _ = writeln!(svg, r#"<g transform="matrix("#);
inverse.to_cols_array().iter().enumerate().for_each(|(i, entry)| { inverse.to_cols_array().iter().enumerate().for_each(|(i, entry)| {
let _ = svg.write_str(&(entry.to_string() + if i != 5 { "," } else { "" })); let _ = svg.write_str(&(entry.to_string() + if i == 5 { "" } else { "," }));
}); });
let _ = svg.write_str(r#")">"#); let _ = svg.write_str(r#")">"#);
let _ = write!(svg, r#"<path d="{}" {} />"#, path.to_svg(), self.style.render(view_mode)); let _ = write!(svg, r#"<path d="{}" {} />"#, path.to_svg(), self.style.render(view_mode));
@ -41,13 +41,14 @@ impl LayerData for Shape {
} }
fn bounding_box(&self, transform: glam::DAffine2) -> Option<[DVec2; 2]> { fn bounding_box(&self, transform: glam::DAffine2) -> Option<[DVec2; 2]> {
use kurbo::Shape;
let mut path = self.path.clone(); let mut path = self.path.clone();
if transform.matrix2 == DMat2::ZERO { if transform.matrix2 == DMat2::ZERO {
return None; return None;
} }
path.apply_affine(glam_to_kurbo(transform)); path.apply_affine(glam_to_kurbo(transform));
use kurbo::Shape;
let kurbo::Rect { x0, y0, x1, y1 } = path.bounding_box(); let kurbo::Rect { x0, y0, x1, y1 } = path.bounding_box();
Some([(x0, y0).into(), (x1, y1).into()]) Some([(x0, y0).into(), (x1, y1).into()])
} }
@ -80,19 +81,23 @@ impl Shape {
pub fn ngon(sides: u8, style: PathStyle) -> Self { pub fn ngon(sides: u8, style: PathStyle) -> Self {
use std::f64::consts::{FRAC_PI_2, TAU}; use std::f64::consts::{FRAC_PI_2, TAU};
fn unit_rotation(theta: f64) -> DVec2 { fn unit_rotation(theta: f64) -> DVec2 {
DVec2::new(theta.sin(), theta.cos()) DVec2::new(theta.sin(), theta.cos())
} }
let mut path = kurbo::BezPath::new(); let mut path = kurbo::BezPath::new();
let apothem_offset_angle = TAU / (sides as f64); let apothem_offset_angle = TAU / (sides as f64);
// Rotate odd sided shapes by 90 degrees // Rotate odd sided shapes by 90 degrees
let offset = ((sides + 1) % 2) as f64 * FRAC_PI_2; let offset = ((sides + 1) % 2) as f64 * FRAC_PI_2;
let relative_points = (0..sides).map(|i| apothem_offset_angle * i as f64 + offset).map(unit_rotation); let relative_points = (0..sides).map(|i| apothem_offset_angle * i as f64 + offset).map(unit_rotation);
let min = relative_points.clone().reduce(|a, b| a.min(b)).unwrap_or_default();
let min = relative_points.clone().reduce(|a, b| a.min(b)).unwrap_or_default();
let transform = DAffine2::from_scale_angle_translation(DVec2::ONE / 2., 0., -min / 2.); let transform = DAffine2::from_scale_angle_translation(DVec2::ONE / 2., 0., -min / 2.);
let point = |vec: DVec2| kurbo::Point::new(vec.x, vec.y); let point = |vec: DVec2| kurbo::Point::new(vec.x, vec.y);
let mut relative_points = relative_points.map(|p| point(transform.transform_point2(p))); let mut relative_points = relative_points.map(|p| point(transform.transform_point2(p)));
path.move_to(relative_points.next().expect("Tried to create an ngon with 0 sides")); path.move_to(relative_points.next().expect("Tried to create an ngon with 0 sides"));
relative_points.for_each(|p| path.line_to(p)); relative_points.for_each(|p| path.line_to(p));
@ -106,6 +111,7 @@ impl Shape {
closed: true, closed: true,
} }
} }
pub fn rectangle(style: PathStyle) -> Self { pub fn rectangle(style: PathStyle) -> Self {
Self { Self {
path: kurbo::Rect::new(0., 0., 1., 1.).to_path(0.01), path: kurbo::Rect::new(0., 0., 1., 1.).to_path(0.01),
@ -114,6 +120,7 @@ impl Shape {
closed: true, closed: true,
} }
} }
pub fn ellipse(style: PathStyle) -> Self { pub fn ellipse(style: PathStyle) -> Self {
Self { Self {
path: kurbo::Ellipse::from_rect(kurbo::Rect::new(0., 0., 1., 1.)).to_path(0.01), path: kurbo::Ellipse::from_rect(kurbo::Rect::new(0., 0., 1., 1.)).to_path(0.01),
@ -122,6 +129,7 @@ impl Shape {
closed: true, closed: true,
} }
} }
pub fn line(style: PathStyle) -> Self { pub fn line(style: PathStyle) -> Self {
Self { Self {
path: kurbo::Line::new((0., 0.), (1., 0.)).to_path(0.01), path: kurbo::Line::new((0., 0.), (1., 0.)).to_path(0.01),
@ -130,6 +138,7 @@ impl Shape {
closed: false, closed: false,
} }
} }
pub fn poly_line(points: Vec<impl Into<glam::DVec2>>, style: PathStyle) -> Self { pub fn poly_line(points: Vec<impl Into<glam::DVec2>>, style: PathStyle) -> Self {
let mut path = kurbo::BezPath::new(); let mut path = kurbo::BezPath::new();
points points