mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-20 03:18:06 +08:00
* Add alignment overlays * Made snapping / overlays not render extra times, made snapping distance larger * Revert snap tolerance change until user testing can be done * WIP conversion to messages * Revert "WIP conversion to messages" This reverts commitddcc23865a. * Overlay document always has (0,0) in top left * Fix AA on overlay lines * Merge branch 'master' into alignment-overlays * Squashed commit of the following: commitdbc19912caAuthor: asyncth <97792158+asyncth@users.noreply.github.com> Date: Sun Jan 16 12:57:03 2022 +0500 Set the mouse cursor in the canvas based on the current tool and its state (#480) * Add FrontendMouseCursor and DisplayMouseCursor * Add update_cursor method to the Fsm trait and implement it for all tools * Rename DisplayMouseCursor to UpdateMouseCursor * Add 'To CSS Cursor Property' transform decorator and change the mouse cursor in the canvas based on the current tool and its state * Implement update_cursor for Navigate tool properly * Keep the cursor when dragging outside of the canvas * Change the mouse cursor to 'zoom-in' when LMB dragging on canvas with Navigate tool * Rename FrontendMouseCursor to MouseCursorIcon * Rename 'event' to 'e' and replace v-on with @ * Change the definition of the MouseCursorIcon type in TS * Replace switch with dictionary look-up * Move the definition of MouseCursorIcon closer to where it's used commit9b36e6a909Author: Keavon Chambers <keavon@keavon.com> Date: Sat Jan 15 17:24:58 2022 -0800 Fix all remaining Vue/TS errors flagged in Volar commit2cc39cdb37Author: Keavon Chambers <keavon@keavon.com> Date: Sat Jan 15 12:55:51 2022 -0800 Tweak whitespace around `use` statements and other lint fixes commitfa390c3875Author: Keavon Chambers <keavon@keavon.com> Date: Sat Jan 15 06:35:06 2022 -0800 Change canvas artboard background color to be 1 shade lighter commitea2d003484Author: Keavon Chambers <keavon@keavon.com> Date: Fri Jan 14 20:54:38 2022 -0800 Modify all message enum data to use named struct values, not tuples (#479) * Massively reorganize and clean up the whole Rust codebase * Modify all message enum data to use named struct values, not tuples commit9b6cbb5f50Author: Keavon Chambers <keavon@keavon.com> Date: Fri Jan 14 14:58:08 2022 -0800 Massively reorganize and clean up the whole Rust codebase (#478) * Massively reorganize and clean up the whole Rust codebase * Additional changes during code review commita535f5c1c1Author: Keavon Chambers <keavon@keavon.com> Date: Wed Jan 12 16:17:40 2022 -0800 Sort messages and message handlers commite70858884dAuthor: Keavon Chambers <keavon@keavon.com> Date: Wed Jan 12 14:16:13 2022 -0800 Standardize FrontendMessage message names commit0b4934b4f3Author: Keavon Chambers <keavon@keavon.com> Date: Wed Jan 12 12:45:07 2022 -0800 Rename document_file.rs to document_message_handler.rs commitec7bf4a771Author: Keavon Chambers <keavon@keavon.com> Date: Wed Jan 12 12:19:14 2022 -0800 Rename DocumentsMessage to PortfolioMessage commit0991312ba0Author: Keavon Chambers <keavon@keavon.com> Date: Wed Jan 12 11:44:49 2022 -0800 Rename document_message_handler.rs to portfolio_message_handler.rs commitc76c92e500Author: 0HyperCube <78500760+0HyperCube@users.noreply.github.com> Date: Wed Jan 12 19:05:55 2022 +0000 Migrate to using MoveSelectedLayersTo (#469) * migrate to using MoveSelectedLayersTo * Fix dragging a selected layer with multiple selected layers * Fix CreatedLayer overriding selection * Fix MoveSelectedLayersTo behaviour * Squashed commit of the following: commit095d577a49Author: Keavon Chambers <keavon@keavon.com> Date: Mon Jan 10 18:06:12 2022 -0800 Fix NumberInput clamping regression with undefined bounds commit9f54a376c4Author: mfish33 <32677537+mfish33@users.noreply.github.com> Date: Sun Jan 9 15:52:55 2022 -0800 Fix bounds with artboards for zoom-to-fit and scrollbar scaling (#473) * - document load keeps postition - zoom to fit - scrollbars use artboard dimensions * - review comments - svg export uses all artboard bounds Co-authored-by: Keavon Chambers <keavon@keavon.com> commit61432de480Author: 0HyperCube <78500760+0HyperCube@users.noreply.github.com> Date: Sat Jan 8 21:06:15 2022 +0000 Fix rotation input (#472) * Fix insert with no nesting at end of panel * Deselect other layers on paste * Resolve logging commit574028375bAuthor: Keavon Chambers <keavon@keavon.com> Date: Wed Jan 12 06:14:32 2022 -0800 Add `npm start` script alias for `npm run serve` commit75e8fc6614Author: Keavon Chambers <keavon@keavon.com> Date: Wed Jan 12 05:17:56 2022 -0800 Switch VS Code's Vue extension from Vetur to Volar commit389b445ef1Author: Keavon Chambers <keavon@keavon.com> Date: Wed Jan 12 03:56:28 2022 -0800 Remove Charcoal references from the code for now commit095d577a49Author: Keavon Chambers <keavon@keavon.com> Date: Mon Jan 10 18:06:12 2022 -0800 Fix NumberInput clamping regression with undefined bounds commit9f54a376c4Author: mfish33 <32677537+mfish33@users.noreply.github.com> Date: Sun Jan 9 15:52:55 2022 -0800 Fix bounds with artboards for zoom-to-fit and scrollbar scaling (#473) * - document load keeps postition - zoom to fit - scrollbars use artboard dimensions * - review comments - svg export uses all artboard bounds Co-authored-by: Keavon Chambers <keavon@keavon.com> commit61432de480Author: 0HyperCube <78500760+0HyperCube@users.noreply.github.com> Date: Sat Jan 8 21:06:15 2022 +0000 Fix rotation input (#472) commit3eeac79f5aAuthor: 0HyperCube <78500760+0HyperCube@users.noreply.github.com> Date: Sat Jan 8 16:30:03 2022 +0000 Enhance the Navigate Tool zoom behavior (#461) * Snap zoom * Navigate zoom from centre * Ctrl to snap zoom in navigate * Use ctrl for global snap rotate * Fix the rotation input on snap rotate * Update hint to use ctrl * Fix mouse centre on drag * Click to zoom in * Clean up centre zoom * Update user input hints; tweak some variable names for clarity and standardization Co-authored-by: Keavon Chambers <keavon@keavon.com> commita2c2f7fc9dAuthor: 0HyperCube <78500760+0HyperCube@users.noreply.github.com> Date: Sat Jan 8 16:02:02 2022 +0000 Add support for resizing workspace panels (#443) * Resize panels * Removing move_selection test pending #444 resolved * Bind event listners and cursor to the document * Fix flex grow on document being reset when drawing * Call onresize when the boundry is dragged * Add min panel size * Add explicit function return types * Dispatch resize event * Lock pointer instead of setting cursor on document Co-authored-by: otdavies <oliver@psyfer.io> Co-authored-by: Keavon Chambers <keavon@keavon.com> commit54e9121115Author: mfish33 <32677537+mfish33@users.noreply.github.com> Date: Sat Jan 8 07:50:08 2022 -0800 Implement artboards and document version enforcement (#466) * - graphite document artboard implementation - autosave document load hitch fix - Autosave will delete saved files when graphite document version changes * formating * - top left 0,0 - fixed hitch on first document - vue calls first render * Revert * Merge branch 'master' into artboards * Small bug fixes and code review tweaks Co-authored-by: Oliver Davies <oliver@psyfer.io> Co-authored-by: Keavon Chambers <keavon@keavon.com> commit11f15bd6afAuthor: Leonard Pauli <leonardpauli@me.com> Date: Sat Jan 8 14:25:24 2022 +0100 Path Tool: Implement anchor point dragging (#451) * #82 path-tool: WIP selecting control point working * Fix bug where duplication with Ctrl+D doesn't properly duplicate (#423) * bug fix: duplication didn't properly duplicate * cargo fmt * changed the formatting slightly for readability * Small cleanups, changed color of handles upon selection * Fix changes from merge * Remove duplicate anchor points on top of one another * Fix possible issues with thumbnails not being updated from Graphene operations * path-tool: attempt to move control points on click * Add dragging for control points * Editing shape anchors functional. Handles next. * Comment cleanup & slight cleanup of closest_anchor(..) * Removing conflict with master * Tiny code tweaks Co-authored-by: Keavon Chambers <keavon@keavon.com> Co-authored-by: caleb <56044292+caleb-ad@users.noreply.github.com> Co-authored-by: otdavies <oliver@psyfer.io> Co-authored-by: Dennis <dennis@kobert.dev> commit05e8a98f46Author: Keavon Chambers <keavon@keavon.com> Date: Fri Jan 7 23:13:33 2022 -0800 Redesign the Layer Tree UI (#468) commit8e3d237228Author: Oliver Davies <oliver@psyfer.io> Date: Fri Jan 7 15:53:12 2022 -0800 Ungroup layers (#465) * WIP handling corner cases, like ungrouping subfolders * Resolved hanging * Fix recursive ungrouping * Functional, corner case free Ungroup. Small Undo issue & warnings * Update layertree upon undo * Also update layerdata upon redo * Add some polish * Resolved TODOs * Oops didn't save all after rename, ha. Co-authored-by: Dennis <dennis@kobert.dev> commitc1c7192948Author: TrueDoctor <dennis@kobert.dev> Date: Fri Jan 7 04:15:08 2022 +0100 Tidy up path handling in document_file (#464) * Tidy up path handling in document_file + Improve #455 * Cargo Clippy lints * Rename to_vec to map_to_vec Co-authored-by: Oliver Davies <oliver@psyfer.io> commitf4707f9b74Author: mfish33 <32677537+mfish33@users.noreply.github.com> Date: Thu Jan 6 18:45:37 2022 -0800 Better decimal rounding in the NumberInput widget (#457) * better decimal rounding in NumberInput * - created function to reuse - used math instead of string manipulation * updated comment to be correct * updated comment * updated comment commit0219f060b8Author: Keavon Chambers <keavon@keavon.com> Date: Wed Jan 5 05:40:32 2022 -0800 Fix build script to use correct branch name * Fix indentation * Overlays fade in * Fix formatting * Add consts for snap visible and opacity * Tweak constants for improved UX, rejigger imports * Fix AA bounding box * Snap only visible layers * Add some comments Co-authored-by: otdavies <oliver@psyfer.io> Co-authored-by: Keavon Chambers <keavon@keavon.com>
209 lines
5.5 KiB
Rust
209 lines
5.5 KiB
Rust
use super::shared::resize::Resize;
|
|
use crate::document::DocumentMessageHandler;
|
|
use crate::frontend::utility_types::MouseCursorIcon;
|
|
use crate::input::keyboard::{Key, MouseMotion};
|
|
use crate::input::InputPreprocessorMessageHandler;
|
|
use crate::message_prelude::*;
|
|
use crate::misc::{HintData, HintGroup, HintInfo, KeysGroup};
|
|
use crate::viewport_tools::tool::{DocumentToolData, Fsm, ToolActionHandlerData, ToolType};
|
|
use crate::viewport_tools::tool_options::{ShapeType, ToolOptions};
|
|
|
|
use graphene::layers::style;
|
|
use graphene::Operation;
|
|
|
|
use glam::DAffine2;
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Default)]
|
|
pub struct Shape {
|
|
fsm_state: ShapeToolFsmState,
|
|
data: ShapeToolData,
|
|
}
|
|
|
|
#[remain::sorted]
|
|
#[impl_message(Message, ToolMessage, Shape)]
|
|
#[derive(PartialEq, Clone, Debug, Hash, Serialize, Deserialize)]
|
|
pub enum ShapeMessage {
|
|
// Standard messages
|
|
#[remain::unsorted]
|
|
Abort,
|
|
|
|
// Tool-specific messages
|
|
DragStart,
|
|
DragStop,
|
|
Resize {
|
|
center: Key,
|
|
lock_ratio: Key,
|
|
},
|
|
}
|
|
|
|
impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for Shape {
|
|
fn process_action(&mut self, action: ToolMessage, data: ToolActionHandlerData<'a>, responses: &mut VecDeque<Message>) {
|
|
if action == ToolMessage::UpdateHints {
|
|
self.fsm_state.update_hints(responses);
|
|
return;
|
|
}
|
|
|
|
if action == ToolMessage::UpdateCursor {
|
|
self.fsm_state.update_cursor(responses);
|
|
return;
|
|
}
|
|
|
|
let new_state = self.fsm_state.transition(action, data.0, data.1, &mut self.data, data.2, responses);
|
|
|
|
if self.fsm_state != new_state {
|
|
self.fsm_state = new_state;
|
|
self.fsm_state.update_hints(responses);
|
|
self.fsm_state.update_cursor(responses);
|
|
}
|
|
}
|
|
|
|
fn actions(&self) -> ActionList {
|
|
use ShapeToolFsmState::*;
|
|
|
|
match self.fsm_state {
|
|
Ready => actions!(ShapeMessageDiscriminant; DragStart),
|
|
Drawing => actions!(ShapeMessageDiscriminant; DragStop, Abort, Resize),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
enum ShapeToolFsmState {
|
|
Ready,
|
|
Drawing,
|
|
}
|
|
|
|
impl Default for ShapeToolFsmState {
|
|
fn default() -> Self {
|
|
ShapeToolFsmState::Ready
|
|
}
|
|
}
|
|
#[derive(Clone, Debug, Default)]
|
|
struct ShapeToolData {
|
|
sides: u8,
|
|
data: Resize,
|
|
}
|
|
|
|
impl Fsm for ShapeToolFsmState {
|
|
type ToolData = ShapeToolData;
|
|
|
|
fn transition(
|
|
self,
|
|
event: ToolMessage,
|
|
document: &DocumentMessageHandler,
|
|
tool_data: &DocumentToolData,
|
|
data: &mut Self::ToolData,
|
|
input: &InputPreprocessorMessageHandler,
|
|
responses: &mut VecDeque<Message>,
|
|
) -> Self {
|
|
use ShapeMessage::*;
|
|
use ShapeToolFsmState::*;
|
|
|
|
let mut shape_data = &mut data.data;
|
|
|
|
if let ToolMessage::Shape(event) = event {
|
|
match (self, event) {
|
|
(Ready, DragStart) => {
|
|
shape_data.start(responses, input.viewport_bounds.size(), document, input.mouse.position);
|
|
responses.push_back(DocumentMessage::StartTransaction.into());
|
|
shape_data.path = Some(vec![generate_uuid()]);
|
|
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
|
data.sides = match tool_data.tool_options.get(&ToolType::Shape) {
|
|
Some(&ToolOptions::Shape {
|
|
shape_type: ShapeType::Polygon { vertices },
|
|
}) => vertices as u8,
|
|
_ => 6,
|
|
};
|
|
|
|
responses.push_back(
|
|
Operation::AddNgon {
|
|
path: shape_data.path.clone().unwrap(),
|
|
insert_index: -1,
|
|
transform: DAffine2::ZERO.to_cols_array(),
|
|
sides: data.sides,
|
|
style: style::PathStyle::new(None, Some(style::Fill::new(tool_data.primary_color))),
|
|
}
|
|
.into(),
|
|
);
|
|
|
|
Drawing
|
|
}
|
|
(state, Resize { center, lock_ratio }) => {
|
|
if let Some(message) = shape_data.calculate_transform(responses, input.viewport_bounds.size(), document, center, lock_ratio, input) {
|
|
responses.push_back(message);
|
|
}
|
|
|
|
state
|
|
}
|
|
(Drawing, DragStop) => {
|
|
// TODO: introduce comparison threshold when operating with canvas coordinates (https://github.com/GraphiteEditor/Graphite/issues/100)
|
|
match shape_data.drag_start == input.mouse.position {
|
|
true => responses.push_back(DocumentMessage::AbortTransaction.into()),
|
|
false => responses.push_back(DocumentMessage::CommitTransaction.into()),
|
|
}
|
|
|
|
shape_data.cleanup(responses);
|
|
|
|
Ready
|
|
}
|
|
(Drawing, Abort) => {
|
|
responses.push_back(DocumentMessage::AbortTransaction.into());
|
|
|
|
shape_data.cleanup(responses);
|
|
|
|
Ready
|
|
}
|
|
_ => self,
|
|
}
|
|
} else {
|
|
self
|
|
}
|
|
}
|
|
|
|
fn update_hints(&self, responses: &mut VecDeque<Message>) {
|
|
let hint_data = match self {
|
|
ShapeToolFsmState::Ready => HintData(vec![HintGroup(vec![
|
|
HintInfo {
|
|
key_groups: vec![],
|
|
mouse: Some(MouseMotion::LmbDrag),
|
|
label: String::from("Draw Shape"),
|
|
plus: false,
|
|
},
|
|
HintInfo {
|
|
key_groups: vec![KeysGroup(vec![Key::KeyShift])],
|
|
mouse: None,
|
|
label: String::from("Constrain 1:1 Aspect"),
|
|
plus: true,
|
|
},
|
|
HintInfo {
|
|
key_groups: vec![KeysGroup(vec![Key::KeyAlt])],
|
|
mouse: None,
|
|
label: String::from("From Center"),
|
|
plus: true,
|
|
},
|
|
])]),
|
|
ShapeToolFsmState::Drawing => HintData(vec![HintGroup(vec![
|
|
HintInfo {
|
|
key_groups: vec![KeysGroup(vec![Key::KeyShift])],
|
|
mouse: None,
|
|
label: String::from("Constrain 1:1 Aspect"),
|
|
plus: false,
|
|
},
|
|
HintInfo {
|
|
key_groups: vec![KeysGroup(vec![Key::KeyAlt])],
|
|
mouse: None,
|
|
label: String::from("From Center"),
|
|
plus: false,
|
|
},
|
|
])]),
|
|
};
|
|
|
|
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
|
}
|
|
|
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
|
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
|
|
}
|
|
}
|