|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 package org.mozilla.gecko.gfx; |
|
6 |
|
7 import org.mozilla.gecko.GeckoAppShell; |
|
8 import org.mozilla.gecko.util.FloatUtils; |
|
9 import org.mozilla.gecko.util.ThreadUtils; |
|
10 |
|
11 import android.graphics.PointF; |
|
12 import android.graphics.Rect; |
|
13 import android.graphics.RectF; |
|
14 import android.view.SurfaceView; |
|
15 import android.view.View; |
|
16 import android.widget.AbsoluteLayout; |
|
17 |
|
18 public class PluginLayer extends TileLayer { |
|
19 private static final String LOGTAG = "PluginLayer"; |
|
20 |
|
21 private View mView; |
|
22 private SurfaceView mSurfaceView; |
|
23 private PluginLayoutParams mLayoutParams; |
|
24 private AbsoluteLayout mContainer; |
|
25 |
|
26 private boolean mDestroyed; |
|
27 private boolean mViewVisible; |
|
28 |
|
29 private RectF mLastViewport; |
|
30 private float mLastZoomFactor; |
|
31 |
|
32 private static final float TEXTURE_MAP[] = { |
|
33 0.0f, 1.0f, // top left |
|
34 0.0f, 0.0f, // bottom left |
|
35 1.0f, 1.0f, // top right |
|
36 1.0f, 0.0f, // bottom right |
|
37 }; |
|
38 |
|
39 public PluginLayer(View view, RectF rect, int maxDimension) { |
|
40 super(new BufferedCairoImage(null, 0, 0, 0), TileLayer.PaintMode.NORMAL); |
|
41 |
|
42 mView = view; |
|
43 mContainer = GeckoAppShell.getGeckoInterface().getPluginContainer(); |
|
44 |
|
45 mView.setWillNotDraw(false); |
|
46 if (mView instanceof SurfaceView) { |
|
47 mSurfaceView = (SurfaceView)view; |
|
48 mSurfaceView.setZOrderOnTop(false); |
|
49 mSurfaceView.setZOrderMediaOverlay(true); |
|
50 } |
|
51 |
|
52 mLayoutParams = new PluginLayoutParams(rect, maxDimension); |
|
53 } |
|
54 |
|
55 public void setVisible(boolean visible) { |
|
56 if (visible) { |
|
57 showView(); |
|
58 } else { |
|
59 hideView(); |
|
60 } |
|
61 } |
|
62 |
|
63 private void hideView() { |
|
64 if (mViewVisible) { |
|
65 ThreadUtils.postToUiThread(new Runnable() { |
|
66 @Override |
|
67 public void run() { |
|
68 mView.setVisibility(View.GONE); |
|
69 mViewVisible = false; |
|
70 } |
|
71 }); |
|
72 } |
|
73 } |
|
74 |
|
75 public void showView() { |
|
76 ThreadUtils.postToUiThread(new Runnable() { |
|
77 @Override |
|
78 public void run() { |
|
79 if (mContainer.indexOfChild(mView) < 0) { |
|
80 mContainer.addView(mView, mLayoutParams); |
|
81 } else { |
|
82 mContainer.updateViewLayout(mView, mLayoutParams); |
|
83 mView.setVisibility(View.VISIBLE); |
|
84 } |
|
85 mViewVisible = true; |
|
86 } |
|
87 }); |
|
88 } |
|
89 |
|
90 @Override |
|
91 public void destroy() { |
|
92 mDestroyed = true; |
|
93 |
|
94 mContainer.removeView(mView); |
|
95 } |
|
96 |
|
97 public void reset(RectF rect) { |
|
98 mLayoutParams.reset(rect); |
|
99 } |
|
100 |
|
101 @Override |
|
102 protected void performUpdates(RenderContext context) { |
|
103 if (mDestroyed) |
|
104 return; |
|
105 |
|
106 if (!RectUtils.fuzzyEquals(context.viewport, mLastViewport) || |
|
107 !FloatUtils.fuzzyEquals(context.zoomFactor, mLastZoomFactor)) { |
|
108 |
|
109 mLastZoomFactor = context.zoomFactor; |
|
110 mLastViewport = context.viewport; |
|
111 mLayoutParams.reposition(context.viewport, context.offset, context.zoomFactor); |
|
112 |
|
113 showView(); |
|
114 } |
|
115 } |
|
116 |
|
117 @Override |
|
118 public void draw(RenderContext context) { |
|
119 } |
|
120 |
|
121 class PluginLayoutParams extends AbsoluteLayout.LayoutParams |
|
122 { |
|
123 private static final String LOGTAG = "GeckoApp.PluginLayoutParams"; |
|
124 |
|
125 private RectF mRect; |
|
126 private int mMaxDimension; |
|
127 private float mLastResolution; |
|
128 |
|
129 public PluginLayoutParams(RectF rect, int maxDimension) { |
|
130 super(0, 0, 0, 0); |
|
131 |
|
132 mMaxDimension = maxDimension; |
|
133 reset(rect); |
|
134 } |
|
135 |
|
136 private void clampToMaxSize() { |
|
137 if (width > mMaxDimension || height > mMaxDimension) { |
|
138 if (width > height) { |
|
139 height = Math.round(((float)height/(float)width) * mMaxDimension); |
|
140 width = mMaxDimension; |
|
141 } else { |
|
142 width = Math.round(((float)width/(float)height) * mMaxDimension); |
|
143 height = mMaxDimension; |
|
144 } |
|
145 } |
|
146 } |
|
147 |
|
148 public void reset(RectF rect) { |
|
149 mRect = rect; |
|
150 } |
|
151 |
|
152 public void reposition(RectF viewport, PointF offset, float zoomFactor) { |
|
153 |
|
154 RectF scaled = RectUtils.scale(mRect, zoomFactor); |
|
155 scaled.offset(offset.x, offset.y); |
|
156 |
|
157 this.x = Math.round(scaled.left - viewport.left); |
|
158 this.y = Math.round(scaled.top - viewport.top); |
|
159 |
|
160 if (!FloatUtils.fuzzyEquals(mLastResolution, zoomFactor)) { |
|
161 width = Math.round(mRect.width() * zoomFactor); |
|
162 height = Math.round(mRect.height() * zoomFactor); |
|
163 mLastResolution = zoomFactor; |
|
164 |
|
165 clampToMaxSize(); |
|
166 } |
|
167 } |
|
168 } |
|
169 } |