From 04dc05e5750272cf4a8053971c66ea37931b01a4 Mon Sep 17 00:00:00 2001 From: TrueDoctor Date: Sat, 27 Mar 2021 22:02:01 +0100 Subject: [PATCH] Rework the ToolState and integrate it into the Editor struct (#48) * Rework the ToolState and integrate it into the Editor struct * Add asset manager sources to docs outline --- client/web/wasm/src/lib.rs | 5 +++ client/web/wasm/src/viewport.rs | 25 ++++++----- core/editor/src/lib.rs | 11 ++++- core/editor/src/tools/mod.rs | 77 ++++++++++++++++++++------------ core/editor/src/workspace/mod.rs | 15 +++++++ 5 files changed, 91 insertions(+), 42 deletions(-) diff --git a/client/web/wasm/src/lib.rs b/client/web/wasm/src/lib.rs index dcdbcbc4e..e12e68caf 100644 --- a/client/web/wasm/src/lib.rs +++ b/client/web/wasm/src/lib.rs @@ -4,8 +4,13 @@ pub mod viewport; pub mod window; pub mod wrappers; +use graphite_editor_core::Editor; +use std::cell::RefCell; use wasm_bindgen::prelude::*; +// the thread_local macro provides a way to initialize static variables with non-constant functions +thread_local! {pub static EDITOR_STATE: RefCell = RefCell::new(Editor::new())} + #[wasm_bindgen(start)] pub fn init() { utils::set_panic_hook(); diff --git a/client/web/wasm/src/viewport.rs b/client/web/wasm/src/viewport.rs index 67a92f730..61f55d2df 100644 --- a/client/web/wasm/src/viewport.rs +++ b/client/web/wasm/src/viewport.rs @@ -1,19 +1,18 @@ use crate::shims::Error; use crate::wrappers::{translate_tool, Color}; -use graphite_editor_core::tools::ToolState; +use crate::EDITOR_STATE; use wasm_bindgen::prelude::*; -pub static mut TOOL_STATE: ToolState = ToolState::default(); - /// Modify the currently selected tool in the document state store #[wasm_bindgen] pub fn select_tool(tool: String) -> Result<(), JsValue> { - let tool_state = unsafe { &mut TOOL_STATE }; - if let Some(tool) = translate_tool(&tool) { - Ok(tool_state.select_tool(tool)) - } else { - Err(Error::new(&format!("Couldn't select {} because it was not recognized as a valid tool", tool)).into()) - } + EDITOR_STATE.with(|editor| match translate_tool(&tool) { + Some(tool) => { + editor.borrow_mut().tools.active_tool = tool; + Ok(()) + } + None => Err(Error::new(&format!("Couldn't select {} because it was not recognized as a valid tool", tool)).into()), + }) } /// Mouse movement with the bounds of the canvas @@ -25,7 +24,9 @@ pub fn on_mouse_move(x: u32, y: u32) { /// Update working colors #[wasm_bindgen] pub fn update_colors(primary_color: Color, secondary_color: Color) { - let tool_state = unsafe { &mut TOOL_STATE }; - tool_state.set_primary_color(primary_color.inner()); - tool_state.set_secondary_color(secondary_color.inner()); + EDITOR_STATE.with(|editor| { + let mut editor = editor.borrow_mut(); + editor.tools.primary_color = primary_color.inner(); + editor.tools.secondary_color = secondary_color.inner(); + }) } diff --git a/core/editor/src/lib.rs b/core/editor/src/lib.rs index 9285d8836..6c5412c42 100644 --- a/core/editor/src/lib.rs +++ b/core/editor/src/lib.rs @@ -15,6 +15,15 @@ use workspace::Workspace; // TODO: serialize with serde to save the current editor state pub struct Editor { - tools: ToolState, + pub tools: ToolState, workspace: Workspace, } + +impl Editor { + pub fn new() -> Self { + Self { + tools: ToolState::new(), + workspace: Workspace::new(), + } + } +} diff --git a/core/editor/src/tools/mod.rs b/core/editor/src/tools/mod.rs index 04af5eba9..c0cfafe09 100644 --- a/core/editor/src/tools/mod.rs +++ b/core/editor/src/tools/mod.rs @@ -1,54 +1,67 @@ use crate::Color; - -const TOOL_COUNT: usize = 10; +use std::collections::HashMap; pub struct ToolState { - primary_color: Color, - secondary_color: Color, - active_tool: ToolType, - tool_settings: [ToolSettings; TOOL_COUNT], + pub primary_color: Color, + pub secondary_color: Color, + pub active_tool: ToolType, + tool_settings: HashMap, } impl ToolState { - pub const fn default() -> ToolState { + pub fn new() -> Self { ToolState { primary_color: Color::BLACK, secondary_color: Color::WHITE, active_tool: ToolType::Select, - tool_settings: [ToolSettings::Select { append_mode: SelectAppendMode::New }; TOOL_COUNT], - // TODO: Initialize to sensible values + tool_settings: default_tool_settings(), } } - pub fn select_tool(&mut self, tool: ToolType) { - self.active_tool = tool - } - pub fn set_primary_color>(&mut self, primary_color: T) { - self.primary_color = primary_color.into(); - } - pub fn set_secondary_color>(&mut self, secondary_color: T) { - self.secondary_color = secondary_color.into(); - } +} + +fn default_tool_settings() -> HashMap { + let tool_init = |tool: &ToolType| (*tool, tool.default_settings()); + [ + tool_init(&ToolType::Select), + tool_init(&ToolType::Shape), // TODO: Add more tool defaults + ] + .iter() + .cloned() + .collect() } #[repr(usize)] -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ToolType { - Select = 0, - Crop = 1, - Navigate = 2, - Sample = 3, - Path = 4, - Pen = 5, - Line = 6, - Rectangle = 7, - Ellipse = 8, - Shape = 9, + Select, + Crop, + Navigate, + Sample, + Path, + Pen, + Line, + Rectangle, + Ellipse, + Shape, // all discriminats must be strictly smaller than TOOL_COUNT! } +impl ToolType { + fn default_settings(&self) -> ToolSettings { + match self { + ToolType::Select => ToolSettings::Select { append_mode: SelectAppendMode::New }, + ToolType::Shape => ToolSettings::Shape { + shape: Shape::Polygon { vertices: 3 }, + }, + _ => todo!(), + } + } +} + #[derive(Debug, Clone, Copy)] pub enum ToolSettings { Select { append_mode: SelectAppendMode }, + Shape { shape: Shape }, } #[derive(Debug, Clone, Copy)] @@ -58,3 +71,9 @@ pub enum SelectAppendMode { Subtract, Intersect, } + +#[derive(Debug, Clone, Copy)] +pub enum Shape { + Star { vertices: u32 }, + Polygon { vertices: u32 }, +} diff --git a/core/editor/src/workspace/mod.rs b/core/editor/src/workspace/mod.rs index 37e265627..7e3cd1109 100644 --- a/core/editor/src/workspace/mod.rs +++ b/core/editor/src/workspace/mod.rs @@ -7,6 +7,12 @@ pub struct Workspace { } impl Workspace { + pub fn new() -> Workspace { + Workspace { + hovered_panel: 0, + root: PanelGroup::new(), + } + } // add panel / panel group // delete panel / panel group // move panel / panel group @@ -18,6 +24,15 @@ struct PanelGroup { layout_direction: LayoutDirection, } +impl PanelGroup { + fn new() -> PanelGroup { + PanelGroup { + contents: vec![], + layout_direction: LayoutDirection::Horizontal, + } + } +} + enum Contents { PanelArea(PanelArea), Group(PanelGroup),