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.util.AttributeSet; 21 import android.util.SparseArray; 22 import android.view.View; 23 import android.widget.ImageButton; 24 25 import com.android.camera.app.CameraAppUI; 26 import com.android.camera.debug.Log; 27 import com.android.camera2.R; 28 29 /** 30 * This is a custom image button that launches an external viewer. It changes its 31 * image resource based on the current viewer type (photosphere, refocus, etc). 32 * Also, it tracks whether it is shown by tracking the visibility change of all 33 * its ancestors, and keep the visibility of the clings that are registered to the 34 * button in sync. 35 */ 36 public class ExternalViewerButton extends ImageButton { 37 private static final Log.Tag TAG = new Log.Tag("ExtViewerButton"); 38 private int mState = CameraAppUI.BottomPanel.VIEWER_NONE; 39 private final SparseArray<Cling> mClingMap; 40 ExternalViewerButton(Context context, AttributeSet attrs)41 public ExternalViewerButton(Context context, AttributeSet attrs) { 42 super(context, attrs); 43 mClingMap = new SparseArray<Cling>(); 44 updateClingVisibility(); 45 } 46 47 @Override onVisibilityChanged(View v, int visibility)48 protected void onVisibilityChanged(View v, int visibility) { 49 super.onVisibilityChanged(v, visibility); 50 if (mClingMap == null) { 51 return; 52 } 53 updateClingVisibility(); 54 } 55 56 /** 57 * Sets cling of the given viewer type for external viewer button. 58 */ setClingForViewer(int viewerType, Cling cling)59 public void setClingForViewer(int viewerType, Cling cling) { 60 if (cling == null) { 61 Log.w(TAG, "Cannot set a null cling for viewer"); 62 return; 63 } 64 mClingMap.put(viewerType, cling); 65 cling.setReferenceView(this); 66 } 67 68 /** 69 * Clears cling of the given viewer type for external viewer button. 70 */ clearClingForViewer(int viewerType)71 public void clearClingForViewer(int viewerType) { 72 Cling cling = mClingMap.get(viewerType); 73 if (cling == null) { 74 Log.w(TAG, "Cling does not exist for the given viewer type: " + viewerType); 75 } 76 cling.setReferenceView(null); 77 mClingMap.remove(viewerType); 78 } 79 80 /** 81 * Returns a cling for the specified viewer type. 82 */ getClingForViewer(int viewerType)83 public Cling getClingForViewer(int viewerType) { 84 return mClingMap.get(viewerType); 85 } 86 87 /** 88 * Sets the current state of the button, which affects the visibility and image 89 * resource of the button. 90 */ setState(int state)91 public void setState(int state) { 92 mState = state; 93 int newVisibility; 94 if (state == CameraAppUI.BottomPanel.VIEWER_NONE) { 95 newVisibility = View.GONE; 96 } else { 97 setImageResource(getViewButtonResource(state)); 98 newVisibility = View.VISIBLE; 99 } 100 101 if (newVisibility != getVisibility()) { 102 setVisibility(newVisibility); 103 } else if (newVisibility == View.VISIBLE){ 104 // If visibility has changed, cling visibility was updated already, 105 // so only need to update it when visibility has not changed. 106 updateClingVisibility(); 107 } 108 } 109 110 /** 111 * Sets all the clings to be invisible. 112 */ hideClings()113 public void hideClings() { 114 for (int i = 0; i < mClingMap.size(); i++) { 115 mClingMap.valueAt(i).setVisibility(View.INVISIBLE); 116 } 117 } 118 119 /** 120 * Gets the image resource for a specific state. 121 */ getViewButtonResource(int state)122 private int getViewButtonResource(int state) { 123 switch (state) { 124 case CameraAppUI.BottomPanel.VIEWER_REFOCUS: 125 return R.drawable.ic_refocus_normal; 126 case CameraAppUI.BottomPanel.VIEWER_PHOTO_SPHERE: 127 return R.drawable.ic_view_photosphere; 128 default: 129 return R.drawable.ic_control_play; 130 } 131 } 132 133 /** 134 * Updates the visibility of clings based on whether the button is currently 135 * shown. 136 */ updateClingVisibility()137 public void updateClingVisibility() { 138 hideClings(); 139 if (isShown()) { 140 Cling cling = mClingMap.get(mState); 141 if (cling != null) { 142 cling.adjustPosition(); 143 cling.setVisibility(View.VISIBLE); 144 } 145 } 146 } 147 } 148