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;
20import com.android.camera.Util;
21
22import android.content.Context;
23import android.util.AttributeSet;
24import android.view.MotionEvent;
25import android.view.View;
26
27/**
28 * A view that contains camera zoom control and its layout.
29 */
30public class ZoomControlBar extends ZoomControl {
31    private static final String TAG = "ZoomControlBar";
32    private static final int THRESHOLD_FIRST_MOVE = Util.dpToPixel(10); // pixels
33    // Space between indicator icon and the zoom-in/out icon.
34    private static final int ICON_SPACING = Util.dpToPixel(12);
35
36    private View mBar;
37    private boolean mStartChanging;
38    private int mSliderPosition = 0;
39    private int mSliderLength;
40    private int mWidth;
41    private int mIconWidth;
42    private int mTotalIconWidth;
43
44    public ZoomControlBar(Context context, AttributeSet attrs) {
45        super(context, attrs);
46        mBar = new View(context);
47        mBar.setBackgroundResource(R.drawable.zoom_slider_bar);
48        addView(mBar);
49    }
50
51    @Override
52    public void setActivated(boolean activated) {
53        super.setActivated(activated);
54        mBar.setActivated(activated);
55    }
56
57    private int getSliderPosition(int x) {
58        // Calculate the absolute offset of the slider in the zoom control bar.
59        // For left-hand users, as the device is rotated for 180 degree for
60        // landscape mode, the zoom-in bottom should be on the top, so the
61        // position should be reversed.
62        int pos; // the relative position in the zoom slider bar
63        if (mOrientation == 90) {
64            pos = mWidth - mTotalIconWidth - x;
65        } else {
66            pos = x - mTotalIconWidth;
67        }
68        if (pos < 0) pos = 0;
69        if (pos > mSliderLength) pos = mSliderLength;
70        return pos;
71    }
72
73    @Override
74    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
75        mWidth = w;
76        mIconWidth = mZoomIn.getMeasuredWidth();
77        mTotalIconWidth = mIconWidth + ICON_SPACING;
78        mSliderLength = mWidth  - (2 * mTotalIconWidth);
79    }
80
81    @Override
82    public boolean dispatchTouchEvent(MotionEvent event) {
83        if (!isEnabled() || (mWidth == 0)) return false;
84        int action = event.getAction();
85
86        switch (action) {
87            case MotionEvent.ACTION_OUTSIDE:
88            case MotionEvent.ACTION_CANCEL:
89            case MotionEvent.ACTION_UP:
90                setActivated(false);
91                closeZoomControl();
92                break;
93
94            case MotionEvent.ACTION_DOWN:
95                setActivated(true);
96                mStartChanging = false;
97            case MotionEvent.ACTION_MOVE:
98                int pos = getSliderPosition((int) event.getX());
99                if (!mStartChanging) {
100                    // Make sure the movement is large enough before we start
101                    // changing the zoom.
102                    int delta = mSliderPosition - pos;
103                    if ((delta > THRESHOLD_FIRST_MOVE) ||
104                            (delta < -THRESHOLD_FIRST_MOVE)) {
105                        mStartChanging = true;
106                    }
107                }
108                if (mStartChanging) {
109                    performZoom(1.0d * pos / mSliderLength);
110                    mSliderPosition = pos;
111                }
112                requestLayout();
113        }
114        return true;
115    }
116
117    @Override
118    public void setOrientation(int orientation) {
119        // layout for the left-hand camera control
120        if ((orientation == 90) || (mOrientation == 90)) requestLayout();
121        super.setOrientation(orientation);
122    }
123
124    @Override
125    protected void onLayout(
126            boolean changed, int left, int top, int right, int bottom) {
127        if (mZoomMax == 0) return;
128        int height = bottom - top;
129        mBar.layout(mTotalIconWidth, 0, mWidth - mTotalIconWidth, height);
130        // For left-hand users, as the device is rotated for 180 degree,
131        // the zoom-in button should be on the top.
132        int pos; // slider position
133        int sliderPosition;
134        if (mSliderPosition != -1) { // -1 means invalid
135            sliderPosition = mSliderPosition;
136        } else {
137            sliderPosition = (int) ((double) mSliderLength * mZoomIndex / mZoomMax);
138        }
139        if (mOrientation == 90) {
140            mZoomIn.layout(0, 0, mIconWidth, height);
141            mZoomOut.layout(mWidth - mIconWidth, 0, mWidth, height);
142            pos = mBar.getRight() - sliderPosition;
143        } else {
144            mZoomOut.layout(0, 0, mIconWidth, height);
145            mZoomIn.layout(mWidth - mIconWidth, 0, mWidth, height);
146            pos = mBar.getLeft() + sliderPosition;
147        }
148        int sliderWidth = mZoomSlider.getMeasuredWidth();
149        mZoomSlider.layout((pos - sliderWidth / 2), 0,
150                (pos + sliderWidth / 2), height);
151    }
152
153    @Override
154    public void setZoomIndex(int index) {
155        super.setZoomIndex(index);
156        mSliderPosition = -1; // -1 means invalid
157        requestLayout();
158    }
159}
160