From 8e56a274fef6d37470a98da68a342d766eba5307 Mon Sep 17 00:00:00 2001 From: Henry Sloan Date: Tue, 20 Jul 2021 00:52:27 -0400 Subject: [PATCH] Add initial tool settings messaging to backend --- .../widgets/options/ToolOptions.vue | 98 ++++++++++--------- client/web/wasm/src/document.rs | 11 ++- client/web/wasm/src/wrappers.rs | 22 +++++ core/editor/src/tool/mod.rs | 2 +- core/editor/src/tool/tool_message_handler.rs | 8 +- core/editor/src/tool/tools/shape.rs | 7 ++ 6 files changed, 98 insertions(+), 50 deletions(-) diff --git a/client/web/src/components/widgets/options/ToolOptions.vue b/client/web/src/components/widgets/options/ToolOptions.vue index 3be38c2d37..0cc45b5988 100644 --- a/client/web/src/components/widgets/options/ToolOptions.vue +++ b/client/web/src/components/widgets/options/ToolOptions.vue @@ -7,7 +7,7 @@

{{ option.title }}

{{ option.placeholder_text }}

- + @@ -28,6 +28,8 @@ import IconButton from "@/components/widgets/buttons/IconButton.vue"; import PopoverButton from "@/components/widgets/buttons/PopoverButton.vue"; import NumberInput from "@/components/widgets/inputs/NumberInput.vue"; +const wasm = import("@/../wasm/pkg"); + type ToolOptionsList = Array; type ToolOptionsMap = Map; @@ -54,60 +56,64 @@ interface NumberOption { kind: "number"; initial: number; step: number; + callback?: Function; } -const optionsMap: ToolOptionsMap = new Map([ - [ - "Select", - [ - { kind: "icon", icon: "AlignHorizontalLeft", title: "Horizontal Align Left" }, - { kind: "icon", icon: "AlignHorizontalCenter", title: "Horizontal Align Center" }, - { kind: "icon", icon: "AlignHorizontalRight", title: "Horizontal Align Right" }, - - { kind: "separator", type: SeparatorType.Unrelated }, - - { kind: "icon", icon: "AlignVerticalTop", title: "Vertical Align Top" }, - { kind: "icon", icon: "AlignVerticalCenter", title: "Vertical Align Center" }, - { kind: "icon", icon: "AlignVerticalBottom", title: "Vertical Align Bottom" }, - - { kind: "separator", type: SeparatorType.Related }, - - { kind: "popover", title: "Align", placeholder_text: "More alignment-related buttons will be here" }, - - { kind: "separator", type: SeparatorType.Section }, - - { kind: "icon", icon: "FlipHorizontal", title: "Flip Horizontal" }, - { kind: "icon", icon: "FlipVertical", title: "Flip Vertical" }, - - { kind: "separator", type: SeparatorType.Related }, - - { kind: "popover", title: "Flip", placeholder_text: "More flip-related buttons will be here" }, - - { kind: "separator", type: SeparatorType.Section }, - - { kind: "icon", icon: "BooleanUnion", title: "Boolean Union" }, - { kind: "icon", icon: "BooleanSubtractFront", title: "Boolean Subtract Front" }, - { kind: "icon", icon: "BooleanSubtractBack", title: "Boolean Subtract Back" }, - { kind: "icon", icon: "BooleanIntersect", title: "Boolean Intersect" }, - { kind: "icon", icon: "BooleanDifference", title: "Boolean Difference" }, - - { kind: "separator", type: SeparatorType.Related }, - - { kind: "popover", title: "Boolean", placeholder_text: "More boolean-related buttons will be here" }, - ], - ], - ["Shape", [{ kind: "number", initial: 6, step: 1 }]], -]); - export default defineComponent({ props: { activeTool: { type: String }, }, computed: {}, - methods: {}, + methods: { + async setToolSettings() { + const { set_tool_settings, ToolSettings } = await wasm; + set_tool_settings(this.$props.activeTool || "Select", new ToolSettings()); + }, + }, data() { return { - optionsMap, + optionsMap: new Map([ + [ + "Select", + [ + { kind: "icon", icon: "AlignHorizontalLeft", title: "Horizontal Align Left" }, + { kind: "icon", icon: "AlignHorizontalCenter", title: "Horizontal Align Center" }, + { kind: "icon", icon: "AlignHorizontalRight", title: "Horizontal Align Right" }, + + { kind: "separator", type: SeparatorType.Unrelated }, + + { kind: "icon", icon: "AlignVerticalTop", title: "Vertical Align Top" }, + { kind: "icon", icon: "AlignVerticalCenter", title: "Vertical Align Center" }, + { kind: "icon", icon: "AlignVerticalBottom", title: "Vertical Align Bottom" }, + + { kind: "separator", type: SeparatorType.Related }, + + { kind: "popover", title: "Align", placeholder_text: "More alignment-related buttons will be here" }, + + { kind: "separator", type: SeparatorType.Section }, + + { kind: "icon", icon: "FlipHorizontal", title: "Flip Horizontal" }, + { kind: "icon", icon: "FlipVertical", title: "Flip Vertical" }, + + { kind: "separator", type: SeparatorType.Related }, + + { kind: "popover", title: "Flip", placeholder_text: "More flip-related buttons will be here" }, + + { kind: "separator", type: SeparatorType.Section }, + + { kind: "icon", icon: "BooleanUnion", title: "Boolean Union" }, + { kind: "icon", icon: "BooleanSubtractFront", title: "Boolean Subtract Front" }, + { kind: "icon", icon: "BooleanSubtractBack", title: "Boolean Subtract Back" }, + { kind: "icon", icon: "BooleanIntersect", title: "Boolean Intersect" }, + { kind: "icon", icon: "BooleanDifference", title: "Boolean Difference" }, + + { kind: "separator", type: SeparatorType.Related }, + + { kind: "popover", title: "Boolean", placeholder_text: "More boolean-related buttons will be here" }, + ], + ], + ["Shape", [{ kind: "number", initial: 6, step: 1, callback: this.setToolSettings }]], + ]), SeparatorType, }; }, diff --git a/client/web/wasm/src/document.rs b/client/web/wasm/src/document.rs index 2c80a6d57b..eaaf36158f 100644 --- a/client/web/wasm/src/document.rs +++ b/client/web/wasm/src/document.rs @@ -1,5 +1,5 @@ use crate::shims::Error; -use crate::wrappers::{translate_key, translate_tool, Color}; +use crate::wrappers::{translate_key, translate_tool, Color, ToolSettings}; use crate::EDITOR_STATE; use editor_core::input::input_preprocessor::ModifierKeys; use editor_core::input::mouse::ScrollDelta; @@ -23,6 +23,15 @@ pub fn select_tool(tool: String) -> Result<(), JsValue> { }) } +/// Update the settings for a given tool +#[wasm_bindgen] +pub fn set_tool_settings(tool: String, settings: ToolSettings) -> Result<(), JsValue> { + EDITOR_STATE.with(|editor| match translate_tool(&tool) { + Some(tool) => editor.borrow_mut().handle_message(ToolMessage::SetToolSettings(tool, settings.inner())).map_err(convert_error), + None => Err(Error::new(&format!("Couldn't select {} because it was not recognized as a valid tool", tool)).into()), + }) +} + #[wasm_bindgen] pub fn select_document(document: usize) -> Result<(), JsValue> { EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentMessage::SelectDocument(document)).map_err(convert_error)) diff --git a/client/web/wasm/src/wrappers.rs b/client/web/wasm/src/wrappers.rs index a6564bec15..790912d9ee 100644 --- a/client/web/wasm/src/wrappers.rs +++ b/client/web/wasm/src/wrappers.rs @@ -1,5 +1,7 @@ use crate::shims::Error; use editor_core::input::keyboard::Key; +use editor_core::tool::tool_settings::Shape; +use editor_core::tool::tool_settings::ToolSettings as InnerToolSettings; use editor_core::tool::{SelectAppendMode, ToolType}; use editor_core::Color as InnerColor; use wasm_bindgen::prelude::*; @@ -24,6 +26,26 @@ impl Color { } } +#[wasm_bindgen] +pub struct ToolSettings(InnerToolSettings); + +#[wasm_bindgen] +impl ToolSettings { + #[wasm_bindgen(constructor)] + pub fn new() -> Result { + // TODO + Ok(Self(InnerToolSettings::Shape { + shape: Shape::Polygon { vertices: 6 }, + })) + } +} + +impl ToolSettings { + pub fn inner(&self) -> InnerToolSettings { + self.0 + } +} + macro_rules! match_string_to_enum { (match ($e:expr) {$($var:ident),* $(,)?}) => { match $e { diff --git a/core/editor/src/tool/mod.rs b/core/editor/src/tool/mod.rs index 4eab531a9b..3d97a27a84 100644 --- a/core/editor/src/tool/mod.rs +++ b/core/editor/src/tool/mod.rs @@ -37,7 +37,7 @@ pub trait Fsm { pub struct DocumentToolData { pub primary_color: Color, pub secondary_color: Color, - tool_settings: HashMap, + pub tool_settings: HashMap, } type SubToolMessageHandler = dyn for<'a> MessageHandler>; diff --git a/core/editor/src/tool/tool_message_handler.rs b/core/editor/src/tool/tool_message_handler.rs index 4acd7efce4..04ed4b83ca 100644 --- a/core/editor/src/tool/tool_message_handler.rs +++ b/core/editor/src/tool/tool_message_handler.rs @@ -4,7 +4,7 @@ use document_core::color::Color; use crate::input::InputPreprocessor; use crate::{ document::Document, - tool::{ToolFsmState, ToolType}, + tool::{tool_settings::ToolSettings, ToolFsmState, ToolType}, }; use std::collections::VecDeque; @@ -16,6 +16,7 @@ pub enum ToolMessage { SelectSecondaryColor(Color), SwapColors, ResetColors, + SetToolSettings(ToolType, ToolSettings), #[child] Fill(FillMessage), #[child] @@ -89,6 +90,9 @@ impl MessageHandler for ToolMessag .into(), ) } + SetToolSettings(tool_type, tool_settings) => { + self.tool_state.document_tool_data.tool_settings.insert(tool_type, tool_settings); + } message => { let tool_type = match message { Fill(_) => ToolType::Fill, @@ -111,7 +115,7 @@ impl MessageHandler for ToolMessag } } fn actions(&self) -> ActionList { - let mut list = actions!(ToolMessageDiscriminant; ResetColors, SwapColors, SelectTool); + let mut list = actions!(ToolMessageDiscriminant; ResetColors, SwapColors, SelectTool, SetToolSettings); list.extend(self.tool_state.tool_data.active_tool().actions()); list } diff --git a/core/editor/src/tool/tools/shape.rs b/core/editor/src/tool/tools/shape.rs index d830d48df5..aba9d35a75 100644 --- a/core/editor/src/tool/tools/shape.rs +++ b/core/editor/src/tool/tools/shape.rs @@ -71,6 +71,13 @@ impl Fsm for ShapeToolFsmState { data.drag_current = input.mouse.position; data.sides = 6; + if let Some(tool_settings) = tool_data.tool_settings.get(&crate::tool::ToolType::Shape) { + if let crate::tool::ToolSettings::Shape { shape } = tool_settings { + if let crate::tool::Shape::Polygon { vertices } = shape { + data.sides = *vertices as u8; + } + } + }; responses.push_back(Operation::MountWorkingFolder { path: vec![] }.into()); Dragging