Massively reorganize and clean up the whole Rust codebase (#478)

* Massively reorganize and clean up the whole Rust codebase

* Additional changes during code review
This commit is contained in:
Keavon Chambers
2022-01-14 14:58:08 -08:00
parent 011c2be26d
commit f48d4e1884
85 changed files with 2515 additions and 2189 deletions

View File

@@ -1,73 +1,27 @@
use std::collections::HashMap;
use std::collections::VecDeque;
use super::artboard_message_handler::ArtboardMessage;
use super::artboard_message_handler::ArtboardMessageHandler;
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::clipboards::Clipboard;
use super::layer_panel::{layer_panel_entry, LayerMetadata, LayerPanelEntry, RawBuffer};
use super::utility_types::{AlignAggregate, AlignAxis, DocumentSave, FlipAxis, VectorManipulatorSegment, VectorManipulatorShape};
use super::vectorize_layer_metadata;
use super::{ArtboardMessageHandler, MovementMessageHandler, OverlaysMessageHandler, TransformLayerMessageHandler};
use crate::consts::{
ASYMPTOTIC_EFFECT, DEFAULT_DOCUMENT_NAME, FILE_EXPORT_SUFFIX, FILE_SAVE_SUFFIX, GRAPHITE_DOCUMENT_VERSION, SCALE_EFFECT, SCROLLBAR_SPACING, VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR,
};
use crate::document::Clipboard;
use crate::input::InputPreprocessor;
use crate::input::InputPreprocessorMessageHandler;
use crate::message_prelude::*;
use crate::EditorError;
use graphene::layers::{style::ViewMode, BlendMode, LayerDataType};
use graphene::{document::Document as GrapheneDocument, DocumentError, LayerId};
use graphene::{DocumentResponse, Operation as DocumentOperation};
use graphene::document::Document as GrapheneDocument;
use graphene::layers::folder::Folder;
use graphene::layers::layer_info::LayerDataType;
use graphene::layers::style::ViewMode;
use graphene::{DocumentError, DocumentResponse, LayerId, Operation as DocumentOperation};
use glam::{DAffine2, DVec2};
use graphene::layers::Folder;
use kurbo::PathSeg;
use log::warn;
use serde::{Deserialize, Serialize};
type DocumentSave = (GrapheneDocument, HashMap<Vec<LayerId>, LayerMetadata>);
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize, Hash)]
pub enum FlipAxis {
X,
Y,
}
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize, Hash)]
pub enum AlignAxis {
X,
Y,
}
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize, Hash)]
pub enum AlignAggregate {
Min,
Max,
Center,
Average,
}
#[derive(PartialEq, Clone, Debug)]
pub enum VectorManipulatorSegment {
Line(DVec2, DVec2),
Quad(DVec2, DVec2, DVec2),
Cubic(DVec2, DVec2, DVec2, DVec2),
}
#[derive(PartialEq, Clone, Debug)]
pub struct VectorManipulatorShape {
/// The path to the layer
pub layer_path: Vec<LayerId>,
/// The outline of the shape
pub path: kurbo::BezPath,
/// The control points / manipulator handles
pub segments: Vec<VectorManipulatorSegment>,
/// The compound Bezier curve is closed
pub closed: bool,
/// The transformation matrix to apply
pub transform: DAffine2,
}
use std::collections::HashMap;
use std::collections::VecDeque;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DocumentMessageHandler {
@@ -83,7 +37,7 @@ pub struct DocumentMessageHandler {
layer_range_selection_reference: Vec<LayerId>,
movement_handler: MovementMessageHandler,
#[serde(skip)]
overlay_message_handler: OverlayMessageHandler,
overlays_message_handler: OverlaysMessageHandler,
artboard_message_handler: ArtboardMessageHandler,
#[serde(skip)]
transform_layer_handler: TransformLayerMessageHandler,
@@ -98,12 +52,12 @@ impl Default for DocumentMessageHandler {
graphene_document: GrapheneDocument::default(),
document_undo_history: Vec::new(),
document_redo_history: Vec::new(),
name: String::from("Untitled Document"),
saved_document_identifier: 0,
name: String::from("Untitled Document"),
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(),
overlays_message_handler: OverlaysMessageHandler::default(),
artboard_message_handler: ArtboardMessageHandler::default(),
transform_layer_handler: TransformLayerMessageHandler::default(),
snapping_enabled: true,
@@ -113,84 +67,6 @@ impl Default for DocumentMessageHandler {
}
}
#[remain::sorted]
#[impl_message(Message, PortfolioMessage, Document)]
#[derive(PartialEq, Clone, Debug, Serialize, Deserialize)]
pub enum DocumentMessage {
AbortTransaction,
AddSelectedLayers(Vec<Vec<LayerId>>),
AlignSelectedLayers(AlignAxis, AlignAggregate),
#[child]
Artboard(ArtboardMessage),
CommitTransaction,
CreateEmptyFolder(Vec<LayerId>),
DebugPrintDocument,
DeleteLayer(Vec<LayerId>),
DeleteSelectedLayers,
DeselectAllLayers,
DirtyRenderDocument,
DirtyRenderDocumentInOutlineView,
DispatchOperation(Box<DocumentOperation>),
DocumentHistoryBackward,
DocumentHistoryForward,
DocumentStructureChanged,
DuplicateSelectedLayers,
ExportDocument,
FlipSelectedLayers(FlipAxis),
FolderChanged(Vec<LayerId>),
GroupSelectedLayers,
LayerChanged(Vec<LayerId>),
#[child]
Movement(MovementMessage),
MoveSelectedLayersTo {
path: Vec<LayerId>,
insert_index: isize,
},
NudgeSelectedLayers(f64, f64),
#[child]
Overlay(OverlayMessage),
Redo,
RenameLayer(Vec<LayerId>, String),
RenderDocument,
ReorderSelectedLayers(i32), // relative_position,
RollbackTransaction,
SaveDocument,
SelectAllLayers,
SelectionChanged,
SelectLayer(Vec<LayerId>, bool, bool),
SetBlendModeForSelectedLayers(BlendMode),
SetLayerExpansion(Vec<LayerId>, bool),
SetOpacityForSelectedLayers(f64),
SetSelectedLayers(Vec<Vec<LayerId>>),
SetSnapping(bool),
SetViewMode(ViewMode),
StartTransaction,
ToggleLayerExpansion(Vec<LayerId>),
ToggleLayerVisibility(Vec<LayerId>),
#[child]
TransformLayers(TransformLayerMessage),
Undo,
UngroupLayers(Vec<LayerId>),
UngroupSelectedLayers,
UpdateLayerMetadata {
layer_path: Vec<LayerId>,
layer_metadata: LayerMetadata,
},
ZoomCanvasToFitAll,
}
impl From<DocumentOperation> for DocumentMessage {
fn from(operation: DocumentOperation) -> DocumentMessage {
Self::DispatchOperation(Box::new(operation))
}
}
impl From<DocumentOperation> for Message {
fn from(operation: DocumentOperation) -> Message {
DocumentMessage::DispatchOperation(Box::new(operation)).into()
}
}
impl DocumentMessageHandler {
pub fn serialize_document(&self) -> String {
let val = serde_json::to_string(self);
@@ -212,7 +88,7 @@ impl DocumentMessageHandler {
}
}
pub fn with_name(name: String, ipp: &InputPreprocessor) -> Self {
pub fn with_name(name: String, ipp: &InputPreprocessorMessageHandler) -> Self {
let mut document = Self { name, ..Self::default() };
let starting_root_transform = document.movement_handler.calculate_offset_transform(ipp.viewport_bounds.size() / 2.);
document.graphene_document.root.transform = starting_root_transform;
@@ -256,13 +132,13 @@ impl DocumentMessageHandler {
self.graphene_document.combined_viewport_bounding_box(paths)
}
// TODO: Consider moving this to some kind of overlay manager in the future
// TODO: Consider moving this to some kind of overlays manager in the future
pub fn selected_visible_layers_vector_points(&self) -> Vec<VectorManipulatorShape> {
let shapes = self.selected_layers().filter_map(|path_to_shape| {
let viewport_transform = self.graphene_document.generate_transform_relative_to_viewport(path_to_shape).ok()?;
let layer = self.graphene_document.layer(path_to_shape);
// Filter out the non-visible layers from the filter_map
// Filter out the non-visible layers from the `filter_map`
match &layer {
Ok(layer) if layer.visible => {}
_ => return None,
@@ -343,30 +219,38 @@ impl DocumentMessageHandler {
structure.push(space | 1 << 63);
}
/// Serializes the layer structure into a compressed 1d structure
/// Serializes the layer structure into a condensed 1D structure.
///
/// # Format
/// It is a string of numbers broken into three sections:
/// (4),(2,1,-2,-0),(16533113728871998040,3427872634365736244,18115028555707261608,15878401910454357952,449479075714955186) <- Example encoded data
/// L = 4 = structure.len() <- First value in the encoding: L, the length of the structure section
/// structure = 2,1,-2,-0 <- Subsequent L values: structure section
/// data = 16533113728871998040,3427872634365736244,18115028555707261608,15878401910454357952,449479075714955186 <- Remaining values: data section (layer IDs)
///
/// | Data | Description | Length |
/// |--------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------|------------------|
/// | `4,` `2, 1, -2, -0,` `16533113728871998040,3427872634365736244,18115028555707261608,15878401910454357952,449479075714955186` | Encoded example data | |
/// | `L` = `4` = `structure.len()` | `L`, the length of the **Structure** section | First value |
/// | **Structure** section = `2, 1, -2, -0` | The **Structure** section | Next `L` values |
/// | **Data** section = `16533113728871998040, 3427872634365736244, 18115028555707261608, 15878401910454357952, 449479075714955186` | The **Data** section (layer IDs) | Remaining values |
///
/// The data section lists the layer IDs for all folders/layers in the tree as read from top to bottom.
/// The structure section lists signed numbers. The sign indicates a folder indentation change (+ is down a level, - is up a level).
/// the numbers in the structure block encode the indentation,
/// 2 mean read two element from the data section, then place a [
/// -x means read x elements from the data section and then insert a ]
/// The structure section lists signed numbers. The sign indicates a folder indentation change (`+` is down a level, `-` is up a level).
/// The numbers in the structure block encode the indentation. For example:
/// - `2` means read two element from the data section, then place a `[`.
/// - `-x` means read `x` elements from the data section and then insert a `]`.
///
/// ```text
/// 2 V 1 V -2 A -0 A
/// 16533113728871998040,3427872634365736244, 18115028555707261608, 15878401910454357952,449479075714955186
/// 16533113728871998040,3427872634365736244,[ 18115028555707261608,[15878401910454357952,449479075714955186] ]
/// ```
///
/// resulting layer panel:
/// Resulting layer panel:
/// ```text
/// 16533113728871998040
/// 3427872634365736244
/// [3427872634365736244,18115028555707261608]
/// [3427872634365736244,18115028555707261608,15878401910454357952]
/// [3427872634365736244,18115028555707261608,449479075714955186]
/// ```
pub fn serialize_root(&self) -> Vec<u64> {
let (mut structure, mut data) = (vec![0], Vec::new());
self.serialize_structure(self.graphene_document.root.as_folder().unwrap(), &mut structure, &mut data, &mut vec![]);
@@ -552,9 +436,9 @@ impl DocumentMessageHandler {
}
}
impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHandler {
impl MessageHandler<DocumentMessage, &InputPreprocessorMessageHandler> for DocumentMessageHandler {
#[remain::check]
fn process_action(&mut self, message: DocumentMessage, ipp: &InputPreprocessor, responses: &mut VecDeque<Message>) {
fn process_action(&mut self, message: DocumentMessage, ipp: &InputPreprocessorMessageHandler, responses: &mut VecDeque<Message>) {
use DocumentMessage::*;
#[remain::sorted]
match message {
@@ -798,13 +682,13 @@ impl MessageHandler<DocumentMessage, &InputPreprocessor> for DocumentMessageHand
}
responses.push_back(ToolMessage::DocumentIsDirty.into());
}
Overlay(message) => {
self.overlay_message_handler.process_action(
Overlays(message) => {
self.overlays_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());
// responses.push_back(OverlaysMessage::RenderOverlays.into());
}
Redo => {
responses.push_back(SelectMessage::Abort.into());