pub mod assets;
pub mod color;
pub mod context_menu;
pub mod fill;
pub mod inspect;
pub mod layers;
pub mod machine;
pub mod modifiers;
pub mod path;
pub mod stroke;
use glam::DVec2;
use renamite_animation::Frame;
use renamite_model::{CompId, Document, NodeId};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
pub struct Selection {
pub nodes: Vec<NodeId>,
pub comp: Option<CompId>,
}
impl Selection {
pub fn is_empty(&self) -> bool {
self.nodes.is_empty()
}
pub fn contains(&self, id: NodeId) -> bool {
self.nodes.contains(&id)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
pub struct ViewTransform {
pub scale: f64,
pub offset: DVec2,
}
impl ViewTransform {
pub fn identity() -> Self {
Self {
scale: 1.0,
offset: DVec2::ZERO,
}
}
pub fn screen_to_world(&self, p: DVec2) -> DVec2 {
(p - self.offset) / self.scale
}
pub fn world_to_screen(&self, p: DVec2) -> DVec2 {
p * self.scale + self.offset
}
pub fn world_tolerance(&self, px: f64) -> f64 {
px / self.scale
}
pub fn zoom_at(&mut self, screen_pos: DVec2, factor: f64, min: f64, max: f64) {
let world = self.screen_to_world(screen_pos);
self.scale = (self.scale * factor).clamp(min, max);
self.offset = screen_pos - world * self.scale;
}
pub fn pan_by(&mut self, delta: DVec2) {
self.offset += delta;
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Modifiers {
pub shift: bool,
pub alt: bool,
pub ctrl: bool,
}
impl Modifiers {
pub fn none() -> Self {
Self {
shift: false,
alt: false,
ctrl: false,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
pub struct SnapConfig {
pub grid: Option<f64>,
pub anchor: bool,
pub guide: bool,
}
pub struct ToolContext<'a> {
pub doc: &'a Document,
pub scene: &'a renamite_model::Scene,
pub comp: CompId,
pub selection: &'a Selection,
pub playhead: Frame,
pub record: bool,
pub view: ViewTransform,
pub snap: SnapConfig,
pub modifiers: Modifiers,
pub current_paint: &'a renamite_model::StylePaint,
}