Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions editor/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ impl Editor {
open: active_document.graph_view_overlay_open,
in_selected_network: &active_document.selection_network_path == breadcrumb_network_path,
previewed_node,
thumbnails: active_document.node_graph_handler.thumbnails.clone()
};
let opacity = active_document.graph_fade_artwork_percentage;
let node_graph_overlay_node = generate_node_graph_overlay(node_graph_render_data, opacity);
Expand Down
1 change: 1 addition & 0 deletions editor/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub const EXPORTS_TO_TOP_EDGE_PIXEL_GAP: u32 = 72;
pub const EXPORTS_TO_RIGHT_EDGE_PIXEL_GAP: u32 = 120;
pub const IMPORTS_TO_TOP_EDGE_PIXEL_GAP: u32 = 72;
pub const IMPORTS_TO_LEFT_EDGE_PIXEL_GAP: u32 = 120;
pub const INPUT_TOOLTIP_DELAY: u64 = 800;

// VIEWPORT
pub const VIEWPORT_ZOOM_WHEEL_RATE: f64 = (1. / 600.) * 3.;
Expand Down
2 changes: 2 additions & 0 deletions editor/src/dispatcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ const SIDE_EFFECT_FREE_MESSAGES: &[MessageDiscriminant] = &[
const DEBUG_MESSAGE_BLOCK_LIST: &[MessageDiscriminant] = &[
MessageDiscriminant::Broadcast(BroadcastMessageDiscriminant::TriggerEvent(EventMessageDiscriminant::AnimationFrame)),
MessageDiscriminant::Animation(AnimationMessageDiscriminant::IncrementFrameCounter),
MessageDiscriminant::Defer(DeferMessageDiscriminant::CheckDeferredMessages),
];
// TODO: Find a way to combine these with the list above. We use strings for now since these are the standard variant names used by multiple messages. But having these also type-checked would be best.
const DEBUG_MESSAGE_ENDING_BLOCK_LIST: &[&str] = &["PointerMove", "PointerOutsideViewport", "Overlays", "Draw", "CurrentTime", "Time"];
Expand Down Expand Up @@ -140,6 +141,7 @@ impl Dispatcher {
Message::Defer(message) => {
let context = DeferMessageContext {
portfolio: &self.message_handlers.portfolio_message_handler,
time: self.message_handlers.input_preprocessor_message_handler.time,
};
self.message_handlers.defer_message_handler.process_message(message, &mut queue, context);
}
Expand Down
4 changes: 4 additions & 0 deletions editor/src/messages/defer/defer_message.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::time::Duration;

use crate::messages::prelude::*;

#[impl_message(Message, Defer)]
Expand All @@ -8,4 +10,6 @@ pub enum DeferMessage {
AfterGraphRun { messages: Vec<Message> },
TriggerNavigationReady,
AfterNavigationReady { messages: Vec<Message> },
RequestDeferredMessage { timeout: Duration, message: Box<Message> },
CheckDeferredMessages,
}
13 changes: 13 additions & 0 deletions editor/src/messages/defer/defer_message_handler.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
use std::collections::BTreeMap;

use crate::messages::prelude::*;

#[derive(ExtractField)]
pub struct DeferMessageContext<'a> {
pub portfolio: &'a PortfolioMessageHandler,
pub time: u64,
}

#[derive(Debug, Default, ExtractField)]
pub struct DeferMessageHandler {
after_graph_run: HashMap<DocumentId, Vec<(u64, Message)>>,
after_viewport_resize: Vec<Message>,
current_graph_submission_id: u64,
after_time_elapsed: BTreeMap<u64, Message>,
}

#[message_handler_data]
Expand Down Expand Up @@ -49,6 +53,15 @@ impl MessageHandler<DeferMessage, DeferMessageContext<'_>> for DeferMessageHandl
responses.add_front(message);
}
}
DeferMessage::RequestDeferredMessage { timeout, message } => {
self.after_time_elapsed.insert(context.time + timeout.as_millis() as u64, *message);
}
DeferMessage::CheckDeferredMessages => {
let after_current_time = self.after_time_elapsed.split_off(&context.time);
for (_, message) in std::mem::replace(&mut self.after_time_elapsed, after_current_time) {
responses.add(message);
}
}
}
}

