mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Hook up the back and forward buttons to history traversal in Magic Leap Servo2D
This commit is contained in:
parent
4ead81717a
commit
c8fa64b93a
3 changed files with 67 additions and 25 deletions
|
@ -24,7 +24,6 @@ use servo::embedder_traits::EmbedderMsg;
|
|||
use servo::embedder_traits::EventLoopWaker;
|
||||
use servo::embedder_traits::resources::Resource;
|
||||
use servo::embedder_traits::resources::ResourceReaderMethods;
|
||||
use servo::euclid::Length;
|
||||
use servo::euclid::TypedPoint2D;
|
||||
use servo::euclid::TypedRect;
|
||||
use servo::euclid::TypedScale;
|
||||
|
@ -32,21 +31,18 @@ use servo::euclid::TypedSize2D;
|
|||
use servo::gl;
|
||||
use servo::gl::Gl;
|
||||
use servo::gl::GlesFns;
|
||||
use servo::msg::constellation_msg::TraversalDirection;
|
||||
use servo::script_traits::MouseButton;
|
||||
use servo::servo_url::ServoUrl;
|
||||
use servo::style_traits::DevicePixel;
|
||||
use servo::webrender_api::DevicePoint;
|
||||
use smallvec::SmallVec;
|
||||
use std::ffi::CStr;
|
||||
use std::ffi::CString;
|
||||
use std::io::Write;
|
||||
use std::os::raw::c_char;
|
||||
use std::os::raw::c_void;
|
||||
use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
|
||||
type ServoInstance = *mut c_void;
|
||||
|
||||
#[repr(u32)]
|
||||
pub enum MLLogLevel {
|
||||
Fatal = 0,
|
||||
|
@ -70,7 +66,7 @@ pub unsafe extern "C" fn init_servo(ctxt: EGLContext,
|
|||
url: *const c_char,
|
||||
width: u32,
|
||||
height: u32,
|
||||
hidpi: f32) -> ServoInstance
|
||||
hidpi: f32) -> *mut ServoInstance
|
||||
{
|
||||
// Servo initialization goes here!
|
||||
servo::embedder_traits::resources::set(Box::new(ResourceReaderInstance::new()));
|
||||
|
@ -93,9 +89,9 @@ pub unsafe extern "C" fn init_servo(ctxt: EGLContext,
|
|||
});
|
||||
|
||||
info!("Starting servo");
|
||||
let mut servo = Box::new(Servo::new(window));
|
||||
|
||||
let mut servo = Servo::new(window);
|
||||
let browser_id = BrowserId::new();
|
||||
|
||||
let blank_url = ServoUrl::parse("about:blank").expect("Failed to parse about:blank!");
|
||||
let url = CStr::from_ptr(url).to_str().unwrap_or("about:blank");
|
||||
let url = ServoUrl::parse(url).unwrap_or(blank_url);
|
||||
|
@ -103,15 +99,19 @@ pub unsafe extern "C" fn init_servo(ctxt: EGLContext,
|
|||
WindowEvent::NewBrowser(url, browser_id),
|
||||
]);
|
||||
|
||||
Box::into_raw(servo) as ServoInstance
|
||||
let result = Box::new(ServoInstance {
|
||||
browser_id: browser_id,
|
||||
servo: servo,
|
||||
});
|
||||
Box::into_raw(result)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn heartbeat_servo(servo: ServoInstance) {
|
||||
pub unsafe extern "C" fn heartbeat_servo(servo: *mut ServoInstance) {
|
||||
// Servo heartbeat goes here!
|
||||
if let Some(servo) = (servo as *mut Servo<WindowInstance>).as_mut() {
|
||||
servo.handle_events(vec![]);
|
||||
for ((_browser_id, event)) in servo.get_events() {
|
||||
if let Some(servo) = servo.as_mut() {
|
||||
servo.servo.handle_events(vec![]);
|
||||
for ((_browser_id, event)) in servo.servo.get_events() {
|
||||
match event {
|
||||
// Respond to any messages with a response channel
|
||||
// to avoid deadlocking the constellation
|
||||
|
@ -156,27 +156,47 @@ pub unsafe extern "C" fn heartbeat_servo(servo: ServoInstance) {
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn cursor_servo(servo: ServoInstance, x: f32, y: f32, trigger: bool) {
|
||||
pub unsafe extern "C" fn cursor_servo(servo: *mut ServoInstance, x: f32, y: f32, trigger: bool) {
|
||||
// Servo was triggered
|
||||
if let Some(servo) = (servo as *mut Servo<WindowInstance>).as_mut() {
|
||||
if let Some(servo) = servo.as_mut() {
|
||||
let point = DevicePoint::new(x, y);
|
||||
let window_event = if trigger {
|
||||
WindowEvent::MouseWindowEventClass(MouseWindowEvent::Click(MouseButton::Left, point))
|
||||
} else {
|
||||
WindowEvent::MouseWindowMoveEventClass(point)
|
||||
};
|
||||
servo.handle_events(vec![window_event]);
|
||||
servo.servo.handle_events(vec![window_event]);
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn discard_servo(servo: ServoInstance) {
|
||||
pub unsafe extern "C" fn traverse_servo(servo: *mut ServoInstance, delta: i32) {
|
||||
// Traverse the session history
|
||||
if let Some(servo) = servo.as_mut() {
|
||||
let window_event = if delta == 0 {
|
||||
WindowEvent::Reload(servo.browser_id)
|
||||
} else if delta < 0 {
|
||||
WindowEvent::Navigation(servo.browser_id, TraversalDirection::Back(-delta as usize))
|
||||
} else {
|
||||
WindowEvent::Navigation(servo.browser_id, TraversalDirection::Forward(delta as usize))
|
||||
};
|
||||
servo.servo.handle_events(vec![window_event]);
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn discard_servo(servo: *mut ServoInstance) {
|
||||
// Servo drop goes here!
|
||||
if !servo.is_null() {
|
||||
Box::from_raw(servo as *mut Servo<WindowInstance>);
|
||||
Box::from_raw(servo);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ServoInstance {
|
||||
browser_id: BrowserId,
|
||||
servo: Servo<WindowInstance>,
|
||||
}
|
||||
|
||||
struct WindowInstance {
|
||||
ctxt: EGLContext,
|
||||
surf: EGLSurface,
|
||||
|
@ -192,7 +212,7 @@ impl WindowMethods for WindowInstance {
|
|||
SwapBuffers(self.disp, self.surf);
|
||||
}
|
||||
|
||||
fn prepare_for_composite(&self, _w: Length<u32, DevicePixel>, _h: Length<u32, DevicePixel>) -> bool {
|
||||
fn prepare_for_composite(&self) -> bool {
|
||||
MakeCurrent(self.disp, self.surf, self.surf, self.ctxt);
|
||||
self.gl.viewport(0, 0, self.width as i32, self.height as i32);
|
||||
true
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include <lumin/resource/PlanarResource.h>
|
||||
#include <SceneDescriptor.h>
|
||||
|
||||
typedef void* ServoInstance;
|
||||
typedef struct Opaque ServoInstance;
|
||||
|
||||
/**
|
||||
* Servo2D Landscape Application
|
||||
|
@ -104,5 +104,5 @@ private:
|
|||
lumin::Prism* prism_ = nullptr; // represents the bounded space where the App renders.
|
||||
lumin::PlanarResource* plane_ = nullptr; // the plane we're rendering into
|
||||
lumin::QuadNode* content_node_ = nullptr; // the node containing the plane
|
||||
ServoInstance servo_ = nullptr; // the servo instance we're embedding
|
||||
ServoInstance* servo_ = nullptr; // the servo instance we're embedding
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <lumin/node/RootNode.h>
|
||||
#include <lumin/node/QuadNode.h>
|
||||
#include <lumin/ui/Cursor.h>
|
||||
#include <lumin/ui/node/UiButton.h>
|
||||
#include <ml_logging.h>
|
||||
#include <scenesGen.h>
|
||||
#include <SceneDescriptor.h>
|
||||
|
@ -36,11 +37,12 @@ void logger(MLLogLevel lvl, char* msg) {
|
|||
|
||||
// The functions Servo provides for hooking up to the ML.
|
||||
// For the moment, this doesn't handle input events.
|
||||
extern "C" ServoInstance init_servo(EGLContext, EGLSurface, EGLDisplay, MLLogger,
|
||||
extern "C" ServoInstance* init_servo(EGLContext, EGLSurface, EGLDisplay, MLLogger,
|
||||
const char* url, int width, int height, float hidpi);
|
||||
extern "C" void heartbeat_servo(ServoInstance);
|
||||
extern "C" void cursor_servo(ServoInstance, float x, float y, bool triggered);
|
||||
extern "C" void discard_servo(ServoInstance);
|
||||
extern "C" void heartbeat_servo(ServoInstance*);
|
||||
extern "C" void cursor_servo(ServoInstance*, float x, float y, bool triggered);
|
||||
extern "C" void traverse_servo(ServoInstance*, int delta);
|
||||
extern "C" void discard_servo(ServoInstance*);
|
||||
|
||||
// Create a Servo2D instance
|
||||
Servo2D::Servo2D() {
|
||||
|
@ -125,6 +127,26 @@ int Servo2D::init() {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// Add a callback to the back button
|
||||
std::string back_button_id = Servo2D_exportedNodes::backButton;
|
||||
lumin::ui::UiButton* back_button = lumin::ui::UiButton::CastFrom(prism_->findNode(back_button_id, root_node));
|
||||
if (!back_button) {
|
||||
ML_LOG(Error, "Servo2D Failed to get back button");
|
||||
abort();
|
||||
return 1;
|
||||
}
|
||||
back_button->onActivateSub(std::bind(traverse_servo, servo_, -1));
|
||||
|
||||
// Add a callback to the forward button
|
||||
std::string fwd_button_id = Servo2D_exportedNodes::fwdButton;
|
||||
lumin::ui::UiButton* fwd_button = lumin::ui::UiButton::CastFrom(prism_->findNode(fwd_button_id, root_node));
|
||||
if (!fwd_button) {
|
||||
ML_LOG(Error, "Servo2D Failed to get forward button");
|
||||
abort();
|
||||
return 1;
|
||||
}
|
||||
fwd_button->onActivateSub(std::bind(traverse_servo, servo_, +1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue