Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Commit

Permalink
Implement multiwindow hover and click border effect. (#1603)
Browse files Browse the repository at this point in the history
* Implement multiwindow hover and click border effect.

* Proxify keyboard layer to fix depth problems
  • Loading branch information
MortimerGoro authored and bluemarvin committed Aug 23, 2019
1 parent 9c4cba9 commit 370e4a9
Show file tree
Hide file tree
Showing 24 changed files with 608 additions and 173 deletions.
1 change: 1 addition & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ add_library( # Sets the name of the library.
src/main/cpp/VRLayer.cpp
src/main/cpp/VRLayerNode.cpp
src/main/cpp/Widget.cpp
src/main/cpp/WidgetBorder.cpp
src/main/cpp/WidgetMover.cpp
src/main/cpp/WidgetPlacement.cpp
src/main/cpp/WidgetResizer.cpp
Expand Down
25 changes: 10 additions & 15 deletions app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,16 @@ protected void onCreate(Bundle savedInstanceState) {

protected void initializeWidgets() {
mWindows = new Windows(this);
mWindows.setDelegate(this::attachToWindow);
mWindows.setDelegate(new Windows.Delegate() {
@Override
public void onFocusedWindowChanged(@NonNull WindowWidget aFocusedWindow, @Nullable WindowWidget aPrevFocusedWindow) {
attachToWindow(aFocusedWindow, aPrevFocusedWindow);
}
@Override
public void onWindowBorderChanged(@NonNull WindowWidget aChangeWindow) {
mKeyboard.proxifyLayerIfNeeded(mWindows.getCurrentWindows());
}
});

// Create Browser navigation widget
mNavigationBar = new NavigationBarWidget(this);
Expand Down Expand Up @@ -648,20 +657,6 @@ void handleMotionEvent(final int aHandle, final int aDevice, final boolean aPres
if (!isWidgetInputEnabled(widget)) {
widget = null; // Fallback to mRootWidget in order to allow world clicks to dismiss UI.
}
if (widget instanceof WindowWidget) {
WindowWidget window = (WindowWidget) widget;
boolean focused = mWindows.getFocusedWindow() == window;
if (!focused && aPressed) {
// Focus the window when pressed
mWindows.focusWindow(window);
// Discard first click.
return;
} else if (!focused) {
// Do not send hover events to not focused windows.
widget = null;
}
}


float scale = widget != null ? widget.getPlacement().textureScale : 1.0f;
final float x = aX / scale;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,23 @@ public void dismiss() {
hideOverlays();
}

public void proxifyLayerIfNeeded(ArrayList<WindowWidget> aWindows) {
if (!SettingsStore.getInstance(getContext()).getLayersEnabled()) {
return;
}
boolean proxify = false;
for (WindowWidget window: aWindows) {
if (window.getPlacement().borderColor != 0) {
proxify = true;
break;
}
}
if (mWidgetPlacement.proxifyLayer != proxify) {
mWidgetPlacement.proxifyLayer = proxify;
mWidgetManager.updateWidget(this);
}
}

private void hideOverlays() {
mPopupKeyboardView.setVisibility(View.GONE);
mPopupKeyboardLayer.setVisibility(View.GONE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ void resize(int aWidth, int aHeight) {
mSurfaceTexture.setDefaultBufferSize(aWidth, aHeight);
}
}
public boolean isLayer() {
return mSurface != null && mSurfaceTexture == null;
}

void release() {
if(mSurface != null){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public interface Delegate {
}

protected UISurfaceTextureRenderer mRenderer;
protected UISurfaceTextureRenderer mProxyRenderer;
protected SurfaceTexture mTexture;
protected float mWorldWidth;
protected int mHandle;
Expand Down Expand Up @@ -102,6 +103,15 @@ public void setSurfaceTexture(SurfaceTexture aTexture, final int aWidth, final i
Log.d(LOGTAG, "Texture already set");
return;
}
if (mRenderer != null && mRenderer.isLayer()) {
// Widget is using a layer write-only surface but we also want a proxy.
if (mProxyRenderer != null) {
mProxyRenderer.release();
}
mProxyRenderer = new UISurfaceTextureRenderer(aTexture, aWidth, aHeight);
postInvalidate();
return;
}
mTexture = aTexture;
if (mRenderer != null) {
mRenderer.release();
Expand Down Expand Up @@ -211,19 +221,27 @@ public void draw(Canvas aCanvas) {
super.draw(aCanvas);
return;
}
Canvas textureCanvas = mRenderer.drawBegin();
draw(aCanvas, mRenderer);
if (mProxyRenderer != null && mWidgetPlacement.proxifyLayer) {
draw(aCanvas, mProxyRenderer);
}

if (mFirstDrawCallback != null) {
mFirstDrawCallback.run();
mFirstDrawCallback = null;
}
}

private void draw(Canvas aCanvas, UISurfaceTextureRenderer aRenderer) {
Canvas textureCanvas = aRenderer.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();
if (mFirstDrawCallback != null) {
mFirstDrawCallback.run();
mFirstDrawCallback = null;
}
aRenderer.drawEnd();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ public WidgetPlacement(Context aContext) {
public boolean showPointer = true;
public boolean firstDraw = false;
public boolean layer = true;
public boolean proxifyLayer = false;
public float textureScale = 0.7f;
// Widget will be curved if enabled.
public boolean cylinder = true;
public int borderColor = 0;
/*
* Flat surface placements are automatically mapped to curved coordinates.
* If a radius is set it's used for the automatic mapping of the yaw & angle when the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
import org.mozilla.vrbrowser.ui.widgets.prompts.ConfirmPromptWidget;
import org.mozilla.vrbrowser.ui.widgets.prompts.PromptWidget;
import org.mozilla.vrbrowser.ui.widgets.prompts.TextPromptWidget;
import org.mozilla.vrbrowser.utils.InternalPages;
import org.mozilla.vrbrowser.utils.ViewUtils;

import java.util.ArrayList;

Expand Down Expand Up @@ -90,7 +92,15 @@ public class WindowWidget extends UIWidget implements SessionChangeListener,
private Windows.WindowPlacement mWindowPlacement = Windows.WindowPlacement.FRONT;
private float mMaxWindowScale = 3;
private boolean mIsRestored = false;
private WindowDelegate mWindowDelegate;
boolean mActive = false;
boolean mHovered = false;
boolean mClickedAfterFocus = false;

public interface WindowDelegate {
void onFocusRequest(@NonNull WindowWidget aWindow);
void onBorderChanged(@NonNull WindowWidget aWindow);
}

public WindowWidget(Context aContext, int windowId, boolean privateMode) {
super(aContext);
Expand Down Expand Up @@ -387,6 +397,7 @@ public void setActiveWindow(boolean active) {
}

TelemetryWrapper.activePlacementEvent(mWindowPlacement.getValue(), mActive);
updateBorder();
}

public SessionStack getSessionStack() {
Expand Down Expand Up @@ -488,6 +499,26 @@ public WidgetPlacement getPlacement() {
@Override
public void handleTouchEvent(MotionEvent aEvent) {
mLastMouseClickPos = new Point((int)aEvent.getX(), (int)aEvent.getY());
if (aEvent.getAction() == MotionEvent.ACTION_DOWN) {
if (!mActive) {
mClickedAfterFocus = true;
updateBorder();
if (mWindowDelegate != null) {
// Focus this window
mWindowDelegate.onFocusRequest(this);
}
// Return to discard first click after focus
return;
}
} else if (aEvent.getAction() == MotionEvent.ACTION_UP || aEvent.getAction() == MotionEvent.ACTION_CANCEL) {
mClickedAfterFocus = false;
updateBorder();
}

if (!mActive) {
// Do not send touch events to not focused windows.
return;
}

if (mView != null) {
super.handleTouchEvent(aEvent);
Expand All @@ -507,6 +538,19 @@ public void handleTouchEvent(MotionEvent aEvent) {

@Override
public void handleHoverEvent(MotionEvent aEvent) {
if (aEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
mHovered = true;
updateBorder();
} else if (aEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
mHovered = false;
updateBorder();
}

if (!mActive) {
// Do not send touch events to not focused windows.
return;
}

if (mView != null) {
super.handleHoverEvent(aEvent);

Expand All @@ -520,6 +564,26 @@ public void handleHoverEvent(MotionEvent aEvent) {
}
}

protected void updateBorder() {
int color = 0;
if (!mActive && !mClickedAfterFocus && mHovered) {
color = ViewUtils.ARGBtoRGBA(getContext().getColor(R.color.window_border_hover));
} else if (mClickedAfterFocus) {
color = ViewUtils.ARGBtoRGBA(getContext().getColor(R.color.window_border_click));
}
if (mWidgetPlacement.borderColor != color) {
mWidgetPlacement.borderColor = color;
mWidgetManager.updateWidget(this);
if (mWindowDelegate != null) {
mWindowDelegate.onBorderChanged(this);
}
}
}

public void setWindowDelegate(WindowDelegate aDelegate) {
mWindowDelegate = aDelegate;
}

@Override
public void handleResizeEvent(float aWorldWidth, float aWorldHeight) {
int width = getWindowWidth(aWorldWidth);
Expand Down Expand Up @@ -975,5 +1039,4 @@ public GeckoResult<AllowOrDeny> onLoadRequest(@NonNull GeckoSession session, @No

return GeckoResult.ALLOW;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import java.lang.reflect.Type;
import java.util.ArrayList;

public class Windows implements TrayListener, TopBarWidget.Delegate, GeckoSession.ContentDelegate {
public class Windows implements TrayListener, TopBarWidget.Delegate, GeckoSession.ContentDelegate, WindowWidget.WindowDelegate {

private static final String LOGTAG = Windows.class.getSimpleName();

Expand Down Expand Up @@ -86,6 +86,7 @@ public enum WindowPlacement{

public interface Delegate {
void onFocusedWindowChanged(@NonNull WindowWidget aFocusedWindow, @Nullable WindowWidget aPrevFocusedWindow);
void onWindowBorderChanged(@NonNull WindowWidget aChangeWindow);
}

public Windows(Context aContext) {
Expand Down Expand Up @@ -347,6 +348,7 @@ public void onPause() {
}

public void onDestroy() {
mDelegate = null;
for (WindowWidget window: mRegularWindows) {
window.close();
}
Expand Down Expand Up @@ -436,7 +438,7 @@ private void showMaxWindowsMessage() {
mFocusedWindow.showMaxWindowsDialog(MAX_WINDOWS);
}

private ArrayList<WindowWidget> getCurrentWindows() {
public ArrayList<WindowWidget> getCurrentWindows() {
return mPrivateMode ? mPrivateWindows : mRegularWindows;
}

Expand Down Expand Up @@ -510,6 +512,7 @@ private void removeWindow(@NonNull WindowWidget aWindow) {
mPrivateWindows.remove(aWindow);
aWindow.getTopBar().setVisible(false);
aWindow.getTopBar().setDelegate((TopBarWidget.Delegate) null);
aWindow.setWindowDelegate(null);
aWindow.getSessionStack().removeContentListener(this);
aWindow.close();
updateMaxWindowScales();
Expand Down Expand Up @@ -664,6 +667,7 @@ private void updateTopBars() {
private WindowWidget createWindow() {
int newWindowId = sIndex++;
WindowWidget window = new WindowWidget(mContext, newWindowId, mPrivateMode);
window.setWindowDelegate(this);
getCurrentWindows().add(window);
window.getTopBar().setDelegate(this);
window.getSessionStack().addContentListener(this);
Expand Down Expand Up @@ -782,4 +786,18 @@ private WindowWidget getWindowWithSession(GeckoSession aSession) {
return null;
}

// WindowWidget.Delegate
@Override
public void onFocusRequest(WindowWidget aWindow) {
focusWindow(aWindow);
}

@Override
public void onBorderChanged(WindowWidget aWindow) {
if (mDelegate != null) {
mDelegate.onWindowBorderChanged(aWindow);
}

}

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package org.mozilla.vrbrowser.utils;

import android.graphics.Color;
import android.os.Build;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
Expand Down Expand Up @@ -117,4 +119,7 @@ public static boolean isInsideView(@NotNull View view, int rx, int ry) {
return true;
}

public static int ARGBtoRGBA(int c) {
return (c & 0x00FFFFFF) << 8 | (c & 0xFF000000) >>> 24;
}
}
2 changes: 2 additions & 0 deletions app/src/main/cpp/BrowserWorld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,6 +910,8 @@ BrowserWorld::UpdateWidget(int32_t aHandle, const WidgetPlacementPtr& aPlacement
widget->SetWorldWidth(newWorldWidth);
}

widget->SetBorderColor(vrb::Color(aPlacement->borderColor));
widget->SetProxifyLayer(aPlacement->proxifyLayer);
LayoutWidget(aHandle);
}

Expand Down
12 changes: 12 additions & 0 deletions app/src/main/cpp/Cylinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,18 @@ Cylinder::Create(vrb::CreationContextPtr aContext, const float aRadius, const fl
return result;
}

CylinderPtr
Cylinder::Create(vrb::CreationContextPtr aContext, const Cylinder& aCylinder) {
CylinderPtr result = std::make_shared<vrb::ConcreteClass<Cylinder, Cylinder::State> >(aContext);
result->m.radius = aCylinder.m.radius;
result->m.height = aCylinder.m.height;
result->m.solidColor = aCylinder.m.solidColor;
result->m.border = aCylinder.m.border;;
result->m.borderColor = aCylinder.m.borderColor;
result->m.Initialize();
return result;
}

CylinderPtr
Cylinder::Create(vrb::CreationContextPtr aContext, const VRLayerCylinderPtr& aLayer) {
CylinderPtr result = std::make_shared<vrb::ConcreteClass<Cylinder, Cylinder::State> >(aContext);
Expand Down
1 change: 1 addition & 0 deletions app/src/main/cpp/Cylinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Cylinder {
static CylinderPtr Create(vrb::CreationContextPtr aContext, const float aRadius, const float aHeight, const VRLayerCylinderPtr& aLayer = nullptr);
static CylinderPtr Create(vrb::CreationContextPtr aContext, const float aRadius, const float aHeight, const vrb::Color& aSolidColor, const float kBorder, const vrb::Color& aBorderColor);
static CylinderPtr Create(vrb::CreationContextPtr aContext, const VRLayerCylinderPtr& aLayer = nullptr);
static CylinderPtr Create(vrb::CreationContextPtr aContext, const Cylinder& aCylinder);
static float kWorldDensityRatio;
void GetTextureSize(int32_t& aWidth, int32_t& aHeight) const;
void SetTextureSize(int32_t aWidth, int32_t aHeight);
Expand Down
Loading

0 comments on commit 370e4a9

Please sign in to comment.