• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.camera;
18 
19 import android.app.Activity;
20 import android.content.Context;
21 import android.util.AttributeSet;
22 import android.util.DisplayMetrics;
23 import android.view.ViewGroup;
24 import android.widget.FrameLayout;
25 
26 /**
27  * A layout which handles the preview aspect ratio and the position of
28  * the gripper.
29  */
30 public class PreviewFrameLayout extends ViewGroup {
31     private static final int MIN_HORIZONTAL_MARGIN = 10; // 10dp
32 
33     /** A callback to be invoked when the preview frame's size changes. */
34     public interface OnSizeChangedListener {
onSizeChanged()35         public void onSizeChanged();
36     }
37 
38     private double mAspectRatio = 4.0 / 3.0;
39     private FrameLayout mFrame;
40     private OnSizeChangedListener mSizeListener;
41     private final DisplayMetrics mMetrics = new DisplayMetrics();
42 
PreviewFrameLayout(Context context, AttributeSet attrs)43     public PreviewFrameLayout(Context context, AttributeSet attrs) {
44         super(context, attrs);
45         ((Activity) context).getWindowManager()
46                 .getDefaultDisplay().getMetrics(mMetrics);
47     }
48 
setOnSizeChangedListener(OnSizeChangedListener listener)49     public void setOnSizeChangedListener(OnSizeChangedListener listener) {
50         mSizeListener = listener;
51     }
52 
53     @Override
onFinishInflate()54     protected void onFinishInflate() {
55         mFrame = (FrameLayout) findViewById(R.id.frame);
56         if (mFrame == null) {
57             throw new IllegalStateException(
58                     "must provide child with id as \"frame\"");
59         }
60     }
61 
setAspectRatio(double ratio)62     public void setAspectRatio(double ratio) {
63         if (ratio <= 0.0) throw new IllegalArgumentException();
64 
65         if (mAspectRatio != ratio) {
66             mAspectRatio = ratio;
67             requestLayout();
68         }
69     }
70 
71     @Override
onLayout(boolean changed, int l, int t, int r, int b)72     protected void onLayout(boolean changed, int l, int t, int r, int b) {
73         int frameWidth = getWidth();
74         int frameHeight = getHeight();
75 
76         FrameLayout f = mFrame;
77         int horizontalPadding = f.getPaddingLeft() + f.getPaddingRight();
78         int verticalPadding = f.getPaddingBottom() + f.getPaddingTop();
79         int previewHeight = frameHeight - verticalPadding;
80         int previewWidth = frameWidth - horizontalPadding;
81 
82         // resize frame and preview for aspect ratio
83         if (previewWidth > previewHeight * mAspectRatio) {
84             previewWidth = (int) (previewHeight * mAspectRatio + .5);
85         } else {
86             previewHeight = (int) (previewWidth / mAspectRatio + .5);
87         }
88 
89         frameWidth = previewWidth + horizontalPadding;
90         frameHeight = previewHeight + verticalPadding;
91 
92         int hSpace = ((r - l) - frameWidth) / 2;
93         int vSpace = ((b - t) - frameHeight) / 2;
94         mFrame.measure(
95                 MeasureSpec.makeMeasureSpec(frameWidth, MeasureSpec.EXACTLY),
96                 MeasureSpec.makeMeasureSpec(frameHeight, MeasureSpec.EXACTLY));
97         mFrame.layout(l + hSpace, t + vSpace, r - hSpace, b - vSpace);
98         if (mSizeListener != null) {
99             mSizeListener.onSizeChanged();
100         }
101     }
102 }
103 
104