mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-26 03:28:12 +08:00
Begin transferring network metadata
This commit is contained in:
@@ -8,8 +8,6 @@ pub const IMPORTS_TO_LEFT_EDGE_PIXEL_GAP: u32 = 120;
|
|||||||
// Viewport
|
// Viewport
|
||||||
pub const VIEWPORT_ZOOM_WHEEL_RATE: f64 = (1. / 600.) * 3.;
|
pub const VIEWPORT_ZOOM_WHEEL_RATE: f64 = (1. / 600.) * 3.;
|
||||||
pub const VIEWPORT_ZOOM_MOUSE_RATE: f64 = 1. / 400.;
|
pub const VIEWPORT_ZOOM_MOUSE_RATE: f64 = 1. / 400.;
|
||||||
pub const VIEWPORT_ZOOM_SCALE_MIN: f64 = 0.000_000_1;
|
|
||||||
pub const VIEWPORT_ZOOM_SCALE_MAX: f64 = 10_000.;
|
|
||||||
pub const VIEWPORT_ZOOM_MIN_FRACTION_COVER: f64 = 0.01;
|
pub const VIEWPORT_ZOOM_MIN_FRACTION_COVER: f64 = 0.01;
|
||||||
pub const VIEWPORT_ZOOM_LEVELS: [f64; 74] = [
|
pub const VIEWPORT_ZOOM_LEVELS: [f64; 74] = [
|
||||||
0.0001, 0.000125, 0.00016, 0.0002, 0.00025, 0.00032, 0.0004, 0.0005, 0.00064, 0.0008, 0.001, 0.0016, 0.002, 0.0025, 0.0032, 0.004, 0.005, 0.0064, 0.008, 0.01, 0.01125, 0.015, 0.02, 0.025, 0.03,
|
0.0001, 0.000125, 0.00016, 0.0002, 0.00025, 0.00032, 0.0004, 0.0005, 0.00064, 0.0008, 0.001, 0.0016, 0.002, 0.0025, 0.0032, 0.004, 0.005, 0.0064, 0.008, 0.01, 0.01125, 0.015, 0.02, 0.025, 0.03,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use super::node_graph::utility_types::Transform;
|
|||||||
use super::utility_types::clipboards::Clipboard;
|
use super::utility_types::clipboards::Clipboard;
|
||||||
use super::utility_types::error::EditorError;
|
use super::utility_types::error::EditorError;
|
||||||
use super::utility_types::misc::{SnappingOptions, SnappingState, GET_SNAP_BOX_FUNCTIONS, GET_SNAP_GEOMETRY_FUNCTIONS};
|
use super::utility_types::misc::{SnappingOptions, SnappingState, GET_SNAP_BOX_FUNCTIONS, GET_SNAP_GEOMETRY_FUNCTIONS};
|
||||||
use super::utility_types::network_interface::{NodeNetworkInterface, TransactionStatus};
|
use super::utility_types::network_interface::{NodeNetworkInterface, NodeNetworkPersistentMetadata, 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::{generate_uuid, GRAPHITE_GIT_COMMIT_HASH};
|
||||||
use crate::consts::{ASYMPTOTIC_EFFECT, DEFAULT_DOCUMENT_NAME, FILE_SAVE_SUFFIX, SCALE_EFFECT, SCROLLBAR_SPACING, VIEWPORT_ROTATE_SNAP_INTERVAL};
|
use crate::consts::{ASYMPTOTIC_EFFECT, DEFAULT_DOCUMENT_NAME, FILE_SAVE_SUFFIX, SCALE_EFFECT, SCROLLBAR_SPACING, VIEWPORT_ROTATE_SNAP_INTERVAL};
|
||||||
@@ -13,7 +13,7 @@ use crate::messages::portfolio::document::node_graph::NodeGraphHandlerData;
|
|||||||
use crate::messages::portfolio::document::overlays::grid_overlays::{grid_overlay, overlay_options};
|
use crate::messages::portfolio::document::overlays::grid_overlays::{grid_overlay, overlay_options};
|
||||||
use crate::messages::portfolio::document::properties_panel::utility_types::PropertiesPanelMessageHandlerData;
|
use crate::messages::portfolio::document::properties_panel::utility_types::PropertiesPanelMessageHandlerData;
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
|
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
|
||||||
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, DocumentMode, FlipAxis, PTZ};
|
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, DocumentMode, FlipAxis};
|
||||||
use crate::messages::portfolio::document::utility_types::nodes::RawBuffer;
|
use crate::messages::portfolio::document::utility_types::nodes::RawBuffer;
|
||||||
use crate::messages::portfolio::utility_types::PersistentData;
|
use crate::messages::portfolio::utility_types::PersistentData;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
@@ -24,7 +24,7 @@ use crate::messages::tool::utility_types::ToolType;
|
|||||||
use crate::node_graph_executor::NodeGraphExecutor;
|
use crate::node_graph_executor::NodeGraphExecutor;
|
||||||
|
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{NodeId, NodeNetwork, OldNodeNetwork};
|
use graph_craft::document::{NodeId, NodeNetwork, OldNodeNetwork, PTZ};
|
||||||
use graphene_core::raster::BlendMode;
|
use graphene_core::raster::BlendMode;
|
||||||
use graphene_core::raster::ImageFrame;
|
use graphene_core::raster::ImageFrame;
|
||||||
use graphene_core::vector::style::ViewMode;
|
use graphene_core::vector::style::ViewMode;
|
||||||
@@ -779,10 +779,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
|||||||
}
|
}
|
||||||
DocumentMessage::RenderRulers => {
|
DocumentMessage::RenderRulers => {
|
||||||
let current_ptz = if self.graph_view_overlay_open {
|
let current_ptz = if self.graph_view_overlay_open {
|
||||||
let Some(network_metadata) = self.network_interface.network_metadata(&self.breadcrumb_network_path) else {
|
self.network_interface.navigation_metadata(&self.breadcrumb_network_path)
|
||||||
return;
|
|
||||||
};
|
|
||||||
&network_metadata.persistent_metadata.navigation_metadata.node_graph_ptz
|
|
||||||
} else {
|
} else {
|
||||||
&self.document_ptz
|
&self.document_ptz
|
||||||
};
|
};
|
||||||
@@ -1112,7 +1109,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
|||||||
|
|
||||||
let transform = self
|
let transform = self
|
||||||
.navigation_handler
|
.navigation_handler
|
||||||
.calculate_offset_transform(ipp.viewport_bounds.center(), &network_metadata.persistent_metadata.navigation_metadata.node_graph_ptz);
|
.calculate_offset_transform(ipp.viewport_bounds.center(), &self.network_interface.navigation_metadata(&self.breadcrumb_network_path).node_graph_ptz);
|
||||||
self.network_interface.set_transform(transform, &self.breadcrumb_network_path);
|
self.network_interface.set_transform(transform, &self.breadcrumb_network_path);
|
||||||
let imports = self.network_interface.frontend_imports(&self.breadcrumb_network_path).unwrap_or_default();
|
let imports = self.network_interface.frontend_imports(&self.breadcrumb_network_path).unwrap_or_default();
|
||||||
let exports = self.network_interface.frontend_exports(&self.breadcrumb_network_path).unwrap_or_default();
|
let exports = self.network_interface.frontend_exports(&self.breadcrumb_network_path).unwrap_or_default();
|
||||||
@@ -1981,5 +1978,6 @@ impl DocumentMessageHandler {
|
|||||||
fn default_document_network_interface() -> NodeNetworkInterface {
|
fn default_document_network_interface() -> NodeNetworkInterface {
|
||||||
let mut network_interface = NodeNetworkInterface::default();
|
let mut network_interface = NodeNetworkInterface::default();
|
||||||
network_interface.add_export(TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::EMPTY), -1, "".to_string(), &[]);
|
network_interface.add_export(TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::EMPTY), -1, "".to_string(), &[]);
|
||||||
|
network_interface.insert_network_metadata(&[], NodeNetworkPersistentMetadata::default());
|
||||||
network_interface
|
network_interface
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,11 +1,11 @@
|
|||||||
use super::transform_utils;
|
use super::transform_utils;
|
||||||
use super::utility_types::ModifyInputsContext;
|
use super::utility_types::ModifyInputsContext;
|
||||||
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, NodeNetworkInterface};
|
use crate::messages::portfolio::document::utility_types::network_interface::NodeNetworkInterface;
|
||||||
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 graph_craft::document::{generate_uuid, NodeId, NodeInput};
|
use graph_craft::document::{generate_uuid, NodeId, NodeInput, InputConnector};
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_core::text::Font;
|
use graphene_core::text::Font;
|
||||||
use graphene_core::vector::style::{Fill, Gradient, GradientStops, GradientType, LineCap, LineJoin, Stroke};
|
use graphene_core::vector::style::{Fill, Gradient, GradientStops, GradientType, LineCap, LineJoin, Stroke};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeNetworkInterface};
|
use crate::messages::portfolio::document::utility_types::network_interface::NodeNetworkInterface;
|
||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
use graph_craft::document::{value::TaggedValue, NodeId, NodeInput};
|
use graph_craft::document::{value::TaggedValue, InputConnector, NodeId, NodeInput};
|
||||||
use graphene_core::vector::PointId;
|
use graphene_core::vector::PointId;
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use super::transform_utils;
|
use super::transform_utils;
|
||||||
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::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, NodeNetworkInterface};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{generate_uuid, NodeId, NodeInput};
|
use graph_craft::document::{generate_uuid, InputConnector, NodeId, NodeInput, OutputConnector};
|
||||||
use graphene_core::raster::{BlendMode, ImageFrame};
|
use graphene_core::raster::{BlendMode, ImageFrame};
|
||||||
use graphene_core::text::Font;
|
use graphene_core::text::Font;
|
||||||
use graphene_core::vector::brush_stroke::BrushStroke;
|
use graphene_core::vector::brush_stroke::BrushStroke;
|
||||||
|
|||||||
@@ -1,17 +1,16 @@
|
|||||||
use crate::consts::{
|
use crate::consts::{
|
||||||
VIEWPORT_ROTATE_SNAP_INTERVAL, VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_LEVELS, VIEWPORT_ZOOM_MIN_FRACTION_COVER, VIEWPORT_ZOOM_MOUSE_RATE, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN,
|
VIEWPORT_ROTATE_SNAP_INTERVAL, VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_LEVELS, VIEWPORT_ZOOM_MIN_FRACTION_COVER, VIEWPORT_ZOOM_MOUSE_RATE, VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR,
|
||||||
VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR, VIEWPORT_ZOOM_WHEEL_RATE,
|
VIEWPORT_ZOOM_WHEEL_RATE,
|
||||||
};
|
};
|
||||||
use crate::messages::frontend::utility_types::MouseCursorIcon;
|
use crate::messages::frontend::utility_types::MouseCursorIcon;
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup, MouseMotion};
|
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup, MouseMotion};
|
||||||
use crate::messages::input_mapper::utility_types::input_mouse::ViewportPosition;
|
use crate::messages::input_mapper::utility_types::input_mouse::ViewportPosition;
|
||||||
use crate::messages::portfolio::document::navigation::utility_types::NavigationOperation;
|
use crate::messages::portfolio::document::navigation::utility_types::NavigationOperation;
|
||||||
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 graph_craft::document::{NodeId, PTZ};
|
||||||
|
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
|
|
||||||
@@ -46,8 +45,7 @@ impl MessageHandler<NavigationMessage, NavigationMessageData<'_>> for Navigation
|
|||||||
if !graph_view_overlay_open {
|
if !graph_view_overlay_open {
|
||||||
Some(document_ptz)
|
Some(document_ptz)
|
||||||
} else {
|
} else {
|
||||||
let network_metadata = network_interface.network_metadata(breadcrumb_network_path)?;
|
Some(network_interface.navigation_metadata(breadcrumb_network_path).node_graph_ptz)
|
||||||
Some(&network_metadata.persistent_metadata.navigation_metadata.node_graph_ptz)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +247,7 @@ impl MessageHandler<NavigationMessage, NavigationMessageData<'_>> for Navigation
|
|||||||
log::error!("Could not get mutable PTZ in CanvasZoomSet");
|
log::error!("Could not get mutable PTZ in CanvasZoomSet");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let zoom = zoom_factor.clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
let zoom = zoom_factor.clamp(graphene_std::consts::VIEWPORT_ZOOM_SCALE_MIN, graphene_std::consts::VIEWPORT_ZOOM_SCALE_MAX);
|
||||||
let zoom = zoom * Self::clamp_zoom(zoom, document_bounds, old_zoom, ipp);
|
let zoom = zoom * Self::clamp_zoom(zoom, document_bounds, old_zoom, ipp);
|
||||||
ptz.set_zoom(zoom);
|
ptz.set_zoom(zoom);
|
||||||
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use super::utility_types::Direction;
|
use super::utility_types::Direction;
|
||||||
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::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, NodeTemplate, OutputConnector};
|
use crate::messages::portfolio::document::utility_types::network_interface::NodeTemplate;
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
|
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{NodeId, NodeInput};
|
use graph_craft::document::{InputConnector, NodeId, NodeInput, OutputConnector};
|
||||||
use graph_craft::proto::GraphErrors;
|
use graph_craft::proto::GraphErrors;
|
||||||
use interpreted_executor::dynamic_executor::ResolvedDocumentNodeTypesDelta;
|
use interpreted_executor::dynamic_executor::ResolvedDocumentNodeTypesDelta;
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ use crate::messages::layout::utility_types::widget_prelude::*;
|
|||||||
use crate::messages::portfolio::document::node_graph::document_node_definitions::NodePropertiesContext;
|
use crate::messages::portfolio::document::node_graph::document_node_definitions::NodePropertiesContext;
|
||||||
use crate::messages::portfolio::document::node_graph::utility_types::{ContextMenuData, Direction, FrontendGraphDataType};
|
use crate::messages::portfolio::document::node_graph::utility_types::{ContextMenuData, Direction, FrontendGraphDataType};
|
||||||
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, NodeTemplate, OutputConnector, Previewing};
|
use crate::messages::portfolio::document::utility_types::network_interface::{self, NodeNetworkInterface, NodeTemplate};
|
||||||
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 graph_craft::document::{DocumentNodeImplementation, NodeId, NodeInput};
|
use graph_craft::document::{DocumentNodeImplementation, InputConnector, NodeId, NodeInput, OutputConnector, Previewing};
|
||||||
use graph_craft::proto::GraphErrors;
|
use graph_craft::proto::GraphErrors;
|
||||||
use graphene_core::*;
|
use graphene_core::*;
|
||||||
use renderer::{ClickTarget, Quad};
|
use renderer::{ClickTarget, Quad};
|
||||||
@@ -158,13 +158,8 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
responses.add(NodeGraphMessage::ShiftNodePosition { node_id, x, y });
|
responses.add(NodeGraphMessage::ShiftNodePosition { node_id, x, y });
|
||||||
// Only auto connect to the dragged wire if the node is being added to the currently opened network
|
// Only auto connect to the dragged wire if the node is being added to the currently opened network
|
||||||
if let Some(output_connector_position) = self.wire_in_progress_from_connector {
|
if let Some(output_connector_position) = self.wire_in_progress_from_connector {
|
||||||
let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else {
|
let output_connector_position_viewport = network_interface
|
||||||
log::error!("Could not get network metadata in CreateNodeFromContextMenu");
|
.navigation_metadata(selection_network_path)
|
||||||
return;
|
|
||||||
};
|
|
||||||
let output_connector_position_viewport = network_metadata
|
|
||||||
.persistent_metadata
|
|
||||||
.navigation_metadata
|
|
||||||
.node_graph_to_viewport
|
.node_graph_to_viewport
|
||||||
.transform_point2(output_connector_position);
|
.transform_point2(output_connector_position);
|
||||||
let Some(output_connector) = &network_interface.output_connector_from_click(output_connector_position_viewport, breadcrumb_network_path) else {
|
let Some(output_connector) = &network_interface.output_connector_from_click(output_connector_position_viewport, breadcrumb_network_path) else {
|
||||||
@@ -339,14 +334,10 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
log::error!("Selection network path does not match breadcrumb network path in PointerDown");
|
log::error!("Selection network path does not match breadcrumb network path in PointerDown");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else {
|
|
||||||
log::error!("Could not get network metadata in PointerDown");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let click = ipp.mouse.position;
|
let click = ipp.mouse.position;
|
||||||
|
|
||||||
let node_graph_point = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.inverse().transform_point2(click);
|
let node_graph_point = network_interface.navigation_metadata(selection_network_path).node_graph_to_viewport.inverse().transform_point2(click);
|
||||||
|
|
||||||
if network_interface
|
if network_interface
|
||||||
.layer_click_target_from_click(click, network_interface::LayerClickTargetTypes::Grip, selection_network_path)
|
.layer_click_target_from_click(click, network_interface::LayerClickTargetTypes::Grip, selection_network_path)
|
||||||
@@ -358,7 +349,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
let clicked_id = network_interface.node_from_click(click, selection_network_path);
|
let clicked_id = network_interface.node_from_click(click, selection_network_path);
|
||||||
let clicked_input = network_interface.input_connector_from_click(click, selection_network_path);
|
let clicked_input = network_interface.input_connector_from_click(click, selection_network_path);
|
||||||
let clicked_output = network_interface.output_connector_from_click(click, selection_network_path);
|
let clicked_output = network_interface.output_connector_from_click(click, selection_network_path);
|
||||||
let network_metadata = network_interface.network_metadata(selection_network_path).unwrap();
|
|
||||||
|
|
||||||
// Create the add node popup on right click, then exit
|
// Create the add node popup on right click, then exit
|
||||||
if right_click {
|
if right_click {
|
||||||
@@ -402,11 +392,11 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
let node_graph_shift = if matches!(context_menu_data, ContextMenuData::CreateNode) {
|
let node_graph_shift = if matches!(context_menu_data, ContextMenuData::CreateNode) {
|
||||||
let appear_right_of_mouse = if click.x > ipp.viewport_bounds.size().x - 180. { -180. } else { 0. };
|
let appear_right_of_mouse = if click.x > ipp.viewport_bounds.size().x - 180. { -180. } else { 0. };
|
||||||
let appear_above_mouse = if click.y > ipp.viewport_bounds.size().y - 200. { -200. } else { 0. };
|
let appear_above_mouse = if click.y > ipp.viewport_bounds.size().y - 200. { -200. } else { 0. };
|
||||||
DVec2::new(appear_right_of_mouse, appear_above_mouse) / network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.matrix2.x_axis.x
|
DVec2::new(appear_right_of_mouse, appear_above_mouse) / network_interface.navigation_metadata(selection_network_path).node_graph_to_viewport.matrix2.x_axis.x
|
||||||
} else {
|
} else {
|
||||||
let appear_right_of_mouse = if click.x > ipp.viewport_bounds.size().x - 173. { -173. } else { 0. };
|
let appear_right_of_mouse = if click.x > ipp.viewport_bounds.size().x - 173. { -173. } else { 0. };
|
||||||
let appear_above_mouse = if click.y > ipp.viewport_bounds.size().y - 34. { -34. } else { 0. };
|
let appear_above_mouse = if click.y > ipp.viewport_bounds.size().y - 34. { -34. } else { 0. };
|
||||||
DVec2::new(appear_right_of_mouse, appear_above_mouse) / network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.matrix2.x_axis.x
|
DVec2::new(appear_right_of_mouse, appear_above_mouse) / network_interface.navigation_metadata(selection_network_path).node_graph_to_viewport.matrix2.x_axis.x
|
||||||
};
|
};
|
||||||
|
|
||||||
let context_menu_coordinates = ((node_graph_point.x + node_graph_shift.x) as i32, (node_graph_point.y + node_graph_shift.y) as i32);
|
let context_menu_coordinates = ((node_graph_point.x + node_graph_shift.x) as i32, (node_graph_point.y + node_graph_shift.y) as i32);
|
||||||
@@ -430,9 +420,8 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
|
|
||||||
// If the user is clicking on the create nodes list or context menu, break here
|
// If the user is clicking on the create nodes list or context menu, break here
|
||||||
if let Some(context_menu) = &self.context_menu {
|
if let Some(context_menu) = &self.context_menu {
|
||||||
let context_menu_viewport = network_metadata
|
let context_menu_viewport = network_interface
|
||||||
.persistent_metadata
|
.navigation_metadata(selection_network_path)
|
||||||
.navigation_metadata
|
|
||||||
.node_graph_to_viewport
|
.node_graph_to_viewport
|
||||||
.transform_point2(DVec2::new(context_menu.context_menu_coordinates.0 as f64, context_menu.context_menu_coordinates.1 as f64));
|
.transform_point2(DVec2::new(context_menu.context_menu_coordinates.0 as f64, context_menu.context_menu_coordinates.1 as f64));
|
||||||
let (width, height) = if matches!(context_menu.context_menu_data, ContextMenuData::ToggleLayer { .. }) {
|
let (width, height) = if matches!(context_menu.context_menu_data, ContextMenuData::ToggleLayer { .. }) {
|
||||||
@@ -576,18 +565,14 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
log::error!("Selection network path does not match breadcrumb network path in PointerMove");
|
log::error!("Selection network path does not match breadcrumb network path in PointerMove");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Auto-panning
|
// Auto-panning
|
||||||
let messages = [NodeGraphMessage::PointerOutsideViewport { shift }.into(), NodeGraphMessage::PointerMove { shift }.into()];
|
let messages = [NodeGraphMessage::PointerOutsideViewport { shift }.into(), NodeGraphMessage::PointerMove { shift }.into()];
|
||||||
self.auto_panning.setup_by_mouse_position(ipp, &messages, responses);
|
self.auto_panning.setup_by_mouse_position(ipp, &messages, responses);
|
||||||
|
|
||||||
let viewport_location = ipp.mouse.position;
|
let viewport_location = ipp.mouse.position;
|
||||||
let point = network_metadata
|
let point = network_interface
|
||||||
.persistent_metadata
|
.navigation_metadata(selection_network_path)
|
||||||
.navigation_metadata
|
|
||||||
.node_graph_to_viewport
|
.node_graph_to_viewport
|
||||||
.inverse()
|
.inverse()
|
||||||
.transform_point2(viewport_location);
|
.transform_point2(viewport_location);
|
||||||
@@ -628,12 +613,8 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
|
|
||||||
if let (Some(wire_in_progress_from_connector), Some(wire_in_progress_to_connector)) = (self.wire_in_progress_from_connector, self.wire_in_progress_to_connector) {
|
if let (Some(wire_in_progress_from_connector), Some(wire_in_progress_to_connector)) = (self.wire_in_progress_from_connector, self.wire_in_progress_to_connector) {
|
||||||
// If performance is a concern this can be stored as a field in the wire_in_progress_from/to_connector struct, and updated when snapping to an output
|
// If performance is a concern this can be stored as a field in the wire_in_progress_from/to_connector struct, and updated when snapping to an output
|
||||||
let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else {
|
let from_connector_viewport = network_interface
|
||||||
return;
|
.navigation_metadata(selection_network_path)
|
||||||
};
|
|
||||||
let from_connector_viewport = network_metadata
|
|
||||||
.persistent_metadata
|
|
||||||
.navigation_metadata
|
|
||||||
.node_graph_to_viewport
|
.node_graph_to_viewport
|
||||||
.transform_point2(wire_in_progress_from_connector);
|
.transform_point2(wire_in_progress_from_connector);
|
||||||
let from_connector_is_layer = network_interface
|
let from_connector_is_layer = network_interface
|
||||||
@@ -747,10 +728,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
log::error!("Could not get selected nodes in PointerUp");
|
log::error!("Could not get selected nodes in PointerUp");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else {
|
|
||||||
warn!("No network_metadata");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
responses.add(DocumentMessage::EndTransaction);
|
responses.add(DocumentMessage::EndTransaction);
|
||||||
|
|
||||||
@@ -764,16 +741,15 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: new_selected_nodes });
|
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: new_selected_nodes });
|
||||||
self.deselect_on_pointer_up = None;
|
self.deselect_on_pointer_up = None;
|
||||||
}
|
}
|
||||||
let point = network_metadata
|
let point = network_interface
|
||||||
.persistent_metadata
|
.navigation_metadata(selection_network_path)
|
||||||
.navigation_metadata
|
|
||||||
.node_graph_to_viewport
|
.node_graph_to_viewport
|
||||||
.inverse()
|
.inverse()
|
||||||
.transform_point2(ipp.mouse.position);
|
.transform_point2(ipp.mouse.position);
|
||||||
// Disconnect if the wire was previously connected to an input
|
// Disconnect if the wire was previously connected to an input
|
||||||
if let (Some(wire_in_progress_from_connector), Some(wire_in_progress_to_connector)) = (self.wire_in_progress_from_connector, self.wire_in_progress_to_connector) {
|
if let (Some(wire_in_progress_from_connector), Some(wire_in_progress_to_connector)) = (self.wire_in_progress_from_connector, self.wire_in_progress_to_connector) {
|
||||||
// Check if dragged connector is reconnected to another input
|
// Check if dragged connector is reconnected to another input
|
||||||
let node_graph_to_viewport = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport;
|
let node_graph_to_viewport = network_interface.navigation_metadata(selection_network_path).node_graph_to_viewport;
|
||||||
let from_connector_viewport = node_graph_to_viewport.transform_point2(wire_in_progress_from_connector);
|
let from_connector_viewport = node_graph_to_viewport.transform_point2(wire_in_progress_from_connector);
|
||||||
let to_connector_viewport = node_graph_to_viewport.transform_point2(wire_in_progress_to_connector);
|
let to_connector_viewport = node_graph_to_viewport.transform_point2(wire_in_progress_to_connector);
|
||||||
let output_connector = network_interface.output_connector_from_click(from_connector_viewport, selection_network_path);
|
let output_connector = network_interface.output_connector_from_click(from_connector_viewport, selection_network_path);
|
||||||
@@ -800,7 +776,8 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
|
|
||||||
let appear_right_of_mouse = if ipp.mouse.position.x > ipp.viewport_bounds.size().x - 173. { -173. } else { 0. };
|
let appear_right_of_mouse = if ipp.mouse.position.x > ipp.viewport_bounds.size().x - 173. { -173. } else { 0. };
|
||||||
let appear_above_mouse = if ipp.mouse.position.y > ipp.viewport_bounds.size().y - 34. { -34. } else { 0. };
|
let appear_above_mouse = if ipp.mouse.position.y > ipp.viewport_bounds.size().y - 34. { -34. } else { 0. };
|
||||||
let node_graph_shift = DVec2::new(appear_right_of_mouse, appear_above_mouse) / network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.matrix2.x_axis.x;
|
let node_graph_shift =
|
||||||
|
DVec2::new(appear_right_of_mouse, appear_above_mouse) / network_interface.navigation_metadata(selection_network_path).node_graph_to_viewport.matrix2.x_axis.x;
|
||||||
|
|
||||||
self.context_menu = Some(ContextMenuInformation {
|
self.context_menu = Some(ContextMenuInformation {
|
||||||
context_menu_coordinates: ((point.x + node_graph_shift.x) as i32, (point.y + node_graph_shift.y) as i32),
|
context_menu_coordinates: ((point.x + node_graph_shift.x) as i32, (point.y + node_graph_shift.y) as i32),
|
||||||
@@ -1283,7 +1260,10 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let box_selection_start_viewport = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.transform_point2(box_selection_start);
|
let box_selection_start_viewport = network_interface
|
||||||
|
.navigation_metadata(selection_network_path)
|
||||||
|
.node_graph_to_viewport
|
||||||
|
.transform_point2(box_selection_start);
|
||||||
|
|
||||||
let box_selection = Some(BoxSelection {
|
let box_selection = Some(BoxSelection {
|
||||||
start_x: box_selection_start_viewport.x.max(0.) as u32,
|
start_x: box_selection_start_viewport.x.max(0.) as u32,
|
||||||
@@ -1291,9 +1271,8 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
|||||||
end_x: ipp.mouse.position.x.max(0.) as u32,
|
end_x: ipp.mouse.position.x.max(0.) as u32,
|
||||||
end_y: ipp.mouse.position.y.max(0.) as u32,
|
end_y: ipp.mouse.position.y.max(0.) as u32,
|
||||||
});
|
});
|
||||||
let box_selection_end_graph = network_metadata
|
let box_selection_end_graph = network_interface
|
||||||
.persistent_metadata
|
.navigation_metadata(selection_network_path)
|
||||||
.navigation_metadata
|
|
||||||
.node_graph_to_viewport
|
.node_graph_to_viewport
|
||||||
.inverse()
|
.inverse()
|
||||||
.transform_point2(ipp.mouse.position);
|
.transform_point2(ipp.mouse.position);
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::{NodeId, InputConnector, OutputConnector};
|
||||||
use graphene_core::Type;
|
use graphene_core::Type;
|
||||||
|
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, OutputConnector};
|
|
||||||
|
|
||||||
#[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 {
|
||||||
#[default]
|
#[default]
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::consts::COLOR_OVERLAY_GRAY;
|
use crate::consts::COLOR_OVERLAY_GRAY;
|
||||||
|
|
||||||
|
use graph_craft::document::PTZ;
|
||||||
use graphene_core::raster::Color;
|
use graphene_core::raster::Color;
|
||||||
|
|
||||||
use glam::DVec2;
|
use glam::DVec2;
|
||||||
@@ -440,27 +441,3 @@ impl fmt::Display for SnappingOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
|
|
||||||
#[serde(default)]
|
|
||||||
pub struct PTZ {
|
|
||||||
pub pan: DVec2,
|
|
||||||
pub tilt: f64,
|
|
||||||
zoom: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for PTZ {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self { pan: DVec2::ZERO, tilt: 0., zoom: 1. }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PTZ {
|
|
||||||
pub fn zoom(&self) -> f64 {
|
|
||||||
self.zoom
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_zoom(&mut self, zoom: f64) {
|
|
||||||
self.zoom = zoom.clamp(crate::consts::VIEWPORT_ZOOM_SCALE_MIN, crate::consts::VIEWPORT_ZOOM_SCALE_MAX)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use super::document_metadata::{DocumentMetadata, LayerNodeIdentifier, NodeRelations};
|
use super::document_metadata::{DocumentMetadata, LayerNodeIdentifier, NodeRelations};
|
||||||
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;
|
||||||
@@ -8,6 +7,7 @@ use crate::messages::tool::common_functionality::graph_modification_utils;
|
|||||||
|
|
||||||
use bezier_rs::Subpath;
|
use bezier_rs::Subpath;
|
||||||
use graph_craft::document::{value::TaggedValue, DocumentNode, DocumentNodeImplementation, NodeId, NodeInput, NodeNetwork, OldDocumentNodeImplementation, OldNodeNetwork};
|
use graph_craft::document::{value::TaggedValue, DocumentNode, DocumentNodeImplementation, NodeId, NodeInput, NodeNetwork, OldDocumentNodeImplementation, OldNodeNetwork};
|
||||||
|
use graph_craft::document::{InputConnector, NavigationMetadata, OutputConnector, Previewing, RootNode, PTZ};
|
||||||
use graph_craft::{concrete, Type};
|
use graph_craft::{concrete, Type};
|
||||||
use graphene_std::renderer::{ClickTarget, Quad};
|
use graphene_std::renderer::{ClickTarget, Quad};
|
||||||
use graphene_std::vector::{PointId, VectorData, VectorModificationType};
|
use graphene_std::vector::{PointId, VectorData, VectorModificationType};
|
||||||
@@ -998,12 +998,16 @@ impl NodeNetworkInterface {
|
|||||||
upstream_nodes_below_layer
|
upstream_nodes_below_layer
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn previewing(&self, network_path: &[NodeId]) -> Previewing {
|
pub fn previewing(&self, network_path: &[NodeId]) -> Option<&Previewing> {
|
||||||
let Some(network_metadata) = self.network_metadata(network_path) else {
|
let Some(tagged_value) = self.metadata_value(&network_path, Metadata::Previewing) else {
|
||||||
log::error!("Could not get nested network_metadata in previewing");
|
log::error!("Could not get tagged value in previewing");
|
||||||
return Previewing::No;
|
return None;
|
||||||
};
|
};
|
||||||
network_metadata.persistent_metadata.previewing
|
let TaggedValue::Previewing(previewing) = tagged_value else {
|
||||||
|
log::error!("Tagged value should be Previewing in previewing");
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some(previewing)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the root node (the node that the solid line is connect to), or None if no nodes are connected to the output
|
/// Returns the root node (the node that the solid line is connect to), or None if no nodes are connected to the output
|
||||||
@@ -1012,11 +1016,8 @@ impl NodeNetworkInterface {
|
|||||||
log::error!("Could not get network in root_node");
|
log::error!("Could not get network in root_node");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let Some(network_metadata) = self.network_metadata(network_path) else {
|
let previewing = self.previewing(network_path);
|
||||||
log::error!("Could not get nested network_metadata in root_node");
|
match &previewing {
|
||||||
return None;
|
|
||||||
};
|
|
||||||
match &network_metadata.persistent_metadata.previewing {
|
|
||||||
Previewing::Yes { root_node_to_restore } => *root_node_to_restore,
|
Previewing::Yes { root_node_to_restore } => *root_node_to_restore,
|
||||||
Previewing::No => network.exports.first().and_then(|export| {
|
Previewing::No => network.exports.first().and_then(|export| {
|
||||||
if let NodeInput::Node { node_id, output_index, .. } = export {
|
if let NodeInput::Node { node_id, output_index, .. } = export {
|
||||||
@@ -1031,23 +1032,35 @@ impl NodeNetworkInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn navigation_metadata(&self, network_path: &[NodeId]) -> Option<&NavigationMetadata> {
|
||||||
|
let Some(tagged_value) = self.metadata_value(&network_path, Metadata::NavigationMetadata) else {
|
||||||
|
log::error!("Could not get tagged value in navigation_metadata");
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
let TaggedValue::NavigationMetadata(navigation_metadata) = tagged_value else {
|
||||||
|
log::error!("Tagged value should be Previewing in previewing");
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some(navigation_metadata)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reference(&self, node_id: &NodeId, network_path: &[NodeId]) -> Option<String> {
|
pub fn reference(&self, node_id: &NodeId, network_path: &[NodeId]) -> Option<String> {
|
||||||
self.node_metadata(node_id, network_path)
|
self.node_metadata(node_id, network_path)
|
||||||
.and_then(|node_metadata| node_metadata.persistent_metadata.reference.as_ref().map(|reference| reference.to_string()))
|
.and_then(|node_metadata| node_metadata.persistent_metadata.reference.as_ref().map(|reference| reference.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn display_name(&self, node_id: &NodeId, network_path: &[NodeId]) -> String {
|
pub fn display_name(&self, node_id: &NodeId, network_path: &[NodeId]) -> Option<&String> {
|
||||||
let mut node_id_path = network_path.to_vec();
|
let mut node_id_path = network_path.to_vec();
|
||||||
node_id_path.push(*node_id);
|
node_id_path.push(*node_id);
|
||||||
let Some(tagged_value, ..) = self.metadata_value(&node_id_path, Metadata::DisplayName) else {
|
let Some(tagged_value) = self.metadata_value(&node_id_path, Metadata::DisplayName) else {
|
||||||
log::error!("Could not get tagged value in display_name");
|
log::error!("Could not get tagged value in display_name");
|
||||||
return "".to_string();
|
return None;
|
||||||
};
|
};
|
||||||
let TaggedValue::String(display_name) = tagged_value else {
|
let TaggedValue::String(display_name) = tagged_value else {
|
||||||
log::error!("Tagged value should be String in display_name");
|
log::error!("Tagged value should be String in display_name");
|
||||||
return "".to_string();
|
return None;
|
||||||
};
|
};
|
||||||
display_name.clone()
|
Some(display_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn frontend_display_name(&self, node_id: &NodeId, network_path: &[NodeId]) -> String {
|
pub fn frontend_display_name(&self, node_id: &NodeId, network_path: &[NodeId]) -> String {
|
||||||
@@ -1842,9 +1855,8 @@ impl NodeNetworkInterface {
|
|||||||
|
|
||||||
let mut import_export_ports = Ports::new();
|
let mut import_export_ports = Ports::new();
|
||||||
|
|
||||||
let viewport_top_right = network_metadata
|
let viewport_top_right = self
|
||||||
.persistent_metadata
|
.navigation_metadata(network_path)
|
||||||
.navigation_metadata
|
|
||||||
.node_graph_to_viewport
|
.node_graph_to_viewport
|
||||||
.inverse()
|
.inverse()
|
||||||
.transform_point2(rounded_network_edge_distance.exports_to_edge_distance);
|
.transform_point2(rounded_network_edge_distance.exports_to_edge_distance);
|
||||||
@@ -1864,9 +1876,8 @@ impl NodeNetworkInterface {
|
|||||||
import_export_ports.insert_input_port_at_center(input_index, export_top_right + DVec2::new(0., input_index as f64 * 24.));
|
import_export_ports.insert_input_port_at_center(input_index, export_top_right + DVec2::new(0., input_index as f64 * 24.));
|
||||||
}
|
}
|
||||||
|
|
||||||
let viewport_top_left = network_metadata
|
let viewport_top_left = self
|
||||||
.persistent_metadata
|
.navigation_metadata(network_path)
|
||||||
.navigation_metadata
|
|
||||||
.node_graph_to_viewport
|
.node_graph_to_viewport
|
||||||
.inverse()
|
.inverse()
|
||||||
.transform_point2(rounded_network_edge_distance.imports_to_edge_distance);
|
.transform_point2(rounded_network_edge_distance.imports_to_edge_distance);
|
||||||
@@ -2541,15 +2552,13 @@ impl NodeNetworkInterface {
|
|||||||
let import_exports_viewport_top_left = rounded_network_edge_distance.imports_to_edge_distance;
|
let import_exports_viewport_top_left = rounded_network_edge_distance.imports_to_edge_distance;
|
||||||
let import_exports_viewport_bottom_right = rounded_network_edge_distance.exports_to_edge_distance;
|
let import_exports_viewport_bottom_right = rounded_network_edge_distance.exports_to_edge_distance;
|
||||||
|
|
||||||
let node_graph_top_left = network_metadata
|
let node_graph_top_left = self
|
||||||
.persistent_metadata
|
.navigation_metadata(network_path)
|
||||||
.navigation_metadata
|
|
||||||
.node_graph_to_viewport
|
.node_graph_to_viewport
|
||||||
.inverse()
|
.inverse()
|
||||||
.transform_point2(import_exports_viewport_top_left);
|
.transform_point2(import_exports_viewport_top_left);
|
||||||
let node_graph_bottom_right = network_metadata
|
let node_graph_bottom_right = self
|
||||||
.persistent_metadata
|
.navigation_metadata(network_path)
|
||||||
.navigation_metadata
|
|
||||||
.node_graph_to_viewport
|
.node_graph_to_viewport
|
||||||
.inverse()
|
.inverse()
|
||||||
.transform_point2(import_exports_viewport_bottom_right);
|
.transform_point2(import_exports_viewport_bottom_right);
|
||||||
@@ -2597,22 +2606,18 @@ impl NodeNetworkInterface {
|
|||||||
log::error!("Could not get nested network_metadata in node_graph_ptz_mut");
|
log::error!("Could not get nested network_metadata in node_graph_ptz_mut");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
Some(&mut network_metadata.persistent_metadata.navigation_metadata.node_graph_ptz)
|
Some(&mut self.navigation_metadata(network_path).node_graph_ptz)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Optimize getting click target intersections from click by using a spacial data structure like a quadtree instead of linear search
|
// TODO: Optimize getting click target intersections from click by using a spacial data structure like a quadtree instead of linear search
|
||||||
/// Click target getter methods
|
/// Click target getter methods
|
||||||
pub fn node_from_click(&mut self, click: DVec2, network_path: &[NodeId]) -> Option<NodeId> {
|
pub fn node_from_click(&mut self, click: DVec2, network_path: &[NodeId]) -> Option<NodeId> {
|
||||||
let Some(network_metadata) = self.network_metadata(network_path) else {
|
|
||||||
log::error!("Could not get nested network_metadata in node_from_click");
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
let Some(network) = self.network(network_path) else {
|
let Some(network) = self.network(network_path) else {
|
||||||
log::error!("Could not get nested network in node_from_click");
|
log::error!("Could not get nested network in node_from_click");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let point = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.inverse().transform_point2(click);
|
let point = self.navigation_metadata(network_path).node_graph_to_viewport.inverse().transform_point2(click);
|
||||||
let nodes = network.nodes.keys().copied().collect::<Vec<_>>();
|
let nodes = network.nodes.keys().copied().collect::<Vec<_>>();
|
||||||
let clicked_nodes = nodes
|
let clicked_nodes = nodes
|
||||||
.iter()
|
.iter()
|
||||||
@@ -2649,7 +2654,7 @@ impl NodeNetworkInterface {
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let point = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.inverse().transform_point2(click);
|
let point = self.navigation_metadata(network_path).node_graph_to_viewport.inverse().transform_point2(click);
|
||||||
let node_ids: Vec<_> = network.nodes.keys().copied().collect();
|
let node_ids: Vec<_> = network.nodes.keys().copied().collect();
|
||||||
|
|
||||||
node_ids
|
node_ids
|
||||||
@@ -2670,16 +2675,12 @@ impl NodeNetworkInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_connector_from_click(&mut self, click: DVec2, network_path: &[NodeId]) -> Option<InputConnector> {
|
pub fn input_connector_from_click(&mut self, click: DVec2, network_path: &[NodeId]) -> Option<InputConnector> {
|
||||||
let Some(network_metadata) = self.network_metadata(network_path) else {
|
|
||||||
log::error!("Could not get nested network_metadata in input_connector_from_click");
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
let Some(network) = self.network(network_path) else {
|
let Some(network) = self.network(network_path) else {
|
||||||
log::error!("Could not get nested network in input_connector_from_click");
|
log::error!("Could not get nested network in input_connector_from_click");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let point = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.inverse().transform_point2(click);
|
let point = self.navigation_metadata(network_path).node_graph_to_viewport.inverse().transform_point2(click);
|
||||||
network
|
network
|
||||||
.nodes
|
.nodes
|
||||||
.keys()
|
.keys()
|
||||||
@@ -2703,16 +2704,12 @@ impl NodeNetworkInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn output_connector_from_click(&mut self, click: DVec2, network_path: &[NodeId]) -> Option<OutputConnector> {
|
pub fn output_connector_from_click(&mut self, click: DVec2, network_path: &[NodeId]) -> Option<OutputConnector> {
|
||||||
let Some(network_metadata) = self.network_metadata(network_path) else {
|
|
||||||
log::error!("Could not get nested network_metadata in output_connector_from_click");
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
let Some(network) = self.network(network_path) else {
|
let Some(network) = self.network(network_path) else {
|
||||||
log::error!("Could not get nested network in output_connector_from_click");
|
log::error!("Could not get nested network in output_connector_from_click");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let point = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.inverse().transform_point2(click);
|
let point = self.navigation_metadata(network_path).node_graph_to_viewport.inverse().transform_point2(click);
|
||||||
let nodes = network.nodes.keys().copied().collect::<Vec<_>>();
|
let nodes = network.nodes.keys().copied().collect::<Vec<_>>();
|
||||||
nodes
|
nodes
|
||||||
.iter()
|
.iter()
|
||||||
@@ -2773,15 +2770,11 @@ impl NodeNetworkInterface {
|
|||||||
/// Get the combined bounding box of the click targets of the selected nodes in the node graph in viewport space
|
/// Get the combined bounding box of the click targets of the selected nodes in the node graph in viewport space
|
||||||
pub fn selected_nodes_bounding_box_viewport(&mut self, network_path: &[NodeId]) -> Option<[DVec2; 2]> {
|
pub fn selected_nodes_bounding_box_viewport(&mut self, network_path: &[NodeId]) -> Option<[DVec2; 2]> {
|
||||||
// Always get the bounding box for nodes in the currently viewed network
|
// Always get the bounding box for nodes in the currently viewed network
|
||||||
let Some(network_metadata) = self.network_metadata(network_path) else {
|
|
||||||
log::error!("Could not get nested network_metadata in selected_nodes_bounding_box_viewport");
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
let Some(selected_nodes) = self.selected_nodes(network_path) else {
|
let Some(selected_nodes) = self.selected_nodes(network_path) else {
|
||||||
log::error!("Could not get selected nodes in selected_nodes_bounding_box_viewport");
|
log::error!("Could not get selected nodes in selected_nodes_bounding_box_viewport");
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let node_graph_to_viewport = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport;
|
let node_graph_to_viewport = self.navigation_metadata(network_path).node_graph_to_viewport;
|
||||||
selected_nodes
|
selected_nodes
|
||||||
.selected_nodes()
|
.selected_nodes()
|
||||||
.cloned()
|
.cloned()
|
||||||
@@ -2797,13 +2790,8 @@ impl NodeNetworkInterface {
|
|||||||
/// Gets the bounding box in viewport coordinates for each node in the node graph
|
/// Gets the bounding box in viewport coordinates for each node in the node graph
|
||||||
pub fn graph_bounds_viewport_space(&mut self, network_path: &[NodeId]) -> Option<[DVec2; 2]> {
|
pub fn graph_bounds_viewport_space(&mut self, network_path: &[NodeId]) -> Option<[DVec2; 2]> {
|
||||||
let bounds = *self.all_nodes_bounding_box(network_path)?;
|
let bounds = *self.all_nodes_bounding_box(network_path)?;
|
||||||
let Some(network_metadata) = self.network_metadata(network_path) else {
|
|
||||||
log::error!("Could not get nested network_metadata in graph_bounds_viewport_space");
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let bounding_box_subpath = bezier_rs::Subpath::<PointId>::new_rect(bounds[0], bounds[1]);
|
let bounding_box_subpath = bezier_rs::Subpath::<PointId>::new_rect(bounds[0], bounds[1]);
|
||||||
bounding_box_subpath.bounding_box_with_transform(network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport)
|
bounding_box_subpath.bounding_box_with_transform(self.navigation_metadata(network_path).node_graph_to_viewport)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn collect_layer_widths(&mut self, network_path: &[NodeId]) -> (HashMap<NodeId, u32>, HashMap<NodeId, u32>) {
|
pub fn collect_layer_widths(&mut self, network_path: &[NodeId]) -> (HashMap<NodeId, u32>, HashMap<NodeId, u32>) {
|
||||||
@@ -2943,27 +2931,26 @@ impl NodeNetworkInterface {
|
|||||||
pub fn copy_all_navigation_metadata(&mut self, other_interface: &NodeNetworkInterface) {
|
pub fn copy_all_navigation_metadata(&mut self, other_interface: &NodeNetworkInterface) {
|
||||||
let mut stack = vec![vec![]];
|
let mut stack = vec![vec![]];
|
||||||
while let Some(path) = stack.pop() {
|
while let Some(path) = stack.pop() {
|
||||||
let Some(self_network_metadata) = self.network_metadata_mut(&path) else {
|
let Some(self_network_metadata) = self.network_metadata(&path) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if let Some(other_network_metadata) = other_interface.network_metadata(&path) {
|
|
||||||
self_network_metadata.persistent_metadata.navigation_metadata = other_network_metadata.persistent_metadata.navigation_metadata.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
stack.extend(self_network_metadata.persistent_metadata.node_metadata.keys().map(|node_id| {
|
stack.extend(self_network_metadata.persistent_metadata.node_metadata.keys().map(|node_id| {
|
||||||
let mut current_path = path.clone();
|
let mut current_path = path.clone();
|
||||||
current_path.push(*node_id);
|
current_path.push(*node_id);
|
||||||
current_path
|
current_path
|
||||||
}));
|
}));
|
||||||
|
if let Some(other_network_metadata) = other_interface.network_metadata(&path) {
|
||||||
|
let Some(navigation_metadata) = self.navigation_metadata_mut(&path) else {
|
||||||
|
log::error!("Could not get nested navigation_metadata in copy_all_navigation_metadata");
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
*navigation_metadata = other_network_metadata.persistent_metadata.navigation_metadata.clone();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_transform(&mut self, transform: DAffine2, network_path: &[NodeId]) {
|
pub fn set_transform(&mut self, transform: DAffine2, network_path: &[NodeId]) {
|
||||||
let Some(network_metadata) = self.network_metadata_mut(network_path) else {
|
self.navigation_metadata(network_path).node_graph_to_viewport = transform;
|
||||||
log::error!("Could not get nested network in set_transform");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport = transform;
|
|
||||||
self.unload_import_export_ports(network_path);
|
self.unload_import_export_ports(network_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3468,8 +3455,27 @@ impl NodeNetworkInterface {
|
|||||||
node_path.push(node_id);
|
node_path.push(node_id);
|
||||||
let display_name_node_id = Self::metadata_node_id(&node_path, Metadata::DisplayName);
|
let display_name_node_id = Self::metadata_node_id(&node_path, Metadata::DisplayName);
|
||||||
self.insert_node_metadata(display_name_node_id, TaggedValue::String(persistent_metadata.display_name));
|
self.insert_node_metadata(display_name_node_id, TaggedValue::String(persistent_metadata.display_name));
|
||||||
|
// TODO: Add the rest of the node metadata nodes
|
||||||
|
|
||||||
|
if let Some(nested_network) = persistent_metadata.network_metadata {
|
||||||
|
self.insert_network_metadata(&node_path, nested_network.persistent_metadata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds nodes for the network metadata. Should always be called when creating a new NodeNetwork
|
||||||
|
pub fn insert_network_metadata(&mut self, network_path: &[NodeId], persistent_metadata: NodeNetworkPersistentMetadata) {
|
||||||
|
let previewing_node_id = Self::metadata_node_id(network_path, Metadata::Previewing);
|
||||||
|
let navigation_metadata_id = Self::metadata_node_id(network_path, Metadata::NavigationMetadata);
|
||||||
|
self.insert_node_metadata(previewing_node_id, TaggedValue::Previewing(persistent_metadata.previewing));
|
||||||
|
self.insert_node_metadata(navigation_metadata_id, TaggedValue::NavigationMetadata(persistent_metadata.navigation_metadata));
|
||||||
|
// TODO: Add the rest of the network metadata nodes
|
||||||
|
|
||||||
|
for (node_id, node_metadata) in persistent_metadata.node_metadata {
|
||||||
|
self.insert_all_node_metadata(node_id, network_path, node_metadata.persistent_metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds a node for the metadata. TODO: Consider calling this if a metadata node cannot be found.
|
||||||
fn insert_node_metadata(&mut self, metadata_node_id: NodeId, tagged_value: TaggedValue) {
|
fn insert_node_metadata(&mut self, metadata_node_id: NodeId, tagged_value: TaggedValue) {
|
||||||
let network = self.network_mut(&[]).unwrap();
|
let network = self.network_mut(&[]).unwrap();
|
||||||
log::debug!("Inserting metadata node with id {metadata_node_id}");
|
log::debug!("Inserting metadata node with id {metadata_node_id}");
|
||||||
@@ -3667,15 +3673,11 @@ impl NodeNetworkInterface {
|
|||||||
|
|
||||||
pub fn start_previewing_without_restore(&mut self, network_path: &[NodeId]) {
|
pub fn start_previewing_without_restore(&mut self, network_path: &[NodeId]) {
|
||||||
// Some logic will have to be performed to prevent the graph positions from being completely changed when the export changes to some previewed node
|
// Some logic will have to be performed to prevent the graph positions from being completely changed when the export changes to some previewed node
|
||||||
let Some(network_metadata) = self.network_metadata_mut(network_path) else {
|
self.set_previewing(network_path, Previewing::Yes { root_node_to_restore: None });
|
||||||
log::error!("Could not get nested network_metadata in start_previewing_without_restore");
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
network_metadata.persistent_metadata.previewing = Previewing::Yes { root_node_to_restore: None };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop_previewing(&mut self, network_path: &[NodeId]) {
|
fn stop_previewing(&mut self, network_path: &[NodeId]) {
|
||||||
if let Previewing::Yes {
|
if let Some(Previewing::Yes) {
|
||||||
root_node_to_restore: Some(root_node_to_restore),
|
root_node_to_restore: Some(root_node_to_restore),
|
||||||
} = self.previewing(network_path)
|
} = self.previewing(network_path)
|
||||||
{
|
{
|
||||||
@@ -3685,11 +3687,57 @@ impl NodeNetworkInterface {
|
|||||||
network_path,
|
network_path,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let Some(network_metadata) = self.network_metadata_mut(network_path) else {
|
self.set_previewing(network_path, Previewing::No);
|
||||||
log::error!("Could not get nested network_metadata in stop_previewing");
|
}
|
||||||
|
|
||||||
|
fn set_previewing(&mut self, network_path: &[NodeId], previewing: Previewing) {
|
||||||
|
let network = self.network_mut(&[]).unwrap();
|
||||||
|
|
||||||
|
let previewing_node_id = Self::metadata_node_id(&network_path, Metadata::Previewing);
|
||||||
|
|
||||||
|
let Some(previewing_node) = network.nodes.get_mut(&previewing_node_id) else {
|
||||||
|
log::error!("Could not get display name node with id {previewing_node_id} in set_previewing");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
network_metadata.persistent_metadata.previewing = Previewing::No;
|
|
||||||
|
let Some(previewing_input) = previewing_node.inputs.get_mut(0) else {
|
||||||
|
log::error!("Could not get display name input in set_previewing");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(TaggedValue::Previewing(current_previewing)) = previewing_input.as_value() else {
|
||||||
|
log::error!("Could not get current display name in set_previewing");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if *current_previewing == previewing {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*previewing_input = NodeInput::value(TaggedValue::Previewing(previewing), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn navigation_metadata_mut(&mut self, network_path: &[NodeId]) -> Option<&mut NavigationMetadata> {
|
||||||
|
let network = self.network_mut(&[]).unwrap();
|
||||||
|
|
||||||
|
let navigation_metadata_id = Self::metadata_node_id(&network_path, Metadata::NavigationMetadata);
|
||||||
|
|
||||||
|
let Some(navigation_metadata_node) = network.nodes.get_mut(&navigation_metadata_id) else {
|
||||||
|
log::error!("Could not get navigation metadata node with id {navigation_metadata_id} in set_navigation_metadata");
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(navigation_metadata_input) = navigation_metadata_node.inputs.get_mut(0) else {
|
||||||
|
log::error!("Could not get navigation metadata input in set_navigation_metadata");
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(TaggedValue::NavigationMetadata(current_navigation_metadata)) = navigation_metadata_input.as_value_mut().as_deref_mut() else {
|
||||||
|
log::error!("Could not get current navigation metadata in set_navigation_metadata");
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(current_navigation_metadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the root node only if a node is being previewed
|
/// Sets the root node only if a node is being previewed
|
||||||
@@ -3709,7 +3757,7 @@ impl NodeNetworkInterface {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
pub fn set_display_name(&mut self, node_id: &NodeId, display_name: String, network_path: &[NodeId]) {
|
pub fn set_display_name(&mut self, node_id: &NodeId, display_name: String, network_path: &[NodeId]) {
|
||||||
let network = self.network_mut(network_path).unwrap();
|
let network = self.network_mut(&[]).unwrap();
|
||||||
|
|
||||||
let mut node_path = network_path.to_vec();
|
let mut node_path = network_path.to_vec();
|
||||||
node_path.push(*node_id);
|
node_path.push(*node_id);
|
||||||
@@ -3911,7 +3959,7 @@ impl NodeNetworkInterface {
|
|||||||
// The export is clicked
|
// The export is clicked
|
||||||
if *node_id == toggle_id {
|
if *node_id == toggle_id {
|
||||||
// If the current export is clicked and is being previewed end the preview and set either export back to root node or disconnect
|
// If the current export is clicked and is being previewed end the preview and set either export back to root node or disconnect
|
||||||
if let Previewing::Yes { root_node_to_restore } = self.previewing(network_path) {
|
if let Some(Previewing::Yes { root_node_to_restore }) = self.previewing(network_path) {
|
||||||
new_export = root_node_to_restore.map(|root_node| root_node.to_connector());
|
new_export = root_node_to_restore.map(|root_node| root_node.to_connector());
|
||||||
new_previewing_state = Previewing::No;
|
new_previewing_state = Previewing::No;
|
||||||
}
|
}
|
||||||
@@ -3930,7 +3978,7 @@ impl NodeNetworkInterface {
|
|||||||
new_export = Some(OutputConnector::node(toggle_id, 0));
|
new_export = Some(OutputConnector::node(toggle_id, 0));
|
||||||
|
|
||||||
// There is currently a dashed line being drawn
|
// There is currently a dashed line being drawn
|
||||||
if let Previewing::Yes { root_node_to_restore } = self.previewing(network_path) {
|
if let Some(Previewing::Yes { root_node_to_restore }) = self.previewing(network_path) {
|
||||||
// There is also a solid line being drawn
|
// There is also a solid line being drawn
|
||||||
if let Some(root_node_to_restore) = root_node_to_restore {
|
if let Some(root_node_to_restore) = root_node_to_restore {
|
||||||
// If the node with the solid line is clicked, then start previewing that node without restore
|
// If the node with the solid line is clicked, then start previewing that node without restore
|
||||||
@@ -3940,7 +3988,7 @@ impl NodeNetworkInterface {
|
|||||||
} else {
|
} else {
|
||||||
// Root node to restore does not change
|
// Root node to restore does not change
|
||||||
new_previewing_state = Previewing::Yes {
|
new_previewing_state = Previewing::Yes {
|
||||||
root_node_to_restore: Some(root_node_to_restore),
|
root_node_to_restore: Some(*root_node_to_restore),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3976,10 +4024,7 @@ impl NodeNetworkInterface {
|
|||||||
self.disconnect_input(&InputConnector::Export(0), network_path);
|
self.disconnect_input(&InputConnector::Export(0), network_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let Some(network_metadata) = self.network_metadata_mut(network_path) else {
|
self.set_previewing(network_path, new_previewing_state);
|
||||||
return;
|
|
||||||
};
|
|
||||||
network_metadata.persistent_metadata.previewing = new_previewing_state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the position of a node to an absolute position
|
/// Sets the position of a node to an absolute position
|
||||||
@@ -4932,86 +4977,6 @@ impl<'a> Iterator for FlowIter<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents an input connector with index based on the [`DocumentNode::inputs`] index, not the visible input index
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, specta::Type)]
|
|
||||||
pub enum InputConnector {
|
|
||||||
#[serde(rename = "node")]
|
|
||||||
Node {
|
|
||||||
#[serde(rename = "nodeId")]
|
|
||||||
node_id: NodeId,
|
|
||||||
#[serde(rename = "inputIndex")]
|
|
||||||
input_index: usize,
|
|
||||||
},
|
|
||||||
#[serde(rename = "export")]
|
|
||||||
Export(usize),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for InputConnector {
|
|
||||||
fn default() -> Self {
|
|
||||||
InputConnector::Export(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InputConnector {
|
|
||||||
pub fn node(node_id: NodeId, input_index: usize) -> Self {
|
|
||||||
InputConnector::Node { node_id, input_index }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn input_index(&self) -> usize {
|
|
||||||
match self {
|
|
||||||
InputConnector::Node { input_index, .. } => *input_index,
|
|
||||||
InputConnector::Export(input_index) => *input_index,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn node_id(&self) -> Option<NodeId> {
|
|
||||||
match self {
|
|
||||||
InputConnector::Node { node_id, .. } => Some(*node_id),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents an output connector
|
|
||||||
#[derive(Debug, Clone, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize, specta::Type)]
|
|
||||||
pub enum OutputConnector {
|
|
||||||
#[serde(rename = "node")]
|
|
||||||
Node {
|
|
||||||
#[serde(rename = "nodeId")]
|
|
||||||
node_id: NodeId,
|
|
||||||
#[serde(rename = "outputIndex")]
|
|
||||||
output_index: usize,
|
|
||||||
},
|
|
||||||
#[serde(rename = "import")]
|
|
||||||
Import(usize),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for OutputConnector {
|
|
||||||
fn default() -> Self {
|
|
||||||
OutputConnector::Import(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OutputConnector {
|
|
||||||
pub fn node(node_id: NodeId, output_index: usize) -> Self {
|
|
||||||
OutputConnector::Node { node_id, output_index }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn index(&self) -> usize {
|
|
||||||
match self {
|
|
||||||
OutputConnector::Node { output_index, .. } => *output_index,
|
|
||||||
OutputConnector::Import(output_index) => *output_index,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn node_id(&self) -> Option<NodeId> {
|
|
||||||
match self {
|
|
||||||
OutputConnector::Node { node_id, .. } => Some(*node_id),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Ports {
|
pub struct Ports {
|
||||||
input_ports: Vec<(usize, ClickTarget)>,
|
input_ports: Vec<(usize, ClickTarget)>,
|
||||||
@@ -5097,30 +5062,6 @@ impl Ports {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone, Copy, Hash, Default, serde::Serialize, serde::Deserialize)]
|
|
||||||
pub struct RootNode {
|
|
||||||
pub node_id: NodeId,
|
|
||||||
pub output_index: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RootNode {
|
|
||||||
pub fn to_connector(&self) -> OutputConnector {
|
|
||||||
OutputConnector::Node {
|
|
||||||
node_id: self.node_id,
|
|
||||||
output_index: self.output_index,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone, Copy, Hash, Default, serde::Serialize, serde::Deserialize)]
|
|
||||||
pub enum Previewing {
|
|
||||||
/// If there is a node to restore the connection to the export for, then it is stored in the option.
|
|
||||||
/// Otherwise, nothing gets restored and the primary export is disconnected.
|
|
||||||
Yes { root_node_to_restore: Option<RootNode> },
|
|
||||||
#[default]
|
|
||||||
No,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// All fields in NetworkMetadata should automatically be updated by using the network interface API. If a field is none then it should be calculated based on the network state.
|
/// All fields in NetworkMetadata should automatically be updated by using the network interface API. If a field is none then it should be calculated based on the network state.
|
||||||
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct NodeNetworkMetadata {
|
pub struct NodeNetworkMetadata {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use super::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use super::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use super::document::utility_types::network_interface::{self, InputConnector, OutputConnector};
|
use super::document::utility_types::network_interface;
|
||||||
use super::utility_types::{PanelType, PersistentData};
|
use super::utility_types::{PanelType, PersistentData};
|
||||||
use crate::application::generate_uuid;
|
use crate::application::generate_uuid;
|
||||||
use crate::consts::DEFAULT_DOCUMENT_NAME;
|
use crate::consts::DEFAULT_DOCUMENT_NAME;
|
||||||
@@ -13,7 +13,7 @@ use crate::messages::tool::utility_types::{HintData, HintGroup};
|
|||||||
use crate::node_graph_executor::{ExportConfig, NodeGraphExecutor};
|
use crate::node_graph_executor::{ExportConfig, NodeGraphExecutor};
|
||||||
|
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{NodeId, NodeInput};
|
use graph_craft::document::{InputConnector, NodeId, NodeInput, OutputConnector};
|
||||||
use graphene_core::text::Font;
|
use graphene_core::text::Font;
|
||||||
use graphene_std::vector::style::{Fill, FillType, Gradient};
|
use graphene_std::vector::style::{Fill, FillType, Gradient};
|
||||||
use interpreted_executor::dynamic_executor::IntrospectError;
|
use interpreted_executor::dynamic_executor::IntrospectError;
|
||||||
|
|||||||
@@ -5,12 +5,11 @@ use crate::application::generate_uuid;
|
|||||||
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
use crate::messages::portfolio::document::graph_operation::utility_types::TransformIn;
|
||||||
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::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 graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{NodeId, NodeInput};
|
use graph_craft::document::{InputConnector, NodeId, NodeInput};
|
||||||
use graphene_core::renderer::Quad;
|
use graphene_core::renderer::Quad;
|
||||||
use graphene_core::text::{load_face, Font, FontCache};
|
use graphene_core::text::{load_face, Font, FontCache};
|
||||||
use graphene_core::vector::style::Fill;
|
use graphene_core::vector::style::Fill;
|
||||||
|
|||||||
@@ -7,3 +7,7 @@ pub const LAYER_OUTLINE_STROKE_WEIGHT: f64 = 1.;
|
|||||||
// Fonts
|
// Fonts
|
||||||
pub const DEFAULT_FONT_FAMILY: &str = "Cabin";
|
pub const DEFAULT_FONT_FAMILY: &str = "Cabin";
|
||||||
pub const DEFAULT_FONT_STYLE: &str = "Normal (400)";
|
pub const DEFAULT_FONT_STYLE: &str = "Normal (400)";
|
||||||
|
|
||||||
|
// Zoom
|
||||||
|
pub const VIEWPORT_ZOOM_SCALE_MIN: f64 = 0.000_000_1;
|
||||||
|
pub const VIEWPORT_ZOOM_SCALE_MAX: f64 = 10_000.;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use graphene_core::memo::MemoHashGuard;
|
|||||||
pub use graphene_core::uuid::generate_uuid;
|
pub use graphene_core::uuid::generate_uuid;
|
||||||
use graphene_core::{Cow, MemoHash, ProtoNodeIdentifier, Type};
|
use graphene_core::{Cow, MemoHash, ProtoNodeIdentifier, Type};
|
||||||
|
|
||||||
use glam::IVec2;
|
use glam::{DAffine2, DVec2, IVec2};
|
||||||
use log::Metadata;
|
use log::Metadata;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::hash_map::DefaultHasher;
|
||||||
@@ -1356,6 +1356,162 @@ impl<'a> Iterator for RecursiveNodeIter<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, Clone, Copy, Hash, Default, serde::Serialize, serde::Deserialize, DynAny)]
|
||||||
|
pub enum Previewing {
|
||||||
|
/// If there is a node to restore the connection to the export for, then it is stored in the option.
|
||||||
|
/// Otherwise, nothing gets restored and the primary export is disconnected.
|
||||||
|
Yes { root_node_to_restore: Option<RootNode> },
|
||||||
|
#[default]
|
||||||
|
No,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, Clone, Copy, Hash, Default, serde::Serialize, serde::Deserialize, DynAny)]
|
||||||
|
pub struct RootNode {
|
||||||
|
pub node_id: NodeId,
|
||||||
|
pub output_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RootNode {
|
||||||
|
pub fn to_connector(&self) -> OutputConnector {
|
||||||
|
OutputConnector::Node {
|
||||||
|
node_id: self.node_id,
|
||||||
|
output_index: self.output_index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents an input connector with index based on the [`DocumentNode::inputs`] index, not the visible input index
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||||
|
pub enum InputConnector {
|
||||||
|
#[serde(rename = "node")]
|
||||||
|
Node {
|
||||||
|
#[serde(rename = "nodeId")]
|
||||||
|
node_id: NodeId,
|
||||||
|
#[serde(rename = "inputIndex")]
|
||||||
|
input_index: usize,
|
||||||
|
},
|
||||||
|
#[serde(rename = "export")]
|
||||||
|
Export(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for InputConnector {
|
||||||
|
fn default() -> Self {
|
||||||
|
InputConnector::Export(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InputConnector {
|
||||||
|
pub fn node(node_id: NodeId, input_index: usize) -> Self {
|
||||||
|
InputConnector::Node { node_id, input_index }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn input_index(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
InputConnector::Node { input_index, .. } => *input_index,
|
||||||
|
InputConnector::Export(input_index) => *input_index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn node_id(&self) -> Option<NodeId> {
|
||||||
|
match self {
|
||||||
|
InputConnector::Node { node_id, .. } => Some(*node_id),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents an output connector
|
||||||
|
#[derive(Debug, Clone, Hash, PartialEq, Eq, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||||
|
pub enum OutputConnector {
|
||||||
|
#[serde(rename = "node")]
|
||||||
|
Node {
|
||||||
|
#[serde(rename = "nodeId")]
|
||||||
|
node_id: NodeId,
|
||||||
|
#[serde(rename = "outputIndex")]
|
||||||
|
output_index: usize,
|
||||||
|
},
|
||||||
|
#[serde(rename = "import")]
|
||||||
|
Import(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for OutputConnector {
|
||||||
|
fn default() -> Self {
|
||||||
|
OutputConnector::Import(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutputConnector {
|
||||||
|
pub fn node(node_id: NodeId, output_index: usize) -> Self {
|
||||||
|
OutputConnector::Node { node_id, output_index }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn index(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
OutputConnector::Node { output_index, .. } => *output_index,
|
||||||
|
OutputConnector::Import(output_index) => *output_index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn node_id(&self) -> Option<NodeId> {
|
||||||
|
match self {
|
||||||
|
OutputConnector::Node { node_id, .. } => Some(*node_id),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, DynAny)]
|
||||||
|
pub struct NavigationMetadata {
|
||||||
|
/// The current pan, and zoom state of the viewport's view of the node graph.
|
||||||
|
/// Ensure `DocumentMessage::UpdateDocumentTransform` is called when the pan, zoom, or transform changes.
|
||||||
|
pub node_graph_ptz: PTZ,
|
||||||
|
// TODO: Remove and replace with calculate_offset_transform from the node_graph_ptz. This will be difficult since it requires both the navigation message handler and the IPP
|
||||||
|
/// Transform from node graph space to viewport space.
|
||||||
|
pub node_graph_to_viewport: DAffine2,
|
||||||
|
/// The viewport pixel distance distance between the left edge of the node graph and the exports. Rounded to nearest grid space when the panning ends.
|
||||||
|
#[serde(skip)]
|
||||||
|
pub exports_to_edge_distance: DVec2,
|
||||||
|
/// The viewport pixel distance between the left edge of the node graph and the imports. Rounded to nearest grid space when the panning ends.
|
||||||
|
#[serde(skip)]
|
||||||
|
pub imports_to_edge_distance: DVec2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for NavigationMetadata {
|
||||||
|
fn default() -> NavigationMetadata {
|
||||||
|
//Default PTZ and transform
|
||||||
|
NavigationMetadata {
|
||||||
|
node_graph_ptz: PTZ::default(),
|
||||||
|
node_graph_to_viewport: DAffine2::IDENTITY,
|
||||||
|
exports_to_edge_distance: DVec2::ZERO,
|
||||||
|
imports_to_edge_distance: DVec2::ZERO,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, serde::Serialize, serde::Deserialize, DynAny)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub struct PTZ {
|
||||||
|
pub pan: DVec2,
|
||||||
|
pub tilt: f64,
|
||||||
|
zoom: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PTZ {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { pan: DVec2::ZERO, tilt: 0., zoom: 1. }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PTZ {
|
||||||
|
pub fn zoom(&self) -> f64 {
|
||||||
|
self.zoom
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_zoom(&mut self, zoom: f64) {
|
||||||
|
self.zoom = zoom.clamp(graphene_core::consts::VIEWPORT_ZOOM_SCALE_MIN, graphene_core::consts::VIEWPORT_ZOOM_SCALE_MAX)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -178,6 +178,8 @@ tagged_value! {
|
|||||||
CentroidType(graphene_core::vector::misc::CentroidType),
|
CentroidType(graphene_core::vector::misc::CentroidType),
|
||||||
BooleanOperation(graphene_core::vector::misc::BooleanOperation),
|
BooleanOperation(graphene_core::vector::misc::BooleanOperation),
|
||||||
FontCache(Arc<graphene_core::text::FontCache>),
|
FontCache(Arc<graphene_core::text::FontCache>),
|
||||||
|
Previewing(crate::document::Previewing),
|
||||||
|
NavigationMetadata(crate::document::NavigationMetadata)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TaggedValue {
|
impl TaggedValue {
|
||||||
@@ -297,4 +299,19 @@ mod fake_hash {
|
|||||||
self.1.hash(state)
|
self.1.hash(state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl FakeHash for crate::document::PTZ {
|
||||||
|
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.pan.hash(state);
|
||||||
|
self.tilt.hash(state);
|
||||||
|
self.zoom.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl FakeHash for crate::document::NavigationMetadata {
|
||||||
|
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.node_graph_ptz.hash(state);
|
||||||
|
self.node_graph_to_viewport.hash(state);
|
||||||
|
self.exports_to_edge_distance.hash(state);
|
||||||
|
self.imports_to_edge_distance.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user