mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-04-01 12:03:08 +00:00
Backed out changeset 684a5ca2efb7 (bug 858969) for Android M3 failures.
CLOSED TREE
This commit is contained in:
parent
40126da44f
commit
4b7c54d033
@ -252,12 +252,6 @@ public:
|
||||
*/
|
||||
virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) = 0;
|
||||
|
||||
/**
|
||||
* Declare an offset to use when rendering layers. This will be ignored when
|
||||
* rendering to a target instead of the screen.
|
||||
*/
|
||||
virtual void SetScreenRenderOffset(const gfx::Point& aOffset) = 0;
|
||||
|
||||
/**
|
||||
* Tell the compositor to actually draw a quad. What to do draw and how it is
|
||||
* drawn is specified by aEffectChain. aRect is the quad to draw, in user space.
|
||||
|
@ -885,7 +885,7 @@ CompositorParent::TransformScrollableLayer(Layer* aLayer, const gfx3DMatrix& aRo
|
||||
const FrameMetrics& metrics = container->GetFrameMetrics();
|
||||
// We must apply the resolution scale before a pan/zoom transform, so we call
|
||||
// GetTransform here.
|
||||
gfx3DMatrix currentTransform = aLayer->GetTransform();
|
||||
const gfx3DMatrix& currentTransform = aLayer->GetTransform();
|
||||
|
||||
gfx3DMatrix treeTransform;
|
||||
|
||||
@ -934,15 +934,10 @@ CompositorParent::TransformScrollableLayer(Layer* aLayer, const gfx3DMatrix& aRo
|
||||
displayPortDevPixels.y += scrollOffsetDevPixels.y;
|
||||
|
||||
gfx::Margin fixedLayerMargins(0, 0, 0, 0);
|
||||
float offsetX = 0, offsetY = 0;
|
||||
SyncViewportInfo(displayPortDevPixels, 1/rootScaleX, mLayersUpdated,
|
||||
mScrollOffset, mXScale, mYScale, fixedLayerMargins,
|
||||
offsetX, offsetY);
|
||||
mScrollOffset, mXScale, mYScale, fixedLayerMargins);
|
||||
mLayersUpdated = false;
|
||||
|
||||
// Apply the render offset
|
||||
mLayerManager->GetCompositor()->SetScreenRenderOffset(gfx::Point(offsetX, offsetY));
|
||||
|
||||
// Handle transformations for asynchronous panning and zooming. We determine the
|
||||
// zoom used by Gecko from the transformation set on the root layer, and we
|
||||
// determine the scroll offset used by Gecko from the frame metrics of the
|
||||
@ -1096,13 +1091,11 @@ void
|
||||
CompositorParent::SyncViewportInfo(const nsIntRect& aDisplayPort,
|
||||
float aDisplayResolution, bool aLayersUpdated,
|
||||
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
|
||||
gfx::Margin& aFixedLayerMargins, float& aOffsetX,
|
||||
float& aOffsetY)
|
||||
gfx::Margin& aFixedLayerMargins)
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
AndroidBridge::Bridge()->SyncViewportInfo(aDisplayPort, aDisplayResolution, aLayersUpdated,
|
||||
aScrollOffset, aScaleX, aScaleY, aFixedLayerMargins,
|
||||
aOffsetX, aOffsetY);
|
||||
aScrollOffset, aScaleX, aScaleY, aFixedLayerMargins);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ protected:
|
||||
virtual void SetPageRect(const gfx::Rect& aCssPageRect);
|
||||
virtual void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
|
||||
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
|
||||
gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY);
|
||||
gfx::Margin& aFixedLayerMargins);
|
||||
void SetEGLSurfaceSize(int width, int height);
|
||||
|
||||
private:
|
||||
|
@ -621,9 +621,6 @@ CompositorOGL::PrepareViewport(const gfx::IntSize& aSize,
|
||||
viewMatrix.Translate(-gfxPoint(1.0, -1.0));
|
||||
viewMatrix.Scale(2.0f / float(aSize.width), 2.0f / float(aSize.height));
|
||||
viewMatrix.Scale(1.0f, -1.0f);
|
||||
if (!mTarget) {
|
||||
viewMatrix.Translate(gfxPoint(mRenderOffset.x, mRenderOffset.y));
|
||||
}
|
||||
|
||||
viewMatrix = aWorldTransform * viewMatrix;
|
||||
|
||||
|
@ -90,10 +90,6 @@ public:
|
||||
*/
|
||||
virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) MOZ_OVERRIDE;
|
||||
|
||||
virtual void SetScreenRenderOffset(const gfx::Point& aOffset) MOZ_OVERRIDE {
|
||||
mRenderOffset = aOffset;
|
||||
}
|
||||
|
||||
virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) MOZ_OVERRIDE {
|
||||
if (mDestroyed) {
|
||||
NS_WARNING("Call on destroyed layer manager");
|
||||
@ -145,8 +141,6 @@ private:
|
||||
/** The size of the surface we are rendering to */
|
||||
nsIntSize mSurfaceSize;
|
||||
|
||||
gfx::Point mRenderOffset;
|
||||
|
||||
/** Helper-class used by Initialize **/
|
||||
class ReadDrawFPSPref MOZ_FINAL : public nsRunnable {
|
||||
public:
|
||||
|
@ -8,7 +8,6 @@ package org.mozilla.gecko;
|
||||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
import org.mozilla.gecko.gfx.GeckoLayerClient;
|
||||
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.gfx.PanZoomController;
|
||||
@ -67,7 +66,6 @@ abstract public class BrowserApp extends GeckoApp
|
||||
implements TabsPanel.TabsLayoutChangeListener,
|
||||
PropertyAnimator.PropertyAnimationListener,
|
||||
View.OnKeyListener,
|
||||
GeckoLayerClient.OnMetricsChangedListener,
|
||||
AboutHome.UriLoadListener,
|
||||
AboutHome.LoadCompleteListener {
|
||||
private static final String LOGTAG = "GeckoBrowserApp";
|
||||
@ -115,9 +113,35 @@ abstract public class BrowserApp extends GeckoApp
|
||||
// We'll ask for feedback after the user launches the app this many times.
|
||||
private static final int FEEDBACK_LAUNCH_COUNT = 15;
|
||||
|
||||
// Variables used for scrolling the toolbar on/off the page;
|
||||
|
||||
// A drag has to move this amount multiplied by the height of the toolbar
|
||||
// before the toolbar will appear or disappear.
|
||||
private static final float TOOLBAR_MOVEMENT_THRESHOLD = 0.3f;
|
||||
|
||||
// Whether the dynamic toolbar pref is enabled.
|
||||
private boolean mDynamicToolbarEnabled = false;
|
||||
|
||||
// The last recorded touch event from onInterceptTouchEvent. These are
|
||||
// not updated until the movement threshold has been exceeded.
|
||||
private float mLastTouchX = 0.0f;
|
||||
private float mLastTouchY = 0.0f;
|
||||
|
||||
// Because we can only scroll by integer amounts, we store the fractional
|
||||
// amounts to be applied here.
|
||||
private float mToolbarSubpixelAccumulation = 0.0f;
|
||||
|
||||
// Used by onInterceptTouchEvent to lock the toolbar into an off or on
|
||||
// position.
|
||||
private boolean mToolbarLocked = false;
|
||||
|
||||
// Whether the toolbar movement threshold has been passed by the current
|
||||
// drag.
|
||||
private boolean mToolbarThresholdPassed = false;
|
||||
|
||||
// Toggled when the tabs tray is made visible to disable toolbar movement.
|
||||
private boolean mToolbarPinned = false;
|
||||
|
||||
// Stored value of the toolbar height, so we know when it's changed.
|
||||
private int mToolbarHeight = 0;
|
||||
|
||||
@ -142,7 +166,7 @@ abstract public class BrowserApp extends GeckoApp
|
||||
|
||||
if (isDynamicToolbarEnabled()) {
|
||||
// Show the toolbar.
|
||||
mLayerView.getLayerMarginsAnimator().showMargins(false);
|
||||
mBrowserToolbar.animateVisibility(true);
|
||||
}
|
||||
} else {
|
||||
hideAboutHome();
|
||||
@ -171,7 +195,7 @@ abstract public class BrowserApp extends GeckoApp
|
||||
|
||||
if (isDynamicToolbarEnabled()) {
|
||||
// Show the toolbar.
|
||||
mLayerView.getLayerMarginsAnimator().showMargins(false);
|
||||
mBrowserToolbar.animateVisibility(true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -204,6 +228,134 @@ abstract public class BrowserApp extends GeckoApp
|
||||
updateAboutHomeTopSites();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(View view, MotionEvent event) {
|
||||
if (!isDynamicToolbarEnabled() || mToolbarPinned) {
|
||||
return super.onInterceptTouchEvent(view, event);
|
||||
}
|
||||
|
||||
// Don't let the toolbar scroll at all if the page is shorter than
|
||||
// the screen height.
|
||||
ImmutableViewportMetrics metrics =
|
||||
mLayerView.getLayerClient().getViewportMetrics();
|
||||
if (metrics.getPageHeight() < metrics.getHeight()) {
|
||||
return super.onInterceptTouchEvent(view, event);
|
||||
}
|
||||
|
||||
int action = event.getActionMasked();
|
||||
int pointerCount = event.getPointerCount();
|
||||
|
||||
// Whenever there are no pointers left on the screen, tell the page
|
||||
// to clamp the viewport on fixed layer margin changes. This lets the
|
||||
// toolbar scrolling off the top of the page make the page scroll up
|
||||
// if it'd cause the page to go into overscroll, but only when there
|
||||
// are no pointers held down.
|
||||
mLayerView.getLayerClient().setClampOnFixedLayerMarginsChange(
|
||||
pointerCount == 0 || action == MotionEvent.ACTION_CANCEL ||
|
||||
action == MotionEvent.ACTION_UP);
|
||||
|
||||
View toolbarView = mBrowserToolbar.getLayout();
|
||||
if (action == MotionEvent.ACTION_DOWN ||
|
||||
action == MotionEvent.ACTION_POINTER_DOWN) {
|
||||
if (pointerCount == 1) {
|
||||
mToolbarLocked = mToolbarThresholdPassed = false;
|
||||
mToolbarSubpixelAccumulation = 0.0f;
|
||||
mLastTouchX = event.getX();
|
||||
mLastTouchY = event.getY();
|
||||
return super.onInterceptTouchEvent(view, event);
|
||||
}
|
||||
|
||||
// Animate the toolbar to the fully on/off position.
|
||||
mBrowserToolbar.animateVisibility(
|
||||
toolbarView.getScrollY() > toolbarView.getHeight() / 2 ?
|
||||
false : true);
|
||||
}
|
||||
|
||||
// If more than one pointer has been tracked, or we've locked the
|
||||
// toolbar movement, let the event pass through and be handled by the
|
||||
// PanZoomController for zooming.
|
||||
if (pointerCount > 1 || mToolbarLocked) {
|
||||
return super.onInterceptTouchEvent(view, event);
|
||||
}
|
||||
|
||||
// If a pointer has been lifted so that there's only one pointer left,
|
||||
// unlock the toolbar and track that remaining pointer.
|
||||
if (pointerCount == 1 && action == MotionEvent.ACTION_POINTER_UP) {
|
||||
mLastTouchY = event.getY(1 - event.getActionIndex());
|
||||
return super.onInterceptTouchEvent(view, event);
|
||||
}
|
||||
|
||||
// Handle scrolling the toolbar
|
||||
float eventX = event.getX();
|
||||
float eventY = event.getY();
|
||||
float deltaX = mLastTouchX - eventX;
|
||||
float deltaY = mLastTouchY - eventY;
|
||||
int toolbarY = toolbarView.getScrollY();
|
||||
int toolbarHeight = toolbarView.getHeight();
|
||||
|
||||
// Check if we've passed the toolbar movement threshold
|
||||
if (!mToolbarThresholdPassed) {
|
||||
float threshold = toolbarHeight * TOOLBAR_MOVEMENT_THRESHOLD;
|
||||
if (Math.abs(deltaY) > threshold) {
|
||||
mToolbarThresholdPassed = true;
|
||||
// If we're scrolling downwards and the toolbar was hidden
|
||||
// when we started scrolling, lock it.
|
||||
if (deltaY > 0 && toolbarY == toolbarHeight) {
|
||||
mToolbarLocked = true;
|
||||
return super.onInterceptTouchEvent(view, event);
|
||||
}
|
||||
} else if (Math.abs(deltaX) > threshold) {
|
||||
// Any horizontal scrolling past the threshold should
|
||||
// initiate toolbar lock.
|
||||
mToolbarLocked = true;
|
||||
mToolbarThresholdPassed = true;
|
||||
return super.onInterceptTouchEvent(view, event);
|
||||
} else {
|
||||
// The threshold hasn't been passed. We don't want to update
|
||||
// the stored last touch position, so return here.
|
||||
return super.onInterceptTouchEvent(view, event);
|
||||
}
|
||||
} else if (action == MotionEvent.ACTION_MOVE) {
|
||||
// Cancel any ongoing animation before we start moving the toolbar.
|
||||
mBrowserToolbar.cancelVisibilityAnimation();
|
||||
|
||||
// Move the toolbar by the amount the touch event has moved,
|
||||
// clamping to fully visible or fully hidden.
|
||||
|
||||
// Don't let the toolbar scroll off the top if it's just exposing
|
||||
// overscroll area.
|
||||
float toolbarMaxY = Math.min(toolbarHeight,
|
||||
Math.max(0, toolbarHeight - (metrics.pageRectTop -
|
||||
metrics.viewportRectTop)));
|
||||
|
||||
float newToolbarYf = Math.max(0, Math.min(toolbarMaxY,
|
||||
toolbarY + deltaY + mToolbarSubpixelAccumulation));
|
||||
int newToolbarY = Math.round(newToolbarYf);
|
||||
mToolbarSubpixelAccumulation = (newToolbarYf - newToolbarY);
|
||||
|
||||
toolbarView.scrollTo(0, newToolbarY);
|
||||
|
||||
// Reset tracking when the toolbar is fully visible or hidden.
|
||||
if (newToolbarY == 0 || newToolbarY == toolbarHeight) {
|
||||
mLastTouchY = eventY;
|
||||
}
|
||||
} else if (action == MotionEvent.ACTION_UP ||
|
||||
action == MotionEvent.ACTION_CANCEL) {
|
||||
// Animate the toolbar to fully on or off, depending on how much
|
||||
// of it is hidden and the current swipe velocity.
|
||||
PanZoomController pzc = mLayerView.getPanZoomController();
|
||||
float yVelocity = (pzc == null ? 0.0f : pzc.getVelocityVector().y);
|
||||
mBrowserToolbar.animateVisibilityWithVelocityBias(
|
||||
toolbarY > toolbarHeight / 2 ? false : true, yVelocity);
|
||||
}
|
||||
|
||||
// Update the last recorded position.
|
||||
mLastTouchX = eventX;
|
||||
mLastTouchY = eventY;
|
||||
|
||||
return super.onInterceptTouchEvent(view, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
// Global onKey handler. This is called if the focused UI doesn't
|
||||
@ -220,19 +372,15 @@ abstract public class BrowserApp extends GeckoApp
|
||||
// Toggle/focus the address bar on gamepad-y button.
|
||||
if (mBrowserToolbar.isVisible()) {
|
||||
if (isDynamicToolbarEnabled() && !mAboutHome.getUserVisibleHint()) {
|
||||
if (mLayerView != null) {
|
||||
mLayerView.getLayerMarginsAnimator().hideMargins(false);
|
||||
mLayerView.requestFocus();
|
||||
}
|
||||
mBrowserToolbar.animateVisibility(false);
|
||||
mLayerView.requestFocus();
|
||||
} else {
|
||||
// Just focus the address bar when about:home is visible
|
||||
// or when the dynamic toolbar isn't enabled.
|
||||
mBrowserToolbar.requestFocusFromTouch();
|
||||
}
|
||||
} else {
|
||||
if (mLayerView != null) {
|
||||
mLayerView.getLayerMarginsAnimator().showMargins(false);
|
||||
}
|
||||
mBrowserToolbar.animateVisibility(true);
|
||||
mBrowserToolbar.requestFocusFromTouch();
|
||||
}
|
||||
return true;
|
||||
@ -351,9 +499,10 @@ abstract public class BrowserApp extends GeckoApp
|
||||
public boolean onInterceptMotionEvent(View view, MotionEvent event) {
|
||||
// If we get a gamepad panning MotionEvent while the focus is not on the layerview,
|
||||
// put the focus on the layerview and carry on
|
||||
if (mLayerView != null && !mLayerView.hasFocus() && GamepadUtils.isPanningControl(event)) {
|
||||
LayerView layerView = mLayerView;
|
||||
if (layerView != null && !layerView.hasFocus() && GamepadUtils.isPanningControl(event)) {
|
||||
if (mAboutHome.getUserVisibleHint()) {
|
||||
mLayerView.requestFocus();
|
||||
layerView.requestFocus();
|
||||
} else {
|
||||
mAboutHome.requestFocus();
|
||||
}
|
||||
@ -446,23 +595,18 @@ abstract public class BrowserApp extends GeckoApp
|
||||
|
||||
private void setDynamicToolbarEnabled(boolean enabled) {
|
||||
if (enabled) {
|
||||
if (mLayerView != null) {
|
||||
mLayerView.getLayerClient().setOnMetricsChangedListener(this);
|
||||
}
|
||||
setToolbarMargin(0);
|
||||
} else {
|
||||
// Immediately show the toolbar when disabling the dynamic
|
||||
// toolbar.
|
||||
if (mLayerView != null) {
|
||||
mLayerView.getLayerClient().setOnMetricsChangedListener(null);
|
||||
}
|
||||
mAboutHome.setPadding(0, 0, 0, 0);
|
||||
if (mBrowserToolbar != null) {
|
||||
mBrowserToolbar.getLayout().scrollTo(0, 0);
|
||||
}
|
||||
mBrowserToolbar.cancelVisibilityAnimation();
|
||||
mBrowserToolbar.getLayout().scrollTo(0, 0);
|
||||
}
|
||||
|
||||
refreshToolbarHeight();
|
||||
// Refresh the margins to reset the padding on the spacer and
|
||||
// make sure that Gecko is in sync.
|
||||
((BrowserToolbarLayout)mBrowserToolbar.getLayout()).refreshMargins();
|
||||
}
|
||||
|
||||
private boolean isDynamicToolbarEnabled() {
|
||||
@ -527,6 +671,12 @@ abstract public class BrowserApp extends GeckoApp
|
||||
mBrowserToolbar.updateBackButton(false);
|
||||
mBrowserToolbar.updateForwardButton(false);
|
||||
|
||||
// Reset mToolbarHeight before setting margins so we force the
|
||||
// Viewport:FixedMarginsChanged message to be sent again now that
|
||||
// Gecko has loaded.
|
||||
mToolbarHeight = 0;
|
||||
((BrowserToolbarLayout)mBrowserToolbar.getLayout()).refreshMargins();
|
||||
|
||||
mDoorHangerPopup.setAnchor(mBrowserToolbar.mFavicon);
|
||||
|
||||
if (isExternalURL || mRestoreMode != RESTORE_NONE) {
|
||||
@ -545,13 +695,6 @@ abstract public class BrowserApp extends GeckoApp
|
||||
}
|
||||
}
|
||||
|
||||
// Listen to margin changes to position the toolbar correctly
|
||||
if (isDynamicToolbarEnabled()) {
|
||||
refreshToolbarHeight();
|
||||
mLayerView.getLayerMarginsAnimator().showMargins(true);
|
||||
mLayerView.getLayerClient().setOnMetricsChangedListener(this);
|
||||
}
|
||||
|
||||
// Intercept key events for gamepad shortcuts
|
||||
mLayerView.setOnKeyListener(this);
|
||||
}
|
||||
@ -566,41 +709,7 @@ abstract public class BrowserApp extends GeckoApp
|
||||
mGeckoLayout.requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMetricsChanged(ImmutableViewportMetrics aMetrics) {
|
||||
if (mAboutHome.getUserVisibleHint() || mBrowserToolbar == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final View toolbarLayout = mBrowserToolbar.getLayout();
|
||||
final int marginTop = Math.round(aMetrics.marginTop);
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
public void run() {
|
||||
toolbarLayout.scrollTo(0, toolbarLayout.getHeight() - marginTop);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPanZoomStopped() {
|
||||
if (!isDynamicToolbarEnabled() || mAboutHome.getUserVisibleHint()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImmutableViewportMetrics metrics = mLayerView.getViewportMetrics();
|
||||
if (metrics.marginTop >= mToolbarHeight / 2) {
|
||||
mLayerView.getLayerMarginsAnimator().showMargins(false);
|
||||
} else {
|
||||
mLayerView.getLayerMarginsAnimator().hideMargins(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshToolbarHeight() {
|
||||
int height = 0;
|
||||
if (mBrowserToolbar != null) {
|
||||
height = mBrowserToolbar.getLayout().getHeight();
|
||||
}
|
||||
|
||||
public void setToolbarHeight(int aHeight, int aVisibleHeight) {
|
||||
if (!isDynamicToolbarEnabled() || mAboutHome.getUserVisibleHint()) {
|
||||
// Use aVisibleHeight here so that when the dynamic toolbar is
|
||||
// enabled, the padding will animate with the toolbar becoming
|
||||
@ -609,19 +718,40 @@ abstract public class BrowserApp extends GeckoApp
|
||||
// When the dynamic toolbar is enabled, set the padding on the
|
||||
// about:home widget directly - this is to avoid resizing the
|
||||
// LayerView, which can cause visible artifacts.
|
||||
mAboutHome.setPadding(0, height, 0, 0);
|
||||
mAboutHome.setPadding(0, aVisibleHeight, 0, 0);
|
||||
} else {
|
||||
setToolbarMargin(height);
|
||||
height = 0;
|
||||
setToolbarMargin(aVisibleHeight);
|
||||
}
|
||||
aHeight = aVisibleHeight = 0;
|
||||
} else {
|
||||
setToolbarMargin(0);
|
||||
}
|
||||
|
||||
if (mLayerView != null && height != mToolbarHeight) {
|
||||
mToolbarHeight = height;
|
||||
mLayerView.getLayerMarginsAnimator().setMaxMargins(0, height, 0, 0);
|
||||
mLayerView.getLayerMarginsAnimator().showMargins(true);
|
||||
// Update the Gecko-side global for fixed viewport margins.
|
||||
if (aHeight != mToolbarHeight) {
|
||||
mToolbarHeight = aHeight;
|
||||
|
||||
// In the current UI, this is the only place we have need of
|
||||
// viewport margins (to stop the toolbar from obscuring fixed-pos
|
||||
// content).
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
GeckoEvent.createBroadcastEvent("Viewport:FixedMarginsChanged",
|
||||
"{ \"top\" : " + aHeight + ", \"right\" : 0, \"bottom\" : 0, \"left\" : 0 }"));
|
||||
}
|
||||
|
||||
if (mLayerView != null) {
|
||||
mLayerView.getLayerClient().setFixedLayerMargins(0, aVisibleHeight, 0, 0);
|
||||
|
||||
// Force a redraw when the view isn't moving and the toolbar is
|
||||
// fully visible or fully hidden. This is to make sure that the
|
||||
// Gecko-side fixed viewport margins are in sync when the view and
|
||||
// bar aren't animating.
|
||||
PointF velocityVector = mLayerView.getPanZoomController().getVelocityVector();
|
||||
if ((aVisibleHeight == 0 || aVisibleHeight == aHeight) &&
|
||||
FloatUtils.fuzzyEquals(velocityVector.x, 0.0f) &&
|
||||
FloatUtils.fuzzyEquals(velocityVector.y, 0.0f)) {
|
||||
mLayerView.getLayerClient().forceRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -973,13 +1103,11 @@ abstract public class BrowserApp extends GeckoApp
|
||||
|
||||
// If the tabs layout is animating onto the screen, pin the dynamic
|
||||
// toolbar.
|
||||
if (mLayerView != null && isDynamicToolbarEnabled()) {
|
||||
if (width > 0 && height > 0) {
|
||||
mLayerView.getLayerMarginsAnimator().showMargins(false);
|
||||
mLayerView.getLayerMarginsAnimator().setMarginsPinned(true);
|
||||
} else {
|
||||
mLayerView.getLayerMarginsAnimator().setMarginsPinned(false);
|
||||
}
|
||||
if (width > 0 && height > 0) {
|
||||
mToolbarPinned = true;
|
||||
mBrowserToolbar.animateVisibility(true);
|
||||
} else {
|
||||
mToolbarPinned = false;
|
||||
}
|
||||
|
||||
mMainLayoutAnimator.start();
|
||||
@ -1081,15 +1209,6 @@ abstract public class BrowserApp extends GeckoApp
|
||||
return;
|
||||
}
|
||||
|
||||
// Refresh toolbar height to possibly restore the toolbar padding
|
||||
refreshToolbarHeight();
|
||||
|
||||
// Show the toolbar before hiding about:home so the
|
||||
// onMetricsChanged callback still works.
|
||||
if (isDynamicToolbarEnabled() && mLayerView != null) {
|
||||
mLayerView.getLayerMarginsAnimator().showMargins(true);
|
||||
}
|
||||
|
||||
// We use commitAllowingStateLoss() instead of commit() here to avoid an
|
||||
// IllegalStateException. showAboutHome() and hideAboutHome() are
|
||||
// executed inside of tab's onChange() callback. Since that callback can
|
||||
@ -1103,6 +1222,9 @@ abstract public class BrowserApp extends GeckoApp
|
||||
mAboutHome.setUserVisibleHint(true);
|
||||
|
||||
mBrowserToolbar.setNextFocusDownId(R.id.abouthome_content);
|
||||
|
||||
// Refresh margins to possibly restore the toolbar padding
|
||||
((BrowserToolbarLayout)mBrowserToolbar.getLayout()).refreshMargins();
|
||||
}
|
||||
|
||||
private void hideAboutHome() {
|
||||
@ -1117,8 +1239,8 @@ abstract public class BrowserApp extends GeckoApp
|
||||
mBrowserToolbar.setShadowVisibility(true);
|
||||
mBrowserToolbar.setNextFocusDownId(R.id.layer_view);
|
||||
|
||||
// Refresh toolbar height to possibly restore the toolbar padding
|
||||
refreshToolbarHeight();
|
||||
// Refresh margins to possibly restore the toolbar padding
|
||||
((BrowserToolbarLayout)mBrowserToolbar.getLayout()).refreshMargins();
|
||||
}
|
||||
|
||||
private class HideTabsTouchListener implements TouchEventInterceptor {
|
||||
@ -1341,8 +1463,8 @@ abstract public class BrowserApp extends GeckoApp
|
||||
if (!mBrowserToolbar.openOptionsMenu())
|
||||
super.openOptionsMenu();
|
||||
|
||||
if (isDynamicToolbarEnabled() && mLayerView != null)
|
||||
mLayerView.getLayerMarginsAnimator().showMargins(false);
|
||||
if (isDynamicToolbarEnabled())
|
||||
mBrowserToolbar.animateVisibility(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -114,11 +114,20 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
||||
|
||||
private PropertyAnimator mVisibilityAnimator;
|
||||
|
||||
private enum ToolbarVisibility {
|
||||
VISIBLE,
|
||||
HIDDEN,
|
||||
INCONSISTENT
|
||||
};
|
||||
private ToolbarVisibility mVisibility;
|
||||
|
||||
private static final int TABS_CONTRACTED = 1;
|
||||
private static final int TABS_EXPANDED = 2;
|
||||
|
||||
private static final int FORWARD_ANIMATION_DURATION = 450;
|
||||
|
||||
private static final int VISIBILITY_ANIMATION_DURATION = 250;
|
||||
|
||||
public BrowserToolbar(BrowserApp activity) {
|
||||
// BrowserToolbar is attached to BrowserApp only.
|
||||
mActivity = activity;
|
||||
@ -129,6 +138,8 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
||||
mAnimateSiteSecurity = true;
|
||||
|
||||
mAnimatingEntry = false;
|
||||
|
||||
mVisibility = ToolbarVisibility.INCONSISTENT;
|
||||
}
|
||||
|
||||
public void from(LinearLayout layout) {
|
||||
@ -494,8 +505,71 @@ public class BrowserToolbar implements ViewSwitcher.ViewFactory,
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canToolbarHide() {
|
||||
// Forbid the toolbar from hiding if hiding the toolbar would cause
|
||||
// the page to go into overscroll.
|
||||
LayerView layerView = GeckoApp.mAppContext.getLayerView();
|
||||
if (layerView != null) {
|
||||
ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
|
||||
return (metrics.getPageHeight() >= metrics.getHeight());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void animateVisibility(boolean show) {
|
||||
// Do nothing if there's a delayed animation pending that does the
|
||||
// same thing and this request also has a delay.
|
||||
if (mVisibility != ToolbarVisibility.INCONSISTENT &&
|
||||
show == isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
cancelVisibilityAnimation();
|
||||
mVisibility = show ? ToolbarVisibility.VISIBLE : ToolbarVisibility.HIDDEN;
|
||||
|
||||
mVisibilityAnimator = new PropertyAnimator(VISIBILITY_ANIMATION_DURATION);
|
||||
mVisibilityAnimator.attach(mLayout, PropertyAnimator.Property.SCROLL_Y,
|
||||
show ? 0 : mLayout.getHeight());
|
||||
|
||||
// Only start the animation if we're showing the toolbar, or it's ok
|
||||
// to hide it.
|
||||
if (mVisibility == ToolbarVisibility.VISIBLE ||
|
||||
canToolbarHide()) {
|
||||
mVisibilityAnimator.start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Animate the visibility of the toolbar, but take into account the
|
||||
* velocity of what's moving underneath the toolbar. If that velocity
|
||||
* is greater than the default animation velocity, it will determine
|
||||
* the direction of the toolbar animation. Velocity is specified in
|
||||
* pixels per 1/60 seconds (a 60Hz frame).
|
||||
*/
|
||||
public void animateVisibilityWithVelocityBias(boolean show, float velocity) {
|
||||
// Work out the default animation velocity. This assumes a linear
|
||||
// animation which is incorrect, but the animation is short enough that
|
||||
// there's very little difference.
|
||||
float defaultVelocity =
|
||||
mLayout.getHeight() / ((VISIBILITY_ANIMATION_DURATION / 1000.0f) * 60);
|
||||
|
||||
if (Math.abs(velocity) > defaultVelocity) {
|
||||
show = (velocity > 0) ? false : true;
|
||||
}
|
||||
|
||||
animateVisibility(show);
|
||||
}
|
||||
|
||||
public void cancelVisibilityAnimation() {
|
||||
if (mVisibilityAnimator != null) {
|
||||
mVisibility = ToolbarVisibility.INCONSISTENT;
|
||||
mVisibilityAnimator.stop(false);
|
||||
mVisibilityAnimator = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isVisible() {
|
||||
return mLayout.getScrollY() == 0;
|
||||
return mVisibility == ToolbarVisibility.VISIBLE;
|
||||
}
|
||||
|
||||
public void setNextFocusDownId(int nextId) {
|
||||
|
@ -28,6 +28,15 @@ public class BrowserToolbarLayout extends LinearLayout {
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
|
||||
super.onScrollChanged(l, t, oldl, oldt);
|
||||
|
||||
if (t != oldt) {
|
||||
refreshMargins();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
@ -35,14 +44,19 @@ public class BrowserToolbarLayout extends LinearLayout {
|
||||
if (h != oldh) {
|
||||
// Post this to happen outside of onSizeChanged, as this may cause
|
||||
// a layout change and relayouts within a layout change don't work.
|
||||
final int height = h;
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((BrowserApp)GeckoApp.mAppContext).refreshToolbarHeight();
|
||||
refreshMargins();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshMargins() {
|
||||
int height = getHeight();
|
||||
int visibleHeight = height - getScrollY();
|
||||
((BrowserApp)GeckoApp.mAppContext).setToolbarHeight(height, visibleHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -766,12 +766,10 @@ abstract public class GeckoApp
|
||||
if (tab == null)
|
||||
return;
|
||||
tab.setZoomConstraints(new ZoomConstraints(message));
|
||||
tab.setIsRTL(message.getBoolean("isRTL"));
|
||||
// Sync up the layer view and the tab if the tab is currently displayed.
|
||||
LayerView layerView = mLayerView;
|
||||
if (layerView != null && Tabs.getInstance().isSelectedTab(tab)) {
|
||||
layerView.setZoomConstraints(tab.getZoomConstraints());
|
||||
layerView.setIsRTL(tab.getIsRTL());
|
||||
}
|
||||
} else if (event.equals("Session:StatePurged")) {
|
||||
onStatePurged();
|
||||
|
@ -590,10 +590,10 @@ public class GeckoEvent {
|
||||
sb.append("{ \"x\" : ").append(metrics.viewportRectLeft)
|
||||
.append(", \"y\" : ").append(metrics.viewportRectTop)
|
||||
.append(", \"zoom\" : ").append(metrics.zoomFactor)
|
||||
.append(", \"fixedMarginLeft\" : ").append(metrics.marginLeft)
|
||||
.append(", \"fixedMarginTop\" : ").append(metrics.marginTop)
|
||||
.append(", \"fixedMarginRight\" : ").append(metrics.marginRight)
|
||||
.append(", \"fixedMarginBottom\" : ").append(metrics.marginBottom)
|
||||
.append(", \"fixedMarginLeft\" : ").append(metrics.fixedLayerMarginLeft)
|
||||
.append(", \"fixedMarginTop\" : ").append(metrics.fixedLayerMarginTop)
|
||||
.append(", \"fixedMarginRight\" : ").append(metrics.fixedLayerMarginRight)
|
||||
.append(", \"fixedMarginBottom\" : ").append(metrics.fixedLayerMarginBottom)
|
||||
.append(", \"displayPort\" :").append(displayPort.toJSON())
|
||||
.append('}');
|
||||
event.mCharactersExtra = sb.toString();
|
||||
|
@ -191,7 +191,6 @@ FENNEC_JAVA_FILES = \
|
||||
gfx/IntSize.java \
|
||||
gfx/JavaPanZoomController.java \
|
||||
gfx/Layer.java \
|
||||
gfx/LayerMarginsAnimator.java \
|
||||
gfx/LayerRenderer.java \
|
||||
gfx/LayerView.java \
|
||||
gfx/PluginLayer.java \
|
||||
|
@ -56,7 +56,6 @@ public class Tab {
|
||||
private String mContentType;
|
||||
private boolean mHasTouchListeners;
|
||||
private ZoomConstraints mZoomConstraints;
|
||||
private boolean mIsRTL;
|
||||
private ArrayList<View> mPluginViews;
|
||||
private HashMap<Object, Layer> mPluginLayers;
|
||||
private int mBackgroundColor;
|
||||
@ -296,14 +295,6 @@ public class Tab {
|
||||
return mZoomConstraints;
|
||||
}
|
||||
|
||||
public void setIsRTL(boolean aIsRTL) {
|
||||
mIsRTL = aIsRTL;
|
||||
}
|
||||
|
||||
public boolean getIsRTL() {
|
||||
return mIsRTL;
|
||||
}
|
||||
|
||||
public void setHasTouchListeners(boolean aValue) {
|
||||
mHasTouchListeners = aValue;
|
||||
}
|
||||
|
@ -122,25 +122,21 @@ class TextSelection extends Layer implements GeckoEventListener {
|
||||
// cache the relevant values from the context and bail out if they are the same. we do this
|
||||
// because this draw function gets called a lot (once per compositor frame) and we want to
|
||||
// avoid doing a lot of extra work in cases where it's not needed.
|
||||
final float viewLeft = context.viewport.left - context.offset.x;
|
||||
final float viewTop = context.viewport.top - context.offset.y;
|
||||
final float viewZoom = context.zoomFactor;
|
||||
|
||||
if (FloatUtils.fuzzyEquals(mViewLeft, viewLeft)
|
||||
&& FloatUtils.fuzzyEquals(mViewTop, viewTop)
|
||||
&& FloatUtils.fuzzyEquals(mViewZoom, viewZoom)) {
|
||||
if (FloatUtils.fuzzyEquals(mViewLeft, context.viewport.left)
|
||||
&& FloatUtils.fuzzyEquals(mViewTop, context.viewport.top)
|
||||
&& FloatUtils.fuzzyEquals(mViewZoom, context.zoomFactor)) {
|
||||
return;
|
||||
}
|
||||
mViewLeft = viewLeft;
|
||||
mViewTop = viewTop;
|
||||
mViewZoom = viewZoom;
|
||||
mViewLeft = context.viewport.left;
|
||||
mViewTop = context.viewport.top;
|
||||
mViewZoom = context.zoomFactor;
|
||||
|
||||
mActivity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mStartHandle.repositionWithViewport(viewLeft, viewTop, viewZoom);
|
||||
mMiddleHandle.repositionWithViewport(viewLeft, viewTop, viewZoom);
|
||||
mEndHandle.repositionWithViewport(viewLeft, viewTop, viewZoom);
|
||||
mStartHandle.repositionWithViewport(context.viewport.left, context.viewport.top, context.zoomFactor);
|
||||
mMiddleHandle.repositionWithViewport(context.viewport.left, context.viewport.top, context.zoomFactor);
|
||||
mEndHandle.repositionWithViewport(context.viewport.left, context.viewport.top, context.zoomFactor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -155,8 +155,7 @@ class TextSelectionHandle extends ImageView implements View.OnTouchListener {
|
||||
}
|
||||
|
||||
ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
|
||||
PointF offset = metrics.getMarginOffset();
|
||||
repositionWithViewport(metrics.viewportRectLeft - offset.x, metrics.viewportRectTop - offset.y, metrics.zoomFactor);
|
||||
repositionWithViewport(metrics.viewportRectLeft, metrics.viewportRectTop, metrics.zoomFactor);
|
||||
}
|
||||
|
||||
void repositionWithViewport(float x, float y, float zoom) {
|
||||
|
@ -83,16 +83,16 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
* that because mViewportMetrics might get reassigned in between reading the different
|
||||
* fields. */
|
||||
private volatile ImmutableViewportMetrics mViewportMetrics;
|
||||
private OnMetricsChangedListener mViewportChangeListener;
|
||||
|
||||
private ZoomConstraints mZoomConstraints;
|
||||
|
||||
private boolean mGeckoIsReady;
|
||||
|
||||
private final PanZoomController mPanZoomController;
|
||||
private final LayerMarginsAnimator mMarginsAnimator;
|
||||
private LayerView mView;
|
||||
|
||||
private boolean mClampOnMarginChange;
|
||||
|
||||
public GeckoLayerClient(Context context, LayerView view, EventDispatcher eventDispatcher) {
|
||||
// we can fill these in with dummy values because they are always written
|
||||
// to before being read
|
||||
@ -108,6 +108,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
mProgressiveUpdateDisplayPort = new DisplayPortMetrics();
|
||||
mLastProgressiveUpdateWasLowPrecision = false;
|
||||
mProgressiveUpdateWasInDanger = false;
|
||||
mClampOnMarginChange = true;
|
||||
|
||||
mForceRedraw = true;
|
||||
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
|
||||
@ -116,7 +117,6 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
mZoomConstraints = new ZoomConstraints(false);
|
||||
|
||||
mPanZoomController = PanZoomController.Factory.create(this, view, eventDispatcher);
|
||||
mMarginsAnimator = new LayerMarginsAnimator(this);
|
||||
mView = view;
|
||||
mView.setListener(this);
|
||||
}
|
||||
@ -206,10 +206,6 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
return mPanZoomController;
|
||||
}
|
||||
|
||||
LayerMarginsAnimator getLayerMarginsAnimator() {
|
||||
return mMarginsAnimator;
|
||||
}
|
||||
|
||||
/* Informs Gecko that the screen size has changed. */
|
||||
private void sendResizeEventIfNecessary(boolean force) {
|
||||
DisplayMetrics metrics = mContext.getResources().getDisplayMetrics();
|
||||
@ -263,49 +259,50 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Derives content document fixed position margins/fixed layer margins from
|
||||
* the view margins in the given metrics object.
|
||||
*/
|
||||
private void getFixedMargins(ImmutableViewportMetrics metrics, RectF fixedMargins) {
|
||||
fixedMargins.left = 0;
|
||||
fixedMargins.top = 0;
|
||||
fixedMargins.right = 0;
|
||||
fixedMargins.bottom = 0;
|
||||
private void adjustFixedLayerMarginsForOverscroll(ImmutableViewportMetrics metrics, RectF adjustedMargins) {
|
||||
// When the page is in overscroll, we want that to 'eat into' the fixed
|
||||
// margin on that side of the viewport. This is because overscroll
|
||||
// equates to extra visible area and we use the fixed margins to stop
|
||||
// fixed position elements from being obscured by chrome.
|
||||
// When we're overscrolled, we also want to make sure that the fixed
|
||||
// content on the non-overscroll side isn't obscured by the edge of the
|
||||
// window, so when adjusting one side of a margin, we apply the opposite
|
||||
// adjustment to the other side of the margin.
|
||||
adjustedMargins.left = metrics.fixedLayerMarginLeft;
|
||||
adjustedMargins.top = metrics.fixedLayerMarginTop;
|
||||
adjustedMargins.right = metrics.fixedLayerMarginRight;
|
||||
adjustedMargins.bottom = metrics.fixedLayerMarginBottom;
|
||||
|
||||
// The maximum margins are determined by the scrollable area of the page.
|
||||
float maxMarginWidth = Math.max(0, metrics.getPageWidth() - metrics.getWidthWithoutMargins());
|
||||
float maxMarginHeight = Math.max(0, metrics.getPageHeight() - metrics.getHeightWithoutMargins());
|
||||
|
||||
PointF offset = metrics.getMarginOffset();
|
||||
RectF overscroll = metrics.getOverscroll();
|
||||
if (offset.x >= 0) {
|
||||
fixedMargins.right = Math.max(0, Math.min(offset.x - overscroll.right, maxMarginWidth));
|
||||
} else {
|
||||
fixedMargins.left = Math.max(0, Math.min(-offset.x - overscroll.left, maxMarginWidth));
|
||||
}
|
||||
if (offset.y >= 0) {
|
||||
fixedMargins.bottom = Math.max(0, Math.min(offset.y - overscroll.bottom, maxMarginHeight));
|
||||
} else {
|
||||
fixedMargins.top = Math.max(0, Math.min(-offset.y - overscroll.top, maxMarginHeight));
|
||||
// Adjust for left overscroll
|
||||
float leftOverscroll = metrics.pageRectLeft - metrics.viewportRectLeft;
|
||||
if (leftOverscroll > 0) {
|
||||
adjustedMargins.left = FloatUtils.clamp(adjustedMargins.left - leftOverscroll, 0, maxMarginWidth);
|
||||
adjustedMargins.right = FloatUtils.clamp(adjustedMargins.right + leftOverscroll, 0, maxMarginWidth - adjustedMargins.left);
|
||||
}
|
||||
|
||||
// Adjust for overscroll. If we're overscrolled on one side, add that
|
||||
// distance to the margins of the other side (limiting to the maximum
|
||||
// margin size calculated above).
|
||||
if (overscroll.left > 0) {
|
||||
fixedMargins.right = Math.min(maxMarginWidth - fixedMargins.left,
|
||||
fixedMargins.right + overscroll.left);
|
||||
} else if (overscroll.right > 0) {
|
||||
fixedMargins.left = Math.min(maxMarginWidth - fixedMargins.right,
|
||||
fixedMargins.left + overscroll.right);
|
||||
// Adjust for right overscroll
|
||||
float rightOverscroll = metrics.viewportRectRight - metrics.pageRectRight;
|
||||
if (rightOverscroll > 0) {
|
||||
adjustedMargins.right = FloatUtils.clamp(adjustedMargins.right - rightOverscroll, 0, maxMarginWidth);
|
||||
adjustedMargins.left = FloatUtils.clamp(adjustedMargins.left + rightOverscroll, 0, maxMarginWidth - adjustedMargins.right);
|
||||
}
|
||||
if (overscroll.top > 0) {
|
||||
fixedMargins.bottom = Math.min(maxMarginHeight - fixedMargins.top,
|
||||
fixedMargins.bottom + overscroll.top);
|
||||
} else if (overscroll.bottom > 0) {
|
||||
fixedMargins.top = Math.min(maxMarginHeight - fixedMargins.bottom,
|
||||
fixedMargins.top + overscroll.bottom);
|
||||
|
||||
// Adjust for top overscroll
|
||||
float topOverscroll = metrics.pageRectTop - metrics.viewportRectTop;
|
||||
if (topOverscroll > 0) {
|
||||
adjustedMargins.top = FloatUtils.clamp(adjustedMargins.top - topOverscroll, 0, maxMarginHeight);
|
||||
adjustedMargins.bottom = FloatUtils.clamp(adjustedMargins.bottom + topOverscroll, 0, maxMarginHeight - adjustedMargins.top);
|
||||
}
|
||||
|
||||
// Adjust for bottom overscroll
|
||||
float bottomOverscroll = metrics.viewportRectBottom - metrics.pageRectBottom;
|
||||
if (bottomOverscroll > 0) {
|
||||
adjustedMargins.bottom = FloatUtils.clamp(adjustedMargins.bottom - bottomOverscroll, 0, maxMarginHeight);
|
||||
adjustedMargins.top = FloatUtils.clamp(adjustedMargins.top + bottomOverscroll, 0, maxMarginHeight - adjustedMargins.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
@ -313,10 +310,11 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
ImmutableViewportMetrics metrics = getViewportMetrics();
|
||||
ImmutableViewportMetrics clampedMetrics = metrics.clamp();
|
||||
|
||||
RectF margins = new RectF();
|
||||
getFixedMargins(metrics, margins);
|
||||
clampedMetrics = clampedMetrics.setMargins(
|
||||
margins.left, margins.top, margins.right, margins.bottom);
|
||||
RectF fixedLayerMargins = new RectF();
|
||||
adjustFixedLayerMarginsForOverscroll(metrics, fixedLayerMargins);
|
||||
clampedMetrics = clampedMetrics.setFixedLayerMargins(
|
||||
fixedLayerMargins.left, fixedLayerMargins.top,
|
||||
fixedLayerMargins.right, fixedLayerMargins.bottom);
|
||||
|
||||
if (displayPort == null) {
|
||||
displayPort = DisplayPortCalculator.calculate(metrics, mPanZoomController.getVelocityVector());
|
||||
@ -388,6 +386,21 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
}
|
||||
});
|
||||
|
||||
// If we're meant to be scrolled to the top, take into account
|
||||
// the current fixed layer margins and offset the local viewport
|
||||
// accordingly.
|
||||
// XXX We should also do this for the left on an ltr document, and
|
||||
// the right on an rtl document, but we don't currently have
|
||||
// a way of determining the text direction from Java.
|
||||
// This also applies to setFirstPaintViewport.
|
||||
if (type == ViewportMessageType.UPDATE
|
||||
&& FloatUtils.fuzzyEquals(newMetrics.viewportRectTop,
|
||||
newMetrics.pageRectTop)
|
||||
&& oldMetrics.fixedLayerMarginTop > 0) {
|
||||
newMetrics = newMetrics.setViewportOrigin(newMetrics.viewportRectLeft,
|
||||
newMetrics.pageRectTop - oldMetrics.fixedLayerMarginTop);
|
||||
}
|
||||
|
||||
setViewportMetrics(newMetrics, type == ViewportMessageType.UPDATE);
|
||||
mDisplayPort = DisplayPortCalculator.calculate(getViewportMetrics(), null);
|
||||
}
|
||||
@ -410,6 +423,58 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets margins on fixed-position layers, to be used when compositing.
|
||||
* Must be called on the UI thread!
|
||||
*/
|
||||
public synchronized void setFixedLayerMargins(float left, float top, float right, float bottom) {
|
||||
ImmutableViewportMetrics oldMetrics = getViewportMetrics();
|
||||
ImmutableViewportMetrics newMetrics = oldMetrics.setFixedLayerMargins(left, top, right, bottom);
|
||||
|
||||
if (mClampOnMarginChange) {
|
||||
// Only clamp on decreased margins
|
||||
boolean changed = false;
|
||||
float viewportRectLeft = oldMetrics.viewportRectLeft;
|
||||
float viewportRectTop = oldMetrics.viewportRectTop;
|
||||
|
||||
// Clamp the x-axis if the page was over-scrolled into the margin
|
||||
// area.
|
||||
if (oldMetrics.fixedLayerMarginLeft > left &&
|
||||
viewportRectLeft < oldMetrics.pageRectLeft - left) {
|
||||
viewportRectLeft = oldMetrics.pageRectLeft - left;
|
||||
changed = true;
|
||||
} else if (oldMetrics.fixedLayerMarginRight > right &&
|
||||
oldMetrics.viewportRectRight > oldMetrics.pageRectRight + right) {
|
||||
viewportRectLeft = oldMetrics.pageRectRight + right - oldMetrics.getWidth();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Do the same for the y-axis.
|
||||
if (oldMetrics.fixedLayerMarginTop > top &&
|
||||
viewportRectTop < oldMetrics.pageRectTop - top) {
|
||||
viewportRectTop = oldMetrics.pageRectTop - top;
|
||||
changed = true;
|
||||
} else if (oldMetrics.fixedLayerMarginBottom > bottom &&
|
||||
oldMetrics.viewportRectBottom > oldMetrics.pageRectBottom + bottom) {
|
||||
viewportRectTop = oldMetrics.pageRectBottom + bottom - oldMetrics.getHeight();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
// Set the new metrics, if they're different.
|
||||
if (changed) {
|
||||
newMetrics = newMetrics.setViewportOrigin(viewportRectLeft, viewportRectTop);
|
||||
}
|
||||
}
|
||||
|
||||
mViewportMetrics = newMetrics;
|
||||
mView.requestRender();
|
||||
setShadowVisibility();
|
||||
}
|
||||
|
||||
public void setClampOnFixedLayerMarginsChange(boolean aClamp) {
|
||||
mClampOnMarginChange = aClamp;
|
||||
}
|
||||
|
||||
// This is called on the Gecko thread to determine if we're still interested
|
||||
// in the update of this display-port to continue. We can return true here
|
||||
// to abort the current update and continue with any subsequent ones. This
|
||||
@ -515,11 +580,6 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
mZoomConstraints = constraints;
|
||||
}
|
||||
|
||||
void setIsRTL(boolean aIsRTL) {
|
||||
ImmutableViewportMetrics newMetrics = getViewportMetrics().setIsRTL(aIsRTL);
|
||||
setViewportMetrics(newMetrics, false);
|
||||
}
|
||||
|
||||
/** This function is invoked by Gecko via JNI; be careful when modifying signature.
|
||||
* The compositor invokes this function just before compositing a frame where the document
|
||||
* is different from the document composited on the last frame. In these cases, the viewport
|
||||
@ -533,14 +593,11 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
synchronized (this) {
|
||||
ImmutableViewportMetrics currentMetrics = getViewportMetrics();
|
||||
|
||||
Tab tab = Tabs.getInstance().getSelectedTab();
|
||||
|
||||
final ImmutableViewportMetrics newMetrics = currentMetrics
|
||||
.setViewportOrigin(offsetX, offsetY)
|
||||
.setZoomFactor(zoom)
|
||||
.setPageRect(new RectF(pageLeft, pageTop, pageRight, pageBottom),
|
||||
new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom))
|
||||
.setIsRTL(tab.getIsRTL());
|
||||
new RectF(cssPageLeft, cssPageTop, cssPageRight, cssPageBottom));
|
||||
// Since we have switched to displaying a different document, we need to update any
|
||||
// viewport-related state we have lying around. This includes mGeckoViewport and
|
||||
// mViewportMetrics. Usually this information is updated via handleViewportMessage
|
||||
@ -552,8 +609,17 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
}
|
||||
});
|
||||
|
||||
setViewportMetrics(newMetrics);
|
||||
// If we're meant to be scrolled to the top, take into account any
|
||||
// margin set on the pan zoom controller.
|
||||
if (FloatUtils.fuzzyEquals(offsetY, pageTop)
|
||||
&& newMetrics.fixedLayerMarginTop > 0) {
|
||||
setViewportMetrics(newMetrics.setViewportOrigin(offsetX,
|
||||
-newMetrics.fixedLayerMarginTop));
|
||||
} else {
|
||||
setViewportMetrics(newMetrics);
|
||||
}
|
||||
|
||||
Tab tab = Tabs.getInstance().getSelectedTab();
|
||||
mView.setBackgroundColor(tab.getBackgroundColor());
|
||||
setZoomConstraints(tab.getZoomConstraints());
|
||||
|
||||
@ -617,23 +683,13 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
mCurrentViewTransform.scale = mFrameMetrics.zoomFactor;
|
||||
|
||||
// Adjust the fixed layer margins so that overscroll subtracts from them.
|
||||
getFixedMargins(mFrameMetrics, mCurrentViewTransformMargins);
|
||||
adjustFixedLayerMarginsForOverscroll(mFrameMetrics, mCurrentViewTransformMargins);
|
||||
mCurrentViewTransform.fixedLayerMarginLeft = mCurrentViewTransformMargins.left;
|
||||
mCurrentViewTransform.fixedLayerMarginTop = mCurrentViewTransformMargins.top;
|
||||
mCurrentViewTransform.fixedLayerMarginRight = mCurrentViewTransformMargins.right;
|
||||
mCurrentViewTransform.fixedLayerMarginBottom = mCurrentViewTransformMargins.bottom;
|
||||
|
||||
// Offset the view transform so that it renders in the correct place.
|
||||
PointF offset = mFrameMetrics.getMarginOffset();
|
||||
mCurrentViewTransform.offsetX = offset.x;
|
||||
mCurrentViewTransform.offsetY = offset.y;
|
||||
|
||||
mRootLayer.setPositionAndResolution(
|
||||
Math.round(x + mCurrentViewTransform.offsetX),
|
||||
Math.round(y + mCurrentViewTransform.offsetY),
|
||||
Math.round(x + width + mCurrentViewTransform.offsetX),
|
||||
Math.round(y + height + mCurrentViewTransform.offsetY),
|
||||
resolution);
|
||||
mRootLayer.setPositionAndResolution(x, y, x + width, y + height, resolution);
|
||||
|
||||
if (layersUpdated && mRecordDrawTimes) {
|
||||
// If we got a layers update, that means a draw finished. Check to see if the area drawn matches
|
||||
@ -762,20 +818,9 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
// ever be updated is in GeckoLayerClient.setFixedLayerMargins; both of these assign to
|
||||
// mViewportMetrics directly.
|
||||
metrics = metrics.setViewportSize(mViewportMetrics.getWidth(), mViewportMetrics.getHeight());
|
||||
metrics = metrics.setMarginsFrom(mViewportMetrics);
|
||||
metrics = metrics.setFixedLayerMarginsFrom(mViewportMetrics);
|
||||
mViewportMetrics = metrics;
|
||||
|
||||
viewportMetricsChanged(notifyGecko);
|
||||
}
|
||||
|
||||
/*
|
||||
* You must hold the monitor while calling this.
|
||||
*/
|
||||
private void viewportMetricsChanged(boolean notifyGecko) {
|
||||
if (mViewportChangeListener != null) {
|
||||
mViewportChangeListener.onMetricsChanged(mViewportMetrics);
|
||||
}
|
||||
|
||||
mView.requestRender();
|
||||
if (notifyGecko && mGeckoIsReady) {
|
||||
geometryChanged();
|
||||
@ -783,48 +828,6 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
setShadowVisibility();
|
||||
}
|
||||
|
||||
/*
|
||||
* Updates the viewport metrics, overriding the viewport size and margins
|
||||
* which are normally retained when calling setViewportMetrics.
|
||||
* You must hold the monitor while calling this.
|
||||
*/
|
||||
void forceViewportMetrics(ImmutableViewportMetrics metrics, boolean notifyGecko, boolean forceRedraw) {
|
||||
if (forceRedraw) {
|
||||
mForceRedraw = true;
|
||||
}
|
||||
mViewportMetrics = metrics;
|
||||
viewportMetricsChanged(notifyGecko);
|
||||
}
|
||||
|
||||
/** Implementation of PanZoomTarget
|
||||
* Scroll the viewport by a certain amount. This will take viewport margins
|
||||
* and margin animation into account. If margins are currently animating,
|
||||
* this will just go ahead and modify the viewport origin, otherwise the
|
||||
* delta will be applied to the margins and the remainder will be applied to
|
||||
* the viewport origin.
|
||||
*
|
||||
* You must hold the monitor while calling this.
|
||||
*/
|
||||
@Override
|
||||
public void scrollBy(float dx, float dy) {
|
||||
// Set mViewportMetrics manually so the margin changes take.
|
||||
mViewportMetrics = mMarginsAnimator.scrollBy(mViewportMetrics, dx, dy);
|
||||
viewportMetricsChanged(true);
|
||||
}
|
||||
|
||||
/** Implementation of PanZoomTarget */
|
||||
@Override
|
||||
public void panZoomStopped() {
|
||||
if (mViewportChangeListener != null) {
|
||||
mViewportChangeListener.onPanZoomStopped();
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnMetricsChangedListener {
|
||||
public void onMetricsChanged(ImmutableViewportMetrics viewport);
|
||||
public void onPanZoomStopped();
|
||||
}
|
||||
|
||||
private void setShadowVisibility() {
|
||||
ThreadUtils.postToUiThread(new Runnable() {
|
||||
@Override
|
||||
@ -833,7 +836,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
return;
|
||||
}
|
||||
ImmutableViewportMetrics m = mViewportMetrics;
|
||||
BrowserApp.mBrowserToolbar.setShadowVisibility(m.viewportRectTop >= m.pageRectTop);
|
||||
BrowserApp.mBrowserToolbar.setShadowVisibility(m.viewportRectTop >= m.pageRectTop - m.fixedLayerMarginTop);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -874,14 +877,12 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
|
||||
ImmutableViewportMetrics viewportMetrics = mViewportMetrics;
|
||||
PointF origin = viewportMetrics.getOrigin();
|
||||
PointF offset = viewportMetrics.getMarginOffset();
|
||||
origin.offset(-offset.x, -offset.y);
|
||||
float zoom = viewportMetrics.zoomFactor;
|
||||
ImmutableViewportMetrics geckoViewport = mGeckoViewport;
|
||||
PointF geckoOrigin = geckoViewport.getOrigin();
|
||||
float geckoZoom = geckoViewport.zoomFactor;
|
||||
|
||||
// viewPoint + origin - offset gives the coordinate in device pixels from the top-left corner of the page.
|
||||
// viewPoint + origin gives the coordinate in device pixels from the top-left corner of the page.
|
||||
// Divided by zoom, this gives us the coordinate in CSS pixels from the top-left corner of the page.
|
||||
// geckoOrigin / geckoZoom is where Gecko thinks it is (scrollTo position) in CSS pixels from
|
||||
// the top-left corner of the page. Subtracting the two gives us the offset of the viewPoint from
|
||||
@ -893,10 +894,6 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
return layerPoint;
|
||||
}
|
||||
|
||||
public void setOnMetricsChangedListener(OnMetricsChangedListener listener) {
|
||||
mViewportChangeListener = listener;
|
||||
}
|
||||
|
||||
/** Used by robocop for testing purposes. Not for production use! */
|
||||
public void setDrawListener(DrawListener listener) {
|
||||
mDrawListener = listener;
|
||||
|
@ -32,26 +32,21 @@ public class ImmutableViewportMetrics {
|
||||
public final float viewportRectTop;
|
||||
public final float viewportRectRight;
|
||||
public final float viewportRectBottom;
|
||||
public final float marginLeft;
|
||||
public final float marginTop;
|
||||
public final float marginRight;
|
||||
public final float marginBottom;
|
||||
public final float fixedLayerMarginLeft;
|
||||
public final float fixedLayerMarginTop;
|
||||
public final float fixedLayerMarginRight;
|
||||
public final float fixedLayerMarginBottom;
|
||||
public final float zoomFactor;
|
||||
public final boolean isRTL;
|
||||
|
||||
public ImmutableViewportMetrics(DisplayMetrics metrics) {
|
||||
viewportRectLeft = pageRectLeft = cssPageRectLeft = 0;
|
||||
viewportRectTop = pageRectTop = cssPageRectTop = 0;
|
||||
viewportRectRight = pageRectRight = cssPageRectRight = metrics.widthPixels;
|
||||
viewportRectBottom = pageRectBottom = cssPageRectBottom = metrics.heightPixels;
|
||||
marginLeft = marginTop = marginRight = marginBottom = 0;
|
||||
fixedLayerMarginLeft = fixedLayerMarginTop = fixedLayerMarginRight = fixedLayerMarginBottom = 0;
|
||||
zoomFactor = 1.0f;
|
||||
isRTL = false;
|
||||
}
|
||||
|
||||
/** This constructor is used by native code in AndroidJavaWrappers.cpp, be
|
||||
* careful when modifying the signature.
|
||||
*/
|
||||
private ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop,
|
||||
float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft,
|
||||
float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom,
|
||||
@ -62,16 +57,16 @@ public class ImmutableViewportMetrics {
|
||||
aPageRectRight, aPageRectBottom, aCssPageRectLeft,
|
||||
aCssPageRectTop, aCssPageRectRight, aCssPageRectBottom,
|
||||
aViewportRectLeft, aViewportRectTop, aViewportRectRight,
|
||||
aViewportRectBottom, 0.0f, 0.0f, 0.0f, 0.0f, aZoomFactor, false);
|
||||
aViewportRectBottom, 0.0f, 0.0f, 0.0f, 0.0f, aZoomFactor);
|
||||
}
|
||||
|
||||
private ImmutableViewportMetrics(float aPageRectLeft, float aPageRectTop,
|
||||
float aPageRectRight, float aPageRectBottom, float aCssPageRectLeft,
|
||||
float aCssPageRectTop, float aCssPageRectRight, float aCssPageRectBottom,
|
||||
float aViewportRectLeft, float aViewportRectTop, float aViewportRectRight,
|
||||
float aViewportRectBottom, float aMarginLeft,
|
||||
float aMarginTop, float aMarginRight,
|
||||
float aMarginBottom, float aZoomFactor, boolean aIsRTL)
|
||||
float aViewportRectBottom, float aFixedLayerMarginLeft,
|
||||
float aFixedLayerMarginTop, float aFixedLayerMarginRight,
|
||||
float aFixedLayerMarginBottom, float aZoomFactor)
|
||||
{
|
||||
pageRectLeft = aPageRectLeft;
|
||||
pageRectTop = aPageRectTop;
|
||||
@ -85,12 +80,11 @@ public class ImmutableViewportMetrics {
|
||||
viewportRectTop = aViewportRectTop;
|
||||
viewportRectRight = aViewportRectRight;
|
||||
viewportRectBottom = aViewportRectBottom;
|
||||
marginLeft = aMarginLeft;
|
||||
marginTop = aMarginTop;
|
||||
marginRight = aMarginRight;
|
||||
marginBottom = aMarginBottom;
|
||||
fixedLayerMarginLeft = aFixedLayerMarginLeft;
|
||||
fixedLayerMarginTop = aFixedLayerMarginTop;
|
||||
fixedLayerMarginRight = aFixedLayerMarginRight;
|
||||
fixedLayerMarginBottom = aFixedLayerMarginBottom;
|
||||
zoomFactor = aZoomFactor;
|
||||
isRTL = aIsRTL;
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
@ -102,24 +96,17 @@ public class ImmutableViewportMetrics {
|
||||
}
|
||||
|
||||
public float getWidthWithoutMargins() {
|
||||
return viewportRectRight - viewportRectLeft - marginLeft - marginRight;
|
||||
return viewportRectRight - viewportRectLeft - fixedLayerMarginLeft - fixedLayerMarginRight;
|
||||
}
|
||||
|
||||
public float getHeightWithoutMargins() {
|
||||
return viewportRectBottom - viewportRectTop - marginTop - marginBottom;
|
||||
return viewportRectBottom - viewportRectTop - fixedLayerMarginTop - fixedLayerMarginBottom;
|
||||
}
|
||||
|
||||
public PointF getOrigin() {
|
||||
return new PointF(viewportRectLeft, viewportRectTop);
|
||||
}
|
||||
|
||||
public PointF getMarginOffset() {
|
||||
if (isRTL) {
|
||||
return new PointF(marginLeft - marginRight, marginTop);
|
||||
}
|
||||
return new PointF(marginLeft, marginTop);
|
||||
}
|
||||
|
||||
public FloatSize getSize() {
|
||||
return new FloatSize(viewportRectRight - viewportRectLeft, viewportRectBottom - viewportRectTop);
|
||||
}
|
||||
@ -143,29 +130,14 @@ public class ImmutableViewportMetrics {
|
||||
return pageRectRight - pageRectLeft;
|
||||
}
|
||||
|
||||
public float getPageWidthWithMargins() {
|
||||
return (pageRectRight - pageRectLeft) + marginLeft + marginRight;
|
||||
}
|
||||
|
||||
public float getPageHeight() {
|
||||
return pageRectBottom - pageRectTop;
|
||||
}
|
||||
|
||||
public float getPageHeightWithMargins() {
|
||||
return (pageRectBottom - pageRectTop) + marginTop + marginBottom;
|
||||
}
|
||||
|
||||
public RectF getCssPageRect() {
|
||||
return new RectF(cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom);
|
||||
}
|
||||
|
||||
public RectF getOverscroll() {
|
||||
return new RectF(Math.max(0, pageRectLeft - viewportRectLeft),
|
||||
Math.max(0, pageRectTop - viewportRectTop),
|
||||
Math.max(0, viewportRectRight - pageRectRight),
|
||||
Math.max(0, viewportRectBottom - pageRectBottom));
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the viewport metrics that represent a linear transition between "this" and "to" at
|
||||
* time "t", which is on the scale [0, 1). This function interpolates all values stored in
|
||||
@ -185,12 +157,11 @@ public class ImmutableViewportMetrics {
|
||||
FloatUtils.interpolate(viewportRectTop, to.viewportRectTop, t),
|
||||
FloatUtils.interpolate(viewportRectRight, to.viewportRectRight, t),
|
||||
FloatUtils.interpolate(viewportRectBottom, to.viewportRectBottom, t),
|
||||
FloatUtils.interpolate(marginLeft, to.marginLeft, t),
|
||||
FloatUtils.interpolate(marginTop, to.marginTop, t),
|
||||
FloatUtils.interpolate(marginRight, to.marginRight, t),
|
||||
FloatUtils.interpolate(marginBottom, to.marginBottom, t),
|
||||
FloatUtils.interpolate(zoomFactor, to.zoomFactor, t),
|
||||
t >= 0.5 ? to.isRTL : isRTL);
|
||||
FloatUtils.interpolate(fixedLayerMarginLeft, to.fixedLayerMarginLeft, t),
|
||||
FloatUtils.interpolate(fixedLayerMarginTop, to.fixedLayerMarginTop, t),
|
||||
FloatUtils.interpolate(fixedLayerMarginRight, to.fixedLayerMarginRight, t),
|
||||
FloatUtils.interpolate(fixedLayerMarginBottom, to.fixedLayerMarginBottom, t),
|
||||
FloatUtils.interpolate(zoomFactor, to.zoomFactor, t));
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics setViewportSize(float width, float height) {
|
||||
@ -202,8 +173,8 @@ public class ImmutableViewportMetrics {
|
||||
pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
|
||||
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
|
||||
viewportRectLeft, viewportRectTop, viewportRectLeft + width, viewportRectTop + height,
|
||||
marginLeft, marginTop, marginRight, marginBottom,
|
||||
zoomFactor, isRTL);
|
||||
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
|
||||
zoomFactor);
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics setViewportOrigin(float newOriginX, float newOriginY) {
|
||||
@ -211,8 +182,8 @@ public class ImmutableViewportMetrics {
|
||||
pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
|
||||
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
|
||||
newOriginX, newOriginY, newOriginX + getWidth(), newOriginY + getHeight(),
|
||||
marginLeft, marginTop, marginRight, marginBottom,
|
||||
zoomFactor, isRTL);
|
||||
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
|
||||
zoomFactor);
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics setZoomFactor(float newZoomFactor) {
|
||||
@ -220,39 +191,28 @@ public class ImmutableViewportMetrics {
|
||||
pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
|
||||
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
|
||||
viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
|
||||
marginLeft, marginTop, marginRight, marginBottom,
|
||||
newZoomFactor, isRTL);
|
||||
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
|
||||
newZoomFactor);
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics offsetViewportBy(float dx, float dy) {
|
||||
return setViewportOrigin(viewportRectLeft + dx, viewportRectTop + dy);
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics offsetViewportByAndClamp(float dx, float dy) {
|
||||
if (isRTL) {
|
||||
return setViewportOrigin(
|
||||
Math.min(pageRectRight - getWidthWithoutMargins(), Math.max(viewportRectLeft + dx, pageRectLeft)),
|
||||
Math.max(pageRectTop, Math.min(viewportRectTop + dy, pageRectBottom - getHeightWithoutMargins())));
|
||||
}
|
||||
return setViewportOrigin(
|
||||
Math.max(pageRectLeft, Math.min(viewportRectLeft + dx, pageRectRight - getWidthWithoutMargins())),
|
||||
Math.max(pageRectTop, Math.min(viewportRectTop + dy, pageRectBottom - getHeightWithoutMargins())));
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics setPageRect(RectF pageRect, RectF cssPageRect) {
|
||||
return new ImmutableViewportMetrics(
|
||||
pageRect.left, pageRect.top, pageRect.right, pageRect.bottom,
|
||||
cssPageRect.left, cssPageRect.top, cssPageRect.right, cssPageRect.bottom,
|
||||
viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
|
||||
marginLeft, marginTop, marginRight, marginBottom,
|
||||
zoomFactor, isRTL);
|
||||
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
|
||||
zoomFactor);
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics setMargins(float left, float top, float right, float bottom) {
|
||||
if (FloatUtils.fuzzyEquals(left, marginLeft)
|
||||
&& FloatUtils.fuzzyEquals(top, marginTop)
|
||||
&& FloatUtils.fuzzyEquals(right, marginRight)
|
||||
&& FloatUtils.fuzzyEquals(bottom, marginBottom)) {
|
||||
public ImmutableViewportMetrics setFixedLayerMargins(float left, float top, float right, float bottom) {
|
||||
if (FloatUtils.fuzzyEquals(left, fixedLayerMarginLeft)
|
||||
&& FloatUtils.fuzzyEquals(top, fixedLayerMarginTop)
|
||||
&& FloatUtils.fuzzyEquals(right, fixedLayerMarginRight)
|
||||
&& FloatUtils.fuzzyEquals(bottom, fixedLayerMarginBottom)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -260,26 +220,14 @@ public class ImmutableViewportMetrics {
|
||||
pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
|
||||
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
|
||||
viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
|
||||
left, top, right, bottom, zoomFactor, isRTL);
|
||||
left, top, right, bottom, zoomFactor);
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics setMarginsFrom(ImmutableViewportMetrics fromMetrics) {
|
||||
return setMargins(fromMetrics.marginLeft,
|
||||
fromMetrics.marginTop,
|
||||
fromMetrics.marginRight,
|
||||
fromMetrics.marginBottom);
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics setIsRTL(boolean aIsRTL) {
|
||||
if (isRTL == aIsRTL) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return new ImmutableViewportMetrics(
|
||||
pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
|
||||
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
|
||||
viewportRectLeft, viewportRectTop, viewportRectRight, viewportRectBottom,
|
||||
marginLeft, marginTop, marginRight, marginBottom, zoomFactor, aIsRTL);
|
||||
public ImmutableViewportMetrics setFixedLayerMarginsFrom(ImmutableViewportMetrics fromMetrics) {
|
||||
return setFixedLayerMargins(fromMetrics.fixedLayerMarginLeft,
|
||||
fromMetrics.fixedLayerMarginTop,
|
||||
fromMetrics.fixedLayerMarginRight,
|
||||
fromMetrics.fixedLayerMarginBottom);
|
||||
}
|
||||
|
||||
/* This will set the zoom factor and re-scale page-size and viewport offset
|
||||
@ -303,33 +251,32 @@ public class ImmutableViewportMetrics {
|
||||
newPageRectLeft, newPageRectTop, newPageRectRight, newPageRectBottom,
|
||||
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
|
||||
origin.x, origin.y, origin.x + getWidth(), origin.y + getHeight(),
|
||||
marginLeft, marginTop, marginRight, marginBottom,
|
||||
newZoomFactor, isRTL);
|
||||
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
|
||||
newZoomFactor);
|
||||
}
|
||||
|
||||
/** Clamps the viewport to remain within the page rect. */
|
||||
private ImmutableViewportMetrics clamp(float marginLeft, float marginTop,
|
||||
float marginRight, float marginBottom) {
|
||||
RectF newViewport = getViewport();
|
||||
PointF offset = getMarginOffset();
|
||||
|
||||
// The viewport bounds ought to never exceed the page bounds.
|
||||
if (newViewport.right > pageRectRight + marginLeft + marginRight)
|
||||
newViewport.offset((pageRectRight + marginLeft + marginRight) - newViewport.right, 0);
|
||||
if (newViewport.left < pageRectLeft)
|
||||
newViewport.offset(pageRectLeft - newViewport.left, 0);
|
||||
if (newViewport.right > pageRectRight + marginRight)
|
||||
newViewport.offset((pageRectRight + marginRight) - newViewport.right, 0);
|
||||
if (newViewport.left < pageRectLeft - marginLeft)
|
||||
newViewport.offset((pageRectLeft - marginLeft) - newViewport.left, 0);
|
||||
|
||||
if (newViewport.bottom > pageRectBottom + marginTop + marginBottom)
|
||||
newViewport.offset(0, (pageRectBottom + marginTop + marginBottom) - newViewport.bottom);
|
||||
if (newViewport.top < pageRectTop)
|
||||
newViewport.offset(0, pageRectTop - newViewport.top);
|
||||
if (newViewport.bottom > pageRectBottom + marginBottom)
|
||||
newViewport.offset(0, (pageRectBottom + marginBottom) - newViewport.bottom);
|
||||
if (newViewport.top < pageRectTop - marginTop)
|
||||
newViewport.offset(0, (pageRectTop - marginTop) - newViewport.top);
|
||||
|
||||
return new ImmutableViewportMetrics(
|
||||
pageRectLeft, pageRectTop, pageRectRight, pageRectBottom,
|
||||
cssPageRectLeft, cssPageRectTop, cssPageRectRight, cssPageRectBottom,
|
||||
newViewport.left, newViewport.top, newViewport.right, newViewport.bottom,
|
||||
marginLeft, marginTop, marginRight, marginBottom,
|
||||
zoomFactor, isRTL);
|
||||
fixedLayerMarginLeft, fixedLayerMarginTop, fixedLayerMarginRight, fixedLayerMarginBottom,
|
||||
zoomFactor);
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics clamp() {
|
||||
@ -337,8 +284,8 @@ public class ImmutableViewportMetrics {
|
||||
}
|
||||
|
||||
public ImmutableViewportMetrics clampWithMargins() {
|
||||
return clamp(marginLeft, marginTop,
|
||||
marginRight, marginBottom);
|
||||
return clamp(fixedLayerMarginLeft, fixedLayerMarginTop,
|
||||
fixedLayerMarginRight, fixedLayerMarginBottom);
|
||||
}
|
||||
|
||||
public boolean fuzzyEquals(ImmutableViewportMetrics other) {
|
||||
@ -346,8 +293,9 @@ public class ImmutableViewportMetrics {
|
||||
// of the cssPageRectXXX values and the zoomFactor, except with more rounding
|
||||
// error. Checking those is both inefficient and can lead to false negatives.
|
||||
//
|
||||
// This doesn't return false if the margins differ as none of the users
|
||||
// of this function are interested in the margins in that way.
|
||||
// This doesn't return false if the fixed layer margins differ as none
|
||||
// of the users of this function are interested in the margins in that
|
||||
// way.
|
||||
return FloatUtils.fuzzyEquals(cssPageRectLeft, other.cssPageRectLeft)
|
||||
&& FloatUtils.fuzzyEquals(cssPageRectTop, other.cssPageRectTop)
|
||||
&& FloatUtils.fuzzyEquals(cssPageRectRight, other.cssPageRectRight)
|
||||
@ -365,8 +313,8 @@ public class ImmutableViewportMetrics {
|
||||
+ viewportRectRight + "," + viewportRectBottom + ") p=(" + pageRectLeft + ","
|
||||
+ pageRectTop + "," + pageRectRight + "," + pageRectBottom + ") c=("
|
||||
+ cssPageRectLeft + "," + cssPageRectTop + "," + cssPageRectRight + ","
|
||||
+ cssPageRectBottom + ") m=(" + marginLeft + ","
|
||||
+ marginTop + "," + marginRight + ","
|
||||
+ marginBottom + ") z=" + zoomFactor + ", rtl=" + isRTL;
|
||||
+ cssPageRectBottom + ") m=(" + fixedLayerMarginLeft + ","
|
||||
+ fixedLayerMarginTop + "," + fixedLayerMarginRight + ","
|
||||
+ fixedLayerMarginBottom + ") z=" + zoomFactor;
|
||||
}
|
||||
}
|
||||
|
@ -197,11 +197,6 @@ class JavaPanZoomController
|
||||
if (state != mState) {
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("PanZoom:StateChange", state.toString()));
|
||||
mState = state;
|
||||
|
||||
// Let the target know we've finished with it (for now)
|
||||
if (state == PanZoomState.NOTHING) {
|
||||
mTarget.panZoomStopped();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -711,7 +706,8 @@ class JavaPanZoomController
|
||||
}
|
||||
|
||||
private void scrollBy(float dx, float dy) {
|
||||
mTarget.scrollBy(dx, dy);
|
||||
ImmutableViewportMetrics scrolled = getMetrics().offsetViewportBy(dx, dy);
|
||||
mTarget.setViewportMetrics(scrolled);
|
||||
}
|
||||
|
||||
private void fling() {
|
||||
@ -1002,8 +998,8 @@ class JavaPanZoomController
|
||||
// Ensure minZoomFactor keeps the page at least as big as the viewport.
|
||||
if (pageRect.width() > 0) {
|
||||
float pageWidth = pageRect.width() +
|
||||
viewportMetrics.marginLeft +
|
||||
viewportMetrics.marginRight;
|
||||
viewportMetrics.fixedLayerMarginLeft +
|
||||
viewportMetrics.fixedLayerMarginRight;
|
||||
float scaleFactor = viewport.width() / pageWidth;
|
||||
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
|
||||
if (viewport.width() > pageWidth)
|
||||
@ -1011,8 +1007,8 @@ class JavaPanZoomController
|
||||
}
|
||||
if (pageRect.height() > 0) {
|
||||
float pageHeight = pageRect.height() +
|
||||
viewportMetrics.marginTop +
|
||||
viewportMetrics.marginBottom;
|
||||
viewportMetrics.fixedLayerMarginTop +
|
||||
viewportMetrics.fixedLayerMarginBottom;
|
||||
float scaleFactor = viewport.height() / pageHeight;
|
||||
minZoomFactor = Math.max(minZoomFactor, zoomFactor * scaleFactor);
|
||||
if (viewport.height() > pageHeight)
|
||||
@ -1047,9 +1043,15 @@ class JavaPanZoomController
|
||||
@Override
|
||||
protected float getViewportLength() { return getMetrics().getWidth(); }
|
||||
@Override
|
||||
protected float getPageStart() { return getMetrics().pageRectLeft; }
|
||||
protected float getPageStart() {
|
||||
ImmutableViewportMetrics metrics = getMetrics();
|
||||
return metrics.pageRectLeft - metrics.fixedLayerMarginLeft;
|
||||
}
|
||||
@Override
|
||||
protected float getPageLength() { return getMetrics().getPageWidthWithMargins(); }
|
||||
protected float getPageLength() {
|
||||
ImmutableViewportMetrics metrics = getMetrics();
|
||||
return metrics.getPageWidth() + metrics.fixedLayerMarginLeft + metrics.fixedLayerMarginRight;
|
||||
}
|
||||
}
|
||||
|
||||
private class AxisY extends Axis {
|
||||
@ -1059,9 +1061,15 @@ class JavaPanZoomController
|
||||
@Override
|
||||
protected float getViewportLength() { return getMetrics().getHeight(); }
|
||||
@Override
|
||||
protected float getPageStart() { return getMetrics().pageRectTop; }
|
||||
protected float getPageStart() {
|
||||
ImmutableViewportMetrics metrics = getMetrics();
|
||||
return metrics.pageRectTop - metrics.fixedLayerMarginTop;
|
||||
}
|
||||
@Override
|
||||
protected float getPageLength() { return getMetrics().getPageHeightWithMargins(); }
|
||||
protected float getPageLength() {
|
||||
ImmutableViewportMetrics metrics = getMetrics();
|
||||
return metrics.getPageHeight() + metrics.fixedLayerMarginTop + metrics.fixedLayerMarginBottom;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -7,7 +7,6 @@ package org.mozilla.gecko.gfx;
|
||||
|
||||
import org.mozilla.gecko.util.FloatUtils;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
|
||||
@ -177,17 +176,15 @@ public abstract class Layer {
|
||||
public final RectF viewport;
|
||||
public final RectF pageRect;
|
||||
public final float zoomFactor;
|
||||
public final PointF offset;
|
||||
public final int positionHandle;
|
||||
public final int textureHandle;
|
||||
public final FloatBuffer coordBuffer;
|
||||
|
||||
public RenderContext(RectF aViewport, RectF aPageRect, float aZoomFactor, PointF aOffset,
|
||||
public RenderContext(RectF aViewport, RectF aPageRect, float aZoomFactor,
|
||||
int aPositionHandle, int aTextureHandle, FloatBuffer aCoordBuffer) {
|
||||
viewport = aViewport;
|
||||
pageRect = aPageRect;
|
||||
zoomFactor = aZoomFactor;
|
||||
offset = aOffset;
|
||||
positionHandle = aPositionHandle;
|
||||
textureHandle = aTextureHandle;
|
||||
coordBuffer = aCoordBuffer;
|
||||
@ -199,8 +196,7 @@ public abstract class Layer {
|
||||
}
|
||||
return RectUtils.fuzzyEquals(viewport, other.viewport)
|
||||
&& RectUtils.fuzzyEquals(pageRect, other.pageRect)
|
||||
&& FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor)
|
||||
&& FloatUtils.fuzzyEquals(offset, other.offset);
|
||||
&& FloatUtils.fuzzyEquals(zoomFactor, other.zoomFactor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,184 +0,0 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; 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.gecko.gfx;
|
||||
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
import org.mozilla.gecko.util.FloatUtils;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class LayerMarginsAnimator {
|
||||
private static final String LOGTAG = "GeckoLayerMarginsAnimator";
|
||||
private static final float MS_PER_FRAME = 1000.0f / 60.0f;
|
||||
private static final long MARGIN_ANIMATION_DURATION = 250;
|
||||
|
||||
/* This rect stores the maximum value margins can grow to when scrolling */
|
||||
private final RectF mMaxMargins;
|
||||
/* If this boolean is true, scroll changes will not affect margins */
|
||||
private boolean mMarginsPinned;
|
||||
/* The timer that handles showing/hiding margins */
|
||||
private Timer mAnimationTimer;
|
||||
/* This interpolator is used for the above mentioned animation */
|
||||
private final DecelerateInterpolator mInterpolator;
|
||||
/* The GeckoLayerClient whose margins will be animated */
|
||||
private final GeckoLayerClient mTarget;
|
||||
|
||||
public LayerMarginsAnimator(GeckoLayerClient aTarget) {
|
||||
// Assign member variables from parameters
|
||||
mTarget = aTarget;
|
||||
|
||||
// Create other member variables
|
||||
mMaxMargins = new RectF();
|
||||
mInterpolator = new DecelerateInterpolator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum values for margins to grow to, in pixels.
|
||||
*/
|
||||
public synchronized void setMaxMargins(float left, float top, float right, float bottom) {
|
||||
mMaxMargins.set(left, top, right, bottom);
|
||||
|
||||
// Update the Gecko-side global for fixed viewport margins.
|
||||
GeckoAppShell.sendEventToGecko(
|
||||
GeckoEvent.createBroadcastEvent("Viewport:FixedMarginsChanged",
|
||||
"{ \"top\" : " + top + ", \"right\" : " + right
|
||||
+ ", \"bottom\" : " + bottom + ", \"left\" : " + left + " }"));
|
||||
}
|
||||
|
||||
private void animateMargins(final float left, final float top, final float right, final float bottom, boolean immediately) {
|
||||
if (mAnimationTimer != null) {
|
||||
mAnimationTimer.cancel();
|
||||
mAnimationTimer = null;
|
||||
}
|
||||
|
||||
if (immediately) {
|
||||
ImmutableViewportMetrics newMetrics = mTarget.getViewportMetrics().setMargins(left, top, right, bottom);
|
||||
mTarget.forceViewportMetrics(newMetrics, true, true);
|
||||
return;
|
||||
}
|
||||
|
||||
ImmutableViewportMetrics metrics = mTarget.getViewportMetrics();
|
||||
|
||||
final long startTime = SystemClock.uptimeMillis();
|
||||
final float startLeft = metrics.marginLeft;
|
||||
final float startTop = metrics.marginTop;
|
||||
final float startRight = metrics.marginRight;
|
||||
final float startBottom = metrics.marginBottom;
|
||||
|
||||
mAnimationTimer = new Timer("Margin Animation Timer");
|
||||
mAnimationTimer.scheduleAtFixedRate(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
float progress = mInterpolator.getInterpolation(
|
||||
Math.min(1.0f, (SystemClock.uptimeMillis() - startTime)
|
||||
/ (float)MARGIN_ANIMATION_DURATION));
|
||||
|
||||
synchronized(mTarget.getLock()) {
|
||||
ImmutableViewportMetrics oldMetrics = mTarget.getViewportMetrics();
|
||||
ImmutableViewportMetrics newMetrics = oldMetrics.setMargins(
|
||||
FloatUtils.interpolate(startLeft, left, progress),
|
||||
FloatUtils.interpolate(startTop, top, progress),
|
||||
FloatUtils.interpolate(startRight, right, progress),
|
||||
FloatUtils.interpolate(startBottom, bottom, progress));
|
||||
PointF oldOffset = oldMetrics.getMarginOffset();
|
||||
PointF newOffset = newMetrics.getMarginOffset();
|
||||
newMetrics =
|
||||
newMetrics.offsetViewportByAndClamp(newOffset.x - oldOffset.x,
|
||||
newOffset.y - oldOffset.y);
|
||||
|
||||
if (progress >= 1.0f) {
|
||||
mAnimationTimer.cancel();
|
||||
mAnimationTimer = null;
|
||||
|
||||
// Force a redraw and update Gecko
|
||||
mTarget.forceViewportMetrics(newMetrics, true, true);
|
||||
} else {
|
||||
mTarget.forceViewportMetrics(newMetrics, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 0, (int)MS_PER_FRAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes the margin area by growing the margin components of the current
|
||||
* metrics to the values set in setMaxMargins.
|
||||
*/
|
||||
public synchronized void showMargins(boolean immediately) {
|
||||
animateMargins(mMaxMargins.left, mMaxMargins.top, mMaxMargins.right, mMaxMargins.bottom, immediately);
|
||||
}
|
||||
|
||||
public synchronized void hideMargins(boolean immediately) {
|
||||
animateMargins(0, 0, 0, 0, immediately);
|
||||
}
|
||||
|
||||
public void setMarginsPinned(boolean pin) {
|
||||
mMarginsPinned = pin;
|
||||
}
|
||||
|
||||
/*
|
||||
* Taking maximum margins into account, offsets the margins and then the
|
||||
* viewport origin and returns the modified metrics.
|
||||
*/
|
||||
ImmutableViewportMetrics scrollBy(ImmutableViewportMetrics aMetrics, float aDx, float aDy) {
|
||||
// Make sure to cancel any margin animations when scrolling begins
|
||||
if (mAnimationTimer != null) {
|
||||
mAnimationTimer.cancel();
|
||||
mAnimationTimer = null;
|
||||
}
|
||||
|
||||
float newMarginLeft = aMetrics.marginLeft;
|
||||
float newMarginTop = aMetrics.marginTop;
|
||||
float newMarginRight = aMetrics.marginRight;
|
||||
float newMarginBottom = aMetrics.marginBottom;
|
||||
|
||||
// Only alter margins if the toolbar isn't pinned
|
||||
if (!mMarginsPinned) {
|
||||
RectF overscroll = aMetrics.getOverscroll();
|
||||
if (aDx >= 0) {
|
||||
// Scrolling right.
|
||||
float marginDx = Math.max(0, aDx - overscroll.left);
|
||||
newMarginLeft = aMetrics.marginLeft - Math.min(marginDx, aMetrics.marginLeft);
|
||||
newMarginRight = aMetrics.marginRight + Math.min(marginDx, mMaxMargins.right - aMetrics.marginRight);
|
||||
|
||||
aDx -= aMetrics.marginLeft - newMarginLeft;
|
||||
} else {
|
||||
// Scrolling left.
|
||||
float marginDx = Math.max(0, -aDx - overscroll.right);
|
||||
newMarginLeft = aMetrics.marginLeft + Math.min(marginDx, mMaxMargins.left - aMetrics.marginLeft);
|
||||
newMarginRight = aMetrics.marginRight - Math.min(marginDx, aMetrics.marginRight);
|
||||
|
||||
aDx -= aMetrics.marginLeft - newMarginLeft;
|
||||
}
|
||||
|
||||
if (aDy >= 0) {
|
||||
// Scrolling down.
|
||||
float marginDy = Math.max(0, aDy - overscroll.top);
|
||||
newMarginTop = aMetrics.marginTop - Math.min(marginDy, aMetrics.marginTop);
|
||||
newMarginBottom = aMetrics.marginBottom + Math.min(marginDy, mMaxMargins.bottom - aMetrics.marginBottom);
|
||||
|
||||
aDy -= aMetrics.marginTop - newMarginTop;
|
||||
} else {
|
||||
// Scrolling up.
|
||||
float marginDy = Math.max(0, -aDy - overscroll.bottom);
|
||||
newMarginTop = aMetrics.marginTop + Math.min(marginDy, mMaxMargins.top - aMetrics.marginTop);
|
||||
newMarginBottom = aMetrics.marginBottom - Math.min(marginDy, aMetrics.marginBottom);
|
||||
|
||||
aDy -= aMetrics.marginTop - newMarginTop;
|
||||
}
|
||||
}
|
||||
|
||||
return aMetrics.setMargins(newMarginLeft, newMarginTop, newMarginRight, newMarginBottom).offsetViewportBy(aDx, aDy);
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.opengl.GLES20;
|
||||
@ -278,23 +277,21 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
||||
return pixelBuffer;
|
||||
}
|
||||
|
||||
private RenderContext createScreenContext(ImmutableViewportMetrics metrics, PointF offset) {
|
||||
private RenderContext createScreenContext(ImmutableViewportMetrics metrics) {
|
||||
RectF viewport = new RectF(0.0f, 0.0f, metrics.getWidth(), metrics.getHeight());
|
||||
RectF pageRect = metrics.getPageRect();
|
||||
|
||||
return createContext(viewport, pageRect, 1.0f, offset);
|
||||
RectF pageRect = new RectF(metrics.getPageRect());
|
||||
return createContext(viewport, pageRect, 1.0f);
|
||||
}
|
||||
|
||||
private RenderContext createPageContext(ImmutableViewportMetrics metrics, PointF offset) {
|
||||
RectF viewport = metrics.getViewport();
|
||||
private RenderContext createPageContext(ImmutableViewportMetrics metrics) {
|
||||
Rect viewport = RectUtils.round(metrics.getViewport());
|
||||
RectF pageRect = metrics.getPageRect();
|
||||
float zoomFactor = metrics.zoomFactor;
|
||||
|
||||
return createContext(new RectF(RectUtils.round(viewport)), pageRect, zoomFactor, offset);
|
||||
return createContext(new RectF(viewport), pageRect, zoomFactor);
|
||||
}
|
||||
|
||||
private RenderContext createContext(RectF viewport, RectF pageRect, float zoomFactor, PointF offset) {
|
||||
return new RenderContext(viewport, pageRect, zoomFactor, offset, mPositionHandle, mTextureHandle,
|
||||
private RenderContext createContext(RectF viewport, RectF pageRect, float zoomFactor) {
|
||||
return new RenderContext(viewport, pageRect, zoomFactor, mPositionHandle, mTextureHandle,
|
||||
mCoordBuffer);
|
||||
}
|
||||
|
||||
@ -413,27 +410,17 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
||||
private boolean mUpdated;
|
||||
private final Rect mPageRect;
|
||||
private final Rect mAbsolutePageRect;
|
||||
private final PointF mRenderOffset;
|
||||
|
||||
public Frame(ImmutableViewportMetrics metrics) {
|
||||
mFrameMetrics = metrics;
|
||||
mPageContext = createPageContext(metrics);
|
||||
mScreenContext = createScreenContext(metrics);
|
||||
|
||||
// Work out the offset due to margins
|
||||
Layer rootLayer = mView.getLayerClient().getRoot();
|
||||
mRenderOffset = mFrameMetrics.getMarginOffset();
|
||||
float scaleDiff = mFrameMetrics.zoomFactor / rootLayer.getResolution();
|
||||
mRenderOffset.set(mRenderOffset.x * scaleDiff,
|
||||
mRenderOffset.y * scaleDiff);
|
||||
|
||||
mPageContext = createPageContext(metrics, mRenderOffset);
|
||||
mScreenContext = createScreenContext(metrics, mRenderOffset);
|
||||
|
||||
RectF pageRect = mFrameMetrics.getPageRect();
|
||||
mAbsolutePageRect = RectUtils.round(pageRect);
|
||||
|
||||
PointF origin = mFrameMetrics.getOrigin();
|
||||
Point origin = PointUtils.round(mFrameMetrics.getOrigin());
|
||||
Rect pageRect = RectUtils.round(mFrameMetrics.getPageRect());
|
||||
mAbsolutePageRect = new Rect(pageRect);
|
||||
pageRect.offset(-origin.x, -origin.y);
|
||||
mPageRect = RectUtils.round(pageRect);
|
||||
mPageRect = pageRect;
|
||||
}
|
||||
|
||||
private void setScissorRect() {
|
||||
@ -451,11 +438,8 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
||||
int right = Math.min(screenSize.width, rect.right);
|
||||
int bottom = Math.min(screenSize.height, rect.bottom);
|
||||
|
||||
Rect scissorRect = new Rect(left, screenSize.height - bottom, right,
|
||||
(screenSize.height - bottom) + (bottom - top));
|
||||
scissorRect.offset(Math.round(-mRenderOffset.x), Math.round(-mRenderOffset.y));
|
||||
|
||||
return scissorRect;
|
||||
return new Rect(left, screenSize.height - bottom, right,
|
||||
(screenSize.height - bottom) + (bottom - top));
|
||||
}
|
||||
|
||||
/** This function is invoked via JNI; be careful when modifying signature. */
|
||||
@ -560,9 +544,7 @@ public class LayerRenderer implements Tabs.OnTabsChangedListener {
|
||||
GLES20.glDisable(GLES20.GL_SCISSOR_TEST);
|
||||
|
||||
// Draw the drop shadow, if we need to.
|
||||
RectF offsetAbsPageRect = new RectF(mAbsolutePageRect);
|
||||
offsetAbsPageRect.offset(mRenderOffset.x, mRenderOffset.y);
|
||||
if (!offsetAbsPageRect.contains(mFrameMetrics.getViewport()))
|
||||
if (!new RectF(mAbsolutePageRect).contains(mFrameMetrics.getViewport()))
|
||||
mShadowLayer.draw(mPageContext);
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,6 @@ public class LayerView extends FrameLayout {
|
||||
|
||||
private GeckoLayerClient mLayerClient;
|
||||
private PanZoomController mPanZoomController;
|
||||
private LayerMarginsAnimator mMarginsAnimator;
|
||||
private GLController mGLController;
|
||||
private InputConnectionHandler mInputConnectionHandler;
|
||||
private LayerRenderer mRenderer;
|
||||
@ -101,7 +100,6 @@ public class LayerView extends FrameLayout {
|
||||
public void initializeView(EventDispatcher eventDispatcher) {
|
||||
mLayerClient = new GeckoLayerClient(getContext(), this, eventDispatcher);
|
||||
mPanZoomController = mLayerClient.getPanZoomController();
|
||||
mMarginsAnimator = mLayerClient.getLayerMarginsAnimator();
|
||||
|
||||
mRenderer = new LayerRenderer(this);
|
||||
mInputConnectionHandler = null;
|
||||
@ -209,7 +207,6 @@ public class LayerView extends FrameLayout {
|
||||
|
||||
public GeckoLayerClient getLayerClient() { return mLayerClient; }
|
||||
public PanZoomController getPanZoomController() { return mPanZoomController; }
|
||||
public LayerMarginsAnimator getLayerMarginsAnimator() { return mMarginsAnimator; }
|
||||
|
||||
public ImmutableViewportMetrics getViewportMetrics() {
|
||||
return mLayerClient.getViewportMetrics();
|
||||
@ -239,10 +236,6 @@ public class LayerView extends FrameLayout {
|
||||
mLayerClient.setZoomConstraints(constraints);
|
||||
}
|
||||
|
||||
public void setIsRTL(boolean aIsRTL) {
|
||||
mLayerClient.setIsRTL(aIsRTL);
|
||||
}
|
||||
|
||||
public void setInputConnectionHandler(InputConnectionHandler inputConnectionHandler) {
|
||||
mInputConnectionHandler = inputConnectionHandler;
|
||||
mLayerClient.forceRedraw();
|
||||
|
@ -75,8 +75,8 @@ public class NinePatchTileLayer extends TileLayer {
|
||||
float tileX, float tileY, float tileWidth, float tileHeight) {
|
||||
RectF viewport = context.viewport;
|
||||
float viewportHeight = viewport.height();
|
||||
float drawX = tileX - viewport.left - context.offset.x;
|
||||
float drawY = viewportHeight - (tileY + tileHeight - viewport.top) - context.offset.y;
|
||||
float drawX = tileX - viewport.left;
|
||||
float drawY = viewportHeight - (tileY + tileHeight - viewport.top);
|
||||
|
||||
float[] coords = {
|
||||
//x, y, z, texture_x, texture_y
|
||||
|
@ -16,8 +16,6 @@ public interface PanZoomTarget {
|
||||
|
||||
public void setAnimationTarget(ImmutableViewportMetrics viewport);
|
||||
public void setViewportMetrics(ImmutableViewportMetrics viewport);
|
||||
public void scrollBy(float dx, float dy);
|
||||
public void panZoomStopped();
|
||||
/** This triggers an (asynchronous) viewport update/redraw. */
|
||||
public void forceRedraw();
|
||||
|
||||
|
@ -188,7 +188,6 @@ public class ScrollbarLayer extends TileLayer {
|
||||
float viewHeight = context.viewport.height();
|
||||
|
||||
mBarRectF.set(mBarRect.left, viewHeight - mBarRect.top, mBarRect.right, viewHeight - mBarRect.bottom);
|
||||
mBarRectF.offset(context.offset.x, -context.offset.y);
|
||||
|
||||
// We take a 1-pixel slice from the center of the image and scale it to become the bar
|
||||
fillRectCoordBuffer(mCoords, mBarRectF, viewWidth, viewHeight, mBodyTexCoords, mTexWidth, mTexHeight);
|
||||
|
@ -13,8 +13,6 @@ public class ViewTransform {
|
||||
public float fixedLayerMarginTop;
|
||||
public float fixedLayerMarginRight;
|
||||
public float fixedLayerMarginBottom;
|
||||
public float offsetX;
|
||||
public float offsetY;
|
||||
|
||||
public ViewTransform(float inX, float inY, float inScale) {
|
||||
x = inX;
|
||||
@ -24,8 +22,6 @@ public class ViewTransform {
|
||||
fixedLayerMarginTop = 0;
|
||||
fixedLayerMarginRight = 0;
|
||||
fixedLayerMarginBottom = 0;
|
||||
offsetX = 0;
|
||||
offsetY = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3462,8 +3462,6 @@ Tab.prototype = {
|
||||
if (aMetadata.maxZoom > 0)
|
||||
aMetadata.maxZoom *= scaleRatio;
|
||||
|
||||
aMetadata.isRTL = this.browser.contentDocument.documentElement.dir == "rtl";
|
||||
|
||||
ViewportHandler.setMetadataForDocument(this.browser.contentDocument, aMetadata);
|
||||
this.updateViewportSize(gScreenWidth, aInitialLoad);
|
||||
this.sendViewportMetadata();
|
||||
@ -3592,7 +3590,6 @@ Tab.prototype = {
|
||||
defaultZoom: metadata.defaultZoom || metadata.scaleRatio,
|
||||
minZoom: metadata.minZoom || 0,
|
||||
maxZoom: metadata.maxZoom || 0,
|
||||
isRTL: metadata.isRTL,
|
||||
tabID: this.id
|
||||
});
|
||||
},
|
||||
@ -5114,8 +5111,6 @@ var ViewportHandler = {
|
||||
(!widthStr && (heightStr == "device-height" || scale == 1.0)));
|
||||
}
|
||||
|
||||
let isRTL = aWindow.document.documentElement.dir == "rtl";
|
||||
|
||||
return new ViewportMetadata({
|
||||
defaultZoom: scale,
|
||||
minZoom: minScale,
|
||||
@ -5124,8 +5119,7 @@ var ViewportHandler = {
|
||||
height: height,
|
||||
autoSize: autoSize,
|
||||
allowZoom: allowZoom,
|
||||
isSpecified: hasMetaViewport,
|
||||
isRTL: isRTL
|
||||
isSpecified: hasMetaViewport
|
||||
});
|
||||
},
|
||||
|
||||
@ -5197,7 +5191,6 @@ function ViewportMetadata(aMetadata = {}) {
|
||||
this.allowZoom = ("allowZoom" in aMetadata) ? aMetadata.allowZoom : true;
|
||||
this.isSpecified = ("isSpecified" in aMetadata) ? aMetadata.isSpecified : false;
|
||||
this.scaleRatio = ViewportHandler.getScaleRatio();
|
||||
this.isRTL = ("isRTL" in aMetadata) ? aMetadata.isRTL : false;
|
||||
Object.seal(this);
|
||||
}
|
||||
|
||||
@ -5211,7 +5204,6 @@ ViewportMetadata.prototype = {
|
||||
allowZoom: null,
|
||||
isSpecified: null,
|
||||
scaleRatio: null,
|
||||
isRTL: null,
|
||||
};
|
||||
|
||||
|
||||
|
@ -2109,15 +2109,14 @@ AndroidBridge::SetPageRect(const gfx::Rect& aCssPageRect)
|
||||
void
|
||||
AndroidBridge::SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
|
||||
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
|
||||
gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY)
|
||||
gfx::Margin& aFixedLayerMargins)
|
||||
{
|
||||
AndroidGeckoLayerClient *client = mLayerClient;
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
client->SyncViewportInfo(aDisplayPort, aDisplayResolution, aLayersUpdated,
|
||||
aScrollOffset, aScaleX, aScaleY, aFixedLayerMargins,
|
||||
aOffsetX, aOffsetY);
|
||||
aScrollOffset, aScaleX, aScaleY, aFixedLayerMargins);
|
||||
}
|
||||
|
||||
AndroidBridge::AndroidBridge()
|
||||
|
@ -342,7 +342,7 @@ public:
|
||||
void SetPageRect(const gfx::Rect& aCssPageRect);
|
||||
void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
|
||||
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
|
||||
gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY);
|
||||
gfx::Margin& aFixedLayerMargins);
|
||||
|
||||
void AddPluginView(jobject view, const gfxRect& rect, bool isFullScreen);
|
||||
void RemovePluginView(jobject view, bool isFullScreen);
|
||||
|
@ -112,8 +112,6 @@ jfieldID AndroidViewTransform::jFixedLayerMarginLeft = 0;
|
||||
jfieldID AndroidViewTransform::jFixedLayerMarginTop = 0;
|
||||
jfieldID AndroidViewTransform::jFixedLayerMarginRight = 0;
|
||||
jfieldID AndroidViewTransform::jFixedLayerMarginBottom = 0;
|
||||
jfieldID AndroidViewTransform::jOffsetXField = 0;
|
||||
jfieldID AndroidViewTransform::jOffsetYField = 0;
|
||||
|
||||
jclass AndroidProgressiveUpdateData::jProgressiveUpdateDataClass = 0;
|
||||
jfieldID AndroidProgressiveUpdateData::jXField = 0;
|
||||
@ -391,8 +389,6 @@ AndroidViewTransform::InitViewTransformClass(JNIEnv *jEnv)
|
||||
jFixedLayerMarginTop = getField("fixedLayerMarginTop", "F");
|
||||
jFixedLayerMarginRight = getField("fixedLayerMarginRight", "F");
|
||||
jFixedLayerMarginBottom = getField("fixedLayerMarginBottom", "F");
|
||||
jOffsetXField = getField("offsetX", "F");
|
||||
jOffsetYField = getField("offsetY", "F");
|
||||
}
|
||||
|
||||
void
|
||||
@ -828,7 +824,7 @@ AndroidGeckoLayerClient::SetPageRect(const gfx::Rect& aCssPageRect)
|
||||
void
|
||||
AndroidGeckoLayerClient::SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
|
||||
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
|
||||
gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY)
|
||||
gfx::Margin& aFixedLayerMargins)
|
||||
{
|
||||
NS_ASSERTION(!isNull(), "SyncViewportInfo called on null layer client!");
|
||||
JNIEnv *env = GetJNIForThread(); // this is called on the compositor thread
|
||||
@ -852,9 +848,6 @@ AndroidGeckoLayerClient::SyncViewportInfo(const nsIntRect& aDisplayPort, float a
|
||||
aScrollOffset = nsIntPoint(viewTransform.GetX(env), viewTransform.GetY(env));
|
||||
aScaleX = aScaleY = viewTransform.GetScale(env);
|
||||
viewTransform.GetFixedLayerMargins(env, aFixedLayerMargins);
|
||||
|
||||
aOffsetX = viewTransform.GetOffsetX(env);
|
||||
aOffsetY = viewTransform.GetOffsetY(env);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1101,22 +1094,6 @@ AndroidViewTransform::GetFixedLayerMargins(JNIEnv *env, gfx::Margin &aFixedLayer
|
||||
aFixedLayerMargins.left = env->GetFloatField(wrapped_obj, jFixedLayerMarginLeft);
|
||||
}
|
||||
|
||||
float
|
||||
AndroidViewTransform::GetOffsetX(JNIEnv *env)
|
||||
{
|
||||
if (!env)
|
||||
return 0.0f;
|
||||
return env->GetFloatField(wrapped_obj, jOffsetXField);
|
||||
}
|
||||
|
||||
float
|
||||
AndroidViewTransform::GetOffsetY(JNIEnv *env)
|
||||
{
|
||||
if (!env)
|
||||
return 0.0f;
|
||||
return env->GetFloatField(wrapped_obj, jOffsetYField);
|
||||
}
|
||||
|
||||
float
|
||||
AndroidProgressiveUpdateData::GetX(JNIEnv *env)
|
||||
{
|
||||
|
@ -195,8 +195,6 @@ public:
|
||||
float GetY(JNIEnv *env);
|
||||
float GetScale(JNIEnv *env);
|
||||
void GetFixedLayerMargins(JNIEnv *env, gfx::Margin &aFixedLayerMargins);
|
||||
float GetOffsetX(JNIEnv *env);
|
||||
float GetOffsetY(JNIEnv *env);
|
||||
|
||||
private:
|
||||
static jclass jViewTransformClass;
|
||||
@ -207,8 +205,6 @@ private:
|
||||
static jfieldID jFixedLayerMarginTop;
|
||||
static jfieldID jFixedLayerMarginRight;
|
||||
static jfieldID jFixedLayerMarginBottom;
|
||||
static jfieldID jOffsetXField;
|
||||
static jfieldID jOffsetYField;
|
||||
};
|
||||
|
||||
class AndroidProgressiveUpdateData : public WrappedJavaObject {
|
||||
@ -270,7 +266,7 @@ public:
|
||||
void SetPageRect(const gfx::Rect& aCssPageRect);
|
||||
void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated,
|
||||
nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY,
|
||||
gfx::Margin& aFixedLayerMargins, float& aOffsetX, float& aOffsetY);
|
||||
gfx::Margin& aFixedLayerMargins);
|
||||
bool ProgressiveUpdateCallback(bool aHasPendingNewThebesContent, const gfx::Rect& aDisplayPort, float aDisplayResolution, bool aDrawingCritical, gfx::Rect& aViewport, float& aScaleX, float& aScaleY);
|
||||
bool CreateFrame(AutoLocalJNIFrame *jniFrame, AndroidLayerRendererFrame& aFrame);
|
||||
bool ActivateProgram(AutoLocalJNIFrame *jniFrame);
|
||||
|
Loading…
x
Reference in New Issue
Block a user