Bug 1180295 - Update the ZoomedView calculations to account for the new dynamic toolbar model. r=rbarker

This commit is contained in:
Kartikaya Gupta 2015-08-18 14:27:20 -04:00
parent c3ade15dae
commit 87fac6d26a
3 changed files with 68 additions and 85 deletions

View File

@ -5,6 +5,7 @@
package org.mozilla.gecko;
import org.mozilla.gecko.animation.ViewHelper;
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
import org.mozilla.gecko.gfx.LayerView;
import org.mozilla.gecko.gfx.PanZoomController;
@ -48,7 +49,7 @@ import android.widget.TextView;
import java.nio.ByteBuffer;
import java.text.DecimalFormat;
public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChangedListener,
public class ZoomedView extends FrameLayout implements LayerView.DynamicToolbarListener,
LayerView.ZoomedViewListener, GeckoEventListener {
private static final String LOGTAG = "Gecko" + ZoomedView.class.getSimpleName();
@ -85,6 +86,7 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
private float offsetDueToToolBarPosition;
private int toolbarHeight;
private int cornerRadius;
private float dynamicToolbarOverlap;
private boolean stopUpdateView;
@ -300,37 +302,41 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
* LayerView
*/
private PointF getUnzoomedPositionFromPointInZoomedView(float x, float y) {
if (toolbarOnTop && y > toolbarHeight) {
y = y - toolbarHeight;
}
ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
PointF offset = metrics.getMarginOffset();
final float parentWidth = metrics.getWidth();
final float parentHeight = metrics.getHeight();
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) getLayoutParams();
returnValue.x = (int) ((x / zoomFactor) + // Conversion of the x offset inside the zoomed view (using the scale factor)
// The number of unzoomed content pixels that can be displayed in the
// zoomed area.
float visibleContentPixels = viewWidth / zoomFactor;
// The offset in content pixels of the leftmost zoomed pixel from the
// layerview's left edge when the zoomed view is moved to the right as
// far as it can go.
float maxContentOffset = parentWidth - visibleContentPixels;
// The maximum offset in screen pixels that the zoomed view can have
float maxZoomedViewOffset = parentWidth - viewContainerWidth;
offset.x + // The offset of the layerView
// The above values allow us to compute the term
// maxContentOffset / maxZoomedViewOffset
// which is the number of content pixels that we should move over by
// for every screen pixel that the zoomed view is moved over by.
// This allows a smooth transition from when the zoomed view is at the
// leftmost extent to when it is at the rightmost extent.
/* Conversion of the left side position of the zoomed view
* Minimum value for the left side of the zoomed view is 0
* and we return 0 after conversion
* Maximum value for the left side of the zoomed view is (parentWidth - offset.x - viewContainerWidth)
* and we return (parentWidth - offset.x - (viewWidth / zoomFactor)) after conversion.
*/
(((float) params.leftMargin) - offset.x) *
((parentWidth - offset.x - (viewWidth / zoomFactor)) /
(parentWidth - offset.x - viewContainerWidth)));
// This is the offset in content pixels of the leftmost zoomed pixel
// visible in the zoomed view. This value is relative to the layerview
// edge.
float zoomedContentOffset = ((float)params.leftMargin) * maxContentOffset / maxZoomedViewOffset;
returnValue.x = (int)(zoomedContentOffset + (x / zoomFactor));
// Same comments here vertically
returnValue.y = (int) ((y / zoomFactor) +
offset.y -
offsetDueToToolBarPosition +
(((float) params.topMargin) - offset.y) *
((parentHeight - offset.y + offsetDueToToolBarPosition - (viewHeight / zoomFactor)) /
(parentHeight - offset.y - viewContainerHeight)));
visibleContentPixels = viewHeight / zoomFactor;
maxContentOffset = parentHeight - visibleContentPixels;
maxZoomedViewOffset = parentHeight - (viewContainerHeight - toolbarHeight);
float zoomedAreaOffset = (float)params.topMargin + offsetDueToToolBarPosition - ViewHelper.getTranslationY(layerView);
zoomedContentOffset = zoomedAreaOffset * maxContentOffset / maxZoomedViewOffset;
returnValue.y = (int)(zoomedContentOffset + ((y - offsetDueToToolBarPosition) / zoomFactor));
return returnValue;
}
@ -342,61 +348,53 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
*/
private PointF getZoomedViewTopLeftPositionFromTouchPosition(float x, float y) {
ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
PointF offset = metrics.getMarginOffset();
final float parentWidth = metrics.getWidth();
final float parentHeight = metrics.getHeight();
returnValue.x = (int) ((((x - (viewWidth / (2 * zoomFactor)))) / // Translation to get the left side position of the zoomed view
// centered on x (the value 2 to get the middle).
// See comments in getUnzoomedPositionFromPointInZoomedView, but the
// transformations here are largely the reverse of that function.
/* Conversion of the left side position of the zoomed view.
* See the comment in getUnzoomedPositionFromPointInZoomedView.
* The proportional factor is the same. It is used in a division
* and not in a multiplication to convert the position from
* the LayerView to the ZoomedView.
*/
((parentWidth - offset.x - (viewWidth / zoomFactor)) /
(parentWidth - offset.x - viewContainerWidth)))
float visibleContentPixels = viewWidth / zoomFactor;
float maxContentOffset = parentWidth - visibleContentPixels;
float maxZoomedViewOffset = parentWidth - viewContainerWidth;
float contentPixelOffset = x - (visibleContentPixels / 2.0f);
returnValue.x = (int)(contentPixelOffset * (maxZoomedViewOffset / maxContentOffset));
+ offset.x); // The offset of the layerView
// Same comments here vertically
returnValue.y = (int) ((((y + offsetDueToToolBarPosition - (viewHeight / (2 * zoomFactor)))) /
((parentHeight - offset.y + offsetDueToToolBarPosition - (viewHeight / zoomFactor)) /
(parentHeight - offset.y - viewContainerHeight)))
+ offset.y);
visibleContentPixels = viewHeight / zoomFactor;
maxContentOffset = parentHeight - visibleContentPixels;
maxZoomedViewOffset = parentHeight - (viewContainerHeight - toolbarHeight);
contentPixelOffset = y - (visibleContentPixels / 2.0f);
float unscaledViewOffset = ViewHelper.getTranslationY(layerView) - offsetDueToToolBarPosition;
returnValue.y = (int)((contentPixelOffset * (maxZoomedViewOffset / maxContentOffset)) + unscaledViewOffset);
return returnValue;
}
private void moveZoomedView(ImmutableViewportMetrics metrics, float newLeftMargin, float newTopMargin,
StartPointUpdate animateStartPoint) {
final float parentWidth = metrics.getWidth();
final float parentHeight = metrics.getHeight();
RelativeLayout.LayoutParams newLayoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
newLayoutParams.leftMargin = (int) newLeftMargin;
newLayoutParams.topMargin = (int) newTopMargin;
int topMarginMin;
int leftMarginMin;
PointF offset = metrics.getMarginOffset();
topMarginMin = (int) offset.y;
leftMarginMin = (int) offset.x;
int topMarginMin = (int)(ViewHelper.getTranslationY(layerView) + dynamicToolbarOverlap);
int topMarginMax = layerView.getHeight() - viewContainerHeight;
int leftMarginMin = 0;
int leftMarginMax = layerView.getWidth() - viewContainerWidth;
if (newTopMargin < topMarginMin) {
newLayoutParams.topMargin = topMarginMin;
} else if (newTopMargin + viewContainerHeight > parentHeight) {
newLayoutParams.topMargin = (int) (parentHeight - viewContainerHeight);
} else if (newTopMargin > topMarginMax) {
newLayoutParams.topMargin = topMarginMax;
}
if (newLeftMargin < leftMarginMin) {
newLayoutParams.leftMargin = leftMarginMin;
} else if (newLeftMargin + viewContainerWidth > parentWidth) {
newLayoutParams.leftMargin = (int) (parentWidth - viewContainerWidth);
} else if (newLeftMargin > leftMarginMax) {
newLayoutParams.leftMargin = leftMarginMax;
}
if (newLayoutParams.topMargin < topMarginMin + 1) {
moveToolbar(false);
} else if (newLayoutParams.topMargin + viewContainerHeight > parentHeight - 1) {
} else if (newLayoutParams.topMargin > topMarginMax - 1) {
moveToolbar(true);
}
@ -417,7 +415,7 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
}
setLayoutParams(newLayoutParams);
PointF convertedPosition = getUnzoomedPositionFromPointInZoomedView(0, 0);
PointF convertedPosition = getUnzoomedPositionFromPointInZoomedView(0, offsetDueToToolBarPosition);
lastPosition = PointUtils.round(convertedPosition);
requestZoomedViewRender();
}
@ -536,11 +534,11 @@ public class ZoomedView extends FrameLayout implements LayerView.OnMetricsChange
});
}
private void startZoomDisplay(LayerView aLayerView, final int leftFromGecko, final int topFromGecko) {
private void startZoomDisplay(LayerView aLayerView, final int leftFromGecko, final int topFromGecko) {
if (layerView == null) {
layerView = aLayerView;
layerView.addZoomedViewListener(this);
layerView.setOnMetricsChangedZoomedViewportListener(this);
layerView.getDynamicToolbarAnimator().addTranslationListener(this);
ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
setCapturedSize(metrics);
}
@ -548,12 +546,11 @@ private void startZoomDisplay(LayerView aLayerView, final int leftFromGecko, fin
shouldSetVisibleOnUpdate = true;
ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
PointF offset = metrics.getMarginOffset();
// At this point, the start point is relative to the layerView.
// Later, it will be converted relative to the zoomed view as soon as
// the position of the zoomed view will be calculated.
animationStart.x = (float) leftFromGecko * metrics.zoomFactor + offset.x;
animationStart.y = (float) topFromGecko * metrics.zoomFactor + offset.y;
animationStart.x = (float) leftFromGecko * metrics.zoomFactor;
animationStart.y = (float) topFromGecko * metrics.zoomFactor + ViewHelper.getTranslationY(layerView);
moveUsingGeckoPosition(leftFromGecko, topFromGecko);
}
@ -564,7 +561,7 @@ private void startZoomDisplay(LayerView aLayerView, final int leftFromGecko, fin
hideZoomedView(withAnimation);
ThreadUtils.removeCallbacksFromUiThread(requestRenderRunnable);
if (layerView != null) {
layerView.setOnMetricsChangedZoomedViewportListener(null);
layerView.getDynamicToolbarAnimator().removeTranslationListener(this);
layerView.removeZoomedViewListener(this);
layerView = null;
}
@ -634,6 +631,15 @@ private void startZoomDisplay(LayerView aLayerView, final int leftFromGecko, fin
moveZoomedView(metrics, convertedPosition.x, convertedPosition.y, StartPointUpdate.GECKO_POSITION);
}
@Override
public void onTranslationChanged(float aToolbarTranslation, float aLayerViewTranslation) {
ThreadUtils.assertOnUiThread();
if (layerView != null) {
dynamicToolbarOverlap = aLayerViewTranslation - aToolbarTranslation;
refreshZoomedViewSize(layerView.getViewportMetrics());
}
}
@Override
public void onMetricsChanged(final ImmutableViewportMetrics viewport) {
// It can be called from a Gecko thread (forceViewportMetrics in GeckoLayerClient).
@ -788,10 +794,9 @@ private void startZoomDisplay(LayerView aLayerView, final int leftFromGecko, fin
ImmutableViewportMetrics metrics = layerView.getViewportMetrics();
PointF origin = metrics.getOrigin();
PointF offset = metrics.getMarginOffset();
final int xPos = (int) (origin.x - offset.x) + lastPosition.x;
final int yPos = (int) (origin.y - offset.y) + lastPosition.y;
final int xPos = (int)origin.x + lastPosition.x;
final int yPos = (int)origin.y + lastPosition.y;
GeckoEvent e = GeckoEvent.createZoomedViewEvent(tabId, xPos, yPos, viewWidth,
viewHeight, zoomFactor * metrics.zoomFactor, buffer);

View File

@ -88,7 +88,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
* that because mViewportMetrics might get reassigned in between reading the different
* fields. */
private volatile ImmutableViewportMetrics mViewportMetrics;
private LayerView.OnMetricsChangedListener mZoomedViewViewportChangeListener;
private ZoomConstraints mZoomConstraints;
@ -836,9 +835,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
*/
private void viewportMetricsChanged(boolean notifyGecko) {
mToolbarAnimator.onMetricsChanged(mViewportMetrics);
if (mZoomedViewViewportChangeListener != null) {
mZoomedViewViewportChangeListener.onMetricsChanged(mViewportMetrics);
}
mView.requestRender();
if (notifyGecko && mGeckoIsReady) {
@ -879,9 +875,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
@Override
public void panZoomStopped() {
mToolbarAnimator.onPanZoomStopped();
if (mZoomedViewViewportChangeListener != null) {
mZoomedViewViewportChangeListener.onPanZoomStopped();
}
}
/** Implementation of PanZoomTarget */
@ -951,10 +944,6 @@ class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
return layerPoint;
}
void setOnMetricsChangedZoomedViewportListener(LayerView.OnMetricsChangedListener listener) {
mZoomedViewViewportChangeListener = listener;
}
public void addDrawListener(DrawListener listener) {
mDrawListeners.add(listener);
}

View File

@ -673,17 +673,6 @@ public class LayerView extends FrameLayout implements Tabs.OnTabsChangedListener
public void onMetricsChanged(ImmutableViewportMetrics viewport);
}
// Public hooks for listening to metrics changing
public interface OnMetricsChangedListener {
public void onMetricsChanged(ImmutableViewportMetrics viewport);
public void onPanZoomStopped();
}
public void setOnMetricsChangedZoomedViewportListener(OnMetricsChangedListener listener) {
mLayerClient.setOnMetricsChangedZoomedViewportListener(listener);
}
// Public hooks for zoomed view
public interface ZoomedViewListener {