Commit 12719f45 authored by Florian Blasius's avatar Florian Blasius 🤘

mouse relative event

parent c7266277
Pipeline #9139 passed with stage
in 1 minute and 12 seconds
......@@ -109,9 +109,9 @@ pub fn start() {
// testing PartialEq for Color
if Color::rgb(11, 2, 3) == Color::rgba(1, 2, 3, 100) {
println!("Testing colors: they are the same!")
log("Testing colors: they are the same!")
} else {
println!("Testing colors: they are NOT the same!")
log("Testing colors: they are NOT the same!")
}
//Draw a transparent rectangle over window content
......
......@@ -45,7 +45,7 @@ pub struct Window {
/// Drawing mode
mode: Cell<Mode>,
/// Mouse in relative mode
mouse_relative: bool,
mouse_relative: Rc<RefCell<bool>>,
/// Content of the last drop (file | text) operation
drop_content: RefCell<Option<String>>,
/// inner frame buffer
......@@ -158,181 +158,9 @@ impl Window {
let events = Rc::new(RefCell::new(vec![]));
let button_state = Rc::new(RefCell::new((false, false, false)));
let mouse_relative = Rc::new(RefCell::new(false));
// mouse event
{
let events = events.clone();
let canvas_clone = canvas.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::MouseEvent| {
events.borrow_mut().push(
MouseEvent {
x: e.client_x() - canvas_clone.get_bounding_client_rect().x() as i32,
y: e.client_y() - canvas_clone.get_bounding_client_rect().y() as i32,
}
.to_event(),
);
}) as Box<dyn FnMut(_)>);
canvas
.add_event_listener_with_callback("mousemove", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// mouse down
{
let events = events.clone();
let button_state = button_state.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::MouseEvent| {
*button_state.borrow_mut() =
(e.button() == 0, e.button() == 1, e.button() == 2);
events.borrow_mut().push(
ButtonEvent {
left: e.button() == 0,
middle: e.button() == 1,
right: e.button() == 2,
}
.to_event(),
);
}) as Box<dyn FnMut(_)>);
canvas
.add_event_listener_with_callback("mousedown", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// mouse up
{
let events = events.clone();
let button_state = button_state.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::MouseEvent| {
*button_state.borrow_mut() = (
!e.button() == 0 && button_state.borrow().0,
!e.button() == 1 && button_state.borrow().1,
!e.button() == 2 && button_state.borrow().2,
);
events.borrow_mut().push(
ButtonEvent {
left: button_state.borrow().0,
middle: button_state.borrow().1,
right: button_state.borrow().2,
}
.to_event(),
);
}) as Box<dyn FnMut(_)>);
canvas
.add_event_listener_with_callback("mouseup", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// key down and text input
{
let events = events.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::KeyboardEvent| {
// need to check len of key to prevent keys like `Shift` or `Backspace` are handled as text input
if !e.repeat() && e.key().len() <= 2 {
events.borrow_mut().push(
TextInputEvent {
character: e.key().chars().nth(0).unwrap(),
}
.to_event(),
);
}
if let Some(code) = convert_code(e.code(), e.shift_key()) {
events.borrow_mut().push(
KeyEvent {
character: code.0,
scancode: code.1,
pressed: true,
}
.to_event(),
);
}
}) as Box<dyn FnMut(_)>);
document()
.unwrap()
.add_event_listener_with_callback("keydown", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// key up
{
let events = events.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::KeyboardEvent| {
if let Some(code) = convert_code(e.code(), e.shift_key()) {
events.borrow_mut().push(
KeyEvent {
character: code.0,
scancode: code.1,
pressed: false,
}
.to_event(),
);
}
}) as Box<dyn FnMut(_)>);
document()
.unwrap()
.add_event_listener_with_callback("keyup", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// wheel (scroll)
{
let events = events.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::WheelEvent| {
events.borrow_mut().push(
ScrollEvent {
x: e.delta_x() as i32,
y: e.delta_y() as i32,
}
.to_event(),
)
}) as Box<dyn FnMut(_)>);
document()
.unwrap()
.add_event_listener_with_callback("wheel", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// focus
{
let events = events.clone();
let closure = Closure::wrap(Box::new(move |_: web_sys::FocusEvent| {
events
.borrow_mut()
.push(FocusEvent { focused: true }.to_event())
}) as Box<dyn FnMut(_)>);
document()
.unwrap()
.add_event_listener_with_callback("focus", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// blur
{
let events = events.clone();
let closure = Closure::wrap(Box::new(move |_: web_sys::FocusEvent| {
events
.borrow_mut()
.push(FocusEvent { focused: false }.to_event())
}) as Box<dyn FnMut(_)>);
document()
.unwrap()
.add_event_listener_with_callback("blur", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
connect_event_handlers(mouse_relative.clone(), &canvas, &events, &button_state);
if let Ok(context) = context_2d(&canvas) {
return Some(Window {
......@@ -343,7 +171,7 @@ impl Window {
t: title.to_string(),
window_async: false,
mode: Cell::new(Mode::Blend),
mouse_relative: false,
mouse_relative,
drop_content: RefCell::new(None),
data: vec![Color::rgb(255, 255, 255); (w * h * 4) as usize],
canvas,
......@@ -407,7 +235,7 @@ impl Window {
/// Set mouse relative mode
pub fn set_mouse_relative(&mut self, relative: bool) {
self.mouse_relative = relative;
*self.mouse_relative.borrow_mut() = relative;
}
/// Set position
......@@ -582,6 +410,8 @@ fn convert_code(code: String, shift: bool) -> Option<(char, u8)> {
}
}
// Helpers
/// Gets the browser window.
pub fn window() -> Result<WebWindow, String> {
web_sys::window().ok_or("body: no global `windows` exists.".to_string())
......@@ -662,3 +492,194 @@ pub fn animation_loop<R: FnMut() -> bool + 'static>(mut run: R) {
}) as Box<dyn FnMut()>));
request_animation_frame(g.borrow().as_ref().unwrap());
}
// connect web event handlers and pushes OrbClient events
fn connect_event_handlers(
mouse_relative: Rc<RefCell<bool>>,
canvas: &HtmlCanvasElement,
events: &Rc<RefCell<Vec<Event>>>,
button_state: &Rc<RefCell<(bool, bool, bool)>>,
) {
// mouse event
{
let events = events.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::MouseEvent| {
if *mouse_relative.borrow() {
events.borrow_mut().push(
MouseEvent {
x: e.movement_x(),
y: e.movement_y(),
}
.to_event(),
);
} else {
events.borrow_mut().push(
MouseEvent {
x: e.offset_x(),
y: e.offset_y(),
}
.to_event(),
);
}
}) as Box<dyn FnMut(_)>);
canvas
.add_event_listener_with_callback("mousemove", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// mouse down
{
let events = events.clone();
let button_state = button_state.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::MouseEvent| {
*button_state.borrow_mut() = (e.button() == 0, e.button() == 1, e.button() == 2);
events.borrow_mut().push(
ButtonEvent {
left: e.button() == 0,
middle: e.button() == 1,
right: e.button() == 2,
}
.to_event(),
);
}) as Box<dyn FnMut(_)>);
canvas
.add_event_listener_with_callback("mousedown", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// mouse up
{
let events = events.clone();
let button_state = button_state.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::MouseEvent| {
*button_state.borrow_mut() = (
!e.button() == 0 && button_state.borrow().0,
!e.button() == 1 && button_state.borrow().1,
!e.button() == 2 && button_state.borrow().2,
);
events.borrow_mut().push(
ButtonEvent {
left: button_state.borrow().0,
middle: button_state.borrow().1,
right: button_state.borrow().2,
}
.to_event(),
);
}) as Box<dyn FnMut(_)>);
canvas
.add_event_listener_with_callback("mouseup", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// key down and text input
{
let events = events.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::KeyboardEvent| {
// need to check len of key to prevent keys like `Shift` or `Backspace` are handled as text input
if !e.repeat() && e.key().len() <= 2 {
events.borrow_mut().push(
TextInputEvent {
character: e.key().chars().nth(0).unwrap(),
}
.to_event(),
);
}
if let Some(code) = convert_code(e.code(), e.shift_key()) {
events.borrow_mut().push(
KeyEvent {
character: code.0,
scancode: code.1,
pressed: true,
}
.to_event(),
);
}
}) as Box<dyn FnMut(_)>);
document()
.unwrap()
.add_event_listener_with_callback("keydown", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// key up
{
let events = events.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::KeyboardEvent| {
if let Some(code) = convert_code(e.code(), e.shift_key()) {
events.borrow_mut().push(
KeyEvent {
character: code.0,
scancode: code.1,
pressed: false,
}
.to_event(),
);
}
}) as Box<dyn FnMut(_)>);
document()
.unwrap()
.add_event_listener_with_callback("keyup", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// wheel (scroll)
{
let events = events.clone();
let closure = Closure::wrap(Box::new(move |e: web_sys::WheelEvent| {
events.borrow_mut().push(
ScrollEvent {
x: e.delta_x() as i32,
y: e.delta_y() as i32,
}
.to_event(),
)
}) as Box<dyn FnMut(_)>);
document()
.unwrap()
.add_event_listener_with_callback("wheel", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// focus
{
let events = events.clone();
let closure = Closure::wrap(Box::new(move |_: web_sys::FocusEvent| {
events
.borrow_mut()
.push(FocusEvent { focused: true }.to_event())
}) as Box<dyn FnMut(_)>);
document()
.unwrap()
.add_event_listener_with_callback("focus", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
// blur
{
let events = events.clone();
let closure = Closure::wrap(Box::new(move |_: web_sys::FocusEvent| {
events
.borrow_mut()
.push(FocusEvent { focused: false }.to_event())
}) as Box<dyn FnMut(_)>);
document()
.unwrap()
.add_event_listener_with_callback("blur", closure.as_ref().unchecked_ref())
.unwrap();
closure.forget();
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment