mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-28 17:38:12 +08:00
Implement event/response roundtrip (#49)
This commit is contained in:
@@ -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")
|
||||||
|
}
|
||||||
@@ -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]
|
||||||
|
|||||||
@@ -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,
|
||||||
@@ -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 }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
@@ -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 +0,0 @@
|
|||||||
pub mod events;
|
|
||||||
Reference in New Issue
Block a user