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 com.android.camera.R;
20 import com.android.camera.Util;
21 
22 import android.content.Context;
23 import android.util.AttributeSet;
24 import android.view.MotionEvent;
25 import android.view.View;
26 
27 /**
28  * A view that contains camera zoom control and its layout.
29  */
30 public class ZoomControlBar extends ZoomControl {
31     private static final String TAG = "ZoomControlBar";
32     private static final int THRESHOLD_FIRST_MOVE = Util.dpToPixel(10); // pixels
33     // Space between indicator icon and the zoom-in/out icon.
34     private static final int ICON_SPACING = Util.dpToPixel(12);
35 
36     private View mBar;
37     private boolean mStartChanging;
38     private int mSliderPosition = 0;
39     private int mSliderLength;
40     private int mWidth;
41     private int mIconWidth;
42     private int mTotalIconWidth;
43 
ZoomControlBar(Context context, AttributeSet attrs)44     public ZoomControlBar(Context context, AttributeSet attrs) {
45         super(context, attrs);
46         mBar = new View(context);
47         mBar.setBackgroundResource(R.drawable.zoom_slider_bar);
48         addView(mBar);
49     }
50 
51     @Override
setActivated(boolean activated)52     public void setActivated(boolean activated) {
53         super.setActivated(activated);
54         mBar.setActivated(activated);
55     }
56 
getSliderPosition(int x)57     private int getSliderPosition(int x) {
58         // Calculate the absolute offset of the slider in the zoom control bar.
59         // For left-hand users, as the device is rotated for 180 degree for
60         // landscape mode, the zoom-in bottom should be on the top, so the
61         // position should be reversed.
62         int pos; // the relative position in the zoom slider bar
63         if (mOrientation == 90) {
64             pos = mWidth - mTotalIconWidth - x;
65         } else {
66             pos = x - mTotalIconWidth;
67         }
68         if (pos < 0) pos = 0;
69         if (pos > mSliderLength) pos = mSliderLength;
70         return pos;
71     }
72 
73     @Override
onSizeChanged(int w, int h, int oldw, int oldh)74     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
75         mWidth = w;
76         mIconWidth = mZoomIn.getMeasuredWidth();
77         mTotalIconWidth = mIconWidth + ICON_SPACING;
78         mSliderLength = mWidth  - (2 * mTotalIconWidth);
79     }
80 
81     @Override
dispatchTouchEvent(MotionEvent event)82     public boolean dispatchTouchEvent(MotionEvent event) {
83         if (!isEnabled() || (mWidth == 0)) return false;
84         int action = event.getAction();
85 
86         switch (action) {
87             case MotionEvent.ACTION_OUTSIDE:
88             case MotionEvent.ACTION_CANCEL:
89             case MotionEvent.ACTION_UP:
90                 setActivated(false);
91                 closeZoomControl();
92                 break;
93 
94             case MotionEvent.ACTION_DOWN:
95                 setActivated(true);
96                 mStartChanging = false;
97             case MotionEvent.ACTION_MOVE:
98                 int pos = getSliderPosition((int) event.getX());
99                 if (!mStartChanging) {
100                     // Make sure the movement is large enough before we start
101                     // changing the zoom.
102                     int delta = mSliderPosition - pos;
103                     if ((delta > THRESHOLD_FIRST_MOVE) ||
104                             (delta < -THRESHOLD_FIRST_MOVE)) {
105                         mStartChanging = true;
106                     }
107                 }
108                 if (mStartChanging) {
109                     performZoom(1.0d * pos / mSliderLength);
110                     mSliderPosition = pos;
111                 }
112                 requestLayout();
113         }
114         return true;
115     }
116 
117     @Override
setOrientation(int orientation)118     public void setOrientation(int orientation) {
119         // layout for the left-hand camera control
120         if ((orientation == 90) || (mOrientation == 90)) requestLayout();
121         super.setOrientation(orientation);
122     }
123 
124     @Override
onLayout( boolean changed, int left, int top, int right, int bottom)125     protected void onLayout(
126             boolean changed, int left, int top, int right, int bottom) {
127         if (mZoomMax == 0) return;
128         int height = bottom - top;
129         mBar.layout(mTotalIconWidth, 0, mWidth - mTotalIconWidth, height);
130         // For left-hand users, as the device is rotated for 180 degree,
131         // the zoom-in button should be on the top.
132         int pos; // slider position
133         int sliderPosition;
134         if (mSliderPosition != -1) { // -1 means invalid
135             sliderPosition = mSliderPosition;
136         } else {
137             sliderPosition = (int) ((double) mSliderLength * mZoomIndex / mZoomMax);
138         }
139         if (mOrientation == 90) {
140             mZoomIn.layout(0, 0, mIconWidth, height);
141             mZoomOut.layout(mWidth - mIconWidth, 0, mWidth, height);
142             pos = mBar.getRight() - sliderPosition;
143         } else {
144             mZoomOut.layout(0, 0, mIconWidth, height);
145             mZoomIn.layout(mWidth - mIconWidth, 0, mWidth, height);
146             pos = mBar.getLeft() + sliderPosition;
147         }
148         int sliderWidth = mZoomSlider.getMeasuredWidth();
149         mZoomSlider.layout((pos - sliderWidth / 2), 0,
150                 (pos + sliderWidth / 2), height);
151     }
152 
153     @Override
setZoomIndex(int index)154     public void setZoomIndex(int index) {
155         super.setZoomIndex(index);
156         mSliderPosition = -1; // -1 means invalid
157         requestLayout();
158     }
159 }
160