1b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb/* 2b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * Copyright (C) 2012 The Android Open Source Project 3b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * 4b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License"); 5b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * you may not use this file except in compliance with the License. 6b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * You may obtain a copy of the License at 7b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * 8b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * http://www.apache.org/licenses/LICENSE-2.0 9b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * 10b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * Unless required by applicable law or agreed to in writing, software 11b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS, 12b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * See the License for the specific language governing permissions and 14b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb * limitations under the License. 15b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb */ 16b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 17b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbpackage com.android.camera.ui; 18b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 19b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.content.Context; 20b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.graphics.Canvas; 21b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.util.AttributeSet; 221373b98135b2854578111dd535e24d39c8853f14Michael Kolbimport android.view.MotionEvent; 23b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport android.view.View; 246f54ad9e32b77db645f31c45b768af221e80e207Michael Kolbimport android.widget.FrameLayout; 25b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 26b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport java.util.ArrayList; 27b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolbimport java.util.List; 28b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 296f54ad9e32b77db645f31c45b768af221e80e207Michael Kolbpublic class RenderOverlay extends FrameLayout { 30b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 31b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private static final String TAG = "CAM_Overlay"; 32b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 33b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb interface Renderer { 34b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 351373b98135b2854578111dd535e24d39c8853f14Michael Kolb public boolean handlesTouch(); 361373b98135b2854578111dd535e24d39c8853f14Michael Kolb public boolean onTouchEvent(MotionEvent evt); 37b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void setOverlay(RenderOverlay overlay); 38b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void layout(int left, int top, int right, int bottom); 39b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void draw(Canvas canvas); 40b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 41b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 42b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 43b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private RenderView mRenderView; 44b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private List<Renderer> mClients; 45b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 461373b98135b2854578111dd535e24d39c8853f14Michael Kolb // reverse list of touch clients 471373b98135b2854578111dd535e24d39c8853f14Michael Kolb private List<Renderer> mTouchClients; 481373b98135b2854578111dd535e24d39c8853f14Michael Kolb private int[] mPosition = new int[2]; 491373b98135b2854578111dd535e24d39c8853f14Michael Kolb 50b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public RenderOverlay(Context context, AttributeSet attrs) { 51b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb super(context, attrs); 52b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mRenderView = new RenderView(context); 53b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb addView(mRenderView, new LayoutParams(LayoutParams.MATCH_PARENT, 54b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb LayoutParams.MATCH_PARENT)); 55b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mClients = new ArrayList<Renderer>(10); 561373b98135b2854578111dd535e24d39c8853f14Michael Kolb mTouchClients = new ArrayList<Renderer>(10); 57ad639dff251233032734106afe4fe51a52be3721Michael Kolb setWillNotDraw(false); 58b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 59b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 60b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void addRenderer(Renderer renderer) { 61b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mClients.add(renderer); 62b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb renderer.setOverlay(this); 631373b98135b2854578111dd535e24d39c8853f14Michael Kolb if (renderer.handlesTouch()) { 641373b98135b2854578111dd535e24d39c8853f14Michael Kolb mTouchClients.add(0, renderer); 651373b98135b2854578111dd535e24d39c8853f14Michael Kolb } 664a8a2a243ef9a6557577a8dc648ef461e9913246Michael Kolb renderer.layout(getLeft(), getTop(), getRight(), getBottom()); 67b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 68b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 69b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void addRenderer(int pos, Renderer renderer) { 70b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mClients.add(pos, renderer); 71b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb renderer.setOverlay(this); 724a8a2a243ef9a6557577a8dc648ef461e9913246Michael Kolb renderer.layout(getLeft(), getTop(), getRight(), getBottom()); 73b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 74b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 75b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void remove(Renderer renderer) { 76b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb mClients.remove(renderer); 77b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb renderer.setOverlay(null); 78b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 79b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 80b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public int getClientSize() { 81b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb return mClients.size(); 82b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 83b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 841373b98135b2854578111dd535e24d39c8853f14Michael Kolb @Override 851373b98135b2854578111dd535e24d39c8853f14Michael Kolb public boolean dispatchTouchEvent(MotionEvent m) { 861373b98135b2854578111dd535e24d39c8853f14Michael Kolb return false; 871373b98135b2854578111dd535e24d39c8853f14Michael Kolb } 881373b98135b2854578111dd535e24d39c8853f14Michael Kolb 894d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb public boolean directDispatchTouch(MotionEvent m, Renderer target) { 904d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb mRenderView.setTouchTarget(target); 914d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb boolean res = super.dispatchTouchEvent(m); 924d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb mRenderView.setTouchTarget(null); 934d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb return res; 941373b98135b2854578111dd535e24d39c8853f14Michael Kolb } 951373b98135b2854578111dd535e24d39c8853f14Michael Kolb 961373b98135b2854578111dd535e24d39c8853f14Michael Kolb private void adjustPosition() { 971373b98135b2854578111dd535e24d39c8853f14Michael Kolb getLocationInWindow(mPosition); 981373b98135b2854578111dd535e24d39c8853f14Michael Kolb } 991373b98135b2854578111dd535e24d39c8853f14Michael Kolb 1001373b98135b2854578111dd535e24d39c8853f14Michael Kolb public int getWindowPositionX() { 1011373b98135b2854578111dd535e24d39c8853f14Michael Kolb return mPosition[0]; 1021373b98135b2854578111dd535e24d39c8853f14Michael Kolb } 1031373b98135b2854578111dd535e24d39c8853f14Michael Kolb 1041373b98135b2854578111dd535e24d39c8853f14Michael Kolb public int getWindowPositionY() { 1051373b98135b2854578111dd535e24d39c8853f14Michael Kolb return mPosition[1]; 1061373b98135b2854578111dd535e24d39c8853f14Michael Kolb } 1071373b98135b2854578111dd535e24d39c8853f14Michael Kolb 108ad639dff251233032734106afe4fe51a52be3721Michael Kolb public void update() { 109ad639dff251233032734106afe4fe51a52be3721Michael Kolb mRenderView.invalidate(); 110ad639dff251233032734106afe4fe51a52be3721Michael Kolb } 111ad639dff251233032734106afe4fe51a52be3721Michael Kolb 112b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb private class RenderView extends View { 113b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 1144d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb private Renderer mTouchTarget; 1154d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb 116b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public RenderView(Context context) { 117b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb super(context); 118b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb setWillNotDraw(false); 119b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 120b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 1214d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb public void setTouchTarget(Renderer target) { 1224d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb mTouchTarget = target; 1234d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb } 1244d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb 125b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb @Override 1261373b98135b2854578111dd535e24d39c8853f14Michael Kolb public boolean onTouchEvent(MotionEvent evt) { 1274d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb if (mTouchTarget != null) { 1284d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb return mTouchTarget.onTouchEvent(evt); 1294d628bcbaf4e6f2330dc9619f2129770863666dcMichael Kolb } 1301373b98135b2854578111dd535e24d39c8853f14Michael Kolb if (mTouchClients != null) { 1311373b98135b2854578111dd535e24d39c8853f14Michael Kolb boolean res = false; 1321373b98135b2854578111dd535e24d39c8853f14Michael Kolb for (Renderer client : mTouchClients) { 1331373b98135b2854578111dd535e24d39c8853f14Michael Kolb res |= client.onTouchEvent(evt); 1341373b98135b2854578111dd535e24d39c8853f14Michael Kolb } 1351373b98135b2854578111dd535e24d39c8853f14Michael Kolb return res; 1361373b98135b2854578111dd535e24d39c8853f14Michael Kolb } 1371373b98135b2854578111dd535e24d39c8853f14Michael Kolb return false; 1381373b98135b2854578111dd535e24d39c8853f14Michael Kolb } 1391373b98135b2854578111dd535e24d39c8853f14Michael Kolb 1401373b98135b2854578111dd535e24d39c8853f14Michael Kolb @Override 14131000593e0f34cd89f2b6f293f07fb54b8bddd5eJohn Reck public void onLayout(boolean changed, int left, int top, int right, int bottom) { 1421373b98135b2854578111dd535e24d39c8853f14Michael Kolb adjustPosition(); 14331000593e0f34cd89f2b6f293f07fb54b8bddd5eJohn Reck super.onLayout(changed, left, top, right, bottom); 144b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mClients == null) return; 145b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb for (Renderer renderer : mClients) { 146b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb renderer.layout(left, top, right, bottom); 147b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 148b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 149b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 150b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb @Override 151b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb public void draw(Canvas canvas) { 1521a9a41b66187eac7ff59f22a50de0d9d9403e4ceMichael Kolb super.draw(canvas); 153b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb if (mClients == null) return; 154ad639dff251233032734106afe4fe51a52be3721Michael Kolb boolean redraw = false; 155b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb for (Renderer renderer : mClients) { 156b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb renderer.draw(canvas); 157ad639dff251233032734106afe4fe51a52be3721Michael Kolb redraw = redraw || ((OverlayRenderer) renderer).isVisible(); 158ad639dff251233032734106afe4fe51a52be3721Michael Kolb } 159ad639dff251233032734106afe4fe51a52be3721Michael Kolb if (redraw) { 160ad639dff251233032734106afe4fe51a52be3721Michael Kolb invalidate(); 161b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 162b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 163b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb } 164b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb 165b19c713286b7beed376ec6c4390e7272a80aa5b9Michael Kolb} 166