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 17package com.android.camera.app; 18 19import android.animation.Animator; 20import android.animation.AnimatorListenerAdapter; 21import android.animation.ObjectAnimator; 22import android.view.View; 23import android.view.View.OnClickListener; 24import android.view.ViewGroup; 25import android.widget.ImageButton; 26import android.widget.ProgressBar; 27import android.widget.TextView; 28 29import com.android.camera.util.Gusterpolator; 30import com.android.camera.widget.Cling; 31import com.android.camera.widget.ExternalViewerButton; 32import com.android.camera2.R; 33 34/** 35 * Shows controls at the bottom of the screen for editing, viewing a photo 36 * sphere image and creating a tiny planet from a photo sphere image. 37 */ 38class FilmstripBottomPanel implements CameraAppUI.BottomPanel { 39 private static final int ANIM_DURATION = 150; 40 41 private final AppController mController; 42 private final ViewGroup mLayout; 43 private Listener mListener; 44 private final View mControlLayout; 45 private ImageButton mEditButton; 46 private ExternalViewerButton mViewButton; 47 private ImageButton mDeleteButton; 48 private ImageButton mShareButton; 49 private final View mMiddleFiller; 50 private View mProgressLayout; 51 private TextView mProgressText; 52 private View mProgressErrorLayout; 53 private TextView mProgressErrorText; 54 private ProgressBar mProgressBar; 55 private boolean mTinyPlanetEnabled; 56 57 public FilmstripBottomPanel(AppController controller, ViewGroup bottomControlsLayout) { 58 mController = controller; 59 mLayout = bottomControlsLayout; 60 mMiddleFiller = mLayout.findViewById(R.id.filmstrip_bottom_control_middle_filler); 61 mControlLayout = mLayout.findViewById(R.id.bottom_control_panel); 62 setupEditButton(); 63 setupViewButton(); 64 setupDeleteButton(); 65 setupShareButton(); 66 setupProgressUi(); 67 } 68 69 @Override 70 public void setListener(Listener listener) { 71 mListener = listener; 72 } 73 74 @Override 75 public void setClingForViewer(int viewerType, Cling cling) { 76 mViewButton.setClingForViewer(viewerType, cling); 77 } 78 79 @Override 80 public void clearClingForViewer(int viewerType) { 81 mViewButton.clearClingForViewer(viewerType); 82 } 83 84 @Override 85 public Cling getClingForViewer(int viewerType) { 86 return mViewButton.getClingForViewer(viewerType); 87 } 88 89 @Override 90 public void setVisible(boolean visible) { 91 if (visible) { 92 mLayout.setVisibility(View.VISIBLE); 93 } else { 94 mLayout.setVisibility(View.INVISIBLE); 95 } 96 } 97 98 @Override 99 public void setEditButtonVisibility(boolean visible) { 100 mEditButton.setVisibility(visible ? View.VISIBLE : View.GONE); 101 updateMiddleFillerLayoutVisibility(); 102 } 103 104 @Override 105 public void setEditEnabled(boolean enabled) { 106 mEditButton.setEnabled(enabled); 107 } 108 109 @Override 110 public void setViewerButtonVisibility(int state) { 111 mViewButton.setState(state); 112 updateMiddleFillerLayoutVisibility(); 113 } 114 115 @Override 116 public void setViewEnabled(boolean enabled) { 117 mViewButton.setEnabled(enabled); 118 } 119 120 @Override 121 public void setTinyPlanetEnabled(boolean enabled) { 122 mTinyPlanetEnabled = enabled; 123 } 124 125 @Override 126 public void setDeleteButtonVisibility(boolean visible) { 127 mDeleteButton.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); 128 } 129 130 @Override 131 public void setDeleteEnabled(boolean enabled) { 132 mDeleteButton.setEnabled(enabled); 133 } 134 135 @Override 136 public void setShareButtonVisibility(boolean visible) { 137 mShareButton.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); 138 } 139 140 @Override 141 public void setShareEnabled(boolean enabled) { 142 mShareButton.setEnabled(enabled); 143 } 144 145 @Override 146 public void setProgressText(CharSequence text) { 147 mProgressText.setText(text); 148 } 149 150 @Override 151 public void setProgress(int progress) { 152 mProgressBar.setProgress(progress); 153 } 154 155 @Override 156 public void showProgressError(CharSequence message) { 157 hideControls(); 158 hideProgress(); 159 mProgressErrorLayout.setVisibility(View.VISIBLE); 160 mProgressErrorText.setText(message); 161 } 162 163 @Override 164 public void hideProgressError() { 165 mProgressErrorLayout.setVisibility(View.INVISIBLE); 166 } 167 168 @Override 169 public void showProgress() { 170 mProgressLayout.setVisibility(View.VISIBLE); 171 hideProgressError(); 172 } 173 174 @Override 175 public void hideProgress() { 176 mProgressLayout.setVisibility(View.INVISIBLE); 177 } 178 179 @Override 180 public void showControls() { 181 mControlLayout.setVisibility(View.VISIBLE); 182 } 183 184 @Override 185 public void hideControls() { 186 mControlLayout.setVisibility(View.INVISIBLE); 187 } 188 189 private void setupEditButton() { 190 mEditButton = (ImageButton) mLayout.findViewById(R.id.filmstrip_bottom_control_edit); 191 mEditButton.setOnClickListener(new View.OnClickListener() { 192 @Override 193 public void onClick(View view) { 194 if (mTinyPlanetEnabled) { 195 mController.openContextMenu(mEditButton); 196 } else if (mListener != null) { 197 mListener.onEdit(); 198 } 199 } 200 }); 201 mController.registerForContextMenu(mEditButton); 202 mEditButton.setLongClickable(false); 203 } 204 205 private void setupViewButton() { 206 mViewButton = (ExternalViewerButton) mLayout.findViewById( 207 R.id.filmstrip_bottom_control_view); 208 mViewButton.setOnClickListener(new View.OnClickListener() { 209 @Override 210 public void onClick(View view) { 211 if (mListener != null) { 212 mListener.onExternalViewer(); 213 } 214 } 215 }); 216 } 217 218 private void setupDeleteButton() { 219 mDeleteButton = (ImageButton) mLayout.findViewById(R.id.filmstrip_bottom_control_delete); 220 mDeleteButton.setOnClickListener(new View.OnClickListener() { 221 @Override 222 public void onClick(View view) { 223 if (mListener != null) { 224 mListener.onDelete(); 225 } 226 } 227 }); 228 } 229 230 private void setupShareButton() { 231 mShareButton = (ImageButton) mLayout.findViewById(R.id.filmstrip_bottom_control_share); 232 mShareButton.setOnClickListener(new View.OnClickListener() { 233 @Override 234 public void onClick(View view) { 235 if (mListener != null) { 236 mListener.onShare(); 237 } 238 } 239 }); 240 } 241 242 private void setupProgressUi() { 243 mProgressLayout = mLayout.findViewById(R.id.bottom_progress_panel); 244 mProgressText = (TextView) mLayout.findViewById(R.id.bottom_session_progress_text); 245 mProgressBar = (ProgressBar) mLayout.findViewById(R.id.bottom_session_progress_bar); 246 mProgressBar.setMax(100); 247 mProgressLayout.setVisibility(View.INVISIBLE); 248 mProgressErrorText = (TextView) mLayout.findViewById(R.id.bottom_progress_error_text); 249 mProgressErrorLayout = mLayout.findViewById(R.id.bottom_progress_error_panel); 250 mProgressErrorLayout.setOnClickListener(new OnClickListener() { 251 @Override 252 public void onClick(View v) { 253 if (mListener != null) { 254 mListener.onProgressErrorClicked(); 255 } 256 } 257 }); 258 } 259 260 /** 261 * Updates the visibility of the middle filler view in the center. The 262 * middle filler view should be visible when edit button and viewer buttons 263 * are both visible. 264 */ 265 private void updateMiddleFillerLayoutVisibility() { 266 if (mEditButton.getVisibility() == View.VISIBLE && 267 mViewButton.getVisibility() == View.VISIBLE) { 268 mMiddleFiller.setVisibility(View.INVISIBLE); 269 } else { 270 mMiddleFiller.setVisibility(View.GONE); 271 } 272 } 273 274 public void show() { 275 ObjectAnimator animator = ObjectAnimator 276 .ofFloat(mLayout, "translationY", mLayout.getHeight(), 0.0f); 277 animator.setDuration(ANIM_DURATION); 278 animator.setInterpolator(Gusterpolator.INSTANCE); 279 animator.addListener(new AnimatorListenerAdapter() { 280 @Override 281 public void onAnimationEnd(Animator animation) { 282 mViewButton.updateClingVisibility(); 283 } 284 }); 285 mViewButton.hideClings(); 286 animator.start(); 287 } 288 289 public void hide() { 290 int offset = mLayout.getHeight(); 291 if (mLayout.getTranslationY() < offset) { 292 ObjectAnimator animator = ObjectAnimator 293 .ofFloat(mLayout, "translationY", mLayout.getTranslationY(), offset); 294 animator.setDuration(ANIM_DURATION); 295 animator.setInterpolator(Gusterpolator.INSTANCE); 296 mViewButton.hideClings(); 297 animator.start(); 298 } 299 } 300} 301