use uuid::Uuid;
use serde::{Deserialize, Serialize};
#[cfg(feature = "egui")]
use crate::ui::*;
use crate::*;
pub type NodeGroupId = Uuid;
pub const NODE_GROUP_MARGIN: f32 = 50.0;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct NodeGroup {
pub id: NodeGroupId,
title: String,
area: emath::Rect,
}
impl GetId for NodeGroup {
fn id(&self) -> Uuid {
self.id
}
}
impl NodeGroup {
pub fn new() -> Self {
Self {
id: Uuid::new_v4(),
title: "".to_string(),
area: emath::Rect::NOTHING,
}
}
pub fn set_area(&mut self, area: emath::Rect) {
self.area = area.expand(NODE_GROUP_MARGIN);
}
pub fn add_node(&mut self, node: &mut Node) {
node.group_id = self.id;
self.area = self.area.union(node.rect().expand(NODE_GROUP_MARGIN));
}
}
#[cfg(feature = "egui")]
impl NodeFrame for NodeGroup {
fn title(&self) -> &str {
&self.title
}
fn set_title(&mut self, title: String) {
self.title = title;
}
fn rect(&self) -> emath::Rect {
self.area
}
fn set_rect(&mut self, rect: emath::Rect) {
self.area = rect;
}
fn frame_style(&self) -> NodeFrameStyle {
NodeFrameStyle {
fill: egui::Color32::from_gray(10),
..Default::default()
}
}
fn handle_resp(
&mut self,
_ui: &mut egui::Ui,
resp: egui::Response,
_graph: &NodeGraphMeta,
frame: &mut NodeFrameState,
) -> Option<NodeAction> {
let mut action = None;
if resp.clicked() {
action = Some(NodeAction::Clicked);
} else if resp.dragged() {
if frame.is_dragging() {
action = Some(NodeAction::Dragged(resp.drag_delta()));
} else {
action = Some(NodeAction::Resize);
}
}
resp.context_menu(|ui| {
if ui.button("Add selected nodes").clicked() {
action = Some(NodeAction::JoinGroup(self.id));
ui.close_kind(egui::UiKind::Menu);
}
if ui.button("Delete group").clicked() {
action = Some(NodeAction::Delete(false));
ui.close_kind(egui::UiKind::Menu);
}
if ui.button("Delete group and nodes").clicked() {
action = Some(NodeAction::Delete(true));
ui.close_kind(egui::UiKind::Menu);
}
});
action
}
}