From 5a184a179cea96499cf0711dbb36ab90577ecfba Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Thu, 30 Dec 2021 23:05:54 -0800 Subject: [PATCH 1/3] Fix all clippy lint errors --- .vscode/extensions.json | 5 +- charcoal/src/lib.rs | 8 +- editor/src/communication/dispatcher.rs | 17 +- editor/src/document/document_file.rs | 13 +- .../src/document/document_message_handler.rs | 6 +- .../src/document/overlay_message_handler.rs | 4 +- editor/src/global/global_message_handler.rs | 6 - editor/src/input/keyboard.rs | 2 +- editor/src/input/mouse.rs | 1 + editor/src/tool/snapping.rs | 8 +- editor/src/tool/tools/line.rs | 2 +- editor/src/tool/tools/path.rs | 2 +- .../scrollbars/PersistentScrollbar.vue | 2 +- frontend/wasm/src/api.rs | 1 + frontend/wasm/tests/web.rs | 8 +- graphene/src/consts.rs | 2 +- graphene/src/document.rs | 26 ++- proc-macros/src/lib.rs | 150 +++++++++--------- 18 files changed, 123 insertions(+), 140 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 13a358fb61..4ca6063754 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -3,6 +3,7 @@ "matklad.rust-analyzer", "dbaeumer.vscode-eslint", "octref.vetur", - "formulahendry.auto-close-tag" + "formulahendry.auto-close-tag", + "aaron-bond.better-comments" ] -} \ No newline at end of file +} diff --git a/charcoal/src/lib.rs b/charcoal/src/lib.rs index 909562f6d5..78b81e0011 100644 --- a/charcoal/src/lib.rs +++ b/charcoal/src/lib.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod tests { - #[test] - fn it_works() { - assert_eq!(2 + 2, 4); - } + // #[test] + // fn it_works() { + // assert_eq!(2 + 2, 4); + // } } diff --git a/editor/src/communication/dispatcher.rs b/editor/src/communication/dispatcher.rs index abe519d9dd..cc7331f6c4 100644 --- a/editor/src/communication/dispatcher.rs +++ b/editor/src/communication/dispatcher.rs @@ -7,6 +7,7 @@ pub use crate::tool::ToolMessageHandler; use crate::global::GlobalMessageHandler; use std::collections::VecDeque; +#[derive(Debug, Default)] pub struct Dispatcher { input_preprocessor: InputPreprocessor, input_mapper: InputMapper, @@ -30,6 +31,10 @@ const SIDE_EFFECT_FREE_MESSAGES: &[MessageDiscriminant] = &[ ]; impl Dispatcher { + pub fn new() -> Self { + Self::default() + } + pub fn handle_message>(&mut self, message: T) { self.messages.push_back(message.into()); @@ -68,18 +73,6 @@ impl Dispatcher { list } - pub fn new() -> Dispatcher { - Dispatcher { - input_preprocessor: InputPreprocessor::default(), - global_message_handler: GlobalMessageHandler::new(), - input_mapper: InputMapper::default(), - documents_message_handler: DocumentsMessageHandler::default(), - tool_message_handler: ToolMessageHandler::default(), - messages: VecDeque::new(), - responses: vec![], - } - } - fn log_message(&self, message: &Message) { use Message::*; if log::max_level() == log::LevelFilter::Trace diff --git a/editor/src/document/document_file.rs b/editor/src/document/document_file.rs index 8d3eb01e7e..9c3789e013 100644 --- a/editor/src/document/document_file.rs +++ b/editor/src/document/document_file.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::collections::VecDeque; -use super::document_message_handler::CopyBufferEntry; pub use super::layer_panel::*; use super::movement_handler::{MovementMessage, MovementMessageHandler}; use super::overlay_message_handler::OverlayMessageHandler; @@ -187,7 +186,7 @@ impl DocumentMessageHandler { } pub fn deserialize_document(serialized_content: &str) -> Result { - log::info!("Deserialising: {:?}", serialized_content); + log::info!("Deserializing: {:?}", serialized_content); serde_json::from_str(serialized_content).map_err(|e| DocumentError::InvalidFile(e.to_string())) } @@ -210,8 +209,8 @@ impl DocumentMessageHandler { pub fn is_unmodified_default(&self) -> bool { self.serialize_root().len() == Self::default().serialize_root().len() - && self.document_undo_history.len() == 0 - && self.document_redo_history.len() == 0 + && self.document_undo_history.is_empty() + && self.document_redo_history.is_empty() && self.name.starts_with(DEFAULT_DOCUMENT_NAME) } @@ -437,7 +436,7 @@ impl DocumentMessageHandler { Some((document, layer_data)) => { let document = std::mem::replace(&mut self.graphene_document, document); let layer_data = std::mem::replace(&mut self.layer_data, layer_data); - self.document_undo_history.push((document.clone(), layer_data.clone())); + self.document_undo_history.push((document, layer_data)); Ok(()) } None => Err(EditorError::NoTransactionInProgress), @@ -645,7 +644,7 @@ impl MessageHandler for DocumentMessageHand // Fill the selection range self.layer_data .iter() - .filter(|(target, _)| self.graphene_document.layer_is_between(&target, &selected, &self.layer_range_selection_reference)) + .filter(|(target, _)| self.graphene_document.layer_is_between(target, &selected, &self.layer_range_selection_reference)) .for_each(|(layer_path, _)| { paths.push(layer_path.clone()); }); @@ -664,7 +663,7 @@ impl MessageHandler for DocumentMessageHand } // Don't create messages for empty operations - if paths.len() > 0 { + if !paths.is_empty() { // Add or set our selected layers if ctrl { responses.push_front(AddSelectedLayers(paths).into()); diff --git a/editor/src/document/document_message_handler.rs b/editor/src/document/document_message_handler.rs index 159cb06df8..fe160a6127 100644 --- a/editor/src/document/document_message_handler.rs +++ b/editor/src/document/document_message_handler.rs @@ -249,7 +249,7 @@ impl MessageHandler for DocumentsMessageHa .document_ids .iter() .filter_map(|id| { - self.documents.get(&id).map(|doc| FrontendDocumentDetails { + self.documents.get(id).map(|doc| FrontendDocumentDetails { is_saved: doc.is_saved(), id: *id, name: doc.name.clone(), @@ -314,7 +314,7 @@ impl MessageHandler for DocumentsMessageHa .document_ids .iter() .filter_map(|id| { - self.documents.get(&id).map(|doc| FrontendDocumentDetails { + self.documents.get(id).map(|doc| FrontendDocumentDetails { is_saved: doc.is_saved(), id: *id, name: doc.name.clone(), @@ -356,7 +356,7 @@ impl MessageHandler for DocumentsMessageHa self.copy_buffer[clipboard as usize].clear(); for path in paths { let document = self.active_document(); - match (document.graphene_document.layer(&path).map(|t| t.clone()), document.layer_data(&path).clone()) { + match (document.graphene_document.layer(&path).map(|t| t.clone()), *document.layer_data(&path)) { (Ok(layer), layer_data) => { self.copy_buffer[clipboard as usize].push(CopyBufferEntry { layer, layer_data }); } diff --git a/editor/src/document/overlay_message_handler.rs b/editor/src/document/overlay_message_handler.rs index 6bd3dbaed5..9088d9a0c7 100644 --- a/editor/src/document/overlay_message_handler.rs +++ b/editor/src/document/overlay_message_handler.rs @@ -30,8 +30,8 @@ pub struct OverlayMessageHandler { } impl MessageHandler for OverlayMessageHandler { - fn process_action(&mut self, message: OverlayMessage, data: (&mut LayerData, &Document, &InputPreprocessor), responses: &mut VecDeque) { - let (layer_data, document, ipp) = data; + fn process_action(&mut self, message: OverlayMessage, _data: (&mut LayerData, &Document, &InputPreprocessor), responses: &mut VecDeque) { + // let (layer_data, document, ipp) = data; use OverlayMessage::*; match message { DispatchOperation(operation) => match self.overlays_graphene_document.handle_operation(&operation) { diff --git a/editor/src/global/global_message_handler.rs b/editor/src/global/global_message_handler.rs index f447a43e94..6fe1fb1e54 100644 --- a/editor/src/global/global_message_handler.rs +++ b/editor/src/global/global_message_handler.rs @@ -13,12 +13,6 @@ pub enum GlobalMessage { #[derive(Debug, Default)] pub struct GlobalMessageHandler {} -impl GlobalMessageHandler { - pub fn new() -> Self { - Self::default() - } -} - impl MessageHandler for GlobalMessageHandler { fn process_action(&mut self, message: GlobalMessage, _data: (), _responses: &mut VecDeque) { use GlobalMessage::*; diff --git a/editor/src/input/keyboard.rs b/editor/src/input/keyboard.rs index f0ec9b99a1..3198b8cdb3 100644 --- a/editor/src/input/keyboard.rs +++ b/editor/src/input/keyboard.rs @@ -197,7 +197,7 @@ macro_rules! bit_ops { macro_rules! bit_ops_assign { ($(($op:ident, $func:ident)),* $(,)?) => { $(impl $op for BitVector { - fn $func(&mut self, right: Self) { + fn $func(&mut self, right: Self) { for (left, right) in self.0.iter_mut().zip(right.0.iter()) { $op::$func(left, right); } diff --git a/editor/src/input/mouse.rs b/editor/src/input/mouse.rs index ca1d514b83..023a9a3560 100644 --- a/editor/src/input/mouse.rs +++ b/editor/src/input/mouse.rs @@ -31,6 +31,7 @@ impl ViewportBounds { #[derive(Debug, Copy, Clone, Default, Eq, PartialEq, Hash, Serialize, Deserialize)] pub struct ScrollDelta { + // TODO: Switch these to `f64` values (not trivial because floats don't provide PartialEq, Eq, and Hash) pub x: i32, pub y: i32, pub z: i32, diff --git a/editor/src/tool/snapping.rs b/editor/src/tool/snapping.rs index 3f4792faa5..1597361bc9 100644 --- a/editor/src/tool/snapping.rs +++ b/editor/src/tool/snapping.rs @@ -58,13 +58,11 @@ impl SnapHandler { .unwrap_or(0.), ); - // Do not move if over snap tolerance - let clamped_closest_move = DVec2::new( + // Clamp, do not move if over snap tolerance + DVec2::new( if closest_move.x.abs() > SNAP_TOLERANCE { 0. } else { closest_move.x }, if closest_move.y.abs() > SNAP_TOLERANCE { 0. } else { closest_move.y }, - ); - - clamped_closest_move + ) } else { DVec2::ZERO } diff --git a/editor/src/tool/tools/line.rs b/editor/src/tool/tools/line.rs index 8053ce1976..c348a8d6b6 100644 --- a/editor/src/tool/tools/line.rs +++ b/editor/src/tool/tools/line.rs @@ -42,7 +42,7 @@ impl<'a> MessageHandler> for Line { fn actions(&self) -> ActionList { use LineToolFsmState::*; match self.fsm_state { - Ready => actions!(LineMessageDiscriminant; DragStart), + Ready => actions!(LineMessageDiscriminant; DragStart), Drawing => actions!(LineMessageDiscriminant; DragStop, Redraw, Abort), } } diff --git a/editor/src/tool/tools/path.rs b/editor/src/tool/tools/path.rs index 24fafc225a..713acb539d 100644 --- a/editor/src/tool/tools/path.rs +++ b/editor/src/tool/tools/path.rs @@ -303,7 +303,7 @@ impl Fsm for PathToolFsmState { } } -fn calculate_total_overlays_per_type(shapes_to_draw: &Vec) -> (usize, usize, usize) { +fn calculate_total_overlays_per_type(shapes_to_draw: &[VectorManipulatorShape]) -> (usize, usize, usize) { let (mut total_anchors, mut total_handles, mut total_anchor_handle_lines) = (0, 0, 0); for shape_to_draw in shapes_to_draw { diff --git a/frontend/src/components/widgets/scrollbars/PersistentScrollbar.vue b/frontend/src/components/widgets/scrollbars/PersistentScrollbar.vue index 617d58f0df..6b3d89e6fc 100644 --- a/frontend/src/components/widgets/scrollbars/PersistentScrollbar.vue +++ b/frontend/src/components/widgets/scrollbars/PersistentScrollbar.vue @@ -114,7 +114,7 @@ import { defineComponent, PropType } from "vue"; const lerp = (x: number, y: number, a: number) => x * (1 - a) + y * a; // Convert the position of the handle (0-1) to the position on the track (0-1). -// This includes the 1/2 handle length gap of the possible handle positionson each side so the end of the handle doesn't go off the track. +// This includes the 1/2 handle length gap of the possible handle positionson each side so the end of the handle doesn't go off the track. const handleToTrack = (handleLen: number, handlePos: number) => lerp(handleLen / 2, 1 - handleLen / 2, handlePos); const pointerPosition = (direction: ScrollbarDirection, e: PointerEvent) => (direction === ScrollbarDirection.Vertical ? e.clientY : e.clientX); diff --git a/frontend/wasm/src/api.rs b/frontend/wasm/src/api.rs index e4c49a40d6..fd4b0be7b1 100644 --- a/frontend/wasm/src/api.rs +++ b/frontend/wasm/src/api.rs @@ -32,6 +32,7 @@ pub struct JsEditorHandle { } #[wasm_bindgen] +#[allow(clippy::too_many_arguments)] impl JsEditorHandle { #[wasm_bindgen(constructor)] pub fn new(handle_response: js_sys::Function) -> Self { diff --git a/frontend/wasm/tests/web.rs b/frontend/wasm/tests/web.rs index db945dfdce..b8e2cd5047 100644 --- a/frontend/wasm/tests/web.rs +++ b/frontend/wasm/tests/web.rs @@ -4,7 +4,7 @@ use wasm_bindgen_test::*; wasm_bindgen_test_configure!(run_in_browser); -#[wasm_bindgen_test] -fn pass() { - assert_eq!(1 + 1, 2); -} +// #[wasm_bindgen_test] +// fn pass() { +// assert_eq!(1 + 1, 2); +// } diff --git a/graphene/src/consts.rs b/graphene/src/consts.rs index a89da61cde..ed30f48d5b 100644 --- a/graphene/src/consts.rs +++ b/graphene/src/consts.rs @@ -1,7 +1,7 @@ use crate::color::Color; // Document -pub const GRAPHENE_DOCUMENT_VERSION: &'static str = "0.0.1"; +pub const GRAPHENE_DOCUMENT_VERSION: &str = "0.0.1"; // RENDERING pub const LAYER_OUTLINE_STROKE_COLOR: Color = Color::BLACK; diff --git a/graphene/src/document.rs b/graphene/src/document.rs index 90c4517f55..002a72c54f 100644 --- a/graphene/src/document.rs +++ b/graphene/src/document.rs @@ -115,7 +115,7 @@ impl Document { // Determines which layer is closer to the root, if path_a return true, if path_b return false // Answers the question: Is A closer to the root than B? - pub fn layer_closer_to_root(&self, path_a: &Vec, path_b: &Vec) -> bool { + pub fn layer_closer_to_root(&self, path_a: &[u64], path_b: &[u64]) -> bool { // Convert UUIDs to indices let indices_for_path_a = self.indices_for_path(path_a).unwrap(); let indices_for_path_b = self.indices_for_path(path_b).unwrap(); @@ -126,24 +126,20 @@ impl Document { let index_a = *indices_for_path_a.get(i).unwrap_or(&usize::MAX) as i32; let index_b = *indices_for_path_b.get(i).unwrap_or(&usize::MAX) as i32; - // index_a == index_b -> true, this means the "2" indices being compared are within the same folder - // eg -> [2, X] == [2, X] since we are only comparing the "2" in this iteration - // Continue onto comparing the X indices. - if index_a == index_b { - continue; + // At the point at which the two paths first differ, compare to see which is closer to the root + if index_a != index_b { + // If index_a is smaller, index_a is closer to the root + return index_a < index_b; } - - // If index_a is smaller, index_a is closer to the root - return index_a < index_b; } - return false; + false } - // Is the target layer between a <-> b layers, inclusive - pub fn layer_is_between(&self, target: &Vec, path_a: &Vec, path_b: &Vec) -> bool { + // Is the target layer between a <-> b layers, inclusive + pub fn layer_is_between(&self, target: &[u64], path_a: &[u64], path_b: &[u64]) -> bool { // If the target is a nonsense path, it isn't between - if target.len() < 1 { + if target.is_empty() { return false; } @@ -156,8 +152,8 @@ impl Document { let layer_vs_a = self.layer_closer_to_root(target, path_a); let layer_vs_b = self.layer_closer_to_root(target, path_b); - // To be inbetween you need to be above A and below B or vice versa - return layer_vs_a != layer_vs_b; + // To be in-between you need to be above A and below B or vice versa + layer_vs_a != layer_vs_b } /// Given a path to a layer, returns a vector of the indices in the layer tree diff --git a/proc-macros/src/lib.rs b/proc-macros/src/lib.rs index 7b99851a0c..5067a74dbe 100644 --- a/proc-macros/src/lib.rs +++ b/proc-macros/src/lib.rs @@ -19,12 +19,12 @@ use syn::parse_macro_input; /// /// This derive macro is enum-only. /// -/// The discriminant enum is a copy of the input enum with all fields of every variant removed.\ -/// *) The exception to that rule is the `#[child]` attribute +/// The discriminant enum is a copy of the input enum with all fields of every variant removed. +/// The exception to that rule is the `#[child]` attribute. /// /// # Helper attributes /// - `#[sub_discriminant]`: only usable on variants with a single field; instead of no fields, the discriminant of the single field will be included in the discriminant, -/// acting as a sub-discriminant. +/// acting as a sub-discriminant. /// - `#[discriminant_attr(…)]`: usable on the enum itself or on any variant; applies `#[…]` in its place on the discriminant. /// /// # Attributes on the Discriminant @@ -40,20 +40,20 @@ use syn::parse_macro_input; /// #[derive(ToDiscriminant)] /// #[discriminant_attr(derive(Debug, Eq, PartialEq))] /// pub enum EnumA { -/// A(u8), -/// #[sub_discriminant] -/// B(EnumB) +/// A(u8), +/// #[sub_discriminant] +/// B(EnumB) /// } /// /// #[derive(ToDiscriminant)] /// #[discriminant_attr(derive(Debug, Eq, PartialEq))] /// #[discriminant_attr(repr(u8))] /// pub enum EnumB { -/// Foo(u8), -/// Bar(String), -/// #[cfg(feature = "some-feature")] -/// #[discriminant_attr(cfg(feature = "some-feature"))] -/// WindowsBar(OsString) +/// Foo(u8), +/// Bar(String), +/// #[cfg(feature = "some-feature")] +/// #[discriminant_attr(cfg(feature = "some-feature"))] +/// WindowsBar(OsString) /// } /// /// let a = EnumA::A(1); @@ -73,7 +73,7 @@ pub fn derive_discriminant(input_item: TokenStream) -> TokenStream { /// /// # Helper Attributes /// - `#[parent(, )]` (**required**): declare the parent type (``) -/// and a function (``, has to evaluate to a single arg function) for converting a value of this type to the parent type +/// and a function (``, has to evaluate to a single arg function) for converting a value of this type to the parent type /// - `#[parent_is_top]`: Denote that the parent type has no further parent type (this is required because otherwise the `From` impls for parent and top parent would overlap) /// /// # Example @@ -85,23 +85,23 @@ pub fn derive_discriminant(input_item: TokenStream) -> TokenStream { /// struct A { u: u8, b: B }; /// /// impl A { -/// pub fn from_b(b: B) -> Self { -/// Self { u: 7, b } -/// } +/// pub fn from_b(b: B) -> Self { +/// Self { u: 7, b } +/// } /// } /// /// impl TransitiveChild for A { -/// type Parent = Self; -/// type TopParent = Self; +/// type Parent = Self; +/// type TopParent = Self; /// } /// /// #[derive(TransitiveChild, Debug, Eq, PartialEq)] /// #[parent(A, A::from_b)] /// #[parent_is_top] /// enum B { -/// Foo, -/// Bar, -/// Child(C) +/// Foo, +/// Bar, +/// Child(C) /// } /// /// #[derive(TransitiveChild, Debug, Eq, PartialEq)] @@ -134,41 +134,41 @@ pub fn derive_transitive_child(input_item: TokenStream) -> TokenStream { /// /// #[derive(AsMessage)] /// pub enum TopMessage { -/// A(u8), -/// B(u16), -/// #[child] -/// C(MessageC), -/// #[child] -/// D(MessageD) +/// A(u8), +/// B(u16), +/// #[child] +/// C(MessageC), +/// #[child] +/// D(MessageD) /// } /// /// impl TransitiveChild for TopMessage { -/// type Parent = Self; -/// type TopParent = Self; +/// type Parent = Self; +/// type TopParent = Self; /// } /// /// #[derive(TransitiveChild, AsMessage, Copy, Clone)] /// #[parent(TopMessage, TopMessage::C)] /// #[parent_is_top] /// pub enum MessageC { -/// X1, -/// X2 +/// X1, +/// X2 /// } /// /// #[derive(TransitiveChild, AsMessage, Copy, Clone)] /// #[parent(TopMessage, TopMessage::D)] /// #[parent_is_top] /// pub enum MessageD { -/// Y1, -/// #[child] -/// Y2(MessageE) +/// Y1, +/// #[child] +/// Y2(MessageE) /// } /// /// #[derive(TransitiveChild, AsMessage, Copy, Clone)] /// #[parent(MessageD, MessageD::Y2)] /// pub enum MessageE { -/// Alpha, -/// Beta +/// Alpha, +/// Beta /// } /// /// let c = MessageC::X1; @@ -195,18 +195,18 @@ pub fn derive_message(input_item: TokenStream) -> TokenStream { /// # Usage /// There are three possible argument syntaxes you can use: /// 1. no arguments: this is for the top-level message enum. It derives `ToDiscriminant`, `AsMessage` on the discriminant, and implements `TransitiveChild` on both -/// (the parent and top parent being the respective types themselves). -/// It also derives the following `std` traits on the discriminant: `Debug, Copy, Clone, PartialEq, Eq, Hash`. +/// (the parent and top parent being the respective types themselves). +/// It also derives the following `std` traits on the discriminant: `Debug, Copy, Clone, PartialEq, Eq, Hash`. /// 2. two arguments: this is for message enums whose direct parent is the top level message enum. The syntax is `#[impl_message(, )]`, -/// where `` is the parent message type and `` is the identifier of the variant used to construct this child. -/// It derives `ToDiscriminant`, `AsMessage` on the discriminant, and `TransitiveChild` on both (adding `#[parent_is_top]` to both). -/// It also derives the following `std` traits on the discriminant: `Debug, Copy, Clone, PartialEq, Eq, Hash`. +/// where `` is the parent message type and `` is the identifier of the variant used to construct this child. +/// It derives `ToDiscriminant`, `AsMessage` on the discriminant, and `TransitiveChild` on both (adding `#[parent_is_top]` to both). +/// It also derives the following `std` traits on the discriminant: `Debug, Copy, Clone, PartialEq, Eq, Hash`. /// 3. three arguments: this is for all other message enums that are transitive children of the top level message enum. The syntax is -/// `#[impl_message(, , )]`, where the first `` is the top parent message type, the second `` is the parent message type -/// and `` is the identifier of the variant used to construct this child. -/// It derives `ToDiscriminant`, `AsMessage` on the discriminant, and `TransitiveChild` on both. -/// It also derives the following `std` traits on the discriminant: `Debug, Copy, Clone, PartialEq, Eq, Hash`. -/// **This third option will likely change in the future** +/// `#[impl_message(, , )]`, where the first `` is the top parent message type, the second `` is the parent message type +/// and `` is the identifier of the variant used to construct this child. +/// It derives `ToDiscriminant`, `AsMessage` on the discriminant, and `TransitiveChild` on both. +/// It also derives the following `std` traits on the discriminant: `Debug, Copy, Clone, PartialEq, Eq, Hash`. +/// **This third option will likely change in the future** #[proc_macro_attribute] pub fn impl_message(attr: TokenStream, input_item: TokenStream) -> TokenStream { TokenStream::from(combined_message_attrs_impl(attr.into(), input_item.into()).unwrap_or_else(|err| err.to_compile_error())) @@ -221,12 +221,12 @@ pub fn impl_message(attr: TokenStream, input_item: TokenStream) -> TokenStream { /// /// #[derive(Hint)] /// pub enum StateMachine { -/// #[hint(rmb = "foo", lmb = "bar")] -/// Ready, -/// #[hint(alt = "baz")] -/// RMBDown, -/// // no hint (also ok) -/// LMBDown +/// #[hint(rmb = "foo", lmb = "bar")] +/// Ready, +/// #[hint(alt = "baz")] +/// RMBDown, +/// // no hint (also ok) +/// LMBDown /// } /// ``` #[proc_macro_derive(Hint, attributes(hint))] @@ -239,30 +239,30 @@ pub fn derive_hint(input_item: TokenStream) -> TokenStream { /// # Example /// ```ignore /// match (example_tool_state, event) { -/// (ToolState::Ready, Event::MouseDown(mouse_state)) if *mouse_state == MouseState::Left => { -/// #[edge("LMB Down")] -/// ToolState::Pending -/// } -/// (SelectToolState::Pending, Event::MouseUp(mouse_state)) if *mouse_state == MouseState::Left => { -/// #[edge("LMB Up: Select Object")] -/// SelectToolState::Ready -/// } -/// (SelectToolState::Pending, Event::MouseMove(x,y)) => { -/// #[edge("Mouse Move")] -/// SelectToolState::TransformSelected -/// } -/// (SelectToolState::TransformSelected, Event::MouseMove(x,y)) => { -/// #[egde("Mouse Move")] -/// SelectToolState::TransformSelected -/// } -/// (SelectToolState::TransformSelected, Event::MouseUp(mouse_state)) if *mouse_state == MouseState::Left => { -/// #[edge("LMB Up")] -/// SelectToolState::Ready -/// } -/// (state, _) => { -/// // Do nothing -/// state -/// } +/// (ToolState::Ready, Event::MouseDown(mouse_state)) if *mouse_state == MouseState::Left => { +/// #[edge("LMB Down")] +/// ToolState::Pending +/// } +/// (SelectToolState::Pending, Event::MouseUp(mouse_state)) if *mouse_state == MouseState::Left => { +/// #[edge("LMB Up: Select Object")] +/// SelectToolState::Ready +/// } +/// (SelectToolState::Pending, Event::MouseMove(x,y)) => { +/// #[edge("Mouse Move")] +/// SelectToolState::TransformSelected +/// } +/// (SelectToolState::TransformSelected, Event::MouseMove(x,y)) => { +/// #[edge("Mouse Move")] +/// SelectToolState::TransformSelected +/// } +/// (SelectToolState::TransformSelected, Event::MouseUp(mouse_state)) if *mouse_state == MouseState::Left => { +/// #[edge("LMB Up")] +/// SelectToolState::Ready +/// } +/// (state, _) => { +/// // Do nothing +/// state +/// } /// } /// ``` #[proc_macro_attribute] From 90d725f682e36f8bd33c431beb77ef4e237de93f Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Fri, 31 Dec 2021 00:02:29 -0800 Subject: [PATCH 2/3] Rename Editor's LayerData to LayerMetadata --- editor/src/document/document_file.rs | 109 +++++++++--------- .../src/document/document_message_handler.rs | 24 ++-- editor/src/document/layer_panel.rs | 22 ++-- editor/src/document/mod.rs | 4 +- .../src/document/overlay_message_handler.rs | 8 +- .../src/document/transform_layer_handler.rs | 14 +-- ...yerdata.rs => vectorize_layer_metadata.rs} | 0 frontend/src/components/panels/LayerTree.vue | 10 +- frontend/src/dispatcher/js-messages.ts | 6 +- graphene/src/layers/mod.rs | 13 +-- 10 files changed, 105 insertions(+), 105 deletions(-) rename editor/src/document/{vectorize_layerdata.rs => vectorize_layer_metadata.rs} (100%) diff --git a/editor/src/document/document_file.rs b/editor/src/document/document_file.rs index 9c3789e013..f33fb1404f 100644 --- a/editor/src/document/document_file.rs +++ b/editor/src/document/document_file.rs @@ -5,7 +5,7 @@ pub use super::layer_panel::*; use super::movement_handler::{MovementMessage, MovementMessageHandler}; use super::overlay_message_handler::OverlayMessageHandler; use super::transform_layer_handler::{TransformLayerMessage, TransformLayerMessageHandler}; -use super::vectorize_layerdata; +use super::vectorize_layer_metadata; use crate::consts::DEFAULT_DOCUMENT_NAME; use crate::consts::{ASYMPTOTIC_EFFECT, FILE_EXPORT_SUFFIX, FILE_SAVE_SUFFIX, SCALE_EFFECT, SCROLLBAR_SPACING}; @@ -24,7 +24,7 @@ use kurbo::PathSeg; use log::warn; use serde::{Deserialize, Serialize}; -type DocumentSave = (GrapheneDocument, HashMap, LayerData>); +type DocumentSave = (GrapheneDocument, HashMap, LayerMetadata>); #[derive(PartialEq, Clone, Debug, Serialize, Deserialize, Hash)] pub enum FlipAxis { @@ -69,8 +69,8 @@ pub struct DocumentMessageHandler { pub document_redo_history: Vec, pub saved_document_identifier: u64, pub name: String, - #[serde(with = "vectorize_layerdata")] - pub layer_data: HashMap, LayerData>, + #[serde(with = "vectorize_layer_metadata")] + pub layer_metadata: HashMap, LayerMetadata>, layer_range_selection_reference: Vec, #[serde(skip)] movement_handler: MovementMessageHandler, @@ -90,7 +90,7 @@ impl Default for DocumentMessageHandler { document_redo_history: Vec::new(), name: String::from("Untitled Document"), saved_document_identifier: 0, - layer_data: vec![(vec![], LayerData::new(true))].into_iter().collect(), + layer_metadata: vec![(vec![], LayerMetadata::new(true))].into_iter().collect(), layer_range_selection_reference: Vec::new(), movement_handler: MovementMessageHandler::default(), overlay_message_handler: OverlayMessageHandler::default(), @@ -111,9 +111,9 @@ pub enum DocumentMessage { DispatchOperation(Box), #[child] Overlay(OverlayMessage), - UpdateLayerData { - path: Vec, - layer_data_entry: LayerData, + UpdateLayerMetadata { + layer_path: Vec, + layer_metadata: LayerMetadata, }, SetSelectedLayers(Vec>), AddSelectedLayers(Vec>), @@ -217,7 +217,7 @@ impl DocumentMessageHandler { fn select_layer(&mut self, path: &[LayerId]) -> Option { println!("Select_layer fail: {:?}", self.all_layers_sorted()); - self.layer_data_mut(path).selected = true; + self.layer_metadata_mut(path).selected = true; let data = self.layer_panel_entry(path.to_vec()).ok()?; (!path.is_empty()).then(|| FrontendMessage::UpdateLayer { data }.into()) } @@ -269,12 +269,8 @@ impl DocumentMessageHandler { shapes.collect::>() } - pub fn create_layer_data(&mut self, path: &[LayerId]) { - self.layer_data.insert(path.to_vec(), LayerData::new(true)); - } - pub fn selected_layers(&self) -> impl Iterator { - self.layer_data.iter().filter_map(|(path, data)| data.selected.then(|| path.as_slice())) + self.layer_metadata.iter().filter_map(|(path, data)| data.selected.then(|| path.as_slice())) } pub fn selected_visible_layers(&self) -> impl Iterator { @@ -293,7 +289,7 @@ impl DocumentMessageHandler { LayerDataType::Shape(_) => (), LayerDataType::Folder(ref folder) => { path.push(*id); - if self.layer_data(path).expanded { + if self.layer_metadata(path).expanded { structure.push(space); self.serialize_structure(folder, structure, data, path); space = 0; @@ -339,7 +335,7 @@ impl DocumentMessageHandler { /// Returns an unsorted list of all layer paths including folders at all levels, except the document's top-level root folder itself pub fn all_layers(&self) -> Vec> { - self.layer_data.keys().filter(|path| !path.is_empty()).cloned().collect() + self.layer_metadata.keys().filter(|path| !path.is_empty()).cloned().collect() } /// Returns the paths to all layers in order, optionally including only selected or non-selected layers. @@ -347,14 +343,13 @@ impl DocumentMessageHandler { // Compute the indices for each layer to be able to sort them let mut layers_with_indices: Vec<(Vec, Vec)> = self - .layer_data + .layer_metadata .iter() // 'path.len() > 0' filters out root layer since it has no indices .filter_map(|(path, data)| (!path.is_empty() && (data.selected == selected.unwrap_or(data.selected))).then(|| path.clone())) .filter_map(|path| { - // Currently it is possible that layer_data contains layers that are don't actually exist (has been partially fixed in #281) - // and thus indices_for_path can return an error. We currently skip these layers and log a warning. - // Once this problem is solved this code can be simplified + // TODO: Currently it is possible that `layer_metadata` contains layers that are don't actually exist (has been partially fixed in #281) and thus + // TODO: `indices_for_path` can return an error. We currently skip these layers and log a warning. Once this problem is solved this code can be simplified. match self.graphene_document.indices_for_path(&path) { Err(err) => { warn!("layers_sorted: Could not get indices for the layer {:?}: {:?}", path, err); @@ -385,23 +380,23 @@ impl DocumentMessageHandler { self.layers_sorted(Some(false)) } - pub fn layer_data(&self, path: &[LayerId]) -> &LayerData { - self.layer_data.get(path).expect("Layerdata does not exist") + pub fn layer_metadata(&self, path: &[LayerId]) -> &LayerMetadata { + self.layer_metadata.get(path).unwrap_or_else(|| panic!("Editor's layer metadata for {:?} does not exist", path)) } - pub fn layer_data_mut(&mut self, path: &[LayerId]) -> &mut LayerData { - Self::layer_data_mut_no_borrow_self(&mut self.layer_data, path) + pub fn layer_metadata_mut(&mut self, path: &[LayerId]) -> &mut LayerMetadata { + Self::layer_metadata_mut_no_borrow_self(&mut self.layer_metadata, path) } - pub fn layer_data_mut_no_borrow_self<'a>(layer_data: &'a mut HashMap, LayerData>, path: &[LayerId]) -> &'a mut LayerData { - layer_data + pub fn layer_metadata_mut_no_borrow_self<'a>(layer_metadata: &'a mut HashMap, LayerMetadata>, path: &[LayerId]) -> &'a mut LayerMetadata { + layer_metadata .get_mut(path) .unwrap_or_else(|| panic!("Layer data cannot be found because the path {:?} does not exist", path)) } pub fn backup(&mut self, responses: &mut VecDeque) { self.document_redo_history.clear(); - self.document_undo_history.push((self.graphene_document.clone(), self.layer_data.clone())); + self.document_undo_history.push((self.graphene_document.clone(), self.layer_metadata.clone())); // Push the UpdateOpenDocumentsList message to the bus in order to update the save status of the open documents responses.push_back(DocumentsMessage::UpdateOpenDocumentsList.into()); @@ -418,10 +413,10 @@ impl DocumentMessageHandler { responses.push_back(DocumentsMessage::UpdateOpenDocumentsList.into()); match self.document_undo_history.pop() { - Some((document, layer_data)) => { + Some((document, layer_metadata)) => { let document = std::mem::replace(&mut self.graphene_document, document); - let layer_data = std::mem::replace(&mut self.layer_data, layer_data); - self.document_redo_history.push((document, layer_data)); + let layer_metadata = std::mem::replace(&mut self.layer_metadata, layer_metadata); + self.document_redo_history.push((document, layer_metadata)); Ok(()) } None => Err(EditorError::NoTransactionInProgress), @@ -433,10 +428,10 @@ impl DocumentMessageHandler { responses.push_back(DocumentsMessage::UpdateOpenDocumentsList.into()); match self.document_redo_history.pop() { - Some((document, layer_data)) => { + Some((document, layer_metadata)) => { let document = std::mem::replace(&mut self.graphene_document, document); - let layer_data = std::mem::replace(&mut self.layer_data, layer_data); - self.document_undo_history.push((document, layer_data)); + let layer_metadata = std::mem::replace(&mut self.layer_metadata, layer_metadata); + self.document_undo_history.push((document, layer_metadata)); Ok(()) } None => Err(EditorError::NoTransactionInProgress), @@ -465,7 +460,7 @@ impl DocumentMessageHandler { } pub fn layer_panel_entry(&mut self, path: Vec) -> Result { - let data: LayerData = *self.layer_data_mut(&path); + let data: LayerMetadata = *self.layer_metadata_mut(&path); let layer = self.graphene_document.layer(&path)?; let entry = layer_panel_entry(&data, self.graphene_document.multiply_transforms(&path)?, layer, path); Ok(entry) @@ -481,14 +476,14 @@ impl DocumentMessageHandler { } pub fn layer_panel_entry_from_path(&self, path: &[LayerId]) -> Option { - let layer_data = self.layer_data(path); + let layer_metadata = self.layer_metadata(path); let transform = self .graphene_document .generate_transform_across_scope(path, Some(self.graphene_document.root.transform.inverse())) .ok()?; let layer = self.graphene_document.layer(path).ok()?; - Some(layer_panel_entry(layer_data, transform, layer, path.to_vec())) + Some(layer_panel_entry(layer_metadata, transform, layer, path.to_vec())) } } @@ -499,7 +494,7 @@ impl MessageHandler for DocumentMessageHand Movement(message) => self.movement_handler.process_action(message, (&self.graphene_document, ipp), responses), TransformLayers(message) => self .transform_layer_handler - .process_action(message, (&mut self.layer_data, &mut self.graphene_document, ipp), responses), + .process_action(message, (&mut self.layer_metadata, &mut self.graphene_document, ipp), responses), DeleteLayer(path) => responses.push_back(DocumentOperation::DeleteLayer { path }.into()), StartTransaction => self.backup(responses), RollbackTransaction => { @@ -512,8 +507,11 @@ impl MessageHandler for DocumentMessageHand } CommitTransaction => (), Overlay(message) => { - self.overlay_message_handler - .process_action(message, (Self::layer_data_mut_no_borrow_self(&mut self.layer_data, &[]), &self.graphene_document, ipp), responses); + self.overlay_message_handler.process_action( + message, + (Self::layer_metadata_mut_no_borrow_self(&mut self.layer_metadata, &[]), &self.graphene_document, ipp), + responses, + ); // responses.push_back(OverlayMessage::RenderOverlays.into()); } ExportDocument => { @@ -588,7 +586,7 @@ impl MessageHandler for DocumentMessageHand } SetBlendModeForSelectedLayers(blend_mode) => { self.backup(responses); - for path in self.layer_data.iter().filter_map(|(path, data)| data.selected.then(|| path.clone())) { + for path in self.layer_metadata.iter().filter_map(|(path, data)| data.selected.then(|| path.clone())) { responses.push_back(DocumentOperation::SetLayerBlendMode { path, blend_mode }.into()); } } @@ -605,12 +603,12 @@ impl MessageHandler for DocumentMessageHand responses.push_back(ToolMessage::DocumentIsDirty.into()); } ToggleLayerExpansion(path) => { - self.layer_data_mut(&path).expanded ^= true; + self.layer_metadata_mut(&path).expanded ^= true; responses.push_back(DocumentStructureChanged.into()); responses.push_back(LayerChanged(path).into()) } SetLayerExpansion(path, is_expanded) => { - self.layer_data_mut(&path).expanded = is_expanded; + self.layer_metadata_mut(&path).expanded = is_expanded; responses.push_back(DocumentStructureChanged.into()); responses.push_back(LayerChanged(path).into()) } @@ -642,7 +640,7 @@ impl MessageHandler for DocumentMessageHand // If we have shift pressed and a layer already selected then fill the range if shift && last_selection_exists { // Fill the selection range - self.layer_data + self.layer_metadata .iter() .filter(|(target, _)| self.graphene_document.layer_is_between(target, &selected, &self.layer_range_selection_reference)) .for_each(|(layer_path, _)| { @@ -651,7 +649,7 @@ impl MessageHandler for DocumentMessageHand } else { if ctrl { // Toggle selection when holding ctrl - let layer = self.layer_data_mut(&selected); + let layer = self.layer_metadata_mut(&selected); layer.selected = !layer.selected; responses.push_back(LayerChanged(selected.clone()).into()); } else { @@ -672,12 +670,13 @@ impl MessageHandler for DocumentMessageHand } } } - UpdateLayerData { path, layer_data_entry } => { - self.layer_data.insert(path, layer_data_entry); + UpdateLayerMetadata { layer_path: path, layer_metadata } => { + self.layer_metadata.insert(path, layer_metadata); } SetSelectedLayers(paths) => { - self.layer_data.iter_mut().filter(|(_, layer_data)| layer_data.selected).for_each(|(path, layer_data)| { - layer_data.selected = false; + let selected = self.layer_metadata.iter_mut().filter(|(_, layer_metadata)| layer_metadata.selected); + selected.for_each(|(path, layer_metadata)| { + layer_metadata.selected = false; responses.push_back(LayerChanged(path.clone()).into()) }); @@ -692,7 +691,7 @@ impl MessageHandler for DocumentMessageHand responses.push_back(ToolMessage::DocumentIsDirty.into()); } DebugPrintDocument => { - log::debug!("{:#?}\n{:#?}", self.graphene_document, self.layer_data); + log::debug!("{:#?}\n{:#?}", self.graphene_document, self.layer_metadata); } SelectAllLayers => { let all_layer_paths = self.all_layers(); @@ -737,11 +736,11 @@ impl MessageHandler for DocumentMessageHand match &response { DocumentResponse::FolderChanged { path } => responses.push_back(FolderChanged(path.clone()).into()), DocumentResponse::DeletedLayer { path } => { - self.layer_data.remove(path); + self.layer_metadata.remove(path); } DocumentResponse::LayerChanged { path } => responses.push_back(LayerChanged(path.clone()).into()), DocumentResponse::CreatedLayer { path } => { - self.layer_data.insert(path.clone(), LayerData::new(false)); + self.layer_metadata.insert(path.clone(), LayerMetadata::new(false)); responses.push_back(LayerChanged(path.clone()).into()); self.layer_range_selection_reference = path.clone(); responses.push_back(SetSelectedLayers(vec![path.clone()]).into()); @@ -953,9 +952,9 @@ impl MessageHandler for DocumentMessageHand .into(), ); responses.push_back( - DocumentMessage::UpdateLayerData { - path: destination_path, - layer_data_entry: *self.layer_data(&target_layer), + DocumentMessage::UpdateLayerMetadata { + layer_path: destination_path, + layer_metadata: *self.layer_metadata(&target_layer), } .into(), ); @@ -983,7 +982,7 @@ impl MessageHandler for DocumentMessageHand MoveLayerInTree, ); - if self.layer_data.values().any(|data| data.selected) { + if self.layer_metadata.values().any(|data| data.selected) { let select = actions!(DocumentMessageDiscriminant; DeleteSelectedLayers, DuplicateSelectedLayers, diff --git a/editor/src/document/document_message_handler.rs b/editor/src/document/document_message_handler.rs index fe160a6127..7ece129f1b 100644 --- a/editor/src/document/document_message_handler.rs +++ b/editor/src/document/document_message_handler.rs @@ -1,4 +1,4 @@ -use super::{DocumentMessageHandler, LayerData}; +use super::{DocumentMessageHandler, LayerMetadata}; use crate::consts::DEFAULT_DOCUMENT_NAME; use crate::frontend::frontend_message_handler::FrontendDocumentDetails; use crate::input::InputPreprocessor; @@ -68,7 +68,7 @@ pub struct DocumentsMessageHandler { #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct CopyBufferEntry { layer: Layer, - layer_data: LayerData, + layer_metadata: LayerMetadata, } impl DocumentsMessageHandler { @@ -121,7 +121,7 @@ impl DocumentsMessageHandler { responses.extend( new_document - .layer_data + .layer_metadata .keys() .filter_map(|path| new_document.layer_panel_entry_from_path(path)) .map(|entry| FrontendMessage::UpdateLayer { data: entry }.into()) @@ -193,7 +193,7 @@ impl MessageHandler for DocumentsMessageHa responses.push_back(FrontendMessage::SetActiveDocument { document_id: id }.into()); responses.push_back(RenderDocument.into()); responses.push_back(DocumentMessage::DocumentStructureChanged.into()); - for layer in self.active_document().layer_data.keys() { + for layer in self.active_document().layer_metadata.keys() { responses.push_back(DocumentMessage::LayerChanged(layer.clone()).into()); } } @@ -262,7 +262,7 @@ impl MessageHandler for DocumentsMessageHa responses.push_back(FrontendMessage::RemoveAutoSaveDocument { document_id: id }.into()); responses.push_back(RenderDocument.into()); responses.push_back(DocumentMessage::DocumentStructureChanged.into()); - for layer in self.active_document().layer_data.keys() { + for layer in self.active_document().layer_metadata.keys() { responses.push_back(DocumentMessage::LayerChanged(layer.clone()).into()); } } @@ -356,9 +356,9 @@ impl MessageHandler for DocumentsMessageHa self.copy_buffer[clipboard as usize].clear(); for path in paths { let document = self.active_document(); - match (document.graphene_document.layer(&path).map(|t| t.clone()), *document.layer_data(&path)) { - (Ok(layer), layer_data) => { - self.copy_buffer[clipboard as usize].push(CopyBufferEntry { layer, layer_data }); + match (document.graphene_document.layer(&path).map(|t| t.clone()), *document.layer_metadata(&path)) { + (Ok(layer), layer_metadata) => { + self.copy_buffer[clipboard as usize].push(CopyBufferEntry { layer, layer_metadata }); } (Err(e), _) => warn!("Could not access selected layer {:?}: {:?}", path, e), } @@ -399,9 +399,9 @@ impl MessageHandler for DocumentsMessageHa .into(), ); responses.push_back( - DocumentMessage::UpdateLayerData { - path: destination_path, - layer_data_entry: entry.layer_data, + DocumentMessage::UpdateLayerMetadata { + layer_path: destination_path, + layer_metadata: entry.layer_metadata, } .into(), ); @@ -431,7 +431,7 @@ impl MessageHandler for DocumentsMessageHa Paste, ); - if self.active_document().layer_data.values().any(|data| data.selected) { + if self.active_document().layer_metadata.values().any(|data| data.selected) { let select = actions!(DocumentsMessageDiscriminant; Copy, Cut, diff --git a/editor/src/document/layer_panel.rs b/editor/src/document/layer_panel.rs index ad094380b3..8bc9841cd4 100644 --- a/editor/src/document/layer_panel.rs +++ b/editor/src/document/layer_panel.rs @@ -1,22 +1,24 @@ -use glam::{DAffine2, DVec2}; -use graphene::layers::{style::ViewMode, BlendMode, Layer, LayerData as DocumentLayerData, LayerDataType}; +use graphene::layers::{style::ViewMode, BlendMode, Layer, LayerData, LayerDataType}; use graphene::LayerId; -use serde::{ser::SerializeStruct, Deserialize, Serialize}; + use std::fmt; +use glam::{DAffine2, DVec2}; +use serde::{ser::SerializeStruct, Deserialize, Serialize}; + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Copy)] -pub struct LayerData { +pub struct LayerMetadata { pub selected: bool, pub expanded: bool, } -impl LayerData { - pub fn new(expanded: bool) -> LayerData { - LayerData { selected: false, expanded } +impl LayerMetadata { + pub fn new(expanded: bool) -> LayerMetadata { + LayerMetadata { selected: false, expanded } } } -pub fn layer_panel_entry(layer_data: &LayerData, transform: DAffine2, layer: &Layer, path: Vec) -> LayerPanelEntry { +pub fn layer_panel_entry(layer_metadata: &LayerMetadata, transform: DAffine2, layer: &Layer, path: Vec) -> LayerPanelEntry { let layer_type: LayerDataTypeDiscriminant = (&layer.data).into(); let name = layer.name.clone().unwrap_or_else(|| format!("Unnamed {}", layer_type)); let arr = layer.data.bounding_box(transform).unwrap_or([DVec2::ZERO, DVec2::ZERO]); @@ -45,7 +47,7 @@ pub fn layer_panel_entry(layer_data: &LayerData, transform: DAffine2, layer: &La blend_mode: layer.blend_mode, opacity: layer.opacity, layer_type: (&layer.data).into(), - layer_data: *layer_data, + layer_metadata: *layer_metadata, path, thumbnail, } @@ -85,7 +87,7 @@ pub struct LayerPanelEntry { pub blend_mode: BlendMode, pub opacity: f64, pub layer_type: LayerDataTypeDiscriminant, - pub layer_data: LayerData, + pub layer_metadata: LayerMetadata, pub path: Vec, pub thumbnail: String, } diff --git a/editor/src/document/mod.rs b/editor/src/document/mod.rs index 1cc14d9849..35cc531e00 100644 --- a/editor/src/document/mod.rs +++ b/editor/src/document/mod.rs @@ -4,10 +4,10 @@ pub mod layer_panel; mod movement_handler; mod overlay_message_handler; mod transform_layer_handler; -mod vectorize_layerdata; +mod vectorize_layer_metadata; #[doc(inline)] -pub use document_file::LayerData; +pub use document_file::LayerMetadata; #[doc(inline)] pub use document_file::{AlignAggregate, AlignAxis, DocumentMessage, DocumentMessageDiscriminant, DocumentMessageHandler, FlipAxis, VectorManipulatorSegment, VectorManipulatorShape}; diff --git a/editor/src/document/overlay_message_handler.rs b/editor/src/document/overlay_message_handler.rs index 9088d9a0c7..77f9d2d7ca 100644 --- a/editor/src/document/overlay_message_handler.rs +++ b/editor/src/document/overlay_message_handler.rs @@ -1,5 +1,5 @@ pub use crate::document::layer_panel::*; -use crate::document::{DocumentMessage, LayerData}; +use crate::document::{DocumentMessage, LayerMetadata}; use crate::input::InputPreprocessor; use crate::message_prelude::*; use graphene::document::Document; @@ -29,9 +29,9 @@ pub struct OverlayMessageHandler { overlay_path_mapping: HashMap, Vec>, } -impl MessageHandler for OverlayMessageHandler { - fn process_action(&mut self, message: OverlayMessage, _data: (&mut LayerData, &Document, &InputPreprocessor), responses: &mut VecDeque) { - // let (layer_data, document, ipp) = data; +impl MessageHandler for OverlayMessageHandler { + fn process_action(&mut self, message: OverlayMessage, _data: (&mut LayerMetadata, &Document, &InputPreprocessor), responses: &mut VecDeque) { + // let (layer_metadata, document, ipp) = data; use OverlayMessage::*; match message { DispatchOperation(operation) => match self.overlays_graphene_document.handle_operation(&operation) { diff --git a/editor/src/document/transform_layer_handler.rs b/editor/src/document/transform_layer_handler.rs index 30af14854d..f2b38902a9 100644 --- a/editor/src/document/transform_layer_handler.rs +++ b/editor/src/document/transform_layer_handler.rs @@ -1,6 +1,6 @@ pub use super::layer_panel::*; -use super::LayerData; +use super::LayerMetadata; use crate::consts::{ROTATE_SNAP_ANGLE, SCALE_SNAP_INTERVAL, SLOWING_DIVISOR}; use crate::input::keyboard::Key; @@ -25,11 +25,11 @@ impl<'a> Selected<'a> { pub fn new( original_transforms: &'a mut OriginalTransforms, pivot: &'a mut DVec2, - layer_data: &'a mut HashMap, LayerData>, + layer_metadata: &'a mut HashMap, LayerMetadata>, responses: &'a mut VecDeque, document: &'a mut Document, ) -> Self { - let selected = layer_data.iter().filter_map(|(layer_path, data)| data.selected.then(|| layer_path.to_owned())).collect(); + let selected = layer_metadata.iter().filter_map(|(layer_path, data)| data.selected.then(|| layer_path.to_owned())).collect(); for path in &selected { if !original_transforms.contains_key::>(path) { original_transforms.insert(path.clone(), document.layer(path).unwrap().transform); @@ -394,12 +394,12 @@ pub struct TransformLayerMessageHandler { pivot: DVec2, } -impl MessageHandler, LayerData>, &mut Document, &InputPreprocessor)> for TransformLayerMessageHandler { - fn process_action(&mut self, message: TransformLayerMessage, data: (&mut HashMap, LayerData>, &mut Document, &InputPreprocessor), responses: &mut VecDeque) { +impl MessageHandler, LayerMetadata>, &mut Document, &InputPreprocessor)> for TransformLayerMessageHandler { + fn process_action(&mut self, message: TransformLayerMessage, data: (&mut HashMap, LayerMetadata>, &mut Document, &InputPreprocessor), responses: &mut VecDeque) { use TransformLayerMessage::*; - let (layer_data, document, ipp) = data; - let mut selected = Selected::new(&mut self.original_transforms, &mut self.pivot, layer_data, responses, document); + let (layer_metadata, document, ipp) = data; + let mut selected = Selected::new(&mut self.original_transforms, &mut self.pivot, layer_metadata, responses, document); let mut begin_operation = |operation: Operation, typing: &mut Typing, mouse_position: &mut DVec2, start_mouse: &mut DVec2| { if !(operation == Operation::None) { diff --git a/editor/src/document/vectorize_layerdata.rs b/editor/src/document/vectorize_layer_metadata.rs similarity index 100% rename from editor/src/document/vectorize_layerdata.rs rename to editor/src/document/vectorize_layer_metadata.rs diff --git a/frontend/src/components/panels/LayerTree.vue b/frontend/src/components/panels/LayerTree.vue index 91789fb804..d7df123c3e 100644 --- a/frontend/src/components/panels/LayerTree.vue +++ b/frontend/src/components/panels/LayerTree.vue @@ -28,13 +28,13 @@
{ - layer.layer_data.selected = false; + layer.layer_metadata.selected = false; }); }, closest(tree: HTMLElement, clientY: number): [BigUint64Array, boolean, Node] { @@ -446,7 +446,7 @@ export default defineComponent({ } }, setBlendModeForSelectedLayers() { - const selected = this.layers.filter((layer) => layer.layer_data.selected); + const selected = this.layers.filter((layer) => layer.layer_metadata.selected); if (selected.length < 1) { this.blendModeSelectedIndex = 0; @@ -467,7 +467,7 @@ export default defineComponent({ }, setOpacityForSelectedLayers() { // todo figure out why this is here - const selected = this.layers.filter((layer) => layer.layer_data.selected); + const selected = this.layers.filter((layer) => layer.layer_metadata.selected); if (selected.length < 1) { this.opacity = 100; diff --git a/frontend/src/dispatcher/js-messages.ts b/frontend/src/dispatcher/js-messages.ts index 72b8abd720..8cd6a6a11d 100644 --- a/frontend/src/dispatcher/js-messages.ts +++ b/frontend/src/dispatcher/js-messages.ts @@ -284,13 +284,13 @@ export class LayerPanelEntry { @Transform(({ value }) => new BigUint64Array(value)) path!: BigUint64Array; - @Type(() => LayerData) - layer_data!: LayerData; + @Type(() => LayerMetadata) + layer_metadata!: LayerMetadata; thumbnail!: string; } -export class LayerData { +export class LayerMetadata { expanded!: boolean; selected!: boolean; diff --git a/graphene/src/layers/mod.rs b/graphene/src/layers/mod.rs index 39f70f23bf..a3cff9d60d 100644 --- a/graphene/src/layers/mod.rs +++ b/graphene/src/layers/mod.rs @@ -18,18 +18,11 @@ use serde::{Deserialize, Serialize}; use std::fmt::Write; -pub trait LayerData { - fn render(&mut self, svg: &mut String, transforms: &mut Vec, view_mode: ViewMode); - fn intersects_quad(&self, quad: Quad, path: &mut Vec, intersections: &mut Vec>); - fn bounding_box(&self, transform: glam::DAffine2) -> Option<[DVec2; 2]>; -} - #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] pub enum LayerDataType { Folder(Folder), Shape(Shape), } - impl LayerDataType { pub fn inner(&self) -> &dyn LayerData { match self { @@ -46,6 +39,12 @@ impl LayerDataType { } } +pub trait LayerData { + fn render(&mut self, svg: &mut String, transforms: &mut Vec, view_mode: ViewMode); + fn intersects_quad(&self, quad: Quad, path: &mut Vec, intersections: &mut Vec>); + fn bounding_box(&self, transform: glam::DAffine2) -> Option<[DVec2; 2]>; +} + impl LayerData for LayerDataType { fn render(&mut self, svg: &mut String, transforms: &mut Vec, view_mode: ViewMode) { self.inner_mut().render(svg, transforms, view_mode) From c64f85838713b2d90cbcf84e157d9b4a1c1266d8 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Sun, 2 Jan 2022 06:00:02 -0800 Subject: [PATCH 3/3] Major frontend code cleanup (#452) Many large changes, including: - TypeScript enums are now string unions throughout - Strong type-checking throughout the TS and Vue codebase - Vue component props now all specify `as PropType<...>` - Usage of annotated return types on all functions - Sorting of JS import statements - Explicit usage of Vue bind attribute function call arguments (`@click="foo"` is now `@click=(e) => foo(e)`) - Much improved code quality related to the color picker - Consistent camelCase Vue bind and v-model attributes - Consistent Vue HTML attribute strings with single quotes - Bug fix and clarity improvement with incorrect hint class parameters - Empty Vue component objects like `props: {}` and `components: {}` removed --- frontend/.eslintrc.js | 53 +++ frontend/src/App.vue | 14 +- frontend/src/components/panels/Document.vue | 95 +++-- frontend/src/components/panels/LayerTree.vue | 69 ++-- frontend/src/components/panels/Minimap.vue | 5 +- frontend/src/components/panels/Properties.vue | 5 +- .../components/widgets/buttons/IconButton.vue | 14 +- .../widgets/buttons/PopoverButton.vue | 21 +- .../components/widgets/buttons/TextButton.vue | 16 +- .../widgets/floating-menus/ColorPicker.vue | 221 +++++------ .../widgets/floating-menus/DialogModal.vue | 14 +- .../widgets/floating-menus/FloatingMenu.vue | 48 +-- .../widgets/floating-menus/MenuList.vue | 30 +- .../widgets/inputs/CheckboxInput.vue | 10 +- .../widgets/inputs/DropdownInput.vue | 20 +- .../widgets/inputs/MenuBarInput.vue | 57 ++- .../components/widgets/inputs/NumberInput.vue | 59 ++- .../widgets/inputs/OptionalInput.vue | 7 +- .../components/widgets/inputs/RadioInput.vue | 2 +- .../widgets/inputs/ShelfItemInput.vue | 9 +- .../widgets/inputs/SwatchPairInput.vue | 68 ++-- .../components/widgets/labels/IconLabel.vue | 361 +++++++++--------- .../components/widgets/labels/TextLabel.vue | 7 +- .../widgets/labels/UserInputLabel.vue | 65 +--- .../widgets/options/ToolOptions.vue | 41 +- .../components/widgets/rulers/CanvasRuler.vue | 30 +- .../scrollbars/PersistentScrollbar.vue | 34 +- .../widgets/separators/Separator.vue | 17 +- frontend/src/components/window/MainWindow.vue | 15 +- .../window/status-bar/StatusBar.vue | 6 +- .../components/window/title-bar/TitleBar.vue | 28 +- .../window/title-bar/WindowButtonsMac.vue | 4 +- .../window/title-bar/WindowButtonsWeb.vue | 2 +- .../window/title-bar/WindowButtonsWindows.vue | 4 +- .../window/title-bar/WindowTitle.vue | 4 +- frontend/src/components/workspace/Panel.vue | 39 +- .../src/components/workspace/Workspace.vue | 4 +- frontend/src/dispatcher/js-dispatcher.ts | 6 +- frontend/src/dispatcher/js-messages.ts | 46 ++- frontend/src/lifetime/auto-save.ts | 11 +- frontend/src/lifetime/errors.ts | 8 +- frontend/src/lifetime/input.ts | 47 +-- frontend/src/main.ts | 2 +- frontend/src/state/dialog.ts | 23 +- frontend/src/state/documents.ts | 21 +- frontend/src/state/fullscreen.ts | 9 +- frontend/src/state/wasm-loader.ts | 13 +- frontend/src/utilities/color.ts | 79 ++-- frontend/src/utilities/files.ts | 4 +- frontend/src/utilities/math.ts | 2 +- frontend/src/utilities/strip-indents.ts | 2 +- .../widgets => utilities}/widgets.ts | 15 +- frontend/vue.config.js | 2 +- 53 files changed, 842 insertions(+), 946 deletions(-) rename frontend/src/{components/widgets => utilities}/widgets.ts (89%) diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index ddb7572817..358fe5ae78 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -73,9 +73,54 @@ module.exports = { "@typescript-eslint/no-use-before-define": "off", "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], "@typescript-eslint/no-loss-of-precision": "off", // TODO: Remove this line after upgrading to eslint 7.1 or greater + "@typescript-eslint/explicit-function-return-type": ["error"], // Import plugin config (used to intelligently validate module import statements) "import/prefer-default-export": "off", + "import/no-relative-packages": "error", + "import/order": [ + "error", + { + alphabetize: { + order: "asc", + caseInsensitive: true, + }, + warnOnUnassignedImports: true, + "newlines-between": "always-and-inside-groups", + pathGroups: [ + { + pattern: "**/*.vue", + group: "unknown", + position: "after", + }, + { + pattern: "**/assets/12px-solid/*.svg", + group: "unknown", + position: "after", + }, + { + pattern: "**/assets/16px-solid/*.svg", + group: "unknown", + position: "after", + }, + { + pattern: "**/assets/16px-two-tone/*.svg", + group: "unknown", + position: "after", + }, + { + pattern: "**/assets/24px-full-color/*.svg", + group: "unknown", + position: "after", + }, + { + pattern: "**/assets/24px-two-tone/*.svg", + group: "unknown", + position: "after", + }, + ], + }, + ], // Prettier plugin config (used to enforce HTML, CSS, and JS formatting styles as an ESLint plugin, where fixes are reported to ESLint to be applied when linting) "prettier-vue/prettier": [ @@ -90,4 +135,12 @@ module.exports = { // Vue plugin config (used to validate Vue single-file components) "vue/multi-word-component-names": "off", }, + overrides: [ + { + files: ["*.js"], + rules: { + "@typescript-eslint/explicit-function-return-type": ["off"], + }, + }, + ], }; diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 9ee7b9df98..77d472ad97 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -221,16 +221,16 @@ img { diff --git a/frontend/src/components/panels/Properties.vue b/frontend/src/components/panels/Properties.vue index fdd88d3382..0763d62cd8 100644 --- a/frontend/src/components/panels/Properties.vue +++ b/frontend/src/components/panels/Properties.vue @@ -7,8 +7,5 @@ diff --git a/frontend/src/components/widgets/buttons/IconButton.vue b/frontend/src/components/widgets/buttons/IconButton.vue index d5f174f743..4a0eec3f74 100644 --- a/frontend/src/components/widgets/buttons/IconButton.vue +++ b/frontend/src/components/widgets/buttons/IconButton.vue @@ -1,5 +1,5 @@ @@ -57,16 +57,16 @@ diff --git a/frontend/src/components/widgets/buttons/TextButton.vue b/frontend/src/components/widgets/buttons/TextButton.vue index 7da0e453a9..257e4ef02a 100644 --- a/frontend/src/components/widgets/buttons/TextButton.vue +++ b/frontend/src/components/widgets/buttons/TextButton.vue @@ -1,5 +1,5 @@ @@ -49,18 +49,18 @@ diff --git a/frontend/src/components/widgets/floating-menus/FloatingMenu.vue b/frontend/src/components/widgets/floating-menus/FloatingMenu.vue index 5d1fe02e5c..67166d49c6 100644 --- a/frontend/src/components/widgets/floating-menus/FloatingMenu.vue +++ b/frontend/src/components/widgets/floating-menus/FloatingMenu.vue @@ -1,6 +1,6 @@ - + @@ -95,28 +95,17 @@ diff --git a/frontend/src/components/widgets/options/ToolOptions.vue b/frontend/src/components/widgets/options/ToolOptions.vue index 07c98dfd73..0c8ee88d56 100644 --- a/frontend/src/components/widgets/options/ToolOptions.vue +++ b/frontend/src/components/widgets/options/ToolOptions.vue @@ -31,17 +31,19 @@ diff --git a/frontend/src/components/window/MainWindow.vue b/frontend/src/components/window/MainWindow.vue index 54b2664df4..aa7b5e749a 100644 --- a/frontend/src/components/window/MainWindow.vue +++ b/frontend/src/components/window/MainWindow.vue @@ -39,18 +39,13 @@ diff --git a/frontend/src/components/window/title-bar/WindowButtonsWeb.vue b/frontend/src/components/window/title-bar/WindowButtonsWeb.vue index 45a601bb20..2c5334c848 100644 --- a/frontend/src/components/window/title-bar/WindowButtonsWeb.vue +++ b/frontend/src/components/window/title-bar/WindowButtonsWeb.vue @@ -1,5 +1,5 @@