2 * Copyright (C) 2012 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.gallery3d.filtershow;
19 import android.annotation.TargetApi;
20 import android.content.Context;
21 import android.text.Html;
22 import android.view.View;
23 import android.view.View.OnClickListener;
24 import android.view.ViewPropertyAnimator;
25 import android.widget.LinearLayout;
26 import android.widget.TextView;
28 import com.android.gallery3d.R;
29 import com.android.gallery3d.filtershow.editors.Editor;
30 import com.android.gallery3d.filtershow.filters.FilterRepresentation;
31 import com.android.gallery3d.filtershow.filters.ImageFilter;
32 import com.android.gallery3d.filtershow.filters.ImageFilterTinyPlanet;
33 import com.android.gallery3d.filtershow.imageshow.ImageCrop;
34 import com.android.gallery3d.filtershow.imageshow.ImageShow;
35 import com.android.gallery3d.filtershow.imageshow.MasterImage;
36 import com.android.gallery3d.filtershow.presets.ImagePreset;
37 import com.android.gallery3d.filtershow.ui.FilterIconButton;
39 import java.util.HashMap;
40 import java.util.Vector;
42 public class PanelController implements OnClickListener {
43 private static int PANEL = 0;
44 private static int COMPONENT = 1;
45 private static int VERTICAL_MOVE = 0;
46 private static int HORIZONTAL_MOVE = 1;
47 private static final int ANIM_DURATION = 200;
48 private static final String LOGTAG = "PanelController";
49 private boolean mDisableFilterButtons = false;
50 private boolean mFixedAspect = false;
52 public static boolean useAnimations() {
53 int currentapiVersion = android.os.Build.VERSION.SDK_INT;
54 if (currentapiVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
60 public void setFixedAspect(boolean t) {
65 private final View mView;
66 private final View mContainer;
67 private int mPosition = 0;
68 private final Vector<View> mSubviews = new Vector<View>();
70 public Panel(View view, View container, int position) {
72 mContainer = container;
76 public void addView(View view) {
80 public int getPosition() {
84 public ViewPropertyAnimator unselect(int newPos, int move) {
85 ViewPropertyAnimator anim = mContainer.animate();
86 mView.setSelected(false);
90 int w = mRowPanel.getWidth();
91 int h = mRowPanel.getHeight();
92 if (move == HORIZONTAL_MOVE) {
93 if (newPos > mPosition) {
98 if (PanelController.useAnimations()) {
101 mContainer.setX(delta);
103 } else if (move == VERTICAL_MOVE) {
104 if (PanelController.useAnimations()) {
110 if (PanelController.useAnimations()) {
111 anim.setDuration(ANIM_DURATION).withLayer().withEndAction(new Runnable() {
114 mContainer.setVisibility(View.GONE);
118 mContainer.setVisibility(View.GONE);
123 public ViewPropertyAnimator select(int oldPos, int move) {
124 mView.setSelected(true);
125 mContainer.setVisibility(View.VISIBLE);
128 ViewPropertyAnimator anim = mContainer.animate();
129 int w = mRowPanel.getWidth();
130 int h = mRowPanel.getHeight();
131 if (useAnimations()) {
132 if (move == HORIZONTAL_MOVE) {
133 if (oldPos < mPosition) {
139 } else if (move == VERTICAL_MOVE) {
143 anim.setDuration(ANIM_DURATION).withLayer();
150 private final Context mContext;
151 private final View mView;
152 private final LinearLayout mAccessoryViewList;
153 private Vector<View> mAccessoryViews = new Vector<View>();
154 private final TextView mTextView;
155 private boolean mSelected = false;
156 private String mEffectName = null;
157 private int mParameterValue = 0;
158 private boolean mShowParameterValue = false;
159 boolean firstTimeCropDisplayed = true;
161 public UtilityPanel(Context context, View view, View accessoryViewList,
165 mAccessoryViewList = (LinearLayout) accessoryViewList;
166 mTextView = (TextView) textView;
169 public boolean selected() {
173 public void hideAccessoryViews() {
174 int childCount = mAccessoryViewList.getChildCount();
175 for (int i = 0; i < childCount; i++) {
176 View child = mAccessoryViewList.getChildAt(i);
177 child.setVisibility(View.GONE);
181 public void onNewValue(int value) {
182 mParameterValue = value;
186 public void setEffectName(String effectName) {
187 mEffectName = effectName;
188 setShowParameter(true);
191 public void setShowParameter(boolean s) {
192 mShowParameterValue = s;
196 public void updateText() {
197 String apply = mContext.getString(R.string.apply_effect);
198 if (mShowParameterValue) {
199 mTextView.setText(Html.fromHtml(apply + " " + mEffectName + " "
202 mTextView.setText(Html.fromHtml(apply + " " + mEffectName));
206 public ViewPropertyAnimator unselect() {
207 ViewPropertyAnimator anim = mView.animate();
210 int h = mRowPanel.getHeight();
212 if (PanelController.useAnimations()) {
213 anim.setDuration(ANIM_DURATION).withLayer().withEndAction(new Runnable() {
216 mView.setVisibility(View.GONE);
220 mView.setVisibility(View.GONE);
226 public ViewPropertyAnimator select() {
227 mView.setVisibility(View.VISIBLE);
228 int h = mRowPanel.getHeight();
233 ViewPropertyAnimator anim = mView.animate();
235 anim.setDuration(ANIM_DURATION);
236 if (PanelController.useAnimations()) {
245 private final int mType;
246 private final View mView;
248 public ViewType(View view, int type) {
258 private final HashMap<View, Panel> mPanels = new HashMap<View, Panel>();
259 private final HashMap<View, ViewType> mViews = new HashMap<View, ViewType>();
260 private final HashMap<String, ImageFilter> mFilters = new HashMap<String, ImageFilter>();
261 private final Vector<View> mImageViews = new Vector<View>();
262 private View mCurrentPanel = null;
263 private View mRowPanel = null;
264 private UtilityPanel mUtilityPanel = null;
265 private ImageShow mCurrentImage = null;
266 private Editor mCurrentEditor = null;
267 private FilterShowActivity mActivity = null;
268 private EditorPlaceHolder mEditorPlaceHolder = null;
270 public void setActivity(FilterShowActivity activity) {
271 mActivity = activity;
274 public void addView(View view) {
275 view.setOnClickListener(this);
276 mViews.put(view, new ViewType(view, COMPONENT));
279 public void addPanel(View view, View container, int position) {
280 mPanels.put(view, new Panel(view, container, position));
281 view.setOnClickListener(this);
282 mViews.put(view, new ViewType(view, PANEL));
285 public void addComponent(View aPanel, View component) {
286 Panel panel = mPanels.get(aPanel);
290 panel.addView(component);
291 component.setOnClickListener(this);
292 mViews.put(component, new ViewType(component, COMPONENT));
295 public void addFilter(ImageFilter filter) {
296 mFilters.put(filter.getName(), filter);
299 public void addImageView(View view) {
300 mImageViews.add(view);
301 ImageShow imageShow = (ImageShow) view;
302 imageShow.setPanelController(this);
305 public void resetParameters() {
306 showPanel(mCurrentPanel);
307 if (mCurrentImage != null) {
308 mCurrentImage.resetParameter();
309 mCurrentImage.select();
310 if (mCurrentEditor != null) {
311 mCurrentEditor.reflectCurrentFilter();
315 if (mDisableFilterButtons) {
316 mActivity.enableFilterButtons();
317 mDisableFilterButtons = false;
321 public boolean onBackPressed() {
322 if (mUtilityPanel == null || !mUtilityPanel.selected()) {
325 HistoryAdapter adapter = MasterImage.getImage().getHistory();
326 int position = adapter.undo();
327 MasterImage.getImage().onHistoryItemClick(position);
328 showPanel(mCurrentPanel);
329 mCurrentImage.select();
330 if (mCurrentEditor != null) {
331 mCurrentEditor.reflectCurrentFilter();
334 if (mDisableFilterButtons) {
335 mActivity.enableFilterButtons();
336 mActivity.resetHistory();
337 mDisableFilterButtons = false;
342 public void onNewValue(int value) {
343 mUtilityPanel.onNewValue(value);
346 public void showParameter(boolean s) {
347 mUtilityPanel.setShowParameter(s);
350 public void setCurrentPanel(View panel) {
354 public void setRowPanel(View rowPanel) {
355 mRowPanel = rowPanel;
358 public void setUtilityPanel(Context context, View utilityPanel,
359 View accessoryViewList, View textView) {
360 mUtilityPanel = new UtilityPanel(context, utilityPanel,
361 accessoryViewList, textView);
365 public void onClick(View view) {
366 ViewType type = mViews.get(view);
367 if (type.type() == PANEL) {
369 } else if (type.type() == COMPONENT) {
374 public ImageShow showImageView(int id) {
375 ImageShow image = null;
376 mActivity.hideImageViews();
377 for (View view : mImageViews) {
378 if (view.getId() == id) {
379 view.setVisibility(View.VISIBLE);
380 image = (ImageShow) view;
382 view.setVisibility(View.GONE);
388 public void showDefaultImageView() {
389 showImageView(R.id.imageShow);
390 MasterImage.getImage().setCurrentFilter(null);
391 MasterImage.getImage().setCurrentFilterRepresentation(null);
394 public void showPanel(View view) {
395 view.setVisibility(View.VISIBLE);
396 boolean removedUtilityPanel = false;
397 Panel current = mPanels.get(mCurrentPanel);
398 if (mUtilityPanel != null && mUtilityPanel.selected()) {
399 ViewPropertyAnimator anim1 = mUtilityPanel.unselect();
400 removedUtilityPanel = true;
404 if (mCurrentPanel == view) {
405 ViewPropertyAnimator anim2 = current.select(-1, VERTICAL_MOVE);
409 showDefaultImageView();
413 if (mCurrentPanel == view) {
417 Panel panel = mPanels.get(view);
418 if (!removedUtilityPanel) {
420 if (current != null) {
421 currentPos = current.getPosition();
423 ViewPropertyAnimator anim1 = panel.select(currentPos, HORIZONTAL_MOVE);
427 if (current != null) {
428 ViewPropertyAnimator anim2 = current.unselect(panel.getPosition(), HORIZONTAL_MOVE);
434 ViewPropertyAnimator anim = panel.select(-1, VERTICAL_MOVE);
440 showDefaultImageView();
441 mCurrentPanel = view;
444 public ImagePreset getImagePreset() {
445 return MasterImage.getImage().getPreset();
448 public void useFilterRepresentation(FilterRepresentation filterRepresentation) {
449 if (filterRepresentation == null) {
452 if (MasterImage.getImage().getCurrentFilterRepresentation() == filterRepresentation) {
455 ImagePreset oldPreset = MasterImage.getImage().getPreset();
456 ImagePreset copy = new ImagePreset(oldPreset);
457 FilterRepresentation representation = copy.getRepresentation(filterRepresentation);
458 if (representation == null) {
459 copy.addFilter(filterRepresentation);
461 if (filterRepresentation.allowsMultipleInstances()) {
462 representation.updateTempParametersFrom(filterRepresentation);
463 copy.setHistoryName(filterRepresentation.getName());
465 filterRepresentation = representation;
467 MasterImage.getImage().setPreset(copy, true);
468 MasterImage.getImage().setCurrentFilterRepresentation(filterRepresentation);
471 public void showComponent(View view) {
473 boolean doPanelTransition = true;
474 if (view instanceof FilterIconButton) {
475 FilterRepresentation f = ((FilterIconButton) view).getFilterRepresentation();
477 // FIXME: this check shouldn't be necessary (f shouldn't be null)
478 doPanelTransition = f.showUtilityPanel();
482 if (mUtilityPanel != null && !mUtilityPanel.selected() && doPanelTransition) {
483 Panel current = mPanels.get(mCurrentPanel);
484 ViewPropertyAnimator anim1 = current.unselect(-1, VERTICAL_MOVE);
488 if (mUtilityPanel != null) {
489 ViewPropertyAnimator anim2 = mUtilityPanel.select();
496 if (mCurrentImage != null) {
497 mCurrentImage.unselect();
499 mUtilityPanel.hideAccessoryViews();
501 if (view instanceof FilterIconButton) {
502 mCurrentEditor = null;
503 FilterIconButton component = (FilterIconButton) view;
504 FilterRepresentation representation = component.getFilterRepresentation();
505 if (representation != null) {
506 mUtilityPanel.setEffectName(representation.getName());
507 mUtilityPanel.setShowParameter(representation.showParameterValue());
509 if (representation.getEditorId() != 0) {
510 if (mEditorPlaceHolder.contains(representation.getEditorId())) {
511 mCurrentEditor = mEditorPlaceHolder.showEditor(representation.getEditorId());
512 mCurrentImage = mCurrentEditor.getImageShow();
513 mCurrentEditor.setPanelController(this);
515 mCurrentImage = showImageView(representation.getEditorId());
518 mUtilityPanel.setShowParameter(representation.showParameterValue());
520 mCurrentImage.select();
521 if (mCurrentEditor != null) {
522 mCurrentEditor.reflectCurrentFilter();
523 if (mCurrentEditor.useUtilityPanel()) {
524 mCurrentEditor.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
526 } else if (mCurrentImage.useUtilityPanel()) {
527 mCurrentImage.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
533 switch (view.getId()) {
534 case R.id.tinyplanetButton: {
535 mCurrentImage = showImageView(R.id.imageTinyPlanet);
536 String ename = mCurrentImage.getContext().getString(R.string.tinyplanet);
537 mUtilityPanel.setEffectName(ename);
538 if (!mDisableFilterButtons) {
539 mActivity.disableFilterButtons();
540 mDisableFilterButtons = true;
544 case R.id.straightenButton: {
545 mCurrentImage = showImageView(R.id.imageStraighten);
546 String ename = mCurrentImage.getContext().getString(R.string.straighten);
547 mUtilityPanel.setEffectName(ename);
550 case R.id.cropButton: {
551 mCurrentImage = showImageView(R.id.imageCrop);
552 String ename = mCurrentImage.getContext().getString(R.string.crop);
553 mUtilityPanel.setEffectName(ename);
554 mUtilityPanel.setShowParameter(false);
555 if (mCurrentImage instanceof ImageCrop && mUtilityPanel.firstTimeCropDisplayed) {
556 ((ImageCrop) mCurrentImage).clear();
557 mUtilityPanel.firstTimeCropDisplayed = false;
559 ((ImageCrop) mCurrentImage).setFixedAspect(mFixedAspect);
562 case R.id.rotateButton: {
563 mCurrentImage = showImageView(R.id.imageRotate);
564 String ename = mCurrentImage.getContext().getString(R.string.rotate);
565 mUtilityPanel.setEffectName(ename);
568 case R.id.flipButton: {
569 mCurrentImage = showImageView(R.id.imageFlip);
570 String ename = mCurrentImage.getContext().getString(R.string.mirror);
571 mUtilityPanel.setEffectName(ename);
572 mUtilityPanel.setShowParameter(false);
575 case R.id.applyEffect: {
576 if (MasterImage.getImage().getCurrentFilter() instanceof ImageFilterTinyPlanet) {
577 mActivity.saveImage();
579 if (mCurrentImage instanceof ImageCrop) {
580 ((ImageCrop) mCurrentImage).saveAndSetPreset();
582 showPanel(mCurrentPanel);
584 MasterImage.getImage().invalidateFiltersOnly();
588 mCurrentImage.select();
589 if (mCurrentEditor != null) {
590 mCurrentEditor.reflectCurrentFilter();
591 if (mCurrentEditor.useUtilityPanel()) {
592 mCurrentEditor.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
594 } else if (mCurrentImage.useUtilityPanel()) {
595 mCurrentImage.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
600 public void setEditorPlaceHolder(EditorPlaceHolder editorPlaceHolder) {
601 mEditorPlaceHolder = editorPlaceHolder;