mirror of
https://github.com/eliasstepanik/egui_node_graph.git
synced 2026-01-17 08:48:28 +00:00
Multiple improvements
This commit is contained in:
parent
316baf91c7
commit
d8189997ce
@ -15,11 +15,17 @@ pub type PortLocations = std::collections::HashMap<AnyParameterId, Pos2>;
|
|||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub enum NodeResponse<UserResponse: UserResponseTrait> {
|
pub enum NodeResponse<UserResponse: UserResponseTrait> {
|
||||||
ConnectEventStarted(NodeId, AnyParameterId),
|
ConnectEventStarted(NodeId, AnyParameterId),
|
||||||
ConnectEventEnded(AnyParameterId),
|
ConnectEventEnded {
|
||||||
|
output: OutputId,
|
||||||
|
input: InputId,
|
||||||
|
},
|
||||||
CreatedNode(NodeId),
|
CreatedNode(NodeId),
|
||||||
SelectNode(NodeId),
|
SelectNode(NodeId),
|
||||||
DeleteNode(NodeId),
|
DeleteNode(NodeId),
|
||||||
DisconnectEvent(InputId),
|
DisconnectEvent {
|
||||||
|
output: OutputId,
|
||||||
|
input: InputId,
|
||||||
|
},
|
||||||
/// Emitted when a node is interacted with, and should be raised
|
/// Emitted when a node is interacted with, and should be raised
|
||||||
RaiseNode(NodeId),
|
RaiseNode(NodeId),
|
||||||
User(UserResponse),
|
User(UserResponse),
|
||||||
@ -183,24 +189,8 @@ where
|
|||||||
NodeResponse::ConnectEventStarted(node_id, port) => {
|
NodeResponse::ConnectEventStarted(node_id, port) => {
|
||||||
self.connection_in_progress = Some((node_id, port));
|
self.connection_in_progress = Some((node_id, port));
|
||||||
}
|
}
|
||||||
NodeResponse::ConnectEventEnded(locator) => {
|
NodeResponse::ConnectEventEnded { input, output } => {
|
||||||
let in_out = match (
|
self.graph.add_connection(output, input)
|
||||||
self.connection_in_progress
|
|
||||||
.map(|(_node, param)| param)
|
|
||||||
.take()
|
|
||||||
.expect("Cannot end drag without in-progress connection."),
|
|
||||||
locator,
|
|
||||||
) {
|
|
||||||
(AnyParameterId::Input(input), AnyParameterId::Output(output))
|
|
||||||
| (AnyParameterId::Output(output), AnyParameterId::Input(input)) => {
|
|
||||||
Some((input, output))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some((input, output)) = in_out {
|
|
||||||
self.graph.add_connection(output, input)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
NodeResponse::CreatedNode(_) => {
|
NodeResponse::CreatedNode(_) => {
|
||||||
//Convenience NodeResponse for users
|
//Convenience NodeResponse for users
|
||||||
@ -213,9 +203,7 @@ where
|
|||||||
extra_responses.extend(
|
extra_responses.extend(
|
||||||
removed
|
removed
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|x| x.0)
|
.map(|(input, output)| NodeResponse::DisconnectEvent { input, output }),
|
||||||
.into_iter()
|
|
||||||
.map(NodeResponse::DisconnectEvent),
|
|
||||||
);
|
);
|
||||||
self.node_positions.remove(node_id);
|
self.node_positions.remove(node_id);
|
||||||
// Make sure to not leave references to old nodes hanging
|
// Make sure to not leave references to old nodes hanging
|
||||||
@ -224,15 +212,11 @@ where
|
|||||||
}
|
}
|
||||||
self.node_order.retain(|id| *id != node_id);
|
self.node_order.retain(|id| *id != node_id);
|
||||||
}
|
}
|
||||||
NodeResponse::DisconnectEvent(input_id) => {
|
NodeResponse::DisconnectEvent { input, output } => {
|
||||||
let corresp_output = self
|
let other_node = self.graph.get_input(input).node();
|
||||||
.graph
|
self.graph.remove_connection(input);
|
||||||
.connection(input_id)
|
|
||||||
.expect("Connection data should be valid");
|
|
||||||
let other_node = self.graph.get_input(input_id).node();
|
|
||||||
self.graph.remove_connection(input_id);
|
|
||||||
self.connection_in_progress =
|
self.connection_in_progress =
|
||||||
Some((other_node, AnyParameterId::Output(corresp_output)));
|
Some((other_node, AnyParameterId::Output(output)));
|
||||||
}
|
}
|
||||||
NodeResponse::RaiseNode(node_id) => {
|
NodeResponse::RaiseNode(node_id) => {
|
||||||
let old_pos = self
|
let old_pos = self
|
||||||
@ -375,6 +359,7 @@ where
|
|||||||
.text_style(TextStyle::Button)
|
.text_style(TextStyle::Button)
|
||||||
.color(text_color),
|
.color(text_color),
|
||||||
));
|
));
|
||||||
|
ui.add_space(8.0); // The size of the little cross icon
|
||||||
});
|
});
|
||||||
ui.add_space(margin.y);
|
ui.add_space(margin.y);
|
||||||
title_height = ui.min_size().y;
|
title_height = ui.min_size().y;
|
||||||
@ -460,7 +445,14 @@ where
|
|||||||
|
|
||||||
if resp.drag_started() {
|
if resp.drag_started() {
|
||||||
if is_connected_input {
|
if is_connected_input {
|
||||||
responses.push(NodeResponse::DisconnectEvent(param_id.assume_input()));
|
let input = param_id.assume_input();
|
||||||
|
let corresp_output = graph
|
||||||
|
.connection(input)
|
||||||
|
.expect("Connection data should be valid");
|
||||||
|
responses.push(NodeResponse::DisconnectEvent {
|
||||||
|
input: param_id.assume_input(),
|
||||||
|
output: corresp_output,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
responses.push(NodeResponse::ConnectEventStarted(node_id, param_id));
|
responses.push(NodeResponse::ConnectEventStarted(node_id, param_id));
|
||||||
}
|
}
|
||||||
@ -473,7 +465,13 @@ where
|
|||||||
&& resp.hovered()
|
&& resp.hovered()
|
||||||
&& ui.input().pointer.any_released()
|
&& ui.input().pointer.any_released()
|
||||||
{
|
{
|
||||||
responses.push(NodeResponse::ConnectEventEnded(param_id));
|
match (param_id, origin_param) {
|
||||||
|
(AnyParameterId::Input(input), AnyParameterId::Output(output))
|
||||||
|
| (AnyParameterId::Output(output), AnyParameterId::Input(input)) => {
|
||||||
|
responses.push(NodeResponse::ConnectEventEnded { input, output });
|
||||||
|
}
|
||||||
|
_ => { /* Ignore in-in or out-out connections */ }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -532,7 +530,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw the background shape.
|
// Draw the background shape.
|
||||||
// NOTE: This code is a bit more involve than it needs to be because egui
|
// NOTE: This code is a bit more involved than it needs to be because egui
|
||||||
// does not support drawing rectangles with asymmetrical round corners.
|
// does not support drawing rectangles with asymmetrical round corners.
|
||||||
|
|
||||||
let (shape, outline) = {
|
let (shape, outline) = {
|
||||||
|
|||||||
@ -16,11 +16,38 @@ pub trait WidgetValueTrait {
|
|||||||
/// [`Graph`]. This trait tells the library how to visually expose data types
|
/// [`Graph`]. This trait tells the library how to visually expose data types
|
||||||
/// to the user.
|
/// to the user.
|
||||||
pub trait DataTypeTrait<UserState>: PartialEq + Eq {
|
pub trait DataTypeTrait<UserState>: PartialEq + Eq {
|
||||||
// The associated port color of this datatype
|
/// The associated port color of this datatype
|
||||||
fn data_type_color(&self, user_state: &UserState) -> egui::Color32;
|
fn data_type_color(&self, user_state: &UserState) -> egui::Color32;
|
||||||
|
|
||||||
// The name of this datatype
|
/// The name of this datatype. Return type is specified as Cow<str> because
|
||||||
fn name(&self) -> &str;
|
/// some implementations will need to allocate a new string to provide an
|
||||||
|
/// answer while others won't.
|
||||||
|
///
|
||||||
|
/// ## Example (borrowed value)
|
||||||
|
/// Use this when you can get the name of the datatype from its fields or as
|
||||||
|
/// a &'static str. Prefer this method when possible.
|
||||||
|
/// ```rust
|
||||||
|
/// pub struct DataType { name: String }
|
||||||
|
///
|
||||||
|
/// impl DataTypeTrait<()> for DataType {
|
||||||
|
/// fn name(&self) -> std::borrow::Cow<str> {
|
||||||
|
/// Cow::Borrowed(&self.name)
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// ## Example (owned value)
|
||||||
|
/// Use this when you can't derive the name of the datatype from its fields.
|
||||||
|
/// ```rust
|
||||||
|
/// pub struct DataType { some_tag: i32 }
|
||||||
|
///
|
||||||
|
/// impl DataTypeTrait<()> for DataType {
|
||||||
|
/// fn name(&self) -> std::borrow::Cow<str> {
|
||||||
|
/// Cow::Owned(format!("Super amazing type #{}", self.some_tag))
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
fn name(&self) -> std::borrow::Cow<str>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This trait must be implemented for the `NodeData` generic parameter of the
|
/// This trait must be implemented for the `NodeData` generic parameter of the
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use std::collections::HashMap;
|
use std::{borrow::Cow, collections::HashMap};
|
||||||
|
|
||||||
use eframe::egui::{self, DragValue, TextStyle};
|
use eframe::egui::{self, DragValue, TextStyle};
|
||||||
use egui_node_graph::*;
|
use egui_node_graph::*;
|
||||||
@ -97,10 +97,10 @@ impl DataTypeTrait<MyGraphState> for MyDataType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> Cow<'_, str> {
|
||||||
match self {
|
match self {
|
||||||
MyDataType::Scalar => "scalar",
|
MyDataType::Scalar => Cow::Borrowed("scalar"),
|
||||||
MyDataType::Vec2 => "2d vector",
|
MyDataType::Vec2 => Cow::Borrowed("2d vector"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -383,7 +383,7 @@ impl eframe::App for NodeGraphExample {
|
|||||||
Err(err) => format!("Execution error: {}", err),
|
Err(err) => format!("Execution error: {}", err),
|
||||||
};
|
};
|
||||||
ctx.debug_painter().text(
|
ctx.debug_painter().text(
|
||||||
egui::pos2(10.0, 10.0),
|
egui::pos2(10.0, 35.0),
|
||||||
egui::Align2::LEFT_TOP,
|
egui::Align2::LEFT_TOP,
|
||||||
text,
|
text,
|
||||||
TextStyle::Button.resolve(&ctx.style()),
|
TextStyle::Button.resolve(&ctx.style()),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user