blob: 06e0af5d4b4939dc5b52305b2d585901e3a699d4 [file] [log] [blame]
Chih-Chung Chang91acfc92009-07-06 15:37:24 +08001/*
2 * Copyright (C) 2009 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
Owen Lindad4b182009-06-11 16:02:29 -070017package com.android.camera;
18
19import android.content.Context;
20import android.graphics.Canvas;
21import android.graphics.drawable.Drawable;
22import android.util.AttributeSet;
Chih-Chung Changd918cfa2009-07-13 13:11:52 +080023import android.util.Log;
Owen Line239acc2009-06-23 22:18:20 -070024import android.view.MotionEvent;
25import android.view.animation.AnimationUtils;
Owen Lindad4b182009-06-11 16:02:29 -070026import android.widget.ImageView;
27
Owen Lindad4b182009-06-11 16:02:29 -070028public class Switcher extends ImageView {
Chih-Chung Changd918cfa2009-07-13 13:11:52 +080029 private static final String TAG = "Switcher";
30
Owen Line239acc2009-06-23 22:18:20 -070031 public interface OnSwitchListener {
Chih-Chung Changd918cfa2009-07-13 13:11:52 +080032 // Returns true if the listener agrees that the switch can be changed.
33 public boolean onSwitchChanged(Switcher source, boolean onOff);
Owen Line239acc2009-06-23 22:18:20 -070034 }
35
36 private static final int ANIMATION_SPEED = 200;
37 private static final long NO_ANIMATION = -1;
Owen Lindad4b182009-06-11 16:02:29 -070038
39 private boolean mSwitch = false;
Owen Line239acc2009-06-23 22:18:20 -070040 private int mPosition = 0;
41 private long mAnimationStartTime = 0;
42 private OnSwitchListener mListener;
Owen Lindad4b182009-06-11 16:02:29 -070043
44 public Switcher(Context context, AttributeSet attrs) {
45 super(context, attrs);
46 }
47
48 public void setSwitch(boolean onOff) {
Chih-Chung Changd918cfa2009-07-13 13:11:52 +080049 try {
50 if (mSwitch == onOff) return;
51
52 if (mListener != null) {
53 if (!mListener.onSwitchChanged(this, onOff)) {
54 return;
55 }
56 }
57
58 mSwitch = onOff;
59 } finally {
60 startParkingAnimation();
61 }
Owen Line239acc2009-06-23 22:18:20 -070062 }
63
64 public void setOnSwitchListener(OnSwitchListener listener) {
65 mListener = listener;
66 }
67
68 @Override
69 public boolean onTouchEvent(MotionEvent event) {
70 if (!isEnabled()) return false;
71
72 final int available = getHeight() - mPaddingTop - mPaddingBottom
73 - getDrawable().getIntrinsicHeight();
74
75 switch (event.getAction()) {
76 case MotionEvent.ACTION_DOWN:
77 mAnimationStartTime = NO_ANIMATION;
78 setPressed(true);
79 trackTouchEvent(event);
80 break;
81
82 case MotionEvent.ACTION_MOVE:
83 trackTouchEvent(event);
84 break;
85
86 case MotionEvent.ACTION_UP:
87 trackTouchEvent(event);
88 setSwitch(mPosition >= available / 2);
Owen Line239acc2009-06-23 22:18:20 -070089 setPressed(false);
90 break;
91
92 case MotionEvent.ACTION_CANCEL:
Chih-Chung Changd918cfa2009-07-13 13:11:52 +080093 setSwitch(mSwitch);
Owen Line239acc2009-06-23 22:18:20 -070094 setPressed(false);
Owen Line239acc2009-06-23 22:18:20 -070095 break;
96 }
97 return true;
98 }
99
100 private void startParkingAnimation() {
101 int drawableHeight = getDrawable().getIntrinsicHeight();
102 int target = mSwitch
103 ? getHeight() - drawableHeight - mPaddingBottom
104 : mPaddingTop;
105 mAnimationStartTime = AnimationUtils.currentAnimationTimeMillis();
106 }
107
108 private void trackTouchEvent(MotionEvent event) {
109 Drawable drawable = getDrawable();
110 int drawableHeight = drawable.getIntrinsicHeight();
111 final int height = getHeight();
112 final int available = height - mPaddingTop - mPaddingBottom
113 - drawableHeight;
114 int x = (int) event.getY();
115 mPosition = x - mPaddingTop - drawableHeight / 2;
116 if (mPosition < 0) mPosition = 0;
117 if (mPosition > available) mPosition = available;
118 invalidate();
Owen Lindad4b182009-06-11 16:02:29 -0700119 }
120
121 @Override
122 protected void onDraw(Canvas canvas) {
123
124 Drawable drawable = getDrawable();
125 int drawableHeight = drawable.getIntrinsicHeight();
126 int drawableWidth = drawable.getIntrinsicWidth();
127
128 if (drawable == null) {
129 return; // couldn't resolve the URI
130 }
131
132 if (drawableWidth == 0 || drawableHeight == 0) {
133 return; // nothing to draw (empty bounds)
134 }
135
Owen Line239acc2009-06-23 22:18:20 -0700136 if (mAnimationStartTime != NO_ANIMATION) {
137 final int available = getHeight() - mPaddingTop - mPaddingBottom
138 - drawableHeight;
139 long time = AnimationUtils.currentAnimationTimeMillis();
140 long deltaTime = time - mAnimationStartTime;
141 mPosition += ANIMATION_SPEED
142 * (mSwitch ? deltaTime : -deltaTime) / 1000;
143 mAnimationStartTime = time;
144 if (mPosition < 0) mPosition = 0;
145 if (mPosition > available) mPosition = available;
146 if (mPosition != 0 && mPosition != available) {
147 postInvalidate();
148 } else {
149 mAnimationStartTime = NO_ANIMATION;
150 }
151 }
152
153 int offsetTop = mPaddingTop + mPosition;
Owen Lindad4b182009-06-11 16:02:29 -0700154 int offsetLeft = (getWidth()
155 - drawableWidth - mPaddingLeft - mPaddingRight) / 2;
156 int saveCount = canvas.getSaveCount();
157 canvas.save();
158 canvas.translate(offsetLeft, offsetTop);
159 drawable.draw(canvas);
160 canvas.restoreToCount(saveCount);
161 }
162
163}