ZoomControl.java revision d2202f9677fcc5f3f2b3e950c35aefe80da14a8a
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.camera.ui;
18
19import com.android.camera.R;
20
21import android.content.Context;
22import android.os.Handler;
23import android.util.AttributeSet;
24import android.view.View;
25import android.widget.ImageView;
26import android.widget.RelativeLayout;
27
28/**
29 * A view that contains camera zoom control which could adjust the zoom in/out
30 * if the camera supports zooming.
31 */
32public abstract class ZoomControl extends RelativeLayout {
33    private static final String TAG = "ZoomControl";
34
35    public static final int ZOOMING_INTERVAL = 300; // milliseconds
36
37    protected ImageView mZoomIn;
38    protected ImageView mZoomOut;
39    protected ImageView mZoomSlider;
40    protected int mSliderPosition = 0;
41    protected int mDegree;
42    protected Handler mHandler;
43
44    public interface OnZoomChangedListener {
45        void onZoomValueChanged(int index);  // only for immediate zoom
46        void onZoomStateChanged(int state);  // only for smooth zoom
47    }
48
49    // The interface OnZoomIndexChangedListener is used to inform the
50    // ZoomIndexBar about the zoom index change. The index position is between
51    // 0 (the index is zero) and 1.0 (the index is mZoomMax).
52    public interface OnZoomIndexChangedListener {
53        void onZoomIndexChanged(double indexPosition);
54    }
55
56    protected int mZoomMax, mZoomIndex;
57    private boolean mSmoothZoomSupported;
58    private OnZoomChangedListener mListener;
59    private OnZoomIndexChangedListener mIndexListener;
60
61    // The state of zoom button.
62    public static final int ZOOM_IN = 0;
63    public static final int ZOOM_OUT = 1;
64    public static final int ZOOM_STOP = 2;
65
66    protected OnIndicatorEventListener mOnIndicatorEventListener;
67
68    protected final Runnable mRunnable = new Runnable() {
69        public void run() {
70            if (mSliderPosition < 0) {
71                zoomIn();
72            } else if (mSliderPosition > 0) {
73                zoomOut();
74            } else {
75                stopZooming();
76            }
77            mHandler.postDelayed(mRunnable, ZOOMING_INTERVAL);
78        }
79    };
80
81    public ZoomControl(Context context, AttributeSet attrs) {
82        super(context, attrs);
83    }
84
85    public void initialize(Context context) {
86        mZoomIn = addImageView(context, R.drawable.ic_zoom_in_holo_light);
87        mZoomSlider = addImageView(context, R.drawable.btn_zoom_slider);
88        mZoomOut = addImageView(context, R.drawable.ic_zoom_out_holo_light);
89        mHandler = new Handler();
90    }
91
92    public void startZoomControl() {
93        mZoomSlider.setPressed(true);
94        mHandler.postDelayed(mRunnable, ZOOMING_INTERVAL);
95        setZoomIndex(mZoomIndex); // Update the zoom index bar.
96    }
97
98    protected ImageView addImageView(Context context, int iconResourceId) {
99        ImageView image = new RotateImageView(context);
100        image.setImageResource(iconResourceId);
101        addView(image);
102        return image;
103    }
104
105    public void closeZoomControl() {
106        mHandler.removeCallbacks(mRunnable);
107        mSliderPosition = 0;
108        mZoomSlider.setPressed(false);
109        stopZooming();
110        mOnIndicatorEventListener.onIndicatorEvent(
111                OnIndicatorEventListener.EVENT_LEAVE_ZOOM_CONTROL);
112    }
113
114    public void setZoomMax(int zoomMax) {
115        mZoomMax = zoomMax;
116    }
117
118    public void setOnZoomChangeListener(OnZoomChangedListener listener) {
119        mListener = listener;
120    }
121
122    public void setOnZoomIndexChangeListener(OnZoomIndexChangedListener listener) {
123        mIndexListener = listener;
124    }
125
126    public void setOnIndicatorEventListener(OnIndicatorEventListener listener) {
127        mOnIndicatorEventListener = listener;
128    }
129
130    public void setZoomIndex(int index) {
131        if (index < 0 || index > mZoomMax) {
132            throw new IllegalArgumentException("Invalid zoom value:" + index);
133        }
134        mZoomIndex = index;
135        if (mIndexListener != null) {
136            mIndexListener.onZoomIndexChanged(1.0d * mZoomIndex / mZoomMax);
137        }
138        invalidate();
139    }
140
141    public void setSmoothZoomSupported(boolean smoothZoomSupported) {
142        mSmoothZoomSupported = smoothZoomSupported;
143    }
144
145    public boolean zoomIn() {
146        return (mZoomIndex == mZoomMax) ? false : changeZoomIndex(mZoomIndex + 1);
147    }
148
149    public boolean zoomOut() {
150        return (mZoomIndex == 0) ? false : changeZoomIndex(mZoomIndex - 1);
151    }
152
153    public void stopZooming() {
154        if (mSmoothZoomSupported) {
155            if (mListener != null) mListener.onZoomStateChanged(ZOOM_STOP);
156        }
157    }
158
159    private boolean changeZoomIndex(int index) {
160        int zoomType = (index < mZoomIndex) ? ZOOM_OUT : ZOOM_IN;
161        if (mListener != null) {
162            if (mSmoothZoomSupported) {
163                if (((zoomType == ZOOM_IN) && (mZoomIndex != mZoomMax)) ||
164                        ((zoomType == ZOOM_OUT) && (mZoomIndex != 0))) {
165                    mListener.onZoomStateChanged(zoomType);
166                }
167            } else {
168                mListener.onZoomStateChanged(index);
169                setZoomIndex(index);
170            }
171        }
172        return true;
173    }
174
175    public void setDegree(int degree) {
176        mDegree = degree;
177        int count = getChildCount();
178        for (int i = 0 ; i < count ; ++i) {
179            View view = getChildAt(i);
180            if (view instanceof RotateImageView) {
181                ((RotateImageView) view).setDegree(degree);
182            }
183        }
184    }
185}
186