diff --git a/client/web/src/components/panels/Document.vue b/client/web/src/components/panels/Document.vue index 8b840e040..31213e104 100644 --- a/client/web/src/components/panels/Document.vue +++ b/client/web/src/components/panels/Document.vue @@ -6,49 +6,7 @@ - - - - - - - - - - - - - -

Align

-

More alignment-related buttons will be here

-
- - - - - - - - - -

Flip

-

More flip-related buttons will be here

-
- - - - - - - - - - - - -

Boolean

-

More boolean-related buttons will be here

-
+
@@ -255,6 +213,7 @@ import RadioInput from "@/components/widgets/inputs/RadioInput.vue"; import NumberInput from "@/components/widgets/inputs/NumberInput.vue"; import DropdownInput from "@/components/widgets/inputs/DropdownInput.vue"; import OptionalInput from "@/components/widgets/inputs/OptionalInput.vue"; +import ToolOptions from "@/components/widgets/options/ToolOptions.vue"; import { SectionsOfMenuListEntries } from "@/components/widgets/floating-menus/MenuList.vue"; const modeMenuEntries: SectionsOfMenuListEntries = [ @@ -401,6 +360,7 @@ export default defineComponent({ NumberInput, DropdownInput, OptionalInput, + ToolOptions, }, }); diff --git a/client/web/src/components/widgets/options/ToolOptions.vue b/client/web/src/components/widgets/options/ToolOptions.vue new file mode 100644 index 000000000..87d647811 --- /dev/null +++ b/client/web/src/components/widgets/options/ToolOptions.vue @@ -0,0 +1,134 @@ + + + + + diff --git a/client/web/wasm/src/document.rs b/client/web/wasm/src/document.rs index 2c80a6d57..e3c81ba32 100644 --- a/client/web/wasm/src/document.rs +++ b/client/web/wasm/src/document.rs @@ -4,6 +4,7 @@ use crate::EDITOR_STATE; use editor_core::input::input_preprocessor::ModifierKeys; use editor_core::input::mouse::ScrollDelta; use editor_core::message_prelude::*; +use editor_core::tool::tool_options::ToolOptions; use editor_core::{ input::mouse::{MouseState, ViewportPosition}, LayerId, @@ -23,6 +24,18 @@ pub fn select_tool(tool: String) -> Result<(), JsValue> { }) } +/// Update the options for a given tool +#[wasm_bindgen] +pub fn set_tool_options(tool: String, options: &JsValue) -> Result<(), JsValue> { + match options.into_serde::() { + Ok(options) => EDITOR_STATE.with(|editor| match translate_tool(&tool) { + Some(tool) => editor.borrow_mut().handle_message(ToolMessage::SetToolOptions(tool, options)).map_err(convert_error), + None => Err(Error::new(&format!("Couldn't select {} because it was not recognized as a valid tool", tool)).into()), + }), + Err(err) => Err(Error::new(&format!("Invalud JSON for ToolOptions: {}", err)).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/core/editor/src/tool/mod.rs b/core/editor/src/tool/mod.rs index 4eab531a9..643b5d9b0 100644 --- a/core/editor/src/tool/mod.rs +++ b/core/editor/src/tool/mod.rs @@ -1,5 +1,5 @@ pub mod tool_message_handler; -pub mod tool_settings; +pub mod tool_options; pub mod tools; use crate::document::Document; @@ -15,8 +15,8 @@ use std::{ fmt::{self, Debug}, }; pub use tool_message_handler::ToolMessageHandler; -use tool_settings::ToolSettings; -pub use tool_settings::*; +use tool_options::ToolOptions; +pub use tool_options::*; use tools::*; pub mod tool_messages { @@ -37,7 +37,7 @@ pub trait Fsm { pub struct DocumentToolData { pub primary_color: Color, pub secondary_color: Color, - tool_settings: HashMap, + pub tool_options: HashMap, } type SubToolMessageHandler = dyn for<'a> MessageHandler>; @@ -48,7 +48,7 @@ pub struct ToolData { impl fmt::Debug for ToolData { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("ToolData").field("active_tool_type", &self.active_tool_type).field("tool_settings", &"[…]").finish() + f.debug_struct("ToolData").field("active_tool_type", &self.active_tool_type).field("tool_options", &"[…]").finish() } } @@ -89,7 +89,7 @@ impl Default for ToolFsmState { document_tool_data: DocumentToolData { primary_color: Color::BLACK, secondary_color: Color::WHITE, - tool_settings: default_tool_settings(), + tool_options: default_tool_options(), }, } } @@ -105,8 +105,8 @@ impl ToolFsmState { } } -fn default_tool_settings() -> HashMap { - let tool_init = |tool: ToolType| (tool, tool.default_settings()); +fn default_tool_options() -> HashMap { + let tool_init = |tool: ToolType| (tool, tool.default_options()); std::array::IntoIter::new([ tool_init(ToolType::Select), tool_init(ToolType::Ellipse), @@ -174,12 +174,12 @@ impl fmt::Display for ToolType { } impl ToolType { - fn default_settings(&self) -> ToolSettings { + fn default_options(&self) -> ToolOptions { match self { - ToolType::Select => ToolSettings::Select { append_mode: SelectAppendMode::New }, - ToolType::Ellipse => ToolSettings::Ellipse, - ToolType::Shape => ToolSettings::Shape { - shape: Shape::Polygon { vertices: 3 }, + ToolType::Select => ToolOptions::Select { append_mode: SelectAppendMode::New }, + ToolType::Ellipse => ToolOptions::Ellipse, + ToolType::Shape => ToolOptions::Shape { + shape_type: ShapeType::Polygon { vertices: 6 }, }, _ => todo!(), } diff --git a/core/editor/src/tool/tool_message_handler.rs b/core/editor/src/tool/tool_message_handler.rs index 4acd7efce..b882d03db 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_options::ToolOptions, ToolFsmState, ToolType}, }; use std::collections::VecDeque; @@ -16,6 +16,7 @@ pub enum ToolMessage { SelectSecondaryColor(Color), SwapColors, ResetColors, + SetToolOptions(ToolType, ToolOptions), #[child] Fill(FillMessage), #[child] @@ -89,6 +90,9 @@ impl MessageHandler for ToolMessag .into(), ) } + SetToolOptions(tool_type, tool_options) => { + self.tool_state.document_tool_data.tool_options.insert(tool_type, tool_options); + } 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, SetToolOptions); list.extend(self.tool_state.tool_data.active_tool().actions()); list } diff --git a/core/editor/src/tool/tool_options.rs b/core/editor/src/tool/tool_options.rs new file mode 100644 index 000000000..e231a8376 --- /dev/null +++ b/core/editor/src/tool/tool_options.rs @@ -0,0 +1,22 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)] +pub enum ToolOptions { + Select { append_mode: SelectAppendMode }, + Ellipse, + Shape { shape_type: ShapeType }, +} + +#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)] +pub enum SelectAppendMode { + New, + Add, + Subtract, + Intersect, +} + +#[derive(Debug, Clone, Copy, Eq, PartialEq, Serialize, Deserialize)] +pub enum ShapeType { + Star { vertices: u32 }, + Polygon { vertices: u32 }, +} diff --git a/core/editor/src/tool/tool_settings.rs b/core/editor/src/tool/tool_settings.rs deleted file mode 100644 index 8233db3e3..000000000 --- a/core/editor/src/tool/tool_settings.rs +++ /dev/null @@ -1,20 +0,0 @@ -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub enum ToolSettings { - Select { append_mode: SelectAppendMode }, - Ellipse, - Shape { shape: Shape }, -} - -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub enum SelectAppendMode { - New, - Add, - Subtract, - Intersect, -} - -#[derive(Debug, Clone, Copy, Eq, PartialEq)] -pub enum Shape { - Star { vertices: u32 }, - Polygon { vertices: u32 }, -} diff --git a/core/editor/src/tool/tools/shape.rs b/core/editor/src/tool/tools/shape.rs index d830d48df..5d4fdc3ee 100644 --- a/core/editor/src/tool/tools/shape.rs +++ b/core/editor/src/tool/tools/shape.rs @@ -1,5 +1,5 @@ use crate::input::{mouse::ViewportPosition, InputPreprocessor}; -use crate::tool::{DocumentToolData, Fsm, ToolActionHandlerData}; +use crate::tool::{DocumentToolData, Fsm, ShapeType, ToolActionHandlerData, ToolOptions, ToolType}; use crate::{document::Document, message_prelude::*}; use document_core::{layers::style, Operation}; use glam::{DAffine2, DVec2}; @@ -70,7 +70,12 @@ impl Fsm for ShapeToolFsmState { data.drag_start = input.mouse.position; data.drag_current = input.mouse.position; - data.sides = 6; + data.sides = match tool_data.tool_options.get(&ToolType::Shape) { + Some(&ToolOptions::Shape { + shape_type: ShapeType::Polygon { vertices }, + }) => vertices as u8, + _ => 6, + }; responses.push_back(Operation::MountWorkingFolder { path: vec![] }.into()); Dragging