diff --git a/client/web/src/components/panels/ViewportPanel.vue b/client/web/src/components/panels/ViewportPanel.vue
index ae05110c4..34358d60e 100644
--- a/client/web/src/components/panels/ViewportPanel.vue
+++ b/client/web/src/components/panels/ViewportPanel.vue
@@ -12,7 +12,7 @@
-
+
@@ -70,12 +70,19 @@ import { defineComponent } from "vue";
import LayoutRow from "../layout/LayoutRow.vue";
import LayoutCol from "../layout/LayoutCol.vue";
+const wasm = import("../../../wasm/pkg");
+
export default defineComponent({
components: {
LayoutRow,
LayoutCol,
},
- props: {
+ methods: {
+ async canvasClick(e: MouseEvent) {
+ console.log(e);
+ const { on_mouse_click } = await wasm;
+ on_mouse_click(e.offsetX, e.offsetY);
+ }
},
});
diff --git a/client/web/src/wasm-callback-processor.js b/client/web/src/wasm-callback-processor.js
new file mode 100644
index 000000000..3701dfa57
--- /dev/null
+++ b/client/web/src/wasm-callback-processor.js
@@ -0,0 +1,3 @@
+export function update_canvas() {
+ console.log("update_canvas")
+}
diff --git a/client/web/wasm/src/lib.rs b/client/web/wasm/src/lib.rs
index e12e68caf..d451348c7 100644
--- a/client/web/wasm/src/lib.rs
+++ b/client/web/wasm/src/lib.rs
@@ -4,23 +4,27 @@ pub mod viewport;
pub mod window;
pub mod wrappers;
-use graphite_editor_core::Editor;
+use graphite_editor_core::{events::Response, Callback, 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())}
+thread_local! {pub static EDITOR_STATE: RefCell = RefCell::new(Editor::new(Box::new(handle_response)))}
#[wasm_bindgen(start)]
pub fn init() {
utils::set_panic_hook();
}
-/// Send events
-#[wasm_bindgen]
-pub fn handle_event(event_name: String) {
- // TODO: add payload
- todo!()
+fn handle_response(response: Response) {
+ match response {
+ Response::UpdateCanvas => update_canvas(),
+ }
+}
+
+#[wasm_bindgen(module = "/../src/wasm-callback-processor.js")]
+extern "C" {
+ fn update_canvas();
}
#[wasm_bindgen]
diff --git a/client/web/wasm/src/viewport.rs b/client/web/wasm/src/viewport.rs
index 61f55d2df..2f24d0d9c 100644
--- a/client/web/wasm/src/viewport.rs
+++ b/client/web/wasm/src/viewport.rs
@@ -1,6 +1,7 @@
use crate::shims::Error;
use crate::wrappers::{translate_tool, Color};
use crate::EDITOR_STATE;
+use graphite_editor_core::events;
use wasm_bindgen::prelude::*;
/// Modify the currently selected tool in the document state store
@@ -15,10 +16,22 @@ pub fn select_tool(tool: String) -> Result<(), JsValue> {
})
}
+static mut POS: (u32, u32) = (0, 0);
+
/// Mouse movement with the bounds of the canvas
#[wasm_bindgen]
pub fn on_mouse_move(x: u32, y: u32) {
- todo!()
+ // SAFETY: This is safe because the code can only ever run in a single thread
+ unsafe {
+ POS = (x, y);
+ }
+}
+
+/// Mouse click within the bounds of the canvas
+#[wasm_bindgen]
+pub fn on_mouse_click(x: u32, y: u32) -> Result<(), JsValue> {
+ let ev = events::Event::Click(events::MouseState::from_pos(x, y));
+ EDITOR_STATE.with(|editor| editor.borrow_mut().handle_event(ev)).map_err(|err| Error::new(&err.to_string()).into())
}
/// Update working colors
diff --git a/core/editor/src/scheduler/events.rs b/core/editor/src/dispatcher/events.rs
similarity index 62%
rename from core/editor/src/scheduler/events.rs
rename to core/editor/src/dispatcher/events.rs
index e4eff7710..41e096c37 100644
--- a/core/editor/src/scheduler/events.rs
+++ b/core/editor/src/dispatcher/events.rs
@@ -11,25 +11,45 @@ pub enum Event {
}
#[derive(Debug, Clone)]
-struct Trace(Vec);
-#[derive(Debug, Clone)]
-struct MouseState {
- x: u32,
- y: u32,
- mod_keys: ModKeys,
- mouse_keys: MouseKeys,
+#[repr(C)]
+pub enum Response {
+ UpdateCanvas,
}
#[derive(Debug, Clone)]
-enum Key {
+pub struct Trace(Vec);
+#[derive(Debug, Clone, Default)]
+pub struct MouseState {
+ x: u32,
+ y: u32,
+ mod_keys: ModKeysStorage,
+ mouse_keys: MouseKeysStorage,
+}
+
+impl MouseState {
+ pub const fn new() -> MouseState {
+ MouseState {
+ x: 0,
+ y: 0,
+ mod_keys: 0,
+ mouse_keys: 0,
+ }
+ }
+ pub const fn from_pos(x: u32, y: u32) -> MouseState {
+ MouseState { x, y, mod_keys: 0, mouse_keys: 0 }
+ }
+}
+
+#[derive(Debug, Clone)]
+pub enum Key {
None,
}
-type ModKeysStorage = u8;
-type MouseKeysStorage = u8;
+pub type ModKeysStorage = u8;
+pub type MouseKeysStorage = u8;
#[derive(Debug, Clone, Copy)]
#[repr(transparent)]
-struct ModKeys(ModKeysStorage);
+pub struct ModKeys(ModKeysStorage);
impl ModKeys {
pub fn get_key(&self, key: ModKey) -> bool {
@@ -55,7 +75,7 @@ impl MouseKeys {
#[repr(u8)]
#[derive(Debug, Clone)]
-enum ModKey {
+pub enum ModKey {
Control = 1,
Shift = 2,
Alt = 4,
@@ -63,7 +83,7 @@ enum ModKey {
#[repr(u8)]
#[derive(Debug, Clone)]
-enum MouseKey {
+pub enum MouseKey {
LeftMouse = 1,
RightMouse = 2,
MiddleMouse = 4,
diff --git a/core/editor/src/dispatcher/mod.rs b/core/editor/src/dispatcher/mod.rs
new file mode 100644
index 000000000..42208860d
--- /dev/null
+++ b/core/editor/src/dispatcher/mod.rs
@@ -0,0 +1,24 @@
+pub mod events;
+use crate::EditorError;
+use events::{Event, Response};
+
+pub type Callback = Box;
+pub struct Dispatcher {
+ callback: Callback,
+}
+
+impl Dispatcher {
+ pub fn handle_event(&self, event: Event) -> Result<(), EditorError> {
+ match event {
+ Event::Click(_) => Ok(self.emit_response(Response::UpdateCanvas)),
+ _ => todo!(),
+ }
+ }
+ pub fn emit_response(&self, response: Response) {
+ let func = &self.callback;
+ func(response)
+ }
+ pub fn new(callback: Callback) -> Dispatcher {
+ Dispatcher { callback }
+ }
+}
diff --git a/core/editor/src/error.rs b/core/editor/src/error.rs
index 00b19e976..b238bf893 100644
--- a/core/editor/src/error.rs
+++ b/core/editor/src/error.rs
@@ -1,3 +1,4 @@
+use crate::events::Event;
use crate::Color;
use std::error::Error;
use std::fmt::{self, Display};
@@ -6,6 +7,7 @@ use std::fmt::{self, Display};
#[derive(Clone, Debug)]
pub enum EditorError {
InvalidOperation(String),
+ InvalidEvent(String),
Misc(String),
Color(String),
}
@@ -14,6 +16,7 @@ impl Display for EditorError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
EditorError::InvalidOperation(e) => write!(f, "Failed to execute operation: {}", e),
+ EditorError::InvalidEvent(e) => write!(f, "Failed to dispatch event: {}", e),
EditorError::Misc(e) => write!(f, "{}", e),
EditorError::Color(c) => write!(f, "Tried to construct an invalid color {:?}", c),
}
@@ -35,3 +38,4 @@ macro_rules! derive_from {
derive_from!(&str, Misc);
derive_from!(String, Misc);
derive_from!(Color, Color);
+derive_from!(Event, InvalidEvent);
diff --git a/core/editor/src/lib.rs b/core/editor/src/lib.rs
index 6c5412c42..9d37f08c6 100644
--- a/core/editor/src/lib.rs
+++ b/core/editor/src/lib.rs
@@ -1,6 +1,6 @@
mod color;
+mod dispatcher;
mod error;
-mod scheduler;
pub mod tools;
pub mod workspace;
@@ -10,6 +10,13 @@ pub use error::EditorError;
#[doc(inline)]
pub use color::Color;
+#[doc(inline)]
+pub use dispatcher::events;
+
+#[doc(inline)]
+pub use dispatcher::Callback;
+
+use dispatcher::Dispatcher;
use tools::ToolState;
use workspace::Workspace;
@@ -17,13 +24,18 @@ use workspace::Workspace;
pub struct Editor {
pub tools: ToolState,
workspace: Workspace,
+ dispatcher: Dispatcher,
}
impl Editor {
- pub fn new() -> Self {
+ pub fn new(callback: Callback) -> Self {
Self {
tools: ToolState::new(),
workspace: Workspace::new(),
+ dispatcher: Dispatcher::new(callback),
}
}
+ pub fn handle_event(&mut self, event: events::Event) -> Result<(), EditorError> {
+ self.dispatcher.handle_event(event)
+ }
}
diff --git a/core/editor/src/scheduler/mod.rs b/core/editor/src/scheduler/mod.rs
deleted file mode 100644
index a9970c28f..000000000
--- a/core/editor/src/scheduler/mod.rs
+++ /dev/null
@@ -1 +0,0 @@
-pub mod events;