1 /*
2  * Copyright (C) 2016 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.dialer.callcomposer.camera.camerafocus;
18 
19 import android.annotation.SuppressLint;
20 import android.content.Context;
21 import android.graphics.Canvas;
22 import android.util.AttributeSet;
23 import android.view.MotionEvent;
24 import android.view.View;
25 import android.widget.FrameLayout;
26 import java.util.ArrayList;
27 import java.util.List;
28 
29 /** Focusing overlay. */
30 public class RenderOverlay extends FrameLayout {
31 
32   /** Render interface. */
33   interface Renderer {
handlesTouch()34     boolean handlesTouch();
35 
onTouchEvent(MotionEvent evt)36     boolean onTouchEvent(MotionEvent evt);
37 
setOverlay(RenderOverlay overlay)38     void setOverlay(RenderOverlay overlay);
39 
layout(int left, int top, int right, int bottom)40     void layout(int left, int top, int right, int bottom);
41 
draw(Canvas canvas)42     void draw(Canvas canvas);
43   }
44 
45   private RenderView mRenderView;
46   private List<Renderer> mClients;
47 
48   // reverse list of touch clients
49   private List<Renderer> mTouchClients;
50   private int[] mPosition = new int[2];
51 
RenderOverlay(Context context, AttributeSet attrs)52   public RenderOverlay(Context context, AttributeSet attrs) {
53     super(context, attrs);
54     mRenderView = new RenderView(context);
55     addView(mRenderView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
56     mClients = new ArrayList<>(10);
57     mTouchClients = new ArrayList<>(10);
58     setWillNotDraw(false);
59 
60     addRenderer(new PieRenderer(context));
61   }
62 
getPieRenderer()63   public PieRenderer getPieRenderer() {
64     for (Renderer renderer : mClients) {
65       if (renderer instanceof PieRenderer) {
66         return (PieRenderer) renderer;
67       }
68     }
69     return null;
70   }
71 
addRenderer(Renderer renderer)72   public void addRenderer(Renderer renderer) {
73     mClients.add(renderer);
74     renderer.setOverlay(this);
75     if (renderer.handlesTouch()) {
76       mTouchClients.add(0, renderer);
77     }
78     renderer.layout(getLeft(), getTop(), getRight(), getBottom());
79   }
80 
addRenderer(int pos, Renderer renderer)81   public void addRenderer(int pos, Renderer renderer) {
82     mClients.add(pos, renderer);
83     renderer.setOverlay(this);
84     renderer.layout(getLeft(), getTop(), getRight(), getBottom());
85   }
86 
remove(Renderer renderer)87   public void remove(Renderer renderer) {
88     mClients.remove(renderer);
89     renderer.setOverlay(null);
90   }
91 
92   @Override
dispatchTouchEvent(MotionEvent m)93   public boolean dispatchTouchEvent(MotionEvent m) {
94     return false;
95   }
96 
adjustPosition()97   private void adjustPosition() {
98     getLocationInWindow(mPosition);
99   }
100 
update()101   public void update() {
102     mRenderView.invalidate();
103   }
104 
105   @SuppressLint("ClickableViewAccessibility")
106   private class RenderView extends View {
107 
RenderView(Context context)108     public RenderView(Context context) {
109       super(context);
110       setWillNotDraw(false);
111     }
112 
113     @Override
onTouchEvent(MotionEvent evt)114     public boolean onTouchEvent(MotionEvent evt) {
115       if (mTouchClients != null) {
116         boolean res = false;
117         for (Renderer client : mTouchClients) {
118           res |= client.onTouchEvent(evt);
119         }
120         return res;
121       }
122       return false;
123     }
124 
125     @Override
onLayout(boolean changed, int left, int top, int right, int bottom)126     public void onLayout(boolean changed, int left, int top, int right, int bottom) {
127       adjustPosition();
128       super.onLayout(changed, left, top, right, bottom);
129       if (mClients == null) {
130         return;
131       }
132       for (Renderer renderer : mClients) {
133         renderer.layout(left, top, right, bottom);
134       }
135     }
136 
137     @Override
draw(Canvas canvas)138     public void draw(Canvas canvas) {
139       super.draw(canvas);
140       if (mClients == null) {
141         return;
142       }
143       boolean redraw = false;
144       for (Renderer renderer : mClients) {
145         renderer.draw(canvas);
146         redraw = redraw || ((OverlayRenderer) renderer).isVisible();
147       }
148       if (redraw) {
149         invalidate();
150       }
151     }
152   }
153 }
154