Rename tools (#537)

* Rename tools

* Rename Text -> TextLayer
This commit is contained in:
0HyperCube 2022-02-12 19:04:34 +00:00 committed by Keavon Chambers
parent 31fb0d7148
commit 916d10980d
32 changed files with 325 additions and 382 deletions

View file

@ -16,7 +16,7 @@ use crate::viewport_tools::vector_editor::vector_shape::VectorShape;
use crate::EditorError;
use graphene::document::Document as GrapheneDocument;
use graphene::layers::folder::Folder;
use graphene::layers::folder_layer::FolderLayer;
use graphene::layers::layer_info::LayerDataType;
use graphene::layers::style::ViewMode;
use graphene::{DocumentError, DocumentResponse, LayerId, Operation as DocumentOperation};
@ -223,7 +223,7 @@ impl DocumentMessageHandler {
)
}
fn serialize_structure(&self, folder: &Folder, structure: &mut Vec<u64>, data: &mut Vec<LayerId>, path: &mut Vec<LayerId>) {
fn serialize_structure(&self, folder: &FolderLayer, structure: &mut Vec<u64>, data: &mut Vec<LayerId>, path: &mut Vec<LayerId>) {
let mut space = 0;
for (id, layer) in folder.layer_ids.iter().zip(folder.layers()).rev() {
data.push(*id);
@ -930,7 +930,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessorMessageHandler> for Docum
responses.push_back(ToolMessage::DocumentIsDirty.into());
}
Redo => {
responses.push_back(SelectMessage::Abort.into());
responses.push_back(SelectToolMessage::Abort.into());
responses.push_back(DocumentHistoryForward.into());
responses.push_back(ToolMessage::DocumentIsDirty.into());
responses.push_back(RenderDocument.into());
@ -1187,7 +1187,7 @@ impl MessageHandler<DocumentMessage, &InputPreprocessorMessageHandler> for Docum
responses.push_back(ToolMessage::DocumentIsDirty.into());
}
Undo => {
responses.push_back(SelectMessage::Abort.into());
responses.push_back(SelectToolMessage::Abort.into());
responses.push_back(DocumentHistoryBackward.into());
responses.push_back(ToolMessage::DocumentIsDirty.into());
responses.push_back(RenderDocument.into());

View file

@ -43,84 +43,84 @@ impl Default for Mapping {
entry! {action=TransformLayerMessage::TypeDecimalPoint, key_down=KeyPeriod},
entry! {action=TransformLayerMessage::PointerMove { slow_key: KeyShift, snap_key: KeyControl }, triggers=[KeyShift, KeyControl]},
// Select
entry! {action=SelectMessage::PointerMove { axis_align: KeyShift, snap_angle: KeyControl, center: KeyAlt }, message=InputMapperMessage::PointerMove},
entry! {action=SelectMessage::DragStart { add_to_selection: KeyShift }, key_down=Lmb},
entry! {action=SelectMessage::DragStop, key_up=Lmb},
entry! {action=SelectMessage::EditLayer, message=InputMapperMessage::DoubleClick},
entry! {action=SelectMessage::Abort, key_down=Rmb},
entry! {action=SelectMessage::Abort, key_down=KeyEscape},
entry! {action=SelectToolMessage::PointerMove { axis_align: KeyShift, snap_angle: KeyControl, center: KeyAlt }, message=InputMapperMessage::PointerMove},
entry! {action=SelectToolMessage::DragStart { add_to_selection: KeyShift }, key_down=Lmb},
entry! {action=SelectToolMessage::DragStop, key_up=Lmb},
entry! {action=SelectToolMessage::EditLayer, message=InputMapperMessage::DoubleClick},
entry! {action=SelectToolMessage::Abort, key_down=Rmb},
entry! {action=SelectToolMessage::Abort, key_down=KeyEscape},
// Crop
entry! {action=CropMessage::PointerDown, key_down=Lmb},
entry! {action=CropMessage::PointerMove { constrain_axis_or_aspect: KeyShift, center: KeyAlt }, message=InputMapperMessage::PointerMove},
entry! {action=CropMessage::PointerUp, key_up=Lmb},
entry! {action=CropMessage::DeleteSelected, key_down=KeyDelete},
entry! {action=CropMessage::DeleteSelected, key_down=KeyBackspace},
entry! {action=CropToolMessage::PointerDown, key_down=Lmb},
entry! {action=CropToolMessage::PointerMove { constrain_axis_or_aspect: KeyShift, center: KeyAlt }, message=InputMapperMessage::PointerMove},
entry! {action=CropToolMessage::PointerUp, key_up=Lmb},
entry! {action=CropToolMessage::DeleteSelected, key_down=KeyDelete},
entry! {action=CropToolMessage::DeleteSelected, key_down=KeyBackspace},
// Navigate
entry! {action=NavigateMessage::ClickZoom { zoom_in: false }, key_up=Lmb, modifiers=[KeyShift]},
entry! {action=NavigateMessage::ClickZoom { zoom_in: true }, key_up=Lmb},
entry! {action=NavigateMessage::PointerMove { snap_angle: KeyControl, snap_zoom: KeyControl }, message=InputMapperMessage::PointerMove},
entry! {action=NavigateMessage::TranslateCanvasBegin, key_down=Mmb},
entry! {action=NavigateMessage::RotateCanvasBegin, key_down=Rmb},
entry! {action=NavigateMessage::ZoomCanvasBegin, key_down=Lmb},
entry! {action=NavigateMessage::TransformCanvasEnd, key_up=Rmb},
entry! {action=NavigateMessage::TransformCanvasEnd, key_up=Lmb},
entry! {action=NavigateMessage::TransformCanvasEnd, key_up=Mmb},
entry! {action=NavigateToolMessage::ClickZoom { zoom_in: false }, key_up=Lmb, modifiers=[KeyShift]},
entry! {action=NavigateToolMessage::ClickZoom { zoom_in: true }, key_up=Lmb},
entry! {action=NavigateToolMessage::PointerMove { snap_angle: KeyControl, snap_zoom: KeyControl }, message=InputMapperMessage::PointerMove},
entry! {action=NavigateToolMessage::TranslateCanvasBegin, key_down=Mmb},
entry! {action=NavigateToolMessage::RotateCanvasBegin, key_down=Rmb},
entry! {action=NavigateToolMessage::ZoomCanvasBegin, key_down=Lmb},
entry! {action=NavigateToolMessage::TransformCanvasEnd, key_up=Rmb},
entry! {action=NavigateToolMessage::TransformCanvasEnd, key_up=Lmb},
entry! {action=NavigateToolMessage::TransformCanvasEnd, key_up=Mmb},
// Eyedropper
entry! {action=EyedropperMessage::LeftMouseDown, key_down=Lmb},
entry! {action=EyedropperMessage::RightMouseDown, key_down=Rmb},
entry! {action=EyedropperToolMessage::LeftMouseDown, key_down=Lmb},
entry! {action=EyedropperToolMessage::RightMouseDown, key_down=Rmb},
// Text
entry! {action=TextMessage::Interact, key_up=Lmb},
entry! {action=TextMessage::Abort, key_down=KeyEscape},
entry! {action=TextMessage::CommitText, key_down=KeyEnter, modifiers=[KeyControl]},
// Rectangle
entry! {action=RectangleMessage::DragStart, key_down=Lmb},
entry! {action=RectangleMessage::DragStop, key_up=Lmb},
entry! {action=RectangleMessage::Abort, key_down=Rmb},
entry! {action=RectangleMessage::Abort, key_down=KeyEscape},
entry! {action=RectangleMessage::Resize { center: KeyAlt, lock_ratio: KeyShift }, triggers=[KeyAlt, KeyShift]},
entry! {action=RectangleToolMessage::DragStart, key_down=Lmb},
entry! {action=RectangleToolMessage::DragStop, key_up=Lmb},
entry! {action=RectangleToolMessage::Abort, key_down=Rmb},
entry! {action=RectangleToolMessage::Abort, key_down=KeyEscape},
entry! {action=RectangleToolMessage::Resize { center: KeyAlt, lock_ratio: KeyShift }, triggers=[KeyAlt, KeyShift]},
// Ellipse
entry! {action=EllipseMessage::DragStart, key_down=Lmb},
entry! {action=EllipseMessage::DragStop, key_up=Lmb},
entry! {action=EllipseMessage::Abort, key_down=Rmb},
entry! {action=EllipseMessage::Abort, key_down=KeyEscape},
entry! {action=EllipseMessage::Resize { center: KeyAlt, lock_ratio: KeyShift }, triggers=[KeyAlt, KeyShift]},
entry! {action=EllipseToolMessage::DragStart, key_down=Lmb},
entry! {action=EllipseToolMessage::DragStop, key_up=Lmb},
entry! {action=EllipseToolMessage::Abort, key_down=Rmb},
entry! {action=EllipseToolMessage::Abort, key_down=KeyEscape},
entry! {action=EllipseToolMessage::Resize { center: KeyAlt, lock_ratio: KeyShift }, triggers=[KeyAlt, KeyShift]},
// Shape
entry! {action=ShapeMessage::DragStart, key_down=Lmb},
entry! {action=ShapeMessage::DragStop, key_up=Lmb},
entry! {action=ShapeMessage::Abort, key_down=Rmb},
entry! {action=ShapeMessage::Abort, key_down=KeyEscape},
entry! {action=ShapeMessage::Resize { center: KeyAlt, lock_ratio: KeyShift }, triggers=[KeyAlt, KeyShift]},
entry! {action=ShapeToolMessage::DragStart, key_down=Lmb},
entry! {action=ShapeToolMessage::DragStop, key_up=Lmb},
entry! {action=ShapeToolMessage::Abort, key_down=Rmb},
entry! {action=ShapeToolMessage::Abort, key_down=KeyEscape},
entry! {action=ShapeToolMessage::Resize { center: KeyAlt, lock_ratio: KeyShift }, triggers=[KeyAlt, KeyShift]},
// Line
entry! {action=LineMessage::DragStart, key_down=Lmb},
entry! {action=LineMessage::DragStop, key_up=Lmb},
entry! {action=LineMessage::Abort, key_down=Rmb},
entry! {action=LineMessage::Abort, key_down=KeyEscape},
entry! {action=LineMessage::Redraw { center: KeyAlt, lock_angle: KeyControl, snap_angle: KeyShift }, triggers=[KeyAlt, KeyShift, KeyControl]},
entry! {action=LineToolMessage::DragStart, key_down=Lmb},
entry! {action=LineToolMessage::DragStop, key_up=Lmb},
entry! {action=LineToolMessage::Abort, key_down=Rmb},
entry! {action=LineToolMessage::Abort, key_down=KeyEscape},
entry! {action=LineToolMessage::Redraw { center: KeyAlt, lock_angle: KeyControl, snap_angle: KeyShift }, triggers=[KeyAlt, KeyShift, KeyControl]},
// Path
entry! {action=PathMessage::DragStart { add_to_selection: KeyShift }, key_down=Lmb},
entry! {action=PathMessage::PointerMove { alt_mirror_angle: KeyAlt, shift_mirror_distance: KeyShift }, message=InputMapperMessage::PointerMove},
entry! {action=PathMessage::DragStop, key_up=Lmb},
entry! {action=PathToolMessage::DragStart { add_to_selection: KeyShift }, key_down=Lmb},
entry! {action=PathToolMessage::PointerMove { alt_mirror_angle: KeyAlt, shift_mirror_distance: KeyShift }, message=InputMapperMessage::PointerMove},
entry! {action=PathToolMessage::DragStop, key_up=Lmb},
// Pen
entry! {action=PenMessage::PointerMove, message=InputMapperMessage::PointerMove},
entry! {action=PenMessage::DragStart, key_down=Lmb},
entry! {action=PenMessage::DragStop, key_up=Lmb},
entry! {action=PenMessage::Confirm, key_down=Rmb},
entry! {action=PenMessage::Confirm, key_down=KeyEscape},
entry! {action=PenMessage::Confirm, key_down=KeyEnter},
entry! {action=PenToolMessage::PointerMove, message=InputMapperMessage::PointerMove},
entry! {action=PenToolMessage::DragStart, key_down=Lmb},
entry! {action=PenToolMessage::DragStop, key_up=Lmb},
entry! {action=PenToolMessage::Confirm, key_down=Rmb},
entry! {action=PenToolMessage::Confirm, key_down=KeyEscape},
entry! {action=PenToolMessage::Confirm, key_down=KeyEnter},
// Freehand
entry! {action=FreehandMessage::PointerMove, message=InputMapperMessage::PointerMove},
entry! {action=FreehandMessage::DragStart, key_down=Lmb},
entry! {action=FreehandMessage::DragStop, key_up=Lmb},
entry! {action=FreehandToolMessage::PointerMove, message=InputMapperMessage::PointerMove},
entry! {action=FreehandToolMessage::DragStart, key_down=Lmb},
entry! {action=FreehandToolMessage::DragStop, key_up=Lmb},
// Spline
entry! {action=SplineMessage::PointerMove, message=InputMapperMessage::PointerMove},
entry! {action=SplineMessage::DragStart, key_down=Lmb},
entry! {action=SplineMessage::DragStop, key_up=Lmb},
entry! {action=SplineMessage::Confirm, key_down=Rmb},
entry! {action=SplineMessage::Confirm, key_down=KeyEscape},
entry! {action=SplineMessage::Confirm, key_down=KeyEnter},
entry! {action=SplineToolMessage::PointerMove, message=InputMapperMessage::PointerMove},
entry! {action=SplineToolMessage::DragStart, key_down=Lmb},
entry! {action=SplineToolMessage::DragStop, key_up=Lmb},
entry! {action=SplineToolMessage::Confirm, key_down=Rmb},
entry! {action=SplineToolMessage::Confirm, key_down=KeyEscape},
entry! {action=SplineToolMessage::Confirm, key_down=KeyEnter},
// Fill
entry! {action=FillMessage::LeftMouseDown, key_down=Lmb},
entry! {action=FillMessage::RightMouseDown, key_down=Rmb},
entry! {action=FillToolMessage::LeftMouseDown, key_down=Lmb},
entry! {action=FillToolMessage::RightMouseDown, key_down=Rmb},
// Tool Actions
entry! {action=ToolMessage::ActivateTool { tool_type: ToolType::Select }, key_down=KeyV},
entry! {action=ToolMessage::ActivateTool { tool_type: ToolType::Navigate }, key_down=KeyZ},

View file

@ -72,20 +72,20 @@ pub mod message_prelude {
pub use crate::layout::{LayoutMessage, LayoutMessageDiscriminant};
pub use crate::misc::derivable_custom_traits::{ToDiscriminant, TransitiveChild};
pub use crate::viewport_tools::tool_message::{ToolMessage, ToolMessageDiscriminant};
pub use crate::viewport_tools::tools::crop::{CropMessage, CropMessageDiscriminant};
pub use crate::viewport_tools::tools::ellipse::{EllipseMessage, EllipseMessageDiscriminant};
pub use crate::viewport_tools::tools::eyedropper::{EyedropperMessage, EyedropperMessageDiscriminant};
pub use crate::viewport_tools::tools::fill::{FillMessage, FillMessageDiscriminant};
pub use crate::viewport_tools::tools::freehand::{FreehandMessage, FreehandMessageDiscriminant};
pub use crate::viewport_tools::tools::line::{LineMessage, LineMessageDiscriminant};
pub use crate::viewport_tools::tools::navigate::{NavigateMessage, NavigateMessageDiscriminant};
pub use crate::viewport_tools::tools::path::{PathMessage, PathMessageDiscriminant};
pub use crate::viewport_tools::tools::pen::{PenMessage, PenMessageDiscriminant};
pub use crate::viewport_tools::tools::rectangle::{RectangleMessage, RectangleMessageDiscriminant};
pub use crate::viewport_tools::tools::select::{SelectMessage, SelectMessageDiscriminant};
pub use crate::viewport_tools::tools::shape::{ShapeMessage, ShapeMessageDiscriminant};
pub use crate::viewport_tools::tools::spline::{SplineMessage, SplineMessageDiscriminant};
pub use crate::viewport_tools::tools::text::{TextMessage, TextMessageDiscriminant};
pub use crate::viewport_tools::tools::crop_tool::{CropToolMessage, CropToolMessageDiscriminant};
pub use crate::viewport_tools::tools::ellipse_tool::{EllipseToolMessage, EllipseToolMessageDiscriminant};
pub use crate::viewport_tools::tools::eyedropper_tool::{EyedropperToolMessage, EyedropperToolMessageDiscriminant};
pub use crate::viewport_tools::tools::fill_tool::{FillToolMessage, FillToolMessageDiscriminant};
pub use crate::viewport_tools::tools::freehand_tool::{FreehandToolMessage, FreehandToolMessageDiscriminant};
pub use crate::viewport_tools::tools::line_tool::{LineToolMessage, LineToolMessageDiscriminant};
pub use crate::viewport_tools::tools::navigate_tool::{NavigateToolMessage, NavigateToolMessageDiscriminant};
pub use crate::viewport_tools::tools::path_tool::{PathToolMessage, PathToolMessageDiscriminant};
pub use crate::viewport_tools::tools::pen_tool::{PenToolMessage, PenToolMessageDiscriminant};
pub use crate::viewport_tools::tools::rectangle_tool::{RectangleToolMessage, RectangleToolMessageDiscriminant};
pub use crate::viewport_tools::tools::select_tool::{SelectToolMessage, SelectToolMessageDiscriminant};
pub use crate::viewport_tools::tools::shape_tool::{ShapeToolMessage, ShapeToolMessageDiscriminant};
pub use crate::viewport_tools::tools::spline_tool::{SplineToolMessage, SplineToolMessageDiscriminant};
pub use crate::viewport_tools::tools::text_tool::{TextMessage, TextMessageDiscriminant};
pub use graphite_proc_macros::*;
pub use std::collections::VecDeque;

View file

@ -77,12 +77,12 @@ impl Default for ToolFsmState {
tool_data: ToolData {
active_tool_type: ToolType::Select,
tools: gen_tools_hash_map! {
Select => select::Select,
Crop => crop::Crop,
Navigate => navigate::Navigate,
Eyedropper => eyedropper::Eyedropper,
Text => text::Text,
Fill => fill::Fill,
Select => select_tool::SelectTool,
Crop => crop_tool::CropTool,
Navigate => navigate_tool::NavigateTool,
Eyedropper => eyedropper_tool::EyedropperTool,
Text => text_tool::TextTool,
Fill => fill_tool::FillTool,
// Gradient => gradient::Gradient,
// Brush => brush::Brush,
// Heal => heal::Heal,
@ -90,14 +90,14 @@ impl Default for ToolFsmState {
// Patch => patch::Patch,
// BlurSharpen => blursharpen::BlurSharpen,
// Relight => relight::Relight,
Path => path::Path,
Pen => pen::Pen,
Freehand => freehand::Freehand,
Spline => spline::Spline,
Line => line::Line,
Rectangle => rectangle::Rectangle,
Ellipse => ellipse::Ellipse,
Shape => shape::Shape,
Path => path_tool::PathTool,
Pen => pen_tool::PenTool,
Freehand => freehand_tool::FreehandTool,
Spline => spline_tool::SplineTool,
Line => line_tool::LineTool,
Rectangle => rectangle_tool::RectangleTool,
Ellipse => ellipse_tool::EllipseTool,
Shape => shape_tool::ShapeTool,
},
},
document_tool_data: DocumentToolData {
@ -186,54 +186,54 @@ pub enum StandardToolMessageType {
pub fn standard_tool_message(tool: ToolType, message_type: StandardToolMessageType) -> Option<ToolMessage> {
match message_type {
StandardToolMessageType::DocumentIsDirty => match tool {
ToolType::Select => Some(SelectMessage::DocumentIsDirty.into()),
ToolType::Crop => Some(CropMessage::DocumentIsDirty.into()),
ToolType::Navigate => None, // Some(NavigateMessage::DocumentIsDirty.into()),
ToolType::Eyedropper => None, // Some(EyedropperMessage::DocumentIsDirty.into()),
ToolType::Select => Some(SelectToolMessage::DocumentIsDirty.into()),
ToolType::Crop => Some(CropToolMessage::DocumentIsDirty.into()),
ToolType::Navigate => None, // Some(NavigateToolMessage::DocumentIsDirty.into()),
ToolType::Eyedropper => None, // Some(EyedropperToolMessage::DocumentIsDirty.into()),
ToolType::Text => Some(TextMessage::DocumentIsDirty.into()),
ToolType::Fill => None, // Some(FillMessage::DocumentIsDirty.into()),
ToolType::Fill => None, // Some(FillToolMessage::DocumentIsDirty.into()),
ToolType::Gradient => None, // Some(GradientMessage::DocumentIsDirty.into()),
ToolType::Brush => None, // Some(BrushMessage::DocumentIsDirty.into()),
ToolType::Heal => None, // Some(HealMessage::DocumentIsDirty.into()),
ToolType::Clone => None, // Some(CloneMessage::DocumentIsDirty.into()),
ToolType::Patch => None, // Some(PatchMessage::DocumentIsDirty.into()),
ToolType::BlurSharpen => None, // Some(BlurSharpenMessage::DocumentIsDirty.into()),
ToolType::BlurSharpen => None, // Some(BlurSharPenToolMessage::DocumentIsDirty.into()),
ToolType::Relight => None, // Some(RelightMessage::DocumentIsDirty.into()),
ToolType::Path => Some(PathMessage::DocumentIsDirty.into()),
ToolType::Pen => Some(PenMessage::DocumentIsDirty.into()),
ToolType::Freehand => None, // Some(FreehandMessage::DocumentIsDirty.into()),
ToolType::Spline => None, // Some(SplineMessage::DocumentIsDirty.into()),
ToolType::Line => None, // Some(LineMessage::DocumentIsDirty.into()),
ToolType::Rectangle => None, // Some(RectangleMessage::DocumentIsDirty.into()),
ToolType::Ellipse => None, // Some(EllipseMessage::DocumentIsDirty.into()),
ToolType::Shape => None, // Some(ShapeMessage::DocumentIsDirty.into()),
ToolType::Path => Some(PathToolMessage::DocumentIsDirty.into()),
ToolType::Pen => Some(PenToolMessage::DocumentIsDirty.into()),
ToolType::Freehand => None, // Some(FreehandToolMessage::DocumentIsDirty.into()),
ToolType::Spline => None, // Some(SplineToolMessage::DocumentIsDirty.into()),
ToolType::Line => None, // Some(LineToolMessage::DocumentIsDirty.into()),
ToolType::Rectangle => None, // Some(RectangleToolMessage::DocumentIsDirty.into()),
ToolType::Ellipse => None, // Some(EllipseToolMessage::DocumentIsDirty.into()),
ToolType::Shape => None, // Some(ShapeToolMessage::DocumentIsDirty.into()),
},
StandardToolMessageType::Abort => match tool {
ToolType::Select => Some(SelectMessage::Abort.into()),
ToolType::Crop => Some(CropMessage::Abort.into()),
ToolType::Navigate => Some(NavigateMessage::Abort.into()),
ToolType::Eyedropper => Some(EyedropperMessage::Abort.into()),
ToolType::Select => Some(SelectToolMessage::Abort.into()),
ToolType::Crop => Some(CropToolMessage::Abort.into()),
ToolType::Navigate => Some(NavigateToolMessage::Abort.into()),
ToolType::Eyedropper => Some(EyedropperToolMessage::Abort.into()),
ToolType::Text => Some(TextMessage::Abort.into()),
ToolType::Fill => Some(FillMessage::Abort.into()),
ToolType::Fill => Some(FillToolMessage::Abort.into()),
// ToolType::Gradient => Some(GradientMessage::Abort.into()),
// ToolType::Brush => Some(BrushMessage::Abort.into()),
// ToolType::Heal => Some(HealMessage::Abort.into()),
// ToolType::Clone => Some(CloneMessage::Abort.into()),
// ToolType::Patch => Some(PatchMessage::Abort.into()),
// ToolType::BlurSharpen => Some(BlurSharpenMessage::Abort.into()),
// ToolType::BlurSharpen => Some(BlurSharPenToolMessage::Abort.into()),
// ToolType::Relight => Some(RelightMessage::Abort.into()),
ToolType::Path => Some(PathMessage::Abort.into()),
ToolType::Pen => Some(PenMessage::Abort.into()),
ToolType::Freehand => Some(FreehandMessage::Abort.into()),
ToolType::Spline => Some(SplineMessage::Abort.into()),
ToolType::Line => Some(LineMessage::Abort.into()),
ToolType::Rectangle => Some(RectangleMessage::Abort.into()),
ToolType::Ellipse => Some(EllipseMessage::Abort.into()),
ToolType::Shape => Some(ShapeMessage::Abort.into()),
ToolType::Path => Some(PathToolMessage::Abort.into()),
ToolType::Pen => Some(PenToolMessage::Abort.into()),
ToolType::Freehand => Some(FreehandToolMessage::Abort.into()),
ToolType::Spline => Some(SplineToolMessage::Abort.into()),
ToolType::Line => Some(LineToolMessage::Abort.into()),
ToolType::Rectangle => Some(RectangleToolMessage::Abort.into()),
ToolType::Ellipse => Some(EllipseToolMessage::Abort.into()),
ToolType::Shape => Some(ShapeToolMessage::Abort.into()),
_ => None,
},
StandardToolMessageType::SelectionChanged => match tool {
ToolType::Path => Some(PathMessage::SelectionChanged.into()),
ToolType::Path => Some(PathToolMessage::SelectionChanged.into()),
_ => None,
},
}

View file

@ -12,16 +12,16 @@ pub enum ToolMessage {
// Sub-messages
#[remain::unsorted]
#[child]
Select(SelectMessage),
Select(SelectToolMessage),
#[remain::unsorted]
#[child]
Crop(CropMessage),
Crop(CropToolMessage),
#[remain::unsorted]
#[child]
Navigate(NavigateMessage),
Navigate(NavigateToolMessage),
#[remain::unsorted]
#[child]
Eyedropper(EyedropperMessage),
Eyedropper(EyedropperToolMessage),
// #[remain::unsorted]
// #[child]
// Text(TextMessage),
@ -30,7 +30,7 @@ pub enum ToolMessage {
Text(TextMessage),
#[remain::unsorted]
#[child]
Fill(FillMessage),
Fill(FillToolMessage),
// #[remain::unsorted]
// #[child]
// Gradient(GradientMessage),
@ -54,28 +54,28 @@ pub enum ToolMessage {
// Relight(RelightMessage),
#[remain::unsorted]
#[child]
Path(PathMessage),
Path(PathToolMessage),
#[remain::unsorted]
#[child]
Pen(PenMessage),
Pen(PenToolMessage),
#[remain::unsorted]
#[child]
Freehand(FreehandMessage),
Freehand(FreehandToolMessage),
#[remain::unsorted]
#[child]
Spline(SplineMessage),
Spline(SplineToolMessage),
#[remain::unsorted]
#[child]
Line(LineMessage),
Line(LineToolMessage),
#[remain::unsorted]
#[child]
Rectangle(RectangleMessage),
Rectangle(RectangleToolMessage),
#[remain::unsorted]
#[child]
Ellipse(EllipseMessage),
Ellipse(EllipseToolMessage),
#[remain::unsorted]
#[child]
Shape(ShapeMessage),
Shape(ShapeToolMessage),
// Messages
#[remain::unsorted]

View file

@ -17,7 +17,7 @@ use glam::{DVec2, Vec2Swizzles};
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Crop {
pub struct CropTool {
fsm_state: CropToolFsmState,
data: CropToolData,
}
@ -25,7 +25,7 @@ pub struct Crop {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Crop)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum CropMessage {
pub enum CropToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -42,7 +42,7 @@ pub enum CropMessage {
PointerUp,
}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Crop {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for CropTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -62,10 +62,10 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Crop {
}
}
advertise_actions!(CropMessageDiscriminant; PointerDown, PointerUp, PointerMove, DeleteSelected, Abort);
advertise_actions!(CropToolMessageDiscriminant; PointerDown, PointerUp, PointerMove, DeleteSelected, Abort);
}
impl PropertyHolder for Crop {}
impl PropertyHolder for CropTool {}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum CropToolFsmState {
@ -107,7 +107,7 @@ impl Fsm for CropToolFsmState {
) -> Self {
if let ToolMessage::Crop(event) = event {
match (self, event) {
(CropToolFsmState::Ready | CropToolFsmState::ResizingBounds | CropToolFsmState::Dragging, CropMessage::DocumentIsDirty) => {
(CropToolFsmState::Ready | CropToolFsmState::ResizingBounds | CropToolFsmState::Dragging, CropToolMessage::DocumentIsDirty) => {
let mut buffer = Vec::new();
match (
data.selected_board.map(|path| document.artboard_bounding_box_and_transform(&[path])).unwrap_or(None),
@ -131,7 +131,7 @@ impl Fsm for CropToolFsmState {
buffer.into_iter().rev().for_each(|message| responses.push_front(message));
self
}
(CropToolFsmState::Ready, CropMessage::PointerDown) => {
(CropToolFsmState::Ready, CropToolMessage::PointerDown) => {
data.drag_start = input.mouse.position;
data.drag_current = input.mouse.position;
@ -188,7 +188,7 @@ impl Fsm for CropToolFsmState {
}
}
}
(CropToolFsmState::ResizingBounds, CropMessage::PointerMove { constrain_axis_or_aspect, center }) => {
(CropToolFsmState::ResizingBounds, CropToolMessage::PointerMove { constrain_axis_or_aspect, center }) => {
if let Some(bounds) = &data.bounding_box_overlays {
if let Some(movement) = &bounds.selected_edges {
let from_center = input.keyboard.get(center as usize);
@ -214,7 +214,7 @@ impl Fsm for CropToolFsmState {
}
CropToolFsmState::ResizingBounds
}
(CropToolFsmState::Dragging, CropMessage::PointerMove { constrain_axis_or_aspect, .. }) => {
(CropToolFsmState::Dragging, CropToolMessage::PointerMove { constrain_axis_or_aspect, .. }) => {
if let Some(bounds) = &data.bounding_box_overlays {
let axis_align = input.keyboard.get(constrain_axis_or_aspect as usize);
@ -243,7 +243,7 @@ impl Fsm for CropToolFsmState {
}
CropToolFsmState::Dragging
}
(CropToolFsmState::Drawing, CropMessage::PointerMove { constrain_axis_or_aspect, center }) => {
(CropToolFsmState::Drawing, CropToolMessage::PointerMove { constrain_axis_or_aspect, center }) => {
let mouse_position = input.mouse.position;
let snapped_mouse_position = data.snap_handler.snap_position(responses, input.viewport_bounds.size(), document, mouse_position);
@ -277,7 +277,7 @@ impl Fsm for CropToolFsmState {
CropToolFsmState::Drawing
}
(CropToolFsmState::Ready, CropMessage::PointerMove { .. }) => {
(CropToolFsmState::Ready, CropToolMessage::PointerMove { .. }) => {
let cursor = data.bounding_box_overlays.as_ref().map_or(MouseCursorIcon::Default, |bounds| bounds.get_cursor(input, false));
if data.cursor != cursor {
@ -287,7 +287,7 @@ impl Fsm for CropToolFsmState {
CropToolFsmState::Ready
}
(CropToolFsmState::ResizingBounds, CropMessage::PointerUp) => {
(CropToolFsmState::ResizingBounds, CropToolMessage::PointerUp) => {
data.snap_handler.cleanup(responses);
if let Some(bounds) = &mut data.bounding_box_overlays {
@ -296,7 +296,7 @@ impl Fsm for CropToolFsmState {
CropToolFsmState::Ready
}
(CropToolFsmState::Drawing, CropMessage::PointerUp) => {
(CropToolFsmState::Drawing, CropToolMessage::PointerUp) => {
data.snap_handler.cleanup(responses);
if let Some(bounds) = &mut data.bounding_box_overlays {
@ -307,7 +307,7 @@ impl Fsm for CropToolFsmState {
CropToolFsmState::Ready
}
(CropToolFsmState::Dragging, CropMessage::PointerUp) => {
(CropToolFsmState::Dragging, CropToolMessage::PointerUp) => {
data.snap_handler.cleanup(responses);
if let Some(bounds) = &mut data.bounding_box_overlays {
@ -316,14 +316,14 @@ impl Fsm for CropToolFsmState {
CropToolFsmState::Ready
}
(_, CropMessage::DeleteSelected) => {
(_, CropToolMessage::DeleteSelected) => {
if let Some(artboard) = data.selected_board.take() {
responses.push_back(ArtboardMessage::DeleteArtboard { artboard }.into());
responses.push_back(ToolMessage::DocumentIsDirty.into());
}
CropToolFsmState::Ready
}
(_, CropMessage::Abort) => {
(_, CropToolMessage::Abort) => {
if let Some(bounding_box_overlays) = data.bounding_box_overlays.take() {
bounding_box_overlays.delete(responses);
}

View file

@ -16,7 +16,7 @@ use glam::DAffine2;
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Ellipse {
pub struct EllipseTool {
fsm_state: EllipseToolFsmState,
data: EllipseToolData,
}
@ -24,7 +24,7 @@ pub struct Ellipse {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Ellipse)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum EllipseMessage {
pub enum EllipseToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -38,9 +38,9 @@ pub enum EllipseMessage {
},
}
impl PropertyHolder for Ellipse {}
impl PropertyHolder for EllipseTool {}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Ellipse {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for EllipseTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -65,8 +65,8 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Ellipse {
use EllipseToolFsmState::*;
match self.fsm_state {
Ready => actions!(EllipseMessageDiscriminant; DragStart),
Drawing => actions!(EllipseMessageDiscriminant; DragStop, Abort, Resize),
Ready => actions!(EllipseToolMessageDiscriminant; DragStart),
Drawing => actions!(EllipseToolMessageDiscriminant; DragStop, Abort, Resize),
}
}
}
@ -102,8 +102,8 @@ impl Fsm for EllipseToolFsmState {
input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>,
) -> Self {
use EllipseMessage::*;
use EllipseToolFsmState::*;
use EllipseToolMessage::*;
let mut shape_data = &mut data.data;

View file

@ -15,7 +15,7 @@ use glam::DVec2;
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Eyedropper {
pub struct EyedropperTool {
fsm_state: EyedropperToolFsmState,
data: EyedropperToolData,
}
@ -23,7 +23,7 @@ pub struct Eyedropper {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Eyedropper)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum EyedropperMessage {
pub enum EyedropperToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -33,9 +33,9 @@ pub enum EyedropperMessage {
RightMouseDown,
}
impl PropertyHolder for Eyedropper {}
impl PropertyHolder for EyedropperTool {}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Eyedropper {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for EyedropperTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -56,7 +56,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Eyedropper {
}
}
advertise_actions!(EyedropperMessageDiscriminant; LeftMouseDown, RightMouseDown);
advertise_actions!(EyedropperToolMessageDiscriminant; LeftMouseDown, RightMouseDown);
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@ -87,8 +87,8 @@ impl Fsm for EyedropperToolFsmState {
input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>,
) -> Self {
use EyedropperMessage::*;
use EyedropperToolFsmState::*;
use EyedropperToolMessage::*;
if let ToolMessage::Eyedropper(event) = event {
match (self, event) {
@ -103,8 +103,8 @@ impl Fsm for EyedropperToolFsmState {
if let LayerDataType::Shape(shape) = &layer.data {
if let Some(fill) = shape.style.fill() {
match lmb_or_rmb {
EyedropperMessage::LeftMouseDown => responses.push_back(ToolMessage::SelectPrimaryColor { color: fill.color() }.into()),
EyedropperMessage::RightMouseDown => responses.push_back(ToolMessage::SelectSecondaryColor { color: fill.color() }.into()),
EyedropperToolMessage::LeftMouseDown => responses.push_back(ToolMessage::SelectPrimaryColor { color: fill.color() }.into()),
EyedropperToolMessage::RightMouseDown => responses.push_back(ToolMessage::SelectSecondaryColor { color: fill.color() }.into()),
_ => {}
}
}

View file

@ -15,7 +15,7 @@ use glam::DVec2;
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Fill {
pub struct FillTool {
fsm_state: FillToolFsmState,
data: FillToolData,
}
@ -23,7 +23,7 @@ pub struct Fill {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Fill)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum FillMessage {
pub enum FillToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -33,9 +33,9 @@ pub enum FillMessage {
RightMouseDown,
}
impl PropertyHolder for Fill {}
impl PropertyHolder for FillTool {}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Fill {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for FillTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -56,7 +56,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Fill {
}
}
advertise_actions!(FillMessageDiscriminant; LeftMouseDown, RightMouseDown);
advertise_actions!(FillToolMessageDiscriminant; LeftMouseDown, RightMouseDown);
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@ -87,8 +87,8 @@ impl Fsm for FillToolFsmState {
input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>,
) -> Self {
use FillMessage::*;
use FillToolFsmState::*;
use FillToolMessage::*;
if let ToolMessage::Fill(event) = event {
match (self, event) {

View file

@ -14,7 +14,7 @@ use glam::{DAffine2, DVec2};
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Freehand {
pub struct FreehandTool {
fsm_state: FreehandToolFsmState,
data: FreehandToolData,
options: FreehandOptions,
@ -33,7 +33,7 @@ impl Default for FreehandOptions {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Freehand)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum FreehandMessage {
pub enum FreehandToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -42,12 +42,12 @@ pub enum FreehandMessage {
DragStart,
DragStop,
PointerMove,
UpdateOptions(FreehandMessageOptionsUpdate),
UpdateOptions(FreehandToolMessageOptionsUpdate),
}
#[remain::sorted]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum FreehandMessageOptionsUpdate {
pub enum FreehandToolMessageOptionsUpdate {
LineWeight(u32),
}
@ -57,7 +57,7 @@ enum FreehandToolFsmState {
Drawing,
}
impl PropertyHolder for Freehand {
impl PropertyHolder for FreehandTool {
fn properties(&self) -> WidgetLayout {
WidgetLayout::new(vec![LayoutRow::Row {
name: "".into(),
@ -67,14 +67,14 @@ impl PropertyHolder for Freehand {
value: self.options.line_weight as f64,
is_integer: true,
min: Some(1.),
on_update: WidgetCallback::new(|number_input| FreehandMessage::UpdateOptions(FreehandMessageOptionsUpdate::LineWeight(number_input.value as u32)).into()),
on_update: WidgetCallback::new(|number_input| FreehandToolMessage::UpdateOptions(FreehandToolMessageOptionsUpdate::LineWeight(number_input.value as u32)).into()),
..NumberInput::default()
}))],
}])
}
}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Freehand {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for FreehandTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -86,9 +86,9 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Freehand {
return;
}
if let ToolMessage::Freehand(FreehandMessage::UpdateOptions(action)) = action {
if let ToolMessage::Freehand(FreehandToolMessage::UpdateOptions(action)) = action {
match action {
FreehandMessageOptionsUpdate::LineWeight(line_weight) => self.options.line_weight = line_weight,
FreehandToolMessageOptionsUpdate::LineWeight(line_weight) => self.options.line_weight = line_weight,
}
return;
}
@ -106,8 +106,8 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Freehand {
use FreehandToolFsmState::*;
match self.fsm_state {
Ready => actions!(FreehandMessageDiscriminant; DragStart, DragStop, Abort),
Drawing => actions!(FreehandMessageDiscriminant; DragStop, PointerMove, Abort),
Ready => actions!(FreehandToolMessageDiscriminant; DragStart, DragStop, Abort),
Drawing => actions!(FreehandToolMessageDiscriminant; DragStop, PointerMove, Abort),
}
}
}
@ -138,8 +138,8 @@ impl Fsm for FreehandToolFsmState {
input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>,
) -> Self {
use FreehandMessage::*;
use FreehandToolFsmState::*;
use FreehandToolMessage::*;
let transform = document.graphene_document.root.transform;

View file

@ -17,7 +17,7 @@ use glam::{DAffine2, DVec2};
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Line {
pub struct LineTool {
fsm_state: LineToolFsmState,
data: LineToolData,
options: LineOptions,
@ -36,7 +36,7 @@ impl Default for LineOptions {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Line)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum LineMessage {
pub enum LineToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -58,7 +58,7 @@ pub enum LineOptionsUpdate {
LineWeight(u32),
}
impl PropertyHolder for Line {
impl PropertyHolder for LineTool {
fn properties(&self) -> WidgetLayout {
WidgetLayout::new(vec![LayoutRow::Row {
name: "".into(),
@ -68,14 +68,14 @@ impl PropertyHolder for Line {
value: self.options.line_weight as f64,
is_integer: true,
min: Some(0.),
on_update: WidgetCallback::new(|number_input| LineMessage::UpdateOptions(LineOptionsUpdate::LineWeight(number_input.value as u32)).into()),
on_update: WidgetCallback::new(|number_input| LineToolMessage::UpdateOptions(LineOptionsUpdate::LineWeight(number_input.value as u32)).into()),
..NumberInput::default()
}))],
}])
}
}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Line {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for LineTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -87,7 +87,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Line {
return;
}
if let ToolMessage::Line(LineMessage::UpdateOptions(action)) = action {
if let ToolMessage::Line(LineToolMessage::UpdateOptions(action)) = action {
match action {
LineOptionsUpdate::LineWeight(line_weight) => self.options.line_weight = line_weight,
}
@ -107,8 +107,8 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Line {
use LineToolFsmState::*;
match self.fsm_state {
Ready => actions!(LineMessageDiscriminant; DragStart),
Drawing => actions!(LineMessageDiscriminant; DragStop, Redraw, Abort),
Ready => actions!(LineToolMessageDiscriminant; DragStart),
Drawing => actions!(LineToolMessageDiscriminant; DragStop, Redraw, Abort),
}
}
}
@ -149,8 +149,8 @@ impl Fsm for LineToolFsmState {
input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>,
) -> Self {
use LineMessage::*;
use LineToolFsmState::*;
use LineToolMessage::*;
if let ToolMessage::Line(event) = event {
match (self, event) {

View file

@ -1,15 +1,15 @@
pub mod crop;
pub mod ellipse;
pub mod eyedropper;
pub mod fill;
pub mod freehand;
pub mod line;
pub mod navigate;
pub mod path;
pub mod pen;
pub mod rectangle;
pub mod select;
pub mod shape;
pub mod crop_tool;
pub mod ellipse_tool;
pub mod eyedropper_tool;
pub mod fill_tool;
pub mod freehand_tool;
pub mod line_tool;
pub mod navigate_tool;
pub mod path_tool;
pub mod pen_tool;
pub mod rectangle_tool;
pub mod select_tool;
pub mod shape_tool;
pub mod shared;
pub mod spline;
pub mod text;
pub mod spline_tool;
pub mod text_tool;

View file

@ -11,7 +11,7 @@ use glam::DVec2;
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Navigate {
pub struct NavigateTool {
fsm_state: NavigateToolFsmState,
data: NavigateToolData,
}
@ -19,7 +19,7 @@ pub struct Navigate {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Navigate)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum NavigateMessage {
pub enum NavigateToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -38,9 +38,9 @@ pub enum NavigateMessage {
ZoomCanvasBegin,
}
impl PropertyHolder for Navigate {}
impl PropertyHolder for NavigateTool {}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Navigate {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for NavigateTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -65,8 +65,8 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Navigate {
use NavigateToolFsmState::*;
match self.fsm_state {
Ready => actions!(NavigateMessageDiscriminant; TranslateCanvasBegin, RotateCanvasBegin, ZoomCanvasBegin),
_ => actions!(NavigateMessageDiscriminant; ClickZoom, PointerMove, TransformCanvasEnd),
Ready => actions!(NavigateToolMessageDiscriminant; TranslateCanvasBegin, RotateCanvasBegin, ZoomCanvasBegin),
_ => actions!(NavigateToolMessageDiscriminant; ClickZoom, PointerMove, TransformCanvasEnd),
}
}
}
@ -105,7 +105,7 @@ impl Fsm for NavigateToolFsmState {
messages: &mut VecDeque<Message>,
) -> Self {
if let ToolMessage::Navigate(navigate) = message {
use NavigateMessage::*;
use NavigateToolMessage::*;
match navigate {
ClickZoom { zoom_in } => {

View file

@ -16,7 +16,7 @@ use glam::DVec2;
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Path {
pub struct PathTool {
fsm_state: PathToolFsmState,
data: PathToolData,
}
@ -24,7 +24,7 @@ pub struct Path {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Path)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum PathMessage {
pub enum PathToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -44,9 +44,9 @@ pub enum PathMessage {
},
}
impl PropertyHolder for Path {}
impl PropertyHolder for PathTool {}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Path {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for PathTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -72,8 +72,8 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Path {
use PathToolFsmState::*;
match self.fsm_state {
Ready => actions!(PathMessageDiscriminant; DragStart),
Dragging => actions!(PathMessageDiscriminant; DragStop, PointerMove),
Ready => actions!(PathToolMessageDiscriminant; DragStart),
Dragging => actions!(PathToolMessageDiscriminant; DragStop, PointerMove),
}
}
}
@ -115,8 +115,8 @@ impl Fsm for PathToolFsmState {
responses: &mut VecDeque<Message>,
) -> Self {
if let ToolMessage::Path(event) = event {
use PathMessage::*;
use PathToolFsmState::*;
use PathToolMessage::*;
match (self, event) {
// TODO: Capture a tool event instead of doing this?

View file

@ -18,7 +18,7 @@ use kurbo::{PathEl, Point};
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Pen {
pub struct PenTool {
fsm_state: PenToolFsmState,
data: PenToolData,
options: PenOptions,
@ -37,7 +37,7 @@ impl Default for PenOptions {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Pen)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum PenMessage {
pub enum PenToolMessage {
// Standard messages
#[remain::unsorted]
DocumentIsDirty,
@ -65,7 +65,7 @@ pub enum PenOptionsUpdate {
LineWeight(u32),
}
impl PropertyHolder for Pen {
impl PropertyHolder for PenTool {
fn properties(&self) -> WidgetLayout {
WidgetLayout::new(vec![LayoutRow::Row {
name: "".into(),
@ -75,14 +75,14 @@ impl PropertyHolder for Pen {
value: self.options.line_weight as f64,
is_integer: true,
min: Some(0.),
on_update: WidgetCallback::new(|number_input| PenMessage::UpdateOptions(PenOptionsUpdate::LineWeight(number_input.value as u32)).into()),
on_update: WidgetCallback::new(|number_input| PenToolMessage::UpdateOptions(PenOptionsUpdate::LineWeight(number_input.value as u32)).into()),
..NumberInput::default()
}))],
}])
}
}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Pen {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for PenTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -94,7 +94,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Pen {
return;
}
if let ToolMessage::Pen(PenMessage::UpdateOptions(action)) = action {
if let ToolMessage::Pen(PenToolMessage::UpdateOptions(action)) = action {
match action {
PenOptionsUpdate::LineWeight(line_weight) => self.options.line_weight = line_weight,
}
@ -114,8 +114,8 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Pen {
use PenToolFsmState::*;
match self.fsm_state {
Ready => actions!(PenMessageDiscriminant; Undo, DragStart, DragStop, Confirm, Abort),
Drawing => actions!(PenMessageDiscriminant; DragStart, DragStop, PointerMove, Confirm, Abort),
Ready => actions!(PenToolMessageDiscriminant; Undo, DragStart, DragStop, Confirm, Abort),
Drawing => actions!(PenToolMessageDiscriminant; DragStart, DragStop, PointerMove, Confirm, Abort),
}
}
}
@ -149,8 +149,8 @@ impl Fsm for PenToolFsmState {
input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>,
) -> Self {
use PenMessage::*;
use PenToolFsmState::*;
use PenToolMessage::*;
let transform = document.graphene_document.root.transform;

View file

@ -16,7 +16,7 @@ use glam::DAffine2;
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Rectangle {
pub struct RectangleTool {
fsm_state: RectangleToolFsmState,
data: RectangleToolData,
}
@ -24,7 +24,7 @@ pub struct Rectangle {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Rectangle)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum RectangleMessage {
pub enum RectangleToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -38,9 +38,9 @@ pub enum RectangleMessage {
},
}
impl PropertyHolder for Rectangle {}
impl PropertyHolder for RectangleTool {}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Rectangle {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for RectangleTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -65,8 +65,8 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Rectangle {
use RectangleToolFsmState::*;
match self.fsm_state {
Ready => actions!(RectangleMessageDiscriminant; DragStart),
Drawing => actions!(RectangleMessageDiscriminant; DragStop, Abort, Resize),
Ready => actions!(RectangleToolMessageDiscriminant; DragStart),
Drawing => actions!(RectangleToolMessageDiscriminant; DragStop, Abort, Resize),
}
}
}
@ -101,8 +101,8 @@ impl Fsm for RectangleToolFsmState {
input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>,
) -> Self {
use RectangleMessage::*;
use RectangleToolFsmState::*;
use RectangleToolMessage::*;
let mut shape_data = &mut data.data;

View file

@ -1,57 +0,0 @@
use crate::document::DocumentMessageHandler;
use crate::input::keyboard::Key;
use crate::input::mouse::ViewportPosition;
use crate::input::InputPreprocessorMessageHandler;
use crate::message_prelude::*;
use crate::viewport_tools::snapping::SnapHandler;
use graphene::Operation;
use glam::{DAffine2, DVec2, Vec2Swizzles};
#[derive(Clone, Debug, Default)]
pub struct Resize {
pub drag_start: ViewportPosition,
pub path: Option<Vec<LayerId>>,
snap_handler: SnapHandler,
}
impl Resize {
/// Starts a resize, assigning the snap targets and snapping the starting position.
pub fn start(&mut self, responses: &mut VecDeque<Message>, viewport_bounds: DVec2, document: &DocumentMessageHandler, mouse_position: DVec2) {
let layers = document.all_layers_sorted();
self.snap_handler.start_snap(responses, viewport_bounds, document, layers);
self.drag_start = self.snap_handler.snap_position(document, mouse_position);
}
pub fn calculate_transform(&self, document: &DocumentMessageHandler, center: Key, lock_ratio: Key, ipp: &InputPreprocessorMessageHandler) -> Option<Message> {
if let Some(path) = &self.path {
let mut start = self.drag_start;
let stop = self.snap_handler.snap_position(document, ipp.mouse.position);
let mut size = stop - start;
if ipp.keyboard.get(lock_ratio as usize) {
size = size.abs().max(size.abs().yx()) * size.signum();
}
if ipp.keyboard.get(center as usize) {
start -= size;
size *= 2.;
}
Some(
Operation::SetLayerTransformInViewport {
path: path.to_vec(),
transform: DAffine2::from_scale_angle_translation(size, 0., start).to_cols_array(),
}
.into(),
)
} else {
None
}
}
pub fn cleanup(&mut self, responses: &mut VecDeque<Message>) {
self.snap_handler.cleanup(responses);
self.path = None;
}
}

View file

@ -23,7 +23,7 @@ use glam::{DAffine2, DVec2};
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Select {
pub struct SelectTool {
fsm_state: SelectToolFsmState,
data: SelectToolData,
}
@ -31,7 +31,7 @@ pub struct Select {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Select)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum SelectMessage {
pub enum SelectToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -57,7 +57,7 @@ pub enum SelectMessage {
},
}
impl PropertyHolder for Select {
impl PropertyHolder for SelectTool {
fn properties(&self) -> WidgetLayout {
WidgetLayout::new(vec![LayoutRow::Row {
name: "".into(),
@ -160,14 +160,14 @@ impl PropertyHolder for Select {
icon: "FlipHorizontal".into(),
tooltip: "Flip Horizontal".into(),
size: 24,
on_update: WidgetCallback::new(|_| SelectMessage::FlipHorizontal.into()),
on_update: WidgetCallback::new(|_| SelectToolMessage::FlipHorizontal.into()),
..IconButton::default()
})),
WidgetHolder::new(Widget::IconButton(IconButton {
icon: "FlipVertical".into(),
tooltip: "Flip Vertical".into(),
size: 24,
on_update: WidgetCallback::new(|_| SelectMessage::FlipVertical.into()),
on_update: WidgetCallback::new(|_| SelectToolMessage::FlipVertical.into()),
..IconButton::default()
})),
WidgetHolder::new(Widget::Separator(Separator {
@ -230,7 +230,7 @@ impl PropertyHolder for Select {
}
}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Select {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for SelectTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -254,9 +254,9 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Select {
use SelectToolFsmState::*;
match self.fsm_state {
Ready => actions!(SelectMessageDiscriminant; DragStart, PointerMove, EditLayer),
Dragging => actions!(SelectMessageDiscriminant; DragStop, PointerMove, EditLayer),
_ => actions!(SelectMessageDiscriminant; DragStop, PointerMove, Abort, EditLayer),
Ready => actions!(SelectToolMessageDiscriminant; DragStart, PointerMove, EditLayer),
Dragging => actions!(SelectToolMessageDiscriminant; DragStop, PointerMove, EditLayer),
_ => actions!(SelectToolMessageDiscriminant; DragStop, PointerMove, Abort, EditLayer),
}
}
}
@ -317,8 +317,8 @@ impl Fsm for SelectToolFsmState {
input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>,
) -> Self {
use SelectMessage::*;
use SelectToolFsmState::*;
use SelectToolMessage::*;
if let ToolMessage::Select(event) = event {
match (self, event) {
@ -446,7 +446,7 @@ impl Fsm for SelectToolFsmState {
}
(Dragging, PointerMove { axis_align, .. }) => {
// TODO: This is a cheat. Break out the relevant functionality from the handler above and call it from there and here.
responses.push_front(SelectMessage::DocumentIsDirty.into());
responses.push_front(SelectToolMessage::DocumentIsDirty.into());
let mouse_position = axis_align_drag(input.keyboard.get(axis_align as usize), input.mouse.position, data.drag_start);

View file

@ -16,7 +16,7 @@ use glam::DAffine2;
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Shape {
pub struct ShapeTool {
fsm_state: ShapeToolFsmState,
data: ShapeToolData,
options: ShapeOptions,
@ -35,7 +35,7 @@ impl Default for ShapeOptions {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Shape)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum ShapeMessage {
pub enum ShapeToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -56,7 +56,7 @@ pub enum ShapeOptionsUpdate {
Vertices(u8),
}
impl PropertyHolder for Shape {
impl PropertyHolder for ShapeTool {
fn properties(&self) -> WidgetLayout {
WidgetLayout::new(vec![LayoutRow::Row {
name: "".into(),
@ -66,14 +66,14 @@ impl PropertyHolder for Shape {
is_integer: true,
min: Some(3.),
max: Some(256.),
on_update: WidgetCallback::new(|number_input| ShapeMessage::UpdateOptions(ShapeOptionsUpdate::Vertices(number_input.value as u8)).into()),
on_update: WidgetCallback::new(|number_input| ShapeToolMessage::UpdateOptions(ShapeOptionsUpdate::Vertices(number_input.value as u8)).into()),
..NumberInput::default()
}))],
}])
}
}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Shape {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for ShapeTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -85,7 +85,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Shape {
return;
}
if let ToolMessage::Shape(ShapeMessage::UpdateOptions(action)) = action {
if let ToolMessage::Shape(ShapeToolMessage::UpdateOptions(action)) = action {
match action {
ShapeOptionsUpdate::Vertices(vertices) => self.options.vertices = vertices,
}
@ -105,8 +105,8 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Shape {
use ShapeToolFsmState::*;
match self.fsm_state {
Ready => actions!(ShapeMessageDiscriminant; DragStart),
Drawing => actions!(ShapeMessageDiscriminant; DragStop, Abort, Resize),
Ready => actions!(ShapeToolMessageDiscriminant; DragStart),
Drawing => actions!(ShapeToolMessageDiscriminant; DragStop, Abort, Resize),
}
}
}
@ -142,8 +142,8 @@ impl Fsm for ShapeToolFsmState {
input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>,
) -> Self {
use ShapeMessage::*;
use ShapeToolFsmState::*;
use ShapeToolMessage::*;
let mut shape_data = &mut data.data;

View file

@ -16,7 +16,7 @@ use glam::{DAffine2, DVec2};
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Spline {
pub struct SplineTool {
fsm_state: SplineToolFsmState,
data: SplineToolData,
options: SplineOptions,
@ -35,7 +35,7 @@ impl Default for SplineOptions {
#[remain::sorted]
#[impl_message(Message, ToolMessage, Spline)]
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
pub enum SplineMessage {
pub enum SplineToolMessage {
// Standard messages
#[remain::unsorted]
Abort,
@ -61,7 +61,7 @@ pub enum SplineOptionsUpdate {
LineWeight(u32),
}
impl PropertyHolder for Spline {
impl PropertyHolder for SplineTool {
fn properties(&self) -> WidgetLayout {
WidgetLayout::new(vec![LayoutRow::Row {
name: "".into(),
@ -71,14 +71,14 @@ impl PropertyHolder for Spline {
value: self.options.line_weight as f64,
is_integer: true,
min: Some(0.),
on_update: WidgetCallback::new(|number_input| SplineMessage::UpdateOptions(SplineOptionsUpdate::LineWeight(number_input.value as u32)).into()),
on_update: WidgetCallback::new(|number_input| SplineToolMessage::UpdateOptions(SplineOptionsUpdate::LineWeight(number_input.value as u32)).into()),
..NumberInput::default()
}))],
}])
}
}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Spline {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for SplineTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);
@ -90,7 +90,7 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Spline {
return;
}
if let ToolMessage::Spline(SplineMessage::UpdateOptions(action)) = action {
if let ToolMessage::Spline(SplineToolMessage::UpdateOptions(action)) = action {
match action {
SplineOptionsUpdate::LineWeight(line_weight) => self.options.line_weight = line_weight,
}
@ -110,8 +110,8 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Spline {
use SplineToolFsmState::*;
match self.fsm_state {
Ready => actions!(SplineMessageDiscriminant; Undo, DragStart, DragStop, Confirm, Abort),
Drawing => actions!(SplineMessageDiscriminant; DragStop, PointerMove, Confirm, Abort),
Ready => actions!(SplineToolMessageDiscriminant; Undo, DragStart, DragStop, Confirm, Abort),
Drawing => actions!(SplineToolMessageDiscriminant; DragStop, PointerMove, Confirm, Abort),
}
}
}
@ -144,8 +144,8 @@ impl Fsm for SplineToolFsmState {
input: &InputPreprocessorMessageHandler,
responses: &mut VecDeque<Message>,
) -> Self {
use SplineMessage::*;
use SplineToolFsmState::*;
use SplineToolMessage::*;
let transform = document.graphene_document.root.transform;

View file

@ -16,7 +16,7 @@ use kurbo::Shape;
use serde::{Deserialize, Serialize};
#[derive(Default)]
pub struct Text {
pub struct TextTool {
fsm_state: TextToolFsmState,
data: TextToolData,
options: TextOptions,
@ -61,7 +61,7 @@ pub enum TextOptionsUpdate {
FontSize(u32),
}
impl PropertyHolder for Text {
impl PropertyHolder for TextTool {
fn properties(&self) -> WidgetLayout {
WidgetLayout::new(vec![LayoutRow::Row {
name: "".into(),
@ -78,7 +78,7 @@ impl PropertyHolder for Text {
}
}
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Text {
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for TextTool {
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
if action == ToolMessage::UpdateHints {
self.fsm_state.update_hints(responses);

View file

@ -120,7 +120,7 @@ impl JsEditorHandle {
pub fn send_tool_message(&self, tool: String, message: &JsValue) -> Result<(), JsValue> {
let tool_message = match translate_tool_type(&tool) {
Some(tool) => match tool {
ToolType::Select => match serde_wasm_bindgen::from_value::<tools::select::SelectMessage>(message.clone()) {
ToolType::Select => match serde_wasm_bindgen::from_value::<tools::select_tool::SelectToolMessage>(message.clone()) {
Ok(select_message) => Ok(ToolMessage::Select(select_message)),
Err(err) => Err(Error::new(&format!("Invalid message for {}: {}", tool, err)).into()),
},

View file

@ -1,6 +1,6 @@
use crate::consts::{F64PRECISE, RAY_FUDGE_FACTOR};
use crate::intersection::{intersections, line_curve_intersections, valid_t, Intersect, Origin};
use crate::layers::simple_shape::Shape;
use crate::layers::shape_layer::ShapeLayer;
use crate::layers::style::PathStyle;
use kurbo::{BezPath, CubicBez, Line, ParamCurve, ParamCurveArclen, ParamCurveArea, ParamCurveExtrema, PathEl, PathSeg, Point, QuadBez, Rect};
@ -377,7 +377,7 @@ impl PathGraph {
cycles
}
pub fn get_shape(&self, cycle: &Cycle, style: &PathStyle) -> Shape {
pub fn get_shape(&self, cycle: &Cycle, style: &PathStyle) -> ShapeLayer {
let mut curve = Vec::new();
let vertices = cycle.vertices();
for index in 1..vertices.len() {
@ -385,7 +385,7 @@ impl PathGraph {
concat_paths(&mut curve, &self.edge(vertices[index - 1].0, vertices[index].0, vertices[index].1).unwrap().curve);
}
curve.push(PathEl::ClosePath);
Shape::from_bez_path(BezPath::from_vec(curve), *style, false)
ShapeLayer::from_bez_path(BezPath::from_vec(curve), *style, false)
}
}
@ -455,7 +455,7 @@ pub fn subdivide_path_seg(p: &PathSeg, t_values: &mut [f64]) -> Vec<Option<PathS
// TODO: check if shapes are filled
// TODO: Bug: shape with at least two subpaths and comprised of many unions sometimes has erroneous movetos embedded in edges
pub fn boolean_operation(select: BooleanOperation, mut alpha: Shape, mut beta: Shape) -> Result<Vec<Shape>, BooleanOperationError> {
pub fn boolean_operation(select: BooleanOperation, mut alpha: ShapeLayer, mut beta: ShapeLayer) -> Result<Vec<ShapeLayer>, BooleanOperationError> {
if alpha.path.is_empty() || beta.path.is_empty() {
return Err(BooleanOperationError::InvalidSelection);
}
@ -618,7 +618,7 @@ pub fn bounding_box(curve: &BezPath) -> Rect {
.unwrap()
}
fn collect_shapes<'a, F, G>(graph: &PathGraph, cycles: &mut Vec<Cycle>, predicate: F, style: G) -> Result<Vec<Shape>, BooleanOperationError>
fn collect_shapes<'a, F, G>(graph: &PathGraph, cycles: &mut Vec<Cycle>, predicate: F, style: G) -> Result<Vec<ShapeLayer>, BooleanOperationError>
where
F: Fn(Direction) -> bool,
G: Fn(Direction) -> &'a PathStyle,

View file

@ -1,11 +1,11 @@
use crate::boolean_ops::boolean_operation;
use crate::intersection::Quad;
use crate::layers;
use crate::layers::folder::Folder;
use crate::layers::folder_layer::FolderLayer;
use crate::layers::layer_info::{Layer, LayerData, LayerDataType};
use crate::layers::simple_shape::Shape;
use crate::layers::shape_layer::ShapeLayer;
use crate::layers::style::ViewMode;
use crate::layers::text::Text;
use crate::layers::text_layer::TextLayer;
use crate::{DocumentError, DocumentResponse, Operation};
use glam::{DAffine2, DVec2};
@ -29,7 +29,7 @@ pub struct Document {
impl Default for Document {
fn default() -> Self {
Self {
root: Layer::new(LayerDataType::Folder(Folder::default()), DAffine2::IDENTITY.to_cols_array()),
root: Layer::new(LayerDataType::Folder(FolderLayer::default()), DAffine2::IDENTITY.to_cols_array()),
state_identifier: DefaultHasher::new(),
}
}
@ -60,7 +60,7 @@ impl Document {
/// Returns a reference to the requested folder. Fails if the path does not exist,
/// or if the requested layer is not of type folder.
pub fn folder(&self, path: impl AsRef<[LayerId]>) -> Result<&Folder, DocumentError> {
pub fn folder(&self, path: impl AsRef<[LayerId]>) -> Result<&FolderLayer, DocumentError> {
let mut root = &self.root;
for id in path.as_ref() {
root = root.as_folder()?.layer(*id).ok_or_else(|| DocumentError::LayerNotFound(path.as_ref().into()))?;
@ -71,7 +71,7 @@ impl Document {
/// Returns a mutable reference to the requested folder. Fails if the path does not exist,
/// or if the requested layer is not of type folder.
/// If you manually edit the folder you have to set the cache_dirty flag yourself.
fn folder_mut(&mut self, path: &[LayerId]) -> Result<&mut Folder, DocumentError> {
fn folder_mut(&mut self, path: &[LayerId]) -> Result<&mut FolderLayer, DocumentError> {
let mut root = &mut self.root;
for id in path {
root = root.as_folder_mut()?.layer_mut(*id).ok_or_else(|| DocumentError::LayerNotFound(path.into()))?;
@ -99,8 +99,8 @@ impl Document {
/// Returns vector `Shape`s for each specified in `paths`.
/// If any path is not a shape, or does not exist, `DocumentError::InvalidPath` is returned.
fn transformed_shapes(&self, paths: &[Vec<LayerId>]) -> Result<Vec<Shape>, DocumentError> {
let mut shapes: Vec<Shape> = Vec::new();
fn transformed_shapes(&self, paths: &[Vec<LayerId>]) -> Result<Vec<ShapeLayer>, DocumentError> {
let mut shapes: Vec<ShapeLayer> = Vec::new();
let undo_viewport = self.root.transform.inverse();
for path in paths {
match (self.multiply_transforms(path), &self.layer(path)?.data) {
@ -263,7 +263,7 @@ impl Document {
}
/// Visit each layer recursively, applies modify_shape to each non-overlay Shape
pub fn visit_all_shapes<F: FnMut(&mut Shape)>(layer: &mut Layer, modify_shape: &mut F) -> bool {
pub fn visit_all_shapes<F: FnMut(&mut ShapeLayer)>(layer: &mut Layer, modify_shape: &mut F) -> bool {
match layer.data {
LayerDataType::Shape(ref mut shape) => {
modify_shape(shape);
@ -434,14 +434,14 @@ impl Document {
let responses = match &operation {
Operation::AddEllipse { path, insert_index, transform, style } => {
let layer = Layer::new(LayerDataType::Shape(Shape::ellipse(*style)), *transform);
let layer = Layer::new(LayerDataType::Shape(ShapeLayer::ellipse(*style)), *transform);
self.set_layer(path, layer, *insert_index)?;
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(path)].concat())
}
Operation::AddOverlayEllipse { path, transform, style } => {
let mut ellipse = Shape::ellipse(*style);
let mut ellipse = ShapeLayer::ellipse(*style);
ellipse.render_index = -1;
let layer = Layer::new(LayerDataType::Shape(ellipse), *transform);
@ -450,14 +450,14 @@ impl Document {
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }]].concat())
}
Operation::AddRect { path, insert_index, transform, style } => {
let layer = Layer::new(LayerDataType::Shape(Shape::rectangle(*style)), *transform);
let layer = Layer::new(LayerDataType::Shape(ShapeLayer::rectangle(*style)), *transform);
self.set_layer(path, layer, *insert_index)?;
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(path)].concat())
}
Operation::AddOverlayRect { path, transform, style } => {
let mut rect = Shape::rectangle(*style);
let mut rect = ShapeLayer::rectangle(*style);
rect.render_index = -1;
let layer = Layer::new(LayerDataType::Shape(rect), *transform);
@ -466,14 +466,14 @@ impl Document {
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }]].concat())
}
Operation::AddLine { path, insert_index, transform, style } => {
let layer = Layer::new(LayerDataType::Shape(Shape::line(*style)), *transform);
let layer = Layer::new(LayerDataType::Shape(ShapeLayer::line(*style)), *transform);
self.set_layer(path, layer, *insert_index)?;
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(path)].concat())
}
Operation::AddOverlayLine { path, transform, style } => {
let mut line = Shape::line(*style);
let mut line = ShapeLayer::line(*style);
line.render_index = -1;
let layer = Layer::new(LayerDataType::Shape(line), *transform);
@ -490,7 +490,7 @@ impl Document {
style,
size,
} => {
let layer = Layer::new(LayerDataType::Text(Text::new(text.clone(), *style, *size)), *transform);
let layer = Layer::new(LayerDataType::Text(TextLayer::new(text.clone(), *style, *size)), *transform);
self.set_layer(path, layer, *insert_index)?;
@ -514,14 +514,14 @@ impl Document {
style,
sides,
} => {
let layer = Layer::new(LayerDataType::Shape(Shape::ngon(*sides, *style)), *transform);
let layer = Layer::new(LayerDataType::Shape(ShapeLayer::ngon(*sides, *style)), *transform);
self.set_layer(path, layer, *insert_index)?;
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(path)].concat())
}
Operation::AddOverlayShape { path, style, bez_path, closed } => {
let mut shape = Shape::from_bez_path(bez_path.clone(), *style, *closed);
let mut shape = ShapeLayer::from_bez_path(bez_path.clone(), *style, *closed);
shape.render_index = -1;
let layer = Layer::new(LayerDataType::Shape(shape), DAffine2::IDENTITY.to_cols_array());
@ -537,7 +537,7 @@ impl Document {
bez_path,
closed,
} => {
let shape = Shape::from_bez_path(bez_path.clone(), *style, *closed);
let shape = ShapeLayer::from_bez_path(bez_path.clone(), *style, *closed);
self.set_layer(path, Layer::new(LayerDataType::Shape(shape), *transform), *insert_index)?;
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }]].concat())
}
@ -549,7 +549,7 @@ impl Document {
style,
} => {
let points: Vec<glam::DVec2> = points.iter().map(|&it| it.into()).collect();
self.set_layer(path, Layer::new(LayerDataType::Shape(Shape::poly_line(points, *style)), *transform), *insert_index)?;
self.set_layer(path, Layer::new(LayerDataType::Shape(ShapeLayer::poly_line(points, *style)), *transform), *insert_index)?;
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(path)].concat())
}
Operation::BooleanOperation { operation, selected } => {
@ -588,11 +588,11 @@ impl Document {
style,
} => {
let points: Vec<glam::DVec2> = points.iter().map(|&it| it.into()).collect();
self.set_layer(path, Layer::new(LayerDataType::Shape(Shape::spline(points, *style)), *transform), *insert_index)?;
self.set_layer(path, Layer::new(LayerDataType::Shape(ShapeLayer::spline(points, *style)), *transform), *insert_index)?;
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(path)].concat())
}
Operation::DeleteLayer { path } => {
fn aggregate_deletions(folder: &Folder, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>) {
fn aggregate_deletions(folder: &FolderLayer, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>) {
for (id, layer) in folder.layer_ids.iter().zip(folder.layers()) {
path.push(*id);
responses.push(DocumentResponse::DeletedLayer { path: path.clone() });
@ -623,7 +623,7 @@ impl Document {
folder.add_layer(layer.clone(), Some(layer_id), *insert_index).ok_or(DocumentError::IndexOutOfBounds)?;
self.mark_as_dirty(destination_path)?;
fn aggregate_insertions(folder: &Folder, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>) {
fn aggregate_insertions(folder: &FolderLayer, path: &mut Vec<LayerId>, responses: &mut Vec<DocumentResponse>) {
for (id, layer) in folder.layer_ids.iter().zip(folder.layers()) {
path.push(*id);
responses.push(DocumentResponse::CreatedLayer { path: path.clone() });
@ -666,7 +666,7 @@ impl Document {
Some(vec![LayerChanged { path: path.clone() }])
}
Operation::CreateFolder { path } => {
self.set_layer(path, Layer::new(LayerDataType::Folder(Folder::default()), DAffine2::IDENTITY.to_cols_array()), -1)?;
self.set_layer(path, Layer::new(LayerDataType::Folder(FolderLayer::default()), DAffine2::IDENTITY.to_cols_array()), -1)?;
self.mark_as_dirty(path)?;
Some([vec![DocumentChanged, CreatedLayer { path: path.clone() }], update_thumbnails_upstream(path)].concat())
@ -705,7 +705,7 @@ impl Document {
if let LayerDataType::Text(t) = &mut self.layer_mut(path)?.data {
let bezpath = t.to_bez_path();
self.layer_mut(path)?.data = layers::layer_info::LayerDataType::Shape(Shape::from_bez_path(bezpath, t.style, true));
self.layer_mut(path)?.data = layers::layer_info::LayerDataType::Shape(ShapeLayer::from_bez_path(bezpath, t.style, true));
}
if let LayerDataType::Shape(shape) = &mut self.layer_mut(path)?.data {

View file

@ -8,13 +8,13 @@ use serde::{Deserialize, Serialize};
use std::fmt::Write;
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Default)]
pub struct Folder {
pub struct FolderLayer {
next_assignment_id: LayerId,
pub layer_ids: Vec<LayerId>,
layers: Vec<Layer>,
}
impl LayerData for Folder {
impl LayerData for FolderLayer {
fn render(&mut self, svg: &mut String, transforms: &mut Vec<glam::DAffine2>, view_mode: ViewMode) {
for layer in &mut self.layers {
let _ = writeln!(svg, "{}", layer.render(transforms, view_mode));
@ -37,7 +37,7 @@ impl LayerData for Folder {
}
}
impl Folder {
impl FolderLayer {
/// When a insertion id is provided, try to insert the layer with the given id.
/// If that id is already used, return None.
/// When no insertion id is provided, search for the next free id and insert it with that.
@ -109,7 +109,7 @@ impl Folder {
self.layer_ids.iter().position(|x| *x == layer_id).ok_or_else(|| DocumentError::LayerNotFound([layer_id].into()))
}
pub fn folder(&self, id: LayerId) -> Option<&Folder> {
pub fn folder(&self, id: LayerId) -> Option<&FolderLayer> {
match self.layer(id) {
Some(Layer {
data: LayerDataType::Folder(folder), ..
@ -118,7 +118,7 @@ impl Folder {
}
}
pub fn folder_mut(&mut self, id: LayerId) -> Option<&mut Folder> {
pub fn folder_mut(&mut self, id: LayerId) -> Option<&mut FolderLayer> {
match self.layer_mut(id) {
Some(Layer {
data: LayerDataType::Folder(folder), ..

View file

@ -1,8 +1,8 @@
use super::blend_mode::BlendMode;
use super::folder::Folder;
use super::simple_shape::Shape;
use super::folder_layer::FolderLayer;
use super::shape_layer::ShapeLayer;
use super::style::ViewMode;
use super::text::Text;
use super::text_layer::TextLayer;
use crate::intersection::Quad;
use crate::DocumentError;
use crate::LayerId;
@ -13,9 +13,9 @@ use std::fmt::Write;
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub enum LayerDataType {
Folder(Folder),
Shape(Shape),
Text(Text),
Folder(FolderLayer),
Shape(ShapeLayer),
Text(TextLayer),
}
impl LayerDataType {
@ -149,28 +149,28 @@ impl Layer {
self.current_bounding_box_with_transform(self.transform)
}
pub fn as_folder_mut(&mut self) -> Result<&mut Folder, DocumentError> {
pub fn as_folder_mut(&mut self) -> Result<&mut FolderLayer, DocumentError> {
match &mut self.data {
LayerDataType::Folder(f) => Ok(f),
_ => Err(DocumentError::NotAFolder),
}
}
pub fn as_folder(&self) -> Result<&Folder, DocumentError> {
pub fn as_folder(&self) -> Result<&FolderLayer, DocumentError> {
match &self.data {
LayerDataType::Folder(f) => Ok(f),
_ => Err(DocumentError::NotAFolder),
}
}
pub fn as_text_mut(&mut self) -> Result<&mut Text, DocumentError> {
pub fn as_text_mut(&mut self) -> Result<&mut TextLayer, DocumentError> {
match &mut self.data {
LayerDataType::Text(t) => Ok(t),
_ => Err(DocumentError::NotText),
}
}
pub fn as_text(&self) -> Result<&Text, DocumentError> {
pub fn as_text(&self) -> Result<&TextLayer, DocumentError> {
match &self.data {
LayerDataType::Text(t) => Ok(t),
_ => Err(DocumentError::NotText),

View file

@ -1,6 +1,6 @@
pub mod blend_mode;
pub mod folder;
pub mod folder_layer;
pub mod layer_info;
pub mod simple_shape;
pub mod shape_layer;
pub mod style;
pub mod text;
pub mod text_layer;

View file

@ -13,14 +13,14 @@ fn glam_to_kurbo(transform: DAffine2) -> Affine {
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct Shape {
pub struct ShapeLayer {
pub path: BezPath,
pub style: style::PathStyle,
pub render_index: i32,
pub closed: bool,
}
impl LayerData for Shape {
impl LayerData for ShapeLayer {
fn render(&mut self, svg: &mut String, transforms: &mut Vec<DAffine2>, view_mode: ViewMode) {
let mut path = self.path.clone();
let transform = self.transform(transforms, view_mode);
@ -60,7 +60,7 @@ impl LayerData for Shape {
}
}
impl Shape {
impl ShapeLayer {
pub fn transform(&self, transforms: &[DAffine2], mode: ViewMode) -> DAffine2 {
let start = match (mode, self.render_index) {
(ViewMode::Outline, _) => 0,

View file

@ -15,7 +15,7 @@ fn glam_to_kurbo(transform: DAffine2) -> Affine {
}
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
pub struct Text {
pub struct TextLayer {
pub text: String,
pub style: style::PathStyle,
pub size: f64,
@ -26,7 +26,7 @@ pub struct Text {
cached_path: Option<BezPath>,
}
impl LayerData for Text {
impl LayerData for TextLayer {
fn render(&mut self, svg: &mut String, transforms: &mut Vec<DAffine2>, view_mode: ViewMode) {
let transform = self.transform(transforms, view_mode);
let inverse = transform.inverse();
@ -84,7 +84,7 @@ impl LayerData for Text {
}
}
impl Text {
impl TextLayer {
pub fn transform(&self, transforms: &[DAffine2], mode: ViewMode) -> DAffine2 {
let start = match mode {
ViewMode::Outline => 0,