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 ZoomControlBar(Context context, AttributeSet attrs)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 setActivated(boolean activated)60 public void setActivated(boolean activated) { 61 super.setActivated(activated); 62 mBar.setActivated(activated); 63 } 64 getSliderPosition(int offset)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 onSizeChanged(int w, int h, int oldw, int oldh)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 dispatchTouchEvent(MotionEvent event)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 setOrientation(int orientation, boolean animation)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 onLayout( boolean changed, int left, int top, int right, int bottom)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 setZoomIndex(int index)204 public void setZoomIndex(int index) { 205 super.setZoomIndex(index); 206 mSliderPosition = -1; // -1 means invalid 207 } 208 } 209