From c98bc770daf6ae5f26140c685ae0cf89aa85d156 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Sat, 10 Apr 2021 03:49:27 -0700 Subject: [PATCH] Implement active tool visual syncing with tool shelf state --- client/web/src/components/panels/Document.vue | 53 +++++++++++-------- client/web/src/response-handler.ts | 1 + client/web/wasm/src/lib.rs | 1 + client/web/wasm/src/wrappers.rs | 11 ++++ core/editor/src/dispatcher/events.rs | 2 + core/editor/src/dispatcher/mod.rs | 20 +++++-- core/editor/src/tools/mod.rs | 44 +++++++++++++-- 7 files changed, 102 insertions(+), 30 deletions(-) diff --git a/client/web/src/components/panels/Document.vue b/client/web/src/components/panels/Document.vue index 3ef3b9105..c9c17a2db 100644 --- a/client/web/src/components/panels/Document.vue +++ b/client/web/src/components/panels/Document.vue @@ -35,36 +35,36 @@
- - - - + + + + - - - + + + - - - - - - + + + + + + - - - - - - - - + + + + + + + +
@@ -293,17 +293,26 @@ export default defineComponent({ const { on_key_up } = await wasm; on_key_up(e.key); }, + async selectTool(toolName: string) { + const { select_tool } = await wasm; + select_tool(toolName); + }, }, mounted() { registerResponseHandler(ResponseType.UpdateCanvas, (responseData) => { - this.viewportSvg = responseData; + this.viewportSvg = responseData.split("\n").map((shape, i) => shape.replace("#fff", `#${Math.floor(Math.abs(Math.sin(i + 1)) * 16777215).toString(16)}`)).join("\n"); }); + registerResponseHandler(ResponseType.SetActiveTool, (responseData) => { + this.activeTool = responseData; + }); + window.addEventListener("keyup", (e: KeyboardEvent) => this.keyUp(e)); window.addEventListener("keydown", (e: KeyboardEvent) => this.keyDown(e)); }, data() { return { viewportSvg: "", + activeTool: "Select", }; }, }); diff --git a/client/web/src/response-handler.ts b/client/web/src/response-handler.ts index f9aed6019..4db206491 100644 --- a/client/web/src/response-handler.ts +++ b/client/web/src/response-handler.ts @@ -8,6 +8,7 @@ declare global { export enum ResponseType { UpdateCanvas = "UpdateCanvas", + SetActiveTool = "SetActiveTool", } export function attachResponseHandlerToPage() { diff --git a/client/web/wasm/src/lib.rs b/client/web/wasm/src/lib.rs index 71d4c0342..2681312ea 100644 --- a/client/web/wasm/src/lib.rs +++ b/client/web/wasm/src/lib.rs @@ -24,6 +24,7 @@ fn handle_response(response: Response) { let response_type = response.to_string(); match response { Response::UpdateCanvas { document } => handleResponse(response_type, document), + Response::SetActiveTool { tool_name } => handleResponse(response_type, tool_name), } } diff --git a/client/web/wasm/src/wrappers.rs b/client/web/wasm/src/wrappers.rs index db11011f9..474d3213d 100644 --- a/client/web/wasm/src/wrappers.rs +++ b/client/web/wasm/src/wrappers.rs @@ -30,8 +30,19 @@ pub fn translate_tool(name: &str) -> Option { "Crop" => Some(ToolType::Crop), "Navigate" => Some(ToolType::Navigate), "Sample" => Some(ToolType::Sample), + "Text" => Some(ToolType::Text), + "Fill" => Some(ToolType::Fill), + "Gradient" => Some(ToolType::Gradient), + "Brush" => Some(ToolType::Brush), + "Heal" => Some(ToolType::Heal), + "Clone" => Some(ToolType::Clone), + "Patch" => Some(ToolType::Patch), + "BlurSharpen" => Some(ToolType::BlurSharpen), + "Relight" => Some(ToolType::Relight), "Path" => Some(ToolType::Path), "Pen" => Some(ToolType::Pen), + "Freehand" => Some(ToolType::Freehand), + "Spline" => Some(ToolType::Spline), "Line" => Some(ToolType::Line), "Rectangle" => Some(ToolType::Rectangle), "Ellipse" => Some(ToolType::Ellipse), diff --git a/core/editor/src/dispatcher/events.rs b/core/editor/src/dispatcher/events.rs index 83fff32d8..70c51d309 100644 --- a/core/editor/src/dispatcher/events.rs +++ b/core/editor/src/dispatcher/events.rs @@ -26,12 +26,14 @@ pub enum Event { // TODO - Make Copy when possible pub enum Response { UpdateCanvas { document: String }, + SetActiveTool { tool_name: String }, } impl fmt::Display for Response { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { match self { Response::UpdateCanvas { document: _ } => write!(formatter, "UpdateCanvas"), + Response::SetActiveTool { tool_name: _ } => write!(formatter, "SetActiveTool"), } } } diff --git a/core/editor/src/dispatcher/mod.rs b/core/editor/src/dispatcher/mod.rs index 9f87c4989..0c430d7ff 100644 --- a/core/editor/src/dispatcher/mod.rs +++ b/core/editor/src/dispatcher/mod.rs @@ -13,8 +13,9 @@ impl Dispatcher { log::trace!("{:?}", event); match event { - Event::SelectTool(tool_type) => { - editor_state.tool_state.active_tool_type = *tool_type; + Event::SelectTool(tool_name) => { + editor_state.tool_state.active_tool_type = *tool_name; + self.dispatch_response(Response::SetActiveTool { tool_name: tool_name.to_string() }); } Event::SelectPrimaryColor(color) => { editor_state.tool_state.primary_color = *color; @@ -56,14 +57,23 @@ impl Dispatcher { log::set_max_level(log::LevelFilter::Trace); log::debug!("set log verbosity to trace"); } + Key::KeyV => { + editor_state.tool_state.active_tool_type = ToolType::Select; + self.dispatch_response(Response::SetActiveTool { + tool_name: ToolType::Select.to_string(), + }); + } Key::KeyM => { editor_state.tool_state.active_tool_type = ToolType::Rectangle; + self.dispatch_response(Response::SetActiveTool { + tool_name: ToolType::Rectangle.to_string(), + }); } Key::KeyE => { editor_state.tool_state.active_tool_type = ToolType::Ellipse; - } - Key::KeyV => { - editor_state.tool_state.active_tool_type = ToolType::Select; + self.dispatch_response(Response::SetActiveTool { + tool_name: ToolType::Ellipse.to_string(), + }); } Key::KeyX => { editor_state.tool_state.swap_colors(); diff --git a/core/editor/src/tools/mod.rs b/core/editor/src/tools/mod.rs index 3e7969b23..360262cb3 100644 --- a/core/editor/src/tools/mod.rs +++ b/core/editor/src/tools/mod.rs @@ -14,7 +14,7 @@ use crate::Color; use crate::Document; use crate::EditorError; use document_core::Operation; -use std::collections::HashMap; +use std::{collections::HashMap, fmt}; pub trait Tool { fn handle_input(&mut self, event: &Event, document: &Document) -> (Vec, Vec); @@ -44,7 +44,7 @@ impl Default for ToolFsmState { trace: Trace::new(), primary_color: Color::BLACK, secondary_color: Color::WHITE, - active_tool_type: ToolType::Rectangle, + active_tool_type: ToolType::Select, tools: gen_tools_hash_map! { Select => select::Select, Crop => crop::Crop, @@ -103,13 +103,51 @@ pub enum ToolType { Crop, Navigate, Sample, + Text, + Fill, + Gradient, + Brush, + Heal, + Clone, + Patch, + BlurSharpen, + Relight, Path, Pen, + Freehand, + Spline, Line, Rectangle, Ellipse, Shape, - // all discriminats must be strictly smaller than TOOL_COUNT! +} + +impl fmt::Display for ToolType { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + match self { + ToolType::Select => write!(formatter, "Select"), + ToolType::Crop => write!(formatter, "Crop"), + ToolType::Navigate => write!(formatter, "Navigate"), + ToolType::Sample => write!(formatter, "Sample"), + ToolType::Text => write!(formatter, "Text"), + ToolType::Fill => write!(formatter, "Fill"), + ToolType::Gradient => write!(formatter, "Gradient"), + ToolType::Brush => write!(formatter, "Brush"), + ToolType::Heal => write!(formatter, "Heal"), + ToolType::Clone => write!(formatter, "Clone"), + ToolType::Patch => write!(formatter, "Patch"), + ToolType::BlurSharpen => write!(formatter, "BlurSharpen"), + ToolType::Relight => write!(formatter, "Relight"), + ToolType::Path => write!(formatter, "Path"), + ToolType::Pen => write!(formatter, "Pen"), + ToolType::Freehand => write!(formatter, "Freehand"), + ToolType::Spline => write!(formatter, "Spline"), + ToolType::Line => write!(formatter, "Line"), + ToolType::Rectangle => write!(formatter, "Rectangle"), + ToolType::Ellipse => write!(formatter, "Ellipse"), + ToolType::Shape => write!(formatter, "Shape"), + } + } } impl ToolType {