Skip to content

Commit

Permalink
UWP: better mouse interaction support
Browse files Browse the repository at this point in the history
  • Loading branch information
paulrouget committed Oct 29, 2019
1 parent f78ca57 commit f2f8223
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 14 deletions.
2 changes: 1 addition & 1 deletion ports/libmlservo/src/lib.rs
Expand Up @@ -278,7 +278,7 @@ pub unsafe extern "C" fn trigger_servo(servo: *mut ServoInstance, x: f32, y: f32
ScrollState::TriggerDown(start) if !down => {
servo.scroll_state = ScrollState::TriggerUp;
let _ = call(|s| s.mouse_up(start.x, start.y, MouseButton::Left));
let _ = call(|s| s.click(start.x, start.y));
let _ = call(|s| s.click(start.x as f32, start.y as f32));
let _ = call(|s| s.move_mouse(start.x, start.y));
},
ScrollState::TriggerDragging(start, prev) if !down => {
Expand Down
41 changes: 38 additions & 3 deletions ports/libsimpleservo/capi/src/lib.rs
Expand Up @@ -15,7 +15,9 @@ use backtrace::Backtrace;
#[cfg(not(target_os = "windows"))]
use env_logger;
use simpleservo::{self, gl_glue, ServoGlue, SERVO};
use simpleservo::{Coordinates, EventLoopWaker, HostTrait, InitOptions, VRInitOptions};
use simpleservo::{
Coordinates, EventLoopWaker, HostTrait, InitOptions, MouseButton, VRInitOptions,
};
use std::ffi::{CStr, CString};
#[cfg(target_os = "windows")]
use std::mem;
Expand Down Expand Up @@ -227,6 +229,23 @@ pub struct CInitOptions {
pub vslogger_mod_size: u32,
}

#[repr(C)]
pub enum CMouseButton {
Left,
Right,
Middle,
}

impl CMouseButton {
pub fn convert(&self) -> MouseButton {
match self {
CMouseButton::Left => MouseButton::Left,
CMouseButton::Right => MouseButton::Right,
CMouseButton::Middle => MouseButton::Middle,
}
}
}

/// The returned string is not freed. This will leak.
#[no_mangle]
pub extern "C" fn servo_version() -> *const c_char {
Expand Down Expand Up @@ -529,10 +548,26 @@ pub extern "C" fn pinchzoom_end(factor: f32, x: i32, y: i32) {
}

#[no_mangle]
pub extern "C" fn click(x: i32, y: i32) {
pub extern "C" fn mouse_down(x: f32, y: f32, button: CMouseButton) {
catch_any_panic(|| {
debug!("mouse_down");
call(|s| s.mouse_down(x, y, button.convert()));
});
}

#[no_mangle]
pub extern "C" fn mouse_up(x: f32, y: f32, button: CMouseButton) {
catch_any_panic(|| {
debug!("mouse_up");
call(|s| s.mouse_up(x, y, button.convert()));
});
}

#[no_mangle]
pub extern "C" fn click(x: f32, y: f32) {
catch_any_panic(|| {
debug!("click");
call(|s| s.click(x as f32, y as f32));
call(|s| s.click(x, y));
});
}

Expand Down
Expand Up @@ -64,7 +64,7 @@ public class JNIServo {

public native void pinchZoomEnd(float factor, int x, int y);

public native void click(int x, int y);
public native void click(float x, float y);

public static class ServoOptions {
public String args;
Expand Down
Expand Up @@ -160,7 +160,7 @@ public void pinchZoomEnd(float factor, int x, int y) {
mRunCallback.inGLThread(() -> mJNI.pinchZoomEnd(factor, x, y));
}

public void click(int x, int y) {
public void click(float x, float y) {
mRunCallback.inGLThread(() -> mJNI.click(x, y));
}

Expand Down
Expand Up @@ -134,7 +134,7 @@ public void scrollEnd(int dx, int dy, int x, int y) {
mServo.scrollEnd(dx, dy, x, y);
}

public void click(int x, int y) {
public void click(float x, float y) {
mServo.click(x, y);
}

Expand Down
2 changes: 1 addition & 1 deletion support/hololens/ServoApp/DefaultUrl.h
@@ -1,3 +1,3 @@
#pragma once

#define DEFAULT_URL L"about:blank";
#define DEFAULT_URL L"http://paulrouget.com/test/bbjs/basic/";
11 changes: 10 additions & 1 deletion support/hololens/ServoApp/ServoControl/Servo.h
Expand Up @@ -47,13 +47,22 @@ class Servo {
~Servo();
ServoDelegate &Delegate() { return mDelegate; }

typedef capi::CMouseButton MouseButton;

void PerformUpdates() { capi::perform_updates(); }
void DeInit() { capi::deinit(); }
void RequestShutdown() { capi::request_shutdown(); }
void SetBatchMode(bool mode) { capi::set_batch_mode(mode); }
void GoForward() { capi::go_forward(); }
void GoBack() { capi::go_back(); }
void Click(float x, float y) { capi::click((int32_t)x, (int32_t)y); }
void Click(float x, float y) { capi::click(x, y); }
void MouseDown(float x, float y, capi::CMouseButton b) {
capi::mouse_down(x, y, b);
}
void MouseUp(float x, float y, capi::CMouseButton b) {
capi::mouse_up(x, y, b);
}

void Reload() { capi::reload(); }
void Stop() { capi::stop(); }
void LoadUri(hstring uri) { capi::load_uri(*hstring2char(uri)); }
Expand Down
46 changes: 42 additions & 4 deletions support/hololens/ServoApp/ServoControl/ServoControl.cpp
Expand Up @@ -36,8 +36,11 @@ void ServoControl::Shutdown() {

void ServoControl::OnLoaded(IInspectable const &, RoutedEventArgs const &) {
auto panel = Panel();
panel.Tapped(
std::bind(&ServoControl::OnSurfaceClicked, this, _1, _2));
panel.Tapped(std::bind(&ServoControl::OnSurfaceTapped, this, _1, _2));
panel.PointerPressed(
std::bind(&ServoControl::OnSurfacePointerPressed, this, _1, _2));
panel.PointerReleased(
std::bind(&ServoControl::OnSurfacePointerPressed, this, _1, _2));
panel.ManipulationStarted(
[=](IInspectable const &,
Input::ManipulationStartedRoutedEventArgs const &e) {
Expand Down Expand Up @@ -93,15 +96,50 @@ void ServoControl::OnSurfaceManipulationDelta(
e.Handled(true);
}

void ServoControl::OnSurfaceClicked(IInspectable const &,
Input::TappedRoutedEventArgs const &e) {
void ServoControl::OnSurfaceTapped(IInspectable const &,
Input::TappedRoutedEventArgs const &e) {
auto coords = e.GetPosition(Panel());
auto x = coords.X * mDPI;
auto y = coords.Y * mDPI;
RunOnGLThread([=] { mServo->Click(x, y); });
e.Handled(true);
}

void ServoControl::OnSurfacePointerPressed(
IInspectable const &, Input::PointerRoutedEventArgs const &e) {
if (e.Pointer().PointerDeviceType() ==
Windows::Devices::Input::PointerDeviceType::Mouse) {
auto point = e.GetCurrentPoint(Panel());

auto x = point.Position().X * mDPI;
auto y = point.Position().Y * mDPI;
auto props = point.Properties();
std::optional<Servo::MouseButton> button = {};

if (props.IsLeftButtonPressed()) {
button = Servo::MouseButton::Left;
} else if (props.IsRightButtonPressed()) {
button = Servo::MouseButton::Right;
} else if (props.IsMiddleButtonPressed()) {
button = Servo::MouseButton::Middle;
}

if (!button.has_value() && mPressedMouseButton.has_value()) {
auto releasedButton = *mPressedMouseButton;
mPressedMouseButton = {};
RunOnGLThread([=] { mServo->MouseUp(x, y, releasedButton); });
e.Handled(true);
}

if (button.has_value()) {
RunOnGLThread([=] { mServo->MouseDown(x, y, *button); });
e.Handled(true);
}

mPressedMouseButton = button;
}
}

void ServoControl::OnSurfaceResized(IInspectable const &,
SizeChangedEventArgs const &e) {
auto size = e.NewSize();
Expand Down
7 changes: 6 additions & 1 deletion support/hololens/ServoApp/ServoControl/ServoControl.h
Expand Up @@ -119,9 +119,12 @@ struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate {
}

void
OnSurfaceClicked(IInspectable const &,
OnSurfaceTapped(IInspectable const &,
Windows::UI::Xaml::Input::TappedRoutedEventArgs const &);

void OnSurfacePointerPressed(IInspectable const &,
Windows::UI::Xaml::Input::PointerRoutedEventArgs const &);

void OnSurfaceManipulationDelta(
IInspectable const &,
Windows::UI::Xaml::Input::ManipulationDeltaRoutedEventArgs const &);
Expand All @@ -142,6 +145,8 @@ struct ServoControl : ServoControlT<ServoControl>, public servo::ServoDelegate {
CONDITION_VARIABLE mGLCondVar;
std::unique_ptr<Concurrency::task<void>> mLoopTask;
hstring mArgs;

std::optional<servo::Servo::MouseButton> mPressedMouseButton = {};
};
} // namespace winrt::ServoApp::implementation

Expand Down

0 comments on commit f2f8223

Please sign in to comment.