Implement event/response roundtrip (#49)

This commit is contained in:
TrueDoctor
2021-03-28 00:23:41 +01:00
committed by GitHub
parent 04dc05e575
commit 0e553adb32
9 changed files with 112 additions and 26 deletions
@@ -12,7 +12,7 @@
</LayoutRow> </LayoutRow>
<LayoutRow :class="'tools-and-viewport'"> <LayoutRow :class="'tools-and-viewport'">
<LayoutCol :class="'tools'"></LayoutCol> <LayoutCol :class="'tools'"></LayoutCol>
<LayoutCol :class="'viewport-container'"></LayoutCol> <LayoutCol :class="'viewport-container'" @click="canvasClick"></LayoutCol>
</LayoutRow> </LayoutRow>
</LayoutCol> </LayoutCol>
</template> </template>
@@ -70,12 +70,19 @@ import { defineComponent } from "vue";
import LayoutRow from "../layout/LayoutRow.vue"; import LayoutRow from "../layout/LayoutRow.vue";
import LayoutCol from "../layout/LayoutCol.vue"; import LayoutCol from "../layout/LayoutCol.vue";
const wasm = import("../../../wasm/pkg");
export default defineComponent({ export default defineComponent({
components: { components: {
LayoutRow, LayoutRow,
LayoutCol, LayoutCol,
}, },
props: { methods: {
async canvasClick(e: MouseEvent) {
console.log(e);
const { on_mouse_click } = await wasm;
on_mouse_click(e.offsetX, e.offsetY);
}
}, },
}); });
</script> </script>
@@ -0,0 +1,3 @@
export function update_canvas() {
console.log("update_canvas")
}
+11 -7
View File
@@ -4,23 +4,27 @@ pub mod viewport;
pub mod window; pub mod window;
pub mod wrappers; pub mod wrappers;
use graphite_editor_core::Editor; use graphite_editor_core::{events::Response, Callback, Editor};
use std::cell::RefCell; use std::cell::RefCell;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
// the thread_local macro provides a way to initialize static variables with non-constant functions // the thread_local macro provides a way to initialize static variables with non-constant functions
thread_local! {pub static EDITOR_STATE: RefCell<Editor> = RefCell::new(Editor::new())} thread_local! {pub static EDITOR_STATE: RefCell<Editor> = RefCell::new(Editor::new(Box::new(handle_response)))}
#[wasm_bindgen(start)] #[wasm_bindgen(start)]
pub fn init() { pub fn init() {
utils::set_panic_hook(); utils::set_panic_hook();
} }
/// Send events fn handle_response(response: Response) {
#[wasm_bindgen] match response {
pub fn handle_event(event_name: String) { Response::UpdateCanvas => update_canvas(),
// TODO: add payload }
todo!() }
#[wasm_bindgen(module = "/../src/wasm-callback-processor.js")]
extern "C" {
fn update_canvas();
} }
#[wasm_bindgen] #[wasm_bindgen]
+14 -1
View File
@@ -1,6 +1,7 @@
use crate::shims::Error; use crate::shims::Error;
use crate::wrappers::{translate_tool, Color}; use crate::wrappers::{translate_tool, Color};
use crate::EDITOR_STATE; use crate::EDITOR_STATE;
use graphite_editor_core::events;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
/// Modify the currently selected tool in the document state store /// 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 /// Mouse movement with the bounds of the canvas
#[wasm_bindgen] #[wasm_bindgen]
pub fn on_mouse_move(x: u32, y: u32) { 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 /// Update working colors
@@ -11,25 +11,45 @@ pub enum Event {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct Trace(Vec<MouseState>); #[repr(C)]
#[derive(Debug, Clone)] pub enum Response {
struct MouseState { UpdateCanvas,
x: u32,
y: u32,
mod_keys: ModKeys,
mouse_keys: MouseKeys,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Key { pub struct Trace(Vec<MouseState>);
#[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, None,
} }
type ModKeysStorage = u8; pub type ModKeysStorage = u8;
type MouseKeysStorage = u8; pub type MouseKeysStorage = u8;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
#[repr(transparent)] #[repr(transparent)]
struct ModKeys(ModKeysStorage); pub struct ModKeys(ModKeysStorage);
impl ModKeys { impl ModKeys {
pub fn get_key(&self, key: ModKey) -> bool { pub fn get_key(&self, key: ModKey) -> bool {
@@ -55,7 +75,7 @@ impl MouseKeys {
#[repr(u8)] #[repr(u8)]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum ModKey { pub enum ModKey {
Control = 1, Control = 1,
Shift = 2, Shift = 2,
Alt = 4, Alt = 4,
@@ -63,7 +83,7 @@ enum ModKey {
#[repr(u8)] #[repr(u8)]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum MouseKey { pub enum MouseKey {
LeftMouse = 1, LeftMouse = 1,
RightMouse = 2, RightMouse = 2,
MiddleMouse = 4, MiddleMouse = 4,
+24
View File
@@ -0,0 +1,24 @@
pub mod events;
use crate::EditorError;
use events::{Event, Response};
pub type Callback = Box<dyn Fn(Response)>;
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 }
}
}
+4
View File
@@ -1,3 +1,4 @@
use crate::events::Event;
use crate::Color; use crate::Color;
use std::error::Error; use std::error::Error;
use std::fmt::{self, Display}; use std::fmt::{self, Display};
@@ -6,6 +7,7 @@ use std::fmt::{self, Display};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum EditorError { pub enum EditorError {
InvalidOperation(String), InvalidOperation(String),
InvalidEvent(String),
Misc(String), Misc(String),
Color(String), Color(String),
} }
@@ -14,6 +16,7 @@ impl Display for EditorError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
EditorError::InvalidOperation(e) => write!(f, "Failed to execute operation: {}", e), 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::Misc(e) => write!(f, "{}", e),
EditorError::Color(c) => write!(f, "Tried to construct an invalid color {:?}", c), 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!(&str, Misc);
derive_from!(String, Misc); derive_from!(String, Misc);
derive_from!(Color, Color); derive_from!(Color, Color);
derive_from!(Event, InvalidEvent);
+14 -2
View File
@@ -1,6 +1,6 @@
mod color; mod color;
mod dispatcher;
mod error; mod error;
mod scheduler;
pub mod tools; pub mod tools;
pub mod workspace; pub mod workspace;
@@ -10,6 +10,13 @@ pub use error::EditorError;
#[doc(inline)] #[doc(inline)]
pub use color::Color; pub use color::Color;
#[doc(inline)]
pub use dispatcher::events;
#[doc(inline)]
pub use dispatcher::Callback;
use dispatcher::Dispatcher;
use tools::ToolState; use tools::ToolState;
use workspace::Workspace; use workspace::Workspace;
@@ -17,13 +24,18 @@ use workspace::Workspace;
pub struct Editor { pub struct Editor {
pub tools: ToolState, pub tools: ToolState,
workspace: Workspace, workspace: Workspace,
dispatcher: Dispatcher,
} }
impl Editor { impl Editor {
pub fn new() -> Self { pub fn new(callback: Callback) -> Self {
Self { Self {
tools: ToolState::new(), tools: ToolState::new(),
workspace: Workspace::new(), workspace: Workspace::new(),
dispatcher: Dispatcher::new(callback),
} }
} }
pub fn handle_event(&mut self, event: events::Event) -> Result<(), EditorError> {
self.dispatcher.handle_event(event)
}
} }
-1
View File
@@ -1 +0,0 @@
pub mod events;