Split mouse events according to the button pressed (#90)
This commit is contained in:
parent
3b32184906
commit
c5506c71b3
|
|
@ -7,7 +7,34 @@ use wasm_bindgen::prelude::*;
|
|||
fn convert_error(err: editor_core::EditorError) -> JsValue {
|
||||
Error::new(&err.to_string()).into()
|
||||
}
|
||||
mod mouse_state {
|
||||
pub(super) type MouseKeys = u8;
|
||||
use editor_core::events::{self, Event, MouseState, ViewportPosition};
|
||||
static mut MOUSE_STATE: MouseKeys = 0;
|
||||
|
||||
pub(super) fn translate_mouse_down(mod_keys: MouseKeys, position: ViewportPosition) -> Event {
|
||||
translate_mouse_event(mod_keys, position, true)
|
||||
}
|
||||
pub(super) fn translate_mouse_up(mod_keys: MouseKeys, position: ViewportPosition) -> Event {
|
||||
translate_mouse_event(mod_keys, position, false)
|
||||
}
|
||||
|
||||
fn translate_mouse_event(mod_keys: MouseKeys, position: ViewportPosition, down: bool) -> Event {
|
||||
let diff = unsafe { MOUSE_STATE } ^ mod_keys;
|
||||
unsafe { MOUSE_STATE = mod_keys };
|
||||
let mouse_keys = events::MouseKeys::from_bits(mod_keys).expect("invalid modifier keys");
|
||||
let state = MouseState { position, mouse_keys };
|
||||
match (down, diff) {
|
||||
(true, 1) => Event::LmbDown(state),
|
||||
(true, 2) => Event::RmbDown(state),
|
||||
(true, 4) => Event::MmbDown(state),
|
||||
(false, 1) => Event::LmbUp(state),
|
||||
(false, 2) => Event::RmbUp(state),
|
||||
(false, 4) => Event::MmbUp(state),
|
||||
_ => panic!("two buttons where modified at the same time. modification: {:#010b}", diff),
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Modify the currently selected tool in the document state store
|
||||
#[wasm_bindgen]
|
||||
pub fn select_tool(tool: String) -> Result<(), JsValue> {
|
||||
|
|
@ -30,11 +57,8 @@ pub fn on_mouse_move(x: u32, y: u32) -> Result<(), JsValue> {
|
|||
#[wasm_bindgen]
|
||||
pub fn on_mouse_down(x: u32, y: u32, mouse_keys: u8) -> Result<(), JsValue> {
|
||||
// TODO: Convert these screenspace viewport coordinates to canvas coordinates based on the current zoom and pan
|
||||
let mouse_keys = events::MouseKeys::from_bits(mouse_keys).expect("invalid modifier keys");
|
||||
let ev = events::Event::MouseDown(events::MouseState {
|
||||
position: events::ViewportPosition { x, y },
|
||||
mouse_keys,
|
||||
});
|
||||
let pos = events::ViewportPosition { x, y };
|
||||
let ev = mouse_state::translate_mouse_down(mouse_keys, pos);
|
||||
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_event(ev)).map_err(convert_error)
|
||||
}
|
||||
|
||||
|
|
@ -42,11 +66,8 @@ pub fn on_mouse_down(x: u32, y: u32, mouse_keys: u8) -> Result<(), JsValue> {
|
|||
#[wasm_bindgen]
|
||||
pub fn on_mouse_up(x: u32, y: u32, mouse_keys: u8) -> Result<(), JsValue> {
|
||||
// TODO: Convert these screenspace viewport coordinates to canvas coordinates based on the current zoom and pan
|
||||
let mouse_keys = events::MouseKeys::from_bits(mouse_keys).expect("invalid modifier keys");
|
||||
let ev = events::Event::MouseUp(events::MouseState {
|
||||
position: events::ViewportPosition { x, y },
|
||||
mouse_keys,
|
||||
});
|
||||
let pos = events::ViewportPosition { x, y };
|
||||
let ev = mouse_state::translate_mouse_up(mouse_keys, pos);
|
||||
EDITOR_STATE.with(|editor| editor.borrow_mut().handle_event(ev)).map_err(convert_error)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,12 @@ pub enum Event {
|
|||
SelectSecondaryColor(Color),
|
||||
SwapColors,
|
||||
ResetColors,
|
||||
MouseDown(MouseState),
|
||||
MouseUp(MouseState),
|
||||
LmbDown(MouseState),
|
||||
RmbDown(MouseState),
|
||||
MmbDown(MouseState),
|
||||
LmbUp(MouseState),
|
||||
RmbUp(MouseState),
|
||||
MmbUp(MouseState),
|
||||
MouseMove(ViewportPosition),
|
||||
KeyUp(Key),
|
||||
KeyDown(Key),
|
||||
|
|
|
|||
|
|
@ -30,16 +30,28 @@ impl Dispatcher {
|
|||
editor_state.tool_state.document_tool_data.primary_color = Color::BLACK;
|
||||
editor_state.tool_state.document_tool_data.secondary_color = Color::WHITE;
|
||||
}
|
||||
Event::MouseDown(mouse_state) => {
|
||||
Event::LmbDown(mouse_state) => {
|
||||
editor_state.tool_state.document_tool_data.mouse_state = *mouse_state;
|
||||
}
|
||||
Event::MouseUp(mouse_state) => {
|
||||
Event::RmbDown(mouse_state) => {
|
||||
editor_state.tool_state.document_tool_data.mouse_state = *mouse_state;
|
||||
}
|
||||
Event::MmbDown(mouse_state) => {
|
||||
editor_state.tool_state.document_tool_data.mouse_state = *mouse_state;
|
||||
}
|
||||
Event::LmbUp(mouse_state) => {
|
||||
editor_state.tool_state.document_tool_data.mouse_state = *mouse_state;
|
||||
}
|
||||
Event::RmbUp(mouse_state) => {
|
||||
editor_state.tool_state.document_tool_data.mouse_state = *mouse_state;
|
||||
}
|
||||
Event::MmbUp(mouse_state) => {
|
||||
editor_state.tool_state.document_tool_data.mouse_state = *mouse_state;
|
||||
}
|
||||
Event::MouseMove(pos) => {
|
||||
editor_state.tool_state.document_tool_data.mouse_state.position = *pos;
|
||||
}
|
||||
Event::KeyUp(key) => (),
|
||||
Event::KeyUp(_key) => (),
|
||||
Event::KeyDown(key) => {
|
||||
log::trace!("pressed key {:?}", key);
|
||||
log::debug!("pressed key {:?}", key);
|
||||
|
|
@ -102,7 +114,7 @@ impl Dispatcher {
|
|||
.handle_input(event, &editor_state.document, &editor_state.tool_state.document_tool_data);
|
||||
|
||||
self.dispatch_operations(&mut editor_state.document, operations);
|
||||
// TODO - Dispatch Responses
|
||||
self.dispatch_responses(responses);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -128,7 +140,6 @@ impl Dispatcher {
|
|||
|
||||
pub fn dispatch_response(&self, response: Response) {
|
||||
let func = &self.callback;
|
||||
// TODO - Remove clone if possible
|
||||
func(response)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::events::{Event, Response};
|
||||
use crate::events::{Key, MouseKeys, ViewportPosition};
|
||||
use crate::events::{Key, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
use document_core::layers::style;
|
||||
|
|
@ -42,9 +42,9 @@ struct EllipseToolData {
|
|||
impl Fsm for EllipseToolFsmState {
|
||||
type ToolData = EllipseToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(EllipseToolFsmState::Ready, Event::MouseDown(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => {
|
||||
(EllipseToolFsmState::Ready, Event::LmbDown(mouse_state)) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
operations.push(Operation::MountWorkingFolder { path: vec![] });
|
||||
EllipseToolFsmState::LmbDown
|
||||
|
|
@ -71,8 +71,7 @@ impl Fsm for EllipseToolFsmState {
|
|||
EllipseToolFsmState::LmbDown
|
||||
}
|
||||
|
||||
// TODO - Check for left mouse button
|
||||
(EllipseToolFsmState::LmbDown, Event::MouseUp(mouse_state)) => {
|
||||
(EllipseToolFsmState::LmbDown, Event::LmbUp(mouse_state)) => {
|
||||
let r = data.drag_start.distance(&mouse_state.position);
|
||||
log::info!("draw ellipse with radius: {:.2}", r);
|
||||
operations.push(Operation::ClearWorkingFolder);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::events::{Event, Response};
|
||||
use crate::events::{Key, MouseKeys, ViewportPosition};
|
||||
use crate::events::{Key, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
use document_core::layers::style;
|
||||
|
|
@ -42,9 +42,9 @@ struct LineToolData {
|
|||
impl Fsm for LineToolFsmState {
|
||||
type ToolData = LineToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(LineToolFsmState::Ready, Event::MouseDown(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => {
|
||||
(LineToolFsmState::Ready, Event::LmbDown(mouse_state)) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
operations.push(Operation::MountWorkingFolder { path: vec![] });
|
||||
LineToolFsmState::LmbDown
|
||||
|
|
@ -71,8 +71,7 @@ impl Fsm for LineToolFsmState {
|
|||
|
||||
LineToolFsmState::LmbDown
|
||||
}
|
||||
// TODO - Check for left mouse button
|
||||
(LineToolFsmState::LmbDown, Event::MouseUp(mouse_state)) => {
|
||||
(LineToolFsmState::LmbDown, Event::LmbUp(mouse_state)) => {
|
||||
let distance = data.drag_start.distance(&mouse_state.position);
|
||||
log::info!("draw Line with distance: {:.2}", distance);
|
||||
operations.push(Operation::ClearWorkingFolder);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::events::{Event, Response};
|
||||
use crate::events::{Key, MouseKeys, ViewportPosition};
|
||||
use crate::events::{Key, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ impl Fsm for PenToolFsmState {
|
|||
let style = style::PathStyle::new(Some(stroke), Some(fill));
|
||||
|
||||
match (self, event) {
|
||||
(PenToolFsmState::Ready, Event::MouseDown(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => {
|
||||
(PenToolFsmState::Ready, Event::LmbDown(mouse_state)) => {
|
||||
operations.push(Operation::MountWorkingFolder { path: vec![] });
|
||||
data.points.push(mouse_state.position);
|
||||
PenToolFsmState::LmbDown
|
||||
|
|
@ -60,8 +60,7 @@ impl Fsm for PenToolFsmState {
|
|||
}
|
||||
PenToolFsmState::Ready
|
||||
}
|
||||
// TODO - Check for left mouse button
|
||||
(PenToolFsmState::LmbDown, Event::MouseDown(mouse_state)) => {
|
||||
(PenToolFsmState::LmbDown, Event::LmbUp(mouse_state)) => {
|
||||
data.points.push(mouse_state.position);
|
||||
PenToolFsmState::LmbDown
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::events::{Event, Response};
|
||||
use crate::events::{Key, MouseKeys, ViewportPosition};
|
||||
use crate::events::{Key, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
use document_core::layers::style;
|
||||
|
|
@ -42,9 +42,9 @@ struct RectangleToolData {
|
|||
impl Fsm for RectangleToolFsmState {
|
||||
type ToolData = RectangleToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(RectangleToolFsmState::Ready, Event::MouseDown(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => {
|
||||
(RectangleToolFsmState::Ready, Event::LmbDown(mouse_state)) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
operations.push(Operation::MountWorkingFolder { path: vec![] });
|
||||
RectangleToolFsmState::LmbDown
|
||||
|
|
@ -71,8 +71,7 @@ impl Fsm for RectangleToolFsmState {
|
|||
|
||||
RectangleToolFsmState::LmbDown
|
||||
}
|
||||
// TODO - Check for left mouse button
|
||||
(RectangleToolFsmState::LmbDown, Event::MouseUp(mouse_state)) => {
|
||||
(RectangleToolFsmState::LmbDown, Event::LmbUp(mouse_state)) => {
|
||||
let r = data.drag_start.distance(&mouse_state.position);
|
||||
log::info!("draw rectangle with radius: {:.2}", r);
|
||||
operations.push(Operation::ClearWorkingFolder);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
use crate::events::MouseKeys;
|
||||
use crate::events::{Event, Response};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
|
|
@ -41,17 +40,17 @@ struct SelectToolData;
|
|||
impl Fsm for SelectToolFsmState {
|
||||
type ToolData = SelectToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
fn transition(self, event: &Event, _document: &Document, _tool_data: &DocumentToolData, _data: &mut Self::ToolData, _responses: &mut Vec<Response>, _operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(SelectToolFsmState::Ready, Event::MouseDown(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => SelectToolFsmState::LmbDown,
|
||||
(SelectToolFsmState::Ready, Event::LmbDown(_mouse_state)) => SelectToolFsmState::LmbDown,
|
||||
|
||||
(SelectToolFsmState::LmbDown, Event::MouseUp(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => SelectToolFsmState::Ready,
|
||||
(SelectToolFsmState::LmbDown, Event::LmbUp(_mouse_state)) => SelectToolFsmState::Ready,
|
||||
|
||||
(SelectToolFsmState::LmbDown, Event::MouseMove(mouse_state)) => SelectToolFsmState::TransformSelected,
|
||||
(SelectToolFsmState::LmbDown, Event::MouseMove(_mouse_state)) => SelectToolFsmState::TransformSelected,
|
||||
|
||||
(SelectToolFsmState::TransformSelected, Event::MouseMove(mouse_state)) => self,
|
||||
(SelectToolFsmState::TransformSelected, Event::MouseMove(_mouse_state)) => self,
|
||||
|
||||
(SelectToolFsmState::TransformSelected, Event::MouseUp(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => SelectToolFsmState::Ready,
|
||||
(SelectToolFsmState::TransformSelected, Event::LmbUp(_mouse_state)) => SelectToolFsmState::Ready,
|
||||
|
||||
_ => self,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use crate::events::{Event, Response};
|
||||
use crate::events::{Key, MouseKeys, ViewportPosition};
|
||||
use crate::events::{Key, ViewportPosition};
|
||||
use crate::tools::{Fsm, Tool};
|
||||
use crate::Document;
|
||||
use document_core::layers::style;
|
||||
|
|
@ -43,9 +43,9 @@ struct ShapeToolData {
|
|||
impl Fsm for ShapeToolFsmState {
|
||||
type ToolData = ShapeToolData;
|
||||
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
fn transition(self, event: &Event, document: &Document, tool_data: &DocumentToolData, data: &mut Self::ToolData, _responses: &mut Vec<Response>, operations: &mut Vec<Operation>) -> Self {
|
||||
match (self, event) {
|
||||
(ShapeToolFsmState::Ready, Event::MouseDown(mouse_state)) if mouse_state.mouse_keys.contains(MouseKeys::LEFT) => {
|
||||
(ShapeToolFsmState::Ready, Event::LmbDown(mouse_state)) => {
|
||||
data.drag_start = mouse_state.position;
|
||||
operations.push(Operation::MountWorkingFolder { path: vec![] });
|
||||
ShapeToolFsmState::LmbDown
|
||||
|
|
@ -73,15 +73,15 @@ impl Fsm for ShapeToolFsmState {
|
|||
|
||||
ShapeToolFsmState::LmbDown
|
||||
}
|
||||
// TODO - Check for left mouse button
|
||||
(ShapeToolFsmState::LmbDown, Event::MouseUp(mouse_state)) => {
|
||||
(ShapeToolFsmState::LmbDown, Event::LmbUp(mouse_state)) => {
|
||||
let r = data.drag_start.distance(&mouse_state.position);
|
||||
log::info!("Draw Shape with radius: {:.2}", r);
|
||||
|
||||
let start = data.drag_start;
|
||||
let end = mouse_state.position;
|
||||
// TODO: Set the sides value and use it for the operation.
|
||||
let sides = data.sides;
|
||||
// let sides = data.sides;
|
||||
let sides = 6;
|
||||
operations.push(Operation::ClearWorkingFolder);
|
||||
operations.push(Operation::AddShape {
|
||||
path: vec![],
|
||||
|
|
@ -90,7 +90,7 @@ impl Fsm for ShapeToolFsmState {
|
|||
y0: start.y as f64,
|
||||
x1: end.x as f64,
|
||||
y1: end.y as f64,
|
||||
sides: 6,
|
||||
sides,
|
||||
style: style::PathStyle::new(None, Some(style::Fill::new(tool_data.primary_color))),
|
||||
});
|
||||
operations.push(Operation::CommitTransaction);
|
||||
|
|
|
|||
Loading…
Reference in New Issue