Home | History | Annotate | Download | only in widget
      1 /*
      2  * Copyright (C) 2014 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.widget;
     18 
     19 import android.content.Context;
     20 import android.content.res.Configuration;
     21 import android.graphics.RectF;
     22 import android.util.AttributeSet;
     23 import android.view.Gravity;
     24 import android.view.MotionEvent;
     25 import android.view.View;
     26 import android.view.ViewGroup;
     27 import android.widget.FrameLayout;
     28 import android.widget.ImageView;
     29 import android.widget.LinearLayout;
     30 
     31 import com.android.camera.CaptureLayoutHelper;
     32 import com.android.camera.ShutterButton;
     33 import com.android.camera.debug.Log;
     34 import com.android.camera.ui.PreviewOverlay;
     35 import com.android.camera.ui.TouchCoordinate;
     36 import com.android.camera2.R;
     37 
     38 /**
     39  * ModeOptionsOverlay is a FrameLayout which positions mode options in
     40  * in the bottom of the preview that is visible above the bottom bar.
     41  */
     42 public class ModeOptionsOverlay extends FrameLayout
     43     implements PreviewOverlay.OnPreviewTouchedListener,
     44                ShutterButton.OnShutterButtonListener {
     45 
     46     private final static Log.Tag TAG = new Log.Tag("ModeOptionsOverlay");
     47 
     48     private static final int BOTTOMBAR_OPTIONS_TIMEOUT_MS = 2000;
     49     private final static int BOTTOM_RIGHT = Gravity.BOTTOM | Gravity.RIGHT;
     50     private final static int TOP_RIGHT = Gravity.TOP | Gravity.RIGHT;
     51 
     52     private ModeOptions mModeOptions;
     53     // need a reference to set the onClickListener and fix the layout gravity on orientation change
     54     private LinearLayout mModeOptionsToggle;
     55     // need a reference to fix the rotation on orientation change
     56     private ImageView mThreeDots;
     57     private CaptureLayoutHelper mCaptureLayoutHelper = null;
     58 
     59     public ModeOptionsOverlay(Context context, AttributeSet attrs) {
     60         super(context, attrs);
     61     }
     62 
     63     /**
     64      * Sets a capture layout helper to query layout rect from.
     65      */
     66     public void setCaptureLayoutHelper(CaptureLayoutHelper helper) {
     67         mCaptureLayoutHelper = helper;
     68     }
     69 
     70     public void setToggleClickable(boolean clickable) {
     71         mModeOptionsToggle.setClickable(clickable);
     72     }
     73 
     74     @Override
     75     public void onFinishInflate() {
     76         mModeOptions = (ModeOptions) findViewById(R.id.mode_options);
     77         mModeOptions.setClickable(true);
     78         mModeOptions.setOnClickListener(new View.OnClickListener() {
     79             @Override
     80             public void onClick(View v) {
     81                 closeModeOptions();
     82             }
     83         });
     84 
     85         mModeOptionsToggle = (LinearLayout) findViewById(R.id.mode_options_toggle);
     86         mModeOptionsToggle.setOnClickListener(new View.OnClickListener() {
     87             @Override
     88             public void onClick(View v) {
     89                 mModeOptions.animateVisible();
     90             }
     91         });
     92         mModeOptions.setViewToShowHide(mModeOptionsToggle);
     93 
     94         mThreeDots = (ImageView) findViewById(R.id.three_dots);
     95     }
     96 
     97     @Override
     98     public void onPreviewTouched(MotionEvent ev) {
     99         closeModeOptions();
    100     }
    101 
    102     @Override
    103     public void onShutterButtonClick() {
    104         closeModeOptions();
    105     }
    106 
    107     @Override
    108     public void onShutterCoordinate(TouchCoordinate coord) {
    109         // Do nothing.
    110     }
    111 
    112     @Override
    113     public void onShutterButtonFocus(boolean pressed) {
    114         // noop
    115     }
    116 
    117     /**
    118      * Schedule (or re-schedule) the options menu to be closed after a number
    119      * of milliseconds.  If the options menu is already closed, nothing is
    120      * scheduled.
    121      */
    122     public void closeModeOptions() {
    123         mModeOptions.animateHidden();
    124     }
    125 
    126     @Override
    127     public void onConfigurationChanged(Configuration configuration) {
    128         super.onConfigurationChanged(configuration);
    129         checkOrientation(configuration.orientation);
    130     }
    131 
    132     @Override
    133     public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    134         if (mCaptureLayoutHelper == null) {
    135             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    136             Log.e(TAG, "Capture layout helper needs to be set first.");
    137         } else {
    138             RectF uncoveredPreviewRect = mCaptureLayoutHelper.getUncoveredPreviewRect();
    139             super.onMeasure(MeasureSpec.makeMeasureSpec(
    140                             (int) uncoveredPreviewRect.width(), MeasureSpec.EXACTLY),
    141                     MeasureSpec.makeMeasureSpec((int) uncoveredPreviewRect.height(),
    142                             MeasureSpec.EXACTLY)
    143             );
    144         }
    145     }
    146 
    147     /**
    148      * Set the layout gravity of the child layout to be bottom or top right
    149      * depending on orientation.
    150      */
    151     private void checkOrientation(int orientation) {
    152         final boolean isPortrait = (Configuration.ORIENTATION_PORTRAIT == orientation);
    153 
    154         final int modeOptionsDimension = (int) getResources()
    155             .getDimension(R.dimen.mode_options_height);
    156 
    157         FrameLayout.LayoutParams modeOptionsParams
    158             = (FrameLayout.LayoutParams) mModeOptions.getLayoutParams();
    159         FrameLayout.LayoutParams modeOptionsToggleParams
    160             = (FrameLayout.LayoutParams) mModeOptionsToggle.getLayoutParams();
    161 
    162         if (isPortrait) {
    163             modeOptionsParams.height = modeOptionsDimension;
    164             modeOptionsParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
    165             modeOptionsParams.gravity = Gravity.BOTTOM;
    166 
    167             modeOptionsToggleParams.gravity = BOTTOM_RIGHT;
    168 
    169             mThreeDots.setImageResource(R.drawable.ic_options_port);
    170         } else {
    171             modeOptionsParams.width = modeOptionsDimension;
    172             modeOptionsParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
    173             modeOptionsParams.gravity = Gravity.RIGHT;
    174 
    175             modeOptionsToggleParams.gravity = TOP_RIGHT;
    176 
    177             mThreeDots.setImageResource(R.drawable.ic_options_land);
    178         }
    179 
    180         requestLayout();
    181     }
    182 }
    183