1 /* 2 * Copyright (C) 2014 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.widget; 18 19 import android.content.Context; 20 import android.content.res.Configuration; 21 import android.graphics.RectF; 22 import android.util.AttributeSet; 23 import android.view.Gravity; 24 import android.view.MotionEvent; 25 import android.view.View; 26 import android.view.ViewGroup; 27 import android.widget.FrameLayout; 28 import android.widget.ImageView; 29 import android.widget.LinearLayout; 30 31 import com.android.camera.CaptureLayoutHelper; 32 import com.android.camera.ShutterButton; 33 import com.android.camera.debug.Log; 34 import com.android.camera.ui.PreviewOverlay; 35 import com.android.camera.ui.TouchCoordinate; 36 import com.android.camera2.R; 37 38 /** 39 * ModeOptionsOverlay is a FrameLayout which positions mode options in 40 * in the bottom of the preview that is visible above the bottom bar. 41 */ 42 public class ModeOptionsOverlay extends FrameLayout 43 implements PreviewOverlay.OnPreviewTouchedListener, 44 ShutterButton.OnShutterButtonListener { 45 46 private final static Log.Tag TAG = new Log.Tag("ModeOptionsOverlay"); 47 48 private static final int BOTTOMBAR_OPTIONS_TIMEOUT_MS = 2000; 49 private final static int BOTTOM_RIGHT = Gravity.BOTTOM | Gravity.RIGHT; 50 private final static int TOP_RIGHT = Gravity.TOP | Gravity.RIGHT; 51 52 private ModeOptions mModeOptions; 53 // need a reference to set the onClickListener and fix the layout gravity on orientation change 54 private LinearLayout mModeOptionsToggle; 55 // need a reference to fix the rotation on orientation change 56 private ImageView mThreeDots; 57 private CaptureLayoutHelper mCaptureLayoutHelper = null; 58 ModeOptionsOverlay(Context context, AttributeSet attrs)59 public ModeOptionsOverlay(Context context, AttributeSet attrs) { 60 super(context, attrs); 61 } 62 63 /** 64 * Sets a capture layout helper to query layout rect from. 65 */ setCaptureLayoutHelper(CaptureLayoutHelper helper)66 public void setCaptureLayoutHelper(CaptureLayoutHelper helper) { 67 mCaptureLayoutHelper = helper; 68 } 69 setToggleClickable(boolean clickable)70 public void setToggleClickable(boolean clickable) { 71 mModeOptionsToggle.setClickable(clickable); 72 } 73 74 @Override onFinishInflate()75 public void onFinishInflate() { 76 mModeOptions = (ModeOptions) findViewById(R.id.mode_options); 77 mModeOptions.setClickable(true); 78 mModeOptions.setOnClickListener(new View.OnClickListener() { 79 @Override 80 public void onClick(View v) { 81 closeModeOptions(); 82 } 83 }); 84 85 mModeOptionsToggle = (LinearLayout) findViewById(R.id.mode_options_toggle); 86 mModeOptionsToggle.setOnClickListener(new View.OnClickListener() { 87 @Override 88 public void onClick(View v) { 89 mModeOptions.animateVisible(); 90 } 91 }); 92 mModeOptions.setViewToShowHide(mModeOptionsToggle); 93 94 mThreeDots = (ImageView) findViewById(R.id.three_dots); 95 } 96 97 @Override onPreviewTouched(MotionEvent ev)98 public void onPreviewTouched(MotionEvent ev) { 99 closeModeOptions(); 100 } 101 102 @Override onShutterButtonClick()103 public void onShutterButtonClick() { 104 closeModeOptions(); 105 } 106 107 @Override onShutterCoordinate(TouchCoordinate coord)108 public void onShutterCoordinate(TouchCoordinate coord) { 109 // Do nothing. 110 } 111 112 @Override onShutterButtonFocus(boolean pressed)113 public void onShutterButtonFocus(boolean pressed) { 114 // noop 115 } 116 117 /** 118 * Schedule (or re-schedule) the options menu to be closed after a number 119 * of milliseconds. If the options menu is already closed, nothing is 120 * scheduled. 121 */ closeModeOptions()122 public void closeModeOptions() { 123 mModeOptions.animateHidden(); 124 } 125 126 @Override onConfigurationChanged(Configuration configuration)127 public void onConfigurationChanged(Configuration configuration) { 128 super.onConfigurationChanged(configuration); 129 checkOrientation(configuration.orientation); 130 } 131 132 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)133 public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 134 if (mCaptureLayoutHelper == null) { 135 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 136 Log.e(TAG, "Capture layout helper needs to be set first."); 137 } else { 138 RectF uncoveredPreviewRect = mCaptureLayoutHelper.getUncoveredPreviewRect(); 139 super.onMeasure(MeasureSpec.makeMeasureSpec( 140 (int) uncoveredPreviewRect.width(), MeasureSpec.EXACTLY), 141 MeasureSpec.makeMeasureSpec((int) uncoveredPreviewRect.height(), 142 MeasureSpec.EXACTLY) 143 ); 144 } 145 } 146 147 /** 148 * Set the layout gravity of the child layout to be bottom or top right 149 * depending on orientation. 150 */ checkOrientation(int orientation)151 private void checkOrientation(int orientation) { 152 final boolean isPortrait = (Configuration.ORIENTATION_PORTRAIT == orientation); 153 154 final int modeOptionsDimension = (int) getResources() 155 .getDimension(R.dimen.mode_options_height); 156 157 FrameLayout.LayoutParams modeOptionsParams 158 = (FrameLayout.LayoutParams) mModeOptions.getLayoutParams(); 159 FrameLayout.LayoutParams modeOptionsToggleParams 160 = (FrameLayout.LayoutParams) mModeOptionsToggle.getLayoutParams(); 161 162 if (isPortrait) { 163 modeOptionsParams.height = modeOptionsDimension; 164 modeOptionsParams.width = ViewGroup.LayoutParams.MATCH_PARENT; 165 modeOptionsParams.gravity = Gravity.BOTTOM; 166 167 modeOptionsToggleParams.gravity = BOTTOM_RIGHT; 168 169 mThreeDots.setImageResource(R.drawable.ic_options_port); 170 } else { 171 modeOptionsParams.width = modeOptionsDimension; 172 modeOptionsParams.height = ViewGroup.LayoutParams.MATCH_PARENT; 173 modeOptionsParams.gravity = Gravity.RIGHT; 174 175 modeOptionsToggleParams.gravity = TOP_RIGHT; 176 177 mThreeDots.setImageResource(R.drawable.ic_options_land); 178 } 179 180 requestLayout(); 181 } 182 } 183