use crate::interaction::gizmo::GizmoAxis;
use crate::interaction::input::ActionFrame;
use super::types::{ManipulationKind, ManipulationState};
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub(super) struct NumericInputState {
pub(super) active_axes: Vec<usize>,
pub(super) current_axis_idx: usize,
pub(super) axis_inputs: [String; 3],
}
#[allow(dead_code)]
impl NumericInputState {
pub(super) fn new(axis: Option<GizmoAxis>, excluded: bool) -> Self {
let active_axes = match axis {
None => vec![0, 1, 2],
Some(GizmoAxis::X) => {
if excluded { vec![1, 2] } else { vec![0] }
}
Some(GizmoAxis::Y) => {
if excluded { vec![0, 2] } else { vec![1] }
}
Some(GizmoAxis::Z) | Some(GizmoAxis::None) => {
if excluded { vec![0, 1] } else { vec![2] }
}
_ => vec![0, 1, 2],
};
Self {
active_axes,
current_axis_idx: 0,
axis_inputs: [String::new(), String::new(), String::new()],
}
}
pub(super) fn current_axis(&self) -> usize {
self.active_axes[self.current_axis_idx]
}
pub(super) fn parsed_values(&self) -> [Option<f32>; 3] {
core::array::from_fn(|i| self.axis_inputs[i].parse::<f32>().ok())
}
pub(super) fn display_string(&self) -> String {
let labels = ["X", "Y", "Z"];
let mut parts = Vec::new();
for (i, label) in labels.iter().enumerate() {
if self.active_axes.contains(&i) {
let val = if self.axis_inputs[i].is_empty() {
"_".to_string()
} else {
self.axis_inputs[i].clone()
};
parts.push(format!("{label}: {val}"));
}
}
parts.join(" ")
}
}
#[derive(Debug, Clone)]
pub(super) struct ManipulationSession {
pub(super) kind: ManipulationKind,
pub(super) axis: Option<GizmoAxis>,
pub(super) exclude_axis: bool,
pub(super) numeric: Option<NumericInputState>,
pub(super) is_gizmo_drag: bool,
pub(super) gizmo_center: glam::Vec3,
pub(super) cursor_anchor: Option<glam::Vec2>,
pub(super) cursor_last_total: glam::Vec2,
pub(super) last_scale_factor: f32,
}
impl ManipulationSession {
pub(super) fn to_state(&self) -> ManipulationState {
let numeric_display = self
.numeric
.as_ref()
.map(|n| n.display_string())
.filter(|s| !s.is_empty());
ManipulationState {
kind: self.kind,
axis: self.axis,
exclude_axis: self.exclude_axis,
is_gizmo_drag: self.is_gizmo_drag,
center: self.gizmo_center,
numeric_display,
}
}
}
pub(super) fn update_constraint(
session: &mut ManipulationSession,
constrain_x: bool,
constrain_y: bool,
constrain_z: bool,
exclude_x: bool,
exclude_y: bool,
exclude_z: bool,
) {
let mut set_axis = |axis: GizmoAxis, exclude: bool| {
session.axis = Some(axis);
session.exclude_axis = exclude;
session.numeric = None;
};
if constrain_x { set_axis(GizmoAxis::X, false); }
if constrain_y { set_axis(GizmoAxis::Y, false); }
if constrain_z { set_axis(GizmoAxis::Z, false); }
if exclude_x { set_axis(GizmoAxis::X, true); }
if exclude_y { set_axis(GizmoAxis::Y, true); }
if exclude_z { set_axis(GizmoAxis::Z, true); }
}
#[allow(unused_variables)]
pub(super) fn update_numeric_state(session: &mut ManipulationSession, frame: &ActionFrame) {
}