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.R;
     26 import com.android.camera.Util;
     27 
     28 /**
     29  * A view that contains camera zoom control and its layout.
     30  */
     31 public class ZoomControlBar extends ZoomControl {
     32     @SuppressWarnings("unused")
     33     private static final String TAG = "ZoomControlBar";
     34     private static final int THRESHOLD_FIRST_MOVE = Util.dpToPixel(10); // pixels
     35     // Space between indicator icon and the zoom-in/out icon.
     36     private static final int ICON_SPACING = Util.dpToPixel(12);
     37 
     38     private View mBar;
     39     private boolean mStartChanging;
     40     private int mSliderPosition = 0;
     41     private int mSliderLength;
     42     // The width of the zoom control bar (including the '+', '-' icons and the
     43     // slider bar) for phone in portrait orientation, or the height of that
     44     // for phone in landscape orientation.
     45     private int mSize;
     46     // The width of the '+' icon (the same as '-' icon) for phone in portrait
     47     // orientation, or the height of that for phone in landscape orientation.
     48     private int mIconSize;
     49     // mIconSize + padding
     50     private int mTotalIconSize;
     51 
     52     public ZoomControlBar(Context context, AttributeSet attrs) {
     53         super(context, attrs);
     54         mBar = new View(context);
     55         mBar.setBackgroundResource(R.drawable.zoom_slider_bar);
     56         addView(mBar);
     57     }
     58 
     59     @Override
     60     public void setActivated(boolean activated) {
     61         super.setActivated(activated);
     62         mBar.setActivated(activated);
     63     }
     64 
     65     private int getSliderPosition(int offset) {
     66         // Calculate the absolute offset of the slider in the zoom control bar.
     67         // For left-hand users, as the device is rotated for 180 degree for
     68         // landscape mode, the zoom-in bottom should be on the top, so the
     69         // position should be reversed.
     70         int pos; // the relative position in the zoom slider bar
     71         if (getResources().getConfiguration().orientation
     72                 == Configuration.ORIENTATION_LANDSCAPE) {
     73             if (mOrientation == 180) {
     74                 pos = offset - mTotalIconSize;
     75             } else {
     76                 pos = mSize - mTotalIconSize - offset;
     77             }
     78         } else {
     79             if (mOrientation == 90) {
     80                 pos = mSize - mTotalIconSize - offset;
     81             } else {
     82                 pos = offset - mTotalIconSize;
     83             }
     84         }
     85         if (pos < 0) pos = 0;
     86         if (pos > mSliderLength) pos = mSliderLength;
     87         return pos;
     88     }
     89 
     90     @Override
     91     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
     92         if (getResources().getConfiguration().orientation
     93                 == Configuration.ORIENTATION_LANDSCAPE) {
     94             mSize = h;
     95             mIconSize = mZoomIn.getMeasuredHeight();
     96         } else {
     97             mSize = w;
     98             mIconSize = mZoomIn.getMeasuredWidth();
     99         }
    100         mTotalIconSize = mIconSize + ICON_SPACING;
    101         mSliderLength = mSize  - (2 * mTotalIconSize);
    102     }
    103 
    104     @Override
    105     public boolean dispatchTouchEvent(MotionEvent event) {
    106         if (!isEnabled() || (mSize == 0)) return false;
    107         int action = event.getAction();
    108 
    109         switch (action) {
    110             case MotionEvent.ACTION_OUTSIDE:
    111             case MotionEvent.ACTION_CANCEL:
    112             case MotionEvent.ACTION_UP:
    113                 setActivated(false);
    114                 closeZoomControl();
    115                 break;
    116 
    117             case MotionEvent.ACTION_DOWN:
    118                 setActivated(true);
    119                 mStartChanging = false;
    120             case MotionEvent.ACTION_MOVE:
    121                 boolean isLandscape = (getResources().getConfiguration().orientation
    122                         == Configuration.ORIENTATION_LANDSCAPE);
    123                 int pos = getSliderPosition((int)
    124                         (isLandscape ? event.getY() : event.getX()));
    125                 if (!mStartChanging) {
    126                     // Make sure the movement is large enough before we start
    127                     // changing the zoom.
    128                     int delta = mSliderPosition - pos;
    129                     if ((delta > THRESHOLD_FIRST_MOVE) ||
    130                             (delta < -THRESHOLD_FIRST_MOVE)) {
    131                         mStartChanging = true;
    132                     }
    133                 }
    134                 if (mStartChanging) {
    135                     performZoom(1.0d * pos / mSliderLength);
    136                     mSliderPosition = pos;
    137                 }
    138                 requestLayout();
    139         }
    140         return true;
    141     }
    142 
    143     @Override
    144     public void setOrientation(int orientation, boolean animation) {
    145         // layout for the left-hand camera control
    146         if ((orientation == 180) || (mOrientation == 180)) requestLayout();
    147         super.setOrientation(orientation, animation);
    148     }
    149 
    150     @Override
    151     protected void onLayout(
    152             boolean changed, int left, int top, int right, int bottom) {
    153         boolean isLandscape = (getResources().getConfiguration().orientation
    154                 == Configuration.ORIENTATION_LANDSCAPE);
    155         if (mZoomMax == 0) return;
    156         int size = 0;
    157         if (isLandscape) {
    158             size = right - left;
    159             mBar.layout(0, mTotalIconSize, size, mSize - mTotalIconSize);
    160         } else {
    161             size = bottom - top;
    162             mBar.layout(mTotalIconSize, 0, mSize - mTotalIconSize, size);
    163         }
    164         // For left-hand users, as the device is rotated for 180 degree,
    165         // the zoom-in button should be on the top.
    166         int pos; // slider position
    167         int sliderPosition;
    168         if (mSliderPosition != -1) { // -1 means invalid
    169             sliderPosition = mSliderPosition;
    170         } else {
    171             sliderPosition = (int) ((double) mSliderLength * mZoomIndex / mZoomMax);
    172         }
    173 
    174         if (isLandscape) {
    175             if (mOrientation == 180) {
    176                 mZoomOut.layout(0, 0, size, mIconSize);
    177                 mZoomIn.layout(0, mSize - mIconSize, size, mSize);
    178                 pos = mBar.getTop() + sliderPosition;
    179             } else {
    180                 mZoomIn.layout(0, 0, size, mIconSize);
    181                 mZoomOut.layout(0, mSize - mIconSize, size, mSize);
    182                 pos = mBar.getBottom() - sliderPosition;
    183             }
    184             int sliderHeight = mZoomSlider.getMeasuredHeight();
    185             mZoomSlider.layout(0, (pos - sliderHeight / 2), size,
    186                     (pos + sliderHeight / 2));
    187         } else {
    188             if (mOrientation == 90) {
    189                 mZoomIn.layout(0, 0, mIconSize, size);
    190                 mZoomOut.layout(mSize - mIconSize, 0, mSize, size);
    191                 pos = mBar.getRight() - sliderPosition;
    192             } else {
    193                 mZoomOut.layout(0, 0, mIconSize, size);
    194                 mZoomIn.layout(mSize - mIconSize, 0, mSize, size);
    195                 pos = mBar.getLeft() + sliderPosition;
    196             }
    197             int sliderWidth = mZoomSlider.getMeasuredWidth();
    198             mZoomSlider.layout((pos - sliderWidth / 2), 0,
    199                     (pos + sliderWidth / 2), size);
    200         }
    201     }
    202 
    203     @Override
    204     public void setZoomIndex(int index) {
    205         super.setZoomIndex(index);
    206         mSliderPosition = -1; // -1 means invalid
    207     }
    208 }
    209