Home | History | Annotate | Download | only in ui
      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