Skip to content

Commit

Permalink
Get the Servo2D URL bar to show the current URL, and to navigate when…
Browse files Browse the repository at this point in the history
… edited.
  • Loading branch information
Alan Jeffrey committed Oct 31, 2018
1 parent 4c5a3c0 commit c2f3370
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 12 deletions.
41 changes: 40 additions & 1 deletion ports/libmlservo/src/lib.rs
Expand Up @@ -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;

Expand All @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 |
Expand Down Expand Up @@ -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!
Expand All @@ -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>,
}

Expand Down
12 changes: 12 additions & 0 deletions support/magicleap/Servo2D/code/inc/Servo2D.h
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand All @@ -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
};
47 changes: 36 additions & 11 deletions support/magicleap/Servo2D/code/src/Servo2D.cpp
Expand Up @@ -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>
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
}

0 comments on commit c2f3370

Please sign in to comment.