blob: 2cd70e3aa8a299d75e270b0b70faea2642902d40 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.gallery3d.filtershow;
import android.content.Context;
import android.os.Handler;
import android.text.Html;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewPropertyAnimator;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.util.Log;
import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.editors.Editor;
import com.android.gallery3d.filtershow.editors.EditorTinyPlanet;
import com.android.gallery3d.filtershow.editors.ImageOnlyEditor;
import com.android.gallery3d.filtershow.filters.FilterRepresentation;
import com.android.gallery3d.filtershow.filters.ImageFilter;
import com.android.gallery3d.filtershow.filters.ImageFilterTinyPlanet;
import com.android.gallery3d.filtershow.imageshow.ImageShow;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
import com.android.gallery3d.filtershow.presets.ImagePreset;
import com.android.gallery3d.filtershow.ui.FilterIconButton;
import java.util.HashMap;
import java.util.Set;
import java.util.Vector;
public class PanelController implements OnClickListener {
private static int PANEL = 0;
private static int COMPONENT = 1;
private static int VERTICAL_MOVE = 0;
private static int HORIZONTAL_MOVE = 1;
private static final int ANIM_DURATION = 200;
private static final String LOGTAG = "PanelController";
private boolean mFixedAspect = false;
final Handler mHandler = new Handler();
public static boolean useAnimationsLayer() {
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
return true;
}
return false;
}
public void setFixedAspect(boolean t) {
mFixedAspect = t;
}
class Panel {
private final View mView;
private final View mContainer;
private int mPosition = 0;
private final Vector<View> mSubviews = new Vector<View>();
public Panel(View view, View container, int position) {
mView = view;
mContainer = container;
mPosition = position;
}
public void addView(View view) {
mSubviews.add(view);
}
public int getPosition() {
return mPosition;
}
public ViewPropertyAnimator unselect(int newPos, int move) {
ViewPropertyAnimator anim = mContainer.animate();
mView.setSelected(false);
mContainer.setX(0);
mContainer.setY(0);
int delta = 0;
int w = mRowPanel.getWidth();
int h = mRowPanel.getHeight();
if (move == HORIZONTAL_MOVE) {
if (newPos > mPosition) {
delta = -w;
} else {
delta = w;
}
anim.x(delta);
} else if (move == VERTICAL_MOVE) {
anim.y(h);
}
anim.setDuration(ANIM_DURATION);
Runnable action = new Runnable() {
@Override
public void run() {
mContainer.setVisibility(View.GONE);
}
};
if (PanelController.useAnimationsLayer()) {
anim.withLayer().withEndAction(action);
} else {
mHandler.postDelayed(action, ANIM_DURATION);
}
return anim;
}
public ViewPropertyAnimator select(int oldPos, int move) {
mView.setSelected(true);
mContainer.setVisibility(View.VISIBLE);
mContainer.setX(0);
mContainer.setY(0);
ViewPropertyAnimator anim = mContainer.animate();
int w = mRowPanel.getWidth();
int h = mRowPanel.getHeight();
if (move == HORIZONTAL_MOVE) {
if (oldPos < mPosition) {
mContainer.setX(w);
} else {
mContainer.setX(-w);
}
anim.x(0);
} else if (move == VERTICAL_MOVE) {
mContainer.setY(h);
anim.y(0);
}
anim.setDuration(ANIM_DURATION);
if (PanelController.useAnimationsLayer()) {
anim.withLayer();
}
return anim;
}
}
class UtilityPanel {
private final Context mContext;
private final View mView;
private final LinearLayout mAccessoryViewList;
private Vector<View> mAccessoryViews = new Vector<View>();
private final Button mTextView;
private boolean mSelected = false;
private String mEffectName = null;
private int mParameterValue = 0;
private boolean mShowParameterValue = false;
public UtilityPanel(Context context, View utilityPanel) {
mView = utilityPanel;
View accessoryViewList = mView.findViewById(R.id.panelAccessoryViewList);
mTextView = (Button) mView.findViewById(R.id.applyEffect);
mContext = context;
mAccessoryViewList = (LinearLayout) accessoryViewList;
}
public boolean selected() {
return mSelected;
}
public void hideAccessoryViews() {
int childCount = mAccessoryViewList.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = mAccessoryViewList.getChildAt(i);
child.setVisibility(View.GONE);
}
}
public void onNewValue(int value) {
mParameterValue = value;
updateText();
}
public void setEffectName(String effectName) {
mEffectName = effectName;
setShowParameter(true);
}
public void setShowParameter(boolean s) {
mShowParameterValue = s;
updateText();
}
public void showMenu(boolean show) {
mTextView.setOnClickListener(null);
if (show){
mAccessoryViewList.setVisibility(View.VISIBLE);
mTextView.setVisibility(View.VISIBLE);
} else {
mAccessoryViewList.setVisibility(View.VISIBLE);
mTextView.setVisibility(View.VISIBLE);
}
}
public View getActionControl() {
return mView.findViewById(R.id.panelAccessoryViewList);
}
public View getEditControl() {
return mView.findViewById(R.id.controlArea);
}
public void removeControlChildren() {
LinearLayout controlArea = (LinearLayout) mView.findViewById(R.id.controlArea);
controlArea.removeAllViews();
}
public Button getEditTitle() {
return mTextView;
}
public void updateText() {
String s;
if (mCurrentEditor == null) {
String apply = mContext.getString(R.string.apply_effect);
s = apply + " " + mEffectName + " " + mParameterValue;
} else {
s = mCurrentEditor.calculateUserMessage(mContext, mEffectName, mParameterValue);
}
mTextView.setText(Html.fromHtml(s));
}
public ViewPropertyAnimator unselect() {
ViewPropertyAnimator anim = mView.animate();
mView.setX(0);
mView.setY(0);
int h = mRowPanel.getHeight();
anim.y(-h);
Runnable action = new Runnable() {
@Override
public void run() {
mView.setVisibility(View.GONE);
}
};
if (PanelController.useAnimationsLayer()) {
anim.setDuration(ANIM_DURATION).withLayer().withEndAction(action);
} else {
mHandler.postDelayed(action, ANIM_DURATION);
}
mSelected = false;
return anim;
}
public ViewPropertyAnimator select() {
mView.setVisibility(View.VISIBLE);
int h = mRowPanel.getHeight();
mView.setX(0);
mView.setY(-h);
updateText();
mSelected = true;
ViewPropertyAnimator anim = mView.animate();
anim.y(0);
anim.setDuration(ANIM_DURATION);
if (PanelController.useAnimationsLayer()) {
anim.withLayer();
}
return anim;
}
}
class ViewType {
private final int mType;
private final View mView;
public ViewType(View view, int type) {
mView = view;
mType = type;
}
public int type() {
return mType;
}
}
private final HashMap<View, Panel> mPanels = new HashMap<View, Panel>();
private final HashMap<View, ViewType> mViews = new HashMap<View, ViewType>();
private final HashMap<String, ImageFilter> mFilters = new HashMap<String, ImageFilter>();
private final Vector<View> mImageViews = new Vector<View>();
private View mCurrentPanel = null;
private View mRowPanel = null;
private UtilityPanel mUtilityPanel = null;
private ImageShow mCurrentImage = null;
private Editor mCurrentEditor = null;
private FilterShowActivity mActivity = null;
private EditorPlaceHolder mEditorPlaceHolder = null;
public void clear() {
mPanels.clear();
mViews.clear();
mFilters.clear();
mImageViews.clear();
}
public void setActivity(FilterShowActivity activity) {
mActivity = activity;
}
public void addView(View view) {
view.setOnClickListener(this);
mViews.put(view, new ViewType(view, COMPONENT));
}
public View getViewFromId(int viewId) {
for (View view : mPanels.keySet()) {
if (view.getId() == viewId) {
return view;
}
}
return null;
}
public void addPanel(int viewId, int containerId, int position) {
View view = mActivity.findViewById(viewId);
View container = mActivity.findViewById(containerId);
mPanels.put(view, new Panel(view, container, position));
view.setOnClickListener(this);
mViews.put(view, new ViewType(view, PANEL));
}
public void addComponent(View aPanel, View component) {
Panel panel = mPanels.get(aPanel);
if (panel == null) {
return;
}
panel.addView(component);
component.setOnClickListener(this);
mViews.put(component, new ViewType(component, COMPONENT));
}
public void addFilter(ImageFilter filter) {
mFilters.put(filter.getName(), filter);
}
public void addImageView(View view) {
mImageViews.add(view);
ImageShow imageShow = (ImageShow) view;
imageShow.setPanelController(this);
}
public void resetParameters() {
showPanel(mCurrentPanel);
if (mCurrentImage != null) {
mCurrentImage.resetParameter();
mCurrentImage.select();
if (mCurrentEditor != null) {
mCurrentEditor.reflectCurrentFilter();
}
}
}
public boolean onBackPressed() {
if (mUtilityPanel == null || !mUtilityPanel.selected()) {
return true;
}
HistoryAdapter adapter = MasterImage.getImage().getHistory();
int position = adapter.undo();
MasterImage.getImage().onHistoryItemClick(position);
mActivity.showCategoryPanel();
showPanel(mCurrentPanel);
mCurrentImage.select();
if (mCurrentEditor != null) {
mCurrentEditor.reflectCurrentFilter();
}
return false;
}
public void onNewValue(int value) {
mUtilityPanel.onNewValue(value);
}
public void showParameter(boolean s) {
mUtilityPanel.setShowParameter(s);
}
public void setCurrentPanel(int panelId) {
showPanel(getViewFromId(panelId));
}
public void setRowPanel(View rowPanel) {
mRowPanel = rowPanel;
}
public void setUtilityPanel(Context context, View utilityPanel) {
addView(utilityPanel.findViewById(R.id.applyEffect));
addView(utilityPanel.findViewById(R.id.applyFilter));
// TODO rename applyFilter to panelFilterDescription
addView(utilityPanel.findViewById(R.id.cancelFilter));
mUtilityPanel = new UtilityPanel(context, utilityPanel);
}
@Override
public void onClick(View view) {
ViewType type = mViews.get(view);
if (type.type() == PANEL) {
showPanel(view);
} else if (type.type() == COMPONENT) {
showComponent(view);
}
}
public ImageShow showImageView(int id) {
ImageShow image = null;
mActivity.hideImageViews();
for (View view : mImageViews) {
image = (ImageShow) view;
if (view.getId() == id) {
view.setVisibility(View.VISIBLE);
image.select();
} else {
view.setVisibility(View.GONE);
image.unselect();
}
}
return image;
}
public void showDefaultImageView() {
showImageView(R.id.imageShow);
MasterImage.getImage().setCurrentFilter(null);
MasterImage.getImage().setCurrentFilterRepresentation(null);
}
public void showPanel(View view) {
view.setVisibility(View.VISIBLE);
boolean removedUtilityPanel = false;
Panel current = mPanels.get(mCurrentPanel);
if (mUtilityPanel != null && mUtilityPanel.selected()) {
ViewPropertyAnimator anim1 = mUtilityPanel.unselect();
removedUtilityPanel = true;
if (anim1 != null) {
anim1.start();
}
if (mCurrentPanel == view) {
ViewPropertyAnimator anim2 = current.select(-1, VERTICAL_MOVE);
if (anim2 != null) {
anim2.start();
}
showDefaultImageView();
}
}
if (mCurrentPanel == view) {
return;
}
Panel panel = mPanels.get(view);
if (!removedUtilityPanel) {
int currentPos = -1;
if (current != null) {
currentPos = current.getPosition();
}
ViewPropertyAnimator anim1 = panel.select(currentPos, HORIZONTAL_MOVE);
if (anim1 != null) {
anim1.start();
}
if (current != null) {
ViewPropertyAnimator anim2 = current.unselect(panel.getPosition(), HORIZONTAL_MOVE);
if (anim2 != null) {
anim2.start();
}
}
} else {
ViewPropertyAnimator anim = panel.select(-1, VERTICAL_MOVE);
if (anim != null) {
anim.start();
}
}
showDefaultImageView();
mCurrentPanel = view;
}
public ImagePreset getImagePreset() {
return MasterImage.getImage().getPreset();
}
public void setEffectName(String ename) {
mUtilityPanel.setEffectName(ename);
}
public void removeFilterRepresentation(FilterRepresentation filterRepresentation) {
if (filterRepresentation == null) {
Log.v(LOGTAG, "RemoveFilterRepresentation: " + filterRepresentation);
return;
}
ImagePreset oldPreset = MasterImage.getImage().getPreset();
ImagePreset copy = new ImagePreset(oldPreset);
copy.removeFilter(filterRepresentation);
MasterImage.getImage().setPreset(copy, true);
if (MasterImage.getImage().getCurrentFilterRepresentation() == filterRepresentation) {
FilterRepresentation lastRepresentation = copy.getLastRepresentation();
MasterImage.getImage().setCurrentFilterRepresentation(lastRepresentation);
}
// Now let's reset the panel
if (mUtilityPanel == null || !mUtilityPanel.selected()) {
return;
}
showPanel(mCurrentPanel);
mCurrentImage.select();
if (mCurrentEditor != null) {
mCurrentEditor.reflectCurrentFilter();
}
}
public void useFilterRepresentation(FilterRepresentation filterRepresentation) {
if (filterRepresentation == null) {
return;
}
if (MasterImage.getImage().getCurrentFilterRepresentation() == filterRepresentation) {
return;
}
ImagePreset oldPreset = MasterImage.getImage().getPreset();
ImagePreset copy = new ImagePreset(oldPreset);
FilterRepresentation representation = copy.getRepresentation(filterRepresentation);
if (representation == null) {
copy.addFilter(filterRepresentation);
} else {
if (filterRepresentation.allowsMultipleInstances()) {
representation.updateTempParametersFrom(filterRepresentation);
copy.setHistoryName(filterRepresentation.getName());
representation.synchronizeRepresentation();
}
filterRepresentation = representation;
}
MasterImage.getImage().setPreset(copy, true);
MasterImage.getImage().setCurrentFilterRepresentation(filterRepresentation);
}
public void showComponentWithRepresentation(FilterRepresentation filterRepresentation) {
if (filterRepresentation == null) {
return;
}
if (filterRepresentation == MasterImage.getImage().getCurrentFilterRepresentation()) {
return;
}
Set<View> views = mViews.keySet();
for (View view : views) {
if (view instanceof FilterIconButton) {
FilterIconButton button = (FilterIconButton) view;
if (button.getFilterRepresentation().getFilterClass() == filterRepresentation.getFilterClass()) {
MasterImage.getImage().setCurrentFilterRepresentation(filterRepresentation);
showComponent(view);
return;
}
}
}
}
public void showComponent(View view) {
boolean doPanelTransition = true;
if (view instanceof FilterIconButton) {
FilterRepresentation f = ((FilterIconButton) view).getFilterRepresentation();
if (f != null) {
// FIXME: this check shouldn't be necessary (f shouldn't be null)
doPanelTransition = f.showUtilityPanel();
}
}
if (mUtilityPanel != null && !mUtilityPanel.selected() && doPanelTransition) {
Panel current = mPanels.get(mCurrentPanel);
ViewPropertyAnimator anim1 = current.unselect(-1, VERTICAL_MOVE);
if (anim1 != null) {
anim1.start();
}
if (mUtilityPanel != null) {
ViewPropertyAnimator anim2 = mUtilityPanel.select();
if (anim2 != null) {
anim2.start();
}
}
}
if (mCurrentImage != null) {
mCurrentImage.unselect();
}
mUtilityPanel.hideAccessoryViews();
mUtilityPanel.showMenu(false);
if (view instanceof FilterIconButton) {
if (mCurrentEditor != null) {
mCurrentEditor.detach();
}
mCurrentEditor = null;
FilterIconButton component = (FilterIconButton) view;
FilterRepresentation representation = component.getFilterRepresentation();
if (representation != null) {
mUtilityPanel.setEffectName(representation.getName());
mUtilityPanel.setShowParameter(representation.showParameterValue());
if (representation.getEditorId() != 0) {
if (representation.getEditorId() != ImageOnlyEditor.ID) {
mActivity.hideCategoryPanel();
}
if (mEditorPlaceHolder.contains(representation.getEditorId())) {
mCurrentEditor = mEditorPlaceHolder.showEditor(
representation.getEditorId());
mUtilityPanel.removeControlChildren();
mCurrentEditor.setUpEditorUI(
mUtilityPanel.getActionControl(), mUtilityPanel.getEditControl(),
mUtilityPanel.getEditTitle());
mCurrentImage = mCurrentEditor.getImageShow();
mCurrentEditor.setPanelController(this);
} else {
mCurrentImage = showImageView(representation.getEditorId());
}
}
mUtilityPanel.setShowParameter(representation.showParameterValue());
mCurrentImage.select();
if (mCurrentEditor != null) {
mCurrentEditor.reflectCurrentFilter();
if (mCurrentEditor.useUtilityPanel()) {
mUtilityPanel.showMenu(true);
mCurrentEditor.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
}
} else if (mCurrentImage.useUtilityPanel()) {
mCurrentImage.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
}
}
return;
}
mActivity.showCategoryPanel();
int id = view.getId();
if (id == EditorTinyPlanet.ID) {
mCurrentImage = showImageView(R.id.imageTinyPlanet);
String ename = mCurrentImage.getContext().getString(R.string.tinyplanet);
mUtilityPanel.setEffectName(ename);
} else {
if (id == R.id.cancelFilter) {
cancelCurrentFilter();
} else if (id == R.id.applyEffect || id == R.id.applyFilter) {
if (MasterImage.getImage().getCurrentFilter() instanceof ImageFilterTinyPlanet) {
mActivity.saveImage();
} else {
showPanel(mCurrentPanel);
}
MasterImage.getImage().invalidateFiltersOnly();
}
}
mCurrentImage.select();
if (mCurrentEditor != null) {
mCurrentEditor.reflectCurrentFilter();
if (mCurrentEditor.useUtilityPanel()) {
mCurrentEditor.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
}
} else if (mCurrentImage.useUtilityPanel()) {
mCurrentImage.openUtilityPanel(mUtilityPanel.mAccessoryViewList);
}
}
public void cancelCurrentFilter() {
resetParameters();
MasterImage masterImage = MasterImage.getImage();
HistoryAdapter adapter = masterImage.getHistory();
int position = adapter.undo();
masterImage.onHistoryItemClick(position);
mActivity.invalidateViews();
}
public void setEditorPlaceHolder(EditorPlaceHolder editorPlaceHolder) {
mEditorPlaceHolder = editorPlaceHolder;
}
}