use serde::{Deserialize, Serialize};
use winit::keyboard::KeyCode;
use crate::geometry::Geometry;
use crate::objects::Object;
use crate::text_label::TextLabel;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct InspectorData {
pub id: usize,
pub name: String,
pub str_id: String,
pub position: [f32; 3],
pub rotation_deg: [f32; 3],
pub scale: [f32; 3],
pub color: [f32; 4],
pub geometry_type: Option<String>,
pub texture_path: Option<String>,
}
impl InspectorData {
pub fn from_object(id: usize, obj: &Object) -> Self {
Self {
id,
name: obj.name.clone(),
str_id: obj.str_id.clone(),
position: obj.transform.position,
rotation_deg: obj.transform.rotation,
scale: obj.transform.scale,
color: obj.color,
geometry_type: obj.geometry.as_ref().map(geometry_type_name),
texture_path: obj.texture_path.clone(),
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct LabelInspectorData {
pub id: usize,
pub text: String,
pub x: f32,
pub y: f32,
pub font_size: f32,
pub color: [f32; 4],
pub font_id: String,
pub zindex: i32,
}
impl LabelInspectorData {
pub fn from_label(label: &TextLabel) -> Self {
Self {
id: label.id,
text: label.text.clone(),
x: label.x,
y: label.y,
font_size: label.font_size,
color: label.color,
font_id: label.font_id.clone(),
zindex: label.zindex,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum LabelDragKind {
Move,
Resize,
}
#[derive(Debug, Clone)]
pub struct LabelDragState {
pub label_id: usize,
pub kind: LabelDragKind,
pub start_cursor: [f32; 2],
pub start_pos: [f32; 2],
pub start_size: f32,
}
fn geometry_type_name(g: &Geometry) -> String {
match g {
Geometry::Cube { .. } => "Cube",
Geometry::Box { .. } => "Box",
Geometry::Plane { .. } => "Plane",
Geometry::Pyramid { .. } => "Pyramid",
Geometry::Capsule { .. } => "Capsule",
Geometry::Sphere { .. } => "Sphere",
}.to_string()
}
#[derive(Debug, Clone, Default)]
pub struct Inspector {
pub selected: Option<InspectorData>,
}
impl Inspector {
pub fn clear(&mut self) { self.selected = None; }
pub fn has_selection(&self) -> bool { self.selected.is_some() }
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DragAxis { X, Y, Z }
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub enum GizmoMode {
#[default]
Translate,
Rotate,
Scale,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum DragKind { Translate, Rotate, Scale }
#[derive(Debug, Clone)]
pub struct DragState {
pub object_id: usize,
pub axis: DragAxis,
pub center: [f32; 3],
pub kind: DragKind,
}
#[derive(Debug, Clone)]
pub enum EditorEvent {
MouseMotionDelta { dx: f32, dy: f32 },
CursorMoved { x: f32, y: f32 },
MouseButton { left: Option<bool>, middle: Option<bool>, right: Option<bool> },
Scroll { delta: f32 },
ModifiersChanged { alt: bool, ctrl: bool },
FocusKey,
KeyPressed(KeyCode),
KeyReleased(KeyCode),
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq)]
pub enum EditorStateEvent {
GizmoModeChanged(GizmoMode),
DragStart {
axis: DragAxis,
},
DragEnd,
SelectionChanged,
LabelSelectionChanged(Option<LabelInspectorData>),
LabelDragStart {
kind: LabelDragKind,
},
LabelDragEnd(LabelInspectorData),
}
#[derive(Debug, Default)]
pub struct EditorInput {
pub left_down: bool,
pub middle_down: bool,
pub right_down: bool,
pub alt_held: bool,
pub ctrl_held: bool,
pub cursor_x: f32,
pub cursor_y: f32,
}