use serde::{Deserialize, Serialize};
mod connection;
mod graph;
mod layout_facts;
mod node;
mod rendering;
mod selection;
mod viewport;
pub use connection::ConformanceConnectionTargetFromHandlesInput;
pub use layout_facts::{
ConformanceEdgeEndpointPosition, ConformanceLayoutEdgePosition,
ConformanceLayoutFactsConnectionTargetExpectation, ConformanceLayoutFactsExpectation,
};
use crate::io::NodeGraphKeyCode;
use crate::runtime::auto_pan::{AutoPanRequest, SelectionAutoPanRequest};
use crate::runtime::connection::{
ConnectEdgeRequest, ConnectionTargetInput, ReconnectEdgeRequest, ResolvedConnectionTarget,
};
use crate::runtime::drag::{NodeNudgeRequest, PointerGestureClaim};
use crate::runtime::events::{ConnectStart, NodeGraphGestureEvent};
use crate::runtime::measurement::NodeMeasurement;
use crate::runtime::rendering::RenderingQueryResult;
use crate::runtime::resize::{NodePointerResizeRequest, NodeResizeRequest};
use crate::runtime::selection::NodePointerDownInput;
use crate::runtime::selection::SelectionBoxInput;
use crate::runtime::viewport::{
ViewportAnimationFrame, ViewportAnimationPlan, ViewportAnimationRequest,
ViewportDoubleClickZoomInput, ViewportDragPanInput, ViewportGestureContext,
ViewportGestureRejection, ViewportPanInertiaFrame, ViewportPanInertiaRequest,
ViewportPanRequest, ViewportScrollInput, ViewportZoomRequest,
};
use jellyflow_core::core::{CanvasPoint, CanvasSize, EdgeId, GroupId, NodeId};
use jellyflow_core::ops::GraphTransaction;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "kind", content = "data", rename_all = "snake_case")]
pub enum ConformanceAction {
DispatchTransaction {
transaction: GraphTransaction,
},
ApplyNodeDrag {
node: NodeId,
to: CanvasPoint,
},
ApplyNodeDragSession {
node: NodeId,
start: CanvasPoint,
to: CanvasPoint,
},
AssertNodePosition {
node: NodeId,
expected: CanvasPoint,
},
ApplyNodeResize {
request: NodeResizeRequest,
},
ApplyNodePointerResize {
request: NodePointerResizeRequest,
},
ApplyNodePointerResizeSession {
request: NodePointerResizeRequest,
},
ApplyNodePointerDown {
input: NodePointerDownInput,
#[serde(default, skip_serializing_if = "Option::is_none")]
expected_claim: Option<PointerGestureClaim>,
},
ApplySelectionBox {
input: SelectionBoxInput,
},
AssertConnectionTarget {
input: ConnectionTargetInput,
expected: ResolvedConnectionTarget,
},
AssertConnectionTargetFromHandles {
input: ConformanceConnectionTargetFromHandlesInput,
expected: ResolvedConnectionTarget,
},
ApplyConnectEdge {
request: ConnectEdgeRequest,
},
ApplyConnectEdgeSession {
start: ConnectStart,
request: ConnectEdgeRequest,
},
ApplyReconnectEdge {
request: ReconnectEdgeRequest,
},
ApplyNodeNudge {
request: NodeNudgeRequest,
},
ApplyDeleteSelection,
ApplyDeleteSelectionForKey {
key: NodeGraphKeyCode,
},
ApplyAutoPan {
request: AutoPanRequest,
},
ApplySelectionAutoPan {
request: SelectionAutoPanRequest,
},
ReportNodeMeasurement {
measurement: NodeMeasurement,
},
AssertLayoutFacts {
viewport_size: CanvasSize,
expected: ConformanceLayoutFactsExpectation,
},
ApplyViewportPan {
request: ViewportPanRequest,
},
ApplyViewportPanConstrained {
request: ViewportPanRequest,
viewport_size: CanvasSize,
},
ApplyViewportZoom {
request: ViewportZoomRequest,
},
ApplyViewportZoomConstrained {
request: ViewportZoomRequest,
viewport_size: CanvasSize,
},
ApplyViewportAnimationFrame {
request: ViewportAnimationRequest,
elapsed_seconds: f32,
},
ApplyViewportAnimationFrames {
request: ViewportAnimationRequest,
elapsed_seconds: Vec<f32>,
},
AssertViewportAnimationFrame {
request: ViewportAnimationRequest,
elapsed_seconds: f32,
expected: ViewportAnimationFrame,
},
ApplyViewportPanInertiaFrame {
request: ViewportPanInertiaRequest,
elapsed_seconds: f32,
},
ApplyViewportPanInertiaFrames {
request: ViewportPanInertiaRequest,
elapsed_seconds: Vec<f32>,
},
AssertViewportPanInertiaFrame {
request: ViewportPanInertiaRequest,
elapsed_seconds: f32,
expected: ViewportPanInertiaFrame,
},
ExpectViewportPanInertiaRejected {
request: ViewportPanInertiaRequest,
},
AssertViewportDoubleClickZoom {
input: ViewportDoubleClickZoomInput,
#[serde(default, skip_serializing_if = "Option::is_none")]
expected: Option<ViewportAnimationPlan>,
#[serde(default, skip_serializing_if = "Option::is_none")]
expect_rejection: Option<ViewportGestureRejection>,
},
ApplyViewportScrollGesture {
context: ViewportGestureContext,
input: ViewportScrollInput,
#[serde(default, skip_serializing_if = "Option::is_none")]
expect_rejection: Option<ViewportGestureRejection>,
},
ApplyViewportDragPanGesture {
context: ViewportGestureContext,
input: ViewportDragPanInput,
#[serde(default, skip_serializing_if = "Option::is_none")]
expect_rejection: Option<ViewportGestureRejection>,
},
ApplyViewportDragPanSession {
context: ViewportGestureContext,
input: ViewportDragPanInput,
#[serde(default, skip_serializing_if = "Option::is_none")]
expect_rejection: Option<ViewportGestureRejection>,
},
SetViewport {
pan: CanvasPoint,
zoom: f32,
},
AssertRenderingQuery {
viewport_size: CanvasSize,
expected: RenderingQueryResult,
},
SetSelection {
nodes: Vec<NodeId>,
edges: Vec<EdgeId>,
groups: Vec<GroupId>,
},
EmitGesture {
event: NodeGraphGestureEvent,
},
}
impl ConformanceAction {
pub fn kind(&self) -> &'static str {
graph::kind(self)
.or_else(|| node::kind(self))
.or_else(|| selection::kind(self))
.or_else(|| connection::kind(self))
.or_else(|| layout_facts::kind(self))
.or_else(|| viewport::kind(self))
.or_else(|| rendering::kind(self))
.expect("all conformance action variants must have a kind")
}
}