use crate::{
AttributeId, EditorContext, Hoverable, InputPinId, Link, LinkId, MiniMapLocation, NodeId,
OutputPinId, PinId, PinShape, sys,
};
#[derive(Debug)]
pub struct OuterScope {}
impl OuterScope {
#[doc(
alias = "IsPinHovered",
alias = "IsNodeHovered",
alias = "IsLinkHovered"
)]
#[must_use]
pub fn is_hovered(&self, id: impl Hoverable) -> bool {
id.is_hovered(self)
}
#[doc(alias = "IsLinkStarted")]
#[must_use]
pub fn link_started_at<T: Into<PinId>>(&self, id: T) -> bool {
let id: PinId = id.into();
id.is_start_of_link(self)
}
#[doc(alias = "IsLinkDropped")]
#[must_use]
pub fn link_dropped_from<T: Into<PinId>>(&self, id: T, including_detached_links: bool) -> bool {
let id: PinId = id.into();
id.dropped_link(including_detached_links, self)
}
#[doc(alias = "NumSelectedNodes")]
#[must_use]
pub fn num_selected_nodes(&self) -> u32 {
let num = unsafe { sys::imnodes_NumSelectedNodes() };
num.max(0) as u32
}
#[doc(alias = "NumSelectedLinks")]
#[must_use]
pub fn num_selected_links(&self) -> u32 {
let num = unsafe { sys::imnodes_NumSelectedLinks() };
num.max(0) as u32
}
#[doc(alias = "GetSelectedNodes")]
#[must_use]
pub fn selected_nodes(&self) -> Vec<NodeId> {
let nr_nodes = self.num_selected_nodes();
if nr_nodes == 0 {
return Vec::new();
}
let mut nodes: Vec<NodeId> = Vec::with_capacity(nr_nodes as usize);
unsafe {
sys::imnodes_GetSelectedNodes(nodes.as_mut_ptr().cast::<i32>());
nodes.set_len(nr_nodes as usize);
}
nodes
}
#[doc(alias = "GetSelectedLinks")]
#[must_use]
pub fn selected_links(&self) -> Vec<LinkId> {
let nr_links = self.num_selected_links();
if nr_links == 0 {
return Vec::new();
}
let mut links: Vec<LinkId> = Vec::with_capacity(nr_links as usize);
unsafe {
sys::imnodes_GetSelectedLinks(links.as_mut_ptr().cast::<i32>());
links.set_len(nr_links as usize);
}
links
}
#[doc(alias = "IsLinkCreated", alias = "IsLinkCreated_IntPtr")]
#[must_use]
pub fn links_created(&self) -> Option<Link> {
let mut start_node_id: i32 = -1;
let mut start_pin_id: i32 = -1;
let mut end_node_id: i32 = -1;
let mut end_pin_id: i32 = -1;
let mut created_from_snap: bool = false;
let is_created = unsafe {
sys::imnodes_IsLinkCreated_IntPtr(
core::ptr::from_mut(&mut start_node_id),
core::ptr::from_mut(&mut start_pin_id),
core::ptr::from_mut(&mut end_node_id),
core::ptr::from_mut(&mut end_pin_id),
core::ptr::from_mut::<bool>(&mut created_from_snap).cast(),
)
};
if is_created
&& start_pin_id >= 0
&& end_pin_id >= 0
&& start_node_id >= 0
&& end_node_id >= 0
{
Some(Link {
start_node: NodeId { id: start_node_id },
end_node: NodeId { id: end_node_id },
start_pin: OutputPinId { id: start_pin_id },
end_pin: InputPinId { id: end_pin_id },
created_from_snap,
})
} else {
None
}
}
#[doc(alias = "IsLinkDestroyed")]
#[must_use]
pub fn get_destroyed_link(&self) -> Option<LinkId> {
let mut id: i32 = -1;
if unsafe { sys::imnodes_IsLinkDestroyed(core::ptr::from_mut(&mut id)) } && id >= 0 {
Some(LinkId { id })
} else {
None
}
}
#[doc(alias = "IsPinHovered")]
#[must_use]
pub fn get_hovered_pin(&self) -> Option<PinId> {
let mut id: i32 = -1;
let ok = unsafe { sys::imnodes_IsPinHovered(core::ptr::from_mut(&mut id)) };
if ok && id >= 0 {
Some(PinId { id })
} else {
None
}
}
#[doc(alias = "IsLinkHovered")]
#[must_use]
pub fn get_hovered_link(&self) -> Option<LinkId> {
let mut id: i32 = -1;
let ok = unsafe { sys::imnodes_IsLinkHovered(core::ptr::from_mut(&mut id)) };
if ok && id >= 0 {
Some(LinkId { id })
} else {
None
}
}
#[doc(alias = "IsAnyAttributeActive")]
#[must_use]
pub fn get_active_attribute(&self) -> Option<AttributeId> {
let mut id: i32 = -1;
let ok = unsafe { sys::imnodes_IsAnyAttributeActive(core::ptr::from_mut(&mut id)) };
if ok && id >= 0 {
Some(AttributeId { id })
} else {
None
}
}
#[doc(alias = "IsLinkStarted")]
#[must_use]
pub fn from_where_link_started(&self) -> Option<PinId> {
let mut id: i32 = -1;
let ok = unsafe { sys::imnodes_IsLinkStarted(core::ptr::from_mut(&mut id)) };
if ok && id >= 0 {
Some(PinId { id })
} else {
None
}
}
#[doc(alias = "IsLinkDropped")]
#[must_use]
pub fn from_where_link_dropped(&self, including_detached_links: bool) -> Option<PinId> {
let mut id: i32 = -1;
let ok = unsafe {
sys::imnodes_IsLinkDropped(core::ptr::from_mut(&mut id), including_detached_links)
};
if ok && id >= 0 {
Some(PinId { id })
} else {
None
}
}
}
#[doc(alias = "BeginNodeEditor", alias = "EndNodeEditor")]
pub fn editor<F: FnOnce(EditorScope)>(context: &mut EditorContext, f: F) -> OuterScope {
let _ = context.set_as_current_editor();
unsafe { sys::imnodes_BeginNodeEditor() };
f(EditorScope {});
unsafe { sys::imnodes_EndNodeEditor() };
OuterScope {}
}
#[derive(Debug)]
pub struct EditorScope {}
impl EditorScope {
#[doc(alias = "MiniMap")]
pub fn add_mini_map(&mut self, size_fraction: f32, location: MiniMapLocation) {
let node_hovering_callback = None;
let node_hovering_callback_data = core::ptr::null_mut::<core::ffi::c_void>();
unsafe {
sys::imnodes_MiniMap(
size_fraction,
location as i32,
node_hovering_callback,
node_hovering_callback_data,
);
}
}
#[doc(alias = "BeginNode", alias = "EndNode")]
pub fn add_node<F: FnOnce(NodeScope)>(&mut self, id: NodeId, f: F) {
unsafe { sys::imnodes_BeginNode(id.into()) }
f(NodeScope {});
unsafe {
sys::imnodes_EndNode();
}
}
#[doc(alias = "Link")]
pub fn add_link(&mut self, id: LinkId, input_pin_id: InputPinId, output_pin_id: OutputPinId) {
unsafe { sys::imnodes_Link(id.into(), output_pin_id.into(), input_pin_id.into()) }
}
#[doc(alias = "IsAnyAttributeActive")]
#[must_use]
pub fn get_active_attribute(&self) -> Option<AttributeId> {
let mut id: i32 = -1;
let ok = unsafe { sys::imnodes_IsAnyAttributeActive(core::ptr::from_mut(&mut id)) };
if ok && id >= 0 {
Some(AttributeId { id })
} else {
None
}
}
#[doc(alias = "IsEditorHovered")]
#[must_use]
pub fn is_hovered(&self) -> bool {
unsafe { sys::imnodes_IsEditorHovered() }
}
}
#[derive(Debug)]
pub struct NodeScope {}
impl NodeScope {
#[doc(alias = "BeginNodeTitleBar", alias = "EndNodeTitleBar")]
pub fn add_titlebar<F: FnOnce()>(&mut self, f: F) {
unsafe { sys::imnodes_BeginNodeTitleBar() }
f();
unsafe { sys::imnodes_EndNodeTitleBar() }
}
#[doc(alias = "BeginInputAttribute", alias = "EndInputAttribute")]
pub fn add_input<F: FnOnce()>(&mut self, id: InputPinId, shape: PinShape, f: F) {
unsafe { sys::imnodes_BeginInputAttribute(id.into(), shape as i32) };
f();
unsafe { sys::imnodes_EndInputAttribute() };
}
#[doc(alias = "BeginOutputAttribute", alias = "EndOutputAttribute")]
pub fn add_output<F: FnOnce()>(&mut self, id: OutputPinId, shape: PinShape, f: F) {
unsafe { sys::imnodes_BeginOutputAttribute(id.into(), shape as i32) };
f();
unsafe { sys::imnodes_EndOutputAttribute() };
}
#[doc(alias = "BeginStaticAttribute", alias = "EndStaticAttribute")]
pub fn add_static_attribute<F: FnOnce()>(&mut self, id: AttributeId, f: F) {
unsafe { sys::imnodes_BeginStaticAttribute(id.into()) };
f();
unsafe { sys::imnodes_EndStaticAttribute() };
}
}