michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.gfx; michael@0: michael@0: import org.mozilla.gecko.GeckoAppShell; michael@0: import org.mozilla.gecko.util.FloatUtils; michael@0: import org.mozilla.gecko.util.ThreadUtils; michael@0: michael@0: import android.graphics.PointF; michael@0: import android.graphics.Rect; michael@0: import android.graphics.RectF; michael@0: import android.view.SurfaceView; michael@0: import android.view.View; michael@0: import android.widget.AbsoluteLayout; michael@0: michael@0: public class PluginLayer extends TileLayer { michael@0: private static final String LOGTAG = "PluginLayer"; michael@0: michael@0: private View mView; michael@0: private SurfaceView mSurfaceView; michael@0: private PluginLayoutParams mLayoutParams; michael@0: private AbsoluteLayout mContainer; michael@0: michael@0: private boolean mDestroyed; michael@0: private boolean mViewVisible; michael@0: michael@0: private RectF mLastViewport; michael@0: private float mLastZoomFactor; michael@0: michael@0: private static final float TEXTURE_MAP[] = { michael@0: 0.0f, 1.0f, // top left michael@0: 0.0f, 0.0f, // bottom left michael@0: 1.0f, 1.0f, // top right michael@0: 1.0f, 0.0f, // bottom right michael@0: }; michael@0: michael@0: public PluginLayer(View view, RectF rect, int maxDimension) { michael@0: super(new BufferedCairoImage(null, 0, 0, 0), TileLayer.PaintMode.NORMAL); michael@0: michael@0: mView = view; michael@0: mContainer = GeckoAppShell.getGeckoInterface().getPluginContainer(); michael@0: michael@0: mView.setWillNotDraw(false); michael@0: if (mView instanceof SurfaceView) { michael@0: mSurfaceView = (SurfaceView)view; michael@0: mSurfaceView.setZOrderOnTop(false); michael@0: mSurfaceView.setZOrderMediaOverlay(true); michael@0: } michael@0: michael@0: mLayoutParams = new PluginLayoutParams(rect, maxDimension); michael@0: } michael@0: michael@0: public void setVisible(boolean visible) { michael@0: if (visible) { michael@0: showView(); michael@0: } else { michael@0: hideView(); michael@0: } michael@0: } michael@0: michael@0: private void hideView() { michael@0: if (mViewVisible) { michael@0: ThreadUtils.postToUiThread(new Runnable() { michael@0: @Override michael@0: public void run() { michael@0: mView.setVisibility(View.GONE); michael@0: mViewVisible = false; michael@0: } michael@0: }); michael@0: } michael@0: } michael@0: michael@0: public void showView() { michael@0: ThreadUtils.postToUiThread(new Runnable() { michael@0: @Override michael@0: public void run() { michael@0: if (mContainer.indexOfChild(mView) < 0) { michael@0: mContainer.addView(mView, mLayoutParams); michael@0: } else { michael@0: mContainer.updateViewLayout(mView, mLayoutParams); michael@0: mView.setVisibility(View.VISIBLE); michael@0: } michael@0: mViewVisible = true; michael@0: } michael@0: }); michael@0: } michael@0: michael@0: @Override michael@0: public void destroy() { michael@0: mDestroyed = true; michael@0: michael@0: mContainer.removeView(mView); michael@0: } michael@0: michael@0: public void reset(RectF rect) { michael@0: mLayoutParams.reset(rect); michael@0: } michael@0: michael@0: @Override michael@0: protected void performUpdates(RenderContext context) { michael@0: if (mDestroyed) michael@0: return; michael@0: michael@0: if (!RectUtils.fuzzyEquals(context.viewport, mLastViewport) || michael@0: !FloatUtils.fuzzyEquals(context.zoomFactor, mLastZoomFactor)) { michael@0: michael@0: mLastZoomFactor = context.zoomFactor; michael@0: mLastViewport = context.viewport; michael@0: mLayoutParams.reposition(context.viewport, context.offset, context.zoomFactor); michael@0: michael@0: showView(); michael@0: } michael@0: } michael@0: michael@0: @Override michael@0: public void draw(RenderContext context) { michael@0: } michael@0: michael@0: class PluginLayoutParams extends AbsoluteLayout.LayoutParams michael@0: { michael@0: private static final String LOGTAG = "GeckoApp.PluginLayoutParams"; michael@0: michael@0: private RectF mRect; michael@0: private int mMaxDimension; michael@0: private float mLastResolution; michael@0: michael@0: public PluginLayoutParams(RectF rect, int maxDimension) { michael@0: super(0, 0, 0, 0); michael@0: michael@0: mMaxDimension = maxDimension; michael@0: reset(rect); michael@0: } michael@0: michael@0: private void clampToMaxSize() { michael@0: if (width > mMaxDimension || height > mMaxDimension) { michael@0: if (width > height) { michael@0: height = Math.round(((float)height/(float)width) * mMaxDimension); michael@0: width = mMaxDimension; michael@0: } else { michael@0: width = Math.round(((float)width/(float)height) * mMaxDimension); michael@0: height = mMaxDimension; michael@0: } michael@0: } michael@0: } michael@0: michael@0: public void reset(RectF rect) { michael@0: mRect = rect; michael@0: } michael@0: michael@0: public void reposition(RectF viewport, PointF offset, float zoomFactor) { michael@0: michael@0: RectF scaled = RectUtils.scale(mRect, zoomFactor); michael@0: scaled.offset(offset.x, offset.y); michael@0: michael@0: this.x = Math.round(scaled.left - viewport.left); michael@0: this.y = Math.round(scaled.top - viewport.top); michael@0: michael@0: if (!FloatUtils.fuzzyEquals(mLastResolution, zoomFactor)) { michael@0: width = Math.round(mRect.width() * zoomFactor); michael@0: height = Math.round(mRect.height() * zoomFactor); michael@0: mLastResolution = zoomFactor; michael@0: michael@0: clampToMaxSize(); michael@0: } michael@0: } michael@0: } michael@0: }