wi-masonry 0.0.0

A vi-style node editor — Masonry widgets
Documentation
use masonry::{
    core::{PointerInfo, PointerState},
    dpi::PhysicalPosition,
};

#[derive(Debug)]
struct Drag<T> {
    pointer: PointerInfo,
    start_pos: PhysicalPosition<f64>,
    start_info: T,
}

#[derive(Debug)]
pub struct DragHandler<T>(Option<Drag<T>>);

impl<T> DragHandler<T> {
    #[inline]
    pub fn new() -> Self { Self(None) }

    pub fn in_drag(&self) -> bool { self.0.is_some() }

    pub fn begin_drag(&mut self, pointer: PointerInfo, state: &PointerState, start_info: T) {
        self.0 = Some(Drag {
            pointer,
            start_pos: state.position,
            start_info,
        });
    }

    pub fn update_drag(
        &mut self,
        pointer: &PointerInfo,
        state: &PointerState,
        update: impl FnOnce(&T, PhysicalPosition<f64>, PhysicalPosition<f64>),
    ) -> bool {
        let Some(drag) = self.0.as_mut() else {
            return false;
        };

        if *pointer != drag.pointer {
            return false;
        }

        update(&drag.start_info, drag.start_pos, state.position);
        true
    }

    pub fn complete_drag(
        &mut self,
        pointer: &PointerInfo,
        state: &PointerState,
        update: impl FnOnce(&T, PhysicalPosition<f64>, PhysicalPosition<f64>),
    ) {
        if self.update_drag(pointer, state, update) {
            self.0 = None;
        }
    }

    pub fn cancel_drag(&mut self, pointer: Option<&PointerInfo>, reset: impl FnOnce(&T)) {
        let Some(drag) = self.0.as_mut() else {
            return;
        };

        if let Some(p) = pointer
            && *p != drag.pointer
        {
            return;
        }

        reset(&drag.start_info);
        self.0 = None;
    }
}