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