OSDN Git Service

Update capture animation
[android-x86/packages-apps-Gallery2.git] / src / com / android / camera / ui / CameraControls.java
1 /*
2  * Copyright (C) 2013 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
17 package com.android.camera.ui;
18
19 import android.app.Activity;
20 import android.content.Context;
21 import android.content.res.Configuration;
22 import android.graphics.Rect;
23 import android.util.AttributeSet;
24 import android.view.Gravity;
25 import android.view.View;
26 import android.widget.FrameLayout;
27
28 import com.android.camera.Util;
29 import com.android.gallery3d.R;
30
31 public class CameraControls extends RotatableLayout {
32
33     private static final String TAG = "CAM_Controls";
34
35     private View mBackgroundView;
36     private View mShutter;
37     private View mSwitcher;
38     private View mMenu;
39     private View mIndicators;
40     private View mPreview;
41
42     public CameraControls(Context context, AttributeSet attrs) {
43         super(context, attrs);
44     }
45
46     public CameraControls(Context context) {
47         super(context);
48     }
49
50     @Override
51     public void onConfigurationChanged(Configuration config) {
52         super.onConfigurationChanged(config);
53         adjustBackground();
54     }
55
56     @Override
57     public void onFinishInflate() {
58         super.onFinishInflate();
59         mBackgroundView = findViewById(R.id.blocker);
60         mSwitcher = findViewById(R.id.camera_switcher);
61         mShutter = findViewById(R.id.shutter_button);
62         mMenu = findViewById(R.id.menu);
63         mIndicators = findViewById(R.id.on_screen_indicators);
64         mPreview = findViewById(R.id.preview_thumb);
65     }
66
67     @Override
68     public void onLayout(boolean changed, int l, int t, int r, int b) {
69         int orientation = getResources().getConfiguration().orientation;
70         int rotation = Util.getDisplayRotation((Activity) getContext());
71         rotation = correctRotation(rotation, orientation);
72         super.onLayout(changed, l, t, r, b);
73         Rect shutter = new Rect();
74         center(mShutter, l, t, r, b, orientation, rotation, shutter);
75         center(mBackgroundView, l, t, r, b, orientation, rotation, new Rect());
76         toLeft(mSwitcher, l, t, r, b, orientation, rotation, shutter);
77         toRight(mMenu, l, t, r, b, orientation, rotation, shutter);
78         toRight(mIndicators, l, t, r, b, orientation, rotation, shutter);
79         topRight(mPreview, l, t, r, b, orientation, rotation);
80         View retake = findViewById(R.id.btn_retake);
81         if (retake != null) {
82             Rect retakeRect = new Rect();
83             center(retake, l, t, r, b, orientation, rotation, retakeRect);
84             View cancel = findViewById(R.id.btn_cancel);
85             toLeft(cancel, l, t, r, b, orientation, rotation, shutter);
86             View done = findViewById(R.id.btn_done);
87             toRight(done, l, t, r, b, orientation, rotation, shutter);
88         }
89     }
90
91     private int correctRotation(int rotation, int orientation) {
92         // all the layout code assumes camera device orientation to be portrait
93         // adjust rotation for landscape
94         int camOrientation = (rotation % 180 == 0) ? Configuration.ORIENTATION_PORTRAIT
95                 : Configuration.ORIENTATION_LANDSCAPE;
96         if (camOrientation != orientation) {
97             return (rotation + 90) % 360;
98         }
99         return rotation;
100     }
101
102     private void center(View v, int l, int t, int r, int b, int orientation, int rotation, Rect result) {
103         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
104         int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin;
105         int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin;
106         switch (rotation) {
107         case 0:
108             // phone portrait; controls bottom
109             result.left = (r - l) / 2 - tw / 2 + lp.leftMargin;
110             result.right = (r - l) / 2 + tw / 2 - lp.rightMargin;
111             result.bottom = b - lp.bottomMargin;
112             result.top = b - th + lp.topMargin;
113             break;
114         case 90:
115             // phone landscape: controls right
116             result.right = r - lp.rightMargin;
117             result.left = r - tw + lp.leftMargin;
118             result.top = (b - t) / 2 - th / 2 + lp.topMargin;
119             result.bottom = (b - t) / 2 + th / 2 - lp.bottomMargin;
120             break;
121         case 180:
122             // phone upside down: controls top
123             result.left = (r - l) / 2 - tw / 2 + lp.leftMargin;
124             result.right = (r - l) / 2 + tw / 2 - lp.rightMargin;
125             result.top = t + lp.topMargin;
126             result.bottom = t + th - lp.bottomMargin;
127             break;
128         case 270:
129             // reverse landscape: controls left
130             result.left = l + lp.leftMargin;
131             result.right = l + tw - lp.rightMargin;
132             result.top = (b - t) / 2 - th / 2 + lp.topMargin;
133             result.bottom = (b - t) / 2 + th / 2 - lp.bottomMargin;
134             break;
135         }
136         v.layout(result.left, result.top, result.right, result.bottom);
137     }
138
139     private void toLeft(View v, int l, int t, int r, int b, int orientation, int rotation, Rect anchor) {
140         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
141         int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin;
142         int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin;
143         Rect result = new Rect();
144         switch (rotation) {
145         case 0:
146             // portrait, to left of anchor at bottom
147             result.right = anchor.left - lp.rightMargin;
148             result.left = anchor.left - tw + lp.leftMargin;
149             result.bottom = b - lp.bottomMargin;
150             result.top = b - th + lp.topMargin;
151             break;
152         case 90:
153             // phone landscape: below anchor on right
154             result.right = r - lp.rightMargin;
155             result.left = r - tw + lp.leftMargin;
156             result.top = anchor.bottom + lp.topMargin;
157             result.bottom = anchor.bottom + th - lp.bottomMargin;
158             break;
159         case 180:
160             // phone upside down: right of anchor at top
161             result.left = anchor.right + lp.leftMargin;
162             result.right = anchor.right + tw - lp.rightMargin;
163             result.top = t + lp.topMargin;
164             result.bottom = t + th - lp.bottomMargin;
165             break;
166         case 270:
167             // reverse landscape: above anchor on left
168             result.left = l + lp.leftMargin;
169             result.right = l + tw - lp.rightMargin;
170             result.bottom = anchor.top - lp.bottomMargin;
171             result.top = anchor.top - th + lp.topMargin;
172             break;
173         }
174         v.layout(result.left, result.top, result.right, result.bottom);
175     }
176
177     private void toRight(View v, int l, int t, int r, int b, int orientation, int rotation, Rect anchor) {
178         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams();
179         int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin;
180         int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin;
181         Rect result = new Rect();
182         switch (rotation) {
183         case 0:
184             // portrait, right of anchor at bottom
185             result.left = anchor.right + lp.leftMargin;
186             result.right = anchor.right + tw - lp.rightMargin;
187             result.bottom = b - lp.bottomMargin;
188             result.top = b - th + lp.topMargin;
189             break;
190         case 90:
191             // phone landscape: above anchor on right
192             result.right = r - lp.rightMargin;
193             result.left = r - tw + lp.leftMargin;
194             result.bottom = anchor.top - lp.bottomMargin;
195             result.top = anchor.top - th + lp.topMargin;
196             break;
197         case 180:
198             // phone upside down: left of anchor at top
199             result.right = anchor.left - lp.rightMargin;
200             result.left = anchor.left - tw + lp.leftMargin;
201             result.top = t + lp.topMargin;
202             result.bottom = t + th - lp.bottomMargin;
203             break;
204         case 270:
205             // reverse landscape: below anchor on left
206             result.left = l + lp.leftMargin;
207             result.right = l + tw - lp.rightMargin;
208             result.top = anchor.bottom + lp.topMargin;
209             result.bottom = anchor.bottom + th - lp.bottomMargin;
210             break;
211         }
212         v.layout(result.left, result.top, result.right, result.bottom);
213     }
214
215     private void topRight(View v, int l, int t, int r, int b, int orientation, int rotation) {
216         // layout using the specific margins; the rotation code messes up the others
217         int mt = getContext().getResources().getDimensionPixelSize(R.dimen.capture_margin_top);
218         int mr = getContext().getResources().getDimensionPixelSize(R.dimen.capture_margin_right);
219         v.layout(r - v.getMeasuredWidth() - mr, t + mt, r - mr, t + mt + v.getMeasuredHeight());
220     }
221
222     // In reverse landscape and reverse portrait, camera controls will be laid out
223     // on the wrong side of the screen. We need to make adjustment to move the controls
224     // to the USB side
225     public void adjustControlsToRightPosition() {
226         Configuration config = getResources().getConfiguration();
227         int orientation = Util.getDisplayRotation((Activity) getContext());
228         if (orientation == 270 && config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
229             flipChildren();
230         }
231         if (orientation == 180 && config.orientation == Configuration.ORIENTATION_PORTRAIT) {
232             flipChildren();
233         }
234         adjustBackground();
235     }
236
237     private void adjustBackground() {
238         // remove current drawable and reset rotation
239         mBackgroundView.setBackgroundDrawable(null);
240         mBackgroundView.setRotationX(0);
241         mBackgroundView.setRotationY(0);
242         // if the switcher background is top aligned we need to flip the background
243         // drawable vertically; if left aligned, flip horizontally
244         int gravity = ((LayoutParams) mBackgroundView.getLayoutParams()).gravity;
245         if ((gravity & Gravity.TOP) == Gravity.TOP) {
246             mBackgroundView.setRotationX(180);
247         } else if ((gravity & Gravity.LEFT) == Gravity.LEFT) {
248             mBackgroundView.setRotationY(180);
249         }
250         mBackgroundView.setBackgroundResource(R.drawable.switcher_bg);
251     }
252
253 }