diff options
Diffstat (limited to 'src/com/android/gallery3d/filtershow/state')
7 files changed, 1026 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/filtershow/state/DragListener.java b/src/com/android/gallery3d/filtershow/state/DragListener.java new file mode 100644 index 000000000..1aa81ed69 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/state/DragListener.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2013 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.state; + +import android.view.DragEvent; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.LinearLayout; + +class DragListener implements View.OnDragListener { + + private static final String LOGTAG = "DragListener"; + private PanelTrack mStatePanelTrack; + private static float sSlope = 0.2f; + + public DragListener(PanelTrack statePanelTrack) { + mStatePanelTrack = statePanelTrack; + } + + private void setState(DragEvent event) { + float translation = event.getY() - mStatePanelTrack.getTouchPoint().y; + float alpha = 1.0f - (Math.abs(translation) + / mStatePanelTrack.getCurrentView().getHeight()); + if (mStatePanelTrack.getOrientation() == LinearLayout.VERTICAL) { + translation = event.getX() - mStatePanelTrack.getTouchPoint().x; + alpha = 1.0f - (Math.abs(translation) + / mStatePanelTrack.getCurrentView().getWidth()); + mStatePanelTrack.getCurrentView().setTranslationX(translation); + } else { + mStatePanelTrack.getCurrentView().setTranslationY(translation); + } + mStatePanelTrack.getCurrentView().setBackgroundAlpha(alpha); + } + + @Override + public boolean onDrag(View v, DragEvent event) { + switch (event.getAction()) { + case DragEvent.ACTION_DRAG_STARTED: { + break; + } + case DragEvent.ACTION_DRAG_LOCATION: { + if (mStatePanelTrack.getCurrentView() != null) { + setState(event); + View over = mStatePanelTrack.findChildAt((int) event.getX(), + (int) event.getY()); + if (over != null && over != mStatePanelTrack.getCurrentView()) { + StateView stateView = (StateView) over; + if (stateView != mStatePanelTrack.getCurrentView()) { + int pos = mStatePanelTrack.findChild(over); + int origin = mStatePanelTrack.findChild( + mStatePanelTrack.getCurrentView()); + ArrayAdapter array = (ArrayAdapter) mStatePanelTrack.getAdapter(); + if (origin != -1 && pos != -1) { + State current = (State) array.getItem(origin); + array.remove(current); + array.insert(current, pos); + mStatePanelTrack.fillContent(false); + mStatePanelTrack.setCurrentView(mStatePanelTrack.getChildAt(pos)); + } + } + } + } + break; + } + case DragEvent.ACTION_DRAG_ENTERED: { + mStatePanelTrack.setExited(false); + if (mStatePanelTrack.getCurrentView() != null) { + mStatePanelTrack.getCurrentView().setVisibility(View.VISIBLE); + } + return true; + } + case DragEvent.ACTION_DRAG_EXITED: { + if (mStatePanelTrack.getCurrentView() != null) { + setState(event); + mStatePanelTrack.getCurrentView().setVisibility(View.INVISIBLE); + } + mStatePanelTrack.setExited(true); + break; + } + case DragEvent.ACTION_DROP: { + break; + } + case DragEvent.ACTION_DRAG_ENDED: { + if (mStatePanelTrack.getCurrentView() != null + && mStatePanelTrack.getCurrentView().getAlpha() > sSlope) { + setState(event); + } + mStatePanelTrack.checkEndState(); + break; + } + default: + break; + } + return true; + } +} diff --git a/src/com/android/gallery3d/filtershow/state/PanelTrack.java b/src/com/android/gallery3d/filtershow/state/PanelTrack.java new file mode 100644 index 000000000..d02207d9b --- /dev/null +++ b/src/com/android/gallery3d/filtershow/state/PanelTrack.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2013 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.state; + +import android.graphics.Point; +import android.view.MotionEvent; +import android.view.View; +import android.widget.Adapter; + +public interface PanelTrack { + public int getOrientation(); + public void onTouch(MotionEvent event, StateView view); + public StateView getCurrentView(); + public void setCurrentView(View view); + public Point getTouchPoint(); + public View findChildAt(int x, int y); + public int findChild(View view); + public Adapter getAdapter(); + public void fillContent(boolean value); + public View getChildAt(int pos); + public void setExited(boolean value); + public void checkEndState(); +} diff --git a/src/com/android/gallery3d/filtershow/state/State.java b/src/com/android/gallery3d/filtershow/state/State.java new file mode 100644 index 000000000..e7dedd6a2 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/state/State.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2013 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.state; + +import com.android.gallery3d.filtershow.filters.FilterFxRepresentation; +import com.android.gallery3d.filtershow.filters.FilterRepresentation; + +public class State { + private String mText; + private int mType; + private FilterRepresentation mFilterRepresentation; + + public State(State state) { + this(state.getText(), state.getType()); + } + + public State(String text) { + this(text, StateView.DEFAULT); + } + + public State(String text, int type) { + mText = text; + mType = type; + } + + public boolean equals(State state) { + if (mFilterRepresentation.getFilterClass() + != state.mFilterRepresentation.getFilterClass()) { + return false; + } + if (mFilterRepresentation instanceof FilterFxRepresentation) { + return mFilterRepresentation.equals(state.getFilterRepresentation()); + } + return true; + } + + public boolean isDraggable() { + return mFilterRepresentation != null; + } + + String getText() { + return mText; + } + + void setText(String text) { + mText = text; + } + + int getType() { + return mType; + } + + void setType(int type) { + mType = type; + } + + public FilterRepresentation getFilterRepresentation() { + return mFilterRepresentation; + } + + public void setFilterRepresentation(FilterRepresentation filterRepresentation) { + mFilterRepresentation = filterRepresentation; + } +} diff --git a/src/com/android/gallery3d/filtershow/state/StateAdapter.java b/src/com/android/gallery3d/filtershow/state/StateAdapter.java new file mode 100644 index 000000000..522585280 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/state/StateAdapter.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2013 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.state; + +import android.content.Context; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import com.android.gallery3d.R; +import com.android.gallery3d.filtershow.FilterShowActivity; +import com.android.gallery3d.filtershow.editors.ImageOnlyEditor; +import com.android.gallery3d.filtershow.filters.FilterRepresentation; +import com.android.gallery3d.filtershow.imageshow.MasterImage; + +import java.util.Vector; + +public class StateAdapter extends ArrayAdapter<State> { + + private static final String LOGTAG = "StateAdapter"; + private int mOrientation; + private String mOriginalText; + private String mResultText; + + public StateAdapter(Context context, int textViewResourceId) { + super(context, textViewResourceId); + mOriginalText = context.getString(R.string.state_panel_original); + mResultText = context.getString(R.string.state_panel_result); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + StateView view = null; + if (convertView == null) { + convertView = new StateView(getContext()); + } + view = (StateView) convertView; + State state = getItem(position); + view.setState(state); + view.setOrientation(mOrientation); + FilterRepresentation currentRep = MasterImage.getImage().getCurrentFilterRepresentation(); + FilterRepresentation stateRep = state.getFilterRepresentation(); + if (currentRep != null && stateRep != null + && currentRep.getFilterClass() == stateRep.getFilterClass() + && currentRep.getEditorId() != ImageOnlyEditor.ID) { + view.setSelected(true); + } else { + view.setSelected(false); + } + return view; + } + + public boolean contains(State state) { + for (int i = 0; i < getCount(); i++) { + if (state == getItem(i)) { + return true; + } + } + return false; + } + + public void setOrientation(int orientation) { + mOrientation = orientation; + } + + public void addOriginal() { + add(new State(mOriginalText)); + } + + public boolean same(Vector<State> states) { + // we have the original state in addition + if (states.size() + 1 != getCount()) { + return false; + } + for (int i = 1; i < getCount(); i++) { + State state = getItem(i); + if (!state.equals(states.elementAt(i-1))) { + return false; + } + } + return true; + } + + public void fill(Vector<State> states) { + if (same(states)) { + return; + } + clear(); + addOriginal(); + addAll(states); + notifyDataSetChanged(); + } + + @Override + public void remove(State state) { + super.remove(state); + FilterRepresentation filterRepresentation = state.getFilterRepresentation(); + FilterShowActivity activity = (FilterShowActivity) getContext(); + activity.removeFilterRepresentation(filterRepresentation); + } +} diff --git a/src/com/android/gallery3d/filtershow/state/StatePanel.java b/src/com/android/gallery3d/filtershow/state/StatePanel.java new file mode 100644 index 000000000..df470f23e --- /dev/null +++ b/src/com/android/gallery3d/filtershow/state/StatePanel.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013 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.state; + +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import com.android.gallery3d.R; +import com.android.gallery3d.filtershow.imageshow.MasterImage; + +public class StatePanel extends Fragment { + private static final String LOGTAG = "StatePanel"; + private StatePanelTrack track; + private LinearLayout mMainView; + public static final String FRAGMENT_TAG = "StatePanel"; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + mMainView = (LinearLayout) inflater.inflate(R.layout.filtershow_state_panel_new, null); + View panel = mMainView.findViewById(R.id.listStates); + track = (StatePanelTrack) panel; + track.setAdapter(MasterImage.getImage().getState()); + return mMainView; + } +} diff --git a/src/com/android/gallery3d/filtershow/state/StatePanelTrack.java b/src/com/android/gallery3d/filtershow/state/StatePanelTrack.java new file mode 100644 index 000000000..fff7e7f5f --- /dev/null +++ b/src/com/android/gallery3d/filtershow/state/StatePanelTrack.java @@ -0,0 +1,351 @@ +/* + * Copyright (C) 2013 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.state; + +import android.animation.LayoutTransition; +import android.content.Context; +import android.content.res.TypedArray; +import android.database.DataSetObserver; +import android.graphics.Canvas; +import android.graphics.Point; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.Log; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Adapter; +import android.widget.LinearLayout; +import com.android.gallery3d.R; +import com.android.gallery3d.filtershow.FilterShowActivity; +import com.android.gallery3d.filtershow.editors.ImageOnlyEditor; +import com.android.gallery3d.filtershow.filters.FilterRepresentation; +import com.android.gallery3d.filtershow.imageshow.MasterImage; + +public class StatePanelTrack extends LinearLayout implements PanelTrack { + + private static final String LOGTAG = "StatePanelTrack"; + private Point mTouchPoint; + private StateView mCurrentView; + private StateView mCurrentSelectedView; + private boolean mExited = false; + private boolean mStartedDrag = false; + private StateAdapter mAdapter; + private DragListener mDragListener = new DragListener(this); + private float mDeleteSlope = 0.2f; + private GestureDetector mGestureDetector; + private int mElemWidth; + private int mElemHeight; + private int mElemSize; + private int mElemEndSize; + private int mEndElemWidth; + private int mEndElemHeight; + private long mTouchTime; + private int mMaxTouchDelay = 300; // 300ms delay for touch + private static final boolean ALLOWS_DRAG = false; + private DataSetObserver mObserver = new DataSetObserver() { + @Override + public void onChanged() { + super.onChanged(); + fillContent(false); + } + + @Override + public void onInvalidated() { + super.onInvalidated(); + fillContent(false); + } + }; + + public StatePanelTrack(Context context, AttributeSet attrs) { + super(context, attrs); + TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.StatePanelTrack); + mElemSize = a.getDimensionPixelSize(R.styleable.StatePanelTrack_elemSize, 0); + mElemEndSize = a.getDimensionPixelSize(R.styleable.StatePanelTrack_elemEndSize, 0); + if (getOrientation() == LinearLayout.HORIZONTAL) { + mElemWidth = mElemSize; + mElemHeight = LayoutParams.MATCH_PARENT; + mEndElemWidth = mElemEndSize; + mEndElemHeight = LayoutParams.MATCH_PARENT; + } else { + mElemWidth = LayoutParams.MATCH_PARENT; + mElemHeight = mElemSize; + mEndElemWidth = LayoutParams.MATCH_PARENT; + mEndElemHeight = mElemEndSize; + } + GestureDetector.SimpleOnGestureListener simpleOnGestureListener + = new GestureDetector.SimpleOnGestureListener(){ + @Override + public void onLongPress(MotionEvent e) { + longPress(e); + } + @Override + public boolean onDoubleTap(MotionEvent e) { + addDuplicate(e); + return true; + } + }; + mGestureDetector = new GestureDetector(context, simpleOnGestureListener); + } + + private void addDuplicate(MotionEvent e) { + if (mCurrentSelectedView == null) { + return; + } + int pos = findChild(mCurrentSelectedView); + if (pos != -1) { + mAdapter.insert(new State(mCurrentSelectedView.getState()), pos); + fillContent(true); + } + } + + private void longPress(MotionEvent e) { + View view = findChildAt((int) e.getX(), (int) e.getY()); + if (view == null) { + return; + } + if (view instanceof StateView) { + StateView stateView = (StateView) view; + stateView.setDuplicateButton(true); + } + } + + public void setAdapter(StateAdapter adapter) { + mAdapter = adapter; + mAdapter.registerDataSetObserver(mObserver); + mAdapter.setOrientation(getOrientation()); + fillContent(false); + requestLayout(); + } + + public StateView findChildWithState(State state) { + for (int i = 0; i < getChildCount(); i++) { + StateView view = (StateView) getChildAt(i); + if (view.getState() == state) { + return view; + } + } + return null; + } + + public void fillContent(boolean animate) { + if (!animate) { + this.setLayoutTransition(null); + } + int n = mAdapter.getCount(); + for (int i = 0; i < getChildCount(); i++) { + StateView child = (StateView) getChildAt(i); + child.resetPosition(); + if (!mAdapter.contains(child.getState())) { + removeView(child); + } + } + LayoutParams params = new LayoutParams(mElemWidth, mElemHeight); + for (int i = 0; i < n; i++) { + State s = mAdapter.getItem(i); + if (findChildWithState(s) == null) { + View view = mAdapter.getView(i, null, this); + addView(view, i, params); + } + } + + for (int i = 0; i < n; i++) { + State state = mAdapter.getItem(i); + StateView view = (StateView) getChildAt(i); + view.setState(state); + if (i == 0) { + view.setType(StateView.BEGIN); + } else if (i == n - 1) { + view.setType(StateView.END); + } else { + view.setType(StateView.DEFAULT); + } + view.resetPosition(); + } + + if (!animate) { + this.setLayoutTransition(new LayoutTransition()); + } + } + + public void onTouch(MotionEvent event, StateView view) { + if (!view.isDraggable()) { + return; + } + mCurrentView = view; + if (mCurrentSelectedView == mCurrentView) { + return; + } + if (mCurrentSelectedView != null) { + mCurrentSelectedView.setSelected(false); + } + // We changed the current view -- let's reset the + // gesture detector. + MotionEvent cancelEvent = MotionEvent.obtain(event); + cancelEvent.setAction(MotionEvent.ACTION_CANCEL); + mGestureDetector.onTouchEvent(cancelEvent); + mCurrentSelectedView = mCurrentView; + // We have to send the event to the gesture detector + mGestureDetector.onTouchEvent(event); + mTouchTime = System.currentTimeMillis(); + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent event) { + if (mCurrentView != null) { + return true; + } + return false; + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (mCurrentView == null) { + return false; + } + if (mTouchTime == 0) { + mTouchTime = System.currentTimeMillis(); + } + mGestureDetector.onTouchEvent(event); + if (mTouchPoint == null) { + mTouchPoint = new Point(); + mTouchPoint.x = (int) event.getX(); + mTouchPoint.y = (int) event.getY(); + } + + if (event.getActionMasked() == MotionEvent.ACTION_MOVE) { + float translation = event.getY() - mTouchPoint.y; + float alpha = 1.0f - (Math.abs(translation) / mCurrentView.getHeight()); + if (getOrientation() == LinearLayout.VERTICAL) { + translation = event.getX() - mTouchPoint.x; + alpha = 1.0f - (Math.abs(translation) / mCurrentView.getWidth()); + mCurrentView.setTranslationX(translation); + } else { + mCurrentView.setTranslationY(translation); + } + mCurrentView.setBackgroundAlpha(alpha); + if (ALLOWS_DRAG && alpha < 0.7) { + setOnDragListener(mDragListener); + DragShadowBuilder shadowBuilder = new DragShadowBuilder(mCurrentView); + mCurrentView.startDrag(null, shadowBuilder, mCurrentView, 0); + mStartedDrag = true; + } + } + if (!mExited && mCurrentView != null + && mCurrentView.getBackgroundAlpha() > mDeleteSlope + && event.getActionMasked() == MotionEvent.ACTION_UP + && System.currentTimeMillis() - mTouchTime < mMaxTouchDelay) { + FilterRepresentation representation = mCurrentView.getState().getFilterRepresentation(); + mCurrentView.setSelected(true); + if (representation != MasterImage.getImage().getCurrentFilterRepresentation()) { + FilterShowActivity activity = (FilterShowActivity) getContext(); + activity.showRepresentation(representation); + mCurrentView.setSelected(false); + } + } + if (event.getActionMasked() == MotionEvent.ACTION_UP + || (!mStartedDrag && event.getActionMasked() == MotionEvent.ACTION_CANCEL)) { + checkEndState(); + if (mCurrentView != null) { + FilterRepresentation representation = mCurrentView.getState().getFilterRepresentation(); + if (representation.getEditorId() == ImageOnlyEditor.ID) { + mCurrentView.setSelected(false); + } + } + } + return true; + } + + public void checkEndState() { + mTouchPoint = null; + mTouchTime = 0; + if (mExited || mCurrentView.getBackgroundAlpha() < mDeleteSlope) { + int origin = findChild(mCurrentView); + if (origin != -1) { + State current = mAdapter.getItem(origin); + FilterRepresentation currentRep = MasterImage.getImage().getCurrentFilterRepresentation(); + FilterRepresentation removedRep = current.getFilterRepresentation(); + mAdapter.remove(current); + fillContent(true); + if (currentRep != null && removedRep != null + && currentRep.getFilterClass() == removedRep.getFilterClass()) { + FilterShowActivity activity = (FilterShowActivity) getContext(); + activity.backToMain(); + return; + } + } + } else { + mCurrentView.setBackgroundAlpha(1.0f); + mCurrentView.setTranslationX(0); + mCurrentView.setTranslationY(0); + } + if (mCurrentSelectedView != null) { + mCurrentSelectedView.invalidate(); + } + if (mCurrentView != null) { + mCurrentView.invalidate(); + } + mCurrentView = null; + mExited = false; + mStartedDrag = false; + } + + public View findChildAt(int x, int y) { + Rect frame = new Rect(); + int scrolledXInt = getScrollX() + x; + int scrolledYInt = getScrollY() + y; + for (int i = 0; i < getChildCount(); i++) { + View child = getChildAt(i); + child.getHitRect(frame); + if (frame.contains(scrolledXInt, scrolledYInt)) { + return child; + } + } + return null; + } + + public int findChild(View view) { + for (int i = 0; i < getChildCount(); i++) { + View child = getChildAt(i); + if (child == view) { + return i; + } + } + return -1; + } + + public StateView getCurrentView() { + return mCurrentView; + } + + public void setCurrentView(View currentView) { + mCurrentView = (StateView) currentView; + } + + public void setExited(boolean value) { + mExited = value; + } + + public Point getTouchPoint() { + return mTouchPoint; + } + + public Adapter getAdapter() { + return mAdapter; + } +} diff --git a/src/com/android/gallery3d/filtershow/state/StateView.java b/src/com/android/gallery3d/filtershow/state/StateView.java new file mode 100644 index 000000000..73d57846a --- /dev/null +++ b/src/com/android/gallery3d/filtershow/state/StateView.java @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2013 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.state; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.*; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewParent; +import android.widget.LinearLayout; +import com.android.gallery3d.R; +import com.android.gallery3d.filtershow.FilterShowActivity; +import com.android.gallery3d.filtershow.imageshow.MasterImage; + +public class StateView extends View { + + private static final String LOGTAG = "StateView"; + private Path mPath = new Path(); + private Paint mPaint = new Paint(); + + public static int DEFAULT = 0; + public static int BEGIN = 1; + public static int END = 2; + + public static int UP = 1; + public static int DOWN = 2; + public static int LEFT = 3; + public static int RIGHT = 4; + + private int mType = DEFAULT; + private float mAlpha = 1.0f; + private String mText = "Default"; + private float mTextSize = 32; + private static int sMargin = 16; + private static int sArrowHeight = 16; + private static int sArrowWidth = 8; + private int mOrientation = LinearLayout.VERTICAL; + private int mDirection = DOWN; + private boolean mDuplicateButton; + private State mState; + + private int mEndsBackgroundColor; + private int mEndsTextColor; + private int mBackgroundColor; + private int mTextColor; + private int mSelectedBackgroundColor; + private int mSelectedTextColor; + private Rect mTextBounds = new Rect(); + + public StateView(Context context) { + this(context, DEFAULT); + } + + public StateView(Context context, int type) { + super(context); + mType = type; + Resources res = getResources(); + mEndsBackgroundColor = res.getColor(R.color.filtershow_stateview_end_background); + mEndsTextColor = res.getColor(R.color.filtershow_stateview_end_text); + mBackgroundColor = res.getColor(R.color.filtershow_stateview_background); + mTextColor = res.getColor(R.color.filtershow_stateview_text); + mSelectedBackgroundColor = res.getColor(R.color.filtershow_stateview_selected_background); + mSelectedTextColor = res.getColor(R.color.filtershow_stateview_selected_text); + mTextSize = res.getDimensionPixelSize(R.dimen.state_panel_text_size); + } + + public String getText() { + return mText; + } + + public void setText(String text) { + mText = text; + invalidate(); + } + + public void setType(int type) { + mType = type; + invalidate(); + } + + @Override + public void setSelected(boolean value) { + super.setSelected(value); + if (!value) { + mDuplicateButton = false; + } + invalidate(); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { + ViewParent parent = getParent(); + if (parent instanceof PanelTrack) { + ((PanelTrack) getParent()).onTouch(event, this); + } + if (mType == BEGIN) { + MasterImage.getImage().setShowsOriginal(true); + } + } + if (event.getActionMasked() == MotionEvent.ACTION_UP + || event.getActionMasked() == MotionEvent.ACTION_CANCEL) { + MasterImage.getImage().setShowsOriginal(false); + } + return true; + } + + public void drawText(Canvas canvas) { + if (mText == null) { + return; + } + mPaint.reset(); + if (isSelected()) { + mPaint.setColor(mSelectedTextColor); + } else { + mPaint.setColor(mTextColor); + } + if (mType == BEGIN) { + mPaint.setColor(mEndsTextColor); + } + mPaint.setTypeface(Typeface.DEFAULT_BOLD); + mPaint.setAntiAlias(true); + mPaint.setTextSize(mTextSize); + mPaint.getTextBounds(mText, 0, mText.length(), mTextBounds); + int x = (canvas.getWidth() - mTextBounds.width()) / 2; + int y = mTextBounds.height() + (canvas.getHeight() - mTextBounds.height()) / 2; + canvas.drawText(mText, x, y, mPaint); + } + + public void onDraw(Canvas canvas) { + canvas.drawARGB(0, 0, 0, 0); + mPaint.reset(); + mPath.reset(); + + float w = canvas.getWidth(); + float h = canvas.getHeight(); + float r = sArrowHeight; + float d = sArrowWidth; + + if (mOrientation == LinearLayout.HORIZONTAL) { + drawHorizontalPath(w, h, r, d); + } else { + if (mDirection == DOWN) { + drawVerticalDownPath(w, h, r, d); + } else { + drawVerticalPath(w, h, r, d); + } + } + + if (mType == DEFAULT || mType == END) { + if (mDuplicateButton) { + mPaint.setARGB(255, 200, 0, 0); + } else if (isSelected()) { + mPaint.setColor(mSelectedBackgroundColor); + } else { + mPaint.setColor(mBackgroundColor); + } + } else { + mPaint.setColor(mEndsBackgroundColor); + } + canvas.drawPath(mPath, mPaint); + drawText(canvas); + } + + private void drawHorizontalPath(float w, float h, float r, float d) { + mPath.moveTo(0, 0); + if (mType == END) { + mPath.lineTo(w, 0); + mPath.lineTo(w, h); + } else { + mPath.lineTo(w - d, 0); + mPath.lineTo(w - d, r); + mPath.lineTo(w, r + d); + mPath.lineTo(w - d, r + d + r); + mPath.lineTo(w - d, h); + } + mPath.lineTo(0, h); + if (mType != BEGIN) { + mPath.lineTo(0, r + d + r); + mPath.lineTo(d, r + d); + mPath.lineTo(0, r); + } + mPath.close(); + } + + private void drawVerticalPath(float w, float h, float r, float d) { + if (mType == BEGIN) { + mPath.moveTo(0, 0); + mPath.lineTo(w, 0); + } else { + mPath.moveTo(0, d); + mPath.lineTo(r, d); + mPath.lineTo(r + d, 0); + mPath.lineTo(r + d + r, d); + mPath.lineTo(w, d); + } + mPath.lineTo(w, h); + if (mType != END) { + mPath.lineTo(r + d + r, h); + mPath.lineTo(r + d, h - d); + mPath.lineTo(r, h); + } + mPath.lineTo(0, h); + mPath.close(); + } + + private void drawVerticalDownPath(float w, float h, float r, float d) { + mPath.moveTo(0, 0); + if (mType != BEGIN) { + mPath.lineTo(r, 0); + mPath.lineTo(r + d, d); + mPath.lineTo(r + d + r, 0); + } + mPath.lineTo(w, 0); + + if (mType != END) { + mPath.lineTo(w, h - d); + + mPath.lineTo(r + d + r, h - d); + mPath.lineTo(r + d, h); + mPath.lineTo(r, h - d); + + mPath.lineTo(0, h - d); + } else { + mPath.lineTo(w, h); + mPath.lineTo(0, h); + } + + mPath.close(); + } + + public void setBackgroundAlpha(float alpha) { + if (mType == BEGIN) { + return; + } + mAlpha = alpha; + setAlpha(alpha); + invalidate(); + } + + public float getBackgroundAlpha() { + return mAlpha; + } + + public void setOrientation(int orientation) { + mOrientation = orientation; + } + + public void setDuplicateButton(boolean b) { + mDuplicateButton = b; + invalidate(); + } + + public State getState() { + return mState; + } + + public void setState(State state) { + mState = state; + mText = mState.getText().toUpperCase(); + mType = mState.getType(); + invalidate(); + } + + public void resetPosition() { + setTranslationX(0); + setTranslationY(0); + setBackgroundAlpha(1.0f); + } + + public boolean isDraggable() { + return mState.isDraggable(); + } +} |