use crate::traits::DropPosition;
use std::hash::Hash;
use std::ops::Deref;
#[derive(Debug)]
pub struct OutlinerResponse<Id>
where
Id: Hash + Eq + Clone,
{
pub inner: egui::Response,
pub changed: bool,
pub selected: Option<Id>,
pub double_clicked: Option<Id>,
pub context_menu: Option<Id>,
pub renamed: Option<(Id, String)>,
pub drag_started: Option<Id>,
pub dragging_nodes: Vec<Id>,
pub drop_event: Option<DropEvent<Id>>,
}
impl<Id> OutlinerResponse<Id>
where
Id: Hash + Eq + Clone,
{
pub fn new(inner: egui::Response) -> Self {
Self {
inner,
changed: false,
selected: None,
double_clicked: None,
context_menu: None,
renamed: None,
drag_started: None,
dragging_nodes: Vec::new(),
drop_event: None,
}
}
#[inline]
pub fn changed(&self) -> bool {
self.changed
}
#[inline]
pub fn selected(&self) -> Option<&Id> {
self.selected.as_ref()
}
#[inline]
pub fn double_clicked(&self) -> Option<&Id> {
self.double_clicked.as_ref()
}
#[inline]
pub fn context_menu(&self) -> Option<&Id> {
self.context_menu.as_ref()
}
#[inline]
pub fn renamed(&self) -> Option<(&Id, &str)> {
self.renamed.as_ref().map(|(id, name)| (id, name.as_str()))
}
#[inline]
pub fn drag_started(&self) -> Option<&Id> {
self.drag_started.as_ref()
}
#[inline]
pub fn dragging_nodes(&self) -> &[Id] {
&self.dragging_nodes
}
#[inline]
pub fn drop_event(&self) -> Option<&DropEvent<Id>> {
self.drop_event.as_ref()
}
}
impl<Id> Deref for OutlinerResponse<Id>
where
Id: Hash + Eq + Clone,
{
type Target = egui::Response;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DropEvent<Id>
where
Id: Hash + Eq + Clone,
{
pub source: Id,
pub target: Id,
pub position: DropPosition,
}
impl<Id> DropEvent<Id>
where
Id: Hash + Eq + Clone,
{
pub fn new(source: Id, target: Id, position: DropPosition) -> Self {
Self {
source,
target,
position,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::traits::DropPosition;
#[test]
fn test_drop_event_new() {
let event = DropEvent::new(10, 20, DropPosition::Before);
assert_eq!(event.source, 10);
assert_eq!(event.target, 20);
assert_eq!(event.position, DropPosition::Before);
}
#[test]
fn test_drop_event_positions() {
let event_before = DropEvent::new(1, 2, DropPosition::Before);
let event_after = DropEvent::new(1, 2, DropPosition::After);
let event_inside = DropEvent::new(1, 2, DropPosition::Inside);
assert_eq!(event_before.position, DropPosition::Before);
assert_eq!(event_after.position, DropPosition::After);
assert_eq!(event_inside.position, DropPosition::Inside);
}
#[test]
fn test_drop_event_equality() {
let event1 = DropEvent::new(1, 2, DropPosition::Inside);
let event2 = DropEvent::new(1, 2, DropPosition::Inside);
let event3 = DropEvent::new(1, 2, DropPosition::Before);
let event4 = DropEvent::new(2, 3, DropPosition::Inside);
assert_eq!(event1, event2);
assert_ne!(event1, event3);
assert_ne!(event1, event4);
}
#[test]
fn test_drop_event_clone() {
let event = DropEvent::new(5, 10, DropPosition::After);
let cloned = event.clone();
assert_eq!(event, cloned);
assert_eq!(cloned.source, 5);
assert_eq!(cloned.target, 10);
assert_eq!(cloned.position, DropPosition::After);
}
#[test]
fn test_drop_event_with_different_id_types() {
let event_u64 = DropEvent::new(1u64, 2u64, DropPosition::Inside);
assert_eq!(event_u64.source, 1u64);
let event_string = DropEvent::new("node1".to_string(), "node2".to_string(), DropPosition::Before);
assert_eq!(event_string.source, "node1".to_string());
assert_eq!(event_string.target, "node2".to_string());
}
}