Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2011 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.content.res.Configuration;
     21 import android.util.AttributeSet;
     22 import android.view.MotionEvent;
     23 import android.view.View;
     24 
     25 import com.android.camera.CameraPreference.OnPreferenceChangedListener;
     26 import com.android.camera.PreferenceGroup;
     27 import com.android.camera.R;
     28 import com.android.camera.Util;
     29 
     30 /**
     31  * On the tablet UI, we have IndicatorControlWheelContainer which contains a
     32  * ShutterButton, an IndicatorControlWheel(which combines first-level and
     33  * second-level indicators and a ZoomControlWheel).
     34  */
     35 public class IndicatorControlWheelContainer extends IndicatorControlContainer {
     36     @SuppressWarnings("unused")
     37     private static final String TAG = "IndicatorControlWheelContainer";
     38 
     39     // From center outwards, the indicator control wheel
     40     // (e.g. res/drawable-sw640dp-hdpi/btn_camera_shutter_holo.png) is composed
     41     // of a center colored button (could be blue, red or green), a light-black
     42     // circle band, a thin gray circle strip and a dark-black circle band.
     43     // The STROKE_WIDTH is the width of the outer-most dark-black circle band.
     44     // The SHUTTER_BUTTON_RADIUS is the radius of the circle containing the
     45     // center colored button and the light-black circle band.
     46     public static final int STROKE_WIDTH = 87;  // in dp
     47     public static final int SHUTTER_BUTTON_RADIUS = 74;  // in dp
     48     // The indicator control wheel is cut by a secant. The secant is at the
     49     // right edge for landscape orientation and at bottom edge for portrait
     50     // orientation. This constant is the distance from the wheel center to the
     51     // secant.
     52     public static final int WHEEL_CENTER_TO_SECANT = 93;  // in dp
     53 
     54     private View mShutterButton;
     55     private double mShutterButtonRadius;  // in pixels
     56     private IndicatorControlWheel mIndicatorControlWheel;
     57     // The center of the shutter button.
     58     private int mCenterX, mCenterY;
     59 
     60     public IndicatorControlWheelContainer(Context context, AttributeSet attrs) {
     61         super(context, attrs);
     62     }
     63 
     64     @Override
     65     protected void onFinishInflate() {
     66         mShutterButton = findViewById(R.id.shutter_button);
     67         mShutterButtonRadius = Util.dpToPixel(SHUTTER_BUTTON_RADIUS);
     68 
     69         mIndicatorControlWheel = (IndicatorControlWheel) findViewById(
     70                 R.id.indicator_control_wheel);
     71     }
     72 
     73     @Override
     74     public void initialize(Context context, PreferenceGroup group,
     75             boolean isZoomSupported, String[] keys, String[] otherSettingKeys) {
     76         mIndicatorControlWheel.initialize(context, group, isZoomSupported,
     77                 keys, otherSettingKeys);
     78     }
     79 
     80     @Override
     81     public void onIndicatorEvent(int event) {
     82     }
     83 
     84     @Override
     85     public boolean dispatchTouchEvent(MotionEvent event) {
     86         if (!onFilterTouchEventForSecurity(event)) return false;
     87 
     88         int action = event.getAction();
     89 
     90         double dx = event.getX() - mCenterX;
     91         double dy = mCenterY - event.getY();
     92         double radius = Math.sqrt(dx * dx + dy * dy);
     93 
     94         // Check if the event should be dispatched to the shutter button.
     95         if (radius <= mShutterButtonRadius) {
     96             if (mIndicatorControlWheel.getVisibility() == View.VISIBLE) {
     97                 mIndicatorControlWheel.onTouchOutBound();
     98             }
     99             if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP) {
    100                 return mShutterButton.dispatchTouchEvent(event);
    101             }
    102             return false;
    103         }
    104 
    105         if (mShutterButton.isPressed()) {
    106             // Send cancel to the shutter button if it was pressed.
    107             event.setAction(MotionEvent.ACTION_CANCEL);
    108             mShutterButton.dispatchTouchEvent(event);
    109             return true;
    110         }
    111 
    112         return mIndicatorControlWheel.dispatchTouchEvent(event);
    113     }
    114 
    115     @Override
    116     protected void onLayout(
    117             boolean changed, int left, int top, int right, int bottom) {
    118 
    119         // Layout the shutter button.
    120         int shutterButtonWidth = mShutterButton.getMeasuredWidth();
    121         int shutterButtonHeight = mShutterButton.getMeasuredHeight();
    122         if (getResources().getConfiguration().orientation
    123                 == Configuration.ORIENTATION_LANDSCAPE) {
    124             mCenterX = right - left - Util.dpToPixel(WHEEL_CENTER_TO_SECANT);
    125             mCenterY = (bottom - top) / 2;
    126             mShutterButton.layout(right - left - shutterButtonWidth,
    127                     mCenterY - shutterButtonHeight / 2,
    128                     right - left,
    129                     mCenterY + shutterButtonHeight / 2);
    130         } else {
    131             mCenterX = (right - left) / 2;
    132             mCenterY = bottom - top - Util.dpToPixel(WHEEL_CENTER_TO_SECANT);
    133             mShutterButton.layout(mCenterX - shutterButtonWidth / 2,
    134                     bottom - top - shutterButtonHeight,
    135                     mCenterX + shutterButtonWidth / 2,
    136                     bottom - top);
    137         }
    138 
    139         // Layout the control wheel.
    140         mIndicatorControlWheel.layout(0, 0, right - left, bottom - top);
    141     }
    142 
    143     @Override
    144     protected void onMeasure(int widthSpec, int heightSpec) {
    145         // Measure all children.
    146         int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    147         mShutterButton.measure(freeSpec, freeSpec);
    148         mIndicatorControlWheel.measure(freeSpec, freeSpec);
    149 
    150         // Measure myself. Add some buffer for highlight arc.
    151         int desiredWidth = mShutterButton.getMeasuredWidth()
    152                 + IndicatorControlWheel.HIGHLIGHT_WIDTH * 4;
    153         int desiredHeight = mShutterButton.getMeasuredHeight()
    154                 + IndicatorControlWheel.HIGHLIGHT_WIDTH * 4;
    155         int widthMode = MeasureSpec.getMode(widthSpec);
    156         int heightMode = MeasureSpec.getMode(heightSpec);
    157         int measuredWidth, measuredHeight;
    158         if (widthMode == MeasureSpec.UNSPECIFIED) {
    159             measuredWidth = desiredWidth;
    160         } else if (widthMode == MeasureSpec.AT_MOST) {
    161             measuredWidth = Math.min(desiredWidth, MeasureSpec.getSize(widthSpec));
    162         } else {  // MeasureSpec.EXACTLY
    163             measuredWidth = MeasureSpec.getSize(widthSpec);
    164         }
    165         if (heightMode == MeasureSpec.UNSPECIFIED) {
    166             measuredHeight = desiredHeight;
    167         } else if (heightMode == MeasureSpec.AT_MOST) {
    168             measuredHeight = Math.min(desiredHeight, MeasureSpec.getSize(heightSpec));
    169         } else {  // MeasureSpec.EXACTLY
    170             measuredHeight = MeasureSpec.getSize(heightSpec);
    171         }
    172         setMeasuredDimension(measuredWidth, measuredHeight);
    173     }
    174 
    175     @Override
    176     public void setListener(OnPreferenceChangedListener listener) {
    177         mIndicatorControlWheel.setListener(listener);
    178     }
    179 
    180     @Override
    181     public void reloadPreferences() {
    182         mIndicatorControlWheel.reloadPreferences();
    183     }
    184 
    185     @Override
    186     public View getActiveSettingPopup() {
    187         return mIndicatorControlWheel.getActiveSettingPopup();
    188     }
    189 
    190     @Override
    191     public boolean dismissSettingPopup() {
    192         return mIndicatorControlWheel.dismissSettingPopup();
    193     }
    194 
    195     @Override
    196     public void setOrientation(int orientation, boolean animation) {
    197         mIndicatorControlWheel.setOrientation(orientation, animation);
    198     }
    199 
    200     @Override
    201     public void startTimeLapseAnimation(int timeLapseInterval, long startTime) {
    202         mIndicatorControlWheel.startTimeLapseAnimation(
    203                 timeLapseInterval, startTime);
    204     }
    205 
    206     @Override
    207     public void stopTimeLapseAnimation() {
    208         mIndicatorControlWheel.stopTimeLapseAnimation();
    209     }
    210 
    211     @Override
    212     public void setEnabled(boolean enabled) {
    213         mIndicatorControlWheel.setEnabled(enabled);
    214     }
    215 
    216     @Override
    217     public void enableZoom(boolean enabled) {
    218         mIndicatorControlWheel.enableZoom(enabled);
    219     }
    220 
    221     @Override
    222     public void overrideSettings(final String ... keyvalues) {
    223         mIndicatorControlWheel.overrideSettings(keyvalues);
    224     }
    225 
    226     @Override
    227     public void dismissSecondLevelIndicator() {
    228         mIndicatorControlWheel.dismissSecondLevelIndicator();
    229     }
    230 
    231     @Override
    232     public void enableFilter(boolean enabled) {
    233         mIndicatorControlWheel.setupFilter(enabled);
    234     }
    235 }
    236