1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.camera.ui; 18 19 import android.content.Context; 20 import android.graphics.Canvas; 21 import android.util.AttributeSet; 22 import android.view.MotionEvent; 23 import android.view.View; 24 import android.widget.FrameLayout; 25 26 import com.android.camera.PreviewGestures; 27 28 import java.util.ArrayList; 29 import java.util.List; 30 31 public class RenderOverlay extends FrameLayout { 32 33 private static final String TAG = "CAM_Overlay"; 34 35 interface Renderer { 36 37 public boolean handlesTouch(); 38 public boolean onTouchEvent(MotionEvent evt); 39 public void setOverlay(RenderOverlay overlay); 40 public void layout(int left, int top, int right, int bottom); 41 public void draw(Canvas canvas); 42 43 } 44 45 private RenderView mRenderView; 46 private List<Renderer> mClients; 47 private PreviewGestures mGestures; 48 // reverse list of touch clients 49 private List<Renderer> mTouchClients; 50 private int[] mPosition = new int[2]; 51 52 public RenderOverlay(Context context, AttributeSet attrs) { 53 super(context, attrs); 54 mRenderView = new RenderView(context); 55 addView(mRenderView, new LayoutParams(LayoutParams.MATCH_PARENT, 56 LayoutParams.MATCH_PARENT)); 57 mClients = new ArrayList<Renderer>(10); 58 mTouchClients = new ArrayList<Renderer>(10); 59 setWillNotDraw(false); 60 } 61 62 public void setGestures(PreviewGestures gestures) { 63 mGestures = gestures; 64 } 65 66 public void addRenderer(Renderer renderer) { 67 mClients.add(renderer); 68 renderer.setOverlay(this); 69 if (renderer.handlesTouch()) { 70 mTouchClients.add(0, renderer); 71 } 72 renderer.layout(getLeft(), getTop(), getRight(), getBottom()); 73 } 74 75 public void addRenderer(int pos, Renderer renderer) { 76 mClients.add(pos, renderer); 77 renderer.setOverlay(this); 78 renderer.layout(getLeft(), getTop(), getRight(), getBottom()); 79 } 80 81 public void remove(Renderer renderer) { 82 mClients.remove(renderer); 83 renderer.setOverlay(null); 84 } 85 86 public int getClientSize() { 87 return mClients.size(); 88 } 89 90 @Override 91 public boolean dispatchTouchEvent(MotionEvent m) { 92 if (mGestures != null) { 93 if (!mGestures.isEnabled()) return false; 94 mGestures.dispatchTouch(m); 95 } 96 return true; 97 } 98 99 public boolean directDispatchTouch(MotionEvent m, Renderer target) { 100 mRenderView.setTouchTarget(target); 101 boolean res = mRenderView.dispatchTouchEvent(m); 102 mRenderView.setTouchTarget(null); 103 return res; 104 } 105 106 private void adjustPosition() { 107 getLocationInWindow(mPosition); 108 } 109 110 public int getWindowPositionX() { 111 return mPosition[0]; 112 } 113 114 public int getWindowPositionY() { 115 return mPosition[1]; 116 } 117 118 public void update() { 119 mRenderView.invalidate(); 120 } 121 122 private class RenderView extends View { 123 124 private Renderer mTouchTarget; 125 126 public RenderView(Context context) { 127 super(context); 128 setWillNotDraw(false); 129 } 130 131 public void setTouchTarget(Renderer target) { 132 mTouchTarget = target; 133 } 134 135 @Override 136 public boolean dispatchTouchEvent(MotionEvent evt) { 137 138 if (mTouchTarget != null) { 139 return mTouchTarget.onTouchEvent(evt); 140 } 141 if (mTouchClients != null) { 142 boolean res = false; 143 for (Renderer client : mTouchClients) { 144 res |= client.onTouchEvent(evt); 145 } 146 return res; 147 } 148 return false; 149 } 150 151 @Override 152 public void onLayout(boolean changed, int left, int top, int right, int bottom) { 153 adjustPosition(); 154 super.onLayout(changed, left, top, right, bottom); 155 if (mClients == null) return; 156 for (Renderer renderer : mClients) { 157 renderer.layout(left, top, right, bottom); 158 } 159 } 160 161 @Override 162 public void draw(Canvas canvas) { 163 super.draw(canvas); 164 if (mClients == null) return; 165 boolean redraw = false; 166 for (Renderer renderer : mClients) { 167 renderer.draw(canvas); 168 redraw = redraw || ((OverlayRenderer) renderer).isVisible(); 169 } 170 if (redraw) { 171 invalidate(); 172 } 173 } 174 } 175 176 } 177