| Index: chrome/browser/resources/vr_shell/vr_shell_ui.js
|
| diff --git a/chrome/browser/resources/vr_shell/vr_shell_ui.js b/chrome/browser/resources/vr_shell/vr_shell_ui.js
|
| index ab078f0afd4f6734cf620ae071b223a30dcb18db..d0107ef646314d321c90f62e5def1bba9b6c1abd 100644
|
| --- a/chrome/browser/resources/vr_shell/vr_shell_ui.js
|
| +++ b/chrome/browser/resources/vr_shell/vr_shell_ui.js
|
| @@ -47,6 +47,34 @@ var vrShellUi = (function() {
|
| ui.updateElement(this.elementId, update);
|
| }
|
|
|
| + setMenuMode(enabled) {
|
| + if (enabled) {
|
| + var opacity = 0.5;
|
| + var x = 0;
|
| + var y = 0.1;
|
| + var z = -1.2;
|
| + var height = 0.5;
|
| + var width = height * this.SCREEN_RATIO;
|
| + } else {
|
| + var opacity = 1;
|
| + var x = 0;
|
| + var y = 0;
|
| + var z = -this.BROWSING_SCREEN_DISTANCE;
|
| + var width = this.SCREEN_HEIGHT * this.SCREEN_RATIO;
|
| + var height = this.SCREEN_HEIGHT;
|
| + }
|
| + let anim;
|
| + anim = new api.Animation(this.elementId, 300);
|
| + anim.setTranslation(x, y, z);
|
| + ui.addAnimation(anim);
|
| + anim = new api.Animation(this.elementId, 300);
|
| + anim.setSize(width, height);
|
| + ui.addAnimation(anim);
|
| + anim = new api.Animation(this.elementId, 300);
|
| + anim.setOpacity(opacity);
|
| + ui.addAnimation(anim);
|
| + }
|
| +
|
| setFullscreen(enabled) {
|
| let anim = new api.Animation(this.elementId, ANIM_DURATION);
|
| if (enabled) {
|
| @@ -129,38 +157,43 @@ var vrShellUi = (function() {
|
| class Controls {
|
| constructor(contentQuadId) {
|
| this.enabled = false;
|
| - this.reloadUiEnabled = false;
|
|
|
| this.buttons = [];
|
| let descriptors = [
|
| [
|
| '#back',
|
| function() {
|
| - api.doAction(api.Action.HISTORY_BACK);
|
| + api.doAction(api.Action.HISTORY_BACK, {});
|
| }
|
| ],
|
| [
|
| '#reload',
|
| function() {
|
| - api.doAction(api.Action.RELOAD);
|
| + api.doAction(api.Action.RELOAD, {});
|
| }
|
| ],
|
| [
|
| '#forward',
|
| function() {
|
| - api.doAction(api.Action.HISTORY_FORWARD);
|
| + api.doAction(api.Action.HISTORY_FORWARD, {});
|
| }
|
| ],
|
| ];
|
|
|
| - /** @const */ var BUTTON_SPACING = 0.136;
|
| + this.translationX = 0;
|
| + this.translationY = -0.27;
|
| + this.translationZ = -1;
|
| +
|
| + /** @const */ var BUTTON_SPACING = 0.11;
|
|
|
| - let startPosition = -BUTTON_SPACING * (descriptors.length / 2.0 - 0.5);
|
| + let startPosition =
|
| + this.translationX - BUTTON_SPACING * (descriptors.length / 2.0 - 0.5);
|
| for (let i = 0; i < descriptors.length; i++) {
|
| // Use an invisible parent to simplify Z-axis movement on hover.
|
| let position = new api.UiElement(0, 0, 0, 0);
|
| position.setVisible(false);
|
| - position.setTranslation(startPosition + i * BUTTON_SPACING, -0.68, -1);
|
| + position.setTranslation(startPosition + i * BUTTON_SPACING,
|
| + this.translationY, this.translationZ);
|
| let id = ui.addElement(position);
|
|
|
| let domId = descriptors[i][0];
|
| @@ -173,41 +206,58 @@ var vrShellUi = (function() {
|
| update.setVisible(false);
|
| ui.updateElement(element.uiElementId, update);
|
| }
|
| + }
|
| +
|
| + setEnabled(enabled) {
|
| + this.enabled = enabled;
|
| + this.configure();
|
| + }
|
| +
|
| + configure() {
|
| + for (let i = 0; i < this.buttons.length; i++) {
|
| + let update = new api.UiElementUpdate();
|
| + update.setVisible(this.enabled);
|
| + ui.updateElement(this.buttons[i].uiElementId, update);
|
| + }
|
| + }
|
| + };
|
|
|
| - this.reloadUiButton = new DomUiElement('#reload-ui-button');
|
| - this.reloadUiButton.domElement.addEventListener('click', function() {
|
| + /**
|
| + * A button to trigger a reload of the HTML UI for development purposes.
|
| + */
|
| + class ReloadUiButton {
|
| + constructor() {
|
| + this.enabled = false;
|
| + this.devMode = false;
|
| +
|
| + this.uiElement = new DomUiElement('#reload-ui-button');
|
| + this.uiElement.domElement.addEventListener('click', function() {
|
| ui.purge();
|
| - api.doAction(api.Action.RELOAD_UI);
|
| + api.doAction(api.Action.RELOAD_UI, {});
|
| });
|
|
|
| let update = new api.UiElementUpdate();
|
| - update.setParentId(contentQuadId);
|
| update.setVisible(false);
|
| - update.setScale(2.2, 2.2, 1);
|
| - update.setTranslation(0, -0.6, 0.3);
|
| - update.setAnchoring(api.XAnchoring.XNONE, api.YAnchoring.YBOTTOM);
|
| - ui.updateElement(this.reloadUiButton.uiElementId, update);
|
| + update.setSize(0.5, 0.2, 1);
|
| + update.setTranslation(0, -2, -1);
|
| + update.setRotation(1, 0, 0, -0.8);
|
| + ui.updateElement(this.uiElement.uiElementId, update);
|
| }
|
|
|
| setEnabled(enabled) {
|
| this.enabled = enabled;
|
| - this.configure();
|
| + this.updateState();
|
| }
|
|
|
| - setReloadUiEnabled(enabled) {
|
| - this.reloadUiEnabled = enabled;
|
| - this.configure();
|
| + setDevMode(enabled) {
|
| + this.devMode = enabled;
|
| + this.updateState();
|
| }
|
|
|
| - configure() {
|
| - for (let i = 0; i < this.buttons.length; i++) {
|
| - let update = new api.UiElementUpdate();
|
| - update.setVisible(this.enabled);
|
| - ui.updateElement(this.buttons[i].uiElementId, update);
|
| - }
|
| + updateState() {
|
| let update = new api.UiElementUpdate();
|
| - update.setVisible(this.enabled && this.reloadUiEnabled);
|
| - ui.updateElement(this.reloadUiButton.uiElementId, update);
|
| + update.setVisible(this.enabled && this.devMode);
|
| + ui.updateElement(this.uiElement.uiElementId, update);
|
| }
|
| };
|
|
|
| @@ -355,8 +405,8 @@ var vrShellUi = (function() {
|
|
|
| setURL(host, path) {
|
| let indicator = this.domUiElement.domElement;
|
| - indicator.querySelector('#domain').innerHTML = host;
|
| - indicator.querySelector('#path').innerHTML = path;
|
| + indicator.querySelector('#domain').textContent = host;
|
| + indicator.querySelector('#path').textContent = path;
|
| this.resetVisibilityTimer();
|
| this.updateState();
|
| }
|
| @@ -454,6 +504,112 @@ var vrShellUi = (function() {
|
| }
|
| };
|
|
|
| + class Omnibox {
|
| + constructor(uiDelegate) {
|
| + this.enabled = false;
|
| + this.uiDelegate = uiDelegate;
|
| +
|
| + this.domUiElement = new DomUiElement('#omnibox-ui-element');
|
| + let root = this.domUiElement.domElement;
|
| + this.inputField = root.querySelector('#omnibox-input-field');
|
| +
|
| + // Initially invisible.
|
| + let update = new api.UiElementUpdate();
|
| + update.setVisible(true);
|
| + //update.setTranslation(0, 0, -1);
|
| + ui.updateElement(this.domUiElement.uiElementId, update);
|
| +
|
| + // Field-clearing button.
|
| + let clearButton = root.querySelector('#omnibox-clear-button');
|
| + clearButton.addEventListener('click', function() {
|
| + this.inputField.value = '';
|
| + api.doAction(api.Action.OMNIBOX_CONTENT, {'text': ''});
|
| + }.bind(this));
|
| +
|
| + // Watch for the enter key to trigger navigation.
|
| + this.inputField.addEventListener('keypress', function(e) {
|
| + if (e.keyCode == 13) {
|
| + this.setSuggestions([]);
|
| + api.doAction(
|
| + // TODO(crbug.com/683344): Properly choose prefix.
|
| + api.Action.LOAD_URL, {'url': 'http://' + e.target.value});
|
| + }
|
| + }.bind(this));
|
| +
|
| + // Watch for field input to generate suggestions.
|
| + this.inputField.addEventListener('input', function(e) {
|
| + api.doAction(api.Action.OMNIBOX_CONTENT, {'text': e.target.value});
|
| + });
|
| +
|
| + // Watch for field input to generate suggestions.
|
| + this.inputField.addEventListener('focus', function(e) {
|
| + this.uiDelegate.showKeyboard(true);
|
| + ui.flush();
|
| + }.bind(this));
|
| + this.inputField.addEventListener('blur', function(e) {
|
| + this.uiDelegate.showKeyboard(false);
|
| + ui.flush();
|
| + }.bind(this));
|
| +
|
| + // Clicking on suggestions triggers navigation.
|
| + let elements = root.querySelectorAll('.suggestion');
|
| + this.maxSuggestions = elements.length;
|
| + for (var i = 0; i < elements.length; i++) {
|
| + elements[i].addEventListener('click', function(index, e) {
|
| + if (e.target.url) {
|
| + api.doAction(api.Action.LOAD_URL, {'url': e.target.url});
|
| + this.setSuggestions([]);
|
| + }
|
| + }.bind(this, i));
|
| + }
|
| + }
|
| +
|
| + setEnabled(enabled) {
|
| + this.enabled = enabled;
|
| +
|
| + let update = new api.UiElementUpdate();
|
| + update.setVisible(enabled);
|
| + ui.updateElement(this.domUiElement.uiElementId, update);
|
| + }
|
| +
|
| + setURL(url) {
|
| + this.inputField.value = url;
|
| + }
|
| +
|
| + setSuggestions(suggestions) {
|
| + for (var i = 0; i < this.maxSuggestions; i++) {
|
| + let element = document.querySelector('#suggestion-' + i);
|
| + if (i >= suggestions.length) {
|
| + element.textContent = '';
|
| + element.style.visibility = 'hidden';
|
| + element.url = null;
|
| + } else {
|
| + element.textContent = suggestions[i].description;
|
| + element.style.visibility = 'visible';
|
| + element.url = suggestions[i].url;
|
| + }
|
| + }
|
| + }
|
| + };
|
| +
|
| + class VirtualKeyboard {
|
| + constructor(contentQuadId) {
|
| + this.domUiElement = new DomUiElement('#vkb');
|
| + let update = new api.UiElementUpdate();
|
| + update.setVisible(false);
|
| + update.setScale(1.4, 1.4, 1);
|
| + update.setTranslation(0, -0.8, -1.5);
|
| + update.setRotation(1.0, 0.0, 0.0, -0.3);
|
| + ui.updateElement(this.domUiElement.uiElementId, update);
|
| + }
|
| +
|
| + setEnabled(enabled) {
|
| + let update = new api.UiElementUpdate();
|
| + update.setVisible(enabled);
|
| + ui.updateElement(this.domUiElement.uiElementId, update);
|
| + }
|
| + };
|
| +
|
| class UiManager {
|
| constructor() {
|
| this.mode = api.Mode.UNKNOWN;
|
| @@ -463,29 +619,47 @@ var vrShellUi = (function() {
|
| this.contentQuad = new ContentQuad();
|
| let contentId = this.contentQuad.getElementId();
|
|
|
| + this.keyboard = new VirtualKeyboard(contentId);
|
| this.controls = new Controls(contentId);
|
| this.secureOriginWarnings = new SecureOriginWarnings();
|
| this.urlIndicator = new UrlIndicator();
|
| + this.omnibox = new Omnibox(this);
|
| + this.reloadUiButton = new ReloadUiButton();
|
| }
|
|
|
| - setMode(mode, menuMode, fullscreen) {
|
| - /** @const */ var URL_INDICATOR_VISIBILITY_TIMEOUT_MS = 5000;
|
| -
|
| + setMode(mode, fullscreen) {
|
| this.mode = mode;
|
| - this.menuMode = menuMode;
|
| this.fullscreen = fullscreen;
|
| + this.updateState();
|
| + }
|
|
|
| - this.contentQuad.setEnabled(mode == api.Mode.STANDARD && !menuMode);
|
| + handleAppButtonClicked() {
|
| + this.menuMode = !this.menuMode;
|
| + this.updateState();
|
| + }
|
| +
|
| + showKeyboard(enabled) {
|
| + this.keyboard.setEnabled(enabled);
|
| + }
|
| +
|
| + updateState() {
|
| + /** @const */ var VISIBILITY_TIMEOUT_MS = 5000;
|
| +
|
| + let mode = this.mode;
|
| + let menuMode = this.menuMode && mode == api.Mode.STANDARD;
|
| + let fullscreen = this.fullscreen;
|
| +
|
| + this.reloadUiButton.setEnabled(mode == api.Mode.STANDARD);
|
| + this.contentQuad.setEnabled(mode == api.Mode.STANDARD);
|
| this.contentQuad.setFullscreen(fullscreen);
|
| + this.contentQuad.setMenuMode(menuMode);
|
| // TODO(crbug/643815): Set aspect ratio on content quad when available.
|
| // TODO(amp): Don't show controls in fullscreen once MENU mode lands.
|
| - this.controls.setEnabled(mode == api.Mode.STANDARD && !menuMode);
|
| + this.controls.setEnabled(menuMode);
|
| this.urlIndicator.setEnabled(mode == api.Mode.STANDARD && !menuMode);
|
| // TODO(amp): Don't show controls in CINEMA mode once MENU mode lands.
|
| - this.urlIndicator.setVisibilityTimeout(
|
| - mode == api.Mode.STANDARD && !menuMode ?
|
| - 0 :
|
| - URL_INDICATOR_VISIBILITY_TIMEOUT_MS);
|
| + this.urlIndicator.setVisibilityTimeout(VISIBILITY_TIMEOUT_MS);
|
| + this.omnibox.setEnabled(menuMode);
|
| this.secureOriginWarnings.setEnabled(mode == api.Mode.WEB_VR);
|
|
|
| api.setUiCssSize(
|
| @@ -499,10 +673,6 @@ var vrShellUi = (function() {
|
| setWebVRSecureOrigin(secure) {
|
| this.secureOriginWarnings.setSecure(secure);
|
| }
|
| -
|
| - setReloadUiEnabled(enabled) {
|
| - this.controls.setReloadUiEnabled(enabled);
|
| - }
|
| };
|
|
|
| function initialize() {
|
| @@ -512,9 +682,14 @@ var vrShellUi = (function() {
|
| api.domLoaded();
|
| }
|
|
|
| + // TODO: Set native mode according to menu mode.
|
| +
|
| function command(dict) {
|
| if ('mode' in dict) {
|
| - uiManager.setMode(dict['mode'], dict['menuMode'], dict['fullscreen']);
|
| + uiManager.setMode(dict['mode'], dict['fullscreen']);
|
| + }
|
| + if ('appButtonClicked' in dict) {
|
| + uiManager.handleAppButtonClicked();
|
| }
|
| if ('securityLevel' in dict) {
|
| uiManager.setSecurityLevel(dict['securityLevel']);
|
| @@ -523,11 +698,12 @@ var vrShellUi = (function() {
|
| uiManager.setWebVRSecureOrigin(dict['webVRSecureOrigin']);
|
| }
|
| if ('enableReloadUi' in dict) {
|
| - uiManager.setReloadUiEnabled(dict['enableReloadUi']);
|
| + uiManager.reloadUiButton.setDevMode(dict['enableReloadUi']);
|
| }
|
| if ('url' in dict) {
|
| let url = dict['url'];
|
| uiManager.urlIndicator.setURL(url['host'], url['path']);
|
| + uiManager.omnibox.setURL(url['host'] + url['path']);
|
| }
|
| if ('loading' in dict) {
|
| uiManager.urlIndicator.setLoading(dict['loading']);
|
| @@ -535,6 +711,9 @@ var vrShellUi = (function() {
|
| if ('loadProgress' in dict) {
|
| uiManager.urlIndicator.setLoadProgress(dict['loadProgress']);
|
| }
|
| + if ('suggestions' in dict) {
|
| + uiManager.omnibox.setSuggestions(dict['suggestions']);
|
| + }
|
| ui.flush();
|
| }
|
|
|
| @@ -544,4 +723,4 @@ var vrShellUi = (function() {
|
| };
|
| })();
|
|
|
| -document.addEventListener('DOMContentLoaded', vrShellUi.initialize);
|
| +window.addEventListener('load', vrShellUi.initialize);
|
|
|