diff --git a/Cargo.lock b/Cargo.lock index 61254dc99..524663bd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,13 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "graphite-editor" +version = "0.1.0" +dependencies = [ + "log", +] + [[package]] name = "js-sys" version = "0.3.49" diff --git a/packages/graphite-editor/Cargo.toml b/packages/graphite-editor/Cargo.toml new file mode 100644 index 000000000..2872eeab6 --- /dev/null +++ b/packages/graphite-editor/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "graphite-editor" +version = "0.1.0" +authors = ["Keavon Chambers "] +edition = "2018" + + +[dependencies] +log = "0.4" diff --git a/packages/graphite-editor/src/color.rs b/packages/graphite-editor/src/color.rs new file mode 100644 index 000000000..fdc4b7ade --- /dev/null +++ b/packages/graphite-editor/src/color.rs @@ -0,0 +1,45 @@ +#[repr(C)] +#[derive(Debug, Clone, Copy)] +pub struct Color { + red: f32, + green: f32, + blue: f32, + alpha: f32, +} + +impl Color { + pub fn from_rgbaf32(red: f32, green: f32, blue: f32, alpha: f32) -> Result { + let color = Color { red, green, blue, alpha }; + if [red, green, blue, alpha].iter().any(|c| c.is_sign_negative() || !c.is_finite()) { + return EditorError::Color(color); + } + Ok(color) + } + pub fn from_rgb8(red: u8, green: u8, blue: u8) -> Color { + from_rgba8(red, green, blue, 255) + } + pub fn from_rgba8(red: u8, green: u8, blue: u8, alpha: u8) -> Color { + let map = |int_color| int_color as f32 / 255.0; + Color { + red: map(red), + green: map(green), + blue: map(blue), + alpha: map(alpha), + } + } + pub fn r(&self) -> f32 { + self.red + } + pub fn g(&self) -> f32 { + self.green + } + pub fn b(&self) -> f32 { + self.blue + } + pub fn a(&self) -> f32 { + self.alpha + } + pub fn components(&self) -> (f32, f32, f32, f32) { + (red, green, blue, alpha) + } +} diff --git a/packages/graphite-editor/src/error.rs b/packages/graphite-editor/src/error.rs new file mode 100644 index 000000000..f54a9b328 --- /dev/null +++ b/packages/graphite-editor/src/error.rs @@ -0,0 +1,37 @@ +use crate::Color; +use std::error::Error; +use std::fmt::{self, Display}; + +/// The error type used by the graphite editor. +#[derive(Debug)] +pub enum EditorError { + InvalidOperation(String), + Misc(String), + Color(Color), +} + +impl Display for EngineError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + EngineError::InvalidOperation(e) => write!(f, "Failed to execute operation: {}", e), + EngineError::Misc(e) => write!(f, "{}", e), + EngineError::Color(c) => write!(f, "Tried to construct an invalid color {:?}", c), + } + } +} + +impl Error for EditorError {} + +macro_rules! derive_from { + ($type:ty, $kind:ident) => { + impl From<$type> for EngineError { + fn from(error: $type) -> Self { + EngineError::$kind(format!("{}", error)) + } + } + }; +} + +derive_from!(&str, Misc); +derive_from!(String, Misc); +derive_from!(Color, Color); diff --git a/packages/graphite-editor/src/layout/mod.rs b/packages/graphite-editor/src/layout/mod.rs new file mode 100644 index 000000000..8b77134c1 --- /dev/null +++ b/packages/graphite-editor/src/layout/mod.rs @@ -0,0 +1,34 @@ +use crate::EditorError; +type PanelId = usize; + +struct LayoutRoot { + hovered_panel: PanelId, + root: PanelGroup, +} + +impl LayoutRoot { + // add panel / panel group + // delete panel / panel group + // move panel / panel group + // get_serialized_layout() +} + +struct PanelGroup { + contents: Vec, + layout_direction: LayoutDirection, +} + +enum Contents { + PanelArea(PanelArea), + Group(PanelGroup), +} + +struct PanelArea { + panels: Vec, + active: PanelId, +} + +enum LayoutDirection { + Horizontal, + Vertical, +} diff --git a/packages/graphite-editor/src/lib.rs b/packages/graphite-editor/src/lib.rs new file mode 100644 index 000000000..ffae55aee --- /dev/null +++ b/packages/graphite-editor/src/lib.rs @@ -0,0 +1,18 @@ +mod color; +mod error; +pub mod layout; +mod scheduler; +pub mod tools; + +#[doc(inline)] +pub use error::EditorError; + +#[doc(inline)] +pub use color::Color; + +use tools::ToolState; + +// TODO: serialize with serde to save the current editor state +struct Editor { + tools: ToolState, +} diff --git a/packages/graphite-editor/src/scheduler/mod.rs b/packages/graphite-editor/src/scheduler/mod.rs new file mode 100644 index 000000000..e69de29bb diff --git a/packages/graphite-editor/src/tools/mod.rs b/packages/graphite-editor/src/tools/mod.rs new file mode 100644 index 000000000..6ab0a70e4 --- /dev/null +++ b/packages/graphite-editor/src/tools/mod.rs @@ -0,0 +1,42 @@ +use crate::Color; + +const TOOL_COUNT: usize = 10; + +struct ToolState { + primary_color: Color, + secondary_color: Color, + active_tool: ToolType, + tool_settings: [ToolSettings; TOOL_COUNT], +} + +impl ToolState { + pub fn select_tool(&mut self, tool: ToolType) { + self.active_tool = ToolType + } +} + +#[repr(usize)] +enum ToolType { + Select = 0, + Crop = 1, + Navigate = 2, + Sample = 3, + Path = 4, + Pen = 5, + Line = 6, + Rectangle = 7, + Ellipse = 8, + Shape = 9, + // all discriminats must be strictly smaller than TOOL_COUNT! +} + +enum ToolSettings { + Select { append_mode: SelectAppendMode }, +} + +enum SelectAppendMode { + New, + Add, + Substract, + Intersect, +}