mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-29 04:18:11 +08:00
Add initial tool settings messaging to backend
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
<h3>{{ option.title }}</h3>
|
<h3>{{ option.title }}</h3>
|
||||||
<p>{{ option.placeholder_text }}</p>
|
<p>{{ option.placeholder_text }}</p>
|
||||||
</PopoverButton>
|
</PopoverButton>
|
||||||
<NumberInput v-if="option.kind === 'number'" :initialValue="option.initial" :step="option.step" :updateOnCallback="false" />
|
<NumberInput v-if="option.kind === 'number'" :callback="option.callback" :initialValue="option.initial" :step="option.step" :updateOnCallback="false" />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -28,6 +28,8 @@ import IconButton from "@/components/widgets/buttons/IconButton.vue";
|
|||||||
import PopoverButton from "@/components/widgets/buttons/PopoverButton.vue";
|
import PopoverButton from "@/components/widgets/buttons/PopoverButton.vue";
|
||||||
import NumberInput from "@/components/widgets/inputs/NumberInput.vue";
|
import NumberInput from "@/components/widgets/inputs/NumberInput.vue";
|
||||||
|
|
||||||
|
const wasm = import("@/../wasm/pkg");
|
||||||
|
|
||||||
type ToolOptionsList = Array<ToolOptions>;
|
type ToolOptionsList = Array<ToolOptions>;
|
||||||
type ToolOptionsMap = Map<string, ToolOptionsList>;
|
type ToolOptionsMap = Map<string, ToolOptionsList>;
|
||||||
|
|
||||||
@@ -54,60 +56,64 @@ interface NumberOption {
|
|||||||
kind: "number";
|
kind: "number";
|
||||||
initial: number;
|
initial: number;
|
||||||
step: 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({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
activeTool: { type: String },
|
activeTool: { type: String },
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {},
|
||||||
methods: {},
|
methods: {
|
||||||
|
async setToolSettings() {
|
||||||
|
const { set_tool_settings, ToolSettings } = await wasm;
|
||||||
|
set_tool_settings(this.$props.activeTool || "Select", new ToolSettings());
|
||||||
|
},
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
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,
|
SeparatorType,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::shims::Error;
|
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 crate::EDITOR_STATE;
|
||||||
use editor_core::input::input_preprocessor::ModifierKeys;
|
use editor_core::input::input_preprocessor::ModifierKeys;
|
||||||
use editor_core::input::mouse::ScrollDelta;
|
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]
|
#[wasm_bindgen]
|
||||||
pub fn select_document(document: usize) -> Result<(), JsValue> {
|
pub fn select_document(document: usize) -> Result<(), JsValue> {
|
||||||
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentMessage::SelectDocument(document)).map_err(convert_error))
|
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_message(DocumentMessage::SelectDocument(document)).map_err(convert_error))
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
use crate::shims::Error;
|
use crate::shims::Error;
|
||||||
use editor_core::input::keyboard::Key;
|
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::tool::{SelectAppendMode, ToolType};
|
||||||
use editor_core::Color as InnerColor;
|
use editor_core::Color as InnerColor;
|
||||||
use wasm_bindgen::prelude::*;
|
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<ToolSettings, JsValue> {
|
||||||
|
// 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 {
|
macro_rules! match_string_to_enum {
|
||||||
(match ($e:expr) {$($var:ident),* $(,)?}) => {
|
(match ($e:expr) {$($var:ident),* $(,)?}) => {
|
||||||
match $e {
|
match $e {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ pub trait Fsm {
|
|||||||
pub struct DocumentToolData {
|
pub struct DocumentToolData {
|
||||||
pub primary_color: Color,
|
pub primary_color: Color,
|
||||||
pub secondary_color: Color,
|
pub secondary_color: Color,
|
||||||
tool_settings: HashMap<ToolType, ToolSettings>,
|
pub tool_settings: HashMap<ToolType, ToolSettings>,
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubToolMessageHandler = dyn for<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>>;
|
type SubToolMessageHandler = dyn for<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>>;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use document_core::color::Color;
|
|||||||
use crate::input::InputPreprocessor;
|
use crate::input::InputPreprocessor;
|
||||||
use crate::{
|
use crate::{
|
||||||
document::Document,
|
document::Document,
|
||||||
tool::{ToolFsmState, ToolType},
|
tool::{tool_settings::ToolSettings, ToolFsmState, ToolType},
|
||||||
};
|
};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@ pub enum ToolMessage {
|
|||||||
SelectSecondaryColor(Color),
|
SelectSecondaryColor(Color),
|
||||||
SwapColors,
|
SwapColors,
|
||||||
ResetColors,
|
ResetColors,
|
||||||
|
SetToolSettings(ToolType, ToolSettings),
|
||||||
#[child]
|
#[child]
|
||||||
Fill(FillMessage),
|
Fill(FillMessage),
|
||||||
#[child]
|
#[child]
|
||||||
@@ -89,6 +90,9 @@ impl MessageHandler<ToolMessage, (&Document, &InputPreprocessor)> for ToolMessag
|
|||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
SetToolSettings(tool_type, tool_settings) => {
|
||||||
|
self.tool_state.document_tool_data.tool_settings.insert(tool_type, tool_settings);
|
||||||
|
}
|
||||||
message => {
|
message => {
|
||||||
let tool_type = match message {
|
let tool_type = match message {
|
||||||
Fill(_) => ToolType::Fill,
|
Fill(_) => ToolType::Fill,
|
||||||
@@ -111,7 +115,7 @@ impl MessageHandler<ToolMessage, (&Document, &InputPreprocessor)> for ToolMessag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn actions(&self) -> ActionList {
|
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.extend(self.tool_state.tool_data.active_tool().actions());
|
||||||
list
|
list
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,13 @@ impl Fsm for ShapeToolFsmState {
|
|||||||
data.drag_current = input.mouse.position;
|
data.drag_current = input.mouse.position;
|
||||||
|
|
||||||
data.sides = 6;
|
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());
|
responses.push_back(Operation::MountWorkingFolder { path: vec![] }.into());
|
||||||
Dragging
|
Dragging
|
||||||
|
|||||||
Reference in New Issue
Block a user