gecko-dev/mobile/android/base/gfx/PluginLayer.java

170 lines
5.0 KiB
Java

/* 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.util.FloatUtils;
import org.mozilla.gecko.util.ThreadUtils;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.SurfaceView;
import android.view.View;
import android.widget.AbsoluteLayout;
public class PluginLayer extends TileLayer {
private static final String LOGTAG = "PluginLayer";
private final View mView;
private SurfaceView mSurfaceView;
private final PluginLayoutParams mLayoutParams;
private final AbsoluteLayout mContainer;
private boolean mDestroyed;
private boolean mViewVisible;
private RectF mLastViewport;
private float mLastZoomFactor;
private static final float TEXTURE_MAP[] = {
0.0f, 1.0f, // top left
0.0f, 0.0f, // bottom left
1.0f, 1.0f, // top right
1.0f, 0.0f, // bottom right
};
public PluginLayer(View view, RectF rect, int maxDimension) {
super(new BufferedCairoImage(null, 0, 0, 0), TileLayer.PaintMode.NORMAL);
mView = view;
mContainer = GeckoAppShell.getGeckoInterface().getPluginContainer();
mView.setWillNotDraw(false);
if (mView instanceof SurfaceView) {
mSurfaceView = (SurfaceView)view;
mSurfaceView.setZOrderOnTop(false);
mSurfaceView.setZOrderMediaOverlay(true);
}
mLayoutParams = new PluginLayoutParams(rect, maxDimension);
}
public void setVisible(boolean visible) {
if (visible) {
showView();
} else {
hideView();
}
}
private void hideView() {
if (mViewVisible) {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
mView.setVisibility(View.GONE);
mViewVisible = false;
}
});
}
}
public void showView() {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (mContainer.indexOfChild(mView) < 0) {
mContainer.addView(mView, mLayoutParams);
} else {
mContainer.updateViewLayout(mView, mLayoutParams);
mView.setVisibility(View.VISIBLE);
}
mViewVisible = true;
}
});
}
@Override
public void destroy() {
mDestroyed = true;
mContainer.removeView(mView);
}
public void reset(RectF rect) {
mLayoutParams.reset(rect);
}
@Override
protected void performUpdates(RenderContext context) {
if (mDestroyed)
return;
if (!RectUtils.fuzzyEquals(context.viewport, mLastViewport) ||
!FloatUtils.fuzzyEquals(context.zoomFactor, mLastZoomFactor)) {
mLastZoomFactor = context.zoomFactor;
mLastViewport = context.viewport;
mLayoutParams.reposition(context.viewport, context.offset, context.zoomFactor);
showView();
}
}
@Override
public void draw(RenderContext context) {
}
class PluginLayoutParams extends AbsoluteLayout.LayoutParams
{
private static final String LOGTAG = "GeckoApp.PluginLayoutParams";
private RectF mRect;
private final int mMaxDimension;
private float mLastResolution;
public PluginLayoutParams(RectF rect, int maxDimension) {
super(0, 0, 0, 0);
mMaxDimension = maxDimension;
reset(rect);
}
private void clampToMaxSize() {
if (width > mMaxDimension || height > mMaxDimension) {
if (width > height) {
height = Math.round(((float)height/ width) * mMaxDimension);
width = mMaxDimension;
} else {
width = Math.round(((float)width/ height) * mMaxDimension);
height = mMaxDimension;
}
}
}
public void reset(RectF rect) {
mRect = rect;
}
public void reposition(RectF viewport, PointF offset, float zoomFactor) {
RectF scaled = RectUtils.scale(mRect, zoomFactor);
scaled.offset(offset.x, offset.y);
this.x = Math.round(scaled.left - viewport.left);
this.y = Math.round(scaled.top - viewport.top);
if (!FloatUtils.fuzzyEquals(mLastResolution, zoomFactor)) {
width = Math.round(mRect.width() * zoomFactor);
height = Math.round(mRect.height() * zoomFactor);
mLastResolution = zoomFactor;
clampToMaxSize();
}
}
}
}