Expand Down
9 changes: 4 additions & 5 deletions editor/src/messages/frontend/frontend_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,10 +175,6 @@ pub enum FrontendMessage {
#[serde(rename = "exportIndex")]
index: Option<usize>,
},
UpdateLayerWidths {
#[serde(rename = "layerWidths")]
layer_widths: HashMap<NodeId, u32>,
},
UpdateDialogButtons {
#[serde(rename = "layoutTarget")]
layout_target: LayoutTarget,
Expand Down Expand Up @@ -269,7 +265,6 @@ pub enum FrontendMessage {
UpdateMouseCursor {
cursor: MouseCursorIcon,
},
RequestNativeNodeGraphRender,
UpdateNativeNodeGraphSVG {
#[serde(rename = "svgString")]
svg_string: String,
Expand Down Expand Up @@ -305,6 +300,10 @@ pub enum FrontendMessage {
layout_target: LayoutTarget,
diff: Vec<WidgetDiff>,
},
UpdateTooltip {
position: Option<FrontendXY>,
text: String,
},
UpdateWirePathInProgress {
#[serde(rename = "wirePathInProgress")]
wire_path_in_progress: Option<WirePathInProgress>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl MessageHandler<InputPreprocessorMessage, InputPreprocessorMessageContext> f
.into(),
],
});
responses.add(NodeGraphMessage::UpdateNodeGraphTopRight);
}
InputPreprocessorMessage::DoubleClick { editor_mouse_state, modifier_keys } => {
self.update_states_of_modifier_keys(modifier_keys, keyboard_platform, responses);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
self.selection_network_path.clone_from(&self.breadcrumb_network_path);
responses.add(NodeGraphMessage::SendGraph);
responses.add(DocumentMessage::ZoomCanvasToFitAll);
responses.add(NodeGraphMessage::UpdateNodeGraphTopRight);
}
DocumentMessage::Escape => {
if self.node_graph_handler.drag_start.is_some() {
Expand Down Expand Up @@ -504,6 +505,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> for DocumentMes
}
responses.add(NodeGraphMessage::SendGraph);
responses.add(DocumentMessage::PTZUpdate);
responses.add(NodeGraphMessage::UpdateNodeGraphTopRight);
}
DocumentMessage::FlipSelectedLayers { flip_axis } => {
let scale = match flip_axis {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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::{ImportOrExport, InputConnector, NodeTemplate, OutputConnector};
use crate::messages::prelude::*;
use glam::IVec2;
use glam::{DVec2, IVec2};
use graph_craft::document::value::TaggedValue;
use graph_craft::document::{NodeId, NodeInput};
use graph_craft::proto::GraphErrors;
Expand Down Expand Up @@ -112,6 +112,7 @@ pub enum NodeGraphMessage {
PointerOutsideViewport {
shift: Key,
},
UpdateNodeGraphTopRight,
ShakeNode,
RemoveImport {
import_index: usize,
Expand Down Expand Up @@ -215,6 +216,9 @@ pub enum NodeGraphMessage {
SetLockedOrVisibilitySideEffects {
node_ids: Vec<NodeId>,
},
TryDisplayTooltip {
initial_position: DVec2,
},
UpdateBoxSelection,
UpdateImportsExports,
UpdateLayerPanel,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::utility_types::{BoxSelection, ContextMenuInformation, DragStart};
use super::{document_node_definitions, node_properties};
use crate::consts::GRID_SIZE;
use crate::consts::*;
use crate::messages::input_mapper::utility_types::macros::action_keys;
use crate::messages::layout::utility_types::widget_prelude::*;
use crate::messages::portfolio::document::document_message_handler::navigation_controls;
Expand Down Expand Up @@ -30,6 +30,7 @@ use graphene_std::*;
use kurbo::{DEFAULT_ACCURACY, Shape};
use renderer::Quad;
use std::cmp::Ordering;
use std::time::Duration;

#[derive(Debug, ExtractField)]
pub struct NodeGraphMessageContext<'a> {
Expand Down Expand Up @@ -94,6 +95,12 @@ pub struct NodeGraphMessageHandler {
end_index: Option<usize>,
// The rendered string for each thumbnail
pub thumbnails: HashMap<NodeId, Graphic>,
// If an input is being hovered. Used for tooltip
hovering_input: bool,
// If an output is being hovered. Used for tooltip
hovering_output: bool,
// If a node is being hovered. Used for tooltip
hovering_node: bool,
}

/// NodeGraphMessageHandler always modifies the network which the selected nodes are in. No GraphOperationMessages should be added here, since those messages will always affect the document network.
Expand Down Expand Up @@ -1143,6 +1150,38 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
.unwrap_or_else(|| modify_import_export.reorder_imports_exports.input_ports().count() + 1),
);
responses.add(FrontendMessage::UpdateExportReorderIndex { index: self.end_index });
} else if !self.hovering_input && !self.hovering_output && !self.hovering_node {
if network_interface.input_connector_from_click(ipp.mouse.position, breadcrumb_network_path).is_some() {
responses.add(DeferMessage::RequestDeferredMessage {
message: Box::new(NodeGraphMessage::TryDisplayTooltip { initial_position: ipp.mouse.position }.into()),
timeout: Duration::from_millis(INPUT_TOOLTIP_DELAY),
});
} else if network_interface.output_connector_from_click(ipp.mouse.position, breadcrumb_network_path).is_some() {
responses.add(DeferMessage::RequestDeferredMessage {
message: Box::new(NodeGraphMessage::TryDisplayTooltip { initial_position: ipp.mouse.position }.into()),
timeout: Duration::from_millis(INPUT_TOOLTIP_DELAY),
})
} else if network_interface.node_from_click(ipp.mouse.position, breadcrumb_network_path).is_some() {
responses.add(DeferMessage::RequestDeferredMessage {
message: Box::new(NodeGraphMessage::TryDisplayTooltip { initial_position: ipp.mouse.position }.into()),
timeout: Duration::from_millis(INPUT_TOOLTIP_DELAY),
})
}
} else if self.hovering_input {
if !network_interface.input_connector_from_click(ipp.mouse.position, breadcrumb_network_path).is_some() {
self.hovering_input = false;
responses.add(FrontendMessage::UpdateTooltip { position: None, text: String::new() });
}
} else if self.hovering_output {
if !network_interface.output_connector_from_click(ipp.mouse.position, breadcrumb_network_path).is_some() {
self.hovering_output = false;
responses.add(FrontendMessage::UpdateTooltip { position: None, text: String::new() });
}
} else if self.hovering_node {
if !network_interface.node_from_click(ipp.mouse.position, breadcrumb_network_path).is_some() {
self.hovering_node = false;
responses.add(FrontendMessage::UpdateTooltip { position: None, text: String::new() });
}
}
}
NodeGraphMessage::PointerUp => {
Expand Down Expand Up @@ -1405,6 +1444,10 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
self.auto_panning.stop(&messages, responses);
}
}
NodeGraphMessage::UpdateNodeGraphTopRight => {
network_interface.set_node_graph_width(ipp.viewport_bounds.size().x, breadcrumb_network_path);
responses.add(NodeGraphMessage::UpdateImportsExports);
}
NodeGraphMessage::ShakeNode => {
let Some(drag_start) = &self.drag_start else {
log::error!("Drag start should be initialized when shaking a node");
Expand Down Expand Up @@ -1595,8 +1638,6 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
responses.add(DocumentMessage::DocumentStructureChanged);
responses.add(PropertiesPanelMessage::Refresh);
responses.add(NodeGraphMessage::UpdateActionButtons);

responses.add(FrontendMessage::RequestNativeNodeGraphRender);
responses.add(NodeGraphMessage::UpdateImportsExports);
self.update_node_graph_hints(responses);
}
Expand Down Expand Up @@ -1807,6 +1848,61 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
responses.add(NodeGraphMessage::SetVisibility { node_id, visible });
responses.add(NodeGraphMessage::SetLockedOrVisibilitySideEffects { node_ids: vec![node_id] });
}
NodeGraphMessage::TryDisplayTooltip { initial_position } => {
if initial_position != ipp.mouse.position {
return;
} else if let Some(input) = network_interface.input_connector_from_click(ipp.mouse.position, breadcrumb_network_path) {
let text = network_interface.input_tooltip_text(&input, breadcrumb_network_path);
if let Some(position) = network_interface.input_position(&input, breadcrumb_network_path) {
let Some(network_metadata) = network_interface.network_metadata(breadcrumb_network_path) else {
return;
};
let position = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.transform_point2(position);
let xy = FrontendXY {
x: position.x as i32,
y: position.y as i32,
};
responses.add(FrontendMessage::UpdateTooltip { position: Some(xy), text });
self.hovering_input = true;
}
} else if let Some(output) = network_interface.output_connector_from_click(ipp.mouse.position, breadcrumb_network_path) {
let text = network_interface.output_tooltip_text(&output, breadcrumb_network_path);
if let Some(position) = network_interface.output_position(&output, breadcrumb_network_path) {
let Some(network_metadata) = network_interface.network_metadata(breadcrumb_network_path) else {
return;
};
let position = network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.transform_point2(position);

let xy = FrontendXY {
x: position.x as i32,
y: position.y as i32,
};
responses.add(FrontendMessage::UpdateTooltip { position: Some(xy), text });
self.hovering_output = true;
}
} else if let Some(node_id) = network_interface.node_from_click(ipp.mouse.position, breadcrumb_network_path) {
let text = network_interface.node_tooltip_text(&node_id, breadcrumb_network_path);
let Some(position) = network_interface.position(&node_id, breadcrumb_network_path) else {
log::error!("Could not get position from node: {node_id}");
return;
};
let Some(network_metadata) = network_interface.network_metadata(breadcrumb_network_path) else {
return;
};
let position = network_metadata
.persistent_metadata
.navigation_metadata
.node_graph_to_viewport
.transform_point2(DVec2::new(position.x as f64 * 24., position.y as f64 * 24.));

let xy = FrontendXY {
x: position.x as i32,
y: position.y as i32,
};
responses.add(FrontendMessage::UpdateTooltip { position: Some(xy), text });
self.hovering_node = true;
}
}
NodeGraphMessage::SetPinned { node_id, pinned } => {
network_interface.set_pinned(&node_id, selection_network_path, pinned);
}
Expand Down Expand Up @@ -2565,6 +2661,9 @@ impl Default for NodeGraphMessageHandler {
reordering_import: None,
end_index: None,
thumbnails: HashMap::new(),
hovering_input: false,
hovering_output: false,
hovering_node: false,
}
}
}
Expand Down
Loading
Loading