diff --git a/app/src/common/nativeactivity/org/mozilla/vrbrowser/PlatformActivity.java b/app/src/common/nativeactivity/org/mozilla/vrbrowser/PlatformActivity.java index f79f4ab5f..419e0f3d9 100644 --- a/app/src/common/nativeactivity/org/mozilla/vrbrowser/PlatformActivity.java +++ b/app/src/common/nativeactivity/org/mozilla/vrbrowser/PlatformActivity.java @@ -10,10 +10,13 @@ import android.os.Bundle; import android.util.Log; import android.view.SurfaceView; +import android.view.View; +import android.widget.FrameLayout; public class PlatformActivity extends NativeActivity { static String LOGTAG = "VRBrowser"; private SurfaceView mSurfaceView; + private FrameLayout mFrameLayout; @Override protected void onCreate(Bundle savedInstanceState) { @@ -22,11 +25,19 @@ protected void onCreate(Bundle savedInstanceState) { getWindow().takeSurface(null); getWindow().takeInputQueue(null); + + mFrameLayout = new FrameLayout(this); SurfaceView surfaceView = new SurfaceView(this); + surfaceView.setClickable(true); surfaceView.getHolder().addCallback(this); surfaceView.setZOrderOnTop(true); surfaceView.setBackgroundColor(Color.BLUE); + mFrameLayout.addView(surfaceView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); + + setContentView(mFrameLayout); + } - setContentView(surfaceView); + protected void addWidget(View aView, int aWidth, int aHeight) { + mFrameLayout.addView(aView, 0, new FrameLayout.LayoutParams(aWidth, aHeight)); } } diff --git a/app/src/common/shared/org/mozilla/vrbrowser/BrowserWidget.java b/app/src/common/shared/org/mozilla/vrbrowser/BrowserWidget.java index f14a79567..855a0211f 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/BrowserWidget.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/BrowserWidget.java @@ -32,12 +32,12 @@ public void setSurfaceTexture(SurfaceTexture aTexture, final int aWidth, final i } @Override - public void onTouchEvent(MotionEvent aEvent) { + public void handleTouchEvent(MotionEvent aEvent) { mSession.getPanZoomController().onTouchEvent(aEvent); } @Override - public void onHoverEvent(MotionEvent aEvent) { + public void handleHoverEvent(MotionEvent aEvent) { mSession.getPanZoomController().onMotionEvent(aEvent); } diff --git a/app/src/common/shared/org/mozilla/vrbrowser/MotionEventGenerator.java b/app/src/common/shared/org/mozilla/vrbrowser/MotionEventGenerator.java index e3ca00d7b..c7e41be0e 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/MotionEventGenerator.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/MotionEventGenerator.java @@ -82,9 +82,9 @@ static void dispatch(Widget aWidget, int aDevice, boolean aPressed, int aX, int /*source*/ InputDevice.SOURCE_TOUCHSCREEN, /*flags*/ 0); if (hover) { - aWidget.onHoverEvent(event); + aWidget.handleHoverEvent(event); return; } - aWidget.onTouchEvent(event); + aWidget.handleTouchEvent(event); } } diff --git a/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java b/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java index 29b344d8c..7d99379fe 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java @@ -6,12 +6,12 @@ package org.mozilla.vrbrowser; import android.content.Intent; -import android.content.res.AssetManager; import android.graphics.SurfaceTexture; import android.net.Uri; import android.os.Bundle; import android.support.annotation.Keep; import android.util.Log; +import android.view.View; import org.mozilla.gecko.GeckoSession; @@ -71,12 +71,19 @@ void createWidget(final int aType, final int aHandle, SurfaceTexture aTexture, i mTargetUrl = ""; } widget = mCurrentBrowser; + } else if (aType == Widget.URLBar) { + widget = (Widget) getLayoutInflater().inflate(R.layout.url, null); } if (widget != null) { widget.setSurfaceTexture(aTexture, aWidth, aHeight); mWidgets.put(aHandle, widget); } + + if (aType != Widget.Browser) { + // Add hidden UI widget to the platform window for invalidation + addWidget((View) widget, aWidth, aHeight); + } } @Keep diff --git a/app/src/common/shared/org/mozilla/vrbrowser/Widget.java b/app/src/common/shared/org/mozilla/vrbrowser/Widget.java index 139f0020b..59ace67fb 100644 --- a/app/src/common/shared/org/mozilla/vrbrowser/Widget.java +++ b/app/src/common/shared/org/mozilla/vrbrowser/Widget.java @@ -5,13 +5,13 @@ package org.mozilla.vrbrowser; -import android.content.Context; import android.graphics.SurfaceTexture; import android.view.MotionEvent; -interface Widget { +public interface Widget { int Browser = 0; + int URLBar = 1; void setSurfaceTexture(SurfaceTexture aTexture, final int aWidth, final int aHeight); - void onTouchEvent(MotionEvent aEvent); - void onHoverEvent(MotionEvent aEvent); + void handleTouchEvent(MotionEvent aEvent); + void handleHoverEvent(MotionEvent aEvent); } diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/UISurfaceTextureRenderer.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/UISurfaceTextureRenderer.java new file mode 100644 index 000000000..f45d0f6c0 --- /dev/null +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/UISurfaceTextureRenderer.java @@ -0,0 +1,72 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +package org.mozilla.vrbrowser.ui; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.SurfaceTexture; +import android.opengl.GLES11Ext; +import android.opengl.GLES20; +import android.view.Surface; + +class UISurfaceTextureRenderer { + private int mTextureWidth; + private int mTextureHeight; + private SurfaceTexture mSurfaceTexture; + private Surface mSurface; + private Canvas mSurfaceCanvas; + + UISurfaceTextureRenderer(SurfaceTexture aTexture, int aWidth, int aHeight) { + mTextureWidth = aWidth; + mTextureHeight = aHeight; + mSurfaceTexture = aTexture; + mSurfaceTexture.setDefaultBufferSize(aWidth, aHeight); + mSurface = new Surface(mSurfaceTexture); + } + + void release() { + if(mSurface != null){ + mSurface.release(); + } + if(mSurfaceTexture != null){ + mSurfaceTexture.release(); + } + mSurface = null; + mSurfaceTexture = null; + } + + Canvas drawBegin() { + mSurfaceCanvas = null; + if (mSurface != null) { + try { + mSurfaceCanvas = mSurface.lockCanvas(null); + //mSurfaceCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); + } + catch (Exception e){ + e.printStackTrace(); + } + } + return mSurfaceCanvas; + } + + void drawEnd() { + if(mSurfaceCanvas != null) { + mSurface.unlockCanvasAndPost(mSurfaceCanvas); + } + mSurfaceCanvas = null; + } + + int width() { + return mTextureWidth; + } + + int height() { + return mTextureHeight; + } + +} diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/UIWidget.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/UIWidget.java new file mode 100644 index 000000000..b5d7ad069 --- /dev/null +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/UIWidget.java @@ -0,0 +1,83 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.vrbrowser.ui; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.SurfaceTexture; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.ViewParent; +import android.widget.FrameLayout; + +import org.mozilla.vrbrowser.Widget; + +public class UIWidget extends FrameLayout implements Widget { + UISurfaceTextureRenderer mRenderer; + + public UIWidget(Context aContext) { + super(aContext); + } + + public UIWidget(Context aContext, AttributeSet aAttrs) { + super(aContext, aAttrs); + } + + public UIWidget(Context aContext, AttributeSet aAttrs, int aDefStyle) { + super(aContext, aAttrs, aDefStyle); + } + + @Override + public void setSurfaceTexture(SurfaceTexture aTexture, final int aWidth, final int aHeight) { + if (mRenderer != null) { + mRenderer.release(); + } + if (aTexture != null) { + mRenderer = new UISurfaceTextureRenderer(aTexture, aWidth, aHeight); + } + setWillNotDraw(mRenderer == null); + } + + @Override + public void handleTouchEvent(MotionEvent aEvent) { + this.dispatchTouchEvent(aEvent); + } + + @Override + public void handleHoverEvent(MotionEvent aEvent) { + this.dispatchHoverEvent(aEvent); + } + + + @Override + public void draw(Canvas aCanvas) { + if (mRenderer == null) { + super.draw(aCanvas); + return; + } + Canvas textureCanvas = mRenderer.drawBegin(); + if(textureCanvas != null) { + // set the proper scale + float xScale = textureCanvas.getWidth() / (float)aCanvas.getWidth(); + textureCanvas.scale(xScale, xScale); + // draw the view to SurfaceTexture + super.draw(textureCanvas); + } + mRenderer.drawEnd(); + } + + @Override + public ViewParent invalidateChildInParent(int[] aLocation, Rect aDirty) { + ViewParent parent = super.invalidateChildInParent(aLocation, aDirty); + if (parent != null) { + // TODO: transform rect and use invalidate(dirty) + invalidate(); + } + return parent; + } + +} diff --git a/app/src/common/shared/org/mozilla/vrbrowser/ui/URLBarWidget.java b/app/src/common/shared/org/mozilla/vrbrowser/ui/URLBarWidget.java new file mode 100644 index 000000000..1c1028451 --- /dev/null +++ b/app/src/common/shared/org/mozilla/vrbrowser/ui/URLBarWidget.java @@ -0,0 +1,44 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.vrbrowser.ui; + +import android.content.Context; +import android.text.InputType; +import android.util.AttributeSet; +import android.widget.EditText; +import android.widget.ImageButton; + +import org.mozilla.vrbrowser.R; + +public class URLBarWidget extends UIWidget { + private ImageButton mBackButton; + private ImageButton mReloadButton; + private EditText mURL; + + public URLBarWidget(Context aContext) { + super(aContext); + } + + public URLBarWidget(Context aContext, AttributeSet aAttrs) { + super(aContext, aAttrs); + } + + public URLBarWidget(Context aContext, AttributeSet aAttrs, int aDefStyle) { + super(aContext, aAttrs, aDefStyle); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mBackButton = findViewById(R.id.backButton); + mReloadButton = findViewById(R.id.reloadButton); + mURL = findViewById(R.id.urlBar); + mURL.setRawInputType(InputType.TYPE_NULL); + mURL.setTextIsSelectable(false); + mURL.setCursorVisible(false); + mURL.setText("http://"); + } +} diff --git a/app/src/main/cpp/BrowserWorld.cpp b/app/src/main/cpp/BrowserWorld.cpp index 181e1cbc1..a9b277752 100644 --- a/app/src/main/cpp/BrowserWorld.cpp +++ b/app/src/main/cpp/BrowserWorld.cpp @@ -31,7 +31,8 @@ using namespace vrb; namespace { // Must be kept in sync with Widget.java -static const int BrowserWidgetType = 0; +static const int WidgetTypeBrowser = 0; +static const int WidgetTypeURLBar = 1; static const char* kDispatchCreateWidgetName = "dispatchCreateWidget"; static const char* kDispatchCreateWidgetSignature = "(IILandroid/graphics/SurfaceTexture;II)V"; @@ -155,10 +156,16 @@ struct BrowserWorld::State { root->AddLight(light); cullVisitor = CullVisitor::Create(contextWeak); drawList = DrawableList::Create(contextWeak); - WidgetPtr browser = Widget::Create(contextWeak, BrowserWidgetType); + + WidgetPtr browser = Widget::Create(contextWeak, WidgetTypeBrowser); browser->SetTransform(Matrix::Position(Vector(0.0f, -3.0f, -18.0f))); root->AddNode(browser->GetRoot()); widgets.push_back(std::move(browser)); + + WidgetPtr urlbar = Widget::Create(contextWeak, WidgetTypeURLBar, 1920, 200, 9.0f); + urlbar->SetTransform(Matrix::Position(Vector(0.0f, 7.5f, -18.0f))); + root->AddNode(urlbar->GetRoot()); + widgets.push_back(std::move(urlbar)); } }; diff --git a/app/src/main/cpp/Widget.cpp b/app/src/main/cpp/Widget.cpp index e5bdccde8..f76c83275 100644 --- a/app/src/main/cpp/Widget.cpp +++ b/app/src/main/cpp/Widget.cpp @@ -140,6 +140,18 @@ Widget::Create(vrb::ContextWeak aContext, const int32_t aType) { return result; } +WidgetPtr +Widget::Create(vrb::ContextWeak aContext, const int aType, const int32_t aWidth, const int32_t aHeight, float aWorldWidth) { + WidgetPtr result = std::make_shared >(aContext); + result->m.textureWidth = aWidth; + result->m.textureHeight = aHeight; + const float aspect = (float)aWidth / (float)aHeight; + result->m.windowMin = vrb::Vector(-aWorldWidth, 0.0f, 0.0f); + result->m.windowMax = vrb::Vector(aWorldWidth, aWorldWidth/aspect * 2.0f, 0.0f); + result->m.Initialize(aType); + return result; +} + WidgetPtr Widget::Create(vrb::ContextWeak aContext, const int aType, const int32_t aWidth, const int32_t aHeight, const vrb::Vector& aMin, const vrb::Vector& aMax) { WidgetPtr result = std::make_shared >(aContext); diff --git a/app/src/main/cpp/Widget.h b/app/src/main/cpp/Widget.h index 3c1a8c6dc..ced71ea0e 100644 --- a/app/src/main/cpp/Widget.h +++ b/app/src/main/cpp/Widget.h @@ -20,6 +20,7 @@ typedef std::shared_ptr WidgetPtr; class Widget { public: static WidgetPtr Create(vrb::ContextWeak aContext, const int aType); + static WidgetPtr Create(vrb::ContextWeak aContext, const int aType, const int32_t aWidth, const int32_t aHeight, float aWorldWidth); static WidgetPtr Create(vrb::ContextWeak aContext, const int aType, const int32_t aWidth, const int32_t aHeight, const vrb::Vector& aMin, const vrb::Vector& aMax); int32_t GetType() const; uint32_t GetHandle() const; diff --git a/app/src/main/res/drawable/url_back_button.xml b/app/src/main/res/drawable/url_back_button.xml new file mode 100644 index 000000000..53798b044 --- /dev/null +++ b/app/src/main/res/drawable/url_back_button.xml @@ -0,0 +1,29 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/url_reload_button.xml b/app/src/main/res/drawable/url_reload_button.xml new file mode 100644 index 000000000..780062d5a --- /dev/null +++ b/app/src/main/res/drawable/url_reload_button.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/url.xml b/app/src/main/res/layout/url.xml new file mode 100644 index 000000000..24edad8d6 --- /dev/null +++ b/app/src/main/res/layout/url.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + diff --git a/app/src/wavevr/java/org/mozilla/vrbrowser/PlatformActivity.java b/app/src/wavevr/java/org/mozilla/vrbrowser/PlatformActivity.java index 822238c2b..0e0fac5f9 100644 --- a/app/src/wavevr/java/org/mozilla/vrbrowser/PlatformActivity.java +++ b/app/src/wavevr/java/org/mozilla/vrbrowser/PlatformActivity.java @@ -8,6 +8,7 @@ import com.htc.vr.sdk.VRActivity; import android.content.res.AssetManager; import android.os.Bundle; +import android.view.View; public class PlatformActivity extends VRActivity { public PlatformActivity() { @@ -25,6 +26,10 @@ public void run() { }); } + protected void addWidget(View aView, int aWidth, int aHeight) { + } + + protected native void queueRunnable(Runnable aRunnable); protected native void initializeJava(AssetManager aAssets); }