Skip to main content

jellyflow_core/interaction/
mod.rs

1//! Editor interaction configuration types.
2//!
3//! These types are shared across:
4//! - persisted view state (`crate::io`),
5//! - the UI substrate (`crate::ui`),
6//! - headless rules/policies (`crate::rules`, `crate::profile`).
7
8use serde::{Deserialize, Serialize};
9
10/// Connection mode for selecting/validating target ports during connection gestures.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
12#[serde(rename_all = "snake_case")]
13#[derive(Default)]
14pub enum NodeGraphConnectionMode {
15    #[default]
16    Strict,
17    Loose,
18}
19
20/// Where node dragging can start from.
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
22#[serde(rename_all = "snake_case")]
23#[derive(Default)]
24pub enum NodeGraphDragHandleMode {
25    /// Start dragging from anywhere inside the node bounds.
26    #[default]
27    Any,
28    /// Start dragging only from the node header region.
29    Header,
30}
31
32/// Modifier requirement for interaction activation (XyFlow mental model).
33///
34/// This is used for zoom activation (`zoomActivationKey`), selection activation (`selectionKeyCode`),
35/// and multi-selection (`multiSelectionKeyCode`).
36#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
37#[serde(rename_all = "snake_case")]
38#[derive(Default)]
39pub enum NodeGraphModifierKey {
40    /// Wheel zoom is always active (no activation modifier required).
41    None,
42    /// Wheel zoom is active only while Ctrl or Meta is held (recommended default).
43    #[default]
44    CtrlOrMeta,
45    /// Wheel zoom is active only while Shift is held.
46    Shift,
47    /// Wheel zoom is active only while Alt is held.
48    Alt,
49}
50
51/// Keyboard modifier state used by headless interaction policies.
52#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
53pub struct NodeGraphModifiers {
54    pub shift: bool,
55    pub ctrl: bool,
56    pub alt: bool,
57    pub alt_gr: bool,
58    pub meta: bool,
59}
60
61impl NodeGraphModifierKey {
62    pub fn is_pressed(self, modifiers: NodeGraphModifiers) -> bool {
63        match self {
64            Self::None => true,
65            Self::CtrlOrMeta => modifiers.ctrl || modifiers.meta,
66            Self::Shift => modifiers.shift,
67            Self::Alt => modifiers.alt || modifiers.alt_gr,
68        }
69    }
70}