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 mSliderLength; 39 private int mHeight; 40 private int mIconHeight; 41 private int mTotalIconHeight; 42 ZoomControlBar(Context context, AttributeSet attrs)43 public ZoomControlBar(Context context, AttributeSet attrs) { 44 super(context, attrs); 45 mBar = new View(context); 46 mBar.setBackgroundResource(R.drawable.zoom_slider_bar); 47 addView(mBar); 48 } 49 50 @Override setActivated(boolean activated)51 public void setActivated(boolean activated) { 52 super.setActivated(activated); 53 mBar.setActivated(activated); 54 } 55 getSliderPosition(int y)56 private int getSliderPosition(int y) { 57 // Calculate the absolute offset of the slider in the zoom control bar. 58 // For left-hand users, as the device is rotated for 180 degree for 59 // landscape mode, the zoom-in bottom should be on the top, so the 60 // position should be reversed. 61 int pos; // the relative position in the zoom slider bar 62 if (mDegree == 180) { 63 pos = y - mTotalIconHeight; 64 } else { 65 pos = mHeight - mTotalIconHeight - y; 66 } 67 if (pos < 0) pos = 0; 68 if (pos > mSliderLength) pos = mSliderLength; 69 return pos; 70 } 71 72 @Override onSizeChanged(int w, int h, int oldw, int oldh)73 protected void onSizeChanged(int w, int h, int oldw, int oldh) { 74 mHeight = h; 75 mIconHeight = mZoomIn.getMeasuredHeight(); 76 mTotalIconHeight = mIconHeight + ICON_SPACING; 77 mSliderLength = mHeight - (2 * mTotalIconHeight); 78 } 79 80 @Override dispatchTouchEvent(MotionEvent event)81 public boolean dispatchTouchEvent(MotionEvent event) { 82 if (!isEnabled() || (mHeight == 0)) return false; 83 int action = event.getAction(); 84 85 switch (action) { 86 case MotionEvent.ACTION_OUTSIDE: 87 case MotionEvent.ACTION_CANCEL: 88 case MotionEvent.ACTION_UP: 89 setActivated(false); 90 closeZoomControl(); 91 break; 92 93 case MotionEvent.ACTION_DOWN: 94 setActivated(true); 95 mStartChanging = false; 96 case MotionEvent.ACTION_MOVE: 97 int pos = getSliderPosition((int) event.getY()); 98 if (!mStartChanging) { 99 // Make sure the movement is large enough before we start 100 // changing the zoom. 101 int delta = mSliderPosition - pos; 102 if ((delta > THRESHOLD_FIRST_MOVE) || 103 (delta < -THRESHOLD_FIRST_MOVE)) { 104 mStartChanging = true; 105 } 106 } 107 if (mStartChanging) { 108 performZoom(1.0d * pos / mSliderLength); 109 mSliderPosition = pos; 110 } 111 requestLayout(); 112 } 113 return true; 114 } 115 116 @Override setDegree(int degree)117 public void setDegree(int degree) { 118 // layout for the left-hand camera control 119 if ((degree == 180) || (mDegree == 180)) requestLayout(); 120 super.setDegree(degree); 121 } 122 123 @Override onLayout( boolean changed, int left, int top, int right, int bottom)124 protected void onLayout( 125 boolean changed, int left, int top, int right, int bottom) { 126 if (mZoomMax == 0) return; 127 int width = right - left; 128 mBar.layout(0, mTotalIconHeight, width, mHeight - mTotalIconHeight); 129 // For left-hand users, as the device is rotated for 180 degree, 130 // the zoom-in button should be on the top. 131 int pos; // slider position 132 int sliderPosition; 133 if (mSliderPosition != -1) { // -1 means invalid 134 sliderPosition = mSliderPosition; 135 } else { 136 sliderPosition = (int) ((double) mSliderLength * mZoomIndex / mZoomMax); 137 } 138 if (mDegree == 180) { 139 mZoomOut.layout(0, 0, width, mIconHeight); 140 mZoomIn.layout(0, mHeight - mIconHeight, width, mHeight); 141 pos = mBar.getTop() + sliderPosition; 142 } else { 143 mZoomIn.layout(0, 0, width, mIconHeight); 144 mZoomOut.layout(0, mHeight - mIconHeight, width, mHeight); 145 pos = mBar.getBottom() - sliderPosition; 146 } 147 int sliderHeight = mZoomSlider.getMeasuredHeight(); 148 mZoomSlider.layout(0, (pos - sliderHeight / 2), 149 width, (pos + sliderHeight / 2)); 150 } 151 152 @Override setZoomIndex(int index)153 public void setZoomIndex(int index) { 154 super.setZoomIndex(index); 155 mSliderPosition = -1; // -1 means invalid 156 requestLayout(); 157 } 158 } 159