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