mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-07-07 15:55:00 +00:00
Upgrade to the Rust 2024 edition (#2367)
* Update to rust 2024 edition * Fixes * Clean up imports * Cargo fmt again --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
927d7dd9b2
commit
beb1c6ae64
253 changed files with 980 additions and 1371 deletions
|
@ -2,9 +2,9 @@
|
||||||
name = "graphite-editor"
|
name = "graphite-editor"
|
||||||
publish = false
|
publish = false
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
rust-version = "1.82"
|
rust-version = "1.85"
|
||||||
authors = ["Graphite Authors <contact@graphite.rs>"]
|
authors = ["Graphite Authors <contact@graphite.rs>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
readme = "../README.md"
|
readme = "../README.md"
|
||||||
homepage = "https://graphite.rs"
|
homepage = "https://graphite.rs"
|
||||||
repository = "https://github.com/GraphiteEditor/Graphite"
|
repository = "https://github.com/GraphiteEditor/Graphite"
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::dispatcher::Dispatcher;
|
use crate::dispatcher::Dispatcher;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
pub use graphene_core::uuid::*;
|
pub use graphene_core::uuid::*;
|
||||||
|
|
||||||
// TODO: serialize with serde to save the current editor state
|
// TODO: serialize with serde to save the current editor state
|
||||||
|
|
|
@ -303,11 +303,7 @@ impl Dispatcher {
|
||||||
fn create_indents(queues: &[VecDeque<Message>]) -> String {
|
fn create_indents(queues: &[VecDeque<Message>]) -> String {
|
||||||
String::from_iter(queues.iter().enumerate().skip(1).map(|(index, queue)| {
|
String::from_iter(queues.iter().enumerate().skip(1).map(|(index, queue)| {
|
||||||
if index == queues.len() - 1 {
|
if index == queues.len() - 1 {
|
||||||
if queue.is_empty() {
|
if queue.is_empty() { "└── " } else { "├── " }
|
||||||
"└── "
|
|
||||||
} else {
|
|
||||||
"├── "
|
|
||||||
}
|
|
||||||
} else if queue.is_empty() {
|
} else if queue.is_empty() {
|
||||||
" "
|
" "
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
macro_rules! actions {
|
macro_rules! actions {
|
||||||
($($v:expr),* $(,)?) => {{
|
($($v:expr_2021),* $(,)?) => {{
|
||||||
vec![$(vec![$v.into()]),*]
|
vec![$(vec![$v.into()]),*]
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ macro_rules! actions {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
macro_rules! advertise_actions {
|
macro_rules! advertise_actions {
|
||||||
($($v:expr),* $(,)?) => {
|
($($v:expr_2021),* $(,)?) => {
|
||||||
fn actions(&self) -> $crate::utility_traits::ActionList {
|
fn actions(&self) -> $crate::utility_traits::ActionList {
|
||||||
actions!($($v),*)
|
actions!($($v),*)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use graph_craft::document::NodeId;
|
|
||||||
|
|
||||||
use glam::{IVec2, UVec2};
|
use glam::{IVec2, UVec2};
|
||||||
|
use graph_craft::document::NodeId;
|
||||||
|
|
||||||
/// A dialog to allow users to set some initial options about a new document.
|
/// A dialog to allow users to set some initial options about a new document.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
|
|
|
@ -26,16 +26,18 @@ impl LayoutHolder for ComingSoonDialog {
|
||||||
|
|
||||||
if let Some(issue) = self.issue {
|
if let Some(issue) = self.issue {
|
||||||
let row2 = vec![TextLabel::new("But you can help build it! Visit its issue:").widget_holder()];
|
let row2 = vec![TextLabel::new("But you can help build it! Visit its issue:").widget_holder()];
|
||||||
let row3 = vec![TextButton::new(format!("GitHub Issue #{issue}"))
|
let row3 = vec![
|
||||||
.icon(Some("Website".into()))
|
TextButton::new(format!("GitHub Issue #{issue}"))
|
||||||
.flush(true)
|
.icon(Some("Website".into()))
|
||||||
.on_update(move |_| {
|
.flush(true)
|
||||||
FrontendMessage::TriggerVisitLink {
|
.on_update(move |_| {
|
||||||
url: format!("https://github.com/GraphiteEditor/Graphite/issues/{issue}"),
|
FrontendMessage::TriggerVisitLink {
|
||||||
}
|
url: format!("https://github.com/GraphiteEditor/Graphite/issues/{issue}"),
|
||||||
.into()
|
}
|
||||||
})
|
.into()
|
||||||
.widget_holder()];
|
})
|
||||||
|
.widget_holder(),
|
||||||
|
];
|
||||||
|
|
||||||
rows.push(LayoutGroup::Row { widgets: row2 });
|
rows.push(LayoutGroup::Row { widgets: row2 });
|
||||||
rows.push(LayoutGroup::Row { widgets: row3 });
|
rows.push(LayoutGroup::Row { widgets: row3 });
|
||||||
|
|
|
@ -32,11 +32,13 @@ impl LayoutHolder for DemoArtworkDialog {
|
||||||
.flat_map(|chunk| {
|
.flat_map(|chunk| {
|
||||||
fn make_dialog(name: &str, filename: &str) -> Message {
|
fn make_dialog(name: &str, filename: &str) -> Message {
|
||||||
DialogMessage::CloseDialogAndThen {
|
DialogMessage::CloseDialogAndThen {
|
||||||
followups: vec![FrontendMessage::TriggerFetchAndOpenDocument {
|
followups: vec![
|
||||||
name: name.to_string(),
|
FrontendMessage::TriggerFetchAndOpenDocument {
|
||||||
filename: filename.to_string(),
|
name: name.to_string(),
|
||||||
}
|
filename: filename.to_string(),
|
||||||
.into()],
|
}
|
||||||
|
.into(),
|
||||||
|
],
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,7 @@ pub use about_graphite_dialog::AboutGraphiteDialog;
|
||||||
pub use close_all_documents_dialog::CloseAllDocumentsDialog;
|
pub use close_all_documents_dialog::CloseAllDocumentsDialog;
|
||||||
pub use close_document_dialog::CloseDocumentDialog;
|
pub use close_document_dialog::CloseDocumentDialog;
|
||||||
pub use coming_soon_dialog::ComingSoonDialog;
|
pub use coming_soon_dialog::ComingSoonDialog;
|
||||||
|
pub use demo_artwork_dialog::ARTWORK;
|
||||||
pub use demo_artwork_dialog::DemoArtworkDialog;
|
pub use demo_artwork_dialog::DemoArtworkDialog;
|
||||||
pub use error_dialog::ErrorDialog;
|
pub use error_dialog::ErrorDialog;
|
||||||
pub use licenses_dialog::LicensesDialog;
|
pub use licenses_dialog::LicensesDialog;
|
||||||
|
|
||||||
pub use demo_artwork_dialog::ARTWORK;
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::messages::portfolio::document::node_graph::utility_types::{
|
||||||
use crate::messages::portfolio::document::utility_types::nodes::{JsRawBuffer, LayerPanelEntry, RawBuffer};
|
use crate::messages::portfolio::document::utility_types::nodes::{JsRawBuffer, LayerPanelEntry, RawBuffer};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::utility_types::HintData;
|
use crate::messages::tool::utility_types::HintData;
|
||||||
|
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
use graphene_core::raster::color::Color;
|
use graphene_core::raster::color::Color;
|
||||||
use graphene_core::text::Font;
|
use graphene_core::text::Font;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::messages::portfolio::utility_types::Platform;
|
use crate::messages::portfolio::utility_types::Platform;
|
||||||
|
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
|
|
||||||
pub static GLOBAL_PLATFORM: OnceLock<Platform> = OnceLock::new();
|
pub static GLOBAL_PLATFORM: OnceLock<Platform> = OnceLock::new();
|
||||||
|
|
|
@ -3,7 +3,6 @@ use super::utility_types::misc::Mapping;
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::{self, Key};
|
use crate::messages::input_mapper::utility_types::input_keyboard::{self, Key};
|
||||||
use crate::messages::portfolio::utility_types::KeyboardPlatformLayout;
|
use crate::messages::portfolio::utility_types::KeyboardPlatformLayout;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
pub struct InputMapperMessageData<'a> {
|
pub struct InputMapperMessageData<'a> {
|
||||||
|
|
|
@ -11,7 +11,6 @@ use crate::messages::portfolio::document::utility_types::misc::GroupFolderType;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::tool_messages::brush_tool::BrushToolMessageOptionsUpdate;
|
use crate::messages::tool::tool_messages::brush_tool::BrushToolMessageOptionsUpdate;
|
||||||
use crate::messages::tool::tool_messages::select_tool::SelectToolPointerKeys;
|
use crate::messages::tool::tool_messages::select_tool::SelectToolPointerKeys;
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
|
|
||||||
impl From<MappingVariant> for Mapping {
|
impl From<MappingVariant> for Mapping {
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use crate::messages::portfolio::utility_types::KeyboardPlatformLayout;
|
use crate::messages::portfolio::utility_types::KeyboardPlatformLayout;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
|
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign};
|
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::consts::DRAG_THRESHOLD;
|
use crate::consts::DRAG_THRESHOLD;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
|
@ -24,7 +24,7 @@ macro_rules! modifiers {
|
||||||
/// Each handler adds or removes actions in the form of message discriminants. Here, we tie an input condition (such as a hotkey) to an action's full message.
|
/// Each handler adds or removes actions in the form of message discriminants. Here, we tie an input condition (such as a hotkey) to an action's full message.
|
||||||
/// When an action is currently available, and the user enters that input, the action's message is dispatched on the message bus.
|
/// When an action is currently available, and the user enters that input, the action's message is dispatched on the message bus.
|
||||||
macro_rules! entry {
|
macro_rules! entry {
|
||||||
($input:expr; $(modifiers=[$($modifier:ident),*],)? $(refresh_keys=[$($refresh:ident),* $(,)?],)? action_dispatch=$action_dispatch:expr$(,)?) => {
|
($input:expr_2021; $(modifiers=[$($modifier:ident),*],)? $(refresh_keys=[$($refresh:ident),* $(,)?],)? action_dispatch=$action_dispatch:expr_2021$(,)?) => {
|
||||||
&[&[
|
&[&[
|
||||||
// Cause the `action_dispatch` message to be sent when the specified input occurs.
|
// Cause the `action_dispatch` message to be sent when the specified input occurs.
|
||||||
MappingEntry {
|
MappingEntry {
|
||||||
|
@ -72,7 +72,7 @@ macro_rules! entry {
|
||||||
/// (key_up, key_down, double_click, wheel_scroll, pointer_move)
|
/// (key_up, key_down, double_click, wheel_scroll, pointer_move)
|
||||||
/// ```
|
/// ```
|
||||||
macro_rules! mapping {
|
macro_rules! mapping {
|
||||||
[$($entry:expr),* $(,)?] => {{
|
[$($entry:expr_2021),* $(,)?] => {{
|
||||||
let mut key_up = KeyMappingEntries::key_array();
|
let mut key_up = KeyMappingEntries::key_array();
|
||||||
let mut key_down = KeyMappingEntries::key_array();
|
let mut key_down = KeyMappingEntries::key_array();
|
||||||
let mut key_up_no_repeat = KeyMappingEntries::key_array();
|
let mut key_up_no_repeat = KeyMappingEntries::key_array();
|
||||||
|
@ -107,7 +107,7 @@ macro_rules! mapping {
|
||||||
|
|
||||||
/// Constructs an `ActionKeys` macro with a certain `Action` variant, conveniently wrapped in `Some()`.
|
/// Constructs an `ActionKeys` macro with a certain `Action` variant, conveniently wrapped in `Some()`.
|
||||||
macro_rules! action_keys {
|
macro_rules! action_keys {
|
||||||
($action:expr) => {
|
($action:expr_2021) => {
|
||||||
Some(crate::messages::input_mapper::utility_types::misc::ActionKeys::Action($action.into()))
|
Some(crate::messages::input_mapper::utility_types::misc::ActionKeys::Action($action.into()))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use super::input_keyboard::{all_required_modifiers_pressed, Key, KeysGroup, LayoutKeysGroup};
|
use super::input_keyboard::{Key, KeysGroup, LayoutKeysGroup, all_required_modifiers_pressed};
|
||||||
use crate::messages::input_mapper::key_mapping::MappingVariant;
|
use crate::messages::input_mapper::key_mapping::MappingVariant;
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::{KeyStates, NUMBER_OF_KEYS};
|
use crate::messages::input_mapper::utility_types::input_keyboard::{KeyStates, NUMBER_OF_KEYS};
|
||||||
use crate::messages::input_mapper::utility_types::input_mouse::NUMBER_OF_MOUSE_BUTTONS;
|
use crate::messages::input_mapper::utility_types::input_mouse::NUMBER_OF_MOUSE_BUTTONS;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, ModifierKeys};
|
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, ModifierKeys};
|
||||||
use crate::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, ViewportBounds};
|
use crate::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, ViewportBounds};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use core::time::Duration;
|
use core::time::Duration;
|
||||||
|
|
||||||
#[impl_message(Message, InputPreprocessor)]
|
#[impl_message(Message, InputPreprocessor)]
|
||||||
|
|
|
@ -3,7 +3,6 @@ use crate::messages::input_mapper::utility_types::input_mouse::{MouseButton, Mou
|
||||||
use crate::messages::input_mapper::utility_types::misc::FrameTimeInfo;
|
use crate::messages::input_mapper::utility_types::misc::FrameTimeInfo;
|
||||||
use crate::messages::portfolio::utility_types::KeyboardPlatformLayout;
|
use crate::messages::portfolio::utility_types::KeyboardPlatformLayout;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
|
|
||||||
pub struct InputPreprocessorMessageData {
|
pub struct InputPreprocessorMessageData {
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use graphene_core::raster::color::Color;
|
use graphene_core::raster::color::Color;
|
||||||
use graphene_core::text::Font;
|
use graphene_core::text::Font;
|
||||||
use graphene_std::vector::style::{FillChoice, GradientStops};
|
use graphene_std::vector::style::{FillChoice, GradientStops};
|
||||||
|
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::application::generate_uuid;
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
||||||
use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -348,11 +347,7 @@ impl LayoutGroup {
|
||||||
val.clone_from(&tooltip);
|
val.clone_from(&tooltip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if is_col {
|
if is_col { Self::Column { widgets } } else { Self::Row { widgets } }
|
||||||
Self::Column { widgets }
|
|
||||||
} else {
|
|
||||||
Self::Row { widgets }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Diffing updates self (where self is old) based on new, updating the list of modifications as it does so.
|
/// Diffing updates self (where self is old) based on new, updating the list of modifications as it does so.
|
||||||
|
|
|
@ -2,12 +2,10 @@ use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::portfolio::document::node_graph::utility_types::FrontendGraphDataType;
|
use crate::messages::portfolio::document::node_graph::utility_types::FrontendGraphDataType;
|
||||||
use crate::messages::tool::tool_messages::tool_prelude::WidgetCallback;
|
use crate::messages::tool::tool_messages::tool_prelude::WidgetCallback;
|
||||||
|
use derivative::*;
|
||||||
use graphene_std::vector::style::FillChoice;
|
use graphene_std::vector::style::FillChoice;
|
||||||
use graphite_proc_macros::WidgetBuilder;
|
use graphite_proc_macros::WidgetBuilder;
|
||||||
|
|
||||||
use derivative::*;
|
|
||||||
|
|
||||||
#[derive(Clone, Default, Derivative, serde::Serialize, serde::Deserialize, WidgetBuilder, specta::Type)]
|
#[derive(Clone, Default, Derivative, serde::Serialize, serde::Deserialize, WidgetBuilder, specta::Type)]
|
||||||
#[derivative(Debug, PartialEq)]
|
#[derivative(Debug, PartialEq)]
|
||||||
pub struct IconButton {
|
pub struct IconButton {
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
|
|
||||||
use graphene_core::{raster::curve::Curve, Color};
|
|
||||||
use graphite_proc_macros::WidgetBuilder;
|
|
||||||
|
|
||||||
use derivative::*;
|
use derivative::*;
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
|
use graphene_core::Color;
|
||||||
|
use graphene_core::raster::curve::Curve;
|
||||||
|
use graphite_proc_macros::WidgetBuilder;
|
||||||
|
|
||||||
#[derive(Clone, Derivative, serde::Serialize, serde::Deserialize, WidgetBuilder, specta::Type)]
|
#[derive(Clone, Derivative, serde::Serialize, serde::Deserialize, WidgetBuilder, specta::Type)]
|
||||||
#[derivative(Debug, PartialEq)]
|
#[derivative(Debug, PartialEq)]
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
|
use super::input_widgets::InvisibleStandinInput;
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
use crate::messages::input_mapper::utility_types::input_keyboard::KeysGroup;
|
||||||
use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use super::input_widgets::InvisibleStandinInput;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Default, specta::Type)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Default, specta::Type)]
|
||||||
pub struct MenuBarEntryChildren(pub Vec<Vec<MenuBarEntry>>);
|
pub struct MenuBarEntryChildren(pub Vec<Vec<MenuBarEntry>>);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use graphite_proc_macros::*;
|
use graphite_proc_macros::*;
|
||||||
|
|
||||||
#[impl_message]
|
#[impl_message]
|
||||||
|
|
|
@ -5,17 +5,15 @@ use crate::messages::portfolio::document::utility_types::document_metadata::Laye
|
||||||
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, FlipAxis, GridSnapping};
|
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, FlipAxis, GridSnapping};
|
||||||
use crate::messages::portfolio::utility_types::PanelType;
|
use crate::messages::portfolio::utility_types::PanelType;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
use glam::DAffine2;
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
|
use graphene_core::Color;
|
||||||
use graphene_core::raster::BlendMode;
|
use graphene_core::raster::BlendMode;
|
||||||
use graphene_core::raster::Image;
|
use graphene_core::raster::Image;
|
||||||
use graphene_core::vector::style::ViewMode;
|
use graphene_core::vector::style::ViewMode;
|
||||||
use graphene_core::Color;
|
|
||||||
use graphene_std::renderer::ClickTarget;
|
use graphene_std::renderer::ClickTarget;
|
||||||
use graphene_std::transform::Footprint;
|
use graphene_std::transform::Footprint;
|
||||||
|
|
||||||
use glam::DAffine2;
|
|
||||||
|
|
||||||
#[impl_message(Message, PortfolioMessage, Document)]
|
#[impl_message(Message, PortfolioMessage, Document)]
|
||||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub enum DocumentMessage {
|
pub enum DocumentMessage {
|
||||||
|
|
|
@ -2,10 +2,10 @@ use super::node_graph::document_node_definitions;
|
||||||
use super::node_graph::utility_types::Transform;
|
use super::node_graph::utility_types::Transform;
|
||||||
use super::overlays::utility_types::Pivot;
|
use super::overlays::utility_types::Pivot;
|
||||||
use super::utility_types::error::EditorError;
|
use super::utility_types::error::EditorError;
|
||||||
use super::utility_types::misc::{GroupFolderType, SnappingOptions, SnappingState, SNAP_FUNCTIONS_FOR_BOUNDING_BOXES, SNAP_FUNCTIONS_FOR_PATHS};
|
use super::utility_types::misc::{GroupFolderType, SNAP_FUNCTIONS_FOR_BOUNDING_BOXES, SNAP_FUNCTIONS_FOR_PATHS, SnappingOptions, SnappingState};
|
||||||
use super::utility_types::network_interface::{self, NodeNetworkInterface, TransactionStatus};
|
use super::utility_types::network_interface::{self, NodeNetworkInterface, TransactionStatus};
|
||||||
use super::utility_types::nodes::{CollapsedLayers, SelectedNodes};
|
use super::utility_types::nodes::{CollapsedLayers, SelectedNodes};
|
||||||
use crate::application::{generate_uuid, GRAPHITE_GIT_COMMIT_HASH};
|
use crate::application::{GRAPHITE_GIT_COMMIT_HASH, generate_uuid};
|
||||||
use crate::consts::{ASYMPTOTIC_EFFECT, COLOR_OVERLAY_GRAY, DEFAULT_DOCUMENT_NAME, FILE_SAVE_SUFFIX, SCALE_EFFECT, SCROLLBAR_SPACING, VIEWPORT_ROTATE_SNAP_INTERVAL};
|
use crate::consts::{ASYMPTOTIC_EFFECT, COLOR_OVERLAY_GRAY, DEFAULT_DOCUMENT_NAME, FILE_SAVE_SUFFIX, SCALE_EFFECT, SCROLLBAR_SPACING, VIEWPORT_ROTATE_SNAP_INTERVAL};
|
||||||
use crate::messages::input_mapper::utility_types::macros::action_keys;
|
use crate::messages::input_mapper::utility_types::macros::action_keys;
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
|
@ -24,17 +24,15 @@ use crate::messages::tool::tool_messages::select_tool::SelectToolPointerKeys;
|
||||||
use crate::messages::tool::tool_messages::tool_prelude::Key;
|
use crate::messages::tool::tool_messages::tool_prelude::Key;
|
||||||
use crate::messages::tool::utility_types::ToolType;
|
use crate::messages::tool::utility_types::ToolType;
|
||||||
use crate::node_graph_executor::NodeGraphExecutor;
|
use crate::node_graph_executor::NodeGraphExecutor;
|
||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
|
use glam::{DAffine2, DVec2, IVec2};
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{NodeId, NodeInput, NodeNetwork, OldNodeNetwork};
|
use graph_craft::document::{NodeId, NodeInput, NodeNetwork, OldNodeNetwork};
|
||||||
use graphene_core::raster::image::ImageFrameTable;
|
|
||||||
use graphene_core::raster::BlendMode;
|
use graphene_core::raster::BlendMode;
|
||||||
|
use graphene_core::raster::image::ImageFrameTable;
|
||||||
use graphene_core::vector::style::ViewMode;
|
use graphene_core::vector::style::ViewMode;
|
||||||
use graphene_std::renderer::{ClickTarget, Quad};
|
use graphene_std::renderer::{ClickTarget, Quad};
|
||||||
use graphene_std::vector::{path_bool_lib, PointId};
|
use graphene_std::vector::{PointId, path_bool_lib};
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2, IVec2};
|
|
||||||
|
|
||||||
pub struct DocumentMessageData<'a> {
|
pub struct DocumentMessageData<'a> {
|
||||||
pub document_id: DocumentId,
|
pub document_id: DocumentId,
|
||||||
|
@ -1497,7 +1495,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
||||||
|
|
||||||
impl DocumentMessageHandler {
|
impl DocumentMessageHandler {
|
||||||
/// Runs an intersection test with all layers and a viewport space quad
|
/// Runs an intersection test with all layers and a viewport space quad
|
||||||
pub fn intersect_quad<'a>(&'a self, viewport_quad: graphene_core::renderer::Quad, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + 'a {
|
pub fn intersect_quad<'a>(&'a self, viewport_quad: graphene_core::renderer::Quad, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + use<'a> {
|
||||||
let document_to_viewport = self.navigation_handler.calculate_offset_transform(ipp.viewport_bounds.center(), &self.document_ptz);
|
let document_to_viewport = self.navigation_handler.calculate_offset_transform(ipp.viewport_bounds.center(), &self.document_ptz);
|
||||||
let document_quad = document_to_viewport.inverse() * viewport_quad;
|
let document_quad = document_to_viewport.inverse() * viewport_quad;
|
||||||
|
|
||||||
|
@ -1505,12 +1503,12 @@ impl DocumentMessageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs an intersection test with all layers and a viewport space quad; ignoring artboards
|
/// Runs an intersection test with all layers and a viewport space quad; ignoring artboards
|
||||||
pub fn intersect_quad_no_artboards<'a>(&'a self, viewport_quad: graphene_core::renderer::Quad, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + 'a {
|
pub fn intersect_quad_no_artboards<'a>(&'a self, viewport_quad: graphene_core::renderer::Quad, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + use<'a> {
|
||||||
self.intersect_quad(viewport_quad, ipp).filter(|layer| !self.network_interface.is_artboard(&layer.to_node(), &[]))
|
self.intersect_quad(viewport_quad, ipp).filter(|layer| !self.network_interface.is_artboard(&layer.to_node(), &[]))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs an intersection test with all layers and a viewport space subpath
|
/// Runs an intersection test with all layers and a viewport space subpath
|
||||||
pub fn intersect_polygon<'a>(&'a self, mut viewport_polygon: Subpath<PointId>, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + 'a {
|
pub fn intersect_polygon<'a>(&'a self, mut viewport_polygon: Subpath<PointId>, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + use<'a> {
|
||||||
let document_to_viewport = self.navigation_handler.calculate_offset_transform(ipp.viewport_bounds.center(), &self.document_ptz);
|
let document_to_viewport = self.navigation_handler.calculate_offset_transform(ipp.viewport_bounds.center(), &self.document_ptz);
|
||||||
viewport_polygon.apply_transform(document_to_viewport.inverse());
|
viewport_polygon.apply_transform(document_to_viewport.inverse());
|
||||||
|
|
||||||
|
@ -1518,7 +1516,7 @@ impl DocumentMessageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs an intersection test with all layers and a viewport space subpath; ignoring artboards
|
/// Runs an intersection test with all layers and a viewport space subpath; ignoring artboards
|
||||||
pub fn intersect_polygon_no_artboards<'a>(&'a self, viewport_polygon: Subpath<PointId>, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + 'a {
|
pub fn intersect_polygon_no_artboards<'a>(&'a self, viewport_polygon: Subpath<PointId>, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + use<'a> {
|
||||||
self.intersect_polygon(viewport_polygon, ipp).filter(|layer| !self.network_interface.is_artboard(&layer.to_node(), &[]))
|
self.intersect_polygon(viewport_polygon, ipp).filter(|layer| !self.network_interface.is_artboard(&layer.to_node(), &[]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1562,7 +1560,7 @@ impl DocumentMessageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find all of the layers that were clicked on from a viewport space location
|
/// Find all of the layers that were clicked on from a viewport space location
|
||||||
pub fn click_xray(&self, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + '_ {
|
pub fn click_xray(&self, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + use<'_> {
|
||||||
let document_to_viewport = self.navigation_handler.calculate_offset_transform(ipp.viewport_bounds.center(), &self.document_ptz);
|
let document_to_viewport = self.navigation_handler.calculate_offset_transform(ipp.viewport_bounds.center(), &self.document_ptz);
|
||||||
let point = document_to_viewport.inverse().transform_point2(ipp.mouse.position);
|
let point = document_to_viewport.inverse().transform_point2(ipp.mouse.position);
|
||||||
ClickXRayIter::new(&self.network_interface, XRayTarget::Point(point))
|
ClickXRayIter::new(&self.network_interface, XRayTarget::Point(point))
|
||||||
|
@ -1584,7 +1582,7 @@ impl DocumentMessageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find layers under the location in viewport space that was clicked, listed by their depth in the layer tree hierarchy.
|
/// Find layers under the location in viewport space that was clicked, listed by their depth in the layer tree hierarchy.
|
||||||
pub fn click_list<'a>(&'a self, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + 'a {
|
pub fn click_list<'a>(&'a self, ipp: &InputPreprocessorMessageHandler) -> impl Iterator<Item = LayerNodeIdentifier> + use<'a> {
|
||||||
self.click_xray(ipp)
|
self.click_xray(ipp)
|
||||||
.filter(move |&layer| !self.network_interface.is_artboard(&layer.to_node(), &[]))
|
.filter(move |&layer| !self.network_interface.is_artboard(&layer.to_node(), &[]))
|
||||||
.skip_while(|&layer| layer == LayerNodeIdentifier::ROOT_PARENT)
|
.skip_while(|&layer| layer == LayerNodeIdentifier::ROOT_PARENT)
|
||||||
|
|
|
@ -2,20 +2,18 @@ use super::utility_types::TransformIn;
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::NodeTemplate;
|
use crate::messages::portfolio::document::utility_types::network_interface::NodeTemplate;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
|
use glam::{DAffine2, DVec2, IVec2};
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
use graphene_core::raster::image::ImageFrameTable;
|
|
||||||
use graphene_core::raster::BlendMode;
|
use graphene_core::raster::BlendMode;
|
||||||
|
use graphene_core::raster::image::ImageFrameTable;
|
||||||
use graphene_core::text::{Font, TypesettingConfig};
|
use graphene_core::text::{Font, TypesettingConfig};
|
||||||
use graphene_core::vector::brush_stroke::BrushStroke;
|
|
||||||
use graphene_core::vector::style::{Fill, Stroke};
|
|
||||||
use graphene_core::vector::PointId;
|
use graphene_core::vector::PointId;
|
||||||
use graphene_core::vector::VectorModificationType;
|
use graphene_core::vector::VectorModificationType;
|
||||||
|
use graphene_core::vector::brush_stroke::BrushStroke;
|
||||||
|
use graphene_core::vector::style::{Fill, Stroke};
|
||||||
use graphene_core::{Artboard, Color};
|
use graphene_core::{Artboard, Color};
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2, IVec2};
|
|
||||||
|
|
||||||
#[impl_message(Message, DocumentMessage, GraphOperation)]
|
#[impl_message(Message, DocumentMessage, GraphOperation)]
|
||||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub enum GraphOperationMessage {
|
pub enum GraphOperationMessage {
|
||||||
|
|
|
@ -5,16 +5,14 @@ use crate::messages::portfolio::document::utility_types::document_metadata::Laye
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeNetworkInterface, OutputConnector};
|
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeNetworkInterface, OutputConnector};
|
||||||
use crate::messages::portfolio::document::utility_types::nodes::CollapsedLayers;
|
use crate::messages::portfolio::document::utility_types::nodes::CollapsedLayers;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
use glam::{DAffine2, DVec2};
|
||||||
use graph_craft::document::{NodeId, NodeInput};
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
|
use graphene_core::Color;
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_core::text::{Font, TypesettingConfig};
|
use graphene_core::text::{Font, TypesettingConfig};
|
||||||
use graphene_core::vector::style::{Fill, Gradient, GradientStops, GradientType, LineCap, LineJoin, Stroke};
|
use graphene_core::vector::style::{Fill, Gradient, GradientStops, GradientType, LineCap, LineJoin, Stroke};
|
||||||
use graphene_core::Color;
|
|
||||||
use graphene_std::vector::convert_usvg_path;
|
use graphene_std::vector::convert_usvg_path;
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct ArtboardInfo {
|
struct ArtboardInfo {
|
||||||
input_node: NodeInput,
|
input_node: NodeInput,
|
||||||
|
@ -262,10 +260,9 @@ impl MessageHandler<GraphOperationMessage, GraphOperationMessageData<'_>> for Gr
|
||||||
// Modify upstream connections
|
// Modify upstream connections
|
||||||
for outward_wire in &artboard.1.output_nodes {
|
for outward_wire in &artboard.1.output_nodes {
|
||||||
let input = NodeInput::node(artboard_data[artboard.0].merge_node, 0);
|
let input = NodeInput::node(artboard_data[artboard.0].merge_node, 0);
|
||||||
let input_connector = if let Some(artboard_info) = artboard_data.get(&outward_wire.node_id().unwrap_or_default()) {
|
let input_connector = match artboard_data.get(&outward_wire.node_id().unwrap_or_default()) {
|
||||||
InputConnector::node(artboard_info.merge_node, outward_wire.input_index())
|
Some(artboard_info) => InputConnector::node(artboard_info.merge_node, outward_wire.input_index()),
|
||||||
} else {
|
_ => *outward_wire,
|
||||||
*outward_wire
|
|
||||||
};
|
};
|
||||||
responses.add(NodeGraphMessage::SetInput { input_connector, input });
|
responses.add(NodeGraphMessage::SetInput { input_connector, input });
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeNetworkInterface};
|
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeNetworkInterface};
|
||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
use graph_craft::document::{value::TaggedValue, NodeId, NodeInput};
|
|
||||||
use graphene_core::vector::PointId;
|
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
|
use graph_craft::document::value::TaggedValue;
|
||||||
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
|
use graphene_core::vector::PointId;
|
||||||
|
|
||||||
/// Convert an affine transform into the tuple `(scale, angle, translation, shear)` assuming `shear.y = 0`.
|
/// Convert an affine transform into the tuple `(scale, angle, translation, shear)` assuming `shear.y = 0`.
|
||||||
pub fn compute_scale_angle_translation_shear(transform: DAffine2) -> (DVec2, f64, DVec2, DVec2) {
|
pub fn compute_scale_angle_translation_shear(transform: DAffine2) -> (DVec2, f64, DVec2, DVec2) {
|
||||||
|
@ -89,11 +88,7 @@ pub fn get_current_transform(inputs: &[NodeInput]) -> DAffine2 {
|
||||||
|
|
||||||
/// Extract the current normalized pivot from the layer
|
/// Extract the current normalized pivot from the layer
|
||||||
pub fn get_current_normalized_pivot(inputs: &[NodeInput]) -> DVec2 {
|
pub fn get_current_normalized_pivot(inputs: &[NodeInput]) -> DVec2 {
|
||||||
if let Some(&TaggedValue::DVec2(pivot)) = inputs[5].as_value() {
|
if let Some(&TaggedValue::DVec2(pivot)) = inputs[5].as_value() { pivot } else { DVec2::splat(0.5) }
|
||||||
pivot
|
|
||||||
} else {
|
|
||||||
DVec2::splat(0.5)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 
|
/// 
|
||||||
|
|
|
@ -3,22 +3,20 @@ use crate::messages::portfolio::document::node_graph::document_node_definitions:
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::{self, InputConnector, NodeNetworkInterface, OutputConnector};
|
use crate::messages::portfolio::document::utility_types::network_interface::{self, InputConnector, NodeNetworkInterface, OutputConnector};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
|
use glam::{DAffine2, DVec2, IVec2};
|
||||||
use graph_craft::concrete;
|
use graph_craft::concrete;
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{NodeId, NodeInput};
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
use graphene_core::raster::image::ImageFrameTable;
|
|
||||||
use graphene_core::raster::BlendMode;
|
use graphene_core::raster::BlendMode;
|
||||||
|
use graphene_core::raster::image::ImageFrameTable;
|
||||||
use graphene_core::text::{Font, TypesettingConfig};
|
use graphene_core::text::{Font, TypesettingConfig};
|
||||||
use graphene_core::vector::brush_stroke::BrushStroke;
|
use graphene_core::vector::brush_stroke::BrushStroke;
|
||||||
use graphene_core::vector::style::{Fill, Stroke};
|
use graphene_core::vector::style::{Fill, Stroke};
|
||||||
use graphene_core::vector::{PointId, VectorModificationType};
|
use graphene_core::vector::{PointId, VectorModificationType};
|
||||||
use graphene_core::{Artboard, Color};
|
use graphene_core::{Artboard, Color};
|
||||||
use graphene_std::vector::{VectorData, VectorDataTable};
|
|
||||||
use graphene_std::GraphicGroupTable;
|
use graphene_std::GraphicGroupTable;
|
||||||
|
use graphene_std::vector::{VectorData, VectorDataTable};
|
||||||
use glam::{DAffine2, DVec2, IVec2};
|
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(PartialEq, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub enum TransformIn {
|
pub enum TransformIn {
|
||||||
|
@ -82,10 +80,9 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
if current_index == insert_index {
|
if current_index == insert_index {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let next_node_in_stack_id =
|
let next_node_in_stack_id = network_interface
|
||||||
network_interface
|
.input_from_connector(&post_node_input_connector, &[])
|
||||||
.input_from_connector(&post_node_input_connector, &[])
|
.and_then(|input_from_connector| if let NodeInput::Node { node_id, .. } = input_from_connector { Some(node_id) } else { None });
|
||||||
.and_then(|input_from_connector| if let NodeInput::Node { node_id, .. } = input_from_connector { Some(node_id) } else { None });
|
|
||||||
|
|
||||||
if let Some(next_node_in_stack_id) = next_node_in_stack_id {
|
if let Some(next_node_in_stack_id) = next_node_in_stack_id {
|
||||||
// Only increment index for layer nodes
|
// Only increment index for layer nodes
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
|
|
||||||
#[impl_message(Message, DocumentMessage, Navigation)]
|
#[impl_message(Message, DocumentMessage, Navigation)]
|
||||||
|
|
|
@ -10,10 +10,8 @@ use crate::messages::portfolio::document::utility_types::misc::PTZ;
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::NodeNetworkInterface;
|
use crate::messages::portfolio::document::utility_types::network_interface::NodeNetworkInterface;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
||||||
|
|
||||||
use graph_craft::document::NodeId;
|
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
|
use graph_craft::document::NodeId;
|
||||||
|
|
||||||
pub struct NavigationMessageData<'a> {
|
pub struct NavigationMessageData<'a> {
|
||||||
pub network_interface: &'a mut NodeNetworkInterface,
|
pub network_interface: &'a mut NodeNetworkInterface,
|
||||||
|
|
|
@ -8,12 +8,12 @@ use crate::messages::portfolio::document::utility_types::network_interface::{
|
||||||
use crate::messages::portfolio::utility_types::PersistentData;
|
use crate::messages::portfolio::utility_types::PersistentData;
|
||||||
use crate::messages::prelude::Message;
|
use crate::messages::prelude::Message;
|
||||||
use crate::node_graph_executor::NodeGraphExecutor;
|
use crate::node_graph_executor::NodeGraphExecutor;
|
||||||
|
use glam::DVec2;
|
||||||
|
use graph_craft::ProtoNodeIdentifier;
|
||||||
use graph_craft::concrete;
|
use graph_craft::concrete;
|
||||||
use graph_craft::document::value::*;
|
use graph_craft::document::value::*;
|
||||||
use graph_craft::document::*;
|
use graph_craft::document::*;
|
||||||
use graph_craft::imaginate_input::ImaginateSamplingMethod;
|
use graph_craft::imaginate_input::ImaginateSamplingMethod;
|
||||||
use graph_craft::ProtoNodeIdentifier;
|
|
||||||
use graphene_core::raster::brush_cache::BrushCache;
|
use graphene_core::raster::brush_cache::BrushCache;
|
||||||
use graphene_core::raster::image::ImageFrameTable;
|
use graphene_core::raster::image::ImageFrameTable;
|
||||||
use graphene_core::raster::{CellularDistanceFunction, CellularReturnType, Color, DomainWarpType, FractalType, NoiseType, RedGreenBlue, RedGreenBlueAlpha};
|
use graphene_core::raster::{CellularDistanceFunction, CellularReturnType, Color, DomainWarpType, FractalType, NoiseType, RedGreenBlue, RedGreenBlueAlpha};
|
||||||
|
@ -22,12 +22,10 @@ use graphene_core::transform::Footprint;
|
||||||
use graphene_core::vector::VectorDataTable;
|
use graphene_core::vector::VectorDataTable;
|
||||||
use graphene_core::*;
|
use graphene_core::*;
|
||||||
use graphene_std::wasm_application_io::WasmEditorApi;
|
use graphene_std::wasm_application_io::WasmEditorApi;
|
||||||
#[cfg(feature = "gpu")]
|
|
||||||
use wgpu_executor::{Bindgroup, CommandBuffer, PipelineLayout, ShaderHandle, ShaderInputFrame, WgpuShaderInput};
|
|
||||||
|
|
||||||
use glam::DVec2;
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use std::collections::{HashMap, HashSet, VecDeque};
|
use std::collections::{HashMap, HashSet, VecDeque};
|
||||||
|
#[cfg(feature = "gpu")]
|
||||||
|
use wgpu_executor::{Bindgroup, CommandBuffer, PipelineLayout, ShaderHandle, ShaderInputFrame, WgpuShaderInput};
|
||||||
|
|
||||||
pub struct NodePropertiesContext<'a> {
|
pub struct NodePropertiesContext<'a> {
|
||||||
pub persistent_data: &'a PersistentData,
|
pub persistent_data: &'a PersistentData,
|
||||||
|
@ -52,10 +50,9 @@ impl NodePropertiesContext<'_> {
|
||||||
log::error!("Could not get input properties row in call_widget_override");
|
log::error!("Could not get input properties row in call_widget_override");
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
};
|
};
|
||||||
if let Some(tooltip) = &input_properties_row.input_data.get("tooltip").and_then(|tooltip| tooltip.as_str()) {
|
match &input_properties_row.input_data.get("tooltip").and_then(|tooltip| tooltip.as_str()) {
|
||||||
layout_group.into_iter().map(|widget| widget.with_tooltip(*tooltip)).collect::<Vec<_>>()
|
Some(tooltip) => layout_group.into_iter().map(|widget| widget.with_tooltip(*tooltip)).collect::<Vec<_>>(),
|
||||||
} else {
|
_ => layout_group,
|
||||||
layout_group
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map_err(|error| {
|
.map_err(|error| {
|
||||||
|
|
|
@ -3,7 +3,6 @@ use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::{ImportOrExport, InputConnector, NodeTemplate, OutputConnector};
|
use crate::messages::portfolio::document::utility_types::network_interface::{ImportOrExport, InputConnector, NodeTemplate, OutputConnector};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use glam::IVec2;
|
use glam::IVec2;
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{NodeId, NodeInput};
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
|
|
|
@ -15,13 +15,11 @@ use crate::messages::portfolio::document::utility_types::network_interface::{
|
||||||
use crate::messages::portfolio::document::utility_types::nodes::{CollapsedLayers, LayerPanelEntry};
|
use crate::messages::portfolio::document::utility_types::nodes::{CollapsedLayers, LayerPanelEntry};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
||||||
|
use glam::{DAffine2, DVec2, IVec2};
|
||||||
use graph_craft::document::{DocumentNodeImplementation, NodeId, NodeInput};
|
use graph_craft::document::{DocumentNodeImplementation, NodeId, NodeInput};
|
||||||
use graph_craft::proto::GraphErrors;
|
use graph_craft::proto::GraphErrors;
|
||||||
use graphene_core::*;
|
use graphene_core::*;
|
||||||
use renderer::Quad;
|
use renderer::Quad;
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2, IVec2};
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -1141,11 +1139,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||||
let mut node_wires = Vec::new();
|
let mut node_wires = Vec::new();
|
||||||
let mut stack_wires = Vec::new();
|
let mut stack_wires = Vec::new();
|
||||||
for wire in overlapping_wires {
|
for wire in overlapping_wires {
|
||||||
if is_stack_wire(&wire) {
|
if is_stack_wire(&wire) { stack_wires.push(wire) } else { node_wires.push(wire) }
|
||||||
stack_wires.push(wire)
|
|
||||||
} else {
|
|
||||||
node_wires.push(wire)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auto convert node to layer when inserting on a single stack wire
|
// Auto convert node to layer when inserting on a single stack wire
|
||||||
|
@ -2068,26 +2062,23 @@ impl NodeGraphMessageHandler {
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|(wire_end, node)| node.inputs.iter().filter(|input| input.is_exposed()).enumerate().map(move |(index, input)| (input, wire_end, index)))
|
.flat_map(|(wire_end, node)| node.inputs.iter().filter(|input| input.is_exposed()).enumerate().map(move |(index, input)| (input, wire_end, index)))
|
||||||
.filter_map(|(input, &wire_end, wire_end_input_index)| {
|
.filter_map(|(input, &wire_end, wire_end_input_index)| {
|
||||||
if let NodeInput::Node {
|
match *input {
|
||||||
node_id: wire_start,
|
NodeInput::Node {
|
||||||
output_index: wire_start_output_index,
|
node_id: wire_start,
|
||||||
// TODO: add ui for lambdas
|
output_index: wire_start_output_index,
|
||||||
lambda: _,
|
// TODO: add ui for lambdas
|
||||||
} = *input
|
lambda: _,
|
||||||
{
|
} => Some(FrontendNodeWire {
|
||||||
Some(FrontendNodeWire {
|
|
||||||
wire_start: OutputConnector::node(wire_start, wire_start_output_index),
|
wire_start: OutputConnector::node(wire_start, wire_start_output_index),
|
||||||
wire_end: InputConnector::node(wire_end, wire_end_input_index),
|
wire_end: InputConnector::node(wire_end, wire_end_input_index),
|
||||||
dashed: false,
|
dashed: false,
|
||||||
})
|
}),
|
||||||
} else if let NodeInput::Network { import_index, .. } = *input {
|
NodeInput::Network { import_index, .. } => Some(FrontendNodeWire {
|
||||||
Some(FrontendNodeWire {
|
|
||||||
wire_start: OutputConnector::Import(import_index),
|
wire_start: OutputConnector::Import(import_index),
|
||||||
wire_end: InputConnector::node(wire_end, wire_end_input_index),
|
wire_end: InputConnector::node(wire_end, wire_end_input_index),
|
||||||
dashed: false,
|
dashed: false,
|
||||||
})
|
}),
|
||||||
} else {
|
_ => None,
|
||||||
None
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
@ -2281,16 +2272,12 @@ impl NodeGraphMessageHandler {
|
||||||
let mut current_network = network_interface.nested_network(¤t_network_path).unwrap();
|
let mut current_network = network_interface.nested_network(¤t_network_path).unwrap();
|
||||||
let mut subgraph_names = vec!["Document".to_string()];
|
let mut subgraph_names = vec!["Document".to_string()];
|
||||||
for node_id in breadcrumb_network_path {
|
for node_id in breadcrumb_network_path {
|
||||||
if let Some(node) = current_network.nodes.get(node_id) {
|
let node = current_network.nodes.get(node_id)?;
|
||||||
if let Some(network) = node.implementation.get_network() {
|
if let Some(network) = node.implementation.get_network() {
|
||||||
current_network = network;
|
current_network = network;
|
||||||
};
|
|
||||||
subgraph_names.push(network_interface.frontend_display_name(node_id, ¤t_network_path));
|
|
||||||
current_network_path.push(*node_id)
|
|
||||||
} else {
|
|
||||||
// Could not get node in network in breadcrumb_network_path
|
|
||||||
return None;
|
|
||||||
};
|
};
|
||||||
|
subgraph_names.push(network_interface.frontend_display_name(node_id, ¤t_network_path));
|
||||||
|
current_network_path.push(*node_id)
|
||||||
}
|
}
|
||||||
Some(subgraph_names)
|
Some(subgraph_names)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
#![allow(clippy::too_many_arguments)]
|
#![allow(clippy::too_many_arguments)]
|
||||||
|
|
||||||
use super::document_node_definitions::{NodePropertiesContext, NODE_OVERRIDES};
|
use super::document_node_definitions::{NODE_OVERRIDES, NodePropertiesContext};
|
||||||
use super::utility_types::FrontendGraphDataType;
|
use super::utility_types::FrontendGraphDataType;
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::InputConnector;
|
use crate::messages::portfolio::document::utility_types::network_interface::InputConnector;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use dyn_any::DynAny;
|
use dyn_any::DynAny;
|
||||||
|
use glam::{DAffine2, DVec2, IVec2, UVec2};
|
||||||
|
use graph_craft::Type;
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeInput};
|
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeInput};
|
||||||
use graph_craft::imaginate_input::{ImaginateMaskStartingFill, ImaginateSamplingMethod};
|
use graph_craft::imaginate_input::{ImaginateMaskStartingFill, ImaginateSamplingMethod};
|
||||||
use graph_craft::Type;
|
|
||||||
use graphene_core::raster::curve::Curve;
|
use graphene_core::raster::curve::Curve;
|
||||||
use graphene_core::raster::image::ImageFrameTable;
|
use graphene_core::raster::image::ImageFrameTable;
|
||||||
use graphene_core::raster::{
|
use graphene_core::raster::{
|
||||||
|
@ -22,25 +22,20 @@ use graphene_core::vector::misc::CentroidType;
|
||||||
use graphene_core::vector::style::{GradientType, LineCap, LineJoin};
|
use graphene_core::vector::style::{GradientType, LineCap, LineJoin};
|
||||||
use graphene_std::application_io::TextureFrameTable;
|
use graphene_std::application_io::TextureFrameTable;
|
||||||
use graphene_std::transform::Footprint;
|
use graphene_std::transform::Footprint;
|
||||||
|
use graphene_std::vector::VectorDataTable;
|
||||||
use graphene_std::vector::misc::BooleanOperation;
|
use graphene_std::vector::misc::BooleanOperation;
|
||||||
use graphene_std::vector::style::{Fill, FillChoice, FillType, GradientStops};
|
use graphene_std::vector::style::{Fill, FillChoice, FillType, GradientStops};
|
||||||
use graphene_std::vector::VectorDataTable;
|
|
||||||
use graphene_std::{GraphicGroupTable, RasterFrame};
|
use graphene_std::{GraphicGroupTable, RasterFrame};
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2, IVec2, UVec2};
|
|
||||||
|
|
||||||
pub(crate) fn string_properties(text: &str) -> Vec<LayoutGroup> {
|
pub(crate) fn string_properties(text: &str) -> Vec<LayoutGroup> {
|
||||||
let widget = TextLabel::new(text).widget_holder();
|
let widget = TextLabel::new(text).widget_holder();
|
||||||
vec![LayoutGroup::Row { widgets: vec![widget] }]
|
vec![LayoutGroup::Row { widgets: vec![widget] }]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn optionally_update_value<T>(value: impl Fn(&T) -> Option<TaggedValue> + 'static + Send + Sync, node_id: NodeId, input_index: usize) -> impl Fn(&T) -> Message + 'static + Send + Sync {
|
fn optionally_update_value<T>(value: impl Fn(&T) -> Option<TaggedValue> + 'static + Send + Sync, node_id: NodeId, input_index: usize) -> impl Fn(&T) -> Message + 'static + Send + Sync {
|
||||||
move |input_value: &T| {
|
move |input_value: &T| match value(input_value) {
|
||||||
if let Some(value) = value(input_value) {
|
Some(value) => NodeGraphMessage::SetInputValue { node_id, input_index, value }.into(),
|
||||||
NodeGraphMessage::SetInputValue { node_id, input_index, value }.into()
|
_ => Message::NoOp,
|
||||||
} else {
|
|
||||||
Message::NoOp
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,68 +172,78 @@ pub(crate) fn property_from_type(
|
||||||
Some(x) if x == TypeId::of::<CellularDistanceFunction>() => cellular_distance_function(document_node, node_id, index, name, true, false),
|
Some(x) if x == TypeId::of::<CellularDistanceFunction>() => cellular_distance_function(document_node, node_id, index, name, true, false),
|
||||||
Some(x) if x == TypeId::of::<CellularReturnType>() => cellular_return_type(document_node, node_id, index, name, true, false),
|
Some(x) if x == TypeId::of::<CellularReturnType>() => cellular_return_type(document_node, node_id, index, name, true, false),
|
||||||
Some(x) if x == TypeId::of::<DomainWarpType>() => domain_warp_type(document_node, node_id, index, name, true, false),
|
Some(x) if x == TypeId::of::<DomainWarpType>() => domain_warp_type(document_node, node_id, index, name, true, false),
|
||||||
Some(x) if x == TypeId::of::<RelativeAbsolute>() => vec![DropdownInput::new(vec![vec![
|
Some(x) if x == TypeId::of::<RelativeAbsolute>() => vec![
|
||||||
MenuListEntry::new("Relative")
|
DropdownInput::new(vec![vec![
|
||||||
.label("Relative")
|
MenuListEntry::new("Relative")
|
||||||
.on_update(update_value(|_| TaggedValue::RelativeAbsolute(RelativeAbsolute::Relative), node_id, index)),
|
.label("Relative")
|
||||||
MenuListEntry::new("Absolute")
|
.on_update(update_value(|_| TaggedValue::RelativeAbsolute(RelativeAbsolute::Relative), node_id, index)),
|
||||||
.label("Absolute")
|
MenuListEntry::new("Absolute")
|
||||||
.on_update(update_value(|_| TaggedValue::RelativeAbsolute(RelativeAbsolute::Absolute), node_id, index)),
|
.label("Absolute")
|
||||||
]])
|
.on_update(update_value(|_| TaggedValue::RelativeAbsolute(RelativeAbsolute::Absolute), node_id, index)),
|
||||||
.widget_holder()]
|
]])
|
||||||
|
.widget_holder(),
|
||||||
|
]
|
||||||
.into(),
|
.into(),
|
||||||
Some(x) if x == TypeId::of::<LineCap>() => line_cap_widget(document_node, node_id, index, name, true),
|
Some(x) if x == TypeId::of::<LineCap>() => line_cap_widget(document_node, node_id, index, name, true),
|
||||||
Some(x) if x == TypeId::of::<LineJoin>() => line_join_widget(document_node, node_id, index, name, true),
|
Some(x) if x == TypeId::of::<LineJoin>() => line_join_widget(document_node, node_id, index, name, true),
|
||||||
Some(x) if x == TypeId::of::<FillType>() => vec![DropdownInput::new(vec![vec![
|
Some(x) if x == TypeId::of::<FillType>() => vec![
|
||||||
MenuListEntry::new("Solid")
|
DropdownInput::new(vec![vec![
|
||||||
.label("Solid")
|
MenuListEntry::new("Solid")
|
||||||
.on_update(update_value(|_| TaggedValue::FillType(FillType::Solid), node_id, index)),
|
.label("Solid")
|
||||||
MenuListEntry::new("Gradient")
|
.on_update(update_value(|_| TaggedValue::FillType(FillType::Solid), node_id, index)),
|
||||||
.label("Gradient")
|
MenuListEntry::new("Gradient")
|
||||||
.on_update(update_value(|_| TaggedValue::FillType(FillType::Gradient), node_id, index)),
|
.label("Gradient")
|
||||||
]])
|
.on_update(update_value(|_| TaggedValue::FillType(FillType::Gradient), node_id, index)),
|
||||||
.widget_holder()]
|
]])
|
||||||
|
.widget_holder(),
|
||||||
|
]
|
||||||
.into(),
|
.into(),
|
||||||
Some(x) if x == TypeId::of::<GradientType>() => vec![DropdownInput::new(vec![vec![
|
Some(x) if x == TypeId::of::<GradientType>() => vec![
|
||||||
MenuListEntry::new("Linear")
|
DropdownInput::new(vec![vec![
|
||||||
.label("Linear")
|
MenuListEntry::new("Linear")
|
||||||
.on_update(update_value(|_| TaggedValue::GradientType(GradientType::Linear), node_id, index)),
|
.label("Linear")
|
||||||
MenuListEntry::new("Radial")
|
.on_update(update_value(|_| TaggedValue::GradientType(GradientType::Linear), node_id, index)),
|
||||||
.label("Radial")
|
MenuListEntry::new("Radial")
|
||||||
.on_update(update_value(|_| TaggedValue::GradientType(GradientType::Radial), node_id, index)),
|
.label("Radial")
|
||||||
]])
|
.on_update(update_value(|_| TaggedValue::GradientType(GradientType::Radial), node_id, index)),
|
||||||
.widget_holder()]
|
]])
|
||||||
|
.widget_holder(),
|
||||||
|
]
|
||||||
.into(),
|
.into(),
|
||||||
Some(x) if x == TypeId::of::<BooleanOperation>() => boolean_operation_radio_buttons(document_node, node_id, index, name, true),
|
Some(x) if x == TypeId::of::<BooleanOperation>() => boolean_operation_radio_buttons(document_node, node_id, index, name, true),
|
||||||
Some(x) if x == TypeId::of::<CentroidType>() => centroid_widget(document_node, node_id, index),
|
Some(x) if x == TypeId::of::<CentroidType>() => centroid_widget(document_node, node_id, index),
|
||||||
Some(x) if x == TypeId::of::<LuminanceCalculation>() => luminance_calculation(document_node, node_id, index, name, true),
|
Some(x) if x == TypeId::of::<LuminanceCalculation>() => luminance_calculation(document_node, node_id, index, name, true),
|
||||||
Some(x) if x == TypeId::of::<ImaginateSamplingMethod>() => vec![DropdownInput::new(
|
Some(x) if x == TypeId::of::<ImaginateSamplingMethod>() => vec![
|
||||||
ImaginateSamplingMethod::list()
|
DropdownInput::new(
|
||||||
.into_iter()
|
ImaginateSamplingMethod::list()
|
||||||
.map(|method| {
|
.into_iter()
|
||||||
vec![MenuListEntry::new(format!("{:?}", method)).label(method.to_string()).on_update(update_value(
|
.map(|method| {
|
||||||
move |_| TaggedValue::ImaginateSamplingMethod(method),
|
vec![MenuListEntry::new(format!("{:?}", method)).label(method.to_string()).on_update(update_value(
|
||||||
node_id,
|
move |_| TaggedValue::ImaginateSamplingMethod(method),
|
||||||
index,
|
node_id,
|
||||||
))]
|
index,
|
||||||
})
|
))]
|
||||||
.collect(),
|
})
|
||||||
)
|
.collect(),
|
||||||
.widget_holder()]
|
)
|
||||||
|
.widget_holder(),
|
||||||
|
]
|
||||||
.into(),
|
.into(),
|
||||||
Some(x) if x == TypeId::of::<ImaginateMaskStartingFill>() => vec![DropdownInput::new(
|
Some(x) if x == TypeId::of::<ImaginateMaskStartingFill>() => vec![
|
||||||
ImaginateMaskStartingFill::list()
|
DropdownInput::new(
|
||||||
.into_iter()
|
ImaginateMaskStartingFill::list()
|
||||||
.map(|fill| {
|
.into_iter()
|
||||||
vec![MenuListEntry::new(format!("{:?}", fill)).label(fill.to_string()).on_update(update_value(
|
.map(|fill| {
|
||||||
move |_| TaggedValue::ImaginateMaskStartingFill(fill),
|
vec![MenuListEntry::new(format!("{:?}", fill)).label(fill.to_string()).on_update(update_value(
|
||||||
node_id,
|
move |_| TaggedValue::ImaginateMaskStartingFill(fill),
|
||||||
index,
|
node_id,
|
||||||
))]
|
index,
|
||||||
})
|
))]
|
||||||
.collect(),
|
})
|
||||||
)
|
.collect(),
|
||||||
.widget_holder()]
|
)
|
||||||
|
.widget_holder(),
|
||||||
|
]
|
||||||
.into(),
|
.into(),
|
||||||
_ => {
|
_ => {
|
||||||
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, true);
|
let mut widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, true);
|
||||||
|
@ -313,7 +318,7 @@ pub fn bool_widget(document_node: &DocumentNode, node_id: NodeId, index: usize,
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return vec![];
|
return vec![];
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::Bool(x)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::Bool(x)) = input.as_non_exposed_value() {
|
||||||
widgets.extend_from_slice(&[
|
widgets.extend_from_slice(&[
|
||||||
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
Separator::new(SeparatorType::Unrelated).widget_holder(),
|
||||||
checkbox_input
|
checkbox_input
|
||||||
|
@ -342,7 +347,7 @@ pub fn footprint_widget(document_node: &DocumentNode, node_id: NodeId, index: us
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return vec![];
|
return vec![];
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::Footprint(footprint)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::Footprint(footprint)) = input.as_non_exposed_value() {
|
||||||
let top_left = footprint.transform.transform_point2(DVec2::ZERO);
|
let top_left = footprint.transform.transform_point2(DVec2::ZERO);
|
||||||
let bounds = footprint.scale();
|
let bounds = footprint.scale();
|
||||||
let oversample = footprint.resolution.as_dvec2() / bounds;
|
let oversample = footprint.resolution.as_dvec2() / bounds;
|
||||||
|
@ -752,7 +757,7 @@ pub fn color_channel(document_node: &DocumentNode, node_id: NodeId, index: usize
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::RedGreenBlue(mode)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::RedGreenBlue(mode)) = input.as_non_exposed_value() {
|
||||||
let calculation_modes = [RedGreenBlue::Red, RedGreenBlue::Green, RedGreenBlue::Blue];
|
let calculation_modes = [RedGreenBlue::Red, RedGreenBlue::Green, RedGreenBlue::Blue];
|
||||||
let mut entries = Vec::with_capacity(calculation_modes.len());
|
let mut entries = Vec::with_capacity(calculation_modes.len());
|
||||||
for method in calculation_modes {
|
for method in calculation_modes {
|
||||||
|
@ -779,7 +784,7 @@ pub fn rgba_channel(document_node: &DocumentNode, node_id: NodeId, index: usize,
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::RedGreenBlueAlpha(mode)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::RedGreenBlueAlpha(mode)) = input.as_non_exposed_value() {
|
||||||
let calculation_modes = [RedGreenBlueAlpha::Red, RedGreenBlueAlpha::Green, RedGreenBlueAlpha::Blue, RedGreenBlueAlpha::Alpha];
|
let calculation_modes = [RedGreenBlueAlpha::Red, RedGreenBlueAlpha::Green, RedGreenBlueAlpha::Blue, RedGreenBlueAlpha::Alpha];
|
||||||
let mut entries = Vec::with_capacity(calculation_modes.len());
|
let mut entries = Vec::with_capacity(calculation_modes.len());
|
||||||
for method in calculation_modes {
|
for method in calculation_modes {
|
||||||
|
@ -807,7 +812,7 @@ pub fn noise_type(document_node: &DocumentNode, node_id: NodeId, index: usize, n
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::NoiseType(noise_type)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::NoiseType(noise_type)) = input.as_non_exposed_value() {
|
||||||
let entries = NoiseType::list()
|
let entries = NoiseType::list()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|noise_type| {
|
.map(|noise_type| {
|
||||||
|
@ -833,7 +838,7 @@ pub fn fractal_type(document_node: &DocumentNode, node_id: NodeId, index: usize,
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::FractalType(fractal_type)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::FractalType(fractal_type)) = input.as_non_exposed_value() {
|
||||||
let entries = FractalType::list()
|
let entries = FractalType::list()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|fractal_type| {
|
.map(|fractal_type| {
|
||||||
|
@ -859,7 +864,7 @@ pub fn cellular_distance_function(document_node: &DocumentNode, node_id: NodeId,
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::CellularDistanceFunction(cellular_distance_function)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::CellularDistanceFunction(cellular_distance_function)) = input.as_non_exposed_value() {
|
||||||
let entries = CellularDistanceFunction::list()
|
let entries = CellularDistanceFunction::list()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|cellular_distance_function| {
|
.map(|cellular_distance_function| {
|
||||||
|
@ -888,7 +893,7 @@ pub fn cellular_return_type(document_node: &DocumentNode, node_id: NodeId, index
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::CellularReturnType(cellular_return_type)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::CellularReturnType(cellular_return_type)) = input.as_non_exposed_value() {
|
||||||
let entries = CellularReturnType::list()
|
let entries = CellularReturnType::list()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|cellular_return_type| {
|
.map(|cellular_return_type| {
|
||||||
|
@ -914,7 +919,7 @@ pub fn domain_warp_type(document_node: &DocumentNode, node_id: NodeId, index: us
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::DomainWarpType(domain_warp_type)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::DomainWarpType(domain_warp_type)) = input.as_non_exposed_value() {
|
||||||
let entries = DomainWarpType::list()
|
let entries = DomainWarpType::list()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|domain_warp_type| {
|
.map(|domain_warp_type| {
|
||||||
|
@ -940,7 +945,7 @@ pub fn blend_mode(document_node: &DocumentNode, node_id: NodeId, index: usize, n
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::BlendMode(blend_mode)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::BlendMode(blend_mode)) = input.as_non_exposed_value() {
|
||||||
let entries = BlendMode::list_svg_subset()
|
let entries = BlendMode::list_svg_subset()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|category| {
|
.map(|category| {
|
||||||
|
@ -973,7 +978,7 @@ pub fn luminance_calculation(document_node: &DocumentNode, node_id: NodeId, inde
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::LuminanceCalculation(calculation)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::LuminanceCalculation(calculation)) = input.as_non_exposed_value() {
|
||||||
let calculation_modes = LuminanceCalculation::list();
|
let calculation_modes = LuminanceCalculation::list();
|
||||||
let mut entries = Vec::with_capacity(calculation_modes.len());
|
let mut entries = Vec::with_capacity(calculation_modes.len());
|
||||||
for method in calculation_modes {
|
for method in calculation_modes {
|
||||||
|
@ -1001,7 +1006,7 @@ pub fn boolean_operation_radio_buttons(document_node: &DocumentNode, node_id: No
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::BooleanOperation(calculation)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::BooleanOperation(calculation)) = input.as_non_exposed_value() {
|
||||||
let operations = BooleanOperation::list();
|
let operations = BooleanOperation::list();
|
||||||
let icons = BooleanOperation::icons();
|
let icons = BooleanOperation::icons();
|
||||||
let mut entries = Vec::with_capacity(operations.len());
|
let mut entries = Vec::with_capacity(operations.len());
|
||||||
|
@ -1030,7 +1035,7 @@ pub fn line_cap_widget(document_node: &DocumentNode, node_id: NodeId, index: usi
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::LineCap(line_cap)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::LineCap(line_cap)) = input.as_non_exposed_value() {
|
||||||
let entries = [("Butt", LineCap::Butt), ("Round", LineCap::Round), ("Square", LineCap::Square)]
|
let entries = [("Butt", LineCap::Butt), ("Round", LineCap::Round), ("Square", LineCap::Square)]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, val)| {
|
.map(|(name, val)| {
|
||||||
|
@ -1055,7 +1060,7 @@ pub fn line_join_widget(document_node: &DocumentNode, node_id: NodeId, index: us
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::LineJoin(line_join)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::LineJoin(line_join)) = input.as_non_exposed_value() {
|
||||||
let entries = [("Miter", LineJoin::Miter), ("Bevel", LineJoin::Bevel), ("Round", LineJoin::Round)]
|
let entries = [("Miter", LineJoin::Miter), ("Bevel", LineJoin::Bevel), ("Round", LineJoin::Round)]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, val)| {
|
.map(|(name, val)| {
|
||||||
|
@ -1101,7 +1106,7 @@ pub fn color_widget(document_node: &DocumentNode, node_id: NodeId, index: usize,
|
||||||
.on_commit(commit_value)
|
.on_commit(commit_value)
|
||||||
.widget_holder(),
|
.widget_holder(),
|
||||||
),
|
),
|
||||||
TaggedValue::GradientStops(ref x) => widgets.push(
|
TaggedValue::GradientStops(x) => widgets.push(
|
||||||
color_button
|
color_button
|
||||||
.value(FillChoice::Gradient(x.clone()))
|
.value(FillChoice::Gradient(x.clone()))
|
||||||
.on_update(update_value(
|
.on_update(update_value(
|
||||||
|
@ -1143,7 +1148,7 @@ pub fn centroid_widget(document_node: &DocumentNode, node_id: NodeId, index: usi
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return LayoutGroup::Row { widgets: vec![] };
|
return LayoutGroup::Row { widgets: vec![] };
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::CentroidType(centroid_type)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::CentroidType(centroid_type)) = input.as_non_exposed_value() {
|
||||||
let entries = vec![
|
let entries = vec![
|
||||||
RadioEntryData::new("area")
|
RadioEntryData::new("area")
|
||||||
.label("Area")
|
.label("Area")
|
||||||
|
@ -1223,13 +1228,10 @@ pub fn query_assign_colors_randomize(node_id: NodeId, context: &NodePropertiesCo
|
||||||
let document_node = get_document_node(node_id, context)?;
|
let document_node = get_document_node(node_id, context)?;
|
||||||
// This is safe since the node is a proto node and the implementation cannot be changed.
|
// This is safe since the node is a proto node and the implementation cannot be changed.
|
||||||
let randomize_index = 5;
|
let randomize_index = 5;
|
||||||
Ok(
|
Ok(match document_node.inputs.get(randomize_index).and_then(|input| input.as_value()) {
|
||||||
if let Some(&TaggedValue::Bool(randomize_enabled)) = &document_node.inputs.get(randomize_index).and_then(|input| input.as_value()) {
|
Some(TaggedValue::Bool(randomize_enabled)) => *randomize_enabled,
|
||||||
randomize_enabled
|
_ => false,
|
||||||
} else {
|
})
|
||||||
false
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn channel_mixer_properties(node_id: NodeId, context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
pub(crate) fn channel_mixer_properties(node_id: NodeId, context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
|
||||||
|
@ -1244,10 +1246,9 @@ pub(crate) fn channel_mixer_properties(node_id: NodeId, context: &mut NodeProper
|
||||||
// Monochrome
|
// Monochrome
|
||||||
let monochrome_index = 1;
|
let monochrome_index = 1;
|
||||||
let monochrome = bool_widget(document_node, node_id, monochrome_index, "Monochrome", CheckboxInput::default(), true);
|
let monochrome = bool_widget(document_node, node_id, monochrome_index, "Monochrome", CheckboxInput::default(), true);
|
||||||
let is_monochrome = if let Some(&TaggedValue::Bool(monochrome_choice)) = &document_node.inputs[monochrome_index].as_value() {
|
let is_monochrome = match document_node.inputs[monochrome_index].as_value() {
|
||||||
monochrome_choice
|
Some(TaggedValue::Bool(monochrome_choice)) => *monochrome_choice,
|
||||||
} else {
|
_ => false,
|
||||||
false
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Output channel choice
|
// Output channel choice
|
||||||
|
@ -1277,11 +1278,12 @@ pub(crate) fn channel_mixer_properties(node_id: NodeId, context: &mut NodeProper
|
||||||
output_channel.extend([RadioInput::new(entries).selected_index(Some(choice as u32)).widget_holder()]);
|
output_channel.extend([RadioInput::new(entries).selected_index(Some(choice as u32)).widget_holder()]);
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_output_channel = if let Some(&TaggedValue::RedGreenBlue(choice)) = &document_node.inputs[output_channel_index].as_value() {
|
let is_output_channel = match &document_node.inputs[output_channel_index].as_value() {
|
||||||
choice
|
Some(TaggedValue::RedGreenBlue(choice)) => choice,
|
||||||
} else {
|
_ => {
|
||||||
warn!("Channel Mixer node properties panel could not be displayed.");
|
warn!("Channel Mixer node properties panel could not be displayed.");
|
||||||
return vec![];
|
return vec![];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Channel values
|
// Channel values
|
||||||
|
@ -1376,11 +1378,12 @@ pub(crate) fn selective_color_properties(node_id: NodeId, context: &mut NodeProp
|
||||||
colors.extend([DropdownInput::new(entries).selected_index(Some(choice as u32)).widget_holder()]);
|
colors.extend([DropdownInput::new(entries).selected_index(Some(choice as u32)).widget_holder()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
let colors_choice_index = if let Some(&TaggedValue::SelectiveColorChoice(choice)) = &document_node.inputs[colors_index].as_value() {
|
let colors_choice_index = match &document_node.inputs[colors_index].as_value() {
|
||||||
choice
|
Some(TaggedValue::SelectiveColorChoice(choice)) => choice,
|
||||||
} else {
|
_ => {
|
||||||
warn!("Selective Color node properties panel could not be displayed.");
|
warn!("Selective Color node properties panel could not be displayed.");
|
||||||
return vec![];
|
return vec![];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// CMYK
|
// CMYK
|
||||||
|
@ -1409,7 +1412,7 @@ pub(crate) fn selective_color_properties(node_id: NodeId, context: &mut NodeProp
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return vec![];
|
return vec![];
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::RelativeAbsolute(relative_or_absolute)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::RelativeAbsolute(relative_or_absolute)) = input.as_non_exposed_value() {
|
||||||
let entries = vec![
|
let entries = vec![
|
||||||
RadioEntryData::new("relative")
|
RadioEntryData::new("relative")
|
||||||
.label("Relative")
|
.label("Relative")
|
||||||
|
@ -1495,7 +1498,7 @@ pub(crate) fn rectangle_properties(node_id: NodeId, context: &mut NodeProperties
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
return vec![];
|
return vec![];
|
||||||
};
|
};
|
||||||
if let Some(&TaggedValue::Bool(is_individual)) = &input.as_non_exposed_value() {
|
if let Some(&TaggedValue::Bool(is_individual)) = input.as_non_exposed_value() {
|
||||||
// Values
|
// Values
|
||||||
let Some(input) = document_node.inputs.get(corner_radius_index) else {
|
let Some(input) = document_node.inputs.get(corner_radius_index) else {
|
||||||
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
log::warn!("A widget failed to be built because its node's input index is invalid.");
|
||||||
|
@ -2216,7 +2219,7 @@ pub(crate) fn fill_properties(node_id: NodeId, context: &mut NodePropertiesConte
|
||||||
|
|
||||||
let mut widgets_first_row = start_widgets(document_node, node_id, fill_index, "Fill", FrontendGraphDataType::General, true);
|
let mut widgets_first_row = start_widgets(document_node, node_id, fill_index, "Fill", FrontendGraphDataType::General, true);
|
||||||
|
|
||||||
let (fill, backup_color, backup_gradient) = if let (Some(TaggedValue::Fill(fill)), Some(&TaggedValue::OptionalColor(backup_color)), Some(TaggedValue::Gradient(backup_gradient))) = (
|
let (fill, backup_color, backup_gradient) = if let (Some(TaggedValue::Fill(fill)), &Some(&TaggedValue::OptionalColor(backup_color)), Some(TaggedValue::Gradient(backup_gradient))) = (
|
||||||
&document_node.inputs[fill_index].as_value(),
|
&document_node.inputs[fill_index].as_value(),
|
||||||
&document_node.inputs[backup_color_index].as_value(),
|
&document_node.inputs[backup_color_index].as_value(),
|
||||||
&document_node.inputs[backup_gradient_index].as_value(),
|
&document_node.inputs[backup_gradient_index].as_value(),
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use graph_craft::document::value::TaggedValue;
|
|
||||||
use graph_craft::document::NodeId;
|
|
||||||
use graphene_core::Type;
|
|
||||||
|
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, OutputConnector, TypeSource};
|
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, OutputConnector, TypeSource};
|
||||||
|
use graph_craft::document::NodeId;
|
||||||
|
use graph_craft::document::value::TaggedValue;
|
||||||
|
use graphene_core::Type;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||||
pub enum FrontendGraphDataType {
|
pub enum FrontendGraphDataType {
|
||||||
|
|
|
@ -2,11 +2,9 @@ use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||||
use crate::messages::portfolio::document::utility_types::misc::{GridSnapping, GridType};
|
use crate::messages::portfolio::document::utility_types::misc::{GridSnapping, GridType};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
use glam::DVec2;
|
||||||
use graphene_core::raster::color::Color;
|
use graphene_core::raster::color::Color;
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
|
|
||||||
use glam::DVec2;
|
|
||||||
use graphene_std::vector::style::FillChoice;
|
use graphene_std::vector::style::FillChoice;
|
||||||
|
|
||||||
fn grid_overlay_rectangular(document: &DocumentMessageHandler, overlay_context: &mut OverlayContext, spacing: DVec2) {
|
fn grid_overlay_rectangular(document: &DocumentMessageHandler, overlay_context: &mut OverlayContext, spacing: DVec2) {
|
||||||
|
@ -211,7 +209,7 @@ pub fn grid_overlay(document: &DocumentMessageHandler, overlay_context: &mut Ove
|
||||||
|
|
||||||
pub fn overlay_options(grid: &GridSnapping) -> Vec<LayoutGroup> {
|
pub fn overlay_options(grid: &GridSnapping) -> Vec<LayoutGroup> {
|
||||||
let mut widgets = Vec::new();
|
let mut widgets = Vec::new();
|
||||||
fn update_val<I>(grid: &GridSnapping, update: impl Fn(&mut GridSnapping, &I)) -> impl Fn(&I) -> Message {
|
fn update_val<I, F: Fn(&mut GridSnapping, &I)>(grid: &GridSnapping, update: F) -> impl Fn(&I) -> Message + use<I, F> {
|
||||||
let grid = grid.clone();
|
let grid = grid.clone();
|
||||||
move |input: &I| {
|
move |input: &I| {
|
||||||
let mut grid = grid.clone();
|
let mut grid = grid.clone();
|
||||||
|
@ -220,7 +218,7 @@ pub fn overlay_options(grid: &GridSnapping) -> Vec<LayoutGroup> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let update_origin = |grid, update: fn(&mut GridSnapping) -> Option<&mut f64>| {
|
let update_origin = |grid, update: fn(&mut GridSnapping) -> Option<&mut f64>| {
|
||||||
update_val::<NumberInput>(grid, move |grid, val| {
|
update_val::<NumberInput, _>(grid, move |grid, val| {
|
||||||
if let Some(val) = val.value {
|
if let Some(val) = val.value {
|
||||||
if let Some(update) = update(grid) {
|
if let Some(update) = update(grid) {
|
||||||
*update = val;
|
*update = val;
|
||||||
|
@ -229,7 +227,7 @@ pub fn overlay_options(grid: &GridSnapping) -> Vec<LayoutGroup> {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let update_color = |grid, update: fn(&mut GridSnapping) -> Option<&mut Color>| {
|
let update_color = |grid, update: fn(&mut GridSnapping) -> Option<&mut Color>| {
|
||||||
update_val::<ColorInput>(grid, move |grid, color| {
|
update_val::<ColorInput, _>(grid, move |grid, color| {
|
||||||
if let FillChoice::Solid(color) = color.value {
|
if let FillChoice::Solid(color) = color.value {
|
||||||
if let Some(update_color) = update(grid) {
|
if let Some(update_color) = update(grid) {
|
||||||
*update_color = color;
|
*update_color = color;
|
||||||
|
@ -238,7 +236,7 @@ pub fn overlay_options(grid: &GridSnapping) -> Vec<LayoutGroup> {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let update_display = |grid, update: fn(&mut GridSnapping) -> Option<&mut bool>| {
|
let update_display = |grid, update: fn(&mut GridSnapping) -> Option<&mut bool>| {
|
||||||
update_val::<CheckboxInput>(grid, move |grid, checkbox| {
|
update_val::<CheckboxInput, _>(grid, move |grid, checkbox| {
|
||||||
if let Some(update) = update(grid) {
|
if let Some(update) = update(grid) {
|
||||||
*update = checkbox.checked;
|
*update = checkbox.checked;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::utility_types::{empty_provider, OverlayProvider};
|
use super::utility_types::{OverlayProvider, empty_provider};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
#[impl_message(Message, DocumentMessage, Overlays)]
|
#[impl_message(Message, DocumentMessage, Overlays)]
|
||||||
|
|
|
@ -2,12 +2,10 @@ use super::utility_types::{DrawHandles, OverlayContext};
|
||||||
use crate::consts::HIDE_HANDLE_DISTANCE;
|
use crate::consts::HIDE_HANDLE_DISTANCE;
|
||||||
use crate::messages::tool::common_functionality::shape_editor::{SelectedLayerState, ShapeState};
|
use crate::messages::tool::common_functionality::shape_editor::{SelectedLayerState, ShapeState};
|
||||||
use crate::messages::tool::tool_messages::tool_prelude::{DocumentMessageHandler, PreferencesMessageHandler};
|
use crate::messages::tool::tool_messages::tool_prelude::{DocumentMessageHandler, PreferencesMessageHandler};
|
||||||
|
|
||||||
use graphene_core::vector::ManipulatorPointId;
|
|
||||||
use graphene_std::vector::{PointId, SegmentId};
|
|
||||||
|
|
||||||
use bezier_rs::{Bezier, BezierHandles};
|
use bezier_rs::{Bezier, BezierHandles};
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
|
use graphene_core::vector::ManipulatorPointId;
|
||||||
|
use graphene_std::vector::{PointId, SegmentId};
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
|
|
||||||
pub fn overlay_canvas_element() -> Option<web_sys::HtmlCanvasElement> {
|
pub fn overlay_canvas_element() -> Option<web_sys::HtmlCanvasElement> {
|
||||||
|
|
|
@ -4,14 +4,12 @@ use crate::consts::{
|
||||||
COMPASS_ROSE_RING_INNER_DIAMETER, MANIPULATOR_GROUP_MARKER_SIZE, PIVOT_CROSSHAIR_LENGTH, PIVOT_CROSSHAIR_THICKNESS, PIVOT_DIAMETER,
|
COMPASS_ROSE_RING_INNER_DIAMETER, MANIPULATOR_GROUP_MARKER_SIZE, PIVOT_CROSSHAIR_LENGTH, PIVOT_CROSSHAIR_THICKNESS, PIVOT_DIAMETER,
|
||||||
};
|
};
|
||||||
use crate::messages::prelude::Message;
|
use crate::messages::prelude::Message;
|
||||||
|
|
||||||
use bezier_rs::{Bezier, Subpath};
|
use bezier_rs::{Bezier, Subpath};
|
||||||
use graphene_core::renderer::Quad;
|
|
||||||
use graphene_std::vector::{PointId, SegmentId, VectorData};
|
|
||||||
|
|
||||||
use core::borrow::Borrow;
|
use core::borrow::Borrow;
|
||||||
use core::f64::consts::{FRAC_PI_2, TAU};
|
use core::f64::consts::{FRAC_PI_2, TAU};
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
|
use graphene_core::renderer::Quad;
|
||||||
|
use graphene_std::vector::{PointId, SegmentId, VectorData};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use wasm_bindgen::JsValue;
|
use wasm_bindgen::JsValue;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use graph_craft::document::NodeId;
|
|
||||||
|
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::NodeNetworkInterface;
|
use crate::messages::portfolio::document::utility_types::network_interface::NodeNetworkInterface;
|
||||||
use crate::node_graph_executor::NodeGraphExecutor;
|
use crate::node_graph_executor::NodeGraphExecutor;
|
||||||
|
use graph_craft::document::NodeId;
|
||||||
|
|
||||||
pub struct PropertiesPanelMessageHandlerData<'a> {
|
pub struct PropertiesPanelMessageHandlerData<'a> {
|
||||||
pub network_interface: &'a mut NodeNetworkInterface,
|
pub network_interface: &'a mut NodeNetworkInterface,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use super::network_interface::NodeTemplate;
|
use super::network_interface::NodeTemplate;
|
||||||
|
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
|
use super::network_interface::NodeNetworkInterface;
|
||||||
use crate::messages::portfolio::document::graph_operation::transform_utils;
|
use crate::messages::portfolio::document::graph_operation::transform_utils;
|
||||||
use crate::messages::portfolio::document::graph_operation::utility_types::ModifyInputsContext;
|
use crate::messages::portfolio::document::graph_operation::utility_types::ModifyInputsContext;
|
||||||
|
use glam::{DAffine2, DVec2};
|
||||||
use super::network_interface::NodeNetworkInterface;
|
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
use graphene_core::renderer::ClickTarget;
|
use graphene_core::renderer::ClickTarget;
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_core::transform::Footprint;
|
use graphene_core::transform::Footprint;
|
||||||
use graphene_std::vector::{PointId, VectorData};
|
use graphene_std::vector::{PointId, VectorData};
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::num::NonZeroU64;
|
use std::num::NonZeroU64;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use graphene_core::raster::color::Color;
|
use graphene_core::raster::color::Color;
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
/// The error type used by the Graphite editor.
|
/// The error type used by the Graphite editor.
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use crate::consts::COLOR_OVERLAY_GRAY;
|
use crate::consts::COLOR_OVERLAY_GRAY;
|
||||||
|
|
||||||
use graphene_core::raster::Color;
|
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
|
use graphene_core::raster::Color;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
|
|
@ -3,21 +3,21 @@ use super::misc::PTZ;
|
||||||
use super::nodes::SelectedNodes;
|
use super::nodes::SelectedNodes;
|
||||||
use crate::consts::{EXPORTS_TO_RIGHT_EDGE_PIXEL_GAP, EXPORTS_TO_TOP_EDGE_PIXEL_GAP, GRID_SIZE, IMPORTS_TO_LEFT_EDGE_PIXEL_GAP, IMPORTS_TO_TOP_EDGE_PIXEL_GAP};
|
use crate::consts::{EXPORTS_TO_RIGHT_EDGE_PIXEL_GAP, EXPORTS_TO_TOP_EDGE_PIXEL_GAP, GRID_SIZE, IMPORTS_TO_LEFT_EDGE_PIXEL_GAP, IMPORTS_TO_TOP_EDGE_PIXEL_GAP};
|
||||||
use crate::messages::portfolio::document::graph_operation::utility_types::ModifyInputsContext;
|
use crate::messages::portfolio::document::graph_operation::utility_types::ModifyInputsContext;
|
||||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::{resolve_document_node_type, DocumentNodeDefinition};
|
use crate::messages::portfolio::document::node_graph::document_node_definitions::{DocumentNodeDefinition, resolve_document_node_type};
|
||||||
use crate::messages::portfolio::document::node_graph::utility_types::{Direction, FrontendClickTargets, FrontendGraphDataType, FrontendGraphInput, FrontendGraphOutput};
|
use crate::messages::portfolio::document::node_graph::utility_types::{Direction, FrontendClickTargets, FrontendGraphDataType, FrontendGraphInput, FrontendGraphOutput};
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||||
use crate::messages::tool::tool_messages::tool_prelude::NumberInputMode;
|
use crate::messages::tool::tool_messages::tool_prelude::NumberInputMode;
|
||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
use graph_craft::document::{value::TaggedValue, DocumentNode, DocumentNodeImplementation, NodeId, NodeInput, NodeNetwork, OldDocumentNodeImplementation, OldNodeNetwork};
|
use glam::{DAffine2, DVec2, IVec2};
|
||||||
use graph_craft::{concrete, Type};
|
use graph_craft::document::value::TaggedValue;
|
||||||
|
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeInput, NodeNetwork, OldDocumentNodeImplementation, OldNodeNetwork};
|
||||||
|
use graph_craft::{Type, concrete};
|
||||||
use graphene_std::renderer::{ClickTarget, Quad};
|
use graphene_std::renderer::{ClickTarget, Quad};
|
||||||
use graphene_std::transform::Footprint;
|
use graphene_std::transform::Footprint;
|
||||||
use graphene_std::vector::{PointId, VectorData, VectorModificationType};
|
use graphene_std::vector::{PointId, VectorData, VectorModificationType};
|
||||||
use interpreted_executor::{dynamic_executor::ResolvedDocumentNodeTypes, node_registry::NODE_REGISTRY};
|
use interpreted_executor::dynamic_executor::ResolvedDocumentNodeTypes;
|
||||||
|
use interpreted_executor::node_registry::NODE_REGISTRY;
|
||||||
use glam::{DAffine2, DVec2, IVec2};
|
use serde_json::{Value, json};
|
||||||
use serde_json::{json, Value};
|
|
||||||
use std::collections::{HashMap, HashSet, VecDeque};
|
use std::collections::{HashMap, HashSet, VecDeque};
|
||||||
use std::hash::{DefaultHasher, Hash, Hasher};
|
use std::hash::{DefaultHasher, Hash, Hasher};
|
||||||
|
|
||||||
|
@ -656,11 +656,7 @@ impl NodeNetworkInterface {
|
||||||
// For example a node input of (Footprint) -> VectorData would not be compatible with () -> VectorData
|
// For example a node input of (Footprint) -> VectorData would not be compatible with () -> VectorData
|
||||||
node_io.inputs[iterator_index].clone().nested_type() == input_type || node_io.inputs[iterator_index] == input_type
|
node_io.inputs[iterator_index].clone().nested_type() == input_type || node_io.inputs[iterator_index] == input_type
|
||||||
});
|
});
|
||||||
if valid_implementation {
|
if valid_implementation { node_io.inputs.get(*input_index).cloned() } else { None }
|
||||||
node_io.inputs.get(*input_index).cloned()
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
@ -1339,7 +1335,7 @@ impl NodeNetworkInterface {
|
||||||
|
|
||||||
/// Layers excluding ones that are children of other layers in the list.
|
/// Layers excluding ones that are children of other layers in the list.
|
||||||
// TODO: Cache this
|
// TODO: Cache this
|
||||||
pub fn shallowest_unique_layers(&self, network_path: &[NodeId]) -> impl Iterator<Item = LayerNodeIdentifier> {
|
pub fn shallowest_unique_layers(&self, network_path: &[NodeId]) -> impl Iterator<Item = LayerNodeIdentifier> + use<> {
|
||||||
let mut sorted_layers = if let Some(selected_nodes) = self.selected_nodes_in_nested_network(network_path) {
|
let mut sorted_layers = if let Some(selected_nodes) = self.selected_nodes_in_nested_network(network_path) {
|
||||||
selected_nodes
|
selected_nodes
|
||||||
.selected_layers(self.document_metadata())
|
.selected_layers(self.document_metadata())
|
||||||
|
@ -2528,10 +2524,9 @@ impl NodeNetworkInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let number_of_outputs = if let DocumentNodeImplementation::Network(network) = &document_node.implementation {
|
let number_of_outputs = match &document_node.implementation {
|
||||||
network.exports.len()
|
DocumentNodeImplementation::Network(network) => network.exports.len(),
|
||||||
} else {
|
_ => 1,
|
||||||
1
|
|
||||||
};
|
};
|
||||||
// If the node does not have a primary output, shift all ports down a row
|
// If the node does not have a primary output, shift all ports down a row
|
||||||
let mut output_row_count = if !node_metadata.persistent_metadata.has_primary_output { 1 } else { 0 };
|
let mut output_row_count = if !node_metadata.persistent_metadata.has_primary_output { 1 } else { 0 };
|
||||||
|
@ -2682,11 +2677,7 @@ impl NodeNetworkInterface {
|
||||||
let Some(downstream_node_id) = downstream_node_connectors.iter().find_map(|input_connector| {
|
let Some(downstream_node_id) = downstream_node_connectors.iter().find_map(|input_connector| {
|
||||||
if let InputConnector::Node { node_id, input_index } = input_connector {
|
if let InputConnector::Node { node_id, input_index } = input_connector {
|
||||||
let downstream_input_index = if self.is_layer(node_id, network_path) { 1 } else { 0 };
|
let downstream_input_index = if self.is_layer(node_id, network_path) { 1 } else { 0 };
|
||||||
if *input_index == downstream_input_index {
|
if *input_index == downstream_input_index { Some(node_id) } else { None }
|
||||||
Some(node_id)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -2933,11 +2924,7 @@ impl NodeNetworkInterface {
|
||||||
log::error!("Could not get node_metadata for node {node_id}");
|
log::error!("Could not get node_metadata for node {node_id}");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
if !node_metadata.persistent_metadata.is_layer() {
|
if !node_metadata.persistent_metadata.is_layer() { Some(*node_id) } else { None }
|
||||||
Some(*node_id)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.or_else(|| clicked_nodes.into_iter().next())
|
.or_else(|| clicked_nodes.into_iter().next())
|
||||||
}
|
}
|
||||||
|
@ -3168,13 +3155,10 @@ impl NodeNetworkInterface {
|
||||||
// Only load structure if there is a root node
|
// Only load structure if there is a root node
|
||||||
let Some(root_node) = self.root_node(&[]) else { return };
|
let Some(root_node) = self.root_node(&[]) else { return };
|
||||||
|
|
||||||
let Some(first_root_layer) = self.upstream_flow_back_from_nodes(vec![root_node.node_id], &[], FlowType::PrimaryFlow).find_map(|node_id| {
|
let Some(first_root_layer) = self
|
||||||
if self.is_layer(&node_id, &[]) {
|
.upstream_flow_back_from_nodes(vec![root_node.node_id], &[], FlowType::PrimaryFlow)
|
||||||
Some(LayerNodeIdentifier::new(node_id, self, &[]))
|
.find_map(|node_id| if self.is_layer(&node_id, &[]) { Some(LayerNodeIdentifier::new(node_id, self, &[])) } else { None })
|
||||||
} else {
|
else {
|
||||||
None
|
|
||||||
}
|
|
||||||
}) else {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
// Should refer to output node
|
// Should refer to output node
|
||||||
|
@ -3329,7 +3313,7 @@ impl NodeNetworkInterface {
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
let mut value = node.inputs.get_mut(1).and_then(|input| input.as_value_mut());
|
let mut value = node.inputs.get_mut(1).and_then(|input| input.as_value_mut());
|
||||||
let Some(TaggedValue::VectorModification(ref mut modification)) = value.as_deref_mut() else {
|
let Some(TaggedValue::VectorModification(modification)) = value.as_deref_mut() else {
|
||||||
panic!("Path node does not have modification input");
|
panic!("Path node does not have modification input");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3846,10 +3830,9 @@ impl NodeNetworkInterface {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let previous_metadata = if let NodeInput::Node { node_id, .. } = &previous_input {
|
let previous_metadata = match &previous_input {
|
||||||
self.position(node_id, network_path).map(|position| (*node_id, position))
|
NodeInput::Node { node_id, .. } => self.position(node_id, network_path).map(|position| (*node_id, position)),
|
||||||
} else {
|
_ => None,
|
||||||
None
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let Some(network) = self.network_mut(network_path) else {
|
let Some(network) = self.network_mut(network_path) else {
|
||||||
|
@ -4701,14 +4684,17 @@ impl NodeNetworkInterface {
|
||||||
log::error!("Could not get node_metadata for node {node_id}");
|
log::error!("Could not get node_metadata for node {node_id}");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if let NodeTypePersistentMetadata::Layer(layer_metadata) = &mut node_metadata.persistent_metadata.node_type_metadata {
|
match &mut node_metadata.persistent_metadata.node_type_metadata {
|
||||||
if layer_metadata.position == LayerPosition::Stack(y_offset) {
|
NodeTypePersistentMetadata::Layer(layer_metadata) => {
|
||||||
return;
|
if layer_metadata.position == LayerPosition::Stack(y_offset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
layer_metadata.position = LayerPosition::Stack(y_offset);
|
||||||
|
self.transaction_modified();
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
log::error!("Could not set stack position for non layer node {node_id}");
|
||||||
}
|
}
|
||||||
layer_metadata.position = LayerPosition::Stack(y_offset);
|
|
||||||
self.transaction_modified();
|
|
||||||
} else {
|
|
||||||
log::error!("Could not set stack position for non layer node {node_id}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5128,16 +5114,12 @@ impl NodeNetworkInterface {
|
||||||
stack_dependents_with_position.sort_unstable_by(|a, b| {
|
stack_dependents_with_position.sort_unstable_by(|a, b| {
|
||||||
a.1.signum().cmp(&b.1.signum()).then_with(|| {
|
a.1.signum().cmp(&b.1.signum()).then_with(|| {
|
||||||
// If the node has a positive offset, then it is shifted up, so shift the top nodes first
|
// If the node has a positive offset, then it is shifted up, so shift the top nodes first
|
||||||
if a.1.signum() == 1 {
|
if a.1.signum() == 1 { a.2.cmp(&b.2) } else { b.2.cmp(&a.2) }
|
||||||
a.2.cmp(&b.2)
|
|
||||||
} else {
|
|
||||||
b.2.cmp(&a.2)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
// Try shift every node that is offset from its original position
|
// Try shift every node that is offset from its original position
|
||||||
for (node_id, mut offset, _) in stack_dependents_with_position.iter() {
|
for &(ref node_id, mut offset, _) in stack_dependents_with_position.iter() {
|
||||||
while offset != 0 {
|
while offset != 0 {
|
||||||
if self.check_collision_with_stack_dependents(node_id, -offset.signum(), network_path).is_empty() {
|
if self.check_collision_with_stack_dependents(node_id, -offset.signum(), network_path).is_empty() {
|
||||||
self.vertical_shift_with_push(node_id, -offset.signum(), &mut HashSet::new(), network_path);
|
self.vertical_shift_with_push(node_id, -offset.signum(), &mut HashSet::new(), network_path);
|
||||||
|
@ -5302,6 +5284,7 @@ impl NodeNetworkInterface {
|
||||||
self.transaction_modified();
|
self.transaction_modified();
|
||||||
} else if let LayerPosition::Stack(y_offset) = &mut layer_metadata.position {
|
} else if let LayerPosition::Stack(y_offset) = &mut layer_metadata.position {
|
||||||
let shifted_y_offset = *y_offset as i32 + shift.y;
|
let shifted_y_offset = *y_offset as i32 + shift.y;
|
||||||
|
|
||||||
// A layer can only be shifted to a positive y_offset
|
// A layer can only be shifted to a positive y_offset
|
||||||
if shifted_y_offset < 0 {
|
if shifted_y_offset < 0 {
|
||||||
log::error!(
|
log::error!(
|
||||||
|
@ -5312,6 +5295,7 @@ impl NodeNetworkInterface {
|
||||||
if shift.x != 0 {
|
if shift.x != 0 {
|
||||||
log::error!("Stack layer {node_id} cannot be shifted horizontally.");
|
log::error!("Stack layer {node_id} cannot be shifted horizontally.");
|
||||||
}
|
}
|
||||||
|
|
||||||
let new_y_offset = shifted_y_offset.max(0) as u32;
|
let new_y_offset = shifted_y_offset.max(0) as u32;
|
||||||
if *y_offset == new_y_offset {
|
if *y_offset == new_y_offset {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use super::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
|
use super::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
|
||||||
use super::network_interface::NodeNetworkInterface;
|
use super::network_interface::NodeNetworkInterface;
|
||||||
|
|
||||||
use graph_craft::document::{NodeId, NodeNetwork};
|
use graph_craft::document::{NodeId, NodeNetwork};
|
||||||
|
|
||||||
use serde::ser::SerializeStruct;
|
use serde::ser::SerializeStruct;
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, specta::Type)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, specta::Type)]
|
||||||
|
|
|
@ -7,13 +7,11 @@ use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||||
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
|
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
|
||||||
use crate::messages::tool::utility_types::ToolType;
|
use crate::messages::tool::utility_types::ToolType;
|
||||||
|
use glam::{DAffine2, DMat2, DVec2};
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_core::vector::ManipulatorPointId;
|
use graphene_core::vector::ManipulatorPointId;
|
||||||
use graphene_core::vector::VectorModificationType;
|
use graphene_core::vector::VectorModificationType;
|
||||||
use graphene_std::vector::{HandleId, PointId};
|
use graphene_std::vector::{HandleId, PointId};
|
||||||
|
|
||||||
use glam::{DAffine2, DMat2, DVec2};
|
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
|
@ -136,11 +134,7 @@ impl Axis {
|
||||||
return (target, false);
|
return (target, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if local {
|
if local { (Axis::Both, false) } else { (self, true) }
|
||||||
(Axis::Both, false)
|
|
||||||
} else {
|
|
||||||
(self, true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,11 +161,7 @@ impl Translation {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let displacement = transform.inverse().transform_vector2(displacement);
|
let displacement = transform.inverse().transform_vector2(displacement);
|
||||||
if increment_mode {
|
if increment_mode { displacement.round() } else { displacement }
|
||||||
displacement.round()
|
|
||||||
} else {
|
|
||||||
displacement
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
@ -259,11 +249,7 @@ impl Default for Scale {
|
||||||
impl Scale {
|
impl Scale {
|
||||||
pub fn to_f64(self, increment: bool) -> f64 {
|
pub fn to_f64(self, increment: bool) -> f64 {
|
||||||
let factor = if let Some(value) = self.typed_factor { value } else { self.dragged_factor };
|
let factor = if let Some(value) = self.typed_factor { value } else { self.dragged_factor };
|
||||||
if increment {
|
if increment { (factor / SCALE_INCREMENT).round() * SCALE_INCREMENT } else { factor }
|
||||||
(factor / SCALE_INCREMENT).round() * SCALE_INCREMENT
|
|
||||||
} else {
|
|
||||||
factor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_dvec(self, increment_mode: bool) -> DVec2 {
|
pub fn to_dvec(self, increment_mode: bool) -> DVec2 {
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use graphene_std::vector::misc::BooleanOperation;
|
|
||||||
|
|
||||||
use crate::messages::debug::utility_types::MessageLoggingVerbosity;
|
use crate::messages::debug::utility_types::MessageLoggingVerbosity;
|
||||||
use crate::messages::input_mapper::utility_types::macros::action_keys;
|
use crate::messages::input_mapper::utility_types::macros::action_keys;
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
|
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
|
||||||
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, FlipAxis, GroupFolderType};
|
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, FlipAxis, GroupFolderType};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
use graphene_std::vector::misc::BooleanOperation;
|
||||||
|
|
||||||
pub struct MenuBarMessageData {
|
pub struct MenuBarMessageData {
|
||||||
pub has_active_document: bool,
|
pub has_active_document: bool,
|
||||||
|
|
|
@ -3,10 +3,9 @@ use super::utility_types::PanelType;
|
||||||
use crate::messages::frontend::utility_types::{ExportBounds, FileType};
|
use crate::messages::frontend::utility_types::{ExportBounds, FileType};
|
||||||
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
|
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
use graphene_core::Color;
|
||||||
use graphene_core::raster::Image;
|
use graphene_core::raster::Image;
|
||||||
use graphene_core::text::Font;
|
use graphene_core::text::Font;
|
||||||
use graphene_core::Color;
|
|
||||||
|
|
||||||
#[impl_message(Message, Portfolio)]
|
#[impl_message(Message, Portfolio)]
|
||||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
|
|
|
@ -7,15 +7,14 @@ use crate::messages::debug::utility_types::MessageLoggingVerbosity;
|
||||||
use crate::messages::dialog::simple_dialogs;
|
use crate::messages::dialog::simple_dialogs;
|
||||||
use crate::messages::frontend::utility_types::FrontendDocumentDetails;
|
use crate::messages::frontend::utility_types::FrontendDocumentDetails;
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
|
use crate::messages::portfolio::document::DocumentMessageData;
|
||||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type;
|
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type;
|
||||||
use crate::messages::portfolio::document::utility_types::clipboards::{Clipboard, CopyBufferEntry, INTERNAL_CLIPBOARD_COUNT};
|
use crate::messages::portfolio::document::utility_types::clipboards::{Clipboard, CopyBufferEntry, INTERNAL_CLIPBOARD_COUNT};
|
||||||
use crate::messages::portfolio::document::utility_types::nodes::SelectedNodes;
|
use crate::messages::portfolio::document::utility_types::nodes::SelectedNodes;
|
||||||
use crate::messages::portfolio::document::DocumentMessageData;
|
|
||||||
use crate::messages::preferences::SelectionMode;
|
use crate::messages::preferences::SelectionMode;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::utility_types::{HintData, HintGroup, ToolType};
|
use crate::messages::tool::utility_types::{HintData, HintGroup, ToolType};
|
||||||
use crate::node_graph_executor::{ExportConfig, NodeGraphExecutor};
|
use crate::node_graph_executor::{ExportConfig, NodeGraphExecutor};
|
||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
use glam::IVec2;
|
use glam::IVec2;
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
|
@ -24,7 +23,6 @@ use graphene_core::text::{Font, TypesettingConfig};
|
||||||
use graphene_std::vector::style::{Fill, FillType, Gradient};
|
use graphene_std::vector::style::{Fill, FillType, Gradient};
|
||||||
use graphene_std::vector::{VectorData, VectorDataTable};
|
use graphene_std::vector::{VectorData, VectorDataTable};
|
||||||
use interpreted_executor::dynamic_executor::IntrospectError;
|
use interpreted_executor::dynamic_executor::IntrospectError;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ use crate::messages::input_mapper::key_mapping::MappingVariant;
|
||||||
use crate::messages::portfolio::document::node_graph::utility_types::GraphWireStyle;
|
use crate::messages::portfolio::document::node_graph::utility_types::GraphWireStyle;
|
||||||
use crate::messages::preferences::SelectionMode;
|
use crate::messages::preferences::SelectionMode;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use graph_craft::wasm_application_io::EditorPreferences;
|
use graph_craft::wasm_application_io::EditorPreferences;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, specta::Type)]
|
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||||
|
|
|
@ -51,9 +51,7 @@ pub use crate::messages::tool::tool_messages::text_tool::{TextToolMessage, TextT
|
||||||
// Helper
|
// Helper
|
||||||
pub use crate::messages::globals::global_variables::*;
|
pub use crate::messages::globals::global_variables::*;
|
||||||
pub use crate::messages::portfolio::document::utility_types::misc::DocumentId;
|
pub use crate::messages::portfolio::document::utility_types::misc::DocumentId;
|
||||||
|
|
||||||
pub use graphite_proc_macros::*;
|
pub use graphite_proc_macros::*;
|
||||||
|
|
||||||
pub use std::collections::{HashMap, HashSet, VecDeque};
|
pub use std::collections::{HashMap, HashSet, VecDeque};
|
||||||
|
|
||||||
pub trait Responses {
|
pub trait Responses {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use graphene_core::Color;
|
use graphene_core::Color;
|
||||||
use graphene_std::vector::style::FillChoice;
|
use graphene_std::vector::style::FillChoice;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::consts::{COMPASS_ROSE_ARROW_CLICK_TARGET_ANGLE, COMPASS_ROSE_HOVER_RING_DIAMETER, COMPASS_ROSE_RING_INNER_DIAMETER};
|
use crate::consts::{COMPASS_ROSE_ARROW_CLICK_TARGET_ANGLE, COMPASS_ROSE_HOVER_RING_DIAMETER, COMPASS_ROSE_RING_INNER_DIAMETER};
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::prelude::DocumentMessageHandler;
|
use crate::messages::prelude::DocumentMessageHandler;
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
use std::f64::consts::FRAC_PI_2;
|
use std::f64::consts::FRAC_PI_2;
|
||||||
|
|
||||||
|
|
|
@ -3,18 +3,17 @@ use crate::messages::portfolio::document::node_graph::document_node_definitions;
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::{FlowType, InputConnector, NodeNetworkInterface, NodeTemplate};
|
use crate::messages::portfolio::document::utility_types::network_interface::{FlowType, InputConnector, NodeNetworkInterface, NodeTemplate};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
|
use glam::DVec2;
|
||||||
use graph_craft::concrete;
|
use graph_craft::concrete;
|
||||||
use graph_craft::document::{value::TaggedValue, NodeId, NodeInput};
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graphene_core::raster::image::ImageFrameTable;
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
|
use graphene_core::Color;
|
||||||
use graphene_core::raster::BlendMode;
|
use graphene_core::raster::BlendMode;
|
||||||
|
use graphene_core::raster::image::ImageFrameTable;
|
||||||
use graphene_core::text::{Font, TypesettingConfig};
|
use graphene_core::text::{Font, TypesettingConfig};
|
||||||
use graphene_core::vector::style::Gradient;
|
use graphene_core::vector::style::Gradient;
|
||||||
use graphene_core::Color;
|
|
||||||
use graphene_std::vector::{ManipulatorPointId, PointId, SegmentId, VectorModificationType};
|
use graphene_std::vector::{ManipulatorPointId, PointId, SegmentId, VectorModificationType};
|
||||||
|
|
||||||
use glam::DVec2;
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
/// Returns the ID of the first Spline node in the horizontal flow which is not followed by a `Path` node, or `None` if none exists.
|
/// Returns the ID of the first Spline node in the horizontal flow which is not followed by a `Path` node, or `None` if none exists.
|
||||||
|
@ -385,7 +384,7 @@ impl<'a> NodeGraphLayer<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return an iterator up the horizontal flow of the layer
|
/// Return an iterator up the horizontal flow of the layer
|
||||||
pub fn horizontal_layer_flow(&self) -> impl Iterator<Item = NodeId> + 'a {
|
pub fn horizontal_layer_flow(&self) -> impl Iterator<Item = NodeId> + use<'a> {
|
||||||
self.network_interface.upstream_flow_back_from_nodes(vec![self.layer_node], &[], FlowType::HorizontalFlow)
|
self.network_interface.upstream_flow_back_from_nodes(vec![self.layer_node], &[], FlowType::HorizontalFlow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||||
|
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::common_functionality::snapping::{SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnapTypeConfiguration};
|
use crate::messages::tool::common_functionality::snapping::{SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnapTypeConfiguration};
|
||||||
use crate::messages::{input_mapper::utility_types::input_keyboard::Key, portfolio::document::graph_operation::utility_types::TransformIn};
|
|
||||||
use glam::{DAffine2, DVec2, Vec2Swizzles};
|
use glam::{DAffine2, DVec2, Vec2Swizzles};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
|
|
|
@ -6,12 +6,10 @@ use crate::messages::portfolio::document::utility_types::network_interface::Node
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::common_functionality::snapping::SnapTypeConfiguration;
|
use crate::messages::tool::common_functionality::snapping::SnapTypeConfiguration;
|
||||||
use crate::messages::tool::tool_messages::path_tool::PointSelectState;
|
use crate::messages::tool::tool_messages::path_tool::PointSelectState;
|
||||||
|
|
||||||
use bezier_rs::{Bezier, BezierHandles, Subpath, TValue};
|
use bezier_rs::{Bezier, BezierHandles, Subpath, TValue};
|
||||||
|
use glam::{DAffine2, DVec2};
|
||||||
use graphene_core::transform::Transform;
|
use graphene_core::transform::Transform;
|
||||||
use graphene_core::vector::{ManipulatorPointId, PointId, VectorData, VectorModificationType};
|
use graphene_core::vector::{ManipulatorPointId, PointId, VectorData, VectorModificationType};
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
|
||||||
use graphene_std::vector::{HandleId, SegmentId};
|
use graphene_std::vector::{HandleId, SegmentId};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
@ -586,7 +584,7 @@ impl ShapeState {
|
||||||
.flat_map(|(data, selection_state)| {
|
.flat_map(|(data, selection_state)| {
|
||||||
selection_state.selected_points.iter().filter_map(move |&point| {
|
selection_state.selected_points.iter().filter_map(move |&point| {
|
||||||
let Some(data) = &data else { return None };
|
let Some(data) = &data else { return None };
|
||||||
let Some(_) = point.get_handle_pair(&data) else { return None }; // ignores the endpoints.
|
let _ = point.get_handle_pair(data)?; // ignores the endpoints.
|
||||||
Some(data.colinear(point))
|
Some(data.colinear(point))
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -1289,10 +1287,13 @@ impl ShapeState {
|
||||||
|
|
||||||
for point in self.selected_points().filter(|point| point.as_handle().is_some()) {
|
for point in self.selected_points().filter(|point| point.as_handle().is_some()) {
|
||||||
let anchor = point.get_anchor(&vector_data);
|
let anchor = point.get_anchor(&vector_data);
|
||||||
if let Some(handles) = point.get_handle_pair(&vector_data) {
|
match point.get_handle_pair(&vector_data) {
|
||||||
points_to_select.push((layer, anchor, Some(handles[1].to_manipulator_point())));
|
Some(handles) => {
|
||||||
} else {
|
points_to_select.push((layer, anchor, Some(handles[1].to_manipulator_point())));
|
||||||
points_to_select.push((layer, anchor, None));
|
}
|
||||||
|
_ => {
|
||||||
|
points_to_select.push((layer, anchor, None));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,21 +3,23 @@ mod distribution_snapper;
|
||||||
mod grid_snapper;
|
mod grid_snapper;
|
||||||
mod layer_snapper;
|
mod layer_snapper;
|
||||||
mod snap_results;
|
mod snap_results;
|
||||||
pub use {alignment_snapper::*, distribution_snapper::*, grid_snapper::*, layer_snapper::*, snap_results::*};
|
|
||||||
|
|
||||||
use crate::consts::{COLOR_OVERLAY_BLUE, COLOR_OVERLAY_LABEL_BACKGROUND, COLOR_OVERLAY_WHITE};
|
use crate::consts::{COLOR_OVERLAY_BLUE, COLOR_OVERLAY_LABEL_BACKGROUND, COLOR_OVERLAY_WHITE};
|
||||||
use crate::messages::portfolio::document::overlays::utility_types::{OverlayContext, Pivot};
|
use crate::messages::portfolio::document::overlays::utility_types::{OverlayContext, Pivot};
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::portfolio::document::utility_types::misc::{GridSnapTarget, PathSnapTarget, SnapTarget};
|
use crate::messages::portfolio::document::utility_types::misc::{GridSnapTarget, PathSnapTarget, SnapTarget};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
pub use alignment_snapper::*;
|
||||||
use bezier_rs::TValue;
|
use bezier_rs::TValue;
|
||||||
|
pub use distribution_snapper::*;
|
||||||
|
use glam::{DAffine2, DVec2};
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_core::vector::PointId;
|
use graphene_core::vector::PointId;
|
||||||
use graphene_std::renderer::Rect;
|
use graphene_std::renderer::Rect;
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
|
||||||
use graphene_std::vector::NoHashBuilder;
|
use graphene_std::vector::NoHashBuilder;
|
||||||
|
pub use grid_snapper::*;
|
||||||
|
pub use layer_snapper::*;
|
||||||
|
pub use snap_results::*;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
/// Configuration for the relevant snap type
|
/// Configuration for the relevant snap type
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::messages::portfolio::document::utility_types::misc::*;
|
use crate::messages::portfolio::document::utility_types::misc::*;
|
||||||
|
|
||||||
use graphene_core::renderer::Quad;
|
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
|
use graphene_core::renderer::Quad;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct AlignmentSnapper {
|
pub struct AlignmentSnapper {
|
||||||
|
|
|
@ -2,10 +2,8 @@ use super::*;
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::portfolio::document::utility_types::misc::*;
|
use crate::messages::portfolio::document::utility_types::misc::*;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use graphene_core::renderer::Quad;
|
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
|
use graphene_core::renderer::Quad;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct DistributionSnapper {
|
pub struct DistributionSnapper {
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use crate::messages::portfolio::document::utility_types::misc::{GridSnapTarget, GridSnapping, GridType, SnapTarget};
|
use crate::messages::portfolio::document::utility_types::misc::{GridSnapTarget, GridSnapping, GridType, SnapTarget};
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,11 @@ use crate::consts::HIDE_HANDLE_DISTANCE;
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::portfolio::document::utility_types::misc::*;
|
use crate::messages::portfolio::document::utility_types::misc::*;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use bezier_rs::{Bezier, Identifier, Subpath, TValue};
|
use bezier_rs::{Bezier, Identifier, Subpath, TValue};
|
||||||
|
use glam::{DAffine2, DVec2};
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_core::vector::PointId;
|
use graphene_core::vector::PointId;
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct LayerSnapper {
|
pub struct LayerSnapper {
|
||||||
points_to_snap: Vec<SnapCandidatePoint>,
|
points_to_snap: Vec<SnapCandidatePoint>,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use std::collections::VecDeque;
|
use super::DistributionMatch;
|
||||||
|
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::portfolio::document::utility_types::misc::{DistributionSnapTarget, SnapSource, SnapTarget};
|
use crate::messages::portfolio::document::utility_types::misc::{DistributionSnapTarget, SnapSource, SnapTarget};
|
||||||
use crate::messages::tool::common_functionality::snapping::SnapCandidatePoint;
|
use crate::messages::tool::common_functionality::snapping::SnapCandidatePoint;
|
||||||
|
@ -8,8 +7,7 @@ use glam::DVec2;
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_core::vector::PointId;
|
use graphene_core::vector::PointId;
|
||||||
use graphene_std::renderer::Rect;
|
use graphene_std::renderer::Rect;
|
||||||
|
use std::collections::VecDeque;
|
||||||
use super::DistributionMatch;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct SnapResults {
|
pub struct SnapResults {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use super::snapping::{self, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnappedPoint};
|
||||||
use crate::consts::{
|
use crate::consts::{
|
||||||
BOUNDS_ROTATE_THRESHOLD, BOUNDS_SELECT_THRESHOLD, COLOR_OVERLAY_WHITE, MAXIMUM_ALT_SCALE_FACTOR, MIN_LENGTH_FOR_CORNERS_VISIBILITY, MIN_LENGTH_FOR_EDGE_RESIZE_PRIORITY_OVER_CORNERS,
|
BOUNDS_ROTATE_THRESHOLD, BOUNDS_SELECT_THRESHOLD, COLOR_OVERLAY_WHITE, MAXIMUM_ALT_SCALE_FACTOR, MIN_LENGTH_FOR_CORNERS_VISIBILITY, MIN_LENGTH_FOR_EDGE_RESIZE_PRIORITY_OVER_CORNERS,
|
||||||
MIN_LENGTH_FOR_MIDPOINT_VISIBILITY, MIN_LENGTH_FOR_RESIZE_TO_INCLUDE_INTERIOR, MIN_LENGTH_FOR_SKEW_TRIANGLE_VISIBILITY, RESIZE_HANDLE_SIZE, SELECTION_DRAG_ANGLE, SKEW_TRIANGLE_OFFSET,
|
MIN_LENGTH_FOR_MIDPOINT_VISIBILITY, MIN_LENGTH_FOR_RESIZE_TO_INCLUDE_INTERIOR, MIN_LENGTH_FOR_SKEW_TRIANGLE_VISIBILITY, RESIZE_HANDLE_SIZE, SELECTION_DRAG_ANGLE, SKEW_TRIANGLE_OFFSET,
|
||||||
|
@ -8,14 +9,10 @@ use crate::messages::portfolio::document::overlays::utility_types::OverlayContex
|
||||||
use crate::messages::portfolio::document::utility_types::transformation::OriginalTransforms;
|
use crate::messages::portfolio::document::utility_types::transformation::OriginalTransforms;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::common_functionality::snapping::SnapTypeConfiguration;
|
use crate::messages::tool::common_functionality::snapping::SnapTypeConfiguration;
|
||||||
|
use glam::{DAffine2, DMat2, DVec2};
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_std::renderer::Rect;
|
use graphene_std::renderer::Rect;
|
||||||
|
|
||||||
use glam::{DAffine2, DMat2, DVec2};
|
|
||||||
|
|
||||||
use super::snapping::{self, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnappedPoint};
|
|
||||||
|
|
||||||
/// (top, bottom, left, right)
|
/// (top, bottom, left, right)
|
||||||
pub type EdgeBool = (bool, bool, bool, bool);
|
pub type EdgeBool = (bool, bool, bool, bool);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils::get_text;
|
use crate::messages::tool::common_functionality::graph_modification_utils::get_text;
|
||||||
|
|
||||||
use graphene_core::renderer::Quad;
|
|
||||||
use graphene_core::text::{load_face, FontCache};
|
|
||||||
use graphene_std::vector::PointId;
|
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
|
use graphene_core::renderer::Quad;
|
||||||
|
use graphene_core::text::{FontCache, load_face};
|
||||||
|
use graphene_std::vector::PointId;
|
||||||
|
|
||||||
/// Determines if a path should be extended. Goal in viewport space. Returns the path and if it is extending from the start, if applicable.
|
/// Determines if a path should be extended. Goal in viewport space. Returns the path and if it is extending from the start, if applicable.
|
||||||
pub fn should_extend(
|
pub fn should_extend(
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use super::utility_types::ToolType;
|
use super::utility_types::ToolType;
|
||||||
use crate::messages::preferences::SelectionMode;
|
use crate::messages::preferences::SelectionMode;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use graphene_core::raster::color::Color;
|
use graphene_core::raster::color::Color;
|
||||||
|
|
||||||
#[impl_message(Message, Tool)]
|
#[impl_message(Message, Tool)]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use super::common_functionality::shape_editor::ShapeState;
|
use super::common_functionality::shape_editor::ShapeState;
|
||||||
use super::utility_types::{tool_message_to_tool_type, ToolActionHandlerData, ToolFsmState};
|
use super::utility_types::{ToolActionHandlerData, ToolFsmState, tool_message_to_tool_type};
|
||||||
use crate::application::generate_uuid;
|
use crate::application::generate_uuid;
|
||||||
use crate::messages::layout::utility_types::widget_prelude::*;
|
use crate::messages::layout::utility_types::widget_prelude::*;
|
||||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayProvider;
|
use crate::messages::portfolio::document::overlays::utility_types::OverlayProvider;
|
||||||
|
@ -7,7 +7,6 @@ use crate::messages::portfolio::utility_types::PersistentData;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::utility_types::ToolType;
|
use crate::messages::tool::utility_types::ToolType;
|
||||||
use crate::node_graph_executor::NodeGraphExecutor;
|
use crate::node_graph_executor::NodeGraphExecutor;
|
||||||
|
|
||||||
use graphene_core::raster::color::Color;
|
use graphene_core::raster::color::Color;
|
||||||
|
|
||||||
const ARTBOARD_OVERLAY_PROVIDER: OverlayProvider = |context| DocumentMessage::DrawArtboardOverlays(context).into();
|
const ARTBOARD_OVERLAY_PROVIDER: OverlayProvider = |context| DocumentMessage::DrawArtboardOverlays(context).into();
|
||||||
|
|
|
@ -9,7 +9,6 @@ use crate::messages::tool::common_functionality::snapping::SnapCandidatePoint;
|
||||||
use crate::messages::tool::common_functionality::snapping::SnapData;
|
use crate::messages::tool::common_functionality::snapping::SnapData;
|
||||||
use crate::messages::tool::common_functionality::snapping::SnapManager;
|
use crate::messages::tool::common_functionality::snapping::SnapManager;
|
||||||
use crate::messages::tool::common_functionality::transformation_cage::*;
|
use crate::messages::tool::common_functionality::transformation_cage::*;
|
||||||
|
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
|
|
||||||
|
@ -277,7 +276,7 @@ impl Fsm for ArtboardToolFsmState {
|
||||||
ArtboardToolFsmState::ResizingBounds
|
ArtboardToolFsmState::ResizingBounds
|
||||||
}
|
}
|
||||||
(ArtboardToolFsmState::Dragging, ArtboardToolMessage::PointerMove { constrain_axis_or_aspect, center }) => {
|
(ArtboardToolFsmState::Dragging, ArtboardToolMessage::PointerMove { constrain_axis_or_aspect, center }) => {
|
||||||
if let Some(ref mut bounds) = &mut tool_data.bounding_box_manager {
|
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||||
let axis_align = input.keyboard.get(constrain_axis_or_aspect as usize);
|
let axis_align = input.keyboard.get(constrain_axis_or_aspect as usize);
|
||||||
|
|
||||||
let ignore = tool_data.selected_artboard.map_or(Vec::new(), |layer| vec![layer]);
|
let ignore = tool_data.selected_artboard.map_or(Vec::new(), |layer| vec![layer]);
|
||||||
|
|
|
@ -5,12 +5,11 @@ use crate::messages::portfolio::document::node_graph::document_node_definitions:
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::FlowType;
|
use crate::messages::portfolio::document::utility_types::network_interface::FlowType;
|
||||||
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
||||||
|
|
||||||
use graph_craft::document::value::TaggedValue;
|
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
|
use graph_craft::document::value::TaggedValue;
|
||||||
|
use graphene_core::Color;
|
||||||
use graphene_core::raster::BlendMode;
|
use graphene_core::raster::BlendMode;
|
||||||
use graphene_core::vector::brush_stroke::{BrushInputSample, BrushStroke, BrushStyle};
|
use graphene_core::vector::brush_stroke::{BrushInputSample, BrushStroke, BrushStyle};
|
||||||
use graphene_core::Color;
|
|
||||||
|
|
||||||
const BRUSH_MAX_SIZE: f64 = 5000.;
|
const BRUSH_MAX_SIZE: f64 = 5000.;
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@ use crate::messages::tool::common_functionality::color_selector::{ToolColorOptio
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||||
use crate::messages::tool::common_functionality::resize::Resize;
|
use crate::messages::tool::common_functionality::resize::Resize;
|
||||||
use crate::messages::tool::common_functionality::snapping::SnapData;
|
use crate::messages::tool::common_functionality::snapping::SnapData;
|
||||||
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{value::TaggedValue, NodeId, NodeInput};
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
use graphene_core::Color;
|
use graphene_core::Color;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -7,13 +7,11 @@ use crate::messages::portfolio::document::utility_types::document_metadata::Laye
|
||||||
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||||
use crate::messages::tool::common_functionality::utility_functions::should_extend;
|
use crate::messages::tool::common_functionality::utility_functions::should_extend;
|
||||||
|
|
||||||
use graph_craft::document::NodeId;
|
|
||||||
use graphene_core::vector::VectorModificationType;
|
|
||||||
use graphene_core::Color;
|
|
||||||
use graphene_std::vector::{PointId, SegmentId};
|
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
|
use graph_craft::document::NodeId;
|
||||||
|
use graphene_core::Color;
|
||||||
|
use graphene_core::vector::VectorModificationType;
|
||||||
|
use graphene_std::vector::{PointId, SegmentId};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct FreehandTool {
|
pub struct FreehandTool {
|
||||||
|
|
|
@ -5,7 +5,6 @@ use crate::messages::portfolio::document::utility_types::document_metadata::Laye
|
||||||
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils::get_gradient;
|
use crate::messages::tool::common_functionality::graph_modification_utils::get_gradient;
|
||||||
use crate::messages::tool::common_functionality::snapping::SnapManager;
|
use crate::messages::tool::common_functionality::snapping::SnapManager;
|
||||||
|
|
||||||
use graphene_core::vector::style::{Fill, Gradient, GradientType};
|
use graphene_core::vector::style::{Fill, Gradient, GradientType};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -2,13 +2,14 @@ use super::tool_prelude::*;
|
||||||
use crate::consts::{BOUNDS_SELECT_THRESHOLD, DEFAULT_STROKE_WIDTH, LINE_ROTATE_SNAP_ANGLE};
|
use crate::consts::{BOUNDS_SELECT_THRESHOLD, DEFAULT_STROKE_WIDTH, LINE_ROTATE_SNAP_ANGLE};
|
||||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type;
|
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type;
|
||||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||||
use crate::messages::portfolio::document::utility_types::{document_metadata::LayerNodeIdentifier, network_interface::InputConnector};
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
|
use crate::messages::portfolio::document::utility_types::network_interface::InputConnector;
|
||||||
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
||||||
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils::{self, NodeGraphLayer};
|
use crate::messages::tool::common_functionality::graph_modification_utils::{self, NodeGraphLayer};
|
||||||
use crate::messages::tool::common_functionality::snapping::{SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnapTypeConfiguration};
|
use crate::messages::tool::common_functionality::snapping::{SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnapTypeConfiguration};
|
||||||
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{value::TaggedValue, NodeId, NodeInput};
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
use graphene_core::Color;
|
use graphene_core::Color;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -23,6 +23,5 @@ pub mod tool_prelude {
|
||||||
pub use crate::messages::prelude::*;
|
pub use crate::messages::prelude::*;
|
||||||
pub use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
|
pub use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHandlerData, ToolMetadata, ToolTransition, ToolType};
|
||||||
pub use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
pub use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
||||||
|
|
||||||
pub use glam::{DAffine2, DVec2};
|
pub use glam::{DAffine2, DVec2};
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,9 @@ use crate::messages::tool::common_functionality::shape_editor::{
|
||||||
ClosestSegment, ManipulatorAngle, OpposingHandleLengths, SelectedPointsInfo, SelectionChange, SelectionShape, SelectionShapeType, ShapeState,
|
ClosestSegment, ManipulatorAngle, OpposingHandleLengths, SelectedPointsInfo, SelectionChange, SelectionShape, SelectionShapeType, ShapeState,
|
||||||
};
|
};
|
||||||
use crate::messages::tool::common_functionality::snapping::{SnapCache, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager};
|
use crate::messages::tool::common_functionality::snapping::{SnapCache, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager};
|
||||||
|
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_core::vector::{ManipulatorPointId, PointId};
|
use graphene_core::vector::{ManipulatorPointId, PointId};
|
||||||
use graphene_std::vector::{NoHashBuilder, SegmentId};
|
use graphene_std::vector::{NoHashBuilder, SegmentId};
|
||||||
|
|
||||||
use std::vec;
|
use std::vec;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -9,11 +9,10 @@ use crate::messages::tool::common_functionality::color_selector::{ToolColorOptio
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils::{self, merge_layers};
|
use crate::messages::tool::common_functionality::graph_modification_utils::{self, merge_layers};
|
||||||
use crate::messages::tool::common_functionality::snapping::{SnapCache, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnapTypeConfiguration};
|
use crate::messages::tool::common_functionality::snapping::{SnapCache, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnapTypeConfiguration};
|
||||||
use crate::messages::tool::common_functionality::utility_functions::{closest_point, should_extend};
|
use crate::messages::tool::common_functionality::utility_functions::{closest_point, should_extend};
|
||||||
|
|
||||||
use bezier_rs::{Bezier, BezierHandles};
|
use bezier_rs::{Bezier, BezierHandles};
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
use graphene_core::vector::{PointId, VectorModificationType};
|
|
||||||
use graphene_core::Color;
|
use graphene_core::Color;
|
||||||
|
use graphene_core::vector::{PointId, VectorModificationType};
|
||||||
use graphene_std::vector::{HandleId, ManipulatorPointId, NoHashBuilder, SegmentId, VectorData};
|
use graphene_std::vector::{HandleId, ManipulatorPointId, NoHashBuilder, SegmentId, VectorData};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -461,6 +460,7 @@ impl PenToolData {
|
||||||
Some(if close_subpath { PenToolFsmState::Ready } else { PenToolFsmState::PlacingAnchor })
|
Some(if close_subpath { PenToolFsmState::Ready } else { PenToolFsmState::PlacingAnchor })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
/// Calculates snap position delta while moving anchor and its handles.
|
/// Calculates snap position delta while moving anchor and its handles.
|
||||||
fn space_anchor_handle_snap(
|
fn space_anchor_handle_snap(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -493,7 +493,7 @@ impl PenToolData {
|
||||||
// Otherwise use either primary or end handle based on is_start flag
|
// Otherwise use either primary or end handle based on is_start flag
|
||||||
if is_start {
|
if is_start {
|
||||||
let primary_handle_id = ManipulatorPointId::PrimaryHandle(self.end_point_segment.unwrap());
|
let primary_handle_id = ManipulatorPointId::PrimaryHandle(self.end_point_segment.unwrap());
|
||||||
match primary_handle_id.get_position(&vector_data) {
|
match primary_handle_id.get_position(vector_data) {
|
||||||
Some(primary_handle) => {
|
Some(primary_handle) => {
|
||||||
let handle_offset = transform.transform_point2(primary_handle - self.next_handle_start);
|
let handle_offset = transform.transform_point2(primary_handle - self.next_handle_start);
|
||||||
let handle_snap = SnapCandidatePoint::handle(document_pos + handle_offset);
|
let handle_snap = SnapCandidatePoint::handle(document_pos + handle_offset);
|
||||||
|
@ -502,7 +502,7 @@ impl PenToolData {
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let end_handle = self.end_point_segment.map(|handle| ManipulatorPointId::EndHandle(handle).get_position(&vector_data)).flatten();
|
let end_handle = self.end_point_segment.and_then(|handle| ManipulatorPointId::EndHandle(handle).get_position(vector_data));
|
||||||
match end_handle {
|
match end_handle {
|
||||||
Some(end_handle) => {
|
Some(end_handle) => {
|
||||||
let handle_offset = transform.transform_point2(end_handle - self.next_handle_start);
|
let handle_offset = transform.transform_point2(end_handle - self.next_handle_start);
|
||||||
|
@ -690,10 +690,10 @@ impl PenToolData {
|
||||||
return Some((handle - self.next_point).length());
|
return Some((handle - self.next_point).length());
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.handle_end.map(|handle| (handle - self.next_point).length()).or_else(|| {
|
self.handle_end.map(|handle| (handle - self.next_point).length()).or_else(|| {
|
||||||
self.end_point_segment
|
self.end_point_segment
|
||||||
.and_then(|segment| Some((ManipulatorPointId::EndHandle(segment).get_position(vector_data)? - self.next_point).length()))
|
.and_then(|segment| Some((ManipulatorPointId::EndHandle(segment).get_position(vector_data)? - self.next_point).length()))
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn adjust_equidistant_handle(&mut self, responses: &mut VecDeque<Message>, layer: LayerNodeIdentifier, vector_data: &VectorData, is_start: bool) {
|
fn adjust_equidistant_handle(&mut self, responses: &mut VecDeque<Message>, layer: LayerNodeIdentifier, vector_data: &VectorData, is_start: bool) {
|
||||||
|
@ -755,12 +755,10 @@ impl PenToolData {
|
||||||
|
|
||||||
if let Some(handle) = self.handle_end.as_mut() {
|
if let Some(handle) = self.handle_end.as_mut() {
|
||||||
*handle = new_position;
|
*handle = new_position;
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
let Some(segment) = self.end_point_segment else { return };
|
let Some(segment) = self.end_point_segment else { return };
|
||||||
let modification_type = VectorModificationType::SetEndHandle { segment, relative_position };
|
let modification_type = VectorModificationType::SetEndHandle { segment, relative_position };
|
||||||
responses.add(GraphOperationMessage::Vector { layer, modification_type });
|
responses.add(GraphOperationMessage::Vector { layer, modification_type });
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1455,7 +1453,7 @@ impl Fsm for PenToolFsmState {
|
||||||
}
|
}
|
||||||
|
|
||||||
let state = tool_data
|
let state = tool_data
|
||||||
.drag_handle(snap_data, transform, input.mouse.position, responses, layer, &input)
|
.drag_handle(snap_data, transform, input.mouse.position, responses, layer, input)
|
||||||
.unwrap_or(PenToolFsmState::Ready);
|
.unwrap_or(PenToolFsmState::Ready);
|
||||||
|
|
||||||
// Auto-panning
|
// Auto-panning
|
||||||
|
|
|
@ -10,8 +10,8 @@ use crate::messages::tool::common_functionality::color_selector::{ToolColorOptio
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils::{self, NodeGraphLayer};
|
use crate::messages::tool::common_functionality::graph_modification_utils::{self, NodeGraphLayer};
|
||||||
use crate::messages::tool::common_functionality::resize::Resize;
|
use crate::messages::tool::common_functionality::resize::Resize;
|
||||||
use crate::messages::tool::common_functionality::snapping::SnapData;
|
use crate::messages::tool::common_functionality::snapping::SnapData;
|
||||||
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{value::TaggedValue, NodeId, NodeInput};
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
use graphene_core::Color;
|
use graphene_core::Color;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
use super::tool_prelude::*;
|
use super::tool_prelude::*;
|
||||||
use crate::consts::DEFAULT_STROKE_WIDTH;
|
use crate::consts::DEFAULT_STROKE_WIDTH;
|
||||||
|
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type;
|
use crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type;
|
||||||
use crate::messages::portfolio::document::{graph_operation::utility_types::TransformIn, overlays::utility_types::OverlayContext, utility_types::network_interface::InputConnector};
|
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||||
|
use crate::messages::portfolio::document::utility_types::network_interface::InputConnector;
|
||||||
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
||||||
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils;
|
use crate::messages::tool::common_functionality::graph_modification_utils;
|
||||||
use crate::messages::tool::common_functionality::resize::Resize;
|
use crate::messages::tool::common_functionality::resize::Resize;
|
||||||
use crate::messages::tool::common_functionality::snapping::SnapData;
|
use crate::messages::tool::common_functionality::snapping::SnapData;
|
||||||
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{value::TaggedValue, NodeId, NodeInput};
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
use graphene_core::Color;
|
use graphene_core::Color;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
|
@ -14,22 +14,21 @@ use crate::messages::portfolio::document::utility_types::network_interface::{Flo
|
||||||
use crate::messages::portfolio::document::utility_types::nodes::SelectedNodes;
|
use crate::messages::portfolio::document::utility_types::nodes::SelectedNodes;
|
||||||
use crate::messages::portfolio::document::utility_types::transformation::Selected;
|
use crate::messages::portfolio::document::utility_types::transformation::Selected;
|
||||||
use crate::messages::preferences::SelectionMode;
|
use crate::messages::preferences::SelectionMode;
|
||||||
|
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
||||||
use crate::messages::tool::common_functionality::compass_rose::{Axis, CompassRose};
|
use crate::messages::tool::common_functionality::compass_rose::{Axis, CompassRose};
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils::is_layer_fed_by_node_of_name;
|
use crate::messages::tool::common_functionality::graph_modification_utils::is_layer_fed_by_node_of_name;
|
||||||
|
use crate::messages::tool::common_functionality::measure;
|
||||||
use crate::messages::tool::common_functionality::pivot::Pivot;
|
use crate::messages::tool::common_functionality::pivot::Pivot;
|
||||||
use crate::messages::tool::common_functionality::shape_editor::SelectionShapeType;
|
use crate::messages::tool::common_functionality::shape_editor::SelectionShapeType;
|
||||||
use crate::messages::tool::common_functionality::snapping::{self, SnapCandidatePoint, SnapData, SnapManager};
|
use crate::messages::tool::common_functionality::snapping::{self, SnapCandidatePoint, SnapData, SnapManager};
|
||||||
use crate::messages::tool::common_functionality::transformation_cage::*;
|
use crate::messages::tool::common_functionality::transformation_cage::*;
|
||||||
use crate::messages::tool::common_functionality::utility_functions::text_bounding_box;
|
use crate::messages::tool::common_functionality::utility_functions::text_bounding_box;
|
||||||
use crate::messages::tool::common_functionality::{auto_panning::AutoPanning, measure};
|
|
||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
|
use glam::DMat2;
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_std::renderer::Rect;
|
use graphene_std::renderer::Rect;
|
||||||
use graphene_std::vector::misc::BooleanOperation;
|
use graphene_std::vector::misc::BooleanOperation;
|
||||||
|
|
||||||
use glam::DMat2;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -137,7 +136,7 @@ impl SelectTool {
|
||||||
.widget_holder()
|
.widget_holder()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn alignment_widgets(&self, disabled: bool) -> impl Iterator<Item = WidgetHolder> {
|
fn alignment_widgets(&self, disabled: bool) -> impl Iterator<Item = WidgetHolder> + use<> {
|
||||||
[AlignAxis::X, AlignAxis::Y]
|
[AlignAxis::X, AlignAxis::Y]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|axis| [(axis, AlignAggregate::Min), (axis, AlignAggregate::Center), (axis, AlignAggregate::Max)])
|
.flat_map(|axis| [(axis, AlignAggregate::Min), (axis, AlignAggregate::Center), (axis, AlignAggregate::Max)])
|
||||||
|
@ -158,7 +157,7 @@ impl SelectTool {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flip_widgets(&self, disabled: bool) -> impl Iterator<Item = WidgetHolder> {
|
fn flip_widgets(&self, disabled: bool) -> impl Iterator<Item = WidgetHolder> + use<> {
|
||||||
[(FlipAxis::X, "Horizontal"), (FlipAxis::Y, "Vertical")].into_iter().map(move |(flip_axis, name)| {
|
[(FlipAxis::X, "Horizontal"), (FlipAxis::Y, "Vertical")].into_iter().map(move |(flip_axis, name)| {
|
||||||
IconButton::new("Flip".to_string() + name, 24)
|
IconButton::new("Flip".to_string() + name, 24)
|
||||||
.tooltip("Flip ".to_string() + name)
|
.tooltip("Flip ".to_string() + name)
|
||||||
|
@ -168,7 +167,7 @@ impl SelectTool {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn turn_widgets(&self, disabled: bool) -> impl Iterator<Item = WidgetHolder> {
|
fn turn_widgets(&self, disabled: bool) -> impl Iterator<Item = WidgetHolder> + use<> {
|
||||||
[(-90., "TurnNegative90", "Turn -90°"), (90., "TurnPositive90", "Turn 90°")]
|
[(-90., "TurnNegative90", "Turn -90°"), (90., "TurnPositive90", "Turn 90°")]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(move |(degrees, icon, name)| {
|
.map(move |(degrees, icon, name)| {
|
||||||
|
@ -180,7 +179,7 @@ impl SelectTool {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn boolean_widgets(&self, selected_count: usize) -> impl Iterator<Item = WidgetHolder> {
|
fn boolean_widgets(&self, selected_count: usize) -> impl Iterator<Item = WidgetHolder> + use<> {
|
||||||
let operations = BooleanOperation::list();
|
let operations = BooleanOperation::list();
|
||||||
let icons = BooleanOperation::icons();
|
let icons = BooleanOperation::icons();
|
||||||
operations.into_iter().zip(icons).map(move |(operation, icon)| {
|
operations.into_iter().zip(icons).map(move |(operation, icon)| {
|
||||||
|
@ -1030,7 +1029,7 @@ impl Fsm for SelectToolFsmState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(SelectToolFsmState::ResizingBounds, SelectToolMessage::PointerMove(modifier_keys)) => {
|
(SelectToolFsmState::ResizingBounds, SelectToolMessage::PointerMove(modifier_keys)) => {
|
||||||
if let Some(ref mut bounds) = &mut tool_data.bounding_box_manager {
|
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||||
if let Some(movement) = &mut bounds.selected_edges {
|
if let Some(movement) = &mut bounds.selected_edges {
|
||||||
let (center, constrain) = (input.keyboard.key(modifier_keys.center), input.keyboard.key(modifier_keys.axis_align));
|
let (center, constrain) = (input.keyboard.key(modifier_keys.center), input.keyboard.key(modifier_keys.axis_align));
|
||||||
|
|
||||||
|
@ -1079,7 +1078,7 @@ impl Fsm for SelectToolFsmState {
|
||||||
SelectToolFsmState::ResizingBounds
|
SelectToolFsmState::ResizingBounds
|
||||||
}
|
}
|
||||||
(SelectToolFsmState::SkewingBounds { skew }, SelectToolMessage::PointerMove(_)) => {
|
(SelectToolFsmState::SkewingBounds { skew }, SelectToolMessage::PointerMove(_)) => {
|
||||||
if let Some(ref mut bounds) = &mut tool_data.bounding_box_manager {
|
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||||
if let Some(movement) = &mut bounds.selected_edges {
|
if let Some(movement) = &mut bounds.selected_edges {
|
||||||
let free_movement = input.keyboard.key(skew);
|
let free_movement = input.keyboard.key(skew);
|
||||||
let transformation = movement.skew_transform(input.mouse.position, bounds.original_bound_transform, free_movement);
|
let transformation = movement.skew_transform(input.mouse.position, bounds.original_bound_transform, free_movement);
|
||||||
|
@ -1227,7 +1226,7 @@ impl Fsm for SelectToolFsmState {
|
||||||
(SelectToolFsmState::ResizingBounds | SelectToolFsmState::SkewingBounds { .. }, SelectToolMessage::PointerOutsideViewport(_)) => {
|
(SelectToolFsmState::ResizingBounds | SelectToolFsmState::SkewingBounds { .. }, SelectToolMessage::PointerOutsideViewport(_)) => {
|
||||||
// AutoPanning
|
// AutoPanning
|
||||||
if let Some(shift) = tool_data.auto_panning.shift_viewport(input, responses) {
|
if let Some(shift) = tool_data.auto_panning.shift_viewport(input, responses) {
|
||||||
if let Some(ref mut bounds) = &mut tool_data.bounding_box_manager {
|
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||||
bounds.center_of_transformation += shift;
|
bounds.center_of_transformation += shift;
|
||||||
bounds.original_bound_transform.translation += shift;
|
bounds.original_bound_transform.translation += shift;
|
||||||
}
|
}
|
||||||
|
@ -1631,12 +1630,14 @@ fn drag_shallowest_manipulation(responses: &mut VecDeque<Message>, selected: Vec
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drag_deepest_manipulation(responses: &mut VecDeque<Message>, selected: Vec<LayerNodeIdentifier>, tool_data: &mut SelectToolData, document: &DocumentMessageHandler) {
|
fn drag_deepest_manipulation(responses: &mut VecDeque<Message>, selected: Vec<LayerNodeIdentifier>, tool_data: &mut SelectToolData, document: &DocumentMessageHandler) {
|
||||||
tool_data.layers_dragging.append(&mut vec![document.find_deepest(&selected).unwrap_or(
|
tool_data.layers_dragging.append(&mut vec![
|
||||||
LayerNodeIdentifier::ROOT_PARENT
|
document.find_deepest(&selected).unwrap_or(
|
||||||
.children(document.metadata())
|
LayerNodeIdentifier::ROOT_PARENT
|
||||||
.next()
|
.children(document.metadata())
|
||||||
.expect("ROOT_PARENT should have a layer child when clicking"),
|
.next()
|
||||||
)]);
|
.expect("ROOT_PARENT should have a layer child when clicking"),
|
||||||
|
),
|
||||||
|
]);
|
||||||
responses.add(NodeGraphMessage::SelectedNodesSet {
|
responses.add(NodeGraphMessage::SelectedNodesSet {
|
||||||
nodes: tool_data
|
nodes: tool_data
|
||||||
.layers_dragging
|
.layers_dragging
|
||||||
|
|
|
@ -9,7 +9,6 @@ use crate::messages::tool::common_functionality::color_selector::{ToolColorOptio
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils::{self, find_spline, merge_layers, merge_points};
|
use crate::messages::tool::common_functionality::graph_modification_utils::{self, find_spline, merge_layers, merge_points};
|
||||||
use crate::messages::tool::common_functionality::snapping::{SnapCandidatePoint, SnapData, SnapManager, SnapTypeConfiguration, SnappedPoint};
|
use crate::messages::tool::common_functionality::snapping::{SnapCandidatePoint, SnapData, SnapManager, SnapTypeConfiguration, SnappedPoint};
|
||||||
use crate::messages::tool::common_functionality::utility_functions::{closest_point, should_extend};
|
use crate::messages::tool::common_functionality::utility_functions::{closest_point, should_extend};
|
||||||
|
|
||||||
use graph_craft::document::{NodeId, NodeInput};
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
use graphene_core::Color;
|
use graphene_core::Color;
|
||||||
use graphene_std::vector::{PointId, SegmentId, VectorModificationType};
|
use graphene_std::vector::{PointId, SegmentId, VectorModificationType};
|
||||||
|
|
|
@ -6,18 +6,20 @@ use crate::messages::portfolio::document::graph_operation::utility_types::Transf
|
||||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::InputConnector;
|
use crate::messages::portfolio::document::utility_types::network_interface::InputConnector;
|
||||||
|
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
||||||
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
use crate::messages::tool::common_functionality::color_selector::{ToolColorOptions, ToolColorType};
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils::{self, is_layer_fed_by_node_of_name};
|
use crate::messages::tool::common_functionality::graph_modification_utils::{self, is_layer_fed_by_node_of_name};
|
||||||
|
use crate::messages::tool::common_functionality::pivot::Pivot;
|
||||||
|
use crate::messages::tool::common_functionality::resize::Resize;
|
||||||
use crate::messages::tool::common_functionality::snapping::{self, SnapCandidatePoint, SnapData};
|
use crate::messages::tool::common_functionality::snapping::{self, SnapCandidatePoint, SnapData};
|
||||||
use crate::messages::tool::common_functionality::transformation_cage::*;
|
use crate::messages::tool::common_functionality::transformation_cage::*;
|
||||||
use crate::messages::tool::common_functionality::{auto_panning::AutoPanning, pivot::Pivot, resize::Resize, utility_functions::text_bounding_box};
|
use crate::messages::tool::common_functionality::utility_functions::text_bounding_box;
|
||||||
|
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{NodeId, NodeInput};
|
use graph_craft::document::{NodeId, NodeInput};
|
||||||
use graphene_core::renderer::Quad;
|
|
||||||
use graphene_core::text::{lines_clipping, load_face, Font, FontCache, TypesettingConfig};
|
|
||||||
use graphene_core::vector::style::Fill;
|
|
||||||
use graphene_core::Color;
|
use graphene_core::Color;
|
||||||
|
use graphene_core::renderer::Quad;
|
||||||
|
use graphene_core::text::{Font, FontCache, TypesettingConfig, lines_clipping, load_face};
|
||||||
|
use graphene_core::vector::style::Fill;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct TextTool {
|
pub struct TextTool {
|
||||||
|
@ -514,7 +516,7 @@ impl Fsm for TextToolFsmState {
|
||||||
// The angle is choosen to be parallel to the X axis in the bounds transform.
|
// The angle is choosen to be parallel to the X axis in the bounds transform.
|
||||||
let angle = bounding_box_manager.transform.transform_vector2(DVec2::X).to_angle();
|
let angle = bounding_box_manager.transform.transform_vector2(DVec2::X).to_angle();
|
||||||
// Update pivot
|
// Update pivot
|
||||||
tool_data.pivot.update_pivot(&document, &mut overlay_context, angle);
|
tool_data.pivot.update_pivot(document, &mut overlay_context, angle);
|
||||||
} else {
|
} else {
|
||||||
tool_data.bounding_box_manager.take();
|
tool_data.bounding_box_manager.take();
|
||||||
}
|
}
|
||||||
|
@ -607,7 +609,7 @@ impl Fsm for TextToolFsmState {
|
||||||
TextToolFsmState::Dragging
|
TextToolFsmState::Dragging
|
||||||
}
|
}
|
||||||
(TextToolFsmState::ResizingBounds, TextToolMessage::PointerMove { center, lock_ratio }) => {
|
(TextToolFsmState::ResizingBounds, TextToolMessage::PointerMove { center, lock_ratio }) => {
|
||||||
if let Some(ref mut bounds) = &mut tool_data.bounding_box_manager {
|
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||||
if let Some(movement) = &mut bounds.selected_edges {
|
if let Some(movement) = &mut bounds.selected_edges {
|
||||||
let (center_bool, lock_ratio_bool) = (input.keyboard.key(center), input.keyboard.key(lock_ratio));
|
let (center_bool, lock_ratio_bool) = (input.keyboard.key(center), input.keyboard.key(lock_ratio));
|
||||||
let center_position = center_bool.then_some(bounds.center_of_transformation);
|
let center_position = center_bool.then_some(bounds.center_of_transformation);
|
||||||
|
@ -682,7 +684,7 @@ impl Fsm for TextToolFsmState {
|
||||||
(TextToolFsmState::ResizingBounds, TextToolMessage::PointerOutsideViewport { .. }) => {
|
(TextToolFsmState::ResizingBounds, TextToolMessage::PointerOutsideViewport { .. }) => {
|
||||||
// AutoPanning
|
// AutoPanning
|
||||||
if let Some(shift) = tool_data.auto_panning.shift_viewport(input, responses) {
|
if let Some(shift) = tool_data.auto_panning.shift_viewport(input, responses) {
|
||||||
if let Some(ref mut bounds) = &mut tool_data.bounding_box_manager {
|
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||||
bounds.center_of_transformation += shift;
|
bounds.center_of_transformation += shift;
|
||||||
bounds.original_bound_transform.translation += shift;
|
bounds.original_bound_transform.translation += shift;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
|
|
||||||
#[impl_message(Message, ToolMessage, TransformLayer)]
|
#[impl_message(Message, ToolMessage, TransformLayer)]
|
||||||
|
|
|
@ -8,12 +8,10 @@ use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
|
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
|
||||||
use crate::messages::tool::tool_messages::tool_prelude::Key;
|
use crate::messages::tool::tool_messages::tool_prelude::Key;
|
||||||
use crate::messages::tool::utility_types::{ToolData, ToolType};
|
use crate::messages::tool::utility_types::{ToolData, ToolType};
|
||||||
|
use glam::{DAffine2, DVec2};
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_core::vector::ManipulatorPointId;
|
use graphene_core::vector::ManipulatorPointId;
|
||||||
use graphene_std::vector::{VectorData, VectorModificationType};
|
use graphene_std::vector::{VectorData, VectorModificationType};
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
|
||||||
use std::f64::consts::TAU;
|
use std::f64::consts::TAU;
|
||||||
|
|
||||||
const TRANSFORM_GRS_OVERLAY_PROVIDER: OverlayProvider = |context| TransformLayerMessage::Overlays(context).into();
|
const TRANSFORM_GRS_OVERLAY_PROVIDER: OverlayProvider = |context| TransformLayerMessage::Overlays(context).into();
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
use super::common_functionality::shape_editor::ShapeState;
|
use super::common_functionality::shape_editor::ShapeState;
|
||||||
use super::tool_messages::*;
|
use super::tool_messages::*;
|
||||||
use crate::messages::broadcast::broadcast_event::BroadcastEvent;
|
|
||||||
use crate::messages::broadcast::BroadcastMessage;
|
use crate::messages::broadcast::BroadcastMessage;
|
||||||
|
use crate::messages::broadcast::broadcast_event::BroadcastEvent;
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup, LayoutKeysGroup, MouseMotion};
|
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup, LayoutKeysGroup, MouseMotion};
|
||||||
use crate::messages::input_mapper::utility_types::macros::action_keys;
|
use crate::messages::input_mapper::utility_types::macros::action_keys;
|
||||||
use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
use crate::messages::input_mapper::utility_types::misc::ActionKeys;
|
||||||
|
@ -12,10 +12,8 @@ use crate::messages::portfolio::document::overlays::utility_types::OverlayProvid
|
||||||
use crate::messages::preferences::PreferencesMessageHandler;
|
use crate::messages::preferences::PreferencesMessageHandler;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::node_graph_executor::NodeGraphExecutor;
|
use crate::node_graph_executor::NodeGraphExecutor;
|
||||||
|
|
||||||
use graphene_core::raster::color::Color;
|
use graphene_core::raster::color::Color;
|
||||||
use graphene_core::text::FontCache;
|
use graphene_core::text::FontCache;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
use crate::consts::FILE_SAVE_SUFFIX;
|
use crate::consts::FILE_SAVE_SUFFIX;
|
||||||
use crate::messages::frontend::utility_types::{ExportBounds, FileType};
|
use crate::messages::frontend::utility_types::{ExportBounds, FileType};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
use glam::{DAffine2, DVec2, UVec2};
|
||||||
use graph_craft::concrete;
|
use graph_craft::concrete;
|
||||||
use graph_craft::document::value::{RenderOutput, TaggedValue};
|
use graph_craft::document::value::{RenderOutput, TaggedValue};
|
||||||
use graph_craft::document::{generate_uuid, DocumentNode, DocumentNodeImplementation, NodeId, NodeInput, NodeNetwork};
|
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeInput, NodeNetwork, generate_uuid};
|
||||||
use graph_craft::graphene_compiler::Compiler;
|
use graph_craft::graphene_compiler::Compiler;
|
||||||
use graph_craft::proto::GraphErrors;
|
use graph_craft::proto::GraphErrors;
|
||||||
use graph_craft::wasm_application_io::EditorPreferences;
|
use graph_craft::wasm_application_io::EditorPreferences;
|
||||||
|
use graphene_core::Context;
|
||||||
use graphene_core::application_io::{NodeGraphUpdateMessage, NodeGraphUpdateSender, RenderConfig};
|
use graphene_core::application_io::{NodeGraphUpdateMessage, NodeGraphUpdateSender, RenderConfig};
|
||||||
use graphene_core::memo::IORecord;
|
use graphene_core::memo::IORecord;
|
||||||
use graphene_core::renderer::{GraphicElementRendered, RenderParams, SvgRender};
|
use graphene_core::renderer::{GraphicElementRendered, RenderParams, SvgRender};
|
||||||
|
@ -15,18 +16,15 @@ use graphene_core::renderer::{RenderSvgSegmentList, SvgSegment};
|
||||||
use graphene_core::text::FontCache;
|
use graphene_core::text::FontCache;
|
||||||
use graphene_core::transform::Footprint;
|
use graphene_core::transform::Footprint;
|
||||||
use graphene_core::vector::style::ViewMode;
|
use graphene_core::vector::style::ViewMode;
|
||||||
use graphene_core::Context;
|
use graphene_std::renderer::{RenderMetadata, format_transform_matrix};
|
||||||
use graphene_std::renderer::{format_transform_matrix, RenderMetadata};
|
|
||||||
use graphene_std::vector::{VectorData, VectorDataTable};
|
use graphene_std::vector::{VectorData, VectorDataTable};
|
||||||
use graphene_std::wasm_application_io::{WasmApplicationIo, WasmEditorApi};
|
use graphene_std::wasm_application_io::{WasmApplicationIo, WasmEditorApi};
|
||||||
use interpreted_executor::dynamic_executor::{DynamicExecutor, IntrospectError, ResolvedDocumentNodeTypesDelta};
|
use interpreted_executor::dynamic_executor::{DynamicExecutor, IntrospectError, ResolvedDocumentNodeTypesDelta};
|
||||||
use interpreted_executor::util::wrap_network_in_scope;
|
use interpreted_executor::util::wrap_network_in_scope;
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2, UVec2};
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
use std::sync::mpsc::{Receiver, Sender};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::sync::mpsc::{Receiver, Sender};
|
||||||
|
|
||||||
/// Persistent data between graph executions. It's updated via message passing from the editor thread with [`NodeRuntimeMessage`]`.
|
/// Persistent data between graph executions. It's updated via message passing from the editor thread with [`NodeRuntimeMessage`]`.
|
||||||
/// Some of these fields are put into a [`WasmEditorApi`] which is passed to the final compiled graph network upon each execution.
|
/// Some of these fields are put into a [`WasmEditorApi`] which is passed to the final compiled graph network upon each execution.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::application::set_uuid_seed;
|
|
||||||
use crate::application::Editor;
|
use crate::application::Editor;
|
||||||
|
use crate::application::set_uuid_seed;
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::ModifierKeys;
|
use crate::messages::input_mapper::utility_types::input_keyboard::ModifierKeys;
|
||||||
use crate::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, MouseKeys, ScrollDelta, ViewportPosition};
|
use crate::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, MouseKeys, ScrollDelta, ViewportPosition};
|
||||||
use crate::messages::portfolio::utility_types::Platform;
|
use crate::messages::portfolio::utility_types::Platform;
|
||||||
|
@ -8,12 +8,10 @@ use crate::messages::tool::tool_messages::tool_prelude::Key;
|
||||||
use crate::messages::tool::utility_types::ToolType;
|
use crate::messages::tool::utility_types::ToolType;
|
||||||
use crate::node_graph_executor::Instrumented;
|
use crate::node_graph_executor::Instrumented;
|
||||||
use crate::node_graph_executor::NodeRuntime;
|
use crate::node_graph_executor::NodeRuntime;
|
||||||
|
|
||||||
use graph_craft::document::DocumentNode;
|
|
||||||
use graphene_core::raster::color::Color;
|
|
||||||
use graphene_core::InputAccessor;
|
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
|
use graph_craft::document::DocumentNode;
|
||||||
|
use graphene_core::InputAccessor;
|
||||||
|
use graphene_core::raster::color::Color;
|
||||||
|
|
||||||
/// A set of utility functions to make the writing of editor test more declarative
|
/// A set of utility functions to make the writing of editor test more declarative
|
||||||
pub struct EditorTestUtils {
|
pub struct EditorTestUtils {
|
||||||
|
@ -256,7 +254,7 @@ pub mod test_prelude {
|
||||||
pub use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
|
pub use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
|
||||||
pub use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
pub use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
pub use crate::messages::prelude::*;
|
pub use crate::messages::prelude::*;
|
||||||
pub use crate::messages::tool::common_functionality::graph_modification_utils::{is_layer_fed_by_node_of_name, NodeGraphLayer};
|
pub use crate::messages::tool::common_functionality::graph_modification_utils::{NodeGraphLayer, is_layer_fed_by_node_of_name};
|
||||||
pub use crate::messages::tool::utility_types::ToolType;
|
pub use crate::messages::tool::utility_types::ToolType;
|
||||||
pub use crate::node_graph_executor::NodeRuntime;
|
pub use crate::node_graph_executor::NodeRuntime;
|
||||||
pub use crate::test_utils::EditorTestUtils;
|
pub use crate::test_utils::EditorTestUtils;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::{fs, path::PathBuf};
|
use std::fs;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Directory required for compilation, but not tracked by git if empty.
|
// Directory required for compilation, but not tracked by git if empty.
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
name = "graphite-wasm"
|
name = "graphite-wasm"
|
||||||
publish = false
|
publish = false
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
rust-version = "1.79"
|
rust-version = "1.85"
|
||||||
authors = ["Graphite Authors <contact@graphite.rs>"]
|
authors = ["Graphite Authors <contact@graphite.rs>"]
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
readme = "../../README.md"
|
readme = "../../README.md"
|
||||||
homepage = "https://graphite.rs"
|
homepage = "https://graphite.rs"
|
||||||
repository = "https://github.com/GraphiteEditor/Graphite"
|
repository = "https://github.com/GraphiteEditor/Graphite"
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
// on the dispatcher messaging system and more complex Rust data types.
|
// on the dispatcher messaging system and more complex Rust data types.
|
||||||
//
|
//
|
||||||
use crate::helpers::translate_key;
|
use crate::helpers::translate_key;
|
||||||
use crate::{Error, EDITOR, EDITOR_HANDLE, EDITOR_HAS_CRASHED};
|
use crate::{EDITOR, EDITOR_HANDLE, EDITOR_HAS_CRASHED, Error};
|
||||||
|
|
||||||
use editor::application::Editor;
|
use editor::application::Editor;
|
||||||
use editor::consts::FILE_SAVE_SUFFIX;
|
use editor::consts::FILE_SAVE_SUFFIX;
|
||||||
use editor::messages::input_mapper::utility_types::input_keyboard::ModifierKeys;
|
use editor::messages::input_mapper::utility_types::input_keyboard::ModifierKeys;
|
||||||
|
@ -18,7 +17,6 @@ use editor::messages::prelude::*;
|
||||||
use editor::messages::tool::tool_messages::tool_prelude::WidgetId;
|
use editor::messages::tool::tool_messages::tool_prelude::WidgetId;
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
use graphene_core::raster::color::Color;
|
use graphene_core::raster::color::Color;
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use serde_wasm_bindgen::{self, from_value};
|
use serde_wasm_bindgen::{self, from_value};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
@ -757,10 +755,11 @@ impl EditorHandle {
|
||||||
use editor::messages::portfolio::document::graph_operation::transform_utils::*;
|
use editor::messages::portfolio::document::graph_operation::transform_utils::*;
|
||||||
use editor::messages::portfolio::document::graph_operation::utility_types::*;
|
use editor::messages::portfolio::document::graph_operation::utility_types::*;
|
||||||
use editor::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type;
|
use editor::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type;
|
||||||
use editor::node_graph_executor::replace_node_runtime;
|
|
||||||
use editor::node_graph_executor::NodeRuntime;
|
use editor::node_graph_executor::NodeRuntime;
|
||||||
|
use editor::node_graph_executor::replace_node_runtime;
|
||||||
|
use graph_craft::document::DocumentNodeImplementation;
|
||||||
use graph_craft::document::NodeInput;
|
use graph_craft::document::NodeInput;
|
||||||
use graph_craft::document::{value::TaggedValue, DocumentNodeImplementation};
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graphene_core::vector::*;
|
use graphene_core::vector::*;
|
||||||
|
|
||||||
let (_, request_receiver) = std::sync::mpsc::channel();
|
let (_, request_receiver) = std::sync::mpsc::channel();
|
||||||
|
@ -989,7 +988,7 @@ fn set_timeout(f: &Closure<dyn FnMut()>, delay: Duration) {
|
||||||
fn editor<T: Default>(callback: impl FnOnce(&mut editor::application::Editor) -> T) -> T {
|
fn editor<T: Default>(callback: impl FnOnce(&mut editor::application::Editor) -> T) -> T {
|
||||||
EDITOR.with(|editor| {
|
EDITOR.with(|editor| {
|
||||||
let mut guard = editor.try_lock();
|
let mut guard = editor.try_lock();
|
||||||
let Ok(Some(ref mut editor)) = guard.as_deref_mut() else { return T::default() };
|
let Ok(Some(editor)) = guard.as_deref_mut() else { return T::default() };
|
||||||
|
|
||||||
callback(editor)
|
callback(editor)
|
||||||
})
|
})
|
||||||
|
@ -1000,7 +999,7 @@ pub(crate) fn editor_and_handle(mut callback: impl FnMut(&mut Editor, &mut Edito
|
||||||
EDITOR_HANDLE.with(|editor_handle| {
|
EDITOR_HANDLE.with(|editor_handle| {
|
||||||
editor(|editor| {
|
editor(|editor| {
|
||||||
let mut guard = editor_handle.try_lock();
|
let mut guard = editor_handle.try_lock();
|
||||||
let Ok(Some(ref mut editor_handle)) = guard.as_deref_mut() else {
|
let Ok(Some(editor_handle)) = guard.as_deref_mut() else {
|
||||||
log::error!("Failed to borrow editor handle");
|
log::error!("Failed to borrow editor handle");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,10 +8,9 @@ pub mod editor_api;
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
|
|
||||||
use editor::messages::prelude::*;
|
use editor::messages::prelude::*;
|
||||||
|
|
||||||
use std::panic;
|
use std::panic;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
|
||||||
// Set up the persistent editor backend state
|
// Set up the persistent editor backend state
|
||||||
|
@ -72,7 +71,7 @@ pub fn panic_hook(info: &panic::PanicHookInfo) {
|
||||||
|
|
||||||
EDITOR_HANDLE.with(|editor_handle| {
|
EDITOR_HANDLE.with(|editor_handle| {
|
||||||
let mut guard = editor_handle.lock();
|
let mut guard = editor_handle.lock();
|
||||||
if let Ok(Some(ref mut handle)) = guard.as_deref_mut() {
|
if let Ok(Some(handle)) = guard.as_deref_mut() {
|
||||||
handle.send_frontend_message_to_js_rust_proxy(FrontendMessage::DisplayDialogPanic { panic_info: info.to_string() });
|
handle.send_frontend_message_to_js_rust_proxy(FrontendMessage::DisplayDialogPanic { panic_info: info.to_string() });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
[package]
|
[package]
|
||||||
name = "bezier-rs"
|
name = "bezier-rs"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
rust-version = "1.79"
|
rust-version = "1.85"
|
||||||
edition = "2021"
|
edition = "2024"
|
||||||
authors = ["Graphite Authors <contact@graphite.rs>"]
|
authors = ["Graphite Authors <contact@graphite.rs>"]
|
||||||
description = "Computational geometry algorithms for Bézier segments and shapes useful in the context of 2D graphics"
|
description = "Computational geometry algorithms for Bézier segments and shapes useful in the context of 2D graphics"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use utils::format_point;
|
|
||||||
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
use utils::format_point;
|
||||||
|
|
||||||
/// Functionality relating to core `Bezier` operations, such as constructors and `abs_diff_eq`.
|
/// Functionality relating to core `Bezier` operations, such as constructors and `abs_diff_eq`.
|
||||||
impl Bezier {
|
impl Bezier {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::utils::{TValue, TValueType};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::utils::{TValue, TValueType};
|
||||||
|
|
||||||
/// Functionality relating to looking up properties of the `Bezier` or points along the `Bezier`.
|
/// Functionality relating to looking up properties of the `Bezier` or points along the `Bezier`.
|
||||||
impl Bezier {
|
impl Bezier {
|
||||||
|
|
|
@ -69,7 +69,7 @@ impl Bezier {
|
||||||
/// - For a linear segment, the order of the points will be: `start`, `end`.
|
/// - For a linear segment, the order of the points will be: `start`, `end`.
|
||||||
/// - For a quadratic segment, the order of the points will be: `start`, `handle`, `end`.
|
/// - For a quadratic segment, the order of the points will be: `start`, `handle`, `end`.
|
||||||
/// - For a cubic segment, the order of the points will be: `start`, `handle_start`, `handle_end`, `end`.
|
/// - For a cubic segment, the order of the points will be: `start`, `handle_start`, `handle_end`, `end`.
|
||||||
pub fn get_points(&self) -> impl Iterator<Item = DVec2> {
|
pub fn get_points(&self) -> impl Iterator<Item = DVec2> + use<> {
|
||||||
match self.handles {
|
match self.handles {
|
||||||
BezierHandles::Linear => [self.start, self.end, DVec2::ZERO, DVec2::ZERO].into_iter().take(2),
|
BezierHandles::Linear => [self.start, self.end, DVec2::ZERO, DVec2::ZERO].into_iter().take(2),
|
||||||
BezierHandles::Quadratic { handle } => [self.start, handle, self.end, DVec2::ZERO].into_iter().take(3),
|
BezierHandles::Quadratic { handle } => [self.start, handle, self.end, DVec2::ZERO].into_iter().take(3),
|
||||||
|
|
|
@ -7,11 +7,9 @@ mod transform;
|
||||||
|
|
||||||
use crate::consts::*;
|
use crate::consts::*;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
|
||||||
pub use structs::*;
|
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
use std::fmt::{Debug, Formatter, Result};
|
use std::fmt::{Debug, Formatter, Result};
|
||||||
|
pub use structs::*;
|
||||||
|
|
||||||
/// Representation of the handle point(s) in a bezier segment.
|
/// Representation of the handle point(s) in a bezier segment.
|
||||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::polynomial::Polynomial;
|
use crate::polynomial::Polynomial;
|
||||||
use crate::utils::{solve_cubic, solve_quadratic, TValue};
|
use crate::utils::{TValue, solve_cubic, solve_quadratic};
|
||||||
use crate::{to_symmetrical_basis_pair, SymmetricalBasis};
|
use crate::{SymmetricalBasis, to_symmetrical_basis_pair};
|
||||||
|
|
||||||
use glam::DMat2;
|
use glam::DMat2;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
|
@ -99,11 +98,7 @@ impl Bezier {
|
||||||
pub fn tangent(&self, t: TValue) -> DVec2 {
|
pub fn tangent(&self, t: TValue) -> DVec2 {
|
||||||
let t = self.t_value_to_parametric(t);
|
let t = self.t_value_to_parametric(t);
|
||||||
let tangent = self.non_normalized_tangent(t);
|
let tangent = self.non_normalized_tangent(t);
|
||||||
if tangent.length() > 0. {
|
if tangent.length() > 0. { tangent.normalize() } else { tangent }
|
||||||
tangent.normalize()
|
|
||||||
} else {
|
|
||||||
tangent
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the `t`-value(s) such that the tangent(s) at `t` pass through the specified point.
|
/// Find the `t`-value(s) such that the tangent(s) at `t` pass through the specified point.
|
||||||
|
@ -147,11 +142,7 @@ impl Bezier {
|
||||||
|
|
||||||
let numerator = d.x * dd.y - d.y * dd.x;
|
let numerator = d.x * dd.y - d.y * dd.x;
|
||||||
let denominator = (d.x.powf(2.) + d.y.powf(2.)).powf(1.5);
|
let denominator = (d.x.powf(2.) + d.y.powf(2.)).powf(1.5);
|
||||||
if denominator.abs() < MAX_ABSOLUTE_DIFFERENCE {
|
if denominator.abs() < MAX_ABSOLUTE_DIFFERENCE { 0. } else { numerator / denominator }
|
||||||
0.
|
|
||||||
} else {
|
|
||||||
numerator / denominator
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns two lists of `t`-values representing the local extrema of the `x` and `y` parametric curves respectively.
|
/// Returns two lists of `t`-values representing the local extrema of the `x` and `y` parametric curves respectively.
|
||||||
|
@ -228,7 +219,7 @@ impl Bezier {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an `Iterator` containing all possible parametric `t`-values at the given `x`-coordinate.
|
/// Returns an `Iterator` containing all possible parametric `t`-values at the given `x`-coordinate.
|
||||||
pub fn find_tvalues_for_x(&self, x: f64) -> impl Iterator<Item = f64> {
|
pub fn find_tvalues_for_x(&self, x: f64) -> impl Iterator<Item = f64> + use<> {
|
||||||
// Compute the roots of the resulting bezier curve
|
// Compute the roots of the resulting bezier curve
|
||||||
match self.handles {
|
match self.handles {
|
||||||
BezierHandles::Linear => {
|
BezierHandles::Linear => {
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use crate::compare::compare_points;
|
use crate::compare::compare_points;
|
||||||
use crate::utils::{f64_compare, Cap, TValue};
|
use crate::utils::{Cap, TValue, f64_compare};
|
||||||
use crate::{AppendType, ManipulatorGroup, Subpath};
|
use crate::{AppendType, ManipulatorGroup, Subpath};
|
||||||
|
|
||||||
use glam::DMat2;
|
use glam::DMat2;
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
|
@ -476,11 +474,7 @@ impl Bezier {
|
||||||
error,
|
error,
|
||||||
max_iterations,
|
max_iterations,
|
||||||
});
|
});
|
||||||
if final_low_t != 1. {
|
if final_low_t != 1. { [auto_arcs, arc_approximations].concat() } else { auto_arcs }
|
||||||
[auto_arcs, arc_approximations].concat()
|
|
||||||
} else {
|
|
||||||
auto_arcs
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ArcStrategy::FavorLargerArcs => self.approximate_curve_with_arcs(0., 1., error, max_iterations, false).0,
|
ArcStrategy::FavorLargerArcs => self.approximate_curve_with_arcs(0., 1., error, max_iterations, false).0,
|
||||||
ArcStrategy::FavorCorrectness => self
|
ArcStrategy::FavorCorrectness => self
|
||||||
|
@ -620,9 +614,9 @@ impl Bezier {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::EmptyId;
|
||||||
use crate::compare::{compare_arcs, compare_points};
|
use crate::compare::{compare_arcs, compare_points};
|
||||||
use crate::utils::{Cap, TValue};
|
use crate::utils::{Cap, TValue};
|
||||||
use crate::EmptyId;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_split() {
|
fn test_split() {
|
||||||
|
@ -777,14 +771,18 @@ mod tests {
|
||||||
|
|
||||||
// Check that the reduce helper is correct
|
// Check that the reduce helper is correct
|
||||||
let (helper_curves, helper_t_values) = bezier.reduced_curves_and_t_values(None);
|
let (helper_curves, helper_t_values) = bezier.reduced_curves_and_t_values(None);
|
||||||
assert!(reduced_curves
|
assert!(
|
||||||
.iter()
|
reduced_curves
|
||||||
.zip(helper_curves.iter())
|
.iter()
|
||||||
.all(|(bezier1, bezier2)| bezier1.abs_diff_eq(bezier2, MAX_ABSOLUTE_DIFFERENCE)));
|
.zip(helper_curves.iter())
|
||||||
assert!(reduced_curves
|
.all(|(bezier1, bezier2)| bezier1.abs_diff_eq(bezier2, MAX_ABSOLUTE_DIFFERENCE))
|
||||||
.iter()
|
);
|
||||||
.zip(helper_t_values.iter())
|
assert!(
|
||||||
.all(|(curve, t_pair)| curve.abs_diff_eq(&bezier.trim(TValue::Parametric(t_pair[0]), TValue::Parametric(t_pair[1])), MAX_ABSOLUTE_DIFFERENCE)))
|
reduced_curves
|
||||||
|
.iter()
|
||||||
|
.zip(helper_t_values.iter())
|
||||||
|
.all(|(curve, t_pair)| curve.abs_diff_eq(&bezier.trim(TValue::Parametric(t_pair[0]), TValue::Parametric(t_pair[1])), MAX_ABSOLUTE_DIFFERENCE))
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_valid_offset<PointId: crate::Identifier>(bezier: &Bezier, offset: &Subpath<PointId>, expected_distance: f64) {
|
fn assert_valid_offset<PointId: crate::Identifier>(bezier: &Bezier, offset: &Subpath<PointId>, expected_distance: f64) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue