mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 14:58:05 +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
|
||||
pub const VIEWPORT_ZOOM_WHEEL_RATE: f64 = (1. / 600.) * 3.;
|
||||
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_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,
|
||||
|
||||
@@ -2,7 +2,7 @@ use super::node_graph::utility_types::Transform;
|
||||
use super::utility_types::clipboards::Clipboard;
|
||||
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::network_interface::{NodeNetworkInterface, TransactionStatus};
|
||||
use super::utility_types::network_interface::{NodeNetworkInterface, NodeNetworkPersistentMetadata, TransactionStatus};
|
||||
use super::utility_types::nodes::{CollapsedLayers, SelectedNodes};
|
||||
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};
|
||||
@@ -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::properties_panel::utility_types::PropertiesPanelMessageHandlerData;
|
||||
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::utility_types::PersistentData;
|
||||
use crate::messages::prelude::*;
|
||||
@@ -24,7 +24,7 @@ use crate::messages::tool::utility_types::ToolType;
|
||||
use crate::node_graph_executor::NodeGraphExecutor;
|
||||
|
||||
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::ImageFrame;
|
||||
use graphene_core::vector::style::ViewMode;
|
||||
@@ -779,10 +779,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
||||
}
|
||||
DocumentMessage::RenderRulers => {
|
||||
let current_ptz = if self.graph_view_overlay_open {
|
||||
let Some(network_metadata) = self.network_interface.network_metadata(&self.breadcrumb_network_path) else {
|
||||
return;
|
||||
};
|
||||
&network_metadata.persistent_metadata.navigation_metadata.node_graph_ptz
|
||||
self.network_interface.navigation_metadata(&self.breadcrumb_network_path)
|
||||
} else {
|
||||
&self.document_ptz
|
||||
};
|
||||
@@ -1112,7 +1109,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
|
||||
|
||||
let transform = self
|
||||
.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);
|
||||
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();
|
||||
@@ -1981,5 +1978,6 @@ impl DocumentMessageHandler {
|
||||
fn default_document_network_interface() -> NodeNetworkInterface {
|
||||
let mut network_interface = NodeNetworkInterface::default();
|
||||
network_interface.add_export(TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::EMPTY), -1, "".to_string(), &[]);
|
||||
network_interface.insert_network_metadata(&[], NodeNetworkPersistentMetadata::default());
|
||||
network_interface
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use super::transform_utils;
|
||||
use super::utility_types::ModifyInputsContext;
|
||||
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::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::text::Font;
|
||||
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 graph_craft::document::{value::TaggedValue, NodeId, NodeInput};
|
||||
use graph_craft::document::{value::TaggedValue, InputConnector, NodeId, NodeInput};
|
||||
use graphene_core::vector::PointId;
|
||||
|
||||
use glam::{DAffine2, DVec2};
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use super::transform_utils;
|
||||
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::network_interface::{self, InputConnector, NodeNetworkInterface, OutputConnector};
|
||||
use crate::messages::portfolio::document::utility_types::network_interface::{self, NodeNetworkInterface};
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
use bezier_rs::Subpath;
|
||||
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::text::Font;
|
||||
use graphene_core::vector::brush_stroke::BrushStroke;
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
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_ZOOM_TO_FIT_PADDING_SCALE_FACTOR, VIEWPORT_ZOOM_WHEEL_RATE,
|
||||
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_WHEEL_RATE,
|
||||
};
|
||||
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_mouse::ViewportPosition;
|
||||
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::prelude::*;
|
||||
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
||||
|
||||
use graph_craft::document::NodeId;
|
||||
use graph_craft::document::{NodeId, PTZ};
|
||||
|
||||
use glam::{DAffine2, DVec2};
|
||||
|
||||
@@ -46,8 +45,7 @@ impl MessageHandler<NavigationMessage, NavigationMessageData<'_>> for Navigation
|
||||
if !graph_view_overlay_open {
|
||||
Some(document_ptz)
|
||||
} else {
|
||||
let network_metadata = network_interface.network_metadata(breadcrumb_network_path)?;
|
||||
Some(&network_metadata.persistent_metadata.navigation_metadata.node_graph_ptz)
|
||||
Some(network_interface.navigation_metadata(breadcrumb_network_path).node_graph_ptz)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +247,7 @@ impl MessageHandler<NavigationMessage, NavigationMessageData<'_>> for Navigation
|
||||
log::error!("Could not get mutable PTZ in CanvasZoomSet");
|
||||
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);
|
||||
ptz.set_zoom(zoom);
|
||||
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use super::utility_types::Direction;
|
||||
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::network_interface::{InputConnector, NodeTemplate, OutputConnector};
|
||||
use crate::messages::portfolio::document::utility_types::network_interface::NodeTemplate;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
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 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::utility_types::{ContextMenuData, Direction, FrontendGraphDataType};
|
||||
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::prelude::*;
|
||||
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 graphene_core::*;
|
||||
use renderer::{ClickTarget, Quad};
|
||||
@@ -158,13 +158,8 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
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
|
||||
if let Some(output_connector_position) = self.wire_in_progress_from_connector {
|
||||
let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else {
|
||||
log::error!("Could not get network metadata in CreateNodeFromContextMenu");
|
||||
return;
|
||||
};
|
||||
let output_connector_position_viewport = network_metadata
|
||||
.persistent_metadata
|
||||
.navigation_metadata
|
||||
let output_connector_position_viewport = network_interface
|
||||
.navigation_metadata(selection_network_path)
|
||||
.node_graph_to_viewport
|
||||
.transform_point2(output_connector_position);
|
||||
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");
|
||||
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 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
|
||||
.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_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 network_metadata = network_interface.network_metadata(selection_network_path).unwrap();
|
||||
|
||||
// Create the add node popup on right click, then exit
|
||||
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 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. };
|
||||
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 {
|
||||
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. };
|
||||
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);
|
||||
@@ -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 let Some(context_menu) = &self.context_menu {
|
||||
let context_menu_viewport = network_metadata
|
||||
.persistent_metadata
|
||||
.navigation_metadata
|
||||
let context_menu_viewport = network_interface
|
||||
.navigation_metadata(selection_network_path)
|
||||
.node_graph_to_viewport
|
||||
.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 { .. }) {
|
||||
@@ -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");
|
||||
return;
|
||||
}
|
||||
let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else {
|
||||
return;
|
||||
};
|
||||
|
||||
// Auto-panning
|
||||
let messages = [NodeGraphMessage::PointerOutsideViewport { shift }.into(), NodeGraphMessage::PointerMove { shift }.into()];
|
||||
self.auto_panning.setup_by_mouse_position(ipp, &messages, responses);
|
||||
|
||||
let viewport_location = ipp.mouse.position;
|
||||
let point = network_metadata
|
||||
.persistent_metadata
|
||||
.navigation_metadata
|
||||
let point = network_interface
|
||||
.navigation_metadata(selection_network_path)
|
||||
.node_graph_to_viewport
|
||||
.inverse()
|
||||
.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 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 {
|
||||
return;
|
||||
};
|
||||
let from_connector_viewport = network_metadata
|
||||
.persistent_metadata
|
||||
.navigation_metadata
|
||||
let from_connector_viewport = network_interface
|
||||
.navigation_metadata(selection_network_path)
|
||||
.node_graph_to_viewport
|
||||
.transform_point2(wire_in_progress_from_connector);
|
||||
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");
|
||||
return;
|
||||
};
|
||||
let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else {
|
||||
warn!("No network_metadata");
|
||||
return;
|
||||
};
|
||||
|
||||
responses.add(DocumentMessage::EndTransaction);
|
||||
|
||||
@@ -764,16 +741,15 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphHandlerData<'a>> for NodeGrap
|
||||
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: new_selected_nodes });
|
||||
self.deselect_on_pointer_up = None;
|
||||
}
|
||||
let point = network_metadata
|
||||
.persistent_metadata
|
||||
.navigation_metadata
|
||||
let point = network_interface
|
||||
.navigation_metadata(selection_network_path)
|
||||
.node_graph_to_viewport
|
||||
.inverse()
|
||||
.transform_point2(ipp.mouse.position);
|
||||
// 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) {
|
||||
// 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 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);
|
||||
@@ -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_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 {
|
||||
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;
|
||||
};
|
||||
|
||||
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 {
|
||||
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_y: ipp.mouse.position.y.max(0.) as u32,
|
||||
});
|
||||
let box_selection_end_graph = network_metadata
|
||||
.persistent_metadata
|
||||
.navigation_metadata
|
||||
let box_selection_end_graph = network_interface
|
||||
.navigation_metadata(selection_network_path)
|
||||
.node_graph_to_viewport
|
||||
.inverse()
|
||||
.transform_point2(ipp.mouse.position);
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
use graph_craft::document::value::TaggedValue;
|
||||
use graph_craft::document::NodeId;
|
||||
use graph_craft::document::{NodeId, InputConnector, OutputConnector};
|
||||
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)]
|
||||
pub enum FrontendGraphDataType {
|
||||
#[default]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use crate::consts::COLOR_OVERLAY_GRAY;
|
||||
|
||||
use graph_craft::document::PTZ;
|
||||
use graphene_core::raster::Color;
|
||||
|
||||
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::misc::PTZ;
|
||||
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::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 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 graphene_std::renderer::{ClickTarget, Quad};
|
||||
use graphene_std::vector::{PointId, VectorData, VectorModificationType};
|
||||
@@ -998,12 +998,16 @@ impl NodeNetworkInterface {
|
||||
upstream_nodes_below_layer
|
||||
}
|
||||
|
||||
pub fn previewing(&self, network_path: &[NodeId]) -> Previewing {
|
||||
let Some(network_metadata) = self.network_metadata(network_path) else {
|
||||
log::error!("Could not get nested network_metadata in previewing");
|
||||
return Previewing::No;
|
||||
pub fn previewing(&self, network_path: &[NodeId]) -> Option<&Previewing> {
|
||||
let Some(tagged_value) = self.metadata_value(&network_path, Metadata::Previewing) else {
|
||||
log::error!("Could not get tagged value in previewing");
|
||||
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
|
||||
@@ -1012,11 +1016,8 @@ impl NodeNetworkInterface {
|
||||
log::error!("Could not get network in root_node");
|
||||
return None;
|
||||
};
|
||||
let Some(network_metadata) = self.network_metadata(network_path) else {
|
||||
log::error!("Could not get nested network_metadata in root_node");
|
||||
return None;
|
||||
};
|
||||
match &network_metadata.persistent_metadata.previewing {
|
||||
let previewing = self.previewing(network_path);
|
||||
match &previewing {
|
||||
Previewing::Yes { root_node_to_restore } => *root_node_to_restore,
|
||||
Previewing::No => network.exports.first().and_then(|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> {
|
||||
self.node_metadata(node_id, network_path)
|
||||
.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();
|
||||
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");
|
||||
return "".to_string();
|
||||
return None;
|
||||
};
|
||||
let TaggedValue::String(display_name) = tagged_value else {
|
||||
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 {
|
||||
@@ -1842,9 +1855,8 @@ impl NodeNetworkInterface {
|
||||
|
||||
let mut import_export_ports = Ports::new();
|
||||
|
||||
let viewport_top_right = network_metadata
|
||||
.persistent_metadata
|
||||
.navigation_metadata
|
||||
let viewport_top_right = self
|
||||
.navigation_metadata(network_path)
|
||||
.node_graph_to_viewport
|
||||
.inverse()
|
||||
.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.));
|
||||
}
|
||||
|
||||
let viewport_top_left = network_metadata
|
||||
.persistent_metadata
|
||||
.navigation_metadata
|
||||
let viewport_top_left = self
|
||||
.navigation_metadata(network_path)
|
||||
.node_graph_to_viewport
|
||||
.inverse()
|
||||
.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_bottom_right = rounded_network_edge_distance.exports_to_edge_distance;
|
||||
|
||||
let node_graph_top_left = network_metadata
|
||||
.persistent_metadata
|
||||
.navigation_metadata
|
||||
let node_graph_top_left = self
|
||||
.navigation_metadata(network_path)
|
||||
.node_graph_to_viewport
|
||||
.inverse()
|
||||
.transform_point2(import_exports_viewport_top_left);
|
||||
let node_graph_bottom_right = network_metadata
|
||||
.persistent_metadata
|
||||
.navigation_metadata
|
||||
let node_graph_bottom_right = self
|
||||
.navigation_metadata(network_path)
|
||||
.node_graph_to_viewport
|
||||
.inverse()
|
||||
.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");
|
||||
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
|
||||
/// Click target getter methods
|
||||
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 {
|
||||
log::error!("Could not get nested network in node_from_click");
|
||||
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 clicked_nodes = nodes
|
||||
.iter()
|
||||
@@ -2649,7 +2654,7 @@ impl NodeNetworkInterface {
|
||||
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();
|
||||
|
||||
node_ids
|
||||
@@ -2670,16 +2675,12 @@ impl NodeNetworkInterface {
|
||||
}
|
||||
|
||||
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 {
|
||||
log::error!("Could not get nested network in input_connector_from_click");
|
||||
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
|
||||
.nodes
|
||||
.keys()
|
||||
@@ -2703,16 +2704,12 @@ impl NodeNetworkInterface {
|
||||
}
|
||||
|
||||
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 {
|
||||
log::error!("Could not get nested network in output_connector_from_click");
|
||||
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<_>>();
|
||||
nodes
|
||||
.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
|
||||
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
|
||||
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 {
|
||||
log::error!("Could not get selected nodes in selected_nodes_bounding_box_viewport");
|
||||
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()
|
||||
.cloned()
|
||||
@@ -2797,13 +2790,8 @@ impl NodeNetworkInterface {
|
||||
/// 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]> {
|
||||
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]);
|
||||
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>) {
|
||||
@@ -2943,27 +2931,26 @@ impl NodeNetworkInterface {
|
||||
pub fn copy_all_navigation_metadata(&mut self, other_interface: &NodeNetworkInterface) {
|
||||
let mut stack = vec![vec![]];
|
||||
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;
|
||||
};
|
||||
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| {
|
||||
let mut current_path = path.clone();
|
||||
current_path.push(*node_id);
|
||||
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]) {
|
||||
let Some(network_metadata) = self.network_metadata_mut(network_path) else {
|
||||
log::error!("Could not get nested network in set_transform");
|
||||
return;
|
||||
};
|
||||
network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport = transform;
|
||||
self.navigation_metadata(network_path).node_graph_to_viewport = transform;
|
||||
self.unload_import_export_ports(network_path);
|
||||
}
|
||||
|
||||
@@ -3468,8 +3455,27 @@ impl NodeNetworkInterface {
|
||||
node_path.push(node_id);
|
||||
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));
|
||||
// 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) {
|
||||
let network = self.network_mut(&[]).unwrap();
|
||||
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]) {
|
||||
// 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 {
|
||||
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 };
|
||||
self.set_previewing(network_path, Previewing::Yes { root_node_to_restore: None });
|
||||
}
|
||||
|
||||
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),
|
||||
} = self.previewing(network_path)
|
||||
{
|
||||
@@ -3685,11 +3687,57 @@ impl NodeNetworkInterface {
|
||||
network_path,
|
||||
);
|
||||
}
|
||||
let Some(network_metadata) = self.network_metadata_mut(network_path) else {
|
||||
log::error!("Could not get nested network_metadata in stop_previewing");
|
||||
self.set_previewing(network_path, Previewing::No);
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
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
|
||||
@@ -3709,7 +3757,7 @@ impl NodeNetworkInterface {
|
||||
// }
|
||||
|
||||
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();
|
||||
node_path.push(*node_id);
|
||||
@@ -3911,7 +3959,7 @@ impl NodeNetworkInterface {
|
||||
// The export is clicked
|
||||
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 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_previewing_state = Previewing::No;
|
||||
}
|
||||
@@ -3930,7 +3978,7 @@ impl NodeNetworkInterface {
|
||||
new_export = Some(OutputConnector::node(toggle_id, 0));
|
||||
|
||||
// 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
|
||||
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
|
||||
@@ -3940,7 +3988,7 @@ impl NodeNetworkInterface {
|
||||
} else {
|
||||
// Root node to restore does not change
|
||||
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);
|
||||
}
|
||||
}
|
||||
let Some(network_metadata) = self.network_metadata_mut(network_path) else {
|
||||
return;
|
||||
};
|
||||
network_metadata.persistent_metadata.previewing = new_previewing_state;
|
||||
self.set_previewing(network_path, new_previewing_state);
|
||||
}
|
||||
|
||||
/// 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)]
|
||||
pub struct Ports {
|
||||
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.
|
||||
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
|
||||
pub struct NodeNetworkMetadata {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 crate::application::generate_uuid;
|
||||
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 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_std::vector::style::{Fill, FillType, Gradient};
|
||||
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::overlays::utility_types::OverlayContext;
|
||||
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::graph_modification_utils::{self, is_layer_fed_by_node_of_name};
|
||||
|
||||
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::text::{load_face, Font, FontCache};
|
||||
use graphene_core::vector::style::Fill;
|
||||
|
||||
@@ -7,3 +7,7 @@ pub const LAYER_OUTLINE_STROKE_WEIGHT: f64 = 1.;
|
||||
// Fonts
|
||||
pub const DEFAULT_FONT_FAMILY: &str = "Cabin";
|
||||
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;
|
||||
use graphene_core::{Cow, MemoHash, ProtoNodeIdentifier, Type};
|
||||
|
||||
use glam::IVec2;
|
||||
use glam::{DAffine2, DVec2, IVec2};
|
||||
use log::Metadata;
|
||||
use rustc_hash::FxHashMap;
|
||||
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)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
@@ -178,6 +178,8 @@ tagged_value! {
|
||||
CentroidType(graphene_core::vector::misc::CentroidType),
|
||||
BooleanOperation(graphene_core::vector::misc::BooleanOperation),
|
||||
FontCache(Arc<graphene_core::text::FontCache>),
|
||||
Previewing(crate::document::Previewing),
|
||||
NavigationMetadata(crate::document::NavigationMetadata)
|
||||
}
|
||||
|
||||
impl TaggedValue {
|
||||
@@ -297,4 +299,19 @@ mod fake_hash {
|
||||
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