highlight node connections directly
This commit is contained in:
parent
3ca03069ec
commit
7e2f63b62d
|
|
@ -395,6 +395,7 @@ where
|
||||||
src_pos,
|
src_pos,
|
||||||
dst_pos,
|
dst_pos,
|
||||||
connection_color,
|
connection_color,
|
||||||
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -406,6 +407,8 @@ where
|
||||||
.any_param_type(AnyParameterId::Output(output))
|
.any_param_type(AnyParameterId::Output(output))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let connection_color = port_type.data_type_color(user_state);
|
let connection_color = port_type.data_type_color(user_state);
|
||||||
|
let highlighted =
|
||||||
|
self.highlighted_connection == Some((input, output));
|
||||||
// outputs can't be wide yet so this is fine.
|
// outputs can't be wide yet so this is fine.
|
||||||
let src_pos = port_locations[&AnyParameterId::Output(output)][0];
|
let src_pos = port_locations[&AnyParameterId::Output(output)][0];
|
||||||
let dst_pos = conn_locations[&input][hook_n];
|
let dst_pos = conn_locations[&input][hook_n];
|
||||||
|
|
@ -415,6 +418,7 @@ where
|
||||||
src_pos,
|
src_pos,
|
||||||
dst_pos,
|
dst_pos,
|
||||||
connection_color,
|
connection_color,
|
||||||
|
highlighted,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -586,10 +590,16 @@ fn draw_connection(
|
||||||
src_pos: Pos2,
|
src_pos: Pos2,
|
||||||
dst_pos: Pos2,
|
dst_pos: Pos2,
|
||||||
color: Color32,
|
color: Color32,
|
||||||
|
highlighted: bool,
|
||||||
) {
|
) {
|
||||||
|
let (width, draw_color) = if highlighted {
|
||||||
|
(7.0 * pan_zoom.zoom, Color32::from_rgb(100, 220, 100))
|
||||||
|
} else {
|
||||||
|
(5.0 * pan_zoom.zoom, color)
|
||||||
|
};
|
||||||
let connection_stroke = egui::Stroke {
|
let connection_stroke = egui::Stroke {
|
||||||
width: 5.0 * pan_zoom.zoom,
|
width,
|
||||||
color,
|
color: draw_color,
|
||||||
};
|
};
|
||||||
|
|
||||||
let control_scale = ((dst_pos.x - src_pos.x) * pan_zoom.zoom / 2.0).max(30.0 * pan_zoom.zoom);
|
let control_scale = ((dst_pos.x - src_pos.x) * pan_zoom.zoom / 2.0).max(30.0 * pan_zoom.zoom);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ pub struct GraphEditorState<NodeData, DataType, ValueType, NodeTemplate, UserSta
|
||||||
pub node_finder: Option<NodeFinder<NodeTemplate>>,
|
pub node_finder: Option<NodeFinder<NodeTemplate>>,
|
||||||
/// The panning of the graph viewport.
|
/// The panning of the graph viewport.
|
||||||
pub pan_zoom: PanZoom,
|
pub pan_zoom: PanZoom,
|
||||||
|
/// A connection to highlight (e.g. as an insertion target during node drag).
|
||||||
|
/// Stored as (InputId, OutputId). Not serialized.
|
||||||
|
#[cfg_attr(feature = "persistence", serde(skip))]
|
||||||
|
pub highlighted_connection: Option<(InputId, OutputId)>,
|
||||||
pub _user_state: PhantomData<fn() -> UserState>,
|
pub _user_state: PhantomData<fn() -> UserState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,6 +61,7 @@ impl<NodeData, DataType, ValueType, NodeKind, UserState> Default
|
||||||
node_positions: Default::default(),
|
node_positions: Default::default(),
|
||||||
node_finder: Default::default(),
|
node_finder: Default::default(),
|
||||||
pan_zoom: Default::default(),
|
pan_zoom: Default::default(),
|
||||||
|
highlighted_connection: Default::default(),
|
||||||
_user_state: Default::default(),
|
_user_state: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1128,36 +1128,6 @@ impl NodeGraphPane {
|
||||||
best.map(|(input, output, src, dst, _)| (input, output, src, dst))
|
best.map(|(input, output, src, dst, _)| (input, output, src, dst))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a highlight over a connection to indicate insertion target.
|
|
||||||
/// src/dst are in graph space — converted to screen space here.
|
|
||||||
fn draw_connection_highlight(
|
|
||||||
ui: &egui::Ui,
|
|
||||||
src_graph: egui::Pos2,
|
|
||||||
dst_graph: egui::Pos2,
|
|
||||||
zoom: f32,
|
|
||||||
pan: egui::Vec2,
|
|
||||||
editor_offset: egui::Vec2,
|
|
||||||
) {
|
|
||||||
// Convert graph space to screen space
|
|
||||||
let to_screen = |p: egui::Pos2| -> egui::Pos2 {
|
|
||||||
egui::pos2(p.x * zoom + pan.x + editor_offset.x, p.y * zoom + pan.y + editor_offset.y)
|
|
||||||
};
|
|
||||||
let src = to_screen(src_graph);
|
|
||||||
let dst = to_screen(dst_graph);
|
|
||||||
|
|
||||||
let control_scale = ((dst.x - src.x) / 2.0).max(30.0 * zoom);
|
|
||||||
let src_ctrl = egui::pos2(src.x + control_scale, src.y);
|
|
||||||
let dst_ctrl = egui::pos2(dst.x - control_scale, dst.y);
|
|
||||||
|
|
||||||
let bezier = egui::epaint::CubicBezierShape::from_points_stroke(
|
|
||||||
[src, src_ctrl, dst_ctrl, dst],
|
|
||||||
false,
|
|
||||||
egui::Color32::TRANSPARENT,
|
|
||||||
egui::Stroke::new(7.0 * zoom, egui::Color32::from_rgb(100, 220, 100)),
|
|
||||||
);
|
|
||||||
ui.painter().add(bezier);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute the insert-node-on-connection action
|
/// Execute the insert-node-on-connection action
|
||||||
fn execute_insert_on_connection(
|
fn execute_insert_on_connection(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
@ -3103,21 +3073,16 @@ impl crate::panes::PaneRenderer for NodeGraphPane {
|
||||||
if let Some(dragged) = self.dragging_node {
|
if let Some(dragged) = self.dragging_node {
|
||||||
if primary_down {
|
if primary_down {
|
||||||
// Still dragging — check for nearby compatible connection
|
// Still dragging — check for nearby compatible connection
|
||||||
if let Some((input_id, output_id, src_graph, dst_graph)) = self.find_insert_target(dragged) {
|
if let Some((input_id, output_id, _src_graph, _dst_graph)) = self.find_insert_target(dragged) {
|
||||||
self.insert_target = Some((input_id, output_id));
|
self.insert_target = Some((input_id, output_id));
|
||||||
Self::draw_connection_highlight(
|
self.state.highlighted_connection = Some((input_id, output_id));
|
||||||
ui,
|
|
||||||
src_graph,
|
|
||||||
dst_graph,
|
|
||||||
self.state.pan_zoom.zoom,
|
|
||||||
self.state.pan_zoom.pan,
|
|
||||||
rect.min.to_vec2(),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
self.insert_target = None;
|
self.insert_target = None;
|
||||||
|
self.state.highlighted_connection = None;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Drag ended — execute insertion if we have a target
|
// Drag ended — execute insertion if we have a target
|
||||||
|
self.state.highlighted_connection = None;
|
||||||
if let Some((target_input, target_output)) = self.insert_target.take() {
|
if let Some((target_input, target_output)) = self.insert_target.take() {
|
||||||
self.execute_insert_on_connection(dragged, target_input, target_output, shared);
|
self.execute_insert_on_connection(dragged, target_input, target_output, shared);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue