summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/com/android/camera/Camera.java164
-rw-r--r--src/com/android/camera/EffectsRecorder.java7
-rw-r--r--src/com/android/camera/FocusManager.java4
-rwxr-xr-xsrc/com/android/camera/VideoCamera.java31
-rwxr-xr-xsrc/com/android/camera/panorama/PanoramaActivity.java1
-rw-r--r--src/com/android/camera/ui/AbstractIndicatorButton.java4
-rw-r--r--src/com/android/camera/ui/IndicatorControlWheel.java137
-rw-r--r--src/com/android/camera/ui/IndicatorControlWheelContainer.java33
-rw-r--r--src/com/android/camera/ui/OneRowGridView.java26
-rw-r--r--src/com/android/camera/ui/RotateTextToast.java58
-rw-r--r--src/com/android/camera/ui/SecondLevelIndicatorControlBar.java34
-rw-r--r--src/com/android/camera/ui/SharePopup.java72
-rw-r--r--src/com/android/camera/ui/StackLayout.java59
-rw-r--r--src/com/android/camera/ui/ZoomControl.java1
-rw-r--r--src/com/android/camera/ui/ZoomControlBar.java1
-rw-r--r--src/com/android/camera/ui/ZoomControlWheel.java66
16 files changed, 438 insertions, 260 deletions
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java
index c768d00..f0c1f30 100644
--- a/src/com/android/camera/Camera.java
+++ b/src/com/android/camera/Camera.java
@@ -22,6 +22,7 @@ import com.android.camera.ui.IndicatorControlContainer;
import com.android.camera.ui.Rotatable;
import com.android.camera.ui.RotateImageView;
import com.android.camera.ui.RotateLayout;
+import com.android.camera.ui.RotateTextToast;
import com.android.camera.ui.SharePopup;
import com.android.camera.ui.ZoomControl;
@@ -66,6 +67,7 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.AnimationUtils;
+import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
@@ -94,8 +96,7 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
private static final int SET_CAMERA_PARAMETERS_WHEN_IDLE = 4;
private static final int CHECK_DISPLAY_ROTATION = 5;
private static final int SHOW_TAP_TO_FOCUS_TOAST = 6;
- private static final int DISMISS_TAP_TO_FOCUS_TOAST = 7;
- private static final int UPDATE_THUMBNAIL = 8;
+ private static final int UPDATE_THUMBNAIL = 7;
// The subset of parameters we need to update in setCameraParameters().
private static final int UPDATE_PARAM_INITIALIZE = 1;
@@ -159,7 +160,7 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
private RotateImageView mThumbnailView;
private ModePicker mModePicker;
private FaceView mFaceView;
- private RotateLayout mFocusIndicator;
+ private RotateLayout mFocusAreaIndicator;
private Rotatable mReviewCancelButton;
private Rotatable mReviewDoneButton;
@@ -167,10 +168,13 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
private String mCropValue;
private Uri mSaveUri;
- // On-screen indicator
- private View mGpsNoSignalIndicator;
- private View mGpsHasSignalIndicator;
+ // Small indicators which show the camera settings in the viewfinder.
private TextView mExposureIndicator;
+ private ImageView mGpsIndicator;
+ private ImageView mFlashIndicator;
+ private ImageView mSceneIndicator;
+ private ImageView mWhiteBalanceIndicator;
+ private ImageView mFocusIndicator;
// We use a thread in ImageSaver to do the work of saving images and
// generating thumbnails. This reduces the shot-to-shot time.
@@ -306,14 +310,6 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
break;
}
- case DISMISS_TAP_TO_FOCUS_TOAST: {
- View v = findViewById(R.id.first_use_hint);
- v.setVisibility(View.GONE);
- v.setAnimation(AnimationUtils.loadAnimation(Camera.this,
- R.anim.on_screen_hint_exit));
- break;
- }
-
case UPDATE_THUMBNAIL: {
mImageSaver.updateThumbnail();
break;
@@ -379,15 +375,16 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
// Initialize focus UI.
mPreviewFrame = findViewById(R.id.camera_preview);
mPreviewFrame.setOnTouchListener(this);
- mFocusIndicator = (RotateLayout) findViewById(R.id.focus_indicator_rotate_layout);
+ mFocusAreaIndicator = (RotateLayout) findViewById(R.id.focus_indicator_rotate_layout);
CameraInfo info = CameraHolder.instance().getCameraInfo()[mCameraId];
boolean mirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT);
- mFocusManager.initialize(mFocusIndicator, mPreviewFrame, mFaceView, this,
+ mFocusManager.initialize(mFocusAreaIndicator, mPreviewFrame, mFaceView, this,
mirror, mDisplayOrientation);
mImageSaver = new ImageSaver();
Util.initializeScreenBrightness(getWindow(), getContentResolver());
installIntentFilter();
initializeZoom();
+ updateOnScreenIndicators();
startFaceDetection();
// Show the tap to focus toast if this is the first start.
if (mFocusAreaSupported &&
@@ -596,39 +593,40 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
};
private void initOnScreenIndicator() {
- mGpsNoSignalIndicator = findViewById(R.id.onscreen_gps_indicator_no_signal);
- mGpsHasSignalIndicator = findViewById(R.id.onscreen_gps_indicator_on);
+ mGpsIndicator = (ImageView) findViewById(R.id.onscreen_gps_indicator);
mExposureIndicator = (TextView) findViewById(R.id.onscreen_exposure_indicator);
+ mFlashIndicator = (ImageView) findViewById(R.id.onscreen_flash_indicator);
+ mSceneIndicator = (ImageView) findViewById(R.id.onscreen_scene_indicator);
+ mWhiteBalanceIndicator =
+ (ImageView) findViewById(R.id.onscreen_white_balance_indicator);
+ mFocusIndicator = (ImageView) findViewById(R.id.onscreen_focus_indicator);
}
@Override
public void showGpsOnScreenIndicator(boolean hasSignal) {
+ if (mGpsIndicator == null) {
+ return;
+ }
if (hasSignal) {
- if (mGpsNoSignalIndicator != null) {
- mGpsNoSignalIndicator.setVisibility(View.GONE);
- }
- if (mGpsHasSignalIndicator != null) {
- mGpsHasSignalIndicator.setVisibility(View.VISIBLE);
- }
+ mGpsIndicator.setImageResource(R.drawable.ic_viewfinder_gps_on);
} else {
- if (mGpsNoSignalIndicator != null) {
- mGpsNoSignalIndicator.setVisibility(View.VISIBLE);
- }
- if (mGpsHasSignalIndicator != null) {
- mGpsHasSignalIndicator.setVisibility(View.GONE);
- }
+ mGpsIndicator.setImageResource(R.drawable.ic_viewfinder_gps_no_signal);
}
+ mGpsIndicator.setVisibility(View.VISIBLE);
}
@Override
public void hideGpsOnScreenIndicator() {
- if (mGpsNoSignalIndicator != null) mGpsNoSignalIndicator.setVisibility(View.GONE);
- if (mGpsHasSignalIndicator != null) mGpsHasSignalIndicator.setVisibility(View.GONE);
+ if (mGpsIndicator == null) {
+ return;
+ }
+ mGpsIndicator.setVisibility(View.GONE);
}
private void updateExposureOnScreenIndicator(int value) {
- if (mExposureIndicator == null) return;
-
+ if (mExposureIndicator == null) {
+ return;
+ }
if (value == 0) {
mExposureIndicator.setText("");
mExposureIndicator.setVisibility(View.GONE);
@@ -643,6 +641,69 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
}
}
+ private void updateFlashOnScreenIndicator(String value) {
+ if (mFlashIndicator == null) {
+ return;
+ }
+ if (Parameters.FLASH_MODE_AUTO.equals(value)) {
+ mFlashIndicator.setImageResource(R.drawable.ic_indicators_landscape_flash_auto);
+ } else if (Parameters.FLASH_MODE_ON.equals(value)) {
+ mFlashIndicator.setImageResource(R.drawable.ic_indicators_landscape_flash_on);
+ } else if (Parameters.FLASH_MODE_OFF.equals(value)) {
+ mFlashIndicator.setImageResource(R.drawable.ic_indicators_landscape_flash_off);
+ }
+ }
+
+ private void updateSceneOnScreenIndicator(boolean isVisible) {
+ if (mSceneIndicator == null) {
+ return;
+ }
+ mSceneIndicator.setVisibility(isVisible ? View.VISIBLE : View.GONE);
+ }
+
+ private void updateWhiteBalanceOnScreenIndicator(String value) {
+ if (mWhiteBalanceIndicator == null) {
+ return;
+ }
+ if (Parameters.WHITE_BALANCE_AUTO.equals(value)) {
+ mWhiteBalanceIndicator.setVisibility(View.GONE);
+ } else {
+ if (Parameters.WHITE_BALANCE_FLUORESCENT.equals(value)) {
+ mWhiteBalanceIndicator.setImageResource(R.drawable.ic_indicators_fluorescent);
+ } else if (Parameters.WHITE_BALANCE_INCANDESCENT.equals(value)) {
+ mWhiteBalanceIndicator.setImageResource(R.drawable.ic_indicators_incandescent);
+ } else if (Parameters.WHITE_BALANCE_DAYLIGHT.equals(value)) {
+ mWhiteBalanceIndicator.setImageResource(R.drawable.ic_indicators_sunlight);
+ } else if (Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT.equals(value)) {
+ mWhiteBalanceIndicator.setImageResource(R.drawable.ic_indicators_cloudy);
+ }
+ mWhiteBalanceIndicator.setVisibility(View.VISIBLE);
+ }
+ }
+
+ private void updateFocusOnScreenIndicator(String value) {
+ if (mFocusIndicator == null) {
+ return;
+ }
+ if (Parameters.FOCUS_MODE_INFINITY.equals(value)) {
+ mFocusIndicator.setImageResource(R.drawable.ic_indicators_landscape);
+ mFocusIndicator.setVisibility(View.VISIBLE);
+ } else if (Parameters.FOCUS_MODE_MACRO.equals(value)) {
+ mFocusIndicator.setImageResource(R.drawable.ic_indicators_macro);
+ mFocusIndicator.setVisibility(View.VISIBLE);
+ } else {
+ mFocusIndicator.setVisibility(View.GONE);
+ }
+ }
+
+ private void updateOnScreenIndicators() {
+ boolean isAutoScene = !(Parameters.SCENE_MODE_AUTO.equals(mParameters.getSceneMode()));
+ updateSceneOnScreenIndicator(isAutoScene);
+ updateExposureOnScreenIndicator(CameraSettings.readExposure(mPreferences));
+ updateFlashOnScreenIndicator(mParameters.getFlashMode());
+ updateWhiteBalanceOnScreenIndicator(mParameters.getWhiteBalance());
+ updateFocusOnScreenIndicator(mParameters.getFocusMode());
+ }
private final class ShutterCallback
implements android.hardware.Camera.ShutterCallback {
public void onShutter() {
@@ -1244,7 +1305,7 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
private void setOrientationIndicator(int orientation) {
Rotatable[] indicators = {mThumbnailView, mModePicker, mSharePopup,
- mIndicatorControlContainer, mZoomControl, mFocusIndicator, mFaceView,
+ mIndicatorControlContainer, mZoomControl, mFocusAreaIndicator, mFaceView,
mReviewCancelButton, mReviewDoneButton, mRotateDialog};
for (Rotatable indicator : indicators) {
if (indicator != null) indicator.setOrientation(orientation);
@@ -1405,8 +1466,10 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
// If the user wants to do a snapshot while the previous one is still
// in progress, remember the fact and do it after we finish the previous
- // one and re-start the preview.
- if (mCameraState == SNAPSHOT_IN_PROGRESS) {
+ // one and re-start the preview. Snapshot in progress also includes the
+ // state that autofocus is focusing and a picture will be taken when
+ // focus callback arrives.
+ if (mFocusManager.isFocusingSnapOnFinish() || mCameraState == SNAPSHOT_IN_PROGRESS) {
mSnapshotOnIdle = true;
return;
}
@@ -1766,13 +1829,15 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
setPreviewDisplay(mSurfaceHolder);
setDisplayOrientation();
- mFocusManager.setAeAwbLock(false); // Unlock AE and AWB.
- setCameraParameters(UPDATE_PARAM_ALL);
- // If the focus mode is continuous autofocus, call cancelAutoFocus to
- // resume it because it may have been paused by autoFocus call.
- if (Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mParameters.getFocusMode())) {
- mCameraDevice.cancelAutoFocus();
+ if (!mSnapshotOnIdle) {
+ // If the focus mode is continuous autofocus, call cancelAutoFocus to
+ // resume it because it may have been paused by autoFocus call.
+ if (Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(mFocusManager.getFocusMode())) {
+ mCameraDevice.cancelAutoFocus();
+ }
+ mFocusManager.setAeAwbLock(false); // Unlock AE and AWB.
}
+ setCameraParameters(UPDATE_PARAM_ALL);
// Inform the mainthread to go on the UI initialization.
if (mCameraPreviewThread != null) {
@@ -2148,8 +2213,7 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
setCameraParametersWhenIdle(UPDATE_PARAM_PREFERENCE);
}
- int exposureValue = CameraSettings.readExposure(mPreferences);
- updateExposureOnScreenIndicator(exposureValue);
+ updateOnScreenIndicators();
}
@Override
@@ -2225,15 +2289,7 @@ public class Camera extends ActivityBase implements FocusManager.Listener,
}
private void showTapToFocusToast() {
- // Set the text of toast
- TextView textView = (TextView) findViewById(R.id.toast_text);
- textView.setText(R.string.tap_to_focus);
- // Show the toast.
- RotateLayout v = (RotateLayout) findViewById(R.id.first_use_hint);
- v.setOrientation(mOrientationCompensation);
- v.startAnimation(AnimationUtils.loadAnimation(this, R.anim.on_screen_hint_enter));
- v.setVisibility(View.VISIBLE);
- mHandler.sendEmptyMessageDelayed(DISMISS_TAP_TO_FOCUS_TOAST, 5000);
+ new RotateTextToast(this, R.string.tap_to_focus, mOrientation).show();
// Clear the preference.
Editor editor = mPreferences.edit();
editor.putBoolean(CameraSettings.KEY_CAMERA_FIRST_USE_HINT_SHOWN, false);
diff --git a/src/com/android/camera/EffectsRecorder.java b/src/com/android/camera/EffectsRecorder.java
index 79087df..ea7ce39 100644
--- a/src/com/android/camera/EffectsRecorder.java
+++ b/src/com/android/camera/EffectsRecorder.java
@@ -487,6 +487,13 @@ public class EffectsRecorder {
Filter backgroundSrc = mRunner.getGraph().getFilter("background");
backgroundSrc.setInputValue("sourceUrl",
(String)mEffectParameter);
+ // For front camera, the background video needs to be mirrored in the
+ // backdropper filter
+ if (mCameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
+ Filter replacer = mRunner.getGraph().getFilter("replacer");
+ replacer.setInputValue("mirrorBg", true);
+ if (mLogVerbose) Log.v(TAG, "Setting the background to be mirrored");
+ }
break;
default:
break;
diff --git a/src/com/android/camera/FocusManager.java b/src/com/android/camera/FocusManager.java
index e25c95e..8c3f14d 100644
--- a/src/com/android/camera/FocusManager.java
+++ b/src/com/android/camera/FocusManager.java
@@ -460,6 +460,10 @@ public class FocusManager {
return mState == STATE_SUCCESS || mState == STATE_FAIL;
}
+ public boolean isFocusingSnapOnFinish() {
+ return mState == STATE_FOCUSING_SNAP_ON_FINISH;
+ }
+
public void removeMessages() {
mHandler.removeMessages(RESET_TOUCH_FOCUS);
}
diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java
index 75cba44..004c36a 100755
--- a/src/com/android/camera/VideoCamera.java
+++ b/src/com/android/camera/VideoCamera.java
@@ -22,6 +22,7 @@ import com.android.camera.ui.IndicatorControlWheelContainer;
import com.android.camera.ui.Rotatable;
import com.android.camera.ui.RotateImageView;
import com.android.camera.ui.RotateLayout;
+import com.android.camera.ui.RotateTextToast;
import com.android.camera.ui.SharePopup;
import com.android.camera.ui.ZoomControl;
@@ -98,7 +99,6 @@ public class VideoCamera extends ActivityBase
private static final int UPDATE_RECORD_TIME = 5;
private static final int ENABLE_SHUTTER_BUTTON = 6;
private static final int SHOW_TAP_TO_SNAPSHOT_TOAST = 7;
- private static final int DISMISS_TAP_TO_SNAPSHOT_TOAST = 8;
private static final int SCREEN_DELAY = 2 * 60 * 1000;
@@ -308,14 +308,6 @@ public class VideoCamera extends ActivityBase
break;
}
- case DISMISS_TAP_TO_SNAPSHOT_TOAST: {
- View v = findViewById(R.id.first_use_hint);
- v.setVisibility(View.GONE);
- v.setAnimation(AnimationUtils.loadAnimation(VideoCamera.this,
- R.anim.on_screen_hint_exit));
- break;
- }
-
default:
Log.v(TAG, "Unhandled message: " + msg.what);
break;
@@ -1394,6 +1386,11 @@ public class VideoCamera extends ActivityBase
mCurrentVideoValues.put(Video.Media.RESOLUTION,
Integer.toString(mProfile.videoFrameWidth) + "x" +
Integer.toString(mProfile.videoFrameHeight));
+ Location loc = mLocationManager.getCurrentLocation();
+ if (loc != null) {
+ mCurrentVideoValues.put(Video.Media.LATITUDE, loc.getLatitude());
+ mCurrentVideoValues.put(Video.Media.LONGITUDE, loc.getLongitude());
+ }
Log.v(TAG, "New video filename: " + mVideoFilename);
}
@@ -1540,6 +1537,7 @@ public class VideoCamera extends ActivityBase
return;
}
+ mCurrentVideoUri = null;
if (effectsActive()) {
initializeEffectsRecording();
if (mEffectsRecorder == null) {
@@ -2343,8 +2341,8 @@ public class VideoCamera extends ActivityBase
@Override
public boolean onTouch(View v, MotionEvent e) {
if (mMediaRecorderRecording && effectsActive()) {
- Toast.makeText(this, getResources().getString(
- R.string.disable_video_snapshot_hint), Toast.LENGTH_LONG).show();
+ new RotateTextToast(this, R.string.disable_video_snapshot_hint,
+ mOrientation).show();
return false;
}
@@ -2443,15 +2441,8 @@ public class VideoCamera extends ActivityBase
}
private void showTapToSnapshotToast() {
- // Set the text of toast
- TextView textView = (TextView) findViewById(R.id.toast_text);
- textView.setText(R.string.video_snapshot_hint);
- // Show the toast.
- RotateLayout v = (RotateLayout) findViewById(R.id.first_use_hint);
- v.setOrientation(mOrientationCompensation);
- v.startAnimation(AnimationUtils.loadAnimation(this, R.anim.on_screen_hint_enter));
- v.setVisibility(View.VISIBLE);
- mHandler.sendEmptyMessageDelayed(DISMISS_TAP_TO_SNAPSHOT_TOAST, 5000);
+ new RotateTextToast(this, R.string.video_snapshot_hint, mOrientation)
+ .show();
// Clear the preference.
Editor editor = mPreferences.edit();
editor.putBoolean(CameraSettings.KEY_VIDEO_FIRST_USE_HINT_SHOWN, false);
diff --git a/src/com/android/camera/panorama/PanoramaActivity.java b/src/com/android/camera/panorama/PanoramaActivity.java
index d7a6d50..e4c8d98 100755
--- a/src/com/android/camera/panorama/PanoramaActivity.java
+++ b/src/com/android/camera/panorama/PanoramaActivity.java
@@ -705,6 +705,7 @@ public class PanoramaActivity extends ActivityBase implements
(Rotatable) findViewById(R.id.pano_review_saving_indication_layout),
(Rotatable) findViewById(R.id.pano_saving_progress_bar_layout),
(Rotatable) findViewById(R.id.pano_review_cancel_button_layout),
+ (Rotatable) findViewById(R.id.pano_rotate_reviewarea),
(Rotatable) mRotateDialog,
(Rotatable) mCaptureIndicator,
(Rotatable) mModePicker,
diff --git a/src/com/android/camera/ui/AbstractIndicatorButton.java b/src/com/android/camera/ui/AbstractIndicatorButton.java
index 362becf..fd0f664 100644
--- a/src/com/android/camera/ui/AbstractIndicatorButton.java
+++ b/src/com/android/camera/ui/AbstractIndicatorButton.java
@@ -44,8 +44,8 @@ public abstract class AbstractIndicatorButton extends RotateImageView implements
public AbstractIndicatorButton(Context context) {
super(context);
- mFadeIn = AnimationUtils.loadAnimation(context, R.anim.grow_fade_in_from_right);
- mFadeOut = AnimationUtils.loadAnimation(context, R.anim.shrink_fade_out_from_right);
+ mFadeIn = AnimationUtils.loadAnimation(context, R.anim.setting_popup_grow_fade_in);
+ mFadeOut = AnimationUtils.loadAnimation(context, R.anim.setting_popup_shrink_fade_out);
HIGHLIGHT_COLOR = context.getResources().getColor(R.color.review_control_pressed_color);
setScaleType(ImageView.ScaleType.CENTER);
PopupManager.getInstance(context).setOnOtherPopupShowedListener(this);
diff --git a/src/com/android/camera/ui/IndicatorControlWheel.java b/src/com/android/camera/ui/IndicatorControlWheel.java
index 92f658a..90d8ba8 100644
--- a/src/com/android/camera/ui/IndicatorControlWheel.java
+++ b/src/com/android/camera/ui/IndicatorControlWheel.java
@@ -47,17 +47,19 @@ public class IndicatorControlWheel extends IndicatorControl implements
private static final double HIGHLIGHT_RADIANS = Math.toRadians(HIGHLIGHT_DEGREES);
// The following angles are based in the zero degree on the right. Here we
- // have the fix 45 degrees for each sector in the first-level as we have to
- // align the zoom button exactly at degree 180. For second-level indicators,
- // the indicators located evenly between start and end angle. In addition,
- // these indicators for the second-level hidden in the same wheel with
- // larger angle values are visible after rotation.
- private static final int FIRST_LEVEL_END_DEGREES = 270;
+ // have the CameraPicker, ZoomControl and the Settings icons in the
+ // first-level. For consistency, we treat the zoom control as one of the
+ // indicator buttons but it needs additional efforts for rotation animation.
+ // For second-level indicators, the indicators are located evenly between start
+ // and end angle. In addition, these indicators for the second-level hidden
+ // in the same wheel with larger angle values are visible after rotation.
+ private static final int FIRST_LEVEL_START_DEGREES = 74;
+ private static final int FIRST_LEVEL_END_DEGREES = 286;
private static final int FIRST_LEVEL_SECTOR_DEGREES = 45;
private static final int SECOND_LEVEL_START_DEGREES = 60;
private static final int SECOND_LEVEL_END_DEGREES = 300;
+ private static final int MAX_ZOOM_CONTROL_DEGREES = 264;
private static final int CLOSE_ICON_DEFAULT_DEGREES = 315;
- private static final int ZOOM_ICON_DEFAULT_DEGREES = 180;
private static final int ANIMATION_TIME = 300; // milliseconds
@@ -111,7 +113,8 @@ public class IndicatorControlWheel extends IndicatorControl implements
private double mSectorRadians[] = new double[2];
private double mTouchSectorRadians[] = new double[2];
- private ImageView mZoomIcon;
+ private ZoomControlWheel mZoomControl;
+ private boolean mInitialized;
public IndicatorControlWheel(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -148,7 +151,6 @@ public class IndicatorControlWheel extends IndicatorControl implements
@Override
public void onClick(View view) {
- if (view == mZoomIcon) return;
changeIndicatorsLevel();
}
@@ -160,9 +162,10 @@ public class IndicatorControlWheel extends IndicatorControl implements
setPreferenceGroup(group);
- // Add Zoom Icon.
+ // Add the ZoomControl if supported.
if (isZoomSupported) {
- mZoomIcon = (ImageView) addImageButton(context, R.drawable.ic_zoom_holo_light, false);
+ mZoomControl = (ZoomControlWheel) findViewById(R.id.zoom_control);
+ mZoomControl.setVisibility(View.VISIBLE);
}
// Add CameraPicker.
@@ -180,6 +183,7 @@ public class IndicatorControlWheel extends IndicatorControl implements
mChildRadians = new double[getChildCount()];
presetFirstLevelChildRadians();
presetSecondLevelChildRadians();
+ mInitialized = true;
}
private ImageView addImageButton(Context context, int resourceId, boolean rotatable) {
@@ -200,18 +204,25 @@ public class IndicatorControlWheel extends IndicatorControl implements
if (mInAnimation) return -1;
int count = getChildCountByLevel(mCurrentLevel);
if (count == 0) return -1;
- int startIndex = (mCurrentLevel == 0) ? 0 : mSecondLevelStartIndex;
+ int startIndex = 0;
int sectors = count - 1;
// Check which indicator is touched.
if ((delta >= (mStartVisibleRadians[mCurrentLevel] - HIGHLIGHT_RADIANS / 2)) &&
(delta <= (mEndVisibleRadians[mCurrentLevel] + HIGHLIGHT_RADIANS / 2))) {
- int index = (int) ((delta - mStartVisibleRadians[mCurrentLevel])
- / mSectorRadians[mCurrentLevel]);
-
- // greater than the center of ending indicator
- if (index > sectors) return (startIndex + sectors);
- // less than the center of starting indicator
- if (index < 0) return startIndex;
+ int index = 0;
+ if (mCurrentLevel == 0) {
+ // Skip the first component if it is zoom control, as we will
+ // deal with it specifically.
+ if (mZoomControl != null) startIndex++;
+ } else {
+ startIndex = mSecondLevelStartIndex;
+ index = (int) ((delta - mStartVisibleRadians[mCurrentLevel])
+ / mSectorRadians[mCurrentLevel]);
+ // greater than the center of ending indicator
+ if (index > sectors) return (startIndex + sectors);
+ // less than the center of starting indicator
+ if (index < 0) return startIndex;
+ }
if (delta <= (mChildRadians[startIndex + index]
+ mTouchSectorRadians[mCurrentLevel] / 2)) {
@@ -221,6 +232,10 @@ public class IndicatorControlWheel extends IndicatorControl implements
- mTouchSectorRadians[mCurrentLevel] / 2)) {
return (startIndex + index + 1);
}
+
+ // It must be for zoom control if the touch event is in the visible
+ // range and not for other indicator buttons.
+ if ((mCurrentLevel == 0) && (mZoomControl != null)) return 0;
}
return -1;
}
@@ -246,6 +261,10 @@ public class IndicatorControlWheel extends IndicatorControl implements
double delta = Math.atan2(dy, dx);
if (delta < 0) delta += Math.PI * 2;
int index = getTouchIndicatorIndex(delta);
+ // Check if the touch event is for zoom control.
+ if ((mZoomControl != null) && (index == 0)) {
+ mZoomControl.dispatchTouchEvent(event);
+ }
// Move over from one indicator to another.
if ((index != mPressedIndex) || (action == MotionEvent.ACTION_DOWN)) {
if (mPressedIndex != -1) {
@@ -255,21 +274,19 @@ public class IndicatorControlWheel extends IndicatorControl implements
if (getSelectedIndicatorIndex() != index) dismissSettingPopup();
}
if ((index != -1) && (action == MotionEvent.ACTION_MOVE)) {
- injectMotionEvent(index, event, MotionEvent.ACTION_DOWN);
+ if (mCurrentLevel != 0) {
+ injectMotionEvent(index, event, MotionEvent.ACTION_DOWN);
+ }
}
}
if ((index != -1) && (action != MotionEvent.ACTION_MOVE)) {
- View view = getChildAt(index);
- // Switch to zoom control only if a touch down event is received.
- if ((view == mZoomIcon) && (action == MotionEvent.ACTION_DOWN)
- && mZoomIcon.isEnabled()) {
- mPressedIndex = -1;
- mOnIndicatorEventListener.onIndicatorEvent(
- OnIndicatorEventListener.EVENT_ENTER_ZOOM_CONTROL);
- return true;
- } else {
- getChildAt(index).dispatchTouchEvent(event);
- }
+ getChildAt(index).dispatchTouchEvent(event);
+ }
+ // Do not highlight the CameraPicker or Settings icon if we
+ // touch from the zoom control to one of them.
+ if ((mCurrentLevel == 0) && (index != 0)
+ && (action == MotionEvent.ACTION_MOVE)) {
+ return true;
}
// Once the button is up, reset the press index.
mPressedIndex = (action == MotionEvent.ACTION_UP) ? -1 : index;
@@ -298,11 +315,17 @@ public class IndicatorControlWheel extends IndicatorControl implements
double increment = Math.toRadians(expectedAngle)
- mChildRadians[mSecondLevelStartIndex];
for (int i = 0 ; i < getChildCount(); ++i) mChildRadians[i] += increment;
- }
+ // We also need to rotate the zoom control wheel as well.
+ if (mZoomControl != null) {
+ mZoomControl.rotate(mChildRadians[0]
+ - Math.toRadians(MAX_ZOOM_CONTROL_DEGREES));
+ }
+ }
@Override
protected void onLayout(
boolean changed, int left, int top, int right, int bottom) {
+ if (!mInitialized) return;
if (mInAnimation) {
rotateWheel();
mHandler.post(mRunnable);
@@ -334,39 +357,31 @@ public class IndicatorControlWheel extends IndicatorControl implements
int y = mCenterY - (int)(mWheelRadius * Math.sin(radian));
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
- view.layout(x - width / 2, y - height / 2, x + width / 2,
- y + height / 2);
+ if (view == mZoomControl) {
+ // ZoomControlWheel matches the size of its parent view.
+ view.layout(0, 0, right - left, bottom - top);
+ } else {
+ view.layout(x - width / 2, y - height / 2, x + width / 2,
+ y + height / 2);
+ }
}
}
private void presetFirstLevelChildRadians() {
- int count = getChildCountByLevel(0);
- int sectors = (count <= 1) ? 0 : (count - 1);
- double sectorDegrees = FIRST_LEVEL_SECTOR_DEGREES;
- mSectorRadians[0] = Math.toRadians(sectorDegrees);
- int zoomIndex = indexOfChild(mZoomIcon);
- double degrees;
-
- // Make sure the zoom button is located at 180 degrees. If there are
- // more buttons than we could show in the visible angle from 90 degrees
- // to 270 degrees, the modification of FIRST_LEVEL_SECTOR_DEGREES is
- // required then.
- if (zoomIndex >= 0) {
- degrees = ZOOM_ICON_DEFAULT_DEGREES - (zoomIndex * sectorDegrees);
- } else {
- degrees = FIRST_LEVEL_END_DEGREES - (sectors * sectorDegrees);
- }
- mStartVisibleRadians[0] = Math.toRadians(degrees);
+ // Set the visible range in the first-level indicator wheel.
+ mStartVisibleRadians[0] = Math.toRadians(FIRST_LEVEL_START_DEGREES);
+ mTouchSectorRadians[0] = HIGHLIGHT_RADIANS;
+ mEndVisibleRadians[0] = Math.toRadians(FIRST_LEVEL_END_DEGREES);
+ // Set the angle of each component in the first-level indicator wheel.
int startIndex = 0;
- for (int i = 0; i < count; i++) {
- mChildRadians[startIndex + i] = Math.toRadians(degrees);
- degrees += sectorDegrees;
+ if (mZoomControl != null) {
+ mChildRadians[startIndex++] = Math.toRadians(MAX_ZOOM_CONTROL_DEGREES);
}
-
- // The radians for the touch sector of an indicator.
- mTouchSectorRadians[0] = HIGHLIGHT_RADIANS;
- mEndVisibleRadians[0] = Math.toRadians(FIRST_LEVEL_END_DEGREES);
+ if (mCameraPicker != null) {
+ mChildRadians[startIndex++] = Math.toRadians(FIRST_LEVEL_START_DEGREES);
+ }
+ mChildRadians[startIndex++] = Math.toRadians(FIRST_LEVEL_END_DEGREES);
}
private void presetSecondLevelChildRadians() {
@@ -425,7 +440,8 @@ public class IndicatorControlWheel extends IndicatorControl implements
int selectedIndex = getSelectedIndicatorIndex();
// Draw the highlight arc if an indicator is selected or being pressed.
- if (selectedIndex >= 0) {
+ // And skip the zoom control which index is zero.
+ if (selectedIndex >= 1) {
int degree = (int) Math.toDegrees(mChildRadians[selectedIndex]);
float innerR = (float) mShutterButtonRadius;
float outerR = (float) (mShutterButtonRadius + mStrokeWidth +
@@ -491,6 +507,7 @@ public class IndicatorControlWheel extends IndicatorControl implements
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
+ if (!mInitialized) return;
if (mCurrentMode == MODE_VIDEO) {
mSecondLevelIcon.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
mCloseIcon.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
@@ -504,7 +521,7 @@ public class IndicatorControlWheel extends IndicatorControl implements
}
public void enableZoom(boolean enabled) {
- if (mZoomIcon != null) mZoomIcon.setEnabled(enabled);
+ if (mZoomControl != null) mZoomControl.setEnabled(enabled);
}
public void onTouchOutBound() {
diff --git a/src/com/android/camera/ui/IndicatorControlWheelContainer.java b/src/com/android/camera/ui/IndicatorControlWheelContainer.java
index a10136b..ab52695 100644
--- a/src/com/android/camera/ui/IndicatorControlWheelContainer.java
+++ b/src/com/android/camera/ui/IndicatorControlWheelContainer.java
@@ -28,8 +28,8 @@ import android.view.View;
/**
* On the tablet UI, we have IndicatorControlWheelContainer which contains a
- * ShutterButton, a IndicatorControlWheel (which combines first-level and
- * second-level indicators) and a ZoomControlWheel.
+ * ShutterButton, an IndicatorControlWheel(which combines first-level and
+ * second-level indicators and a ZoomControlWheel).
*/
public class IndicatorControlWheelContainer extends IndicatorControlContainer {
public static final int STROKE_WIDTH = 87;
@@ -41,7 +41,6 @@ public class IndicatorControlWheelContainer extends IndicatorControlContainer {
private View mShutterButton;
private double mShutterButtonRadius;
private IndicatorControlWheel mIndicatorControlWheel;
- private ZoomControlWheel mZoomControlWheel;
private int mCenterX, mCenterY;
public IndicatorControlWheelContainer(Context context, AttributeSet attrs) {
@@ -53,9 +52,6 @@ public class IndicatorControlWheelContainer extends IndicatorControlContainer {
mShutterButton = findViewById(R.id.shutter_button);
mShutterButtonRadius = Util.dpToPixel(SHUTTER_BUTTON_RADIUS);
- mZoomControlWheel = (ZoomControlWheel) findViewById(R.id.zoom_control);
- mZoomControlWheel.setOnIndicatorEventListener(this);
-
mIndicatorControlWheel = (IndicatorControlWheel) findViewById(
R.id.indicator_control_wheel);
}
@@ -64,22 +60,9 @@ public class IndicatorControlWheelContainer extends IndicatorControlContainer {
boolean isZoomSupported, String[] keys, String[] otherSettingKeys) {
mIndicatorControlWheel.initialize(context, group, isZoomSupported,
keys, otherSettingKeys);
- mIndicatorControlWheel.setOnIndicatorEventListener(this);
}
public void onIndicatorEvent(int event) {
- switch (event) {
- case OnIndicatorEventListener.EVENT_ENTER_ZOOM_CONTROL:
- mIndicatorControlWheel.setVisibility(View.GONE);
- mZoomControlWheel.setVisibility(View.VISIBLE);
- mZoomControlWheel.startZoomControl();
- break;
-
- case OnIndicatorEventListener.EVENT_LEAVE_ZOOM_CONTROL:
- mZoomControlWheel.setVisibility(View.GONE);
- mIndicatorControlWheel.setVisibility(View.VISIBLE);
- break;
- }
}
@Override
@@ -96,8 +79,6 @@ public class IndicatorControlWheelContainer extends IndicatorControlContainer {
if (radius <= mShutterButtonRadius) {
if (mIndicatorControlWheel.getVisibility() == View.VISIBLE) {
mIndicatorControlWheel.onTouchOutBound();
- } else {
- return mZoomControlWheel.dispatchTouchEvent(event);
}
if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP) {
return mShutterButton.dispatchTouchEvent(event);
@@ -112,11 +93,7 @@ public class IndicatorControlWheelContainer extends IndicatorControlContainer {
return true;
}
- if (mIndicatorControlWheel.getVisibility() == View.VISIBLE) {
- return mIndicatorControlWheel.dispatchTouchEvent(event);
- } else {
- return mZoomControlWheel.dispatchTouchEvent(event);
- }
+ return mIndicatorControlWheel.dispatchTouchEvent(event);
}
@Override
@@ -134,7 +111,6 @@ public class IndicatorControlWheelContainer extends IndicatorControlContainer {
mCenterY + shutterButtonHeight - shutterButtonHeight / 2);
// Layout the control wheel.
mIndicatorControlWheel.layout(0, 0, right - left, bottom - top);
- mZoomControlWheel.layout(0, 0, right - left, bottom - top);
}
@Override
@@ -143,7 +119,6 @@ public class IndicatorControlWheelContainer extends IndicatorControlContainer {
int freeSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
mShutterButton.measure(freeSpec, freeSpec);
mIndicatorControlWheel.measure(freeSpec, freeSpec);
- mZoomControlWheel.measure(freeSpec, freeSpec);
// Measure myself. Add some buffer for highlight arc.
int desiredWidth = mShutterButton.getMeasuredWidth()
@@ -193,7 +168,6 @@ public class IndicatorControlWheelContainer extends IndicatorControlContainer {
@Override
public void setOrientation(int orientation) {
mIndicatorControlWheel.setOrientation(orientation);
- mZoomControlWheel.setOrientation(orientation);
}
public void startTimeLapseAnimation(int timeLapseInterval, long startTime) {
@@ -208,7 +182,6 @@ public class IndicatorControlWheelContainer extends IndicatorControlContainer {
@Override
public void setEnabled(boolean enabled) {
mIndicatorControlWheel.setEnabled(enabled);
- mZoomControlWheel.setEnabled(enabled);
}
@Override
diff --git a/src/com/android/camera/ui/OneRowGridView.java b/src/com/android/camera/ui/OneRowGridView.java
index 5e37d35..2545f1c 100644
--- a/src/com/android/camera/ui/OneRowGridView.java
+++ b/src/com/android/camera/ui/OneRowGridView.java
@@ -16,28 +16,32 @@
package com.android.camera.ui;
-import com.android.camera.R;
-import com.android.camera.Util;
-
import android.content.Context;
import android.util.AttributeSet;
import android.widget.GridView;
public class OneRowGridView extends GridView {
+ private int mInternalRequestedColumnWidth;
public OneRowGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
+ public void setColumnWidth(int columnWidth) {
+ super.setColumnWidth(columnWidth);
+ if (mInternalRequestedColumnWidth != columnWidth) {
+ mInternalRequestedColumnWidth = columnWidth;
+ requestLayout();
+ }
+ }
+
+ @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- // Once we know the number of children in this view, we have to set
- // the correct width and height for containing the icons in one row.
- int n = getChildCount();
- if (n == 0) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- } else {
- setMeasuredDimension((n * getChildAt(0).getMeasuredWidth()),
- getMeasuredHeight());
+ if (mInternalRequestedColumnWidth != 0) {
+ int n = (getAdapter() == null) ? 0 : getAdapter().getCount();
+ int size = mInternalRequestedColumnWidth * n;
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
}
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
diff --git a/src/com/android/camera/ui/RotateTextToast.java b/src/com/android/camera/ui/RotateTextToast.java
new file mode 100644
index 0000000..8ff381a
--- /dev/null
+++ b/src/com/android/camera/ui/RotateTextToast.java
@@ -0,0 +1,58 @@
+/*
+ * 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.R;
+import com.android.camera.Util;
+
+import android.app.Activity;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+public class RotateTextToast {
+ private static final int TOAST_DURATION = 5000; // milliseconds
+ ViewGroup mLayoutRoot;
+ RotateLayout mToast;
+ Handler mHandler;
+
+ public RotateTextToast(Activity activity, int textResourceId, int orientation) {
+ mLayoutRoot = (ViewGroup) activity.getWindow().getDecorView();
+ LayoutInflater inflater = activity.getLayoutInflater();
+ View v = inflater.inflate(R.layout.rotate_text_toast, mLayoutRoot);
+ mToast = (RotateLayout) v.findViewById(R.id.rotate_toast);
+ TextView tv = (TextView) mToast.findViewById(R.id.message);
+ tv.setText(textResourceId);
+ mToast.setOrientation(orientation);
+ mHandler = new Handler();
+ }
+
+ private final Runnable mRunnable = new Runnable() {
+ public void run() {
+ Util.fadeOut(mToast);
+ mLayoutRoot.removeView(mToast);
+ mToast = null;
+ }
+ };
+
+ public void show() {
+ mToast.setVisibility(View.VISIBLE);
+ mHandler.postDelayed(mRunnable, TOAST_DURATION);
+ }
+}
diff --git a/src/com/android/camera/ui/SecondLevelIndicatorControlBar.java b/src/com/android/camera/ui/SecondLevelIndicatorControlBar.java
index bc29d88..c1b9b2f 100644
--- a/src/com/android/camera/ui/SecondLevelIndicatorControlBar.java
+++ b/src/com/android/camera/ui/SecondLevelIndicatorControlBar.java
@@ -106,23 +106,31 @@ public class SecondLevelIndicatorControlBar extends IndicatorControl implements
if (x > width) x = width;
int index = getTouchViewIndex((int) x, width);
- View b = getChildAt(index);
- if (b == null) return true;
- dispatchRelativeTouchEvent(b, event);
+
+ // Cancel the previous target if we moved out of it
if ((mSelectedIndex != -1) && (index != mSelectedIndex)) {
- View v = getChildAt(mSelectedIndex);
- if (v instanceof AbstractIndicatorButton) {
- AbstractIndicatorButton c = (AbstractIndicatorButton) v;
- event.setAction(MotionEvent.ACTION_CANCEL);
- dispatchRelativeTouchEvent(c, event);
- c.dismissPopup();
- }
+ View p = getChildAt(mSelectedIndex);
+
+ int oldAction = event.getAction();
+ event.setAction(MotionEvent.ACTION_CANCEL);
+ dispatchRelativeTouchEvent(p, event);
+ event.setAction(oldAction);
- if (action == MotionEvent.ACTION_MOVE) {
- event.setAction(MotionEvent.ACTION_DOWN);
- dispatchRelativeTouchEvent(b, event);
+ if (p instanceof AbstractIndicatorButton) {
+ AbstractIndicatorButton b = (AbstractIndicatorButton) p;
+ b.dismissPopup();
}
}
+
+ // Send event to the target
+ View v = getChildAt(index);
+ if (v == null) return true;
+
+ // Change MOVE to DOWN if this is a new target
+ if (mSelectedIndex != index && action == MotionEvent.ACTION_MOVE) {
+ event.setAction(MotionEvent.ACTION_DOWN);
+ }
+ dispatchRelativeTouchEvent(v, event);
mSelectedIndex = index;
return true;
}
diff --git a/src/com/android/camera/ui/SharePopup.java b/src/com/android/camera/ui/SharePopup.java
index 134b7c0..43f3ae8 100644
--- a/src/com/android/camera/ui/SharePopup.java
+++ b/src/com/android/camera/ui/SharePopup.java
@@ -31,6 +31,7 @@ import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
@@ -38,10 +39,10 @@ import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.AdapterView;
-import android.widget.ImageView;
+import android.widget.FrameLayout;
import android.widget.GridView;
+import android.widget.ImageView;
import android.widget.PopupWindow;
-import android.widget.RelativeLayout;
import android.widget.SimpleAdapter;
import java.util.ArrayList;
@@ -61,17 +62,17 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
private int mBitmapWidth;
private int mBitmapHeight;
private int mOrientation;
- // A view that contains a thumbnail and an arrow icon.
- private ViewGroup mShareView;
+ private int mActivityOrientation;
// A view that contains a list of application icons and the share view.
private View mRootView;
// The list of the application icons.
private GridView mShareList;
- // A rotated view that contains the thumbnail.
+ // A rotated view that contains the thumbnail and the play icon.
private RotateLayout mThumbnailRotateLayout;
private RotateLayout mGotoGalleryRotate;
private View mPreviewFrame;
private ArrayList<ComponentName> mComponent = new ArrayList<ComponentName>();
+ private View mImageViewFrame;
private class MySimpleAdapter extends SimpleAdapter {
public MySimpleAdapter(Context context, List<? extends Map<String, ?>> data,
@@ -94,7 +95,7 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
public boolean setViewValue(final View view, final Object data,
final String text) {
if (view instanceof ImageView) {
- ((ImageView)view).setImageDrawable((Drawable) data);
+ ((ImageView) view).setImageDrawable((Drawable) data);
return true;
}
return false;
@@ -105,6 +106,8 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
View previewFrame) {
super(activity);
+ mActivityOrientation = activity.getRequestedOrientation();
+
// Initialize variables
mContext = activity;
mUri = uri;
@@ -114,14 +117,18 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
ViewGroup sharePopup = (ViewGroup) inflater.inflate(R.layout.share_popup, null, false);
// This is required because popup window is full screen.
sharePopup.setOnTouchListener(this);
- mThumbnailRotateLayout = (RotateLayout) sharePopup.findViewById(R.id.thumbnail_rotate_layout);
+ mThumbnailRotateLayout =
+ (RotateLayout) sharePopup.findViewById(R.id.thumbnail_rotate_layout);
mShareList = (GridView) sharePopup.findViewById(R.id.share_list);
mThumbnail = (ImageView) sharePopup.findViewById(R.id.thumbnail);
mThumbnail.setImageBitmap(bitmap);
- mShareView = (ViewGroup) sharePopup.findViewById(R.id.share_view);
- mShareView.setOnClickListener(this);
+ mImageViewFrame =
+ (View) sharePopup.findViewById(R.id.thumbnail_image_frame);
+ mImageViewFrame.setOnClickListener(this);
- mGotoGalleryRotate =(RotateLayout) sharePopup.findViewById(R.id.goto_gallery_button_rotate);
+
+ mGotoGalleryRotate =
+ (RotateLayout) sharePopup.findViewById(R.id.goto_gallery_button_rotate);
sharePopup.findViewById(R.id.goto_gallery_button).setOnClickListener(this);
mBitmapWidth = bitmap.getWidth();
@@ -157,31 +164,27 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
}
private void adjustThumbnailPosition() {
- RelativeLayout.LayoutParams lpOld =
- (RelativeLayout.LayoutParams) mThumbnailRotateLayout.getLayoutParams();
- RelativeLayout.LayoutParams lpNew =
- new RelativeLayout.LayoutParams(lpOld.width, lpOld.height);
+ FrameLayout.LayoutParams lpOld =
+ (FrameLayout.LayoutParams) mThumbnailRotateLayout.getLayoutParams();
+ FrameLayout.LayoutParams lpNew =
+ new FrameLayout.LayoutParams(lpOld.width, lpOld.height);
mRootView.setBackgroundDrawable(null);
if (mBitmapWidth > mBitmapHeight * 2 || mBitmapHeight > mBitmapWidth * 2) {
// panorama image
- lpNew.addRule(RelativeLayout.CENTER_HORIZONTAL);
- lpNew.addRule(RelativeLayout.CENTER_VERTICAL);
+ lpNew.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
// panorama images block the preview from showing in the background
// use a special color here for that.
mRootView.setBackgroundColor(
mContext.getResources().getColor(R.color.share_popup_blackout));
- } else if (mBitmapWidth > mBitmapHeight) {
- // landscape image
- lpNew.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
- lpNew.addRule(RelativeLayout.ALIGN_PARENT_TOP);
- lpNew.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
} else {
- // portrait image
- lpNew.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
- lpNew.addRule(RelativeLayout.ALIGN_PARENT_TOP);
- lpNew.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
+ // landscape or portrait image
+ if (mActivityOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
+ lpNew.gravity = Gravity.BOTTOM;
+ } else {
+ lpNew.gravity = Gravity.RIGHT;
+ }
}
mThumbnailRotateLayout.setLayoutParams(lpNew);
@@ -192,13 +195,11 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
int hPaddingRootView = mRootView.getPaddingLeft() + mRootView.getPaddingRight();
int vPaddingRootView = mRootView.getPaddingTop() + mRootView.getPaddingBottom();
- int hPadding = mShareView.getPaddingLeft() + mShareView.getPaddingRight();
- int vPadding = mShareView.getPaddingTop() + mShareView.getPaddingBottom();
// Calculate the width and the height of the thumbnail. Reserve the
// space for paddings.
- float maxWidth = mPreviewFrame.getWidth() - hPadding - hPaddingRootView;
- float maxHeight = mPreviewFrame.getHeight() - vPadding - vPaddingRootView;
+ float maxWidth = mPreviewFrame.getWidth() - hPaddingRootView;
+ float maxHeight = mPreviewFrame.getHeight() - vPaddingRootView;
// Swap the width and height if it is portrait mode.
if (orientation == 90 || orientation == 270) {
float temp = maxWidth;
@@ -209,10 +210,10 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
float desiredAspect = (float) mBitmapWidth / mBitmapHeight;
if (mMimeType.startsWith("video/")) {
- desiredAspect = 4F/3F;
+ desiredAspect = 4F / 3F;
mThumbnail.setScaleType(ImageView.ScaleType.CENTER_CROP);
} else {
- mThumbnail.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+ mThumbnail.setScaleType(ImageView.ScaleType.FIT_CENTER);
}
LayoutParams params = mThumbnail.getLayoutParams();
@@ -250,7 +251,7 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
public void onClick(View v) {
switch (v.getId()) {
case R.id.goto_gallery_button:
- case R.id.share_view:
+ case R.id.thumbnail_image_frame:
Util.viewUri(mUri, mContext);
break;
}
@@ -271,7 +272,7 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
new Intent(Intent.ACTION_SEND).setType(mMimeType), 0);
ArrayList<HashMap<String, Object>> items = new ArrayList<HashMap<String, Object>>();
- for (ResolveInfo info: infos) {
+ for (ResolveInfo info : infos) {
ComponentName component = new ComponentName(
info.activityInfo.packageName, info.activityInfo.name);
HashMap<String, Object> map = new HashMap<String, Object>();
@@ -282,9 +283,10 @@ public class SharePopup extends PopupWindow implements View.OnClickListener,
// On phone UI, we have to know how many icons in the grid view before
// the view is measured.
- if (((Activity) mContext).getRequestedOrientation()
- == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
+ if (mActivityOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
mShareList.setNumColumns(items.size());
+ int width = mContext.getResources().getDimensionPixelSize(R.dimen.share_item_width);
+ mShareList.setColumnWidth(width);
}
SimpleAdapter listItemAdapter = new MySimpleAdapter(mContext, items,
diff --git a/src/com/android/camera/ui/StackLayout.java b/src/com/android/camera/ui/StackLayout.java
new file mode 100644
index 0000000..ab08d2f
--- /dev/null
+++ b/src/com/android/camera/ui/StackLayout.java
@@ -0,0 +1,59 @@
+/*
+ * 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 android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+
+// A layout designed to make the children same size as the first child.
+public class StackLayout extends ViewGroup {
+ private static final String TAG = "StackLayout";
+
+ public StackLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ final int count = getChildCount();
+
+ // Measure only the first child.
+ final View child = getChildAt(0);
+ measureChild(child, widthMeasureSpec, heightMeasureSpec);
+
+ // Ignore the paddings.
+ int width = child.getMeasuredWidth();
+ int height = child.getMeasuredHeight();
+
+ setMeasuredDimension(resolveSize(width, widthMeasureSpec),
+ resolveSize(height, heightMeasureSpec));
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ final int count = super.getChildCount();
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() != View.GONE) {
+ child.layout(0, 0, r - l, b - t);
+ }
+ }
+ }
+}
diff --git a/src/com/android/camera/ui/ZoomControl.java b/src/com/android/camera/ui/ZoomControl.java
index f2971cd..594662f 100644
--- a/src/com/android/camera/ui/ZoomControl.java
+++ b/src/com/android/camera/ui/ZoomControl.java
@@ -41,7 +41,6 @@ public abstract class ZoomControl extends RelativeLayout implements Rotatable {
protected ImageView mZoomIn;
protected ImageView mZoomOut;
protected ImageView mZoomSlider;
- protected int mSliderPosition = 0;
protected int mOrientation;
private Handler mHandler;
diff --git a/src/com/android/camera/ui/ZoomControlBar.java b/src/com/android/camera/ui/ZoomControlBar.java
index 4e572cf..3d5d2e9 100644
--- a/src/com/android/camera/ui/ZoomControlBar.java
+++ b/src/com/android/camera/ui/ZoomControlBar.java
@@ -35,6 +35,7 @@ public class ZoomControlBar extends ZoomControl {
private View mBar;
private boolean mStartChanging;
+ private int mSliderPosition = 0;
private int mSliderLength;
private int mWidth;
private int mIconWidth;
diff --git a/src/com/android/camera/ui/ZoomControlWheel.java b/src/com/android/camera/ui/ZoomControlWheel.java
index 6a75097..9114fe8 100644
--- a/src/com/android/camera/ui/ZoomControlWheel.java
+++ b/src/com/android/camera/ui/ZoomControlWheel.java
@@ -29,23 +29,27 @@ import android.view.MotionEvent;
import android.view.View;
/**
- * A view that contains camera zoom control and its layout.
+ * A view that contains camera zoom control and its layout. In addition to the
+ * zoom control, the method {@link #rotate} is added for rotation animation
+ * which is called in switching between first-level and second-level indicators.
*/
public class ZoomControlWheel extends ZoomControl {
private static final String TAG = "ZoomControlWheel";
private static final int HIGHLIGHT_WIDTH = 4;
private static final int HIGHLIGHT_DEGREES = 30;
private static final int TRAIL_WIDTH = 2;
- private static final int ZOOM_IN_ICON_DEGREES = 60;
- private static final int ZOOM_OUT_ICON_DEGREES = 300;
- private static final int DEFAULT_SLIDER_POSITION = 180;
+ private static final int ZOOM_IN_ICON_DEGREES = 96;
+ private static final int ZOOM_OUT_ICON_DEGREES = 264;
private static final int MAX_SLIDER_ANGLE =
ZOOM_OUT_ICON_DEGREES - (HIGHLIGHT_DEGREES / 2);
private static final int MIN_SLIDER_ANGLE =
ZOOM_IN_ICON_DEGREES + (HIGHLIGHT_DEGREES / 2);
+ private static final int DEFAULT_SLIDER_POSITION = MAX_SLIDER_ANGLE;
private static final float EDGE_STROKE_WIDTH = 6f;
private static final double BUFFER_RADIANS = Math.toRadians(HIGHLIGHT_DEGREES / 2);
- private double mSliderRadians = Math.toRadians(DEFAULT_SLIDER_POSITION);
+ private static final double SLIDER_RANGE =
+ Math.toRadians(MAX_SLIDER_ANGLE - MIN_SLIDER_ANGLE);
+ private double mSliderRadians = DEFAULT_SLIDER_POSITION;
private final int HIGHLIGHT_COLOR;
private final int TRAIL_COLOR;
@@ -59,6 +63,8 @@ public class ZoomControlWheel extends ZoomControl {
private Paint mBackgroundPaint;
private RectF mBackgroundRect;
+ private double mRotateAngle;
+
public ZoomControlWheel(Context context, AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(false);
@@ -75,35 +81,21 @@ public class ZoomControlWheel extends ZoomControl {
mShutterButtonRadius = IndicatorControlWheelContainer.SHUTTER_BUTTON_RADIUS;
mStrokeWidth = Util.dpToPixel(IndicatorControlWheelContainer.STROKE_WIDTH);
mWheelRadius = mShutterButtonRadius + mStrokeWidth * 0.5;
- super.setZoomStep(1); // one zoom level at a time
- }
-
- private void performZoom() {
- if (mSliderRadians > (Math.PI + BUFFER_RADIANS)) {
- super.performZoom(ZOOM_OUT);
- } else if (mSliderRadians < (Math.PI - BUFFER_RADIANS)) {
- super.performZoom(ZOOM_IN);
- } else {
- super.performZoom(ZOOM_STOP);
- }
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
- if (!onFilterTouchEventForSecurity(event)) return false;
+ if (!onFilterTouchEventForSecurity(event) || !isEnabled()) return false;
int action = event.getAction();
double dx = event.getX() - mCenterX;
double dy = mCenterY - event.getY();
double radius = Math.sqrt(dx * dx + dy * dy);
// Ignore the event if too far from the shutter button.
- mSliderRadians = Math.atan2(dy, dx);
- if (mSliderRadians < 0) mSliderRadians += Math.PI * 2;
- if (mSliderRadians > (Math.PI + BUFFER_RADIANS)) {
- mSliderPosition = 1;
- } else {
- mSliderPosition = (mSliderRadians < (Math.PI - BUFFER_RADIANS)) ? -1 : 0;
- }
+ double angle = Math.atan2(dy, dx);
+ if (angle < 0) angle += (2 * Math.PI);
+ mSliderRadians = getSliderDrawAngle(angle);
+
// We assume the slider button is pressed all the time when the
// zoom control is active. So we take care of the following events
// only.
@@ -114,7 +106,8 @@ public class ZoomControlWheel extends ZoomControl {
closeZoomControl();
break;
case MotionEvent.ACTION_MOVE:
- performZoom();
+ performZoom((Math.toRadians(MAX_SLIDER_ANGLE)
+ - mSliderRadians) / SLIDER_RANGE);
requestLayout();
}
return true;
@@ -127,6 +120,9 @@ public class ZoomControlWheel extends ZoomControl {
}
private void layoutIcon(View view, double radian) {
+ // Rotate the wheel with the angle when the wheel is rotating or
+ // the indicator control is in the second-level.
+ radian += mRotateAngle;
int x = mCenterX + (int)(mWheelRadius * Math.cos(radian));
int y = mCenterY - (int)(mWheelRadius * Math.sin(radian));
int width = view.getMeasuredWidth();
@@ -135,8 +131,7 @@ public class ZoomControlWheel extends ZoomControl {
y + height / 2);
}
- private double getSliderDrawAngle() {
- double sliderAngle = mSliderRadians;
+ private double getSliderDrawAngle(double sliderAngle) {
if (sliderAngle > Math.toRadians(MAX_SLIDER_ANGLE)) {
return Math.toRadians(MAX_SLIDER_ANGLE);
} else if (sliderAngle < Math.toRadians(MIN_SLIDER_ANGLE)) {
@@ -153,7 +148,7 @@ public class ZoomControlWheel extends ZoomControl {
mCenterY = (bottom - top) / 2;
layoutIcon(mZoomIn, Math.toRadians(ZOOM_IN_ICON_DEGREES));
layoutIcon(mZoomOut, Math.toRadians(ZOOM_OUT_ICON_DEGREES));
- layoutIcon(mZoomSlider, getSliderDrawAngle());
+ layoutIcon(mZoomSlider, getSliderDrawAngle(mSliderRadians));
}
private double getZoomIndexAngle() {
@@ -174,14 +169,17 @@ public class ZoomControlWheel extends ZoomControl {
@Override
protected void onDraw(Canvas canvas) {
- // Draw zoom index highlight.
- float radius = (float) (mWheelRadius + mStrokeWidth * 0.5 + EDGE_STROKE_WIDTH);
- int degree = (int) Math.toDegrees(getZoomIndexAngle());
- drawArc(canvas, (-degree - HIGHLIGHT_DEGREES / 2), HIGHLIGHT_DEGREES,
- radius, HIGHLIGHT_COLOR, HIGHLIGHT_WIDTH);
// Draw the slider trail.
- drawArc(canvas, -MAX_SLIDER_ANGLE, (MAX_SLIDER_ANGLE - MIN_SLIDER_ANGLE),
+ int startAngle = -MAX_SLIDER_ANGLE - (int) Math.toDegrees(mRotateAngle);
+ int radians = (MAX_SLIDER_ANGLE - MIN_SLIDER_ANGLE);
+ if ((startAngle + radians) > 0) radians = -startAngle;
+ drawArc(canvas, startAngle, radians,
mWheelRadius, TRAIL_COLOR, TRAIL_WIDTH);
super.onDraw(canvas);
}
+
+ public void rotate(double angle) {
+ mRotateAngle = angle;
+ requestLayout();
+ }
}