10744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen/* 20744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * Copyright (C) 2013 The Android Open Source Project 30744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * 40744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * Licensed under the Apache License, Version 2.0 (the "License"); 50744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * you may not use this file except in compliance with the License. 60744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * You may obtain a copy of the License at 70744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * 80744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * http://www.apache.org/licenses/LICENSE-2.0 90744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * 100744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * Unless required by applicable law or agreed to in writing, software 110744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * distributed under the License is distributed on an "AS IS" BASIS, 120744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * See the License for the specific language governing permissions and 140744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen * limitations under the License. 150744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen */ 160744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 170744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenpackage com.android.camera.ui; 180744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 190744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenimport android.content.Context; 20d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Spragueimport android.content.res.TypedArray; 212268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Spragueimport android.graphics.Rect; 22a1ec04a9f9526418f5cb17a5afbfc48aca1e02d0Doris Liuimport android.graphics.RectF; 23d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Spragueimport android.graphics.drawable.ColorDrawable; 244dae414b0e4ad4d6528ee04f0761fbe9eacca5ceSpike Spragueimport android.graphics.drawable.Drawable; 25d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Spragueimport android.graphics.drawable.LayerDrawable; 264dae414b0e4ad4d6528ee04f0761fbe9eacca5ceSpike Spragueimport android.graphics.drawable.TransitionDrawable; 270744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenimport android.util.AttributeSet; 284efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgrenimport android.view.MotionEvent; 292268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Spragueimport android.view.TouchDelegate; 300744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenimport android.view.View; 310744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissenimport android.widget.FrameLayout; 3266a3e6ceb306833355acb740711ccb5c53576e0aSpike Spragueimport android.widget.ImageButton; 330744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 3428a2950939614a0c1c83787960ce1a218fb69a5eDoris Liuimport com.android.camera.CaptureLayoutHelper; 3539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport com.android.camera.ShutterButton; 365596b4c902dcb685928b43678f428746ca5ffd08Angus Kongimport com.android.camera.debug.Log; 3779150ed3f8963016e1dc4576e6acab507bef4228Spike Spragueimport com.android.camera.util.ApiHelper; 38d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Spragueimport com.android.camera.util.CameraUtil; 3939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Spragueimport com.android.camera2.R; 4039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 410744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen/** 42d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * BottomBar swaps its width and height on rotation. In addition, it also 43d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * changes gravity and layout orientation based on the new orientation. 44d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * Specifically, in landscape it aligns to the right side of its parent and lays 45d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * out its children vertically, whereas in portrait, it stays at the bottom of 46d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * the parent and has a horizontal layout orientation. 47d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague */ 4828a2950939614a0c1c83787960ce1a218fb69a5eDoris Liupublic class BottomBar extends FrameLayout { 4994c9b43061bee072a2322a2001d27e51dae023dbSpike Sprague 505596b4c902dcb685928b43678f428746ca5ffd08Angus Kong private static final Log.Tag TAG = new Log.Tag("BottomBar"); 5139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 52217512ce074220090a8ede01adf0406a70f4958fSpike Sprague private static final int CIRCLE_ANIM_DURATION_MS = 300; 53d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague private static final int DRAWABLE_MAX_LEVEL = 10000; 54d4c5070dfcd7007654ad71ab292d1909c0091cebSpike Sprague private static final int MODE_CAPTURE = 0; 55165bb8d85e6eab4e261c6b21a754ee227f732795Erin Dahlgren private static final int MODE_INTENT = 1; 56165bb8d85e6eab4e261c6b21a754ee227f732795Erin Dahlgren private static final int MODE_INTENT_REVIEW = 2; 572db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael private static final int MODE_CANCEL = 3; 582db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael 59d4c5070dfcd7007654ad71ab292d1909c0091cebSpike Sprague private int mMode; 60d4c5070dfcd7007654ad71ab292d1909c0091cebSpike Sprague 6158b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong private final int mBackgroundAlphaOverlay; 6258b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong private final int mBackgroundAlphaDefault; 6370da918464276b110c43868caa272c97baadb89eDoris Liu private boolean mOverLayBottomBar; 640744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 654efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren private FrameLayout mCaptureLayout; 662db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael private FrameLayout mCancelLayout; 6715690d02da08bda74ed63f260b70076801bf91bfSpike Sprague private TopRightWeightedLayout mIntentReviewLayout; 684efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 6939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private ShutterButton mShutterButton; 702db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael private ImageButton mCancelButton; 7139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 7239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private int mBackgroundColor; 73b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague private int mBackgroundPressedColor; 74b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague private int mBackgroundAlpha = 0xff; 75b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague 76e3f095bd84ba5a07d5fba1020a28d40d067d187cSpike Sprague private boolean mDrawCircle; 774dae414b0e4ad4d6528ee04f0761fbe9eacca5ceSpike Sprague private final float mCircleRadius; 7828a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu private CaptureLayoutHelper mCaptureLayoutHelper = null; 7994c9b43061bee072a2322a2001d27e51dae023dbSpike Sprague 80fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague private final Drawable.ConstantState[] mShutterButtonBackgroundConstantStates; 81d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague // a reference to the shutter background's first contained drawable 82d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague // if it's an animated circle drawable (for video mode) 83d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague private AnimatedCircleDrawable mAnimatedCircleDrawable; 84d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague // a reference to the shutter background's first contained drawable 85d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague // if it's a color drawable (for all other modes) 86d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague private ColorDrawable mColorDrawable; 87d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 889bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague private RectF mRect = new RectF(); 899bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague 900744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen public BottomBar(Context context, AttributeSet attrs) { 910744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen super(context, attrs); 924dae414b0e4ad4d6528ee04f0761fbe9eacca5ceSpike Sprague mCircleRadius = getResources() 93d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague .getDimensionPixelSize(R.dimen.video_capture_circle_diameter) / 2; 94d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mBackgroundAlphaOverlay = getResources() 95d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague .getInteger(R.integer.bottom_bar_background_alpha_overlay); 96d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mBackgroundAlphaDefault = getResources() 97d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague .getInteger(R.integer.bottom_bar_background_alpha); 98d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 99d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague // preload all the drawable BGs 100d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague TypedArray ar = context.getResources() 101d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague .obtainTypedArray(R.array.shutter_button_backgrounds); 102d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague int len = ar.length(); 103fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague mShutterButtonBackgroundConstantStates = new Drawable.ConstantState[len]; 104d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague for (int i = 0; i < len; i++) { 105d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague int drawableId = ar.getResourceId(i, -1); 106fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague mShutterButtonBackgroundConstantStates[i] = 107fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague context.getResources().getDrawable(drawableId).getConstantState(); 108d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 109d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague ar.recycle(); 1100744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen } 1110744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen 112d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague private void setPaintColor(int alpha, int color) { 113d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague if (mAnimatedCircleDrawable != null) { 114d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mAnimatedCircleDrawable.setColor(color); 115d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mAnimatedCircleDrawable.setAlpha(alpha); 116d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } else if (mColorDrawable != null) { 117d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mColorDrawable.setColor(color); 118d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mColorDrawable.setAlpha(alpha); 119d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 120d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 121d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague if (mIntentReviewLayout != null) { 122d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague ColorDrawable intentBackground = (ColorDrawable) mIntentReviewLayout 123d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague .getBackground(); 124d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague intentBackground.setColor(color); 125d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague intentBackground.setAlpha(alpha); 126d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 127b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague } 128b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague 129d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague private void refreshPaintColor() { 130d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setPaintColor(mBackgroundAlpha, mBackgroundColor); 131d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 132d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 133d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague private void setCancelBackgroundColor(int alpha, int color) { 134d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague LayerDrawable layerDrawable = (LayerDrawable) mCancelButton.getBackground(); 135bfec41e5a5b57715e91ca273d3d1bde65bbcc154Spike Sprague Drawable d = layerDrawable.getDrawable(0); 136bfec41e5a5b57715e91ca273d3d1bde65bbcc154Spike Sprague if (d instanceof AnimatedCircleDrawable) { 137bfec41e5a5b57715e91ca273d3d1bde65bbcc154Spike Sprague AnimatedCircleDrawable animatedCircleDrawable = (AnimatedCircleDrawable) d; 138bfec41e5a5b57715e91ca273d3d1bde65bbcc154Spike Sprague animatedCircleDrawable.setColor(color); 139bfec41e5a5b57715e91ca273d3d1bde65bbcc154Spike Sprague animatedCircleDrawable.setAlpha(alpha); 140bfec41e5a5b57715e91ca273d3d1bde65bbcc154Spike Sprague } else if (d instanceof ColorDrawable) { 141bfec41e5a5b57715e91ca273d3d1bde65bbcc154Spike Sprague ColorDrawable colorDrawable = (ColorDrawable) d; 142bfec41e5a5b57715e91ca273d3d1bde65bbcc154Spike Sprague if (!ApiHelper.isLOrHigher()) { 143bfec41e5a5b57715e91ca273d3d1bde65bbcc154Spike Sprague colorDrawable.setColor(color); 144bfec41e5a5b57715e91ca273d3d1bde65bbcc154Spike Sprague } 145bfec41e5a5b57715e91ca273d3d1bde65bbcc154Spike Sprague colorDrawable.setAlpha(alpha); 146d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 147cf9010d314a5a263a3f0e9fa9abf16a80f26d281Spike Sprague } 148cf9010d314a5a263a3f0e9fa9abf16a80f26d281Spike Sprague 14987f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague private void setCaptureButtonUp() { 150d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setPaintColor(mBackgroundAlpha, mBackgroundColor); 15187f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague } 15287f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague 15387f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague private void setCaptureButtonDown() { 15479150ed3f8963016e1dc4576e6acab507bef4228Spike Sprague if (!ApiHelper.isLOrHigher()) { 155d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setPaintColor(mBackgroundAlpha, mBackgroundPressedColor); 156d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 157d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 158d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 159d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague private void setCancelButtonUp() { 160d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setCancelBackgroundColor(mBackgroundAlpha, mBackgroundColor); 161d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 162d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 163d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague private void setCancelButtonDown() { 164d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setCancelBackgroundColor(mBackgroundAlpha, mBackgroundPressedColor); 16587f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague } 16687f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague 1674efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren @Override 1684efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren public void onFinishInflate() { 1699bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague mCaptureLayout = 1709bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague (FrameLayout) findViewById(R.id.bottombar_capture); 1719bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague mCancelLayout = 1729bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague (FrameLayout) findViewById(R.id.bottombar_cancel); 173d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mCancelLayout.setVisibility(View.GONE); 1742db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael 1759bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague mIntentReviewLayout = 1769bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague (TopRightWeightedLayout) findViewById(R.id.bottombar_intent_review); 177b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague 1789bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague mShutterButton = 1799bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague (ShutterButton) findViewById(R.id.shutter_button); 180b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague mShutterButton.setOnTouchListener(new OnTouchListener() { 181b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague @Override 182b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague public boolean onTouch(View v, MotionEvent event) { 183b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague if (MotionEvent.ACTION_DOWN == event.getActionMasked()) { 18487f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague setCaptureButtonDown(); 18558b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong } else if (MotionEvent.ACTION_UP == event.getActionMasked() || 18658b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong MotionEvent.ACTION_CANCEL == event.getActionMasked()) { 18787f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague setCaptureButtonUp(); 18887f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague } else if (MotionEvent.ACTION_MOVE == event.getActionMasked()) { 1899bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague mRect.set(0, 0, getWidth(), getHeight()); 19087f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague if (!mRect.contains(event.getX(), event.getY())) { 19187f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague setCaptureButtonUp(); 19287f7af57932a826d54a74eb2b22b5bfa7a94f583Spike Sprague } 193b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague } 194b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague return false; 195b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague } 196b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague }); 1972db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael 1989bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague mCancelButton = 1999bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague (ImageButton) findViewById(R.id.shutter_cancel_button); 2002db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael mCancelButton.setOnTouchListener(new OnTouchListener() { 2012db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael @Override 2022db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael public boolean onTouch(View v, MotionEvent event) { 2032db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael if (MotionEvent.ACTION_DOWN == event.getActionMasked()) { 204d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setCancelButtonDown(); 2052db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael } else if (MotionEvent.ACTION_UP == event.getActionMasked() || 2062db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael MotionEvent.ACTION_CANCEL == event.getActionMasked()) { 207d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setCancelButtonUp(); 2082db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael } else if (MotionEvent.ACTION_MOVE == event.getActionMasked()) { 2099bfd6bddaa09ccdadabf3b0e7e2b81bc1bcf175dSpike Sprague mRect.set(0, 0, getWidth(), getHeight()); 2102db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael if (!mRect.contains(event.getX(), event.getY())) { 211d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setCancelButtonUp(); 2122db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael } 2132db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael } 2142db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael return false; 2152db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael } 2162db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael }); 2172db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael 2182268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague extendTouchAreaToMatchParent(R.id.done_button); 2192268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague } 2202268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague 2212268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague private void extendTouchAreaToMatchParent(int id) { 2222268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague final View button = findViewById(id); 2232268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague final View parent = (View) button.getParent(); 2242268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague 2252268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague parent.post(new Runnable() { 2262268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague @Override 2272268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague public void run() { 2282268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague Rect parentRect = new Rect(); 2292268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague parent.getHitRect(parentRect); 2302268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague Rect buttonRect = new Rect(); 2312268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague button.getHitRect(buttonRect); 2322268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague 2332268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague int widthDiff = parentRect.width() - buttonRect.width(); 2342268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague int heightDiff = parentRect.height() - buttonRect.height(); 2352268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague 2362268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague buttonRect.left -= widthDiff/2; 2372268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague buttonRect.right += widthDiff/2; 2382268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague buttonRect.top -= heightDiff/2; 2392268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague buttonRect.bottom += heightDiff/2; 2402268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague 2412268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague parent.setTouchDelegate(new TouchDelegate(buttonRect, button)); 2422268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague } 2432268fbb50d07e327c9ac00642db0a83a49c8f3e3Spike Sprague }); 2444efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 2454efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 2464efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 247d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * Perform a transition from the bottom bar options layout to the bottom bar 248d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * capture layout. 2494efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 250a1fab413bcbe5f62ae1d829bac0539519fef96a6Erin Dahlgren public void transitionToCapture() { 2514efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mCaptureLayout.setVisibility(View.VISIBLE); 252d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mCancelLayout.setVisibility(View.GONE); 253d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mIntentReviewLayout.setVisibility(View.GONE); 254d4c5070dfcd7007654ad71ab292d1909c0091cebSpike Sprague 255d4c5070dfcd7007654ad71ab292d1909c0091cebSpike Sprague mMode = MODE_CAPTURE; 2564efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 2574efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 2582db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael /** 259d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * Perform a transition from the bottom bar options layout to the bottom bar 260d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * capture layout. 2612db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael */ 2622db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael public void transitionToCancel() { 263d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mCaptureLayout.setVisibility(View.GONE); 264d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mIntentReviewLayout.setVisibility(View.GONE); 2652db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael mCancelLayout.setVisibility(View.VISIBLE); 266d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 2672db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael mMode = MODE_CANCEL; 2682db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael } 2692db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael 2704efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 271d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * Perform a transition to the global intent layout. The current layout 272d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * state of the bottom bar is irrelevant. 2730f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague */ 27415690d02da08bda74ed63f260b70076801bf91bfSpike Sprague public void transitionToIntentCaptureLayout() { 275d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mIntentReviewLayout.setVisibility(View.GONE); 2764efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren mCaptureLayout.setVisibility(View.VISIBLE); 277d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mCancelLayout.setVisibility(View.GONE); 2782db51d761f8fb070f660b90913e131ab361cbbadSeth Raphael 279d4c5070dfcd7007654ad71ab292d1909c0091cebSpike Sprague mMode = MODE_INTENT; 2804efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren } 2814efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren 2824efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren /** 283d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * Perform a transition to the global intent review layout. The current 284d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * layout state of the bottom bar is irrelevant. 2854efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren */ 2864efa8b54c1df4e06f2d3caed2568015a737f9ddaErin Dahlgren public void transitionToIntentReviewLayout() { 287d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mCaptureLayout.setVisibility(View.GONE); 28815690d02da08bda74ed63f260b70076801bf91bfSpike Sprague mIntentReviewLayout.setVisibility(View.VISIBLE); 289d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mCancelLayout.setVisibility(View.GONE); 290d4c5070dfcd7007654ad71ab292d1909c0091cebSpike Sprague 291d4c5070dfcd7007654ad71ab292d1909c0091cebSpike Sprague mMode = MODE_INTENT_REVIEW; 2920f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague } 2930f3c4b4fc9ac87d7d4c3d04c3cb3426c711f57eaSpike Sprague 2949f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague /** 2959f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague * @return whether UI is in intent review mode 2969f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague */ 2979f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague public boolean isInIntentReview() { 2989f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague return mMode == MODE_INTENT_REVIEW; 2999f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague } 3009f3d01d9c5d2200882de76e309db55d74d950110Spike Sprague 30166a3e6ceb306833355acb740711ccb5c53576e0aSpike Sprague private void setButtonImageLevels(int level) { 30266a3e6ceb306833355acb740711ccb5c53576e0aSpike Sprague ((ImageButton) findViewById(R.id.cancel_button)).setImageLevel(level); 30366a3e6ceb306833355acb740711ccb5c53576e0aSpike Sprague ((ImageButton) findViewById(R.id.done_button)).setImageLevel(level); 30466a3e6ceb306833355acb740711ccb5c53576e0aSpike Sprague ((ImageButton) findViewById(R.id.retake_button)).setImageLevel(level); 30566a3e6ceb306833355acb740711ccb5c53576e0aSpike Sprague } 30666a3e6ceb306833355acb740711ccb5c53576e0aSpike Sprague 307d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger /** 308d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * Configure the bottom bar to either overlay a live preview, or render off 309d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * the preview. If overlaying the preview, ensure contained drawables have 310d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * reduced opacity and that the bottom bar itself has no background to allow 311d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * the preview to render through. If not overlaying the preview, set 312d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * contained drawables to opaque and ensure that the bottom bar itself has 313d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * a view background, so that varying alpha (i.e. mode list transitions) are 314d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * based upon that background instead of an underlying preview. 315d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * 316d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger * @param overlay if true, treat bottom bar as overlaying the preview 317d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger */ 31858b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong private void setOverlayBottomBar(boolean overlay) { 31958b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong mOverLayBottomBar = overlay; 32058b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong if (overlay) { 32158b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong setBackgroundAlpha(mBackgroundAlphaOverlay); 32258b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong setButtonImageLevels(1); 323d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger // clear background on the containing bottom bar, rather than the 324d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger // contained drawables 325d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger super.setBackground(null); 32658b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong } else { 32758b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong setBackgroundAlpha(mBackgroundAlphaDefault); 32858b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong setButtonImageLevels(0); 329d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger // setBackgroundColor is overridden and delegates to contained 330d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger // drawables, call super to set the containing background color in 331d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger // this mode. 332d7064a6c6f1eb0748de8f56b8a1e006d60ab0f7eAlan Newberger super.setBackgroundColor(mBackgroundColor); 33358b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong } 33458b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong } 33558b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong 33628a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu /** 33728a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu * Sets a capture layout helper to query layout rect from. 33828a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu */ 33928a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu public void setCaptureLayoutHelper(CaptureLayoutHelper helper) { 34028a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu mCaptureLayoutHelper = helper; 34128a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu } 34228a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu 34370da918464276b110c43868caa272c97baadb89eDoris Liu @Override 34470da918464276b110c43868caa272c97baadb89eDoris Liu public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 34558b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong final int measureWidth = MeasureSpec.getSize(widthMeasureSpec); 34658b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong final int measureHeight = MeasureSpec.getSize(heightMeasureSpec); 34758b9b03f2bedc522bde5b4199121ea2e559c79a9Angus Kong if (measureWidth == 0 || measureHeight == 0) { 34870da918464276b110c43868caa272c97baadb89eDoris Liu return; 34970da918464276b110c43868caa272c97baadb89eDoris Liu } 35070da918464276b110c43868caa272c97baadb89eDoris Liu 35128a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu if (mCaptureLayoutHelper == null) { 35228a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu super.onMeasure(widthMeasureSpec, heightMeasureSpec); 35328a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu Log.e(TAG, "Capture layout helper needs to be set first."); 3540744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen } else { 35528a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu RectF bottomBarRect = mCaptureLayoutHelper.getBottomBarRect(); 35628a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu super.onMeasure(MeasureSpec.makeMeasureSpec( 357d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague (int) bottomBarRect.width(), MeasureSpec.EXACTLY), 35828a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu MeasureSpec.makeMeasureSpec((int) bottomBarRect.height(), MeasureSpec.EXACTLY) 359d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague ); 36028a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu boolean shouldOverlayBottomBar = mCaptureLayoutHelper.shouldOverlayBottomBar(); 36128a2950939614a0c1c83787960ce1a218fb69a5eDoris Liu setOverlayBottomBar(shouldOverlayBottomBar); 3620744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen } 36370da918464276b110c43868caa272c97baadb89eDoris Liu } 36470da918464276b110c43868caa272c97baadb89eDoris Liu 365e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague // prevent touches on bottom bar (not its children) 366e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague // from triggering a touch event on preview area 367e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague @Override 368e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague public boolean onTouchEvent(MotionEvent event) { 369e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague return true; 370e3b0e946924e45f6788db69aaa8f48a2d81031f0Spike Sprague } 37139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 37239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague @Override 37339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void setBackgroundColor(int color) { 37439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mBackgroundColor = color; 375b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague setPaintColor(mBackgroundAlpha, mBackgroundColor); 376d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setCancelBackgroundColor(mBackgroundAlpha, mBackgroundColor); 377d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 378d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 379d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague private void setBackgroundPressedColor(int color) { 38079150ed3f8963016e1dc4576e6acab507bef4228Spike Sprague if (ApiHelper.isLOrHigher()) { 381d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague // not supported (setting a color on a RippleDrawable is hard =[ ) 382d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } else { 383d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mBackgroundPressedColor = color; 384d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 385d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 386d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 387fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague private LayerDrawable applyCircleDrawableToShutterBackground(LayerDrawable shutterBackground) { 388fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague // the background for video has a circle_item drawable placeholder 389fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague // that gets replaced by an AnimatedCircleDrawable for the cool 390fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague // shrink-down-to-a-circle effect 391fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague // all other modes need not do this replace 392fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague Drawable d = shutterBackground.findDrawableByLayerId(R.id.circle_item); 393fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague if (d != null) { 394fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague Drawable animatedCircleDrawable = 395fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague new AnimatedCircleDrawable((int) mCircleRadius); 396fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague shutterBackground 397fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague .setDrawableByLayerId(R.id.circle_item, animatedCircleDrawable); 398c5ecbd6e0a6c2a2d93fc58f0ba3d273249b06da2Spike Sprague animatedCircleDrawable.setLevel(DRAWABLE_MAX_LEVEL); 399fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague } 400fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague 401fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague return shutterBackground; 402fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague } 403fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague 404fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague private LayerDrawable newDrawableFromConstantState(Drawable.ConstantState constantState) { 405fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague return (LayerDrawable) constantState.newDrawable(getContext().getResources()); 406fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague } 407fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague 408d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague private void setupShutterBackgroundForModeIndex(int index) { 409fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague LayerDrawable shutterBackground = applyCircleDrawableToShutterBackground( 410fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague newDrawableFromConstantState(mShutterButtonBackgroundConstantStates[index])); 411d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mShutterButton.setBackground(shutterBackground); 412fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague mCancelButton.setBackground(applyCircleDrawableToShutterBackground( 413fcc9143368d134ce26dec7d904f21e06676b2a02Spike Sprague newDrawableFromConstantState(mShutterButtonBackgroundConstantStates[index]))); 414d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 415d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague Drawable d = shutterBackground.getDrawable(0); 416d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mAnimatedCircleDrawable = null; 417d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mColorDrawable = null; 418d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague if (d instanceof AnimatedCircleDrawable) { 419d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mAnimatedCircleDrawable = (AnimatedCircleDrawable) d; 420d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } else if (d instanceof ColorDrawable) { 421d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mColorDrawable = (ColorDrawable) d; 422d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague } 423d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague 424d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague int colorId = CameraUtil.getCameraThemeColorId(index, getContext()); 425d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague int pressedColor = getContext().getResources().getColor(colorId); 426d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setBackgroundPressedColor(pressedColor); 427d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague refreshPaintColor(); 428b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague } 429b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague 430d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague public void setColorsForModeIndex(int index) { 431d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setupShutterBackgroundForModeIndex(index); 43239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 43339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 43439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void setBackgroundAlpha(int alpha) { 435b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague mBackgroundAlpha = alpha; 436b92910e04c4da91fc4ea5a9484b83f9ecba1c896Spike Sprague setPaintColor(mBackgroundAlpha, mBackgroundColor); 437d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague setCancelBackgroundColor(mBackgroundAlpha, mBackgroundColor); 43839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 43939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 440667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren /** 441667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren * Sets the shutter button enabled if true, disabled if false. 442667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren * <p> 443d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * Disabled means that the shutter button is not clickable and is greyed 444d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * out. 445667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren */ 44657bcd92f39d85427102f30be2c749c4a7bd4be96Sascha Haeberling public void setShutterButtonEnabled(final boolean enabled) { 44757bcd92f39d85427102f30be2c749c4a7bd4be96Sascha Haeberling mShutterButton.post(new Runnable() { 44857bcd92f39d85427102f30be2c749c4a7bd4be96Sascha Haeberling @Override 44957bcd92f39d85427102f30be2c749c4a7bd4be96Sascha Haeberling public void run() { 45057bcd92f39d85427102f30be2c749c4a7bd4be96Sascha Haeberling mShutterButton.setEnabled(enabled); 45157bcd92f39d85427102f30be2c749c4a7bd4be96Sascha Haeberling setShutterButtonImportantToA11y(enabled); 45257bcd92f39d85427102f30be2c749c4a7bd4be96Sascha Haeberling } 45357bcd92f39d85427102f30be2c749c4a7bd4be96Sascha Haeberling }); 454b7e41a734a9cf9b5789fd3221ba10833f669b7c5Spike Sprague } 455b7e41a734a9cf9b5789fd3221ba10833f669b7c5Spike Sprague 456b7e41a734a9cf9b5789fd3221ba10833f669b7c5Spike Sprague /** 457d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * Sets whether shutter button should be included in a11y announcement and 458d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * navigation 459b7e41a734a9cf9b5789fd3221ba10833f669b7c5Spike Sprague */ 460b7e41a734a9cf9b5789fd3221ba10833f669b7c5Spike Sprague public void setShutterButtonImportantToA11y(boolean important) { 461b7e41a734a9cf9b5789fd3221ba10833f669b7c5Spike Sprague if (important) { 46238989540cb1488cb7b8062ff74b9dedcd76c047fSpike Sprague mShutterButton.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); 46338989540cb1488cb7b8062ff74b9dedcd76c047fSpike Sprague } else { 46438989540cb1488cb7b8062ff74b9dedcd76c047fSpike Sprague mShutterButton.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); 46538989540cb1488cb7b8062ff74b9dedcd76c047fSpike Sprague } 466a93909ffe93c9f5e27e493f32a78aab6fbf3e06eSpike Sprague } 467a93909ffe93c9f5e27e493f32a78aab6fbf3e06eSpike Sprague 468667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren /** 469667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren * Returns whether the capture button is enabled. 470667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren */ 471667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren public boolean isShutterButtonEnabled() { 472667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren return mShutterButton.isEnabled(); 473667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren } 474667630d16a2b0cf3acecb817b3aa398abdd33623Erin Dahlgren 47539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague private TransitionDrawable crossfadeDrawable(Drawable from, Drawable to) { 476d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague Drawable[] arrayDrawable = new Drawable[2]; 47739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague arrayDrawable[0] = from; 47839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague arrayDrawable[1] = to; 47939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague TransitionDrawable transitionDrawable = new TransitionDrawable(arrayDrawable); 48039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague transitionDrawable.setCrossFadeEnabled(true); 48139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague return transitionDrawable; 48239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 48339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 48439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague /** 485d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * Sets the shutter button's icon resource. By default, all drawables 486d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * instances loaded from the same resource share a common state; if you 487d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * modify the state of one instance, all the other instances will receive 488d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * the same modification. In order to modify properties of this icon 489d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * drawable without affecting other drawables, here we use a mutable 490d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague * drawable which is guaranteed to not share states with other drawables. 49139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague */ 49239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void setShutterButtonIcon(int resId) { 49358ac7e042e0718e860f9aea6dca3697e1c3d9bb8Doris Liu Drawable iconDrawable = getResources().getDrawable(resId); 49458ac7e042e0718e860f9aea6dca3697e1c3d9bb8Doris Liu if (iconDrawable != null) { 49558ac7e042e0718e860f9aea6dca3697e1c3d9bb8Doris Liu iconDrawable = iconDrawable.mutate(); 49658ac7e042e0718e860f9aea6dca3697e1c3d9bb8Doris Liu } 49758ac7e042e0718e860f9aea6dca3697e1c3d9bb8Doris Liu mShutterButton.setImageDrawable(iconDrawable); 49839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 49939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 50039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague /** 50139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague * Animates bar to a single stop button 50239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague */ 50345a821d43ae8d7287b649f670a66ab3d99eeccafSpike Sprague public void animateToVideoStop(int resId) { 504d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague if (mOverLayBottomBar && mAnimatedCircleDrawable != null) { 505d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mAnimatedCircleDrawable.animateToSmallRadius(); 50645a821d43ae8d7287b649f670a66ab3d99eeccafSpike Sprague mDrawCircle = true; 50745a821d43ae8d7287b649f670a66ab3d99eeccafSpike Sprague } 50839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 50939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague TransitionDrawable transitionDrawable = crossfadeDrawable( 51039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mShutterButton.getDrawable(), 51139f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague getResources().getDrawable(resId)); 51239f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mShutterButton.setImageDrawable(transitionDrawable); 51339f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague transitionDrawable.startTransition(CIRCLE_ANIM_DURATION_MS); 51439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 51539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 51639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague /** 51739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague * Animates bar to full width / length with video capture icon 51839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague */ 51939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague public void animateToFullSize(int resId) { 520d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague if (mDrawCircle && mAnimatedCircleDrawable != null) { 521d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mAnimatedCircleDrawable.animateToFullSize(); 522d9516f276cd45f87edc7eafe6aa476eeab7c29e7Spike Sprague mDrawCircle = false; 52345a821d43ae8d7287b649f670a66ab3d99eeccafSpike Sprague } 52439f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague 52539f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague TransitionDrawable transitionDrawable = crossfadeDrawable( 52639f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mShutterButton.getDrawable(), 52739f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague getResources().getDrawable(resId)); 52839f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague mShutterButton.setImageDrawable(transitionDrawable); 52939f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague transitionDrawable.startTransition(CIRCLE_ANIM_DURATION_MS); 53039f8a7647aa4051a1c260b9496c2db82f93f8667Spike Sprague } 5310744e4ab3ec5f0270bdad33e7c477f52ba680bbdMarco Nelissen} 532