1 /* 2 * Copyright (C) 2012 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.imageshow; 18 19 import android.content.Context; 20 import android.graphics.Bitmap; 21 import android.graphics.Canvas; 22 import android.graphics.Paint; 23 import android.graphics.RectF; 24 import android.util.AttributeSet; 25 26 import com.android.gallery3d.R; 27 import com.android.gallery3d.filtershow.editors.EditorFlip; 28 import com.android.gallery3d.filtershow.imageshow.GeometryMetadata.FLIP; 29 30 public class ImageFlip extends ImageGeometry { 31 32 private static final Paint gPaint = new Paint(); 33 private static final float MIN_FLICK_DIST_FOR_FLIP = 0.1f; 34 private static final String LOGTAG = "ImageFlip"; 35 private FLIP mNextFlip = FLIP.NONE; 36 private EditorFlip mEditorFlip; 37 38 public ImageFlip(Context context, AttributeSet attrs) { 39 super(context, attrs); 40 } 41 42 public ImageFlip(Context context) { 43 super(context); 44 } 45 46 @Override 47 public String getName() { 48 return getContext().getString(R.string.mirror); 49 } 50 51 @Override 52 protected void setActionDown(float x, float y) { 53 super.setActionDown(x, y); 54 } 55 56 boolean hasRotated90(){ 57 int rot = constrainedRotation(getLocalRotation()); 58 return (rot / 90) % 2 != 0; 59 } 60 61 public void flip() { 62 FLIP flip = getLocalFlip(); 63 boolean next = true; 64 // Picks next flip in order from enum FLIP (wrapping) 65 for (FLIP f : FLIP.values()) { 66 if (next) { 67 mNextFlip = f; 68 next = false; 69 } 70 if (f.equals(flip)) { 71 next = true; 72 } 73 } 74 setLocalFlip(mNextFlip); 75 } 76 77 @Override 78 protected void setActionMove(float x, float y) { 79 super.setActionMove(x, y); 80 81 float diffx = mTouchCenterX - x; 82 float diffy = mTouchCenterY - y; 83 float flick = getScaledMinFlick(); 84 if(hasRotated90()){ 85 float temp = diffx; 86 diffx = diffy; 87 diffy = temp; 88 } 89 if (Math.abs(diffx) >= flick) { 90 // flick moving left/right 91 FLIP flip = getLocalFlip(); 92 switch (flip) { 93 case NONE: 94 flip = FLIP.HORIZONTAL; 95 break; 96 case HORIZONTAL: 97 flip = FLIP.NONE; 98 break; 99 case VERTICAL: 100 flip = FLIP.BOTH; 101 break; 102 case BOTH: 103 flip = FLIP.VERTICAL; 104 break; 105 default: 106 flip = FLIP.NONE; 107 break; 108 } 109 mNextFlip = flip; 110 } 111 if (Math.abs(diffy) >= flick) { 112 // flick moving up/down 113 FLIP flip = getLocalFlip(); 114 switch (flip) { 115 case NONE: 116 flip = FLIP.VERTICAL; 117 break; 118 case VERTICAL: 119 flip = FLIP.NONE; 120 break; 121 case HORIZONTAL: 122 flip = FLIP.BOTH; 123 break; 124 case BOTH: 125 flip = FLIP.HORIZONTAL; 126 break; 127 default: 128 flip = FLIP.NONE; 129 break; 130 } 131 mNextFlip = flip; 132 } 133 } 134 135 @Override 136 protected void setActionUp() { 137 super.setActionUp(); 138 setLocalFlip(mNextFlip); 139 } 140 141 @Override 142 public void resetParameter() { 143 super.resetParameter(); 144 mNextFlip = FLIP.NONE; 145 } 146 147 private float getScaledMinFlick() { 148 RectF disp = getLocalDisplayBounds(); 149 float scaled = Math.min(disp.width(), disp.height()) * MIN_FLICK_DIST_FOR_FLIP 150 / getLocalScale(); 151 return scaled; 152 } 153 154 @Override 155 protected void drawShape(Canvas canvas, Bitmap image) { 156 gPaint.setAntiAlias(true); 157 gPaint.setARGB(255, 255, 255, 255); 158 drawTransformedCropped(canvas, image, gPaint); 159 } 160 161 public void setEditor(EditorFlip editorFlip) { 162 mEditorFlip = editorFlip; 163 } 164 165 } 166