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 17 package com.android.gallery3d.filtershow.state; 18 19 import android.content.Context; 20 import android.content.res.Resources; 21 import android.graphics.*; 22 import android.view.MotionEvent; 23 import android.view.View; 24 import android.widget.LinearLayout; 25 import com.android.gallery3d.R; 26 import com.android.gallery3d.filtershow.FilterShowActivity; 27 import com.android.gallery3d.filtershow.category.SwipableView; 28 import com.android.gallery3d.filtershow.filters.FilterRepresentation; 29 import com.android.gallery3d.filtershow.imageshow.MasterImage; 30 import com.android.gallery3d.filtershow.pipeline.ImagePreset; 31 32 public class StateView extends View implements SwipableView { 33 34 private static final String LOGTAG = "StateView"; 35 private Path mPath = new Path(); 36 private Paint mPaint = new Paint(); 37 38 public static int DEFAULT = 0; 39 public static int BEGIN = 1; 40 public static int END = 2; 41 42 public static int UP = 1; 43 public static int DOWN = 2; 44 public static int LEFT = 3; 45 public static int RIGHT = 4; 46 47 private int mType = DEFAULT; 48 private float mAlpha = 1.0f; 49 private String mText = "Default"; 50 private float mTextSize = 32; 51 private static int sMargin = 16; 52 private static int sArrowHeight = 16; 53 private static int sArrowWidth = 8; 54 private float mStartTouchX = 0; 55 private float mStartTouchY = 0; 56 private float mDeleteSlope = 20; 57 58 private int mOrientation = LinearLayout.VERTICAL; 59 private int mDirection = DOWN; 60 private boolean mDuplicateButton; 61 private State mState; 62 63 private int mEndsBackgroundColor; 64 private int mEndsTextColor; 65 private int mBackgroundColor; 66 private int mTextColor; 67 private int mSelectedBackgroundColor; 68 private int mSelectedTextColor; 69 private Rect mTextBounds = new Rect(); 70 71 public StateView(Context context) { 72 this(context, DEFAULT); 73 } 74 75 public StateView(Context context, int type) { 76 super(context); 77 mType = type; 78 Resources res = getResources(); 79 mEndsBackgroundColor = res.getColor(R.color.filtershow_stateview_end_background); 80 mEndsTextColor = res.getColor(R.color.filtershow_stateview_end_text); 81 mBackgroundColor = res.getColor(R.color.filtershow_stateview_background); 82 mTextColor = res.getColor(R.color.filtershow_stateview_text); 83 mSelectedBackgroundColor = res.getColor(R.color.filtershow_stateview_selected_background); 84 mSelectedTextColor = res.getColor(R.color.filtershow_stateview_selected_text); 85 mTextSize = res.getDimensionPixelSize(R.dimen.state_panel_text_size); 86 } 87 88 public String getText() { 89 return mText; 90 } 91 92 public void setText(String text) { 93 mText = text; 94 invalidate(); 95 } 96 97 public void setType(int type) { 98 mType = type; 99 invalidate(); 100 } 101 102 @Override 103 public void setSelected(boolean value) { 104 super.setSelected(value); 105 if (!value) { 106 mDuplicateButton = false; 107 } 108 invalidate(); 109 } 110 111 public void drawText(Canvas canvas) { 112 if (mText == null) { 113 return; 114 } 115 mPaint.reset(); 116 if (isSelected()) { 117 mPaint.setColor(mSelectedTextColor); 118 } else { 119 mPaint.setColor(mTextColor); 120 } 121 if (mType == BEGIN) { 122 mPaint.setColor(mEndsTextColor); 123 } 124 mPaint.setTypeface(Typeface.DEFAULT_BOLD); 125 mPaint.setAntiAlias(true); 126 mPaint.setTextSize(mTextSize); 127 mPaint.getTextBounds(mText, 0, mText.length(), mTextBounds); 128 int x = (canvas.getWidth() - mTextBounds.width()) / 2; 129 int y = mTextBounds.height() + (canvas.getHeight() - mTextBounds.height()) / 2; 130 canvas.drawText(mText, x, y, mPaint); 131 } 132 133 public void onDraw(Canvas canvas) { 134 canvas.drawARGB(0, 0, 0, 0); 135 mPaint.reset(); 136 mPath.reset(); 137 138 float w = canvas.getWidth(); 139 float h = canvas.getHeight(); 140 float r = sArrowHeight; 141 float d = sArrowWidth; 142 143 if (mOrientation == LinearLayout.HORIZONTAL) { 144 drawHorizontalPath(w, h, r, d); 145 } else { 146 if (mDirection == DOWN) { 147 drawVerticalDownPath(w, h, r, d); 148 } else { 149 drawVerticalPath(w, h, r, d); 150 } 151 } 152 153 if (mType == DEFAULT || mType == END) { 154 if (mDuplicateButton) { 155 mPaint.setARGB(255, 200, 0, 0); 156 } else if (isSelected()) { 157 mPaint.setColor(mSelectedBackgroundColor); 158 } else { 159 mPaint.setColor(mBackgroundColor); 160 } 161 } else { 162 mPaint.setColor(mEndsBackgroundColor); 163 } 164 canvas.drawPath(mPath, mPaint); 165 drawText(canvas); 166 } 167 168 private void drawHorizontalPath(float w, float h, float r, float d) { 169 if (this.getLayoutDirection() == LAYOUT_DIRECTION_RTL) { 170 mPath.moveTo(w, 0); 171 if (mType == END) { 172 mPath.lineTo(0, 0); 173 mPath.lineTo(0, h); 174 } else { 175 mPath.lineTo(d, 0); 176 mPath.lineTo(d, r); 177 mPath.lineTo(0, r + d); 178 mPath.lineTo(d, r + d + r); 179 mPath.lineTo(d, h); 180 } 181 mPath.lineTo(w, h); 182 if (mType != BEGIN) { 183 mPath.lineTo(w, r + d + r); 184 mPath.lineTo(w - d, r + d); 185 mPath.lineTo(w, r); 186 } 187 } else { 188 mPath.moveTo(0, 0); 189 if (mType == END) { 190 mPath.lineTo(w, 0); 191 mPath.lineTo(w, h); 192 } else { 193 mPath.lineTo(w - d, 0); 194 mPath.lineTo(w - d, r); 195 mPath.lineTo(w, r + d); 196 mPath.lineTo(w - d, r + d + r); 197 mPath.lineTo(w - d, h); 198 } 199 mPath.lineTo(0, h); 200 if (mType != BEGIN) { 201 mPath.lineTo(0, r + d + r); 202 mPath.lineTo(d, r + d); 203 mPath.lineTo(0, r); 204 } 205 } 206 mPath.close(); 207 } 208 209 private void drawVerticalPath(float w, float h, float r, float d) { 210 if (mType == BEGIN) { 211 mPath.moveTo(0, 0); 212 mPath.lineTo(w, 0); 213 } else { 214 mPath.moveTo(0, d); 215 mPath.lineTo(r, d); 216 mPath.lineTo(r + d, 0); 217 mPath.lineTo(r + d + r, d); 218 mPath.lineTo(w, d); 219 } 220 mPath.lineTo(w, h); 221 if (mType != END) { 222 mPath.lineTo(r + d + r, h); 223 mPath.lineTo(r + d, h - d); 224 mPath.lineTo(r, h); 225 } 226 mPath.lineTo(0, h); 227 mPath.close(); 228 } 229 230 private void drawVerticalDownPath(float w, float h, float r, float d) { 231 mPath.moveTo(0, 0); 232 if (mType != BEGIN) { 233 mPath.lineTo(r, 0); 234 mPath.lineTo(r + d, d); 235 mPath.lineTo(r + d + r, 0); 236 } 237 mPath.lineTo(w, 0); 238 239 if (mType != END) { 240 mPath.lineTo(w, h - d); 241 242 mPath.lineTo(r + d + r, h - d); 243 mPath.lineTo(r + d, h); 244 mPath.lineTo(r, h - d); 245 246 mPath.lineTo(0, h - d); 247 } else { 248 mPath.lineTo(w, h); 249 mPath.lineTo(0, h); 250 } 251 252 mPath.close(); 253 } 254 255 public void setBackgroundAlpha(float alpha) { 256 if (mType == BEGIN) { 257 return; 258 } 259 mAlpha = alpha; 260 setAlpha(alpha); 261 invalidate(); 262 } 263 264 public float getBackgroundAlpha() { 265 return mAlpha; 266 } 267 268 public void setOrientation(int orientation) { 269 mOrientation = orientation; 270 } 271 272 public void setDuplicateButton(boolean b) { 273 mDuplicateButton = b; 274 invalidate(); 275 } 276 277 public State getState() { 278 return mState; 279 } 280 281 public void setState(State state) { 282 mState = state; 283 mText = mState.getText().toUpperCase(); 284 mType = mState.getType(); 285 invalidate(); 286 } 287 288 public void resetPosition() { 289 setTranslationX(0); 290 setTranslationY(0); 291 setBackgroundAlpha(1.0f); 292 } 293 294 public boolean isDraggable() { 295 return mState.isDraggable(); 296 } 297 298 @Override 299 public void delete() { 300 FilterShowActivity activity = (FilterShowActivity) getContext(); 301 FilterRepresentation representation = getState().getFilterRepresentation(); 302 activity.removeFilterRepresentation(representation); 303 } 304 305 @Override 306 public boolean onTouchEvent(MotionEvent event) { 307 boolean ret = super.onTouchEvent(event); 308 FilterShowActivity activity = (FilterShowActivity) getContext(); 309 310 if (event.getActionMasked() == MotionEvent.ACTION_UP) { 311 activity.startTouchAnimation(this, event.getX(), event.getY()); 312 } 313 if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 314 mStartTouchY = event.getY(); 315 mStartTouchX = event.getX(); 316 if (mType == BEGIN) { 317 MasterImage.getImage().setShowsOriginal(true); 318 } 319 } 320 if (event.getActionMasked() == MotionEvent.ACTION_UP 321 || event.getActionMasked() == MotionEvent.ACTION_CANCEL) { 322 setTranslationX(0); 323 setTranslationY(0); 324 MasterImage.getImage().setShowsOriginal(false); 325 if (mType != BEGIN && event.getActionMasked() == MotionEvent.ACTION_UP) { 326 setSelected(true); 327 FilterRepresentation representation = getState().getFilterRepresentation(); 328 MasterImage image = MasterImage.getImage(); 329 ImagePreset preset = image != null ? image.getCurrentPreset() : null; 330 if (getTranslationY() == 0 331 && image != null && preset != null 332 && representation != image.getCurrentFilterRepresentation() 333 && preset.getRepresentation(representation) != null) { 334 activity.showRepresentation(representation); 335 setSelected(false); 336 } 337 } 338 } 339 if (mType != BEGIN && event.getActionMasked() == MotionEvent.ACTION_MOVE) { 340 float delta = event.getY() - mStartTouchY; 341 if (Math.abs(delta) > mDeleteSlope) { 342 activity.setHandlesSwipeForView(this, mStartTouchX, mStartTouchY); 343 } 344 } 345 return true; 346 } 347 } 348