Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Magic Leap URL bar #22066

Merged
merged 1 commit into from Nov 1, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -40,6 +40,7 @@ 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;

@@ -56,13 +57,22 @@ pub enum MLLogLevel {
#[repr(transparent)]
pub struct MLLogger(extern "C" fn (MLLogLevel, *const c_char));

#[repr(transparent)]
pub struct MLHistoryUpdate(extern "C" fn (MLApp, bool, *const c_char, bool));

#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct MLApp(*mut c_void);

const LOG_LEVEL: log::LevelFilter = log::LevelFilter::Info;

#[no_mangle]
pub unsafe extern "C" fn init_servo(ctxt: EGLContext,
surf: EGLSurface,
disp: EGLDisplay,
app: MLApp,
logger: MLLogger,
history_update: MLHistoryUpdate,
url: *const c_char,
width: u32,
height: u32,
@@ -100,7 +110,9 @@ pub unsafe extern "C" fn init_servo(ctxt: EGLContext,
]);

let result = Box::new(ServoInstance {
app: app,
browser_id: browser_id,
history_update: history_update,
servo: servo,
});
Box::into_raw(result)
@@ -130,10 +142,19 @@ pub unsafe extern "C" fn heartbeat_servo(servo: *mut ServoInstance) {
EmbedderMsg::AllowOpeningBrowser(sender) => {
let _ = sender.send(false);
},
// Update the history UI
EmbedderMsg::HistoryChanged(urls, index) => {
if let Some(url) = urls.get(index) {
if let Ok(cstr) = CString::new(url.as_str()) {
let can_go_back = index > 0;
let can_go_fwd = (index + 1) < urls.len();
(servo.history_update.0)(servo.app, can_go_back, cstr.as_ptr(), can_go_fwd);
}
}
},
// Ignore most messages for now
EmbedderMsg::ChangePageTitle(..) |
EmbedderMsg::BrowserCreated(..) |
EmbedderMsg::HistoryChanged(..) |
EmbedderMsg::LoadStart |
EmbedderMsg::LoadComplete |
EmbedderMsg::CloseBrowser |
@@ -184,6 +205,22 @@ pub unsafe extern "C" fn traverse_servo(servo: *mut ServoInstance, delta: i32) {
}
}

#[no_mangle]
pub unsafe extern "C" fn navigate_servo(servo: *mut ServoInstance, text: *const c_char) {
if let Some(servo) = servo.as_mut() {
let text = CStr::from_ptr(text).to_str().expect("Failed to convert text to UTF-8");
let url = ServoUrl::parse(text).unwrap_or_else(|_| {
let mut search = ServoUrl::parse("http://google.com/search")
.expect("Failed to parse search URL")
.into_url();
search.query_pairs_mut().append_pair("q", text);
ServoUrl::from_url(search)
});
let window_event = WindowEvent::LoadUrl(servo.browser_id, url);
servo.servo.handle_events(vec![window_event]);
}
}

#[no_mangle]
pub unsafe extern "C" fn discard_servo(servo: *mut ServoInstance) {
// Servo drop goes here!
@@ -193,7 +230,9 @@ pub unsafe extern "C" fn discard_servo(servo: *mut ServoInstance) {
}

pub struct ServoInstance {
app: MLApp,
browser_id: BrowserId,
history_update: MLHistoryUpdate,
servo: Servo<WindowInstance>,
}

@@ -9,6 +9,9 @@
#include <lumin/event/ControlTouchPadInputEventData.h>
#include <lumin/node/QuadNode.h>
#include <lumin/resource/PlanarResource.h>
#include <lumin/ui/KeyboardDefines.h>
#include <lumin/ui/node/UiButton.h>
#include <lumin/ui/node/UiTextEdit.h>
#include <SceneDescriptor.h>

typedef struct Opaque ServoInstance;
@@ -48,6 +51,11 @@ class Servo2D : public lumin::LandscapeApp {
*/
Servo2D& operator=(Servo2D&&) = delete;

/**
* Update the browser history UI
*/
void updateHistory(bool canGoBack, const char* url, bool canGoForward);

protected:
/**
* Initializes the Landscape Application.
@@ -93,6 +101,7 @@ class Servo2D : public lumin::LandscapeApp {
virtual bool eventListener(lumin::ServerEvent* event) override;
bool touchpadEventListener(lumin::ControlTouchPadInputEventData* event);
bool keyEventListener(lumin::KeyInputEventData* event);
void urlBarEventListener();

/**
* Get the current cursor position, with respect to the viewport.
@@ -104,5 +113,8 @@ class Servo2D : public lumin::LandscapeApp {
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
lumin::ui::UiButton* back_button_ = nullptr; // the back button
lumin::ui::UiButton* fwd_button_ = nullptr; // the forward button
lumin::ui::UiTextEdit* url_bar_ = nullptr; // the URL bar
ServoInstance* servo_ = nullptr; // the servo instance we're embedding
};
@@ -6,7 +6,6 @@
#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>
@@ -35,13 +34,20 @@ void logger(MLLogLevel lvl, char* msg) {
}
}

// A function which updates the history ui, suitable for passing into Servo
typedef void (*MLHistoryUpdate)(Servo2D* app, bool canGoBack, char* url, bool canGoForward);
void history(Servo2D* app, bool canGoBack, char* url, bool canGoForward) {
app->updateHistory(canGoBack, url, canGoForward);
}

// 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,
const char* url, int width, int height, float hidpi);
extern "C" ServoInstance* init_servo(EGLContext, EGLSurface, EGLDisplay,
Servo2D*, MLLogger, MLHistoryUpdate,
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 traverse_servo(ServoInstance*, int delta);
extern "C" void navigate_servo(ServoInstance*, const char* text);
extern "C" void discard_servo(ServoInstance*);

// Create a Servo2D instance
@@ -120,7 +126,7 @@ int Servo2D::init() {
EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);

// Hook into servo
servo_ = init_servo(ctx, surf, dpy, logger, "https://servo.org/", VIEWPORT_H, VIEWPORT_W, HIDPI);
servo_ = init_servo(ctx, surf, dpy, this, logger, history, "https://servo.org/", VIEWPORT_H, VIEWPORT_W, HIDPI);
if (!servo_) {
ML_LOG(Error, "Servo2D Failed to init servo instance");
abort();
@@ -129,24 +135,33 @@ int Servo2D::init() {

// 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) {
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));
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) {
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));
fwd_button_->onActivateSub(std::bind(traverse_servo, servo_, +1));

// Add a callback to the URL bar
std::string url_bar_id = Servo2D_exportedNodes::urlBar;
url_bar_ = lumin::ui::UiTextEdit::CastFrom(prism_->findNode(url_bar_id, root_node));
if (!url_bar_) {
ML_LOG(Error, "Servo2D Failed to get URL bar");
abort();
return 1;
}
url_bar_->onFocusLostSub(std::bind(&Servo2D::urlBarEventListener, this));
return 0;
}

@@ -268,3 +283,13 @@ bool Servo2D::keyEventListener(lumin::KeyInputEventData* event) {
cursor_servo(servo_, pos.x, pos.y, true);
return true;
}

void Servo2D::urlBarEventListener() {
navigate_servo(servo_, url_bar_->getText().c_str());
}

void Servo2D::updateHistory(bool canGoBack, const char* url, bool canGoForward) {
back_button_->setEnabled(canGoBack);
fwd_button_->setEnabled(canGoForward);
url_bar_->setText(url);
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.