diff options
author | Chung-yih Wang <cywang@google.com> | 2011-08-19 00:06:51 +0800 |
---|---|---|
committer | Chung-yih Wang <cywang@google.com> | 2011-08-23 19:01:11 +0800 |
commit | ff45331706e2fe361b4ff736d90b0ad4af0e7be9 (patch) | |
tree | b2e242b2ef9808b93fbc7eb853ed61a4a336b47c /src/com/android/camera | |
parent | e285af9d6df325a8c3dfd70248add8ab62fe5b3b (diff) | |
download | LegacyCamera-ff45331706e2fe361b4ff736d90b0ad4af0e7be9.zip LegacyCamera-ff45331706e2fe361b4ff736d90b0ad4af0e7be9.tar.gz LegacyCamera-ff45331706e2fe361b4ff736d90b0ad4af0e7be9.tar.bz2 |
Refactor indicator wheel.
+add IndicatorControlWheel container.
Change-Id: Ia3c7f0441de75a70c8a2172e86d3812b2ef1a15b
Diffstat (limited to 'src/com/android/camera')
-rw-r--r-- | src/com/android/camera/VideoCamera.java | 6 | ||||
-rw-r--r-- | src/com/android/camera/ui/IndicatorControl.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/ui/IndicatorControlBar.java (renamed from src/com/android/camera/ui/IndicatorBar.java) | 6 | ||||
-rw-r--r-- | src/com/android/camera/ui/IndicatorControlBarContainer.java (renamed from src/com/android/camera/ui/IndicatorControlContainer.java) | 73 | ||||
-rw-r--r-- | src/com/android/camera/ui/IndicatorControlWheel.java (renamed from src/com/android/camera/ui/IndicatorWheel.java) | 251 | ||||
-rw-r--r-- | src/com/android/camera/ui/IndicatorControlWheelContainer.java | 183 | ||||
-rw-r--r-- | src/com/android/camera/ui/SecondLevelIndicatorControlBar.java (renamed from src/com/android/camera/ui/SecondLevelIndicatorBar.java) | 6 | ||||
-rw-r--r-- | src/com/android/camera/ui/ZoomPicker.java | 8 |
8 files changed, 334 insertions, 201 deletions
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java index e023c6c..cec06c7 100644 --- a/src/com/android/camera/VideoCamera.java +++ b/src/com/android/camera/VideoCamera.java @@ -17,7 +17,7 @@ package com.android.camera; import com.android.camera.ui.IndicatorControl; -import com.android.camera.ui.IndicatorWheel; +import com.android.camera.ui.IndicatorControlWheelContainer; import com.android.camera.ui.RotateImageView; import com.android.camera.ui.SharePopup; import com.android.camera.ui.ZoomControl; @@ -1381,7 +1381,7 @@ public class VideoCamera extends ActivityBase if (mReviewControl != null) mReviewControl.setVisibility(View.GONE); if (mCaptureTimeLapse) { if (Util.isTabletUI()) { - ((IndicatorWheel) mIndicatorControl).startTimeLapseAnimation( + ((IndicatorControlWheelContainer) mIndicatorControl).startTimeLapseAnimation( mTimeBetweenTimeLapseFrameCaptureMs, mRecordingStartTime); } @@ -1392,7 +1392,7 @@ public class VideoCamera extends ActivityBase if (mReviewControl != null) mReviewControl.setVisibility(View.VISIBLE); if (mCaptureTimeLapse) { if (Util.isTabletUI()) { - ((IndicatorWheel) mIndicatorControl).stopTimeLapseAnimation(); + ((IndicatorControlWheelContainer) mIndicatorControl).stopTimeLapseAnimation(); } } } diff --git a/src/com/android/camera/ui/IndicatorControl.java b/src/com/android/camera/ui/IndicatorControl.java index d8233dc..814dc6d 100644 --- a/src/com/android/camera/ui/IndicatorControl.java +++ b/src/com/android/camera/ui/IndicatorControl.java @@ -106,7 +106,7 @@ public abstract class IndicatorControl extends RelativeLayout implements public void initializeCameraPicker(Context context, PreferenceGroup group) { ListPreference pref = group.findPreference( CameraSettings.KEY_CAMERA_ID); - if (pref == null) return; + if ((pref == null) || (mCameraPicker != null)) return; mCameraPicker = new CameraPicker(context); mCameraPicker.initialize(pref); addView(mCameraPicker); diff --git a/src/com/android/camera/ui/IndicatorBar.java b/src/com/android/camera/ui/IndicatorControlBar.java index 44a83af..49bf409 100644 --- a/src/com/android/camera/ui/IndicatorBar.java +++ b/src/com/android/camera/ui/IndicatorControlBar.java @@ -27,14 +27,14 @@ import android.widget.ImageView; /** * A view that contains the top-level indicator control. */ -public class IndicatorBar extends IndicatorControl implements +public class IndicatorControlBar extends IndicatorControl implements View.OnClickListener { - private static final String TAG = "IndicatorBar"; + private static final String TAG = "IndicatorControlBar"; private ImageView mZoomIcon; private ImageView mSecondLevelIcon; - public IndicatorBar(Context context, AttributeSet attrs) { + public IndicatorControlBar(Context context, AttributeSet attrs) { super(context, attrs); } diff --git a/src/com/android/camera/ui/IndicatorControlContainer.java b/src/com/android/camera/ui/IndicatorControlBarContainer.java index d5c07c5..6bf9c50 100644 --- a/src/com/android/camera/ui/IndicatorControlContainer.java +++ b/src/com/android/camera/ui/IndicatorControlBarContainer.java @@ -30,16 +30,16 @@ import android.view.animation.AnimationUtils; * A view contains indicator control bar, second-level indicator bar and * zoom control. */ -public class IndicatorControlContainer extends IndicatorControl implements +public class IndicatorControlBarContainer extends IndicatorControl implements OnIndicatorEventListener { - private static final String TAG = "IndicatorControlContainer"; + private static final String TAG = "IndicatorControlBarContainer"; private Animation mFadeIn, mFadeOut; - private IndicatorBar mIndicatorBar; + private IndicatorControlBar mIndicatorControlBar; private ZoomControlBar mZoomControlBar; - private SecondLevelIndicatorBar mSecondLevelIndicatorBar; + private SecondLevelIndicatorControlBar mSecondLevelIndicatorControlBar; - public IndicatorControlContainer(Context context, AttributeSet attrs) { + public IndicatorControlBarContainer(Context context, AttributeSet attrs) { super(context, attrs); } @@ -47,7 +47,7 @@ public class IndicatorControlContainer extends IndicatorControl implements public void initialize(Context context, PreferenceGroup group, String flashSetting, String[] secondLevelKeys, String[] secondLevelOtherSettingKeys) { - mIndicatorBar = (IndicatorBar) + mIndicatorControlBar = (IndicatorControlBar) findViewById(R.id.indicator_bar); mZoomControlBar = (ZoomControlBar) @@ -56,15 +56,15 @@ public class IndicatorControlContainer extends IndicatorControl implements // We need to show/hide the zoom slider icon accordingly. // From UI spec, we have camera_flash setting on the first level. - mIndicatorBar.initialize(context, group, flashSetting, + mIndicatorControlBar.initialize(context, group, flashSetting, mZoomControlBar.isZoomSupported()); - mIndicatorBar.setOnIndicatorEventListener(this); + mIndicatorControlBar.setOnIndicatorEventListener(this); - mSecondLevelIndicatorBar = (SecondLevelIndicatorBar) + mSecondLevelIndicatorControlBar = (SecondLevelIndicatorControlBar) findViewById(R.id.second_level_indicator_bar); - mSecondLevelIndicatorBar.initialize(context, group, secondLevelKeys, + mSecondLevelIndicatorControlBar.initialize(context, group, secondLevelKeys, secondLevelOtherSettingKeys); - mSecondLevelIndicatorBar.setOnIndicatorEventListener(this); + mSecondLevelIndicatorControlBar.setOnIndicatorEventListener(this); mFadeIn = AnimationUtils.loadAnimation( context, R.anim.grow_fade_in_from_bottom); @@ -73,63 +73,70 @@ public class IndicatorControlContainer extends IndicatorControl implements } public void setDegree(int degree) { - mIndicatorBar.setDegree(degree); - mSecondLevelIndicatorBar.setDegree(degree); + mIndicatorControlBar.setDegree(degree); + mSecondLevelIndicatorControlBar.setDegree(degree); mZoomControlBar.setDegree(degree); } public void onIndicatorEvent(int event) { switch (event) { case OnIndicatorEventListener.EVENT_ENTER_SECOND_LEVEL_INDICATOR_BAR: - mIndicatorBar.setVisibility(View.GONE); - mSecondLevelIndicatorBar.startAnimation(mFadeIn); - mSecondLevelIndicatorBar.setVisibility(View.VISIBLE); + mIndicatorControlBar.setVisibility(View.GONE); + mSecondLevelIndicatorControlBar.startAnimation(mFadeIn); + mSecondLevelIndicatorControlBar.setVisibility(View.VISIBLE); break; case OnIndicatorEventListener.EVENT_LEAVE_SECOND_LEVEL_INDICATOR_BAR: - mSecondLevelIndicatorBar.startAnimation(mFadeOut); - mSecondLevelIndicatorBar.setVisibility(View.GONE); - mIndicatorBar.setVisibility(View.VISIBLE); + mSecondLevelIndicatorControlBar.startAnimation(mFadeOut); + mSecondLevelIndicatorControlBar.setVisibility(View.GONE); + mIndicatorControlBar.setVisibility(View.VISIBLE); break; case OnIndicatorEventListener.EVENT_ENTER_ZOOM_CONTROL_BAR: - mIndicatorBar.setVisibility(View.GONE); + mIndicatorControlBar.setVisibility(View.GONE); mZoomControlBar.setVisibility(View.VISIBLE); break; case OnIndicatorEventListener.EVENT_LEAVE_ZOOM_CONTROL_BAR: mZoomControlBar.setVisibility(View.GONE); - mIndicatorBar.setVisibility(View.VISIBLE); + mIndicatorControlBar.setVisibility(View.VISIBLE); break; } } public void reloadPreferences() { - mIndicatorBar.reloadPreferences(); - mSecondLevelIndicatorBar.reloadPreferences(); + mIndicatorControlBar.reloadPreferences(); + mSecondLevelIndicatorControlBar.reloadPreferences(); } public void setListener(OnPreferenceChangedListener listener) { - mIndicatorBar.setListener(listener); - mSecondLevelIndicatorBar.setListener(listener); + mIndicatorControlBar.setListener(listener); + mSecondLevelIndicatorControlBar.setListener(listener); } @Override public View getActiveSettingPopup() { - if (mIndicatorBar.getVisibility() == View.VISIBLE) { - return mIndicatorBar.getActiveSettingPopup(); - } else if (mSecondLevelIndicatorBar.getVisibility() == View.VISIBLE) { - return mSecondLevelIndicatorBar.getActiveSettingPopup(); + if (mIndicatorControlBar.getVisibility() == View.VISIBLE) { + return mIndicatorControlBar.getActiveSettingPopup(); + } else if (mSecondLevelIndicatorControlBar.getVisibility() == View.VISIBLE) { + return mSecondLevelIndicatorControlBar.getActiveSettingPopup(); } return null; } public boolean dismissSettingPopup() { - if (mIndicatorBar.getVisibility() == View.VISIBLE) { - return mIndicatorBar.dismissSettingPopup(); - } else if (mSecondLevelIndicatorBar.getVisibility() == View.VISIBLE) { - return mSecondLevelIndicatorBar.dismissSettingPopup(); + if (mIndicatorControlBar.getVisibility() == View.VISIBLE) { + return mIndicatorControlBar.dismissSettingPopup(); + } else if (mSecondLevelIndicatorControlBar.getVisibility() == View.VISIBLE) { + return mSecondLevelIndicatorControlBar.dismissSettingPopup(); } return false; } + + @Override + public void overrideSettings(final String ... keyvalues) { + if (mSecondLevelIndicatorControlBar.getVisibility() == View.VISIBLE) { + mSecondLevelIndicatorControlBar.overrideSettings(keyvalues); + } + } } diff --git a/src/com/android/camera/ui/IndicatorWheel.java b/src/com/android/camera/ui/IndicatorControlWheel.java index 6235cb1..409868f 100644 --- a/src/com/android/camera/ui/IndicatorWheel.java +++ b/src/com/android/camera/ui/IndicatorControlWheel.java @@ -31,17 +31,19 @@ import android.view.MotionEvent; import android.view.View; /** - * A view that contains shutter button and camera setting indicators. The + * A view that contains camera setting indicators. The * indicators are spreaded around the shutter button. The first child is always * the shutter button. */ -public class IndicatorWheel extends IndicatorControl { - private static final String TAG = "IndicatorWheel"; +public class IndicatorControlWheel extends IndicatorControl { + public static final int HIGHLIGHT_WIDTH = 4; + public static final int HIGHLIGHT_DEGREES = 30; + public static final double HIGHLIGHT_RADIANS = Math.toRadians(HIGHLIGHT_DEGREES); + + private static final String TAG = "IndicatorControlWheel"; // The width of the edges on both sides of the wheel, which has less alpha. private static final float EDGE_STROKE_WIDTH = 6f; - private static final int HIGHLIGHT_WIDTH = 4; - private static final int HIGHLIGHT_DEGREE = 30; private static final int TIME_LAPSE_ARC_WIDTH = 6; private final int HIGHLIGHT_COLOR; @@ -50,11 +52,10 @@ public class IndicatorWheel extends IndicatorControl { // The center of the shutter button. private int mCenterX, mCenterY; // The width of the wheel stroke. - private int mStrokeWidth = 60; - private View mShutterButton; + private int mStrokeWidth; private double mShutterButtonRadius; private double mWheelRadius; - private double mSectorInitialRadians[]; + private double mChildRadians[]; private Paint mBackgroundPaint; private RectF mBackgroundRect; // The index of the child that is being pressed. -1 means no child is being @@ -66,7 +67,10 @@ public class IndicatorWheel extends IndicatorControl { private long mRecordingStartTime = 0; private long mNumberOfFrames = 0; - public IndicatorWheel(Context context, AttributeSet attrs) { + // Remember the last event for event cancelling if out of bound. + private MotionEvent mLastMotionEvent; + + public IndicatorControlWheel(Context context, AttributeSet attrs) { super(context, attrs); Resources resources = context.getResources(); HIGHLIGHT_COLOR = resources.getColor(R.color.review_control_pressed_color); @@ -81,97 +85,80 @@ public class IndicatorWheel extends IndicatorControl { mBackgroundRect = new RectF(); } - @Override public void initialize(Context context, PreferenceGroup group, String flashSetting, String[] keys, String[] otherSettingKeys) { + mShutterButtonRadius = IndicatorControlWheelContainer.SHUTTER_BUTTON_RADIUS; + mStrokeWidth = Util.dpToPixel(IndicatorControlWheelContainer.STROKE_WIDTH); + mWheelRadius = mShutterButtonRadius + mStrokeWidth * 0.5; // Add CameraPicker control. initializeCameraPicker(context, group); super.initialize(context, group, flashSetting, keys, otherSettingKeys); + + // The radian intervals for each icon for touch events. + mChildRadians = new double[getChildCount()]; + } + + private int getTouchIndicatorIndex(double delta) { + // The delta is the touch point in radians. + int count = getChildCount(); + if (count == 0) return -1; + int sectors = count - 1; + double sectorDegrees = Math.min(HIGHLIGHT_RADIANS, + (count == 1) ? HIGHLIGHT_RADIANS : (Math.PI / sectors)); + // Check which indicator is touched. + if ((delta >= (Math.PI - HIGHLIGHT_RADIANS) / 2) && + (delta <= (Math.PI + (Math.PI + HIGHLIGHT_RADIANS) / 2))) { + int index = (int) ((delta - Math.PI / 2) * sectors / Math.PI); + if (index > sectors) return sectors ; // degree greater than 270 + if (index < 0) return 0; // degree less than 90 + if (delta <= (mChildRadians[index] + sectorDegrees / 2)) return index; + if (delta >= (mChildRadians[index + 1] - sectorDegrees / 2)) { + return index + 1; + } + } + return -1; + } + + private void injectMotionEvent(int viewIndex, MotionEvent event, int action) { + View v = getChildAt(viewIndex); + event.setAction(action); + v.dispatchTouchEvent(event); } @Override public boolean dispatchTouchEvent(MotionEvent event) { if (!onFilterTouchEventForSecurity(event)) return false; - + mLastMotionEvent = event; int action = event.getAction(); double dx = event.getX() - mCenterX; double dy = mCenterY - event.getY(); double radius = Math.sqrt(dx * dx + dy * dy); - // Check if the event should be dispatched to the shutter button. - if (radius <= mShutterButtonRadius) { - if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP) { - mPressedIndex = (action == MotionEvent.ACTION_DOWN) ? 0 : -1; - return mShutterButton.dispatchTouchEvent(event); - } - return false; - } - - // Send cancel to the shutter button if it was pressed. - if (mPressedIndex == 0) { - event.setAction(MotionEvent.ACTION_CANCEL); - mShutterButton.dispatchTouchEvent(event); - mPressedIndex = -1; - return true; - } - - // Ignore the event if it's too near to the shutter button or too far - // from the shutter button. - if (radius <= mWheelRadius + mStrokeWidth) { + // Ignore the event if too far from the shutter button. + if ((radius <= mWheelRadius + mStrokeWidth) && (radius > mShutterButtonRadius)) { double delta = Math.atan2(dy, dx); if (delta < 0) delta += Math.PI * 2; - // Check which sector is pressed. - if (delta > mSectorInitialRadians[0]) { - for (int i = 1; i < getChildCount(); i++) { - if (delta < mSectorInitialRadians[i]) { - View child = getChildAt(i); - if (action == MotionEvent.ACTION_DOWN) { - if (child instanceof AbstractIndicatorButton) { - AbstractIndicatorButton b = (AbstractIndicatorButton) child; - // If the same setting is pressed when the popup is open, - // do not dismiss it because it will be handled in the child. - if (b.getPopupWindow() == null) { - dismissSettingPopup(); - } - } else { - // Zoom button or back/front camera switch is pressed. - dismissSettingPopup(); - } - if (child.dispatchTouchEvent(event)) { - mPressedIndex = i; - } - invalidate(); - } else if (action == MotionEvent.ACTION_UP) { - child.dispatchTouchEvent(event); - invalidate(); - mPressedIndex = -1; - } else if (action == MotionEvent.ACTION_MOVE) { - // Dispatch the event if the location across a sector. - if (i != mPressedIndex) { - dismissSettingPopup(); - // Cancel the previous one. - if (mPressedIndex != -1) { - View cancelChild = getChildAt(mPressedIndex); - event.setAction(MotionEvent.ACTION_CANCEL); - cancelChild.dispatchTouchEvent(event); - mPressedIndex = -1; - } - // Send down to the current one. - event.setAction(MotionEvent.ACTION_DOWN); - if (child.dispatchTouchEvent(event)) { - mPressedIndex = i; - } - invalidate(); - } - // The children do not care about ACTION_MOVE. - // Besides, the press state will be wrong - // because of View.pointInView. - } - return true; - } + int index = getTouchIndicatorIndex(delta); + // Move over from one indicator to another. + if ((index != mPressedIndex) || (action == MotionEvent.ACTION_DOWN)) { + if (mPressedIndex != -1) { + injectMotionEvent(mPressedIndex, event, MotionEvent.ACTION_CANCEL); + } else { + // Cancel the popup if it is different from the selected. + if (getSelectedIndicatorIndex() != index) dismissSettingPopup(); + } + if ((index != -1) && (action == MotionEvent.ACTION_MOVE)) { + injectMotionEvent(index, event, MotionEvent.ACTION_DOWN); } } + if ((index != -1) && (action != MotionEvent.ACTION_MOVE)) { + getChildAt(index).dispatchTouchEvent(event); + } + // Once the button is up, reset the press index. + mPressedIndex = (action == MotionEvent.ACTION_UP) ? -1 : index; + invalidate(); + return true; } // The event is not on any of the child. dismissSettingPopup(); @@ -186,75 +173,25 @@ public class IndicatorWheel extends IndicatorControl { } @Override - protected void onFinishInflate() { - super.onFinishInflate(); - // The first view is shutter button. - mShutterButton = getChildAt(0); - invalidate(); - } - - @Override - protected void onMeasure(int widthSpec, int heightSpec) { - // Measure all children. - int childCount = getChildCount(); - int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); - for (int i = 0; i < childCount; i++) { - getChildAt(i).measure(freeSpec, freeSpec); - } - - // Measure myself. Add some buffer for highlight arc. - int desiredWidth = mShutterButton.getMeasuredWidth() + HIGHLIGHT_WIDTH * 4; - int desiredHeight = mShutterButton.getMeasuredHeight() + HIGHLIGHT_WIDTH * 4; - int widthMode = MeasureSpec.getMode(widthSpec); - int heightMode = MeasureSpec.getMode(heightSpec); - int measuredWidth, measuredHeight; - if (widthMode == MeasureSpec.UNSPECIFIED) { - measuredWidth = desiredWidth; - } else if (widthMode == MeasureSpec.AT_MOST) { - measuredWidth = Math.min(desiredWidth, MeasureSpec.getSize(widthSpec)); - } else { // MeasureSpec.EXACTLY - measuredWidth = MeasureSpec.getSize(widthSpec); - } - if (heightMode == MeasureSpec.UNSPECIFIED) { - measuredHeight = desiredHeight; - } else if (heightMode == MeasureSpec.AT_MOST) { - measuredHeight = Math.min(desiredHeight, MeasureSpec.getSize(heightSpec)); - } else { // MeasureSpec.EXACTLY - measuredHeight = MeasureSpec.getSize(heightSpec); - } - setMeasuredDimension(measuredWidth, measuredHeight); - } - - @Override protected void onLayout( boolean changed, int left, int top, int right, int bottom) { int count = getChildCount(); if (count == 0) return; - // Layout the shutter button. - int shutterButtonWidth = mShutterButton.getMeasuredWidth(); - int shutterButtonHeight = mShutterButton.getMeasuredHeight(); - // These numbers have to sync with the background of the shutter button. - mShutterButtonRadius = Util.dpToPixel(74); - mStrokeWidth = Util.dpToPixel(87); - mCenterX = right - left - Util.dpToPixel(93); + mCenterX = right - left - Util.dpToPixel( + IndicatorControlWheelContainer.FULL_WHEEL_RADIUS); mCenterY = (bottom - top) / 2; - mShutterButton.layout(right - left - shutterButtonWidth, - mCenterY - shutterButtonHeight / 2, - right - left, - mCenterY + shutterButtonHeight - shutterButtonHeight / 2); // Layout the settings. The icons are spreaded on the left side of the // shutter button. So the angle starts from 90 to 270 degrees. - if (count == 1) return; - mWheelRadius = mShutterButtonRadius + mStrokeWidth * 0.5; - double intervalDegrees = (count == 2) ? 90.0 : 180.0 / (count - 2); + + // This will just get rid of Divide-By-Zero. + double intervalDegrees = (count == 1) ? 90.0 : 180.0 / (count - 1); double initialDegrees = 90.0; - int index = 0; + for (int i = 0; i < count; i++) { View view = getChildAt(i); - if (view == mShutterButton) continue; - double degree = initialDegrees + intervalDegrees * index; + double degree = initialDegrees + intervalDegrees * i; double radian = Math.toRadians(degree); int x = mCenterX + (int)(mWheelRadius * Math.cos(radian)); int y = mCenterY - (int)(mWheelRadius * Math.sin(radian)); @@ -262,16 +199,8 @@ public class IndicatorWheel extends IndicatorControl { int height = view.getMeasuredHeight(); view.layout(x - width / 2, y - height / 2, x + width / 2, y + height / 2); - index++; - } - - // Store the radian intervals for each icon. - mSectorInitialRadians = new double[count]; - mSectorInitialRadians[0] = Math.toRadians( - initialDegrees - intervalDegrees / 2.0); - for (int i = 1; i < count; i++) { - mSectorInitialRadians[i] = mSectorInitialRadians[i - 1] - + Math.toRadians(intervalDegrees); + // Store the radian intervals for each icon. + mChildRadians[i] = Math.toRadians(degree); } } @@ -294,6 +223,11 @@ public class IndicatorWheel extends IndicatorControl { return indexOfChild(b); } } + if (mPressedIndex != -1) { + if (!(getChildAt(mPressedIndex) instanceof AbstractIndicatorButton)) { + return mPressedIndex; + } + } return -1; } @@ -308,21 +242,17 @@ public class IndicatorWheel extends IndicatorControl { int selectedIndex = getSelectedIndicatorIndex(); // Draw the highlight arc if an indicator is selected or being pressed. - if (selectedIndex >= 0 || mPressedIndex > 0) { + if (selectedIndex >= 0) { int count = getChildCount(); float initialDegrees = 90.0f; - float intervalDegrees = (count <= 2) ? 0.0f : 180.0f / (count - 2); + float intervalDegrees = (count <= 1) ? 0.0f : 180.0f / (count - 1); float degree; - if (selectedIndex >= 0) { - degree = initialDegrees + intervalDegrees * (selectedIndex - 1); - } else { - degree = initialDegrees + intervalDegrees * (mPressedIndex - 1); - } + degree = initialDegrees + intervalDegrees * selectedIndex; mBackgroundPaint.setStrokeWidth(HIGHLIGHT_WIDTH); mBackgroundPaint.setStrokeCap(Paint.Cap.ROUND); mBackgroundPaint.setColor(HIGHLIGHT_COLOR); - canvas.drawArc(mBackgroundRect, -degree - HIGHLIGHT_DEGREE / 2, - HIGHLIGHT_DEGREE, false, mBackgroundPaint); + canvas.drawArc(mBackgroundRect, -degree - HIGHLIGHT_DEGREES / 2, + HIGHLIGHT_DEGREES, false, mBackgroundPaint); } // Draw arc shaped indicator in time lapse recording. @@ -356,4 +286,13 @@ public class IndicatorWheel extends IndicatorControl { super.onDraw(canvas); } + + public void onTouchOutBound() { + if (mPressedIndex != -1) { + dismissSettingPopup(); + injectMotionEvent(mPressedIndex, mLastMotionEvent, MotionEvent.ACTION_CANCEL); + mPressedIndex = -1; + invalidate(); + } + } } diff --git a/src/com/android/camera/ui/IndicatorControlWheelContainer.java b/src/com/android/camera/ui/IndicatorControlWheelContainer.java new file mode 100644 index 0000000..fbf7565 --- /dev/null +++ b/src/com/android/camera/ui/IndicatorControlWheelContainer.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.ui; + +import com.android.camera.CameraPreference.OnPreferenceChangedListener; +import com.android.camera.PreferenceGroup; +import com.android.camera.R; +import com.android.camera.Util; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; + +/** + * A view that contains shutter button and indicator control wheel + * and zoom control wheel. + */ +public class IndicatorControlWheelContainer extends IndicatorControl { + public static final int STROKE_WIDTH = 87; + public static final int SHUTTER_BUTTON_RADIUS = 74; + public static final int FULL_WHEEL_RADIUS = 93; + + private static final String TAG = "IndicatorControlWheelContainer"; + + private View mShutterButton; + private double mShutterButtonRadius; + private IndicatorControlWheel mIndicatorControlWheel; + private int mCenterX, mCenterY; + + public IndicatorControlWheelContainer(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + public void initialize(Context context, PreferenceGroup group, + String flashSetting, String[] keys, String[] otherSettingKeys) { + mShutterButton = findViewById(R.id.shutter_button); + mShutterButtonRadius = Util.dpToPixel(SHUTTER_BUTTON_RADIUS); + mIndicatorControlWheel = (IndicatorControlWheel) findViewById( + R.id.indicator_control_wheel); + mIndicatorControlWheel.initialize(context, group, + flashSetting, keys, otherSettingKeys); + // TODO: add ZoomControlWheel here. + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) { + if (!onFilterTouchEventForSecurity(event)) return false; + + int action = event.getAction(); + + double dx = event.getX() - mCenterX; + double dy = mCenterY - event.getY(); + double radius = Math.sqrt(dx * dx + dy * dy); + + // Check if the event should be dispatched to the shutter button. + if (radius <= mShutterButtonRadius) { + mIndicatorControlWheel.onTouchOutBound(); + if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP) { + return mShutterButton.dispatchTouchEvent(event); + } + return false; + } + + if (mShutterButton.isPressed()) { + // Send cancel to the shutter button if it was pressed. + event.setAction(MotionEvent.ACTION_CANCEL); + mShutterButton.dispatchTouchEvent(event); + return true; + } + + // TODO: dispatch event to ZoomControlWheel instead if it is visible. + return mIndicatorControlWheel.dispatchTouchEvent(event); + } + + @Override + protected void onLayout( + boolean changed, int left, int top, int right, int bottom) { + + // Layout the shutter button. + int shutterButtonWidth = mShutterButton.getMeasuredWidth(); + int shutterButtonHeight = mShutterButton.getMeasuredHeight(); + mCenterX = right - left - Util.dpToPixel(FULL_WHEEL_RADIUS); + mCenterY = (bottom - top) / 2; + mShutterButton.layout(right - left - shutterButtonWidth, + mCenterY - shutterButtonHeight / 2, + right - left, + mCenterY + shutterButtonHeight - shutterButtonHeight / 2); + // Layout the control wheel. + mIndicatorControlWheel.layout(0, 0, right - left, bottom - top); + } + + @Override + protected void onMeasure(int widthSpec, int heightSpec) { + // Measure all children. + int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); + mShutterButton.measure(freeSpec, freeSpec); + mIndicatorControlWheel.measure(freeSpec, freeSpec); + + // Measure myself. Add some buffer for highlight arc. + int desiredWidth = mShutterButton.getMeasuredWidth() + + IndicatorControlWheel.HIGHLIGHT_WIDTH * 4; + int desiredHeight = mShutterButton.getMeasuredHeight() + + IndicatorControlWheel.HIGHLIGHT_WIDTH * 4; + int widthMode = MeasureSpec.getMode(widthSpec); + int heightMode = MeasureSpec.getMode(heightSpec); + int measuredWidth, measuredHeight; + if (widthMode == MeasureSpec.UNSPECIFIED) { + measuredWidth = desiredWidth; + } else if (widthMode == MeasureSpec.AT_MOST) { + measuredWidth = Math.min(desiredWidth, MeasureSpec.getSize(widthSpec)); + } else { // MeasureSpec.EXACTLY + measuredWidth = MeasureSpec.getSize(widthSpec); + } + if (heightMode == MeasureSpec.UNSPECIFIED) { + measuredHeight = desiredHeight; + } else if (heightMode == MeasureSpec.AT_MOST) { + measuredHeight = Math.min(desiredHeight, MeasureSpec.getSize(heightSpec)); + } else { // MeasureSpec.EXACTLY + measuredHeight = MeasureSpec.getSize(heightSpec); + } + setMeasuredDimension(measuredWidth, measuredHeight); + } + + @Override + public void setListener(OnPreferenceChangedListener listener) { + mIndicatorControlWheel.setListener(listener); + } + + @Override + public void reloadPreferences() { + mIndicatorControlWheel.reloadPreferences(); + } + + @Override + public View getActiveSettingPopup() { + return mIndicatorControlWheel.getActiveSettingPopup(); + } + + @Override + public boolean dismissSettingPopup() { + return mIndicatorControlWheel.dismissSettingPopup(); + } + + @Override + public void setDegree(int degree) { + mIndicatorControlWheel.setDegree(degree); + } + + public void startTimeLapseAnimation(int timeLapseInterval, long startTime) { + mIndicatorControlWheel.startTimeLapseAnimation( + timeLapseInterval, startTime); + } + + public void stopTimeLapseAnimation() { + mIndicatorControlWheel.stopTimeLapseAnimation(); + } + + @Override + public void setEnabled(boolean enabled) { + mIndicatorControlWheel.setEnabled(enabled); + } + + @Override + public void overrideSettings(final String ... keyvalues) { + mIndicatorControlWheel.overrideSettings(keyvalues); + } +} diff --git a/src/com/android/camera/ui/SecondLevelIndicatorBar.java b/src/com/android/camera/ui/SecondLevelIndicatorControlBar.java index 07ff602..8fb3599 100644 --- a/src/com/android/camera/ui/SecondLevelIndicatorBar.java +++ b/src/com/android/camera/ui/SecondLevelIndicatorControlBar.java @@ -29,14 +29,14 @@ import android.widget.ImageView; * A view that contains camera setting indicators which are spread over a * vertical bar in preview frame. */ -public class SecondLevelIndicatorBar extends IndicatorControl implements +public class SecondLevelIndicatorControlBar extends IndicatorControl implements View.OnClickListener { - private static final String TAG = "SecondLevelIndicatorBar"; + private static final String TAG = "SecondLevelIndicatorControlBar"; private ImageView mCloseIcon; int mDegree = 0; int mSelectedIndex = -1; - public SecondLevelIndicatorBar(Context context, AttributeSet attrs) { + public SecondLevelIndicatorControlBar(Context context, AttributeSet attrs) { super(context, attrs); } diff --git a/src/com/android/camera/ui/ZoomPicker.java b/src/com/android/camera/ui/ZoomPicker.java index 75db254..d25b6f8 100644 --- a/src/com/android/camera/ui/ZoomPicker.java +++ b/src/com/android/camera/ui/ZoomPicker.java @@ -73,8 +73,12 @@ public class ZoomPicker extends ZoomControl { if (zooming()) mHandler.postDelayed(mRunnable, 300); } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { - mState = ZOOM_STOP; - stopZooming(); + int eventState = (v == increment) ? ZOOM_IN : ZOOM_OUT; + // Ignore the event if the current state does not match. + if (eventState == mState) { + stopZooming(); + mState = ZOOM_STOP; + } } return false; } |