mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-03 04:52:16 +00:00
Implement event/response roundtrip (#49)
This commit is contained in:
parent
a5d85812ce
commit
b6d4baa513
9 changed files with 112 additions and 26 deletions
|
@ -12,7 +12,7 @@
|
|||
</LayoutRow>
|
||||
<LayoutRow :class="'tools-and-viewport'">
|
||||
<LayoutCol :class="'tools'"></LayoutCol>
|
||||
<LayoutCol :class="'viewport-container'"></LayoutCol>
|
||||
<LayoutCol :class="'viewport-container'" @click="canvasClick"></LayoutCol>
|
||||
</LayoutRow>
|
||||
</LayoutCol>
|
||||
</template>
|
||||
|
@ -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);
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
3
client/web/src/wasm-callback-processor.js
Normal file
3
client/web/src/wasm-callback-processor.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export function update_canvas() {
|
||||
console.log("update_canvas")
|
||||
}
|
|
@ -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<Editor> = RefCell::new(Editor::new())}
|
||||
thread_local! {pub static EDITOR_STATE: RefCell<Editor> = 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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -11,25 +11,45 @@ pub enum Event {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Trace(Vec<MouseState>);
|
||||
#[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<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,
|
||||
}
|
||||
|
||||
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,
|
24
core/editor/src/dispatcher/mod.rs
Normal file
24
core/editor/src/dispatcher/mod.rs
Normal 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 }
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
pub mod events;
|
Loading…
Add table
Add a link
Reference in a new issue