Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2013 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.annotation.SuppressLint;
     20 import android.app.Activity;
     21 import android.content.Context;
     22 import android.content.res.Configuration;
     23 import android.graphics.Rect;
     24 import android.hardware.display.DisplayManager;
     25 import android.hardware.display.DisplayManager.DisplayListener;
     26 import android.util.AttributeSet;
     27 import android.view.View;
     28 import android.widget.FrameLayout;
     29 
     30 import com.android.camera.util.ApiHelper;
     31 import com.android.camera.util.CameraUtil;
     32 
     33 @SuppressLint("NewApi")
     34 public class CameraRootView extends FrameLayout {
     35 
     36     private int mTopMargin = 0;
     37     private int mBottomMargin = 0;
     38     private int mLeftMargin = 0;
     39     private int mRightMargin = 0;
     40     private Rect mCurrentInsets;
     41     private int mOffset = 0;
     42     private Object mDisplayListener;
     43     private MyDisplayListener mListener;
     44 
     45     public interface MyDisplayListener {
     46         public void onDisplayChanged();
     47     }
     48 
     49     public CameraRootView(Context context, AttributeSet attrs) {
     50         super(context, attrs);
     51         initDisplayListener();
     52     }
     53 
     54     @Override
     55     protected boolean fitSystemWindows(Rect insets) {
     56         mCurrentInsets = insets;
     57         // insets include status bar, navigation bar, etc
     58         // In this case, we are only concerned with the size of nav bar
     59         if (mOffset > 0) {
     60             return true;
     61         }
     62 
     63         if (insets.bottom > 0) {
     64             mOffset = insets.bottom;
     65         } else if (insets.right > 0) {
     66             mOffset = insets.right;
     67         }
     68         return true;
     69     }
     70 
     71     public void initDisplayListener() {
     72         if (ApiHelper.HAS_DISPLAY_LISTENER) {
     73             mDisplayListener = new DisplayListener() {
     74 
     75                 @Override
     76                 public void onDisplayAdded(int arg0) {}
     77 
     78                 @Override
     79                 public void onDisplayChanged(int arg0) {
     80                     if (mListener != null) {
     81                         mListener.onDisplayChanged();
     82                     }
     83                 }
     84 
     85                 @Override
     86                 public void onDisplayRemoved(int arg0) {}
     87             };
     88         }
     89     }
     90 
     91     public void removeDisplayChangeListener() {
     92         mListener = null;
     93     }
     94 
     95     public void setDisplayChangeListener(MyDisplayListener listener) {
     96         mListener = listener;
     97     }
     98 
     99     @Override
    100     public void onAttachedToWindow() {
    101         super.onAttachedToWindow();
    102         if (ApiHelper.HAS_DISPLAY_LISTENER) {
    103             ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE))
    104             .registerDisplayListener((DisplayListener) mDisplayListener, null);
    105         }
    106     }
    107 
    108     @Override
    109     public void onDetachedFromWindow () {
    110         super.onDetachedFromWindow();
    111         if (ApiHelper.HAS_DISPLAY_LISTENER) {
    112             ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE))
    113             .unregisterDisplayListener((DisplayListener) mDisplayListener);
    114         }
    115     }
    116 
    117     @Override
    118     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    119         int rotation = CameraUtil.getDisplayRotation((Activity) getContext());
    120         // all the layout code assumes camera device orientation to be portrait
    121         // adjust rotation for landscape
    122         int orientation = getResources().getConfiguration().orientation;
    123         int camOrientation = (rotation % 180 == 0) ? Configuration.ORIENTATION_PORTRAIT
    124                 : Configuration.ORIENTATION_LANDSCAPE;
    125         if (camOrientation != orientation) {
    126             rotation = (rotation + 90) % 360;
    127         }
    128         // calculate margins
    129         mLeftMargin = 0;
    130         mRightMargin = 0;
    131         mBottomMargin = 0;
    132         mTopMargin = 0;
    133         switch (rotation) {
    134             case 0:
    135                 mBottomMargin += mOffset;
    136                 break;
    137             case 90:
    138                 mRightMargin += mOffset;
    139                 break;
    140             case 180:
    141                 mTopMargin += mOffset;
    142                 break;
    143             case 270:
    144                 mLeftMargin += mOffset;
    145                 break;
    146         }
    147         if (mCurrentInsets != null) {
    148             if (mCurrentInsets.right > 0) {
    149                 // navigation bar on the right
    150                 mRightMargin = mRightMargin > 0 ? mRightMargin : mCurrentInsets.right;
    151             } else {
    152                 // navigation bar on the bottom
    153                 mBottomMargin = mBottomMargin > 0 ? mBottomMargin : mCurrentInsets.bottom;
    154             }
    155         }
    156         // make sure all the children are resized
    157         super.onMeasure(widthMeasureSpec - mLeftMargin - mRightMargin,
    158                 heightMeasureSpec - mTopMargin - mBottomMargin);
    159         setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
    160     }
    161 
    162     @Override
    163     public void onLayout(boolean changed, int l, int t, int r, int b) {
    164         r -= l;
    165         b -= t;
    166         l = 0;
    167         t = 0;
    168         int orientation = getResources().getConfiguration().orientation;
    169         // Lay out children
    170         for (int i = 0; i < getChildCount(); i++) {
    171             View v = getChildAt(i);
    172             if (v instanceof CameraControls) {
    173                 // Lay out camera controls to center on the short side of the screen
    174                 // so that they stay in place during rotation
    175                 int width = v.getMeasuredWidth();
    176                 int height = v.getMeasuredHeight();
    177                 if (orientation == Configuration.ORIENTATION_PORTRAIT) {
    178                     int left = (l + r - width) / 2;
    179                     v.layout(left, t + mTopMargin, left + width, b - mBottomMargin);
    180                 } else {
    181                     int top = (t + b - height) / 2;
    182                     v.layout(l + mLeftMargin, top, r - mRightMargin, top + height);
    183                 }
    184             } else {
    185                 v.layout(l + mLeftMargin, t + mTopMargin, r - mRightMargin, b - mBottomMargin);
    186             }
    187         }
    188     }
    189 }
    